diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml new file mode 100644 index 00000000..1c284c9d --- /dev/null +++ b/.github/codeql/codeql-config.yml @@ -0,0 +1,28 @@ +name: "CodeQL config" + +packs: + - trailofbits/cpp-queries + - githubsecuritylab/codeql-cpp-queries + - githubsecuritylab/codeql-python-queries + +queries: + - uses: security-extended + - uses: security-and-quality + +query-filters: + - exclude: + query path: + - /^experimental\/.*/ + - exclude: + tags contain: + - experimental + - exclude: + problem.severity: + - recommendation + - exclude: + id: tob/cpp/use-of-legacy-algorithm # We use legacy algorithms in many places for integrity checks + - exclude: + id: cpp/dead-code-goto # Too many false positives in no-build mode + +paths-ignore: + - tests/** diff --git a/.github/scripts/process_sarif.py b/.github/scripts/process_sarif.py new file mode 100644 index 00000000..fad689b6 --- /dev/null +++ b/.github/scripts/process_sarif.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python3 + +# This script is used to process the SARIF file generated by CodeQL and +# to rename files back to .ino and adjust line numbers to match the original .ino files. + +import json +import sys +import os + +def process_artifact_location(artifact_location, renamed_files): + """ + Process a single artifact location to rename .cpp files back to .ino + """ + if 'uri' in artifact_location: + uri = artifact_location['uri'] + if uri in renamed_files: + print(f"Renaming file: {uri} -> {renamed_files[uri]}") + artifact_location['uri'] = renamed_files[uri] + return True + return False + +def process_region(region): + """ + Adjust line numbers in a region by decreasing them by 1 + """ + if 'startLine' in region: + region['startLine'] = max(1, region['startLine'] - 1) + if 'endLine' in region: + region['endLine'] = max(1, region['endLine'] - 1) + +def process_physical_location(physical_location, renamed_files): + """ + Process a physical location to rename files and adjust line numbers + """ + file_renamed = False + + if 'artifactLocation' in physical_location: + if process_artifact_location(physical_location['artifactLocation'], renamed_files): + file_renamed = True + + # Adjust line numbers if the file was renamed + if file_renamed and 'region' in physical_location: + process_region(physical_location['region']) + + return file_renamed + + +def process_sarif_file(sarif_file, renamed_files_file): + """ + Process SARIF file to rename files back to .ino and adjust line numbers + """ + # Read the renamed files mapping + with open(renamed_files_file, 'r') as f: + renamed_files = json.load(f) + + print(f"Loaded {len(renamed_files)} file mappings:") + for cpp_file, ino_file in renamed_files.items(): + print(f" {cpp_file} -> {ino_file}") + + + # Read the SARIF file + with open(sarif_file, 'r') as f: + sarif_data = json.load(f) + + files_processed = 0 + + # Process each run + if 'runs' in sarif_data: + for run in sarif_data['runs']: + # Process results + if 'results' in run: + for result in run['results']: + # Process all locations in the result + if 'locations' in result: + for location in result['locations']: + if 'physicalLocation' in location: + if process_physical_location(location['physicalLocation'], renamed_files): + files_processed += 1 + + # Process related locations if they exist + if 'relatedLocations' in result: + for location in result['relatedLocations']: + if 'physicalLocation' in location: + if process_physical_location(location['physicalLocation'], renamed_files): + files_processed += 1 + + # Process artifacts if they exist + if 'artifacts' in run: + for artifact in run['artifacts']: + if 'location' in artifact and 'uri' in artifact['location']: + uri = artifact['location']['uri'] + if uri in renamed_files: + artifact['location']['uri'] = renamed_files[uri] + files_processed += 1 + + print(f"Processed {files_processed} file references") + + # Write the processed SARIF file + with open(sarif_file, 'w') as f: + json.dump(sarif_data, f, indent=2) + +def main(): + if len(sys.argv) != 3: + print("Usage: python3 sarif_nobuild.py ") + sys.exit(1) + + sarif_file = sys.argv[1] + renamed_files_file = sys.argv[2] + + # Check if files exist + if not os.path.exists(sarif_file): + print(f"SARIF file not found: {sarif_file}") + sys.exit(1) + + if not os.path.exists(renamed_files_file): + print(f"Renamed files mapping not found: {renamed_files_file}") + sys.exit(1) + + try: + process_sarif_file(sarif_file, renamed_files_file) + print("SARIF file processed successfully") + except Exception as e: + print(f"Error processing SARIF file: {e}") + import traceback + traceback.print_exc() + sys.exit(1) + +if __name__ == "__main__": + main() diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..26bd868c --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,94 @@ +name: CodeQL Analysis + +on: + workflow_dispatch: + push: + branches: + - master + pull_request: + paths: + - "**/*.c" + - "**/*.cpp" + - "**/*.h" + - "**/*.ino" + - "**/*.py" + - ".github/workflows/*.yml" + - ".github/workflows/*.yaml" + +permissions: + actions: read + contents: read + pull-requests: read + security-events: write + +jobs: + codeql-analysis: + name: CodeQL ${{ matrix.language }} analysis + runs-on: ubuntu-latest + strategy: + matrix: + language: [python, actions, cpp] + + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Process .ino files + if: matrix.language == 'cpp' + run: | + # Create a mapping file to track renamed files + echo "{}" > renamed_files.json + + # Find all .ino files and process them + find . -name "*.ino" -type f | while read -r file; do + echo "Processing $file" + + # Get the relative path from repository root + rel_path=$(realpath --relative-to=. "$file") + cpp_path="${rel_path%.ino}.cpp" + + # Create new .cpp file with Arduino.h include + echo "#include " > "$cpp_path" + + # Append the original content + cat "$file" >> "$cpp_path" + + # Update the mapping file + jq --arg ino "$rel_path" --arg cpp "$cpp_path" '. += {($cpp): $ino}' renamed_files.json > temp.json && mv temp.json renamed_files.json + + # Remove the original .ino file + rm "$file" + + echo "Converted $file to $cpp_path" + done + + echo "Renamed files mapping:" + cat renamed_files.json + + - name: Initialize CodeQL + uses: github/codeql-action/init@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2 + with: + build-mode: none + languages: ${{ matrix.language }} + config-file: ./.github/codeql/codeql-config.yml + + - name: Run CodeQL Analysis + uses: github/codeql-action/analyze@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2 + with: + category: "/language:${{ matrix.language }}" + output: sarif-results + upload: failure-only + + - name: Process SARIF file + if: matrix.language == 'cpp' + run: | + sarif_file="sarif-results/${{ matrix.language }}.sarif" + + # Run the Python script to process the SARIF file + python3 .github/scripts/process_sarif.py "$sarif_file" "renamed_files.json" + + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2 + with: + sarif_file: sarif-results/${{ matrix.language }}.sarif + category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/make-release.yml b/.github/workflows/make-release.yml new file mode 100644 index 00000000..36616946 --- /dev/null +++ b/.github/workflows/make-release.yml @@ -0,0 +1,25 @@ +name: Build all and make release on tag + +on: + workflow_dispatch: + push: + tags: + - '*' + +jobs: + make-release: + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Drafting release + uses: ncipollo/release-action@b7eabc95ff50cbeeedec83973935c8f306dfcd0b # v1.20.0 + with: + draft: true + generateReleaseNotes: true diff --git a/.github/workflows/pr-or-master-push.yml b/.github/workflows/pr-or-master-push.yml index 88d6fca7..fe31c425 100644 --- a/.github/workflows/pr-or-master-push.yml +++ b/.github/workflows/pr-or-master-push.yml @@ -11,64 +11,110 @@ on: - master pull_request: +permissions: + contents: read + pull-requests: write + + jobs: - build-esp8266: - name: Build ESP8266 + build-rp2040: + name: Build RP2040 runs-on: ubuntu-latest strategy: matrix: - chunk: [0, 1, 2, 3, 4] + shift: [1-, 2-, 3-, 4-, 5-] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v5 with: python-version: '3.x' - - name: Build Sketches - env: - TRAVIS_BUILD_DIR: ${{ github.workspace }} - TRAVIS_TAG: ${{ github.ref }} - BUILD_TYPE: build - BUILD_MOD: 5 - BUILD_REM: ${{ matrix.chunk }} + - name: Install Arduino-CLI, RP2040 core, this library run: | - bash ./tests/common.sh + wget --quiet https://downloads.arduino.cc/arduino-cli/nightly/arduino-cli_nightly-latest_Linux_64bit.tar.gz + tar xf arduino-cli_nightly-latest_Linux_64bit.tar.gz + ./arduino-cli config init + ./arduino-cli config add board_manager.additional_urls https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json + ./arduino-cli config set library.enable_unsafe_install true + ./arduino-cli core update-index + ./arduino-cli core install rp2040:rp2040 + mkdir -p ~/Arduino/libraries + cp -a /home/runner/work/ESP8266Audio/ESP8266Audio ~/Arduino/libraries/. + - name: Build examples RP2040 + run: | + ./tests/build-ci.sh rp2040 ${{matrix.shift}} "rp2040:rp2040:rpipicow:flash=2097152_262144,freq=200,opt=Small,os=none,profile=Disabled,rtti=Disabled,stackprotect=Disabled,exceptions=Disabled,dbgport=Disabled,dbglvl=None,usbstack=picosdk,wificountry=worldwide,ipbtstack=ipv4only,uploadmethod=default" 1 + build-esp8266: + name: Build all examples on Arduino-ESP8266 latest release + runs-on: ubuntu-latest + strategy: + matrix: + shift: [1-, 2-, 3-, 4-, 5-] + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install Arduino-CLI, ESP8266 core, this library + run: | + wget --quiet https://downloads.arduino.cc/arduino-cli/nightly/arduino-cli_nightly-latest_Linux_64bit.tar.gz + tar xf arduino-cli_nightly-latest_Linux_64bit.tar.gz + ./arduino-cli config init + mkdir -p ~/Arduino/libraries + cp -a /home/runner/work/ESP8266Audio/ESP8266Audio ~/Arduino/libraries/. + mkdir -p ~/Arduino/hardware/esp8266com + cd ~/Arduino/hardware/esp8266com + git clone https://github.com/esp8266/Arduino.git esp8266 + cd esp8266 + git submodule update --init --recursive + cd tools + ./get.py -q + - name: Build examples ESP8266 + run: | + ./tests/build-ci.sh esp8266 ${{matrix.shift}} "esp8266com:esp8266:d1_mini:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,eesz=4M2M,ip=lm2f,dbg=Disabled,lvl=None____,optim=Smallest,wipe=none,baud=921600,iramfloat=no" 1 build-esp32: - name: Build ESP-32 + name: Build all examples on Arduino-ESP32 latest release runs-on: ubuntu-latest strategy: matrix: - chunk: [0, 1, 2, 3, 4] + shift: [1-, 2-, 3-, 4-, 5-] + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - - uses: actions/setup-python@v2 - with: - python-version: '3.x' - - name: Build Sketches - env: - TRAVIS_BUILD_DIR: ${{ github.workspace }} - TRAVIS_TAG: ${{ github.ref }} - BUILD_TYPE: build_esp32 - BUILD_MOD: 5 - BUILD_REM: ${{ matrix.chunk }} + - name: Install Arduino-CLI, ESP32 core, this library + run: | + wget --quiet https://downloads.arduino.cc/arduino-cli/nightly/arduino-cli_nightly-latest_Linux_64bit.tar.gz + tar xf arduino-cli_nightly-latest_Linux_64bit.tar.gz + ./arduino-cli config init + ./arduino-cli config add board_manager.additional_urls https://espressif.github.io/arduino-esp32/package_esp32_index.json + ./arduino-cli config set library.enable_unsafe_install true + ./arduino-cli core update-index + ./arduino-cli core install esp32:esp32 + mkdir -p ~/Arduino/libraries + cp -a /home/runner/work/ESP8266Audio/ESP8266Audio ~/Arduino/libraries/. + - name: Build examples ESP32C6 run: | - bash ./tests/common.sh + # TODO - Don't use -Werror on ESP32, I2S deprecation warnings + ./tests/build-ci.sh esp32c6 ${{matrix.shift}} "esp32:esp32:esp32c6:PartitionScheme=huge_app" 0 # Run host test suite under valgrind for runtime checking of code. host-tests: name: Host tests runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v5 with: python-version: '3.x' - name: Run host tests @@ -84,5 +130,37 @@ jobs: valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all --error-exitcode=999 ./mp3 valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all --error-exitcode=999 ./aac valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all --error-exitcode=999 ./wav + valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all --error-exitcode=999 ./flac + valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all --error-exitcode=999 ./mod + valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all --error-exitcode=999 ./wav valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all --error-exitcode=999 ./midi + valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all --error-exitcode=999 ./opus + + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: arduino/arduino-lint-action@4de5fc895deecbda2f6b1cc05de7a8fdd5c4c51f # v2 + with: + library-manager: 'update' +# Style and spelling + code-spell: + name: Spelling, Style + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Run codespell + uses: codespell-project/actions-codespell@406322ec52dd7b488e48c1c4b82e2a8b3a1bf630 # v2.1 + with: + skip: ./src/libmad,./src/libhelix-aac,./src/libopus,./src/libflac,./lib/opus + ignore_words_list: ESP8266,esp8266,esp,dout,DOUT,ser,ans,inout,numer,hist + - name: Run astyle on all code/examples + run: | + sudo apt update + sudo apt install astyle + ./tests/restyle.sh + # If anything changed, GIT should return an error and fail the test + git diff --exit-code diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 00000000..f5236fa5 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,26 @@ +name: Close stale issues and PRs + +on: + schedule: + - cron: '55 1 * * *' + workflow_dispatch: + +permissions: + issues: write + pull-requests: write + actions: write + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v10 + with: + operations-per-run: 500 + days-before-issue-stale: 60 + days-before-issue-close: 14 + stale-issue-label: "stale" + stale-issue-message: "This issue is stale because it has been open for 60 days with no activity." + close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale." + days-before-pr-stale: -1 + days-before-pr-close: -1 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..2108e90c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/opus"] + path = lib/opus + url = https://gitlab.xiph.org/xiph/opus.git diff --git a/README.md b/README.md index c8c92ff6..5c52fda9 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,31 @@ -# ESP8266Audio - supports ESP8266 & ESP32 [![Gitter](https://badges.gitter.im/ESP8266Audio/community.svg)](https://gitter.im/ESP8266Audio/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) +# ESP8266Audio - supports ESP8266 & ESP32 & Raspberry Pi Pico RP2040 and Pico 2 RP2350 [![Gitter](https://badges.gitter.im/ESP8266Audio/community.svg)](https://gitter.im/ESP8266Audio/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) Arduino library for parsing and decoding MOD, WAV, MP3, FLAC, MIDI, AAC, and RTTL files and playing them on an I2S DAC or even using a software-simulated delta-sigma DAC with dynamic 32x-128x oversampling. -ESP8266 is fully supported and most mature, but ESP32 is also mostly there with built-in DAC as well as external ones. +For real-time, autonomous speech synthesis, check out [ESP8266SAM](https://github.com/earlephilhower/ESP8266SAM), a library which uses this one and a port of an ancient formant-based synthesis program to allow your ESP8266 to talk with low memory and no network required. -For real-time, autonomous speech synthesis, check out [ESP8266SAM](https://github.com/earlephilhower/ESP8266SAM), a library which uses this one and a port of an ancient format-based synthesis program to allow your ESP8266 to talk with low memory and no network required. +# ESP32, Raspberry Pi Pico (RP2040 and RP2350) Users +Consider using [BackgroundAudio](https://github.com/earlephilhower/BackgroundAudio) instead of this library as it can provide a simpler usage model and better results and performance on the Pico by using an interrupt-based, frame-aligned output model. ## Disclaimer -All this code is released under the GPL, and all of it is to be used at your own risk. If you find any bugs, please let me know via the GitHub issue tracker or drop me an email. The MOD and MP3 routines were taken from StellaPlayer and libMAD respectively. The software I2S delta-sigma 32x oversampling DAC was my own creation, and sounds quite good if I do say so myself. +All this code is released under the GPL, and all of it is to be used at your own risk. If you find any bugs, please let me know via the GitHub issue tracker or drop me an email. -The AAC decode code is from the Helix project and licensed under RealNetwork's RSPL license. For commercial use you're still going to need the usual AAC licensing from [Via Licensing](http://www.via-corp.com/us/en/licensing/aac/overview.html). - -On the ESP32, AAC-SBR is supported (many webradio stations use this to reduce bandwidth even further). The ESP8266, however, does not support it due to a lack of onboard RAM. - -MIDI decoding comes from a highly ported [MIDITONES](https://github.com/LenShustek/miditones) combined with a massively memory-optimized [TinySoundFont](https://github.com/schellingb/TinySoundFont), see the respective source files for more information. - -Opus, OGG, and OpusFile are from [Xiph.org](https://xiph.org) with the Xiph license and patent described in src/{opusfile,libggg,libopus}/COPYING.. **NOTE** Opus decoding currently only works on the ESP32 due to the large memory requirements of opusfile. PRs to rewrite it to be less memory intensive would be much appreciated. +* The MOD and MP3 routines were taken from StellarPlayer and libMAD respectively. +* The software I2S delta-sigma 32x oversampling DAC was my own creation, and sounds quite good if I do say so myself. +* The AAC decode code is from the Helix project and licensed under RealNetwork's RSPL license. For commercial use you're still going to need the usual AAC licensing from [Via Licensing](http://www.via-corp.com/us/en/licensing/aac/overview.html). On the ESP32, AAC-SBR is supported (many webradio stations use this to reduce bandwidth even further). The ESP8266, however, does not support it due to a lack of onboard RAM. +* MIDI decoding comes from a highly ported [MIDITONES](https://github.com/LenShustek/miditones) combined with a massively memory-optimized [TinySoundFont](https://github.com/schellingb/TinySoundFont), see the respective source files for more information. +* Opusis from [Xiph.org](https://xiph.org) with the Xiph license and patent described in src/{opusfile,libggg,libopus}/COPYING. ## Neat Things People Have Done With ESP8266Audio If you have a neat use for this library, [I'd love to hear about it](mailto:earlephilhower@yahoo.com)! -My personal use of the ESP8266Audio library is only to drive a 3D-printed, network-time-setting alarm clock for my kids which can play an MP3 instead of a bell to wake them up, called [Psychoclock](https://github.com/earlephilhower/psychoclock). - -Harald Sattler has built a neat German [word clock with MP3 alarm](http://www.harald-sattler.de/html/mini-wecker.htm). Detailed discussion on the process and models are included. - -Erich Heinemann has developed a Stomper (instrument for playing samples in real-time during a live stage performance) that you can find more info about [here](https://github.com/ErichHeinemann/hman-stomper). - -Dagnall53 has integrated this into a really neat MQTT based model train controller to add sounds to his set. More info is available [here](https://github.com/dagnall53/ESPMQTTRocnetSound), including STL files for 3D printed components! - -JohannesMTC has built a similar project especially for model trains: https://github.com/JohannesMTC/ESP32_MAS - -A neat MQTT-driven ESP8266 light-and-sound device (alarm? toy? who can say!) was built by @CosmicMac, available at https://github.com/CosmicMac/ESParkle - -A very interesting "linear clock" with a stepper motor, NTP time keeping, and configurable recorded chimes with schematics, 3D printer plans, and source code, is now available http://home.kpn.nl/bderogee1980/projects/linear_clock/linear_clock.html +* My personal use of the ESP8266Audio library is only to drive a 3D-printed, network-time-setting alarm clock for my kids which can play an MP3 instead of a bell to wake them up, called [Psychoclock](https://github.com/earlephilhower/psychoclock). +* Harald Sattler has built a neat German [word clock with MP3 alarm](http://www.harald-sattler.de/html/mini-wecker.htm). Detailed discussion on the process and models are included. +* Erich Heinemann has developed a Stomper (instrument for playing samples in real-time during a live stage performance) that you can find more info about [here](https://github.com/ErichHeinemann/hman-stomper). +* Dagnall53 has integrated this into a really neat MQTT based model train controller to add sounds to his set. More info is available [here](https://github.com/dagnall53/ESPMQTTRocnetSound), including STL files for 3D printed components! +* JohannesMTC has built a similar project especially for model trains: https://github.com/JohannesMTC/ESP32_MAS +* A neat MQTT-driven ESP8266 light-and-sound device (alarm? toy? who can say!) was built by @CosmicMac, available at https://github.com/CosmicMac/ESParkle +* A very interesting "linear clock" with a stepper motor, NTP time keeping, and configurable recorded chimes with schematics, 3D printer plans, and source code, is now available https://janderogee.com/projects/linear_clock/linear_clock.htm +* Source and instructions for a gorgeous wooden MP3-playing clock, FM radio and a walkie-talkie using the ESP8266 and AVR microcontrollers is available https://github.com/zduka/mp3-player ## Prerequisites First, make sure you are running the 2.6.3/later or GIT head version of the Arduino libraries for ESP8266, or the latest ESP32 SDK from Espressif. @@ -100,7 +94,7 @@ AudioFileSourcePROGMEM: Reads a file from a PROGMEM array. Under UNIX you can AudioFileSourceHTTPStream: Simple implementation of a streaming HTTP reader for ShoutCast-type MP3 streaming. Not yet resilient, and at 44.1khz 128bit stutters due to CPU limitations, but it works more or less. ## AudioFileSourceBuffer - Double buffering, useful for HTTP streams -AudioFileSourceBuffer is an input source that simpy adds an additional RAM buffer of the output of any other AudioFileSource. This is particularly useful for web streaming where you need to have 1-2 packets in memory to ensure hiccup-free playback. +AudioFileSourceBuffer is an input source that simply adds an additional RAM buffer of the output of any other AudioFileSource. This is particularly useful for web streaming where you need to have 1-2 packets in memory to ensure hiccup-free playback. Create your standard input file source, create the buffer with the original source as its input, and pass this buffer object to the generator. ```cpp @@ -145,7 +139,7 @@ AudioGeneratorRTTTL: Enjoy the pleasures of monophonic, 4-octave ringtones on y ## AudioOutput classes AudioOutput: Base class for all output drivers. Takes a sample at a time and returns true/false if there is buffer space for it. If it returns false, it is the calling object's (AudioGenerator's) job to keep the data that didn't fit and try again later. -AudioOutputI2S: Interface for any I2S 16-bit DAC. Sends stereo or mono signals out at whatever frequency set. Tested with Adafruit's I2SDAC and a Beyond9032 DAC from eBay. Tested up to 44.1KHz. To use the internal DAC on ESP32, instantiate this class as `AudioOutputI2S(0,1)`, see example `PlayMODFromPROGMEMToDAC` and code in [AudioOutputI2S.cpp](src/AudioOutputI2S.cpp#L29) for details. +AudioOutputI2S: Interface for any I2S 16-bit DAC. Sends stereo or mono signals out at whatever frequency set. Tested with Adafruit's I2SDAC and a Beyond9032 DAC from eBay. Tested up to 44.1KHz. To use the internal DAC on ESP32, instantiate this class as `AudioOutputI2S(0,AudioOutputI2S::INTERNAL_DAC)`, see example `PlayMODFromPROGMEMToDAC` and code in [AudioOutputI2S.cpp](src/AudioOutputI2S.cpp#L29) for details. To use the hardware Pulse Density Modulation (PDM) on ESP32, instantiate this class as `AudioOutputI2S(0,AudioOutputI2S::INTERNAL_PDM)`. For both later cases, default output pins are GPIO25 and GPIO26. AudioOutputI2SNoDAC: Abuses the I2S interface to play music without a DAC. Turns it into a 32x (or higher) oversampling delta-sigma DAC. Use the schematic below to drive a speaker or headphone from the I2STx pin (i.e. Rx). Note that with this interface, depending on the transistor used, you may need to disconnect the Rx pin from the driver to perform serial uploads. Mono-only output, of course. @@ -158,7 +152,15 @@ AudioOutputSPIFFSWAV: Writes a binary WAV format with headers to a SPIFFS files AudioOutputNull: Just dumps samples to /dev/null. Used for speed testing as it doesn't artificially limit the AudioGenerator output speed since there are no buffers to fill/drain. ## I2S DACs -I've used both the Adafruit [I2S +3W amp DAC](https://www.adafruit.com/product/3006) and a generic PCM5102 based DAC with success. The biggest problems I've seen from users involve pinouts from the ESP8266 for GPIO and hooking up all necessary pins on the DAC board. +I've used both the Adafruit [I2S +3W amp DAC](https://www.adafruit.com/product/3006) and a generic PCM5102 based DAC with success. The biggest problems I've seen from users involve pinouts from the ESP8266 for GPIO and hooking up all necessary pins on the DAC board. The essential pins are: + +I2S pin | Common label* | ESP8266 pin +--------|---------------|------------- +LRC | D4 | GPIO2 +BCLK | D8 | GPIO15 +DIN | RX | GPIO3 + +\* The "common label" column applies to common NodeMCU and D1 Mini development boards. Unfortunately some manufacturers use different mappings so the labels listed here might not apply to your particular model. ### Adafruit I2S DAC This is quite simple and only needs the GND, VIN, LRC, BCLK< and DIN pins to be wired. Be sure to use +5V on the VIN to get the loudest sound. See the [Adafruit example page](https://learn.adafruit.com/adafruit-max98357-i2s-class-d-mono-amp) for more info. @@ -171,7 +173,7 @@ I've used several versions of PCM5102 DAC boards purchased from eBay. They've a ### Others -There are many other variants out there, and they should all work reasonably well with this code and the ESP8266. Please be certain you've read the datasheet and are applying proper input voltages, and be sure to tie off any unused inputs to GND or VCC as appropriate. LEaving an input pin floating on any integrated circuit can cause unstable operation as it may pick up noise from the environment (very low input capacitance) and cause havoc with internal IC settings. +There are many other variants out there, and they should all work reasonably well with this code and the ESP8266. Please be certain you've read the datasheet and are applying proper input voltages, and be sure to tie off any unused inputs to GND or VCC as appropriate. Leaving an input pin floating on any integrated circuit can cause unstable operation as it may pick up noise from the environment (very low input capacitance) and cause havoc with internal IC settings. ## Software I2S Delta-Sigma DAC (i.e. playing music with a single transistor and speaker) For the best fidelity, and stereo to boot, spend the money on a real I2S DAC. Adafruit makes a great mono one with amplifier, and you can find stereo unamplified ones on eBay or elsewhere quite cheaply. However, thanks to the software delta-sigma DAC with 32x oversampling (up to 128x if the audio rate is low enough) you can still have pretty good sound! @@ -189,7 +191,8 @@ Use the `AudioOutputI2S*No*DAC` object instead of the `AudioOutputI2S` in your c ESP8266-GND ------------------+ | +------+ K| | | | E| ESP8266-I2SOUT (Rx) -----/\/\/\--+ | \ R| - | +-| +or ESP32 DOUT pin | +-| + | USB 5V -----------------------------+ You may also want to add a 220uF cap from USB5V to GND just to help filter out any voltage droop during high volume playback. @@ -202,11 +205,18 @@ ESP8266-RX(I2S tx) -- Resistor (~1K ohm, not critical) -- 2N3904 Base ESP8266-GND -- 2N3904 Emitter USB-5V -- Speaker + Terminal 2N3904-Collector -- Speaker - Terminal + +*For ESP32, default output pin is GPIO22. Note that GPIO25 ang GPIO26 are occupied by wclk/bclk and can not be used. ``` *NOTE*: A prior version of this schematic had a direct connection from the ESP8266 to the base of the transistor. While this does provide the maximum amplitude, it also can draw more current from the 8266 than is safe, and can also cause the transistor to overheat. -As of the latest ESP8266Audio release, with the software delta-sigma DAC the LRCLK and BCLK pins *can* be used by an application. Simply use normal `pinMode` and `dicitalWrite` or `digitalRead` as desired. +As of the latest ESP8266Audio release, with the software delta-sigma DAC the LRCLK and BCLK pins *can* be used by an application. Simply use normal `pinMode` and `digitalWrite` or `digitalRead` as desired. + +### Hardware PDM on ESP32 + +Hardware PDM outputs 128 * 48Khz pulses regardless of sample rate. +It seems that currently hardware PDM either does not output constant One at maximum sample level, or does not output 3.3V voltage at pulse sound is not as loud as desired. You may consider using software delta-sigma DAC instead. ### High pitched buzzing with the 1-T circuit The 1-T amp can _NOT_ drive any sort of amplified speaker. If there is a power or USB input to the speaker, or it has lights or Bluetooth or a battery, it can _NOT_ be used with this circuit. @@ -227,6 +237,13 @@ If you've built the amp but are not getting any sound, @msmcmickey wrote up a ve 2. If connected properly, do you have ~5 volts between the collector and emitter? 3. Was the transistor possibly damaged/overheated during soldering, or by connecting it improperly? Out-of-circuit diode check voltage drop test using a multimeter from base->emitter and base->collector should be between .5 and .7 volts. If it's shorted or open or conducting in both directions, then replace it and make sure it's connected properly. +### User-Submitted Improvements for 1-Bit Output Modes (Sigma-Delta I2S, PDM) + +To improve the quality of the output, a 20kHZ low pass filter (LPF) was suggested by @kimstik +![LPF Schematic](images/lpf.png) + +@MarianoSys provided a small amplification circuit that minimizes power draw when idle and provides some visual feedback, described in his [PDF](images/PWM%20audio%20amplifier%20with%20only%201%20transistor,%20power=0%20when%20RX%20signal%20is%20idle%20(high).pdf) + ## SPDIF optical output The proper way would be using optical TOSLINK transmitter (i.e. TOTXxxx). For testing, you can try with ~660nm red LED and resistor. Same as your basic Blink project with external LED, just that the LED will blink a bit faster. ``` @@ -239,7 +256,7 @@ ESP Pin -------|____|--------+ | Ground ---------------------+ ``` -For ESP8266 with red LED (~1.9Vf drop) you need minimum 150Ohm resistor (12mA max per pin), and output pin is fixed (GPIO3/RX0).On ESP32 it is confgurable with `AudioOutputSPDIF(gpio_num)`. +For ESP8266 with red LED (~1.9Vf drop) you need minimum 150Ohm resistor (12mA max per pin), and output pin is fixed (GPIO3/RX0).On ESP32 it is configurable with `AudioOutputSPDIF(gpio_num)`. ## Using external SPI RAM to increase buffer A class allows you to use a 23lc1024 SPI RAM from Microchip as input buffer. This chip connects to ESP8266 HSPI port and provides a large buffer to help avoid hiccus in playback of web streams. @@ -255,10 +272,11 @@ I've been told the Wemos SD card shield uses GPIO15 as the SD chip select. This There's no ESP8266-specific code in the AudioGenerator routines, so porting to other controllers should be relatively easy assuming they have the same endianness as the Xtensa core used. Drop me a line if you're doing this, I may be able to help point you in the right direction. ## Thanks -Thanks to the authors of StellaPlayer and libMAD for releasing their code freely, and to the maintainers and contributors to the ESP8266 Arduino port. +Thanks to the authors of StellarPlayer and libMAD for releasing their code freely, and to the maintainers and contributors to the ESP8266 Arduino port. Also, big thanks to @tueddy for getting the initial ESP32 porting into the tree! -Earle F. Philhower, III + earlephilhower@yahoo.com diff --git a/examples/MixerSample/MixerSample.ino b/examples/MixerSample/MixerSample.ino index 7a9a1e20..4265520b 100644 --- a/examples/MixerSample/MixerSample.ino +++ b/examples/MixerSample/MixerSample.ino @@ -1,8 +1,8 @@ #include -#ifdef ESP32 - #include +#ifdef ESP8266 +#include #else - #include +#include #endif #include "AudioFileSourcePROGMEM.h" @@ -19,15 +19,14 @@ AudioOutputI2S *out; AudioOutputMixer *mixer; AudioOutputMixerStub *stub[2]; -void setup() -{ - WiFi.mode(WIFI_OFF); +void setup() { + WiFi.mode(WIFI_OFF); Serial.begin(115200); delay(1000); Serial.printf("WAV start\n"); audioLogger = &Serial; - file[0] = new AudioFileSourcePROGMEM( viola, sizeof(viola) ); + file[0] = new AudioFileSourcePROGMEM(viola, sizeof(viola)); out = new AudioOutputI2S(); mixer = new AudioOutputMixer(32, out); stub[0] = mixer->NewInput(); @@ -38,31 +37,38 @@ void setup() Serial.printf("starting 1\n"); } -void loop() -{ +void loop() { static uint32_t start = 0; static bool go = false; - - if (!start) start = millis(); + + if (!start) { + start = millis(); + } if (wav[0]->isRunning()) { - if (!wav[0]->loop()) { wav[0]->stop(); stub[0]->stop(); Serial.printf("stopping 1\n"); } + if (!wav[0]->loop()) { + wav[0]->stop(); + stub[0]->stop(); + Serial.printf("stopping 1\n"); + } } - if (millis()-start > 3000) { + if (millis() - start > 3000) { if (!go) { Serial.printf("starting 2\n"); stub[1] = mixer->NewInput(); stub[1]->SetGain(0.4); wav[1] = new AudioGeneratorWAV(); - file[1] = new AudioFileSourcePROGMEM( viola, sizeof(viola) ); + file[1] = new AudioFileSourcePROGMEM(viola, sizeof(viola)); wav[1]->begin(file[1], stub[1]); go = true; } if (wav[1]->isRunning()) { - if (!wav[1]->loop()) { wav[1]->stop(); stub[1]->stop(); Serial.printf("stopping 2\n");} + if (!wav[1]->loop()) { + wav[1]->stop(); + stub[1]->stop(); + Serial.printf("stopping 2\n"); + } } } - } - diff --git a/examples/PlayAACFromPROGMEM/PlayAACFromPROGMEM.ino b/examples/PlayAACFromPROGMEM/PlayAACFromPROGMEM.ino index af7f9087..a4a03690 100644 --- a/examples/PlayAACFromPROGMEM/PlayAACFromPROGMEM.ino +++ b/examples/PlayAACFromPROGMEM/PlayAACFromPROGMEM.ino @@ -8,8 +8,7 @@ AudioFileSourcePROGMEM *in; AudioGeneratorAAC *aac; AudioOutputI2S *out; -void setup() -{ +void setup() { Serial.begin(115200); audioLogger = &Serial; @@ -20,9 +19,7 @@ void setup() aac->begin(in, out); } - -void loop() -{ +void loop() { if (aac->isRunning()) { aac->loop(); } else { @@ -30,4 +27,3 @@ void loop() delay(1000); } } - diff --git a/examples/PlayFLAC-SD-SPDIF/PlayFLAC-SD-SPDIF.ino b/examples/PlayFLAC-SD-SPDIF/PlayFLAC-SD-SPDIF.ino index 3c127883..8c0629da 100644 --- a/examples/PlayFLAC-SD-SPDIF/PlayFLAC-SD-SPDIF.ino +++ b/examples/PlayFLAC-SD-SPDIF/PlayFLAC-SD-SPDIF.ino @@ -1,21 +1,25 @@ #include +#ifdef ARDUINO_ARCH_RP2040 +void setup() {} +void loop() {} +#else #include "AudioFileSourceSD.h" #include "AudioOutputSPDIF.h" #include "AudioGeneratorFLAC.h" // For this sketch, you need connected SD card with '.flac' music files in the root -// directory. Some samples with various sampling rates are available from i.e. +// directory. Some samples with various sampling rates are available from i.e. // Espressif Audio Development Framework at: // https://docs.espressif.com/projects/esp-adf/en/latest/design-guide/audio-samples.html // -// On ESP8266 you might need to reencode FLAC files with max '-2' compression level -// (i.e. 1152 maximum block size) or you will run out of memory. FLAC files will be +// On ESP8266 you might need to re-encode FLAC files with max '-2' compression level +// (i.e. 1152 maximum block size) or you will run out of memory. FLAC files will be // slightly bigger but you don't loose audio quality with reencoding (lossles codec). // You may need a fast SD card. Set this as high as it will work (40MHz max). #define SPI_SPEED SD_SCK_MHZ(40) -// On ESP32 you can adjust the SPDIF_OUT_PIN (GPIO number). +// On ESP32 you can adjust the SPDIF_OUT_PIN (GPIO number). // On ESP8266 it is fixed to GPIO3/RX0 and this setting has no effect #define SPDIF_OUT_PIN 27 @@ -29,40 +33,44 @@ void setup() { Serial.println(); delay(1000); - audioLogger = &Serial; + audioLogger = &Serial; source = new AudioFileSourceSD(); output = new AudioOutputSPDIF(SPDIF_OUT_PIN); decoder = new AudioGeneratorFLAC(); - // NOTE: SD.begin(...) should be called AFTER AudioOutputSPDIF() + // NOTE: SD.begin(...) should be called AFTER AudioOutputSPDIF() // to takover the the SPI pins if they share some with I2S // (i.e. D8 on Wemos D1 mini is both I2S BCK and SPI SS) - #if defined(ESP8266) - SD.begin(SS, SPI_SPEED); - #else - SD.begin(); - #endif - dir = SD.open("/"); +#if defined(ESP8266) + SD.begin(SS, SPI_SPEED); +#else + SD.begin(); +#endif + dir = SD.open("/"); } void loop() { if ((decoder) && (decoder->isRunning())) { - if (!decoder->loop()) decoder->stop(); + if (!decoder->loop()) { + decoder->stop(); + } } else { File file = dir.openNextFile(); - if (file) { + if (file) { if (String(file.name()).endsWith(".flac")) { source->close(); - if (source->open(file.name())) { + if (source->open(file.name())) { Serial.printf_P(PSTR("Playing '%s' from SD card...\n"), file.name()); decoder->begin(source, output); } else { Serial.printf_P(PSTR("Error opening '%s'\n"), file.name()); } - } + } } else { - Serial.println(F("Playback form SD card done\n")); + Serial.println(F("Playback from SD card done\n")); delay(1000); - } + } } } +#endif + diff --git a/examples/PlayFLACFromPROGMEMToDAC/PlayFLACFromPROGMEMToDAC.ino b/examples/PlayFLACFromPROGMEMToDAC/PlayFLACFromPROGMEMToDAC.ino index 847b4d97..177efbe1 100644 --- a/examples/PlayFLACFromPROGMEMToDAC/PlayFLACFromPROGMEMToDAC.ino +++ b/examples/PlayFLACFromPROGMEMToDAC/PlayFLACFromPROGMEMToDAC.ino @@ -9,25 +9,24 @@ AudioOutputI2S *out; AudioFileSourcePROGMEM *file; AudioGeneratorFLAC *flac; -void setup() -{ +void setup() { Serial.begin(115200); Serial.println("Starting up...\n"); audioLogger = &Serial; - file = new AudioFileSourcePROGMEM( sample_flac, sizeof(sample_flac) ); + file = new AudioFileSourcePROGMEM(sample_flac, sizeof(sample_flac)); out = new AudioOutputI2S(); flac = new AudioGeneratorFLAC(); flac->begin(file, out); } -void loop() -{ +void loop() { if (flac->isRunning()) { - if (!flac->loop()) flac->stop(); + if (!flac->loop()) { + flac->stop(); + } } else { Serial.printf("FLAC done\n"); delay(1000); } } - diff --git a/examples/PlayMIDIFromLittleFS/PlayMIDIFromLittleFS.ino b/examples/PlayMIDIFromLittleFS/PlayMIDIFromLittleFS.ino index b4f02e3c..1f374ef8 100644 --- a/examples/PlayMIDIFromLittleFS/PlayMIDIFromLittleFS.ino +++ b/examples/PlayMIDIFromLittleFS/PlayMIDIFromLittleFS.ino @@ -1,12 +1,14 @@ -#include -#ifdef ESP32 - void setup() { - Serial.begin(115200); - Serial.printf("ERROR - ESP32 does not support LittleFS\n"); - } - void loop() {} +#if (defined(ESP32) && (__GNUC__ >= 8) && (__XTENSA__)) +// GCC compiler bug for the Xtensa ESP32s, no MIDI for you. :( +void setup() {} +void loop() {} #else +#include +#ifdef ESP8266 #include +#else +#include +#endif #include #include #include @@ -16,12 +18,11 @@ AudioFileSourceLittleFS *mid; AudioOutputI2S *dac; AudioGeneratorMIDI *midi; -void setup() -{ +void setup() { const char *soundfont = "/1mgm.sf2"; const char *midifile = "/furelise.mid"; - WiFi.mode(WIFI_OFF); + WiFi.mode(WIFI_OFF); Serial.begin(115200); Serial.println("Starting up...\n"); @@ -29,7 +30,7 @@ void setup() audioLogger = &Serial; sf2 = new AudioFileSourceLittleFS(soundfont); mid = new AudioFileSourceLittleFS(midifile); - + dac = new AudioOutputI2S(); midi = new AudioGeneratorMIDI(); midi->SetSoundfont(sf2); @@ -38,11 +39,9 @@ void setup() midi->begin(mid, dac); } -void loop() -{ +void loop() { if (midi->isRunning()) { if (!midi->loop()) { - uint32_t e = millis(); midi->stop(); } } else { diff --git a/examples/PlayMIDIFromSPIFFS/PlayMIDIFromSPIFFS.ino b/examples/PlayMIDIFromSPIFFS/PlayMIDIFromSPIFFS.ino index dcfa8f98..d0a311f6 100644 --- a/examples/PlayMIDIFromSPIFFS/PlayMIDIFromSPIFFS.ino +++ b/examples/PlayMIDIFromSPIFFS/PlayMIDIFromSPIFFS.ino @@ -1,9 +1,16 @@ #include + +// Do not build on Espressif GCC8+, compiler bug + +#if defined(ARDUINO_ARCH_RP2040) || (defined(ESP32) && (__GNUC__ >= 8) && (__XTENSA__)) +void setup() {} +void loop() {} +#else #ifdef ESP32 - #include - #include "SPIFFS.h" +#include +#include "SPIFFS.h" #else - #include +#include #endif @@ -17,20 +24,20 @@ AudioFileSourceSPIFFS *mid; AudioOutputI2S *dac; AudioGeneratorMIDI *midi; -void setup() -{ +void setup() { const char *soundfont = "/1mgm.sf2"; const char *midifile = "/furelise.mid"; - WiFi.mode(WIFI_OFF); + WiFi.mode(WIFI_OFF); Serial.begin(115200); + SPIFFS.begin(); Serial.println("Starting up...\n"); audioLogger = &Serial; sf2 = new AudioFileSourceSPIFFS(soundfont); mid = new AudioFileSourceSPIFFS(midifile); - + dac = new AudioOutputI2S(); midi = new AudioGeneratorMIDI(); midi->SetSoundfont(sf2); @@ -39,11 +46,9 @@ void setup() midi->begin(mid, dac); } -void loop() -{ +void loop() { if (midi->isRunning()) { if (!midi->loop()) { - uint32_t e = millis(); midi->stop(); } } else { @@ -52,4 +57,4 @@ void loop() } } - +#endif diff --git a/examples/PlayMODFromPROGMEMToDAC/PlayMODFromPROGMEMToDAC.ino b/examples/PlayMODFromPROGMEMToDAC/PlayMODFromPROGMEMToDAC.ino index 44aac59e..6792925a 100644 --- a/examples/PlayMODFromPROGMEMToDAC/PlayMODFromPROGMEMToDAC.ino +++ b/examples/PlayMODFromPROGMEMToDAC/PlayMODFromPROGMEMToDAC.ino @@ -2,10 +2,11 @@ #include "AudioFileSourcePROGMEM.h" #include "AudioGeneratorMOD.h" #include "AudioOutputI2S.h" -#ifdef ESP32 - #include + +#ifdef ESP8266 +#include #else - #include +#include #endif // enigma.mod sample from the mod archive: https://modarchive.org/index.php?request=view_by_moduleid&query=42146 @@ -15,30 +16,29 @@ AudioGeneratorMOD *mod; AudioFileSourcePROGMEM *file; AudioOutputI2S *out; -void setup() -{ +void setup() { WiFi.mode(WIFI_OFF); //WiFi.forceSleepBegin(); Serial.begin(115200); delay(1000); audioLogger = &Serial; - file = new AudioFileSourcePROGMEM( enigma_mod, sizeof(enigma_mod) ); + file = new AudioFileSourcePROGMEM(enigma_mod, sizeof(enigma_mod)); // out = new AudioOutputI2S(0, 1); Uncomment this line, comment the next one to use the internal DAC channel 1 (pin25) on ESP32 out = new AudioOutputI2S(); mod = new AudioGeneratorMOD(); - mod->SetBufferSize(3*1024); + mod->SetBufferSize(3 * 1024); mod->SetSampleRate(44100); mod->SetStereoSeparation(32); mod->begin(file, out); } -void loop() -{ +void loop() { if (mod->isRunning()) { - if (!mod->loop()) mod->stop(); + if (!mod->loop()) { + mod->stop(); + } } else { Serial.printf("MOD done\n"); delay(1000); } } - diff --git a/examples/PlayMODFromPROGMEMToPWM/5steps.h b/examples/PlayMODFromPROGMEMToPWM/5steps.h new file mode 100644 index 00000000..312e4efa --- /dev/null +++ b/examples/PlayMODFromPROGMEMToPWM/5steps.h @@ -0,0 +1,11253 @@ +const unsigned char steps_mod[] = { + 0x35, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x20, 0x76, 0x69, + 0x6e, 0x6e, 0x69, 0x65, 0x2f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x62, 0x61, + 0x6c, 0x6c, 0x73, 0x20, 0x20, 0x00, 0x03, 0xed, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xd1, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe1, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x01, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x20, 0x6d, + 0x65, 0x3a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, + 0x05, 0xf4, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x20, 0x70, 0x61, 0x61, + 0x6c, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x75, 0x6d, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x06, 0x6a, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x01, 0x20, 0x67, 0x65, 0x6f, 0x72, 0x67, 0x20, 0x73, 0x74, 0x61, + 0x6e, 0x67, 0x73, 0x20, 0x67, 0x74, 0x20, 0x36, 0x20, 0x20, 0x20, 0x00, + 0x03, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x20, 0x31, 0x37, 0x37, + 0x37, 0x20, 0x68, 0x61, 0x6c, 0x64, 0x65, 0x6e, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x06, 0x52, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x01, 0x20, 0x6e, 0x6f, 0x72, 0x77, 0x61, 0x79, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, + 0x05, 0xef, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x30, 0x0c, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1c, 0x01, 0x00, 0x40, 0x00, 0x01, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x50, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1e, 0x61, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x93, 0x00, 0x40, 0x04, 0x08, + 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x70, 0x00, 0x40, 0x00, 0x63, 0x02, 0xf6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xd0, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xcc, 0x00, 0x40, 0x00, 0xc2, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x20, 0x05, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x40, 0x0c, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x22, 0x7f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x10, 0x10, 0x00, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1b, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4d, 0x2e, 0x4b, 0x2e, 0x00, 0xd6, 0x5c, 0x00, 0x00, 0x00, 0x0f, 0x0f, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0a, 0x10, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x0e, 0x92, 0x00, 0xf0, 0x9c, 0x00, 0x00, 0x00, 0x0f, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x5c, 0x28, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0f, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x5c, 0x10, 0x00, 0xa0, 0x5c, 0x05, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0xa0, 0x5c, 0x10, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x5c, 0x06, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4c, 0x20, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xdc, 0x20, + 0x00, 0xbe, 0xbc, 0x20, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x08, 0x00, 0x00, 0x0c, 0x0a, + 0x00, 0x00, 0x0c, 0x0a, 0x00, 0x00, 0x0c, 0x0a, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xbc, 0x13, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x7c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xac, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x0e, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x08, + 0x00, 0xe2, 0x9c, 0x08, 0x01, 0x53, 0xac, 0x00, 0x10, 0xd6, 0x0c, 0x20, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0xd6, 0x03, 0x03, 0x00, 0x00, 0x0a, 0x10, + 0x01, 0xac, 0xfc, 0x11, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x04, 0xe2, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0e, 0xa2, 0x10, 0xd6, 0x0c, 0x10, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0e, 0xa2, + 0x01, 0xac, 0xec, 0x10, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x0e, 0xa2, + 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x7f, 0x7c, 0x20, + 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0e, 0xa2, + 0x00, 0xd6, 0x0e, 0xc1, 0x00, 0xa0, 0x1f, 0x08, 0x00, 0x00, 0x0e, 0xa2, + 0x00, 0x00, 0x0e, 0xa2, 0x10, 0xd6, 0x0c, 0x20, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0e, 0xa2, + 0x10, 0xd6, 0x0c, 0x20, 0x00, 0xa0, 0x6c, 0x10, 0x00, 0x00, 0x0e, 0xa2, + 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0e, 0xa2, 0x10, 0xd6, 0x0c, 0x10, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0e, 0xa2, + 0x00, 0xf0, 0xdc, 0x20, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x0e, 0xa2, + 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xa0, 0xbc, 0x30, + 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0e, 0xa2, 0x00, 0xf0, 0xec, 0x10, + 0x00, 0xa0, 0x1f, 0x08, 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0e, 0xa2, + 0x10, 0xd6, 0x0a, 0x04, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x0e, 0xa2, + 0x00, 0x00, 0x0e, 0xa2, 0x00, 0xd6, 0x0e, 0xc2, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0e, 0xa2, + 0x10, 0xd6, 0x0c, 0x20, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x0e, 0xa2, + 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xa0, 0x5c, 0x10, + 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0e, 0xa2, 0x01, 0xe0, 0xfc, 0x10, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x02, 0x01, + 0x00, 0x00, 0x02, 0x01, 0x10, 0xd6, 0x0c, 0x20, 0x00, 0xa0, 0x1f, 0x08, + 0x00, 0xd6, 0x09, 0x05, 0x01, 0x53, 0x09, 0x05, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x10, 0xd6, 0x0c, 0x10, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb2, 0x00, 0xd6, 0xec, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x02, 0x00, 0x00, 0x0e, 0xb1, 0x01, 0xac, 0x03, 0xf0, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0xe2, 0x03, 0xf0, 0x01, 0x68, 0x03, 0xf9, + 0x01, 0x40, 0x01, 0x01, 0x00, 0xa0, 0x5c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x02, 0x01, 0x40, 0x03, 0x03, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb2, 0x01, 0x53, 0xec, 0x11, + 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x08, 0x00, 0xfe, 0x99, 0x03, + 0x01, 0x7d, 0xac, 0x20, 0x10, 0xf0, 0x0c, 0x20, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0xf0, 0x03, 0xf0, 0x00, 0x00, 0x0e, 0x11, 0x00, 0x00, 0x04, 0xe1, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe2, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0xf0, 0xfc, 0x21, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x0e, 0xb1, 0x10, 0xf0, 0x0c, 0x10, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0xf0, 0xdc, 0x10, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x5c, 0x20, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x0e, 0xb1, 0x01, 0x68, 0xec, 0x10, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x0e, 0xb1, + 0x10, 0xf0, 0x0c, 0x20, 0x00, 0xa0, 0xbc, 0x20, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x20, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7c, 0x20, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0x00, 0x0e, 0xb1, 0x10, 0xf0, 0x0c, 0x20, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x0e, 0xb0, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0xa0, 0x1c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xf0, 0x0c, 0x20, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x6c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xf0, 0x0c, 0x20, 0x00, 0xa0, 0x5c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xf0, 0x0c, 0x20, 0x00, 0xa0, 0x1f, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xf0, 0x0c, 0x30, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0xd6, 0x50, 0x00, 0x00, 0x00, 0x0a, 0x02, + 0x00, 0x00, 0x0a, 0x02, 0x00, 0xf0, 0xfc, 0x20, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0xe2, 0x03, 0xd0, 0x01, 0x68, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0x5c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xf0, 0x0c, 0x20, 0x00, 0x7f, 0x7c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x03, 0xf0, 0x00, 0xd6, 0x5c, 0x30, + 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0xa0, 0x1f, 0x08, 0x00, 0xe2, 0x9c, 0x20, 0x01, 0x53, 0xac, 0x18, + 0x10, 0xd6, 0x0c, 0x30, 0x00, 0xa0, 0x60, 0x00, 0x00, 0xd6, 0x03, 0x00, + 0x00, 0x00, 0x0a, 0x01, 0x01, 0xac, 0xfc, 0x1f, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0xac, 0xec, 0x10, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0xac, 0x03, 0xd0, 0x00, 0xa0, 0x8c, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xd6, 0xec, 0x0f, + 0x00, 0x7f, 0x7c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x0a, 0x20, 0x00, 0xa0, 0x8c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0a, 0x20, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0xac, 0xec, 0x30, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x68, 0xec, 0x10, 0x00, 0xa0, 0x6c, 0x10, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x01, 0xac, 0x0e, 0xc1, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0x40, 0xdc, 0x30, 0x00, 0xa0, 0x8c, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x2e, 0x03, 0x06, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x68, 0xdc, 0x10, + 0x00, 0xa0, 0xbc, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x10, 0xd6, 0x04, 0xe4, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x04, 0xe8, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x01, 0xac, 0xea, 0x0f, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xd6, 0xdc, 0x1f, 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xf0, 0xec, 0x10, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0a, 0x20, + 0x00, 0xa0, 0x8c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xd6, 0x03, 0xf0, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x0f, 0x00, 0xd6, 0x3c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0xd6, 0x03, 0x07, 0x01, 0x53, 0x03, 0x0f, + 0x00, 0xd6, 0xdc, 0x30, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0xda, 0x0f, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0xde, 0xc1, 0x00, 0xa0, 0x80, 0x00, 0x00, 0xe2, 0x03, 0xf0, + 0x01, 0x68, 0x03, 0x02, 0x00, 0xe2, 0xdc, 0x21, 0x00, 0xaa, 0x5c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x04, 0xe8, + 0x00, 0xaa, 0x5c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb2, + 0x00, 0x00, 0x04, 0xed, 0x00, 0xa0, 0x8c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb2, 0x00, 0x00, 0x02, 0x0f, 0x00, 0xa0, 0x1f, 0x08, + 0x00, 0xfe, 0x09, 0x03, 0x01, 0x7d, 0xac, 0x20, 0x00, 0xf0, 0xec, 0x30, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0xf0, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xda, 0x0f, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x0c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xf0, 0x0c, 0x20, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0d, 0xdc, 0x10, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x02, 0x00, 0xa0, 0x8c, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xdc, 0x10, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0e, 0xc1, + 0x00, 0xd6, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x0d, 0xec, 0x10, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xec, 0x10, 0x00, 0xa0, 0xbc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x30, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe8, 0x00, 0xa0, 0x1c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xec, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0xa0, 0x8c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x01, 0x40, 0xec, 0x10, 0x00, 0xa0, 0x1c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x01, 0x0d, 0xec, 0x20, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0xf0, 0xdc, 0x10, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x01, 0xe0, 0xec, 0x20, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0xf0, 0xdc, 0x20, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0xa0, 0x6c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x0a, 0x50, 0x00, 0xa0, 0x8c, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x78, 0x0a, 0x0f, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x0a, 0x02, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x87, 0xdc, 0x10, 0x00, 0xa0, 0x1f, 0x08, + 0x00, 0x00, 0x9c, 0x20, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xbc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x01, 0xe0, 0xfc, 0x2f, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x10, + 0x00, 0x00, 0x0a, 0x01, 0x00, 0xb4, 0xac, 0x05, 0x00, 0xf0, 0xdc, 0x26, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0xe2, 0x03, 0xf0, 0x00, 0x00, 0x0a, 0x10, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0xa0, 0x5c, 0x09, 0x00, 0x00, 0x0a, 0x01, + 0x00, 0x00, 0x0a, 0x10, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x0a, 0x10, 0x10, 0x87, 0x0c, 0x10, + 0x00, 0xbe, 0x4c, 0x10, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0a, 0x10, + 0x01, 0xc5, 0xfc, 0x20, 0x00, 0xa0, 0xcf, 0x08, 0x00, 0xe2, 0x9c, 0x20, + 0x00, 0xaa, 0xac, 0x30, 0x01, 0xac, 0xdc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0x03, 0x03, 0x00, 0x00, 0x0a, 0x03, 0x10, 0xd6, 0x0c, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xf0, 0xdc, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x10, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0xac, 0xfc, 0x30, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x0a, 0x10, 0x10, 0xd6, 0x0c, 0x20, + 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x0a, 0x10, + 0x00, 0xd6, 0xec, 0x0f, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x0a, 0x10, + 0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x0a, 0x20, 0x00, 0xbe, 0xbc, 0x30, + 0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0a, 0x60, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0xd6, 0x3c, 0x20, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xf0, 0xdc, 0x20, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x1d, 0xdc, 0x1a, + 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0xac, 0x0e, 0xc1, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x40, 0xdc, 0x30, 0x00, 0xbe, 0xbc, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x40, 0x03, 0x36, + 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0x68, 0xdc, 0x18, 0x00, 0xbe, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x10, 0xd6, 0x0c, 0x30, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x04, 0x03, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0xac, 0xea, 0x0f, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0xac, 0xfc, 0x2f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xf0, 0xec, 0x10, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x0a, 0x20, 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xd6, 0x03, 0xf0, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xd6, 0xdc, 0x30, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0xda, 0x0f, + 0x00, 0xbe, 0x4c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb2, 0x00, 0x00, 0xde, 0xc1, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0xe2, 0x03, 0xf0, 0x00, 0xb4, 0x03, 0xf2, 0x00, 0xe2, 0xdc, 0x21, + 0x00, 0xbe, 0xbc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb2, + 0x00, 0x00, 0x04, 0xe8, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb2, 0x00, 0x00, 0x04, 0xed, 0x00, 0x7f, 0x7c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb2, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0xa0, 0x1f, 0x08, 0x00, 0xfe, 0x90, 0x00, 0x00, 0xbe, 0xac, 0x20, + 0x00, 0xf0, 0xec, 0x30, 0x00, 0xa0, 0xbc, 0x10, 0x00, 0xf0, 0x93, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x09, 0x10, 0x00, 0x7f, 0x7c, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xec, 0x10, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x0d, 0xdc, 0x10, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0x00, 0xbe, 0x4c, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xdc, 0x10, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x0d, 0xec, 0x10, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xec, 0x20, + 0x00, 0xd6, 0x3c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe8, 0x00, 0xd6, 0x3c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xec, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0xbe, 0xbc, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xec, 0x10, 0x00, 0x7f, 0x7c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0d, 0xec, 0x20, + 0x00, 0xbe, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xdc, 0x10, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0xec, 0x20, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xdc, 0x20, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xf0, 0x0c, 0x10, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0xa0, 0x5c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xfc, 0x10, 0x00, 0xa0, 0x0e, 0x93, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xa0, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0xdc, 0x10, + 0x00, 0xa0, 0x1c, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0a, 0x0f, 0x00, 0xbe, 0x4c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xf0, 0x0c, 0x24, + 0x00, 0xaa, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe8, 0x00, 0xbe, 0x40, 0x00, 0x00, 0xe2, 0x03, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0xfc, 0x20, 0x00, 0xbe, 0xbc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0xf0, 0x00, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xfc, 0x20, 0x00, 0xa0, 0xcd, 0x00, 0x00, 0xd6, 0x90, 0x00, + 0x00, 0xaa, 0xac, 0x30, 0x10, 0xd6, 0x04, 0xe4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x03, 0x00, 0x00, 0x04, 0xea, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0a, 0x03, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0xac, 0xfc, 0x30, 0x00, 0x7f, 0x7c, 0x20, + 0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xd6, 0xf0, 0x00, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xd6, 0xfc, 0x10, 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x0a, 0x10, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xd6, 0xea, 0x0f, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0a, 0x20, + 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0xac, 0xfc, 0x30, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x10, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xd6, 0xe2, 0x0f, 0x00, 0xd6, 0x3c, 0x20, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xf0, 0xdc, 0x30, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0x1d, 0xdc, 0x10, 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0xac, 0x0e, 0xc1, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x40, 0xdc, 0x30, + 0x00, 0xbe, 0xbc, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0x40, 0x03, 0x06, 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x68, 0xdc, 0x10, 0x00, 0xbe, 0xbc, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x10, 0xd6, 0x0c, 0x20, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x0c, 0x10, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0xac, 0xea, 0x0f, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xd6, 0xdc, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xf0, 0xec, 0x10, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0a, 0x20, 0x00, 0xbe, 0x4c, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xd6, 0x03, 0xf0, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x0f, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xd6, 0xdc, 0x30, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0xda, 0x0f, 0x00, 0xbe, 0x4c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb2, 0x00, 0x00, 0xde, 0xc1, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0xe2, 0x03, 0xf0, 0x00, 0xb4, 0x0e, 0xb2, + 0x00, 0xe2, 0xdc, 0x21, 0x00, 0xbe, 0xbc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb2, 0x00, 0x00, 0x04, 0xe8, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb2, 0x00, 0x00, 0x04, 0xed, + 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb2, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0xa0, 0x1f, 0x08, 0x00, 0xfe, 0x90, 0x00, + 0x00, 0xbe, 0xac, 0x20, 0x00, 0xf0, 0xec, 0x30, 0x00, 0xa0, 0xbc, 0x10, + 0x00, 0xf0, 0x93, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x09, 0x10, + 0x00, 0x7f, 0x7c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xec, 0x10, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x0d, 0xdc, 0x10, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, + 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xdc, 0x10, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0d, 0xec, 0x10, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xec, 0x20, 0x00, 0xd6, 0x3c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe8, + 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xec, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0xbe, 0xbc, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xec, 0x10, + 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x0d, 0xec, 0x20, 0x00, 0xbe, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xdc, 0x10, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0xec, 0x20, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xdc, 0x20, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x40, 0x00, 0xa0, 0x8c, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0a, 0x0f, 0x00, 0xa0, 0x0e, 0x93, + 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x0a, 0x01, + 0x00, 0x87, 0xdc, 0x10, 0x00, 0xa0, 0x1c, 0x24, 0x00, 0x00, 0x0a, 0x01, + 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x5c, 0x20, + 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x78, 0x0a, 0x0f, + 0x00, 0xa0, 0x8c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x7d, 0xec, 0x10, 0x00, 0xbe, 0x4c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x00, 0xbe, 0x4c, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0xec, 0x40, + 0x00, 0xbe, 0x4c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x53, 0x03, 0x30, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xcf, 0x08, 0x00, 0xaa, 0x9c, 0x30, 0x00, 0xfe, 0xac, 0x30, + 0x01, 0x40, 0xdc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x03, 0x03, + 0x00, 0x00, 0x0a, 0x01, 0x10, 0xa0, 0x0c, 0x1f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x68, 0xfc, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xa0, 0xdc, 0x20, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xbe, 0x4c, 0x08, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xa0, 0xec, 0x0f, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x0a, 0x20, 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0a, 0x60, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0xd6, 0x3c, 0x20, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xb4, 0xdc, 0x20, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x68, 0xfc, 0x30, 0x00, 0xd6, 0x3c, 0x10, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0x68, 0xfc, 0x40, 0x00, 0xbe, 0xbc, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x40, 0xfa, 0x0f, 0x00, 0x7f, 0x7c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x40, 0xdc, 0x20, + 0x00, 0xbe, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0x40, 0xfc, 0x20, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x40, 0xea, 0x0f, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0x40, 0xfc, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xb4, 0xec, 0x10, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0a, 0x20, + 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xa0, 0x03, 0xf0, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x0f, 0x00, 0xbe, 0xbc, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xa0, 0xdc, 0x30, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0xda, 0x0f, 0x00, 0xbe, 0x4c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb2, + 0x00, 0x00, 0xde, 0xc1, 0x00, 0xbe, 0x40, 0x00, 0x00, 0xaa, 0x03, 0xf0, + 0x01, 0x0d, 0x03, 0xf2, 0x00, 0xaa, 0xdc, 0x21, 0x00, 0xbe, 0xbc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb2, 0x00, 0x00, 0x04, 0xe8, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb2, + 0x00, 0x00, 0x04, 0xed, 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb2, 0x00, 0x00, 0x02, 0x0f, 0x00, 0xa0, 0x1f, 0x08, + 0x00, 0xbe, 0x9c, 0x29, 0x01, 0x1d, 0xac, 0x20, 0x00, 0xb4, 0xec, 0x30, + 0x00, 0xa0, 0xbc, 0x10, 0x00, 0xb4, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x68, 0x09, 0x10, 0x00, 0x7f, 0x7c, 0x30, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xec, 0x10, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x02, 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xdc, 0x10, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xec, 0x10, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xec, 0x20, 0x00, 0xd6, 0x3c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe8, 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xec, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0xbe, 0xbc, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xec, 0x10, 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xec, 0x20, 0x00, 0xbe, 0xbc, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xdc, 0x10, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x68, 0xec, 0x20, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xdc, 0x20, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x5c, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0xfc, 0x20, + 0x00, 0xa0, 0x0e, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xd0, 0x00, 0x00, 0xa0, 0x1c, 0x24, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xe2, 0x0f, + 0x00, 0xa0, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xac, 0xfc, 0x20, 0x00, 0xbe, 0x4c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xec, 0x20, 0x00, 0xaa, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xac, 0x05, 0x02, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb4, 0xdc, 0x22, 0x00, 0xbe, 0xbc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x53, 0xf0, 0x00, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb4, 0x0c, 0x20, + 0x00, 0xa0, 0xcd, 0x00, 0x00, 0xaa, 0x9c, 0x30, 0x00, 0xfe, 0xac, 0x30, + 0x10, 0xa0, 0x04, 0xe4, 0x00, 0x00, 0x0f, 0x08, 0x00, 0xa0, 0x03, 0xf3, + 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x04, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0x40, 0xf0, 0x00, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xa0, 0xfc, 0x30, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x10, 0xa0, 0x0c, 0x20, + 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xa0, 0xec, 0x0f, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0a, 0x20, 0x00, 0xbe, 0xbc, 0x30, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0a, 0x60, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0xd6, 0x3c, 0x20, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xb4, 0xdc, 0x20, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x68, 0xfc, 0x30, + 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x68, 0xfc, 0x40, 0x00, 0xbe, 0xbc, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x40, 0xfa, 0x0f, + 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x10, 0xb4, 0x0c, 0x20, 0x00, 0xbe, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x40, 0xfc, 0x20, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0x40, 0xea, 0x0f, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x40, 0xfc, 0x2f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x40, 0xec, 0x20, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xb4, 0xec, 0x30, 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xa0, 0x03, 0xf0, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xa0, 0xdc, 0x20, + 0x00, 0xbe, 0x4c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb2, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb2, 0x00, 0x00, 0xde, 0xc1, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0xaa, 0x03, 0xf0, 0x01, 0x0d, 0x03, 0xf2, 0x00, 0xaa, 0xdc, 0x21, + 0x00, 0xbe, 0xbc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb2, + 0x00, 0x00, 0x04, 0xe8, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb2, 0x00, 0x00, 0x04, 0xed, 0x00, 0x7f, 0x7c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb2, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0xa0, 0x1f, 0x08, 0x00, 0xbe, 0x9c, 0x29, 0x01, 0x1d, 0xac, 0x20, + 0x00, 0xb4, 0xec, 0x30, 0x00, 0xa0, 0xbc, 0x10, 0x00, 0xb4, 0x03, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0x09, 0x10, 0x00, 0x7f, 0x7c, 0x30, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xec, 0x10, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xca, 0xdc, 0x10, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0x00, 0xbe, 0x4c, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xdc, 0x10, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xec, 0x10, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xec, 0x20, + 0x00, 0xd6, 0x3c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x04, 0xe8, 0x00, 0xd6, 0x3c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x04, 0xec, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0xbe, 0xbc, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0xf0, 0xec, 0x10, 0x00, 0x7f, 0x7c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0xca, 0xec, 0x20, + 0x00, 0xbe, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0xb4, 0xdc, 0x10, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x01, 0x68, 0xec, 0x20, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0xb4, 0xdc, 0x20, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x01, 0x68, 0xdc, 0x20, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0xa0, 0x8c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x01, 0x68, 0xec, 0x20, 0x00, 0xa0, 0x0e, 0x93, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x01, 0x40, 0xdc, 0x10, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0xa0, 0x03, 0x30, + 0x00, 0xa0, 0x1c, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x01, 0x53, 0xec, 0x17, 0x00, 0xa0, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0xaa, 0x03, 0xf0, 0x00, 0xa0, 0x8c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x01, 0x68, 0xec, 0x20, + 0x00, 0xbe, 0x4c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0xb4, 0x03, 0xf0, 0x00, 0xbe, 0x4c, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x01, 0x7d, 0xec, 0x1a, 0x00, 0xbe, 0x4c, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0xbe, 0x03, 0xf0, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x01, 0x94, 0xec, 0x1a, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0xca, 0x03, 0xf0, 0x00, 0xa0, 0xc0, 0x00, + 0x00, 0xd6, 0x9f, 0x08, 0x00, 0x00, 0x0a, 0x01, 0x10, 0xd6, 0x04, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x0a, 0x01, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x01, + 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x04, 0x05, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x06, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0xa0, 0x7c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xac, 0xfc, 0x20, 0x00, 0xa0, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x20, + 0x00, 0xa0, 0x8c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, 0x00, 0xa0, 0x8c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0x3c, 0x20, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x10, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xb0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xfc, 0x20, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xd6, 0x0c, 0x30, 0x00, 0xa0, 0x8c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xac, 0xfc, 0x20, 0x00, 0xd6, 0x3c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x5c, 0x00, 0x00, 0xd6, 0x3c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x7c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x20, 0x00, 0xd6, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0e, 0x93, 0x00, 0xd6, 0x3c, 0x10, + 0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x50, 0x00, + 0x00, 0xd6, 0x3c, 0x30, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x5c, 0x20, 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x0a, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x5c, 0x07, 0x00, 0xd6, 0x3c, 0x08, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x5c, 0x10, + 0x00, 0xd6, 0x3c, 0x20, 0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x5c, 0x20, 0x00, 0xd6, 0x3c, 0x28, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x5c, 0x08, 0x00, 0xd6, 0x3c, 0x10, + 0x00, 0x00, 0x0a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x20, + 0x00, 0xa0, 0xc0, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x15, 0x00, 0x00, 0x9a, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x9a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xec, 0x30, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0d, 0x00, 0xd6, 0x3c, 0x08, 0x00, 0x00, 0x9a, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0d, 0x00, 0xd6, 0x3c, 0x10, + 0x00, 0x00, 0x9a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0xac, 0xfc, 0x20, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xd6, 0x0c, 0x20, 0x00, 0x7f, 0x7c, 0x20, 0x00, 0x00, 0x9a, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xac, 0xda, 0x0f, 0x00, 0x7f, 0x2c, 0x06, + 0x00, 0x00, 0x9a, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xdc, 0x20, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xac, 0xec, 0x10, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xe1, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xe3, 0x30, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x68, 0xec, 0x20, 0x00, 0xa0, 0xb0, 0x00, 0x00, 0x00, 0x9a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x9a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10, 0xd6, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0xfc, 0x20, 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xd6, 0x0c, 0x10, 0x00, 0xa0, 0xbc, 0x20, + 0x00, 0x00, 0x9a, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0xac, 0xda, 0x0f, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x9a, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0xec, 0x20, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x9a, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0xbe, 0x4c, 0x10, 0x00, 0x00, 0x9a, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x0a, 0x20, 0x00, 0x00, 0x9a, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, 0x00, 0xbe, 0x0e, 0x93, + 0x00, 0x00, 0x9a, 0x06, 0x11, 0x1d, 0x1c, 0x10, 0x01, 0x68, 0xda, 0x0f, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9a, 0x06, 0x00, 0x00, 0x0c, 0x00, + 0x10, 0xa0, 0x01, 0x02, 0x00, 0xbe, 0x4c, 0x14, 0x00, 0x00, 0x9a, 0x06, + 0x10, 0xf0, 0x1c, 0x12, 0x10, 0xa0, 0x03, 0x02, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x9a, 0x06, 0x00, 0x00, 0x0c, 0x02, 0x10, 0xb4, 0x0c, 0x10, + 0x00, 0xbe, 0x4c, 0x30, 0x00, 0x00, 0x9a, 0x06, 0x10, 0xd6, 0x1c, 0x10, + 0x10, 0xa0, 0x01, 0x02, 0x00, 0xbe, 0x4c, 0x10, 0x00, 0x00, 0x9a, 0x06, + 0x00, 0x00, 0x0c, 0x00, 0x10, 0xa0, 0x03, 0x02, 0x00, 0xa0, 0xc0, 0x00, + 0x00, 0xd6, 0x9f, 0x02, 0x10, 0xca, 0x1c, 0x1a, 0x10, 0xd6, 0x0c, 0x30, + 0x00, 0x00, 0x0f, 0x0a, 0x00, 0x00, 0x04, 0xe1, 0x10, 0xbe, 0x10, 0x00, + 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x0f, 0x04, 0x00, 0x00, 0x04, 0xe1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x01, + 0x00, 0xd6, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x9c, 0x10, 0x00, 0x00, 0x0c, 0x08, 0x10, 0xbe, 0x1c, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x11, 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x99, 0x19, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0xd6, 0x99, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x30, + 0x00, 0x00, 0x94, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x04, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0x3c, 0x20, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xd6, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x9a, 0x04, + 0x10, 0xf0, 0x1c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9a, 0x04, 0x10, 0xbe, 0x10, 0x00, + 0x10, 0xf0, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x0a, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x18, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0xb4, 0x0e, 0xd3, 0x00, 0xd6, 0x03, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x0f, 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x0a, 0x01, 0x10, 0xb4, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0xaa, 0x0e, 0xd2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0xbc, 0x10, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xaa, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0xd6, 0x9c, 0x20, 0x10, 0xaa, 0x1c, 0x15, 0x10, 0xd6, 0x0f, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x10, 0xa0, 0x1c, 0x20, + 0x00, 0x00, 0x0f, 0x06, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x0a, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xfc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x06, 0x10, 0xa0, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x1d, 0xec, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x94, 0xe1, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xd6, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0f, + 0x00, 0xa0, 0x1f, 0x04, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xaa, 0x1c, 0x0a, 0x10, 0xd6, 0x0c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x0f, 0x00, 0xbe, 0x4c, 0x10, 0x00, 0x00, 0x9a, 0x04, + 0x10, 0xb4, 0x1c, 0x14, 0x10, 0xaa, 0x1c, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x0a, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x04, 0x00, 0xa0, 0x03, 0xd3, + 0x00, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xbe, 0x1c, 0x10, 0x00, 0xa0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x20, 0x00, 0x00, 0x9a, 0x04, + 0x10, 0xca, 0x1c, 0x10, 0x00, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x04, 0x10, 0xf0, 0x1c, 0x1a, + 0x00, 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7c, 0x10, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xfe, 0x1c, 0x10, 0x00, 0xf0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x04, 0x00, 0xf0, 0x94, 0xe1, + 0x11, 0x0d, 0x10, 0x00, 0x10, 0xa0, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x04, 0xe1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x9a, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x7c, 0x07, 0x00, 0x00, 0x9a, 0x02, + 0x10, 0xb4, 0x1c, 0x10, 0x01, 0x40, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9c, 0x10, 0x00, 0x00, 0x0c, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x80, + 0x00, 0x00, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4c, 0x08, + 0x00, 0x00, 0x99, 0x19, 0x00, 0x00, 0x0e, 0x11, 0x10, 0xb4, 0x1c, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0xf0, 0x99, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x94, 0xe1, 0x11, 0x0d, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0xa0, 0x1f, 0x04, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb4, 0x0c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x20, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xa0, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x10, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xb4, 0x1c, 0x07, 0x11, 0x0d, 0x1c, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0xbc, 0x18, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xb4, 0x1c, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7c, 0x10, + 0x00, 0x00, 0x9a, 0x04, 0x11, 0x0d, 0x1c, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x10, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xa0, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe3, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0xf0, 0x9c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x68, 0xfc, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xa0, 0x1c, 0x10, 0x01, 0x40, 0xfc, 0x1a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x10, 0x97, 0x1e, 0xd3, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x04, + 0x10, 0x8f, 0x10, 0x00, 0x10, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xa0, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x10, 0x97, 0x1e, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x1c, 0x10, 0x10, 0x8f, 0x1e, 0x11, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x9a, 0x04, + 0x10, 0x87, 0x1c, 0x10, 0x00, 0x00, 0x0c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x04, 0x10, 0x8f, 0x1c, 0x20, + 0x10, 0x87, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xb0, 0x00, + 0x00, 0x00, 0x94, 0xe1, 0x10, 0x97, 0x1c, 0x06, 0x01, 0x68, 0xe0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x04, 0x00, 0x00, 0x04, 0xe4, + 0x10, 0xa0, 0x1c, 0x10, 0x10, 0xb4, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x8f, 0x03, 0xd0, + 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4c, 0x10, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xb4, 0x1c, 0x10, 0x01, 0x68, 0xec, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0xa0, 0x03, 0xf0, 0x10, 0xb4, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9a, 0x04, 0x10, 0xbe, 0x1c, 0x10, + 0x10, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x20, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xf0, 0x1c, 0x08, 0x01, 0x1d, 0xde, 0xc2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x04, + 0x10, 0xd6, 0x1c, 0x10, 0x00, 0xf0, 0xdc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x04, 0x10, 0xca, 0x1c, 0x05, + 0x01, 0xac, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x04, + 0x00, 0xd6, 0x94, 0xe1, 0x10, 0xca, 0x1f, 0x01, 0x10, 0xd6, 0x04, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe1, 0x10, 0xbe, 0x1f, 0x07, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x04, 0xe1, + 0x00, 0x00, 0x0f, 0x04, 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xac, 0xfc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xbe, 0x1c, 0x0a, + 0x00, 0x00, 0x9a, 0x02, 0x11, 0x1d, 0x1c, 0x10, 0x00, 0xd6, 0xfc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9c, 0x10, + 0x00, 0x00, 0x0c, 0x06, 0x11, 0x1d, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x99, 0x19, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0xd6, 0x99, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x94, 0xe1, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xac, 0xfc, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1f, 0x04, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x20, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, 0xf0, 0x1c, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x40, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x0a, 0x30, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x0a, 0x30, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0xbe, 0xbc, 0x18, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0xb4, 0x0e, 0xd3, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, + 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x0a, 0x03, + 0x01, 0x68, 0xec, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0xaa, 0x0e, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x10, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x02, 0x00, 0xd6, 0x9c, 0x20, + 0x10, 0xa0, 0x10, 0x00, 0x10, 0xd6, 0x04, 0xe2, 0x00, 0x00, 0x0f, 0x06, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0xa0, 0x6f, 0x04, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x0e, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x0c, 0x0a, 0x10, 0xa0, 0x1c, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x04, + 0x10, 0xbe, 0x1c, 0x10, 0x00, 0xf0, 0xe4, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0xbe, 0x4c, 0x08, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xca, 0x1c, 0x10, 0x00, 0xd6, 0xe3, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x04, + 0x10, 0xd6, 0x1c, 0x10, 0x00, 0x00, 0x02, 0x1f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1f, + 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x94, 0xe1, 0x10, 0xf0, 0x1c, 0x0a, + 0x01, 0xac, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x02, + 0x00, 0x00, 0x04, 0xe4, 0x10, 0xca, 0x10, 0x00, 0x10, 0xf0, 0x1c, 0x0a, + 0x00, 0x00, 0x0f, 0x06, 0x00, 0x00, 0x04, 0xe8, 0x10, 0xbe, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x6f, 0x04, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x0e, 0x11, 0x10, 0xbe, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x4c, 0x10, 0x00, 0x00, 0x9a, 0x04, 0x10, 0x8f, 0x1c, 0x10, + 0x10, 0xf0, 0x1c, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xbe, 0x1c, 0x10, 0x10, 0x8f, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xbe, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0xbc, 0x20, 0x00, 0x00, 0x9a, 0x04, 0x11, 0x1d, 0x1c, 0x10, + 0x10, 0xd6, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xf0, 0x1c, 0x20, 0x11, 0x1d, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x04, + 0x10, 0xe2, 0x1c, 0x14, 0x10, 0xf0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1f, 0x04, 0x00, 0xf0, 0x94, 0xe1, 0x10, 0xd6, 0x10, 0x00, + 0x10, 0xa0, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, 0x01, 0x40, 0xfc, 0x20, + 0x00, 0x00, 0x04, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xd6, 0x1c, 0x0a, 0x00, 0x00, 0x9a, 0x02, 0x11, 0x40, 0x1c, 0x10, + 0x10, 0xa0, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x9c, 0x10, 0x00, 0x00, 0x0c, 0x04, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x99, 0x19, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xec, 0x1a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0xf0, 0x99, 0x10, 0x10, 0xd6, 0x1c, 0x0a, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0xbe, 0xbc, 0x30, + 0x00, 0x00, 0x94, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xfc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x04, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xa0, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0x3c, 0x20, 0x00, 0x00, 0x9a, 0x04, 0x11, 0x40, 0x1c, 0x0a, + 0x01, 0x40, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0f, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x0c, 0x05, 0x01, 0x68, 0xdc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xa0, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9a, 0x04, 0x10, 0xd6, 0x1c, 0x06, + 0x01, 0x40, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0xbe, 0xbc, 0x18, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xe3, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x03, 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x04, + 0x11, 0x40, 0x1c, 0x10, 0x01, 0x68, 0xec, 0x1a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0xbc, 0x10, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xaa, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe3, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0xfe, 0x9c, 0x20, 0x11, 0x53, 0x10, 0x00, 0x00, 0x00, 0x04, 0xe5, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x53, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xe2, 0x1c, 0x10, 0x01, 0x68, 0xec, 0x12, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, + 0x00, 0xbe, 0x8c, 0x20, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x68, 0xec, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x10, + 0x01, 0x0d, 0x9a, 0x04, 0x11, 0x68, 0x1c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x94, 0xe1, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0xec, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1f, 0x04, 0x00, 0x00, 0x0c, 0x14, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4c, 0x20, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xf0, 0x1c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x01, 0x1d, 0x9a, 0x04, 0x11, 0x7d, 0x1c, 0x13, 0x01, 0x7d, 0xe0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x10, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xbe, 0xc3, 0x00, 0x00, 0x9a, 0x04, 0x10, 0xfe, 0x1c, 0x0a, + 0x10, 0xf0, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc0, 0x00, + 0x10, 0xd6, 0x44, 0xe1, 0x10, 0xbe, 0x1c, 0x1a, 0x10, 0xd6, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe3, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x02, 0x00, 0xa0, 0x60, 0x00, 0x10, 0x00, 0x4c, 0x19, + 0x00, 0x00, 0x01, 0x01, 0x00, 0xd6, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x40, 0x00, 0x10, 0x00, 0x4a, 0x06, 0x00, 0x00, 0x0c, 0x08, + 0x10, 0xbe, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x11, 0x00, 0xbe, 0x4c, 0x08, + 0x10, 0x00, 0x4a, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x09, 0x19, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0xbc, 0x30, 0x10, 0x00, 0x44, 0xe1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x04, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x20, 0x10, 0x00, 0x4a, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xd6, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x7f, 0x2c, 0x20, 0x10, 0x00, 0x4a, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x10, + 0x10, 0x00, 0x4c, 0x20, 0x10, 0xd6, 0x1c, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0xbe, 0x40, 0x00, 0x10, 0x00, 0x4c, 0x1a, + 0x10, 0xbe, 0x10, 0x00, 0x10, 0xf0, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x07, 0x00, 0x00, 0x0a, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0xbc, 0x18, 0x10, 0x00, 0x4c, 0x15, 0x00, 0xb4, 0x0e, 0xd3, + 0x00, 0xd6, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0f, 0x00, 0x7f, 0x7c, 0x10, + 0x10, 0x00, 0x4c, 0x10, 0x00, 0x00, 0x0a, 0x01, 0x10, 0xb4, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x06, 0x00, 0xaa, 0x0e, 0xd2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x10, 0x00, 0xd6, 0x9c, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xaa, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0xd6, 0x9c, 0x20, 0x10, 0xaa, 0x1c, 0x15, + 0x10, 0xd6, 0x0f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x10, 0xa0, 0x1c, 0x20, 0x00, 0x00, 0x0f, 0x06, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x10, 0xa0, 0x1c, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x1d, 0xec, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x04, 0x10, 0xa0, 0x1c, 0x0a, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0xbe, 0xbc, 0x30, + 0x00, 0x00, 0x94, 0xe1, 0x00, 0x00, 0x0c, 0x10, 0x10, 0xd6, 0x0c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x0f, 0x00, 0xa0, 0x1f, 0x04, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0x00, 0x0c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x04, 0x10, 0xaa, 0x1c, 0x0a, + 0x10, 0xd6, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0f, 0x00, 0xbe, 0x4c, 0x10, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xb4, 0x1c, 0x14, 0x10, 0xaa, 0x1c, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x0a, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0xa0, 0x03, 0xd3, 0x00, 0xb4, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9a, 0x04, 0x10, 0xbe, 0x1c, 0x10, + 0x00, 0xa0, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x20, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xb4, 0x1c, 0x10, 0x00, 0xbe, 0x0c, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x04, + 0x10, 0xf0, 0x1c, 0x1a, 0x00, 0xb4, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x04, 0x10, 0xfe, 0x1c, 0x10, + 0x00, 0xf0, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x04, + 0x00, 0xf0, 0x94, 0xe1, 0x11, 0x0d, 0x1c, 0x1a, 0x10, 0xa0, 0x04, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x04, 0xe1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x7c, 0x07, + 0x00, 0x00, 0x9a, 0x02, 0x00, 0xb4, 0x0c, 0x10, 0x01, 0x40, 0xfc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9c, 0x10, + 0x00, 0x00, 0x0c, 0x0a, 0x11, 0x0d, 0x1c, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x99, 0x19, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0xf0, 0x99, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x94, 0xe1, + 0x11, 0x0d, 0x1c, 0x0a, 0x10, 0xb4, 0x1c, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1f, 0x04, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x0c, 0x0a, + 0x10, 0xa0, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x20, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xfa, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x9a, 0x04, 0x10, 0xb4, 0x1c, 0x03, + 0x10, 0xa0, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x18, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x04, 0x10, 0xa0, 0x1c, 0x10, + 0x01, 0x68, 0xfc, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x10, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, 0xa0, 0x04, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x10, 0x97, 0x1c, 0x0a, + 0x00, 0x00, 0x04, 0xe3, 0x00, 0xa0, 0x10, 0x00, 0x00, 0xf0, 0x9c, 0x20, + 0x10, 0x8f, 0x10, 0x00, 0x01, 0x68, 0xf4, 0xe5, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x40, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x10, 0x87, 0x1c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, 0x87, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x04, + 0x10, 0x78, 0x1c, 0x0a, 0x01, 0x68, 0xec, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0xbe, 0x4c, 0x08, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0x7f, 0x1c, 0x10, 0x01, 0x40, 0xe3, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x0f, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x04, + 0x10, 0x87, 0x1c, 0x20, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0xa0, 0xb0, 0x00, 0x00, 0x00, 0x94, 0xe1, 0x00, 0x78, 0x03, 0xf0, + 0x01, 0x68, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x04, + 0x00, 0x00, 0x04, 0xe4, 0x10, 0x8f, 0x10, 0x00, 0x01, 0x40, 0xe0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x10, 0xb4, 0x1c, 0x10, 0x00, 0x00, 0x01, 0x02, + 0x00, 0xbe, 0x4c, 0x10, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x40, 0xe3, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xd6, 0x1c, 0x10, 0x01, 0x68, 0xec, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9a, 0x04, + 0x10, 0xa0, 0x1c, 0x10, 0x10, 0xd6, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0xbc, 0x20, 0x00, 0x00, 0x9a, 0x04, 0x00, 0xbe, 0x0e, 0xd3, + 0x00, 0xd6, 0xde, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x0c, 0x06, 0x10, 0xf0, 0x0c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0xf0, 0x0e, 0xd2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xe2, 0x0c, 0x13, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1f, 0x04, 0x00, 0xd6, 0x94, 0xe1, 0x10, 0xbe, 0x1c, 0x15, + 0x10, 0xd6, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x04, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xac, 0xfc, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x9c, 0x10, 0x00, 0x00, 0x0c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x99, 0x19, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xbe, 0x1c, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x05, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0xd6, 0x99, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x30, + 0x00, 0x00, 0x94, 0xe1, 0x10, 0xca, 0x10, 0x00, 0x01, 0xac, 0xfc, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x04, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xca, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0x3c, 0x20, 0x00, 0x00, 0x9a, 0x04, 0x10, 0xd6, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xf0, 0x1c, 0x05, 0x10, 0xd6, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x9a, 0x04, + 0x10, 0xd6, 0x1c, 0x0a, 0x01, 0x40, 0xef, 0x02, 0x00, 0x00, 0x0f, 0x06, + 0x00, 0x00, 0x0a, 0x04, 0x10, 0xca, 0x1c, 0x10, 0x00, 0x00, 0x01, 0x02, + 0x00, 0xbe, 0x4f, 0x04, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0xbe, 0xbc, 0x18, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xd6, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x04, + 0x10, 0xf0, 0x1c, 0x0a, 0x01, 0x68, 0xec, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0xbc, 0x10, 0x00, 0x00, 0x9a, 0x04, 0x10, 0xbe, 0x1c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x02, + 0x00, 0xd6, 0x9c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0xd6, 0x04, 0xe2, + 0x00, 0x00, 0x0f, 0x06, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0xa0, 0x6f, 0x04, 0x00, 0x00, 0x9a, 0x04, + 0x10, 0xca, 0x1c, 0x10, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x04, 0x10, 0xd6, 0x1c, 0x0a, + 0x10, 0xca, 0x1c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xf0, 0x1c, 0x05, 0x00, 0xf0, 0xe4, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x97, 0x10, 0x00, 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x8f, 0x10, 0x00, 0x00, 0x00, 0x01, 0x02, + 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0xe3, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xbe, 0x1c, 0x10, 0x00, 0x00, 0x02, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x1f, 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x94, 0xe1, + 0x10, 0xd6, 0x10, 0x00, 0x01, 0xac, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1f, 0x02, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x06, 0x00, 0x00, 0x04, 0xe5, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x6f, 0x04, + 0x00, 0x00, 0x9a, 0x08, 0x10, 0xa0, 0x1c, 0x12, 0x10, 0xd6, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4c, 0x10, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x0c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0f, 0x02, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x0f, 0x06, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0xca, 0x0e, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4f, 0x04, + 0x00, 0x00, 0x9a, 0x04, 0x10, 0xbe, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x20, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xd6, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x04, 0x10, 0xca, 0x1c, 0x10, + 0x00, 0x00, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x7f, 0x7c, 0x10, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, 0xca, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x04, 0x00, 0xf0, 0x94, 0xe1, + 0x10, 0xd6, 0x10, 0x00, 0x10, 0xa0, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x04, 0xe1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x9a, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x7c, 0x07, 0x00, 0x00, 0x9a, 0x02, + 0x11, 0x40, 0x1c, 0x10, 0x01, 0x40, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xd6, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4c, 0x08, + 0x00, 0x00, 0x99, 0x19, 0x00, 0x00, 0x0c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0xf0, 0x99, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x94, 0xe1, 0x10, 0xd6, 0x1c, 0x06, + 0x11, 0x40, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x04, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x10, 0xa0, 0x0c, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x20, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xfa, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x10, + 0x00, 0x00, 0x9a, 0x04, 0x11, 0x40, 0x1c, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0xbc, 0x18, 0x00, 0x00, 0x9a, 0x04, 0x11, 0x2e, 0x1c, 0x10, + 0x10, 0xb4, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x9c, 0x12, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7c, 0x10, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, 0xa0, 0x0c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x10, 0x00, 0x00, 0x9a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x03, 0xd0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1f, 0x04, 0x00, 0xd6, 0x9c, 0x20, 0x11, 0x1d, 0x1c, 0x0a, + 0x10, 0x8f, 0x0c, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe3, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x9a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe5, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x0c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0a, + 0x00, 0x00, 0x0c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x97, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0x9c, 0x10, 0x01, 0x2e, 0x00, 0x00, 0x10, 0xa0, 0x0c, 0x20, + 0x00, 0xa0, 0x6f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0a, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x01, 0x1d, 0x9c, 0x10, 0x01, 0x40, 0x00, 0x00, + 0x10, 0xb4, 0x0c, 0x10, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xbc, 0x20, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x08, + 0x01, 0x40, 0x9c, 0x10, 0x00, 0xfe, 0xac, 0x10, 0x10, 0xd6, 0x0c, 0x10, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x7c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0e, 0xc1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x08, 0x00, 0xd6, 0x9c, 0x12, + 0x01, 0x53, 0xac, 0x12, 0x01, 0x1d, 0xec, 0x10, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x48, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x7c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xbc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0e, 0xc1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x4c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbc, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1f, 0x08, 0x01, 0x40, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xd6, 0x0c, 0x10, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x1d, 0x1c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xd6, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x05, 0x00, 0x00, 0x00, 0x00, 0x11, 0x1d, 0x1c, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xbe, 0x1c, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x11, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x7c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x0e, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xca, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x08, + 0x00, 0xd6, 0x9c, 0x12, 0x10, 0xd6, 0x1c, 0x10, 0x01, 0x1d, 0xec, 0x10, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xf0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x1d, 0x1c, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x7c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0e, 0xc1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x08, 0x01, 0x40, 0x9c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xd6, 0x0c, 0x10, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x1d, 0x1c, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x02, 0x10, 0xca, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8e, 0xd6, 0x00, 0x00, 0x0f, 0x0e, + 0x10, 0xbe, 0x1c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x0f, 0x08, 0x10, 0xb4, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xaa, 0x1c, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x7c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xaa, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb4, 0x1c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0e, 0xc1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x03, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xbe, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x11, 0x1d, 0x1c, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xf0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbc, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x1d, 0x1c, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1f, 0x08, 0x00, 0xd6, 0x9c, 0x12, 0x10, 0xd6, 0x1c, 0x10, + 0x01, 0x1d, 0xec, 0x10, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xf0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x1d, 0x1c, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x40, 0x1c, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x40, 0x1c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x1d, 0x1c, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x0c, 0x0a, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x0c, 0x0a, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xaa, 0x5c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x0e, 0x93, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xaa, 0x5c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x5c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x6c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x5c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x5c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0x5c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x08, + 0x01, 0x40, 0x9c, 0x10, 0x11, 0x40, 0x4c, 0x00, 0x10, 0xd6, 0x0c, 0x10, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x7c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0e, 0xc1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x08, 0x01, 0x2e, 0x0c, 0x12, + 0x10, 0xca, 0x4c, 0x0a, 0x10, 0xca, 0x0c, 0x10, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x01, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x05, + 0x01, 0x0d, 0xec, 0x10, 0x00, 0xa0, 0x8c, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x7c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xbc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0e, 0xc1, 0x00, 0x00, 0x0e, 0xa1, + 0x10, 0xe2, 0x4c, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xbe, 0x4c, 0x0a, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0e, 0xa2, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xa0, 0xbc, 0x10, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xa0, 0x1f, 0x08, 0x01, 0x2e, 0x9c, 0x17, 0x10, 0xe2, 0x4c, 0x08, + 0x00, 0xfe, 0xec, 0x24, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x53, 0xec, 0x10, + 0x00, 0xa0, 0x8c, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x7c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x0e, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x08, + 0x01, 0x0d, 0x9c, 0x22, 0x10, 0xb4, 0x4c, 0x14, 0x01, 0x68, 0xec, 0x20, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x7c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0e, 0xc1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4c, 0x0a, 0x00, 0x00, 0x0c, 0x10, + 0x00, 0x00, 0x0c, 0x10, 0x01, 0x0d, 0xec, 0x20, 0x00, 0x7f, 0x2c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0xa0, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x08, 0x00, 0xfe, 0x9c, 0x18, + 0x11, 0x53, 0x4c, 0x16, 0x00, 0xfe, 0xec, 0x24, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x7c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0e, 0xc1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbc, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1f, 0x08, 0x00, 0xd6, 0x9c, 0x22, 0x11, 0x40, 0x4c, 0x0a, + 0x01, 0x68, 0xec, 0x20, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x7c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x0e, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x08, + 0x00, 0xf0, 0x9c, 0x18, 0x10, 0xf0, 0x4c, 0x15, 0x01, 0x0d, 0xec, 0x24, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xec, 0x20, 0x00, 0xa0, 0x8c, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x7c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0e, 0xc1, + 0x00, 0x00, 0x0e, 0x21, 0x00, 0x00, 0x0e, 0x22, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0xe2, 0x03, 0xd0, 0x00, 0xe2, 0x03, 0xf0, + 0x00, 0xe2, 0xec, 0x10, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xbc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x08, 0x00, 0xd6, 0x9c, 0x22, + 0x10, 0xd6, 0x4c, 0x0a, 0x01, 0xac, 0xec, 0x20, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x8c, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xd6, 0x0c, 0x20, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xac, 0xfc, 0x10, + 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xd6, 0x0c, 0x20, 0x00, 0xa0, 0x8c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0xbe, 0x4c, 0x00, 0x10, 0xd6, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x0a, 0x20, 0x00, 0xa0, 0x7c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0xbe, 0x0e, 0x93, + 0x00, 0xa0, 0xbc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0xa0, 0x0e, 0xc1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0xbe, 0x4c, 0x30, 0x10, 0xd6, 0x0c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x4c, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb1, + 0x00, 0xbe, 0x4c, 0x10, 0x00, 0x7f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc0, 0x00, + 0x00, 0xd6, 0x90, 0x00, 0x00, 0x00, 0x0e, 0xb1, 0x10, 0xd6, 0x00, 0x00, + 0x00, 0x00, 0x0f, 0x04, 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x0f, 0x04, 0x00, 0x00, 0x04, 0xe3, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe9, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xac, 0xfa, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xea, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0xbe, 0xbc, 0x30, + 0x00, 0x00, 0x94, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x01, 0xac, 0xfc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x04, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xd6, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0x3c, 0x20, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xdc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xd6, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x40, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0xbe, 0xbc, 0x18, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xe3, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0xec, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0xbc, 0x10, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0xd6, 0x9c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0xd6, 0x04, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xac, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xe4, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, + 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0xe3, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x1f, 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x94, 0xe1, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xac, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1f, 0x04, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x40, 0xdc, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2e, 0x03, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4c, 0x10, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x1d, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0xe2, 0x9c, 0x19, 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0xe0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x00, 0xbe, 0xbc, 0x20, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x68, 0xec, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x7f, 0x7c, 0x10, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x00, 0xa0, 0x1f, 0x04, 0x00, 0xf0, 0x9c, 0x11, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xa0, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9c, 0x11, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x7c, 0x07, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4c, 0x08, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x78, 0x9c, 0x00, 0x00, 0xa0, 0xec, 0x1a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0a, 0x20, + 0x03, 0x58, 0x03, 0x0a, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x0a, 0x20, 0x00, 0x00, 0x05, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0a, 0x30, 0x00, 0x00, 0x05, 0x50, + 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x94, 0xe1, 0x00, 0x00, 0x04, 0xf2, + 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, + 0x00, 0x00, 0x04, 0xf3, 0x00, 0x00, 0x05, 0x05, 0x00, 0xa0, 0x1f, 0x04, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x04, 0xf5, 0x10, 0xa0, 0x0c, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe8, 0x00, 0x00, 0x04, 0xf7, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x20, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x0a, 0x04, 0x01, 0x40, 0xea, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0a, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0a, 0x03, + 0x01, 0x68, 0xdc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x10, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x9c, 0x18, 0x10, 0xa0, 0x0c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x9c, 0x2f, 0x01, 0x40, 0xec, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0a, 0x0f, 0x00, 0x00, 0x01, 0x03, + 0x00, 0xbe, 0xbc, 0x18, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x9c, 0x15, + 0x01, 0x40, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7c, 0x10, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x9c, 0x06, 0x01, 0x68, 0xec, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0a, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x10, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x9c, 0x06, 0x10, 0xa0, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0a, 0x07, 0x00, 0x00, 0x04, 0xe3, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0xf0, 0x9c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xfc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x68, 0xec, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xe3, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0xa0, 0xb0, 0x00, + 0x00, 0x00, 0x94, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0xe0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x04, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0xbe, 0x4c, 0x10, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xe3, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0xec, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xd6, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x20, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xde, 0xc2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xf0, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xe2, 0x0c, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xcf, 0x04, + 0x00, 0xd6, 0x94, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x10, 0xd6, 0x04, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x10, 0xd6, 0x4c, 0x00, + 0x01, 0xac, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xd6, 0xfc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xd6, 0xea, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x94, 0xe1, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0xac, 0xfc, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1f, 0x04, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe8, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x20, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, 0x10, 0xd6, 0x0c, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xd6, 0xdc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, + 0x10, 0x7f, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, 0x10, 0x78, 0x03, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x0a, 0x07, 0x00, 0xbe, 0xbc, 0x18, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xb4, 0x03, 0xf3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, + 0x10, 0xf0, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x10, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, 0x10, 0xe2, 0x0c, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, 0x00, 0xd6, 0x9c, 0x20, + 0x00, 0x00, 0x0e, 0xa1, 0x10, 0xd6, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0xac, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xf0, 0xe4, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x01, 0x02, 0x00, 0xbe, 0x4c, 0x08, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xd6, 0xe3, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x1f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x1f, + 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x94, 0xe1, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xa0, 0xec, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x04, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x97, 0xec, 0x33, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe8, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x8f, 0x03, 0x33, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0xbe, 0x4c, 0x10, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0x1d, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xf0, 0xfc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xa0, 0xe1, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xa0, 0x05, 0x08, + 0x00, 0xbe, 0xbc, 0x20, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xb4, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xd6, 0x05, 0x20, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xf0, 0x05, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xfe, 0x05, 0x20, 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x1d, 0x05, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x2e, 0x05, 0x20, + 0x00, 0xa0, 0x1f, 0x04, 0x00, 0xf0, 0x9c, 0x20, 0x10, 0xf0, 0x4c, 0x19, + 0x10, 0xa0, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x7f, 0x7c, 0x07, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x40, 0xfc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x38, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1c, 0x10, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xaa, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xcc, 0x30, + 0x00, 0x00, 0x94, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xe4, 0xf2, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x0f, 0x04, 0x00, 0x00, 0x04, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0xa0, 0x1c, 0x10, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xa0, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x40, 0xec, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0xbe, 0xbc, 0x18, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x03, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0xec, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0xbc, 0x10, 0x00, 0xf0, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xa0, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe3, 0x00, 0xa0, 0x10, 0x00, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe5, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xec, 0x12, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, + 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x2e, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x70, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0xbe, 0xbc, 0x30, 0x00, 0xd6, 0x94, 0xe1, + 0x10, 0xd6, 0x4c, 0x06, 0x10, 0x8f, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1f, 0x04, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3a, 0xfc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0xbe, 0x4c, 0x10, 0x00, 0x00, 0x06, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xfc, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x8f, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0xa0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x00, 0xbe, 0xbc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xa0, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, + 0x00, 0xa0, 0xbe, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xb4, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc0, 0x00, + 0x10, 0xd6, 0x44, 0xe1, 0x00, 0xb4, 0xac, 0x23, 0x10, 0xd6, 0x0c, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, 0x00, 0xaa, 0x03, 0x07, + 0x00, 0x00, 0x04, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe3, + 0x00, 0x00, 0x04, 0xe1, 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x64, 0x00, 0x00, 0x04, 0xe1, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x04, 0xe2, + 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, + 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x08, 0x00, 0x00, 0x04, 0xe3, 0x01, 0xac, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x00, 0x00, 0x04, 0xe3, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x4c, 0x19, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0xd6, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x40, 0x00, 0x10, 0x00, 0x4a, 0x09, 0x00, 0x00, 0x04, 0xe3, + 0x00, 0xd6, 0xea, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x04, 0xe3, 0x00, 0x00, 0x02, 0x0f, 0x00, 0xbe, 0x4c, 0x08, + 0x10, 0x00, 0x4a, 0x09, 0x00, 0x00, 0x06, 0x04, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x06, 0x04, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x09, 0x19, + 0x00, 0x00, 0x06, 0x04, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x06, 0x04, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0xbe, 0xbc, 0x30, 0x10, 0x00, 0x44, 0xe1, 0x10, 0xd6, 0x4c, 0x00, + 0x01, 0xac, 0xfc, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x04, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe8, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x20, 0x10, 0x00, 0x4a, 0x09, + 0x00, 0x00, 0x0e, 0xa1, 0x10, 0xd6, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x20, 0x10, 0x00, 0x4a, 0x09, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xf0, 0xdc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x10, + 0x10, 0x00, 0x4a, 0x08, 0x00, 0x00, 0x0e, 0xa1, 0x10, 0xd6, 0x0c, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, 0x10, 0x00, 0x4a, 0x07, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x40, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x01, 0x03, + 0x00, 0xbe, 0xbc, 0x18, 0x10, 0x00, 0x4a, 0x06, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0x40, 0xe3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7c, 0x10, + 0x10, 0x00, 0x4a, 0x05, 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x68, 0xec, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x10, 0x00, 0xd6, 0x9a, 0x09, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x00, 0x00, 0x0e, 0xa1, + 0x10, 0xd6, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x04, 0xe4, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, 0x01, 0xac, 0xfc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0xf0, 0xe4, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x04, 0xe4, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x04, 0xe6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x01, 0x02, 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xd6, 0xe3, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x02, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x02, 0x1f, 0x00, 0xbe, 0xbc, 0x30, + 0x00, 0x00, 0x94, 0xe1, 0x00, 0x00, 0x0e, 0xa1, 0x01, 0xac, 0xfc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x04, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x40, 0xdc, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe8, 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, + 0x01, 0x2e, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4c, 0x10, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0e, 0xa1, 0x01, 0x1d, 0x03, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xa1, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x0e, 0xa1, 0x00, 0xf0, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0e, 0xbf, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0xe2, 0x9c, 0x19, 0x00, 0xe2, 0x03, 0xf0, + 0x01, 0x68, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0xbe, 0xbc, 0x20, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0xec, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, + 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0xa0, 0x1f, 0x04, + 0x00, 0xf0, 0x9c, 0x20, 0x10, 0xf0, 0x4c, 0x10, 0x10, 0xa0, 0x04, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x7c, 0x07, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xfc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0a, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x9a, 0x09, 0x10, 0xf0, 0x4c, 0x13, + 0x00, 0xa0, 0xec, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x10, 0xf0, 0x4c, 0x07, 0x03, 0x58, 0x03, 0x0a, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x50, 0x00, 0xbe, 0xbc, 0x30, 0x00, 0x00, 0x94, 0xe1, + 0x10, 0xf0, 0x4c, 0x17, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x04, 0xe3, 0x00, 0x00, 0x05, 0x05, + 0x00, 0xa0, 0x1f, 0x04, 0x00, 0x00, 0x04, 0xe8, 0x00, 0x00, 0x04, 0xe4, + 0x10, 0xa0, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x06, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x20, + 0x00, 0x00, 0x9a, 0x09, 0x10, 0xf0, 0x4c, 0x05, 0x01, 0x40, 0xea, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0c, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x0c, 0x09, 0x01, 0x68, 0xdc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0c, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0c, 0x0b, + 0x10, 0xa0, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0c, 0x0d, 0x01, 0x40, 0xec, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0c, 0x0e, + 0x00, 0x00, 0x01, 0x03, 0x00, 0xbe, 0xbc, 0x18, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x0c, 0x0f, 0x01, 0x40, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x68, 0xec, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbc, 0x10, + 0x00, 0xf0, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0xa0, 0x04, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe3, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe5, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x40, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0xec, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0xbe, 0x4c, 0x08, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2e, 0xe3, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x0f, 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0xa0, 0xc0, 0x00, 0x00, 0x00, 0x9c, 0x20, 0x00, 0x00, 0x0a, 0x01, + 0x01, 0x40, 0xdc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x0c, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x01, 0x00, 0xbe, 0x4c, 0x13, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0xbe, 0x4c, 0x13, + 0x00, 0xa0, 0x8c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x01, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xb0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x01, 0x40, 0xfe, 0xc2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xaa, 0x4c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x40, 0xfc, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x7c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc0, 0x00, 0x10, 0xd6, 0x44, 0xe1, + 0x00, 0xb4, 0xac, 0x23, 0x10, 0xd6, 0x0c, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe2, 0x00, 0xaa, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x1f, 0x04, 0x00, 0xf0, 0x9c, 0x20, 0x10, 0xf0, 0x4c, 0x10, + 0x10, 0xa0, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, 0x00, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x00, 0x7f, 0x7c, 0x07, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x40, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x78, 0x9c, 0x00, 0x00, 0xa0, 0xec, 0x1a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0a, 0x20, 0x03, 0x58, 0x03, 0x0a, + 0x00, 0x7f, 0x2c, 0x10, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0a, 0x20, + 0x00, 0x00, 0x05, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x0a, 0x30, 0x00, 0x00, 0x05, 0x50, 0x00, 0xbe, 0xbc, 0x30, + 0x00, 0x00, 0x94, 0xe1, 0x00, 0x00, 0x04, 0xf2, 0x00, 0x00, 0x05, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x04, 0xf3, + 0x00, 0x00, 0x05, 0x05, 0x00, 0xa0, 0x1f, 0x04, 0x00, 0x00, 0x04, 0xe8, + 0x00, 0x00, 0x04, 0xf5, 0x10, 0xa0, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0xf7, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0x3c, 0x20, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0a, 0x04, + 0x01, 0x40, 0xea, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x0a, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x2c, 0x20, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x0a, 0x03, 0x01, 0x68, 0xdc, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x3c, 0x10, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x9c, 0x18, 0x10, 0xa0, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x9c, 0x2f, + 0x01, 0x40, 0xec, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x0a, 0x0f, 0x00, 0x00, 0x01, 0x03, 0x00, 0xbe, 0xbc, 0x18, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0x00, 0x9c, 0x15, 0x01, 0x40, 0x03, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7c, 0x10, 0x00, 0x00, 0x9a, 0x09, + 0x00, 0x00, 0x9c, 0x06, 0x01, 0x68, 0xec, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0xbc, 0x10, 0x00, 0xf0, 0x9c, 0x10, 0x00, 0x00, 0x9c, 0x06, + 0x10, 0xa0, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x0a, 0x07, 0x00, 0x00, 0x04, 0xe3, 0x00, 0xa0, 0x1f, 0x04, + 0x00, 0x00, 0x9a, 0x09, 0x10, 0xf0, 0x4c, 0x10, 0x00, 0x00, 0x04, 0xe5, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0xa0, 0x60, 0x00, 0x00, 0x00, 0x9a, 0x09, + 0x11, 0x1d, 0x1c, 0x02, 0x01, 0x40, 0xfc, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0x2c, 0x20, 0x00, 0x00, 0x9a, 0x09, 0x10, 0xd6, 0x1c, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0x09, 0x00, 0xb4, 0x03, 0xf0, 0x01, 0x68, 0xec, 0x12, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe4, 0x00, 0xbe, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbe, 0x0c, 0x08, 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, + 0x00, 0xbe, 0x4c, 0x08, 0x00, 0x00, 0x9a, 0x09, 0x00, 0xb4, 0x03, 0xd0, + 0x01, 0x2e, 0xe3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0x00, 0x7f, 0x2c, 0x10, + 0x00, 0x00, 0x9a, 0x09, 0x10, 0xf0, 0x1c, 0x0a, 0x10, 0x7f, 0x1c, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc0, 0x00, 0x00, 0xd6, 0x94, 0xe1, + 0x00, 0xd6, 0x03, 0xd0, 0x00, 0x78, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0f, 0x04, 0x00, 0x00, 0x04, 0xe4, 0x10, 0xfe, 0x1c, 0x10, + 0x00, 0x8f, 0x0c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xb4, 0x1c, 0x08, 0x00, 0xf0, 0x03, 0xd0, 0x00, 0xa0, 0x03, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x03, 0xf0, + 0x01, 0x1d, 0x03, 0xf0, 0x00, 0xb4, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x05, 0x10, 0x00, 0xfe, 0x03, 0xf0, + 0x00, 0xd6, 0x05, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x10, + 0x00, 0x00, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x1d, 0x05, 0x10, 0x01, 0x40, 0x03, 0xf0, 0x00, 0xf0, 0x05, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x10, 0x00, 0x00, 0x05, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xf0, 0x1f, 0x08, 0x11, 0x2e, 0x10, 0x00, + 0x11, 0x68, 0x1c, 0x20, 0x10, 0xd6, 0x1c, 0x20, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x0a, 0x04, + 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x0c, 0x03, + 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x0f, 0x1f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xe3, + 0x01, 0x1d, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x0a, 0x01, + 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0xff, 0xf3, 0xf3, 0x05, 0x40, 0x3e, + 0x09, 0xc4, 0xa9, 0xfd, 0x3e, 0x68, 0x20, 0x03, 0xbd, 0x09, 0x0b, 0x0b, + 0x3c, 0x1b, 0x55, 0x3a, 0xe3, 0xc2, 0xa9, 0x05, 0x43, 0x53, 0x05, 0xbf, + 0xab, 0x13, 0x3a, 0x4b, 0xf5, 0x03, 0xc2, 0x0b, 0x20, 0x55, 0xf5, 0xef, + 0xe0, 0x0f, 0x0d, 0x4f, 0x4d, 0x0f, 0xda, 0x2e, 0xe7, 0xf7, 0x11, 0xd2, + 0xca, 0xc2, 0xfb, 0xe7, 0x1d, 0xf1, 0xe0, 0xf1, 0xe0, 0xfb, 0xeb, 0xb7, + 0xb9, 0xd6, 0xef, 0x13, 0xd8, 0xf7, 0xde, 0x09, 0xe0, 0x15, 0xc4, 0xb1, + 0xcc, 0x1d, 0xf7, 0xde, 0x0b, 0xc8, 0xaf, 0x9e, 0x88, 0x82, 0xd0, 0x15, + 0x1f, 0xc6, 0xc8, 0xe0, 0x09, 0xe9, 0xe5, 0xce, 0xbb, 0xbd, 0xb3, 0xd4, + 0xb1, 0xfd, 0x03, 0xc8, 0xe9, 0xbb, 0xfd, 0xd2, 0x20, 0xfb, 0xf9, 0xde, + 0x03, 0x1b, 0xdc, 0xf9, 0x0d, 0x0b, 0x0b, 0x26, 0xe1, 0x34, 0x38, 0x24, + 0xff, 0x22, 0x03, 0x26, 0x09, 0x4d, 0x09, 0x34, 0x28, 0x22, 0x11, 0x3a, + 0x20, 0x30, 0x1b, 0x30, 0x1d, 0x1d, 0x2e, 0x32, 0x4f, 0x57, 0x38, 0x68, + 0x20, 0x3c, 0xe1, 0x40, 0x2a, 0x40, 0x3c, 0x26, 0x2e, 0x40, 0x53, 0x61, + 0x1b, 0x45, 0x05, 0x49, 0x0b, 0x4b, 0x4b, 0x40, 0x49, 0x32, 0x30, 0x2e, + 0x59, 0x3a, 0x4d, 0xff, 0x1f, 0x4d, 0x22, 0x4b, 0x00, 0x05, 0x3e, 0x4b, + 0x1d, 0x03, 0x07, 0x45, 0x2e, 0x1d, 0x34, 0x01, 0x20, 0x11, 0x0b, 0xfb, + 0x30, 0x0b, 0xe5, 0x09, 0x13, 0x1b, 0x0d, 0xff, 0xc8, 0x0b, 0xd4, 0x26, + 0x11, 0xe3, 0xc0, 0xd2, 0x0d, 0xfb, 0xc2, 0xda, 0xcc, 0xef, 0xd6, 0xfb, + 0xd2, 0xed, 0xb1, 0xca, 0xe5, 0xc0, 0xd4, 0xbb, 0xb9, 0xbd, 0xd6, 0xcc, + 0xb3, 0xd6, 0xb5, 0xc0, 0xce, 0xce, 0xbb, 0xbd, 0xb3, 0xd0, 0xbf, 0xb5, + 0xb3, 0xbd, 0xbd, 0xc4, 0xc4, 0xc4, 0xa7, 0xc2, 0xab, 0xd8, 0xb7, 0xc6, + 0xc2, 0xb1, 0xbd, 0xd6, 0xca, 0xc4, 0xbb, 0xc4, 0xe3, 0xb5, 0xe1, 0xbb, + 0xd6, 0xdc, 0xde, 0xc0, 0xca, 0xd4, 0xeb, 0xd8, 0xd6, 0xcc, 0xcc, 0xed, + 0xde, 0xe9, 0xe1, 0xe1, 0xf5, 0xdc, 0xda, 0xed, 0xf1, 0xf1, 0xe3, 0xda, + 0xe9, 0xf5, 0xf7, 0xf3, 0xff, 0x03, 0x0f, 0x07, 0xff, 0xff, 0x03, 0x07, + 0x1b, 0x07, 0x07, 0x05, 0x24, 0x13, 0x19, 0x0f, 0x1f, 0x0d, 0x1f, 0x20, + 0x11, 0x20, 0x1f, 0x32, 0x28, 0x3a, 0x20, 0x2e, 0x1b, 0x30, 0x2c, 0x3c, + 0x2e, 0x2a, 0x30, 0x3e, 0x38, 0x34, 0x24, 0x2e, 0x22, 0x2e, 0x32, 0x47, + 0x30, 0x34, 0x38, 0x2c, 0x3a, 0x41, 0x38, 0x2c, 0x45, 0x2c, 0x26, 0x38, + 0x24, 0x22, 0x3e, 0x36, 0x3e, 0x28, 0x24, 0x20, 0x2e, 0x28, 0x3a, 0x32, + 0x32, 0x2c, 0x34, 0x17, 0x2e, 0x1d, 0x2e, 0x2e, 0x32, 0x30, 0x2a, 0x26, + 0x28, 0x19, 0x28, 0x24, 0x26, 0x32, 0x1d, 0x1f, 0x26, 0x20, 0x24, 0x22, + 0x1b, 0x17, 0x17, 0x1f, 0x24, 0x24, 0x17, 0x1b, 0x17, 0x19, 0x13, 0x1d, + 0x0f, 0x11, 0x0f, 0x0f, 0x0d, 0x0f, 0x09, 0x11, 0x00, 0x0b, 0x05, 0x0d, + 0x00, 0x0d, 0x01, 0x03, 0x03, 0xf7, 0x01, 0xfd, 0x03, 0x07, 0xfb, 0x01, + 0xf9, 0xf7, 0xf5, 0xfd, 0xf7, 0xf5, 0xf7, 0xe9, 0xf1, 0x00, 0xf7, 0xeb, + 0xde, 0xe1, 0xde, 0xe9, 0xf1, 0xef, 0xed, 0xe3, 0xd4, 0xde, 0xe3, 0xe3, + 0xe0, 0xe0, 0xdc, 0xde, 0xd8, 0xda, 0xd8, 0xd8, 0xd4, 0xd2, 0xcc, 0xd0, + 0xcc, 0xc8, 0xce, 0xd6, 0xcc, 0xca, 0xc8, 0xc8, 0xc6, 0xcc, 0xc4, 0xca, + 0xc4, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc, 0xc2, 0xc0, 0xc4, 0xc8, 0xca, 0xcc, + 0xca, 0xc4, 0xc8, 0xc6, 0xce, 0xc4, 0xce, 0xc8, 0xc6, 0xce, 0xce, 0xd0, + 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd8, 0xd8, 0xd4, 0xd8, 0xde, 0xde, 0xde, + 0xe0, 0xe1, 0xde, 0xe1, 0xe1, 0xe5, 0xe7, 0xeb, 0xed, 0xed, 0xe9, 0xeb, + 0xef, 0xf1, 0xf3, 0xef, 0xf7, 0xfd, 0xfb, 0xf7, 0xf5, 0xf9, 0xff, 0xfd, + 0xff, 0xff, 0x03, 0x07, 0x05, 0x00, 0x09, 0x07, 0x0d, 0x09, 0x0d, 0x09, + 0x11, 0x15, 0x1b, 0x15, 0x0f, 0x0d, 0x13, 0x13, 0x15, 0x17, 0x1d, 0x17, + 0x17, 0x17, 0x1d, 0x1d, 0x24, 0x24, 0x22, 0x1d, 0x1d, 0x22, 0x26, 0x26, + 0x26, 0x20, 0x22, 0x22, 0x22, 0x24, 0x26, 0x26, 0x28, 0x2a, 0x28, 0x20, + 0x22, 0x26, 0x26, 0x2a, 0x2a, 0x2a, 0x28, 0x2a, 0x26, 0x24, 0x22, 0x28, + 0x2a, 0x2a, 0x28, 0x2a, 0x2c, 0x2e, 0x2c, 0x28, 0x26, 0x26, 0x26, 0x26, + 0x2a, 0x28, 0x26, 0x26, 0x26, 0x22, 0x1f, 0x24, 0x28, 0x2a, 0x2a, 0x22, + 0x24, 0x26, 0x24, 0x20, 0x1f, 0x20, 0x1f, 0x1d, 0x1d, 0x19, 0x1b, 0x1b, + 0x1f, 0x1f, 0x1b, 0x15, 0x17, 0x1b, 0x1f, 0x1b, 0x15, 0x13, 0x13, 0x11, + 0x11, 0x13, 0x15, 0x13, 0x11, 0x0d, 0x0b, 0x0d, 0x0d, 0x0b, 0x0d, 0x0b, + 0x05, 0x03, 0x03, 0x03, 0x05, 0x09, 0x09, 0x05, 0xff, 0xf9, 0xf7, 0xfd, + 0x01, 0x01, 0x00, 0xff, 0xfb, 0xf9, 0xf9, 0xf9, 0xf5, 0xf5, 0xf9, 0xf9, + 0xf5, 0xef, 0xef, 0xed, 0xf1, 0xf3, 0xf1, 0xef, 0xeb, 0xe9, 0xe9, 0xeb, + 0xeb, 0xeb, 0xe7, 0xe7, 0xe5, 0xe7, 0xed, 0xeb, 0xe3, 0xe0, 0xe1, 0xe3, + 0xe3, 0xe1, 0xe3, 0xe5, 0xe7, 0xe7, 0xe1, 0xe0, 0xde, 0xe0, 0xe0, 0xe0, + 0xe1, 0xe1, 0xe3, 0xe3, 0xe5, 0xe7, 0xe3, 0xde, 0xde, 0xe1, 0xe1, 0xe1, + 0xe1, 0xe0, 0xdc, 0xe1, 0xe3, 0xe1, 0xe3, 0xe1, 0xe1, 0xe0, 0xe0, 0xe1, + 0xe0, 0xe1, 0xe3, 0xe7, 0xeb, 0xe7, 0xe3, 0xe0, 0xe0, 0xe3, 0xe5, 0xe7, + 0xe3, 0xe1, 0xe3, 0xe7, 0xed, 0xed, 0xeb, 0xe9, 0xed, 0xed, 0xef, 0xed, + 0xef, 0xed, 0xeb, 0xed, 0xf1, 0xf3, 0xf3, 0xf5, 0xf5, 0xf3, 0xf1, 0xef, + 0xef, 0xf1, 0xf5, 0xf5, 0xf3, 0xf1, 0xed, 0xf1, 0xf5, 0xf9, 0xfd, 0xfd, + 0xf7, 0xf3, 0xf3, 0xf7, 0xf9, 0xfb, 0xfb, 0xfb, 0xf9, 0xf9, 0xf9, 0xf9, + 0xfb, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xfd, 0xfd, 0x00, 0xff, 0xfd, 0xfd, + 0xfd, 0x00, 0x01, 0x01, 0xff, 0xfd, 0xfd, 0x00, 0x01, 0x03, 0x03, 0x03, + 0x01, 0x00, 0xff, 0x01, 0x01, 0x03, 0x03, 0x00, 0x00, 0x01, 0x05, 0x05, + 0x05, 0x03, 0x03, 0x05, 0x03, 0x01, 0x03, 0x07, 0x09, 0x07, 0x03, 0x01, + 0x05, 0x07, 0x09, 0x07, 0x05, 0x05, 0x07, 0x0b, 0x09, 0x05, 0x03, 0x01, + 0x03, 0x07, 0x09, 0x0b, 0x09, 0x09, 0x0b, 0x0b, 0x0b, 0x0d, 0x0b, 0x0d, + 0x0d, 0x0d, 0x0d, 0x0b, 0x07, 0x09, 0x0b, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x13, 0x13, 0x11, 0x0f, 0x0d, 0x0d, 0x0f, 0x11, 0x11, 0x0f, 0x0d, 0x0f, + 0x0f, 0x11, 0x0f, 0x11, 0x13, 0x0f, 0x0f, 0x0f, 0x13, 0x13, 0x15, 0x13, + 0x11, 0x11, 0x11, 0x0f, 0x0f, 0x0d, 0x13, 0x17, 0x13, 0x11, 0x11, 0x13, + 0x15, 0x13, 0x13, 0x15, 0x15, 0x17, 0x15, 0x11, 0x11, 0x15, 0x17, 0x15, + 0x13, 0x15, 0x19, 0x19, 0x19, 0x15, 0x13, 0x13, 0x15, 0x15, 0x15, 0x17, + 0x17, 0x15, 0x13, 0x13, 0x13, 0x13, 0x11, 0x15, 0x15, 0x15, 0x15, 0x15, + 0x17, 0x17, 0x15, 0x15, 0x13, 0x0f, 0x0f, 0x17, 0x1d, 0x1b, 0x17, 0x15, + 0x13, 0x15, 0x1b, 0x1b, 0x17, 0x17, 0x17, 0x17, 0x15, 0x15, 0x13, 0x11, + 0x11, 0x13, 0x15, 0x17, 0x11, 0x0d, 0x0d, 0x0f, 0x0f, 0x0f, 0x0d, 0x0b, + 0x09, 0x0b, 0x0f, 0x0d, 0x09, 0x09, 0x07, 0x09, 0x0b, 0x0b, 0x09, 0x01, + 0x00, 0x01, 0x03, 0x03, 0x03, 0x00, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xfb, + 0xfb, 0xfb, 0xf9, 0xf9, 0xf7, 0xf3, 0xf3, 0xf5, 0xf7, 0xf5, 0xf1, 0xf1, + 0xf3, 0xf3, 0xf1, 0xed, 0xeb, 0xe9, 0xed, 0xed, 0xed, 0xeb, 0xe9, 0xe7, + 0xe7, 0xe5, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe5, 0xe3, 0xe0, + 0xe0, 0xe0, 0xe0, 0xde, 0xdc, 0xde, 0xe0, 0xe0, 0xdc, 0xd8, 0xd8, 0xdc, + 0xde, 0xda, 0xd8, 0xd8, 0xde, 0xe0, 0xdc, 0xda, 0xda, 0xdc, 0xde, 0xe0, + 0xde, 0xdc, 0xdc, 0xde, 0xde, 0xdc, 0xdc, 0xde, 0xde, 0xdc, 0xdc, 0xdc, + 0xde, 0xe1, 0xe3, 0xe1, 0xe0, 0xe0, 0xde, 0xe0, 0xe0, 0xe1, 0xe3, 0xe5, + 0xe1, 0xe0, 0xe1, 0xe3, 0xe7, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, 0xe9, 0xe7, + 0xe5, 0xe9, 0xed, 0xed, 0xe9, 0xe5, 0xe3, 0xe7, 0xeb, 0xed, 0xeb, 0xeb, + 0xeb, 0xe9, 0xeb, 0xed, 0xf1, 0xf1, 0xf1, 0xef, 0xed, 0xeb, 0xed, 0xf1, + 0xf3, 0xf1, 0xed, 0xed, 0xef, 0xf1, 0xf5, 0xf3, 0xf3, 0xf5, 0xf5, 0xf5, + 0xf7, 0xf7, 0xf9, 0xf9, 0xf9, 0xf9, 0xfb, 0xfd, 0xfd, 0xff, 0xfd, 0xfb, + 0xf9, 0xfd, 0xfd, 0xff, 0xfd, 0xfd, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x05, 0x07, 0x07, + 0x09, 0x09, 0x05, 0x05, 0x01, 0x03, 0x05, 0x07, 0x05, 0x05, 0x05, 0x07, + 0x0b, 0x0d, 0x07, 0x05, 0x05, 0x07, 0x0d, 0x0d, 0x0b, 0x09, 0x0d, 0x0f, + 0x0f, 0x0d, 0x0d, 0x0f, 0x0f, 0x0f, 0x0d, 0x0d, 0x0f, 0x0f, 0x13, 0x17, + 0x15, 0x11, 0x0f, 0x11, 0x13, 0x15, 0x15, 0x17, 0x17, 0x19, 0x19, 0x19, + 0x15, 0x11, 0x11, 0x15, 0x1b, 0x1f, 0x1b, 0x17, 0x11, 0x15, 0x19, 0x1d, + 0x1d, 0x1d, 0x1d, 0x1d, 0x1b, 0x19, 0x19, 0x19, 0x1b, 0x1f, 0x1f, 0x1d, + 0x1d, 0x1d, 0x1b, 0x19, 0x1b, 0x1d, 0x1d, 0x1b, 0x1d, 0x1f, 0x1f, 0x1f, + 0x1d, 0x1b, 0x19, 0x19, 0x1b, 0x1b, 0x1d, 0x1d, 0x1b, 0x1d, 0x1d, 0x1f, + 0x1f, 0x19, 0x15, 0x17, 0x1b, 0x20, 0x22, 0x1f, 0x1b, 0x19, 0x19, 0x19, + 0x19, 0x19, 0x1b, 0x1b, 0x19, 0x17, 0x17, 0x19, 0x19, 0x17, 0x15, 0x15, + 0x17, 0x19, 0x17, 0x13, 0x11, 0x11, 0x13, 0x15, 0x13, 0x0f, 0x0f, 0x0d, + 0x09, 0x07, 0x09, 0x0d, 0x0f, 0x0f, 0x0d, 0x07, 0x07, 0x07, 0x09, 0x09, + 0x09, 0x05, 0x05, 0x03, 0x05, 0x07, 0x07, 0x03, 0x01, 0x00, 0x01, 0x03, + 0x05, 0x05, 0x03, 0x00, 0xff, 0xff, 0x00, 0x01, 0x01, 0xff, 0xff, 0xfd, + 0xfb, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfb, 0xfb, 0xfb, 0xf9, + 0xf9, 0xfb, 0xfd, 0xfd, 0xfd, 0xfd, 0xf9, 0xf7, 0xf9, 0xfb, 0xfd, 0xfb, + 0xf9, 0xf9, 0xf9, 0xf7, 0xf5, 0xf1, 0xf1, 0xf3, 0xf7, 0xf9, 0xf5, 0xf1, + 0xf1, 0xf3, 0xf5, 0xf5, 0xf1, 0xef, 0xef, 0xf1, 0xf1, 0xf1, 0xef, 0xef, + 0xef, 0xef, 0xef, 0xef, 0xf1, 0xf3, 0xf1, 0xef, 0xed, 0xeb, 0xeb, 0xeb, + 0xef, 0xef, 0xed, 0xeb, 0xe7, 0xe9, 0xe9, 0xeb, 0xed, 0xed, 0xeb, 0xe9, + 0xeb, 0xeb, 0xe5, 0xe3, 0xe5, 0xe9, 0xed, 0xed, 0xe7, 0xe1, 0xe1, 0xe5, + 0xe7, 0xe7, 0xe7, 0xeb, 0xe9, 0xe5, 0xe3, 0xe1, 0xe3, 0xe9, 0xeb, 0xe9, + 0xe3, 0xe1, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe5, 0xe3, 0xe1, 0xe3, 0xe7, + 0xe9, 0xe7, 0xe3, 0xe1, 0xe1, 0xe3, 0xe5, 0xe5, 0xe3, 0xe5, 0xe7, 0xe7, + 0xe7, 0xe7, 0xe3, 0xe3, 0xe7, 0xe9, 0xed, 0xeb, 0xe9, 0xeb, 0xe9, 0xe7, + 0xe5, 0xe5, 0xe9, 0xeb, 0xeb, 0xe9, 0xeb, 0xed, 0xed, 0xed, 0xeb, 0xeb, + 0xeb, 0xe7, 0xe9, 0xe9, 0xf1, 0xf7, 0xf7, 0xf1, 0xeb, 0xeb, 0xf3, 0xf7, + 0xf5, 0xf1, 0xef, 0xf1, 0xf3, 0xf3, 0xf3, 0xf3, 0xf5, 0xf7, 0xf7, 0xf3, + 0xf3, 0xf5, 0xf9, 0xf9, 0xf7, 0xf7, 0xfb, 0xfb, 0xfb, 0xfb, 0xf9, 0xf9, + 0xf7, 0xf7, 0xf7, 0xfb, 0xfd, 0x00, 0x01, 0x00, 0xfd, 0xf9, 0xfb, 0xff, + 0x01, 0x07, 0x09, 0x07, 0x03, 0xfd, 0xf9, 0xfb, 0x03, 0x09, 0x07, 0x03, + 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 0x09, 0x07, 0x05, 0x05, 0x05, 0x0b, + 0x0d, 0x0b, 0x07, 0x07, 0x0b, 0x0d, 0x0f, 0x0d, 0x09, 0x09, 0x07, 0x07, + 0x0b, 0x0f, 0x11, 0x11, 0x0d, 0x0b, 0x0b, 0x0d, 0x0d, 0x0f, 0x0f, 0x0f, + 0x0d, 0x0f, 0x15, 0x17, 0x15, 0x0f, 0x0b, 0x0f, 0x11, 0x13, 0x13, 0x15, + 0x15, 0x15, 0x13, 0x11, 0x13, 0x19, 0x1d, 0x19, 0x13, 0x0d, 0x11, 0x17, + 0x19, 0x17, 0x13, 0x11, 0x17, 0x1d, 0x1f, 0x19, 0x17, 0x15, 0x15, 0x17, + 0x1d, 0x1f, 0x1f, 0x1b, 0x17, 0x15, 0x17, 0x19, 0x1d, 0x1d, 0x1b, 0x19, + 0x1b, 0x1d, 0x1f, 0x1d, 0x1b, 0x19, 0x19, 0x17, 0x1b, 0x1d, 0x1f, 0x1f, + 0x1d, 0x1b, 0x19, 0x19, 0x1b, 0x1f, 0x22, 0x1f, 0x1b, 0x19, 0x19, 0x1b, + 0x1f, 0x22, 0x1f, 0x19, 0x15, 0x17, 0x19, 0x1f, 0x22, 0x20, 0x1d, 0x19, + 0x19, 0x1b, 0x1b, 0x1b, 0x19, 0x17, 0x17, 0x17, 0x19, 0x17, 0x17, 0x17, + 0x15, 0x13, 0x13, 0x15, 0x17, 0x17, 0x11, 0x0b, 0x09, 0x0b, 0x0d, 0x0f, + 0x0f, 0x0f, 0x0b, 0x05, 0x03, 0x05, 0x07, 0x09, 0x09, 0x05, 0x01, 0x00, + 0x00, 0x05, 0x07, 0x05, 0x00, 0xfd, 0xfd, 0xfd, 0xff, 0x00, 0xff, 0x00, + 0x00, 0xfd, 0xf9, 0xf9, 0xf9, 0xfb, 0xfb, 0xf7, 0xf3, 0xf3, 0xf7, 0xf7, + 0xf7, 0xf3, 0xf1, 0xef, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xef, 0xeb, 0xe9, + 0xeb, 0xf1, 0xf1, 0xed, 0xe9, 0xe7, 0xe7, 0xe5, 0xe9, 0xeb, 0xeb, 0xe9, + 0xe9, 0xe7, 0xe7, 0xe9, 0xeb, 0xe9, 0xe3, 0xe1, 0xe3, 0xe5, 0xe9, 0xeb, + 0xeb, 0xe5, 0xe3, 0xe3, 0xe1, 0xe1, 0xe5, 0xe7, 0xe7, 0xe5, 0xe3, 0xe3, + 0xe7, 0xeb, 0xeb, 0xe7, 0xe3, 0xe1, 0xe3, 0xe7, 0xe9, 0xeb, 0xe9, 0xe7, + 0xe5, 0xe5, 0xe5, 0xe9, 0xeb, 0xeb, 0xe9, 0xe7, 0xe7, 0xe9, 0xe7, 0xe7, + 0xe7, 0xe7, 0xe7, 0xe9, 0xe7, 0xe9, 0xeb, 0xed, 0xeb, 0xe7, 0xe7, 0xeb, + 0xed, 0xeb, 0xeb, 0xe9, 0xed, 0xef, 0xf1, 0xef, 0xed, 0xeb, 0xef, 0xf1, + 0xf3, 0xf5, 0xf3, 0xed, 0xeb, 0xed, 0xf3, 0xf3, 0xf3, 0xf7, 0xf9, 0xfb, + 0xfb, 0xf9, 0xf7, 0xf5, 0xf9, 0xfb, 0xfb, 0xf9, 0xf7, 0xf7, 0xfb, 0xfd, + 0xfd, 0xfb, 0xfb, 0xff, 0x03, 0x01, 0xfd, 0xf7, 0xf9, 0xfd, 0x03, 0x03, + 0x00, 0xff, 0xff, 0x00, 0x03, 0x03, 0x01, 0x03, 0x05, 0x07, 0x05, 0x03, + 0x01, 0x03, 0x05, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, + 0x00, 0x00, 0x03, 0x07, 0x09, 0x07, 0x05, 0x05, 0x05, 0x07, 0x05, 0x05, + 0x05, 0x05, 0x07, 0x09, 0x07, 0x05, 0x03, 0x07, 0x07, 0x05, 0x03, 0x03, + 0x07, 0x0b, 0x0b, 0x09, 0x03, 0x01, 0x03, 0x07, 0x05, 0x05, 0x01, 0x03, + 0x05, 0x07, 0x03, 0x00, 0x00, 0x01, 0x03, 0x03, 0x00, 0xff, 0x00, 0x03, + 0x09, 0x0b, 0x0b, 0x05, 0xff, 0xfb, 0x00, 0x03, 0x05, 0x03, 0x00, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0xff, 0xff, 0x00, 0x03, + 0x05, 0x05, 0x03, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x01, 0x00, 0x00, + 0x01, 0x05, 0x09, 0x07, 0x01, 0xff, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, + 0x01, 0x05, 0x07, 0x07, 0x03, 0x00, 0xff, 0xff, 0x00, 0x01, 0x03, 0x01, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00, 0xfb, 0xf9, 0x00, 0x00, 0x00, + 0x00, 0xf3, 0x05, 0x01, 0x00, 0xf7, 0x05, 0xf3, 0x11, 0x00, 0xeb, 0x09, + 0x05, 0xfb, 0xfb, 0x05, 0xf3, 0x15, 0xff, 0xd3, 0x2d, 0xf7, 0xf3, 0xef, + 0x21, 0xef, 0xf7, 0x0d, 0xfb, 0x00, 0xff, 0x00, 0x01, 0xef, 0x01, 0x0d, + 0xf3, 0xe7, 0x2d, 0xf3, 0xdb, 0x29, 0xf7, 0xfb, 0xef, 0x19, 0xfb, 0xf7, + 0xf3, 0x15, 0xff, 0x09, 0xd3, 0x25, 0x00, 0xeb, 0xff, 0x19, 0xff, 0xdf, + 0x1d, 0xff, 0xe7, 0x19, 0x00, 0xe7, 0x01, 0x09, 0xff, 0xf3, 0x0d, 0xfb, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x05, 0xef, + 0x15, 0x01, 0xcf, 0x21, 0x00, 0xe3, 0x11, 0x01, 0xff, 0xdf, 0x2d, 0xef, + 0xe3, 0x1d, 0xf3, 0x09, 0xff, 0xff, 0x01, 0x05, 0xdb, 0x1d, 0xfb, 0x00, + 0x01, 0xf7, 0x00, 0x0d, 0xe7, 0x05, 0x09, 0x05, 0xeb, 0xf3, 0x21, 0xf7, + 0xe7, 0x15, 0x05, 0xef, 0xff, 0x0d, 0xf3, 0x0d, 0x01, 0xe3, 0x0d, 0xfb, + 0x15, 0xef, 0xef, 0x1d, 0xf7, 0x09, 0xeb, 0x05, 0x05, 0x05, 0xe7, 0xff, + 0x1d, 0xfb, 0xe3, 0x19, 0x00, 0xff, 0xf3, 0x05, 0x09, 0x00, 0xdb, 0x25, + 0xfb, 0xf3, 0x09, 0x09, 0xf3, 0xf7, 0x05, 0x00, 0x0d, 0xeb, 0xff, 0x19, + 0xdf, 0x0d, 0x09, 0xf7, 0xeb, 0x1d, 0x00, 0xe7, 0x00, 0x15, 0xf3, 0x00, + 0x00, 0x00, 0xff, 0xfb, 0x05, 0xff, 0xff, 0x00, 0x00, 0x00, 0xfb, 0x00, + 0x01, 0x05, 0xf3, 0xeb, 0x21, 0xff, 0xf7, 0xeb, 0x21, 0x00, 0xe3, 0x01, + 0x0d, 0x00, 0xdf, 0x1d, 0xfb, 0xfb, 0x00, 0x0d, 0xef, 0xf7, 0x11, 0x00, + 0xf3, 0x05, 0x0d, 0xeb, 0xf3, 0x19, 0xf3, 0x09, 0xef, 0x00, 0x05, 0x01, + 0x00, 0xf7, 0x01, 0x09, 0xe3, 0x05, 0x09, 0x00, 0xdf, 0x1d, 0x00, 0xef, + 0xff, 0x11, 0xf7, 0x01, 0x09, 0xdb, 0x11, 0x09, 0xf7, 0xf3, 0x11, 0xff, + 0xf7, 0xff, 0x09, 0xfb, 0xf7, 0x19, 0xe7, 0xfb, 0x11, 0x01, 0xdf, 0x11, + 0x00, 0x09, 0xeb, 0xff, 0x15, 0xfb, 0xef, 0x0d, 0xf7, 0x01, 0x05, 0xf7, + 0x01, 0x05, 0xf3, 0x00, 0x09, 0xeb, 0x05, 0x01, 0x01, 0xe3, 0x1d, 0x00, + 0xe7, 0x11, 0xf3, 0x15, 0xfb, 0xe7, 0x1d, 0xf3, 0xf7, 0x05, 0x09, 0xf7, + 0xeb, 0x1d, 0xff, 0xef, 0x00, 0x0d, 0xf7, 0x09, 0x00, 0xd7, 0x29, 0xfb, + 0xef, 0x00, 0x0d, 0x00, 0xdb, 0x29, 0xef, 0xeb, 0x19, 0x00, 0xe7, 0x0d, + 0x01, 0x09, 0xdf, 0x09, 0x09, 0x01, 0xdb, 0x15, 0x01, 0xfb, 0xf3, 0x15, + 0xf3, 0xef, 0x0d, 0x01, 0xff, 0xeb, 0x15, 0xff, 0xfb, 0xf7, 0x09, 0x01, + 0xfb, 0xef, 0x19, 0xff, 0xe3, 0x15, 0x00, 0xeb, 0x11, 0xef, 0x05, 0x0d, + 0xe7, 0x00, 0x09, 0x00, 0xfb, 0x00, 0xff, 0x01, 0x05, 0xe7, 0x00, 0x11, + 0x01, 0xdf, 0x11, 0x05, 0x00, 0xeb, 0x11, 0xff, 0x09, 0xeb, 0x01, 0x00, + 0x0d, 0xeb, 0xff, 0x09, 0x01, 0xf7, 0xf7, 0x0d, 0xfb, 0x0d, 0xf7, 0xe3, + 0x25, 0xfb, 0xe7, 0x05, 0x0d, 0x00, 0xdb, 0x21, 0xfb, 0xfb, 0xf7, 0x11, + 0xfb, 0xfb, 0x05, 0x00, 0xfb, 0xff, 0x05, 0x05, 0xef, 0xf7, 0x15, 0xe7, + 0x09, 0x0d, 0xef, 0xf3, 0x25, 0xdb, 0x01, 0x09, 0x01, 0xdf, 0x15, 0x00, + 0xff, 0xf7, 0x09, 0xfb, 0x00, 0xff, 0xff, 0x00, 0xff, 0x05, 0x00, 0xe7, + 0x19, 0x01, 0xe3, 0x11, 0x05, 0x00, 0xe3, 0x15, 0xf7, 0x11, 0xf7, 0xe7, + 0x19, 0xff, 0x01, 0xdf, 0x25, 0xef, 0xf7, 0x09, 0x00, 0xfb, 0xfb, 0x09, + 0xfb, 0xf7, 0x09, 0xff, 0xfb, 0x00, 0x09, 0x00, 0xdb, 0x1d, 0xf7, 0x05, + 0xf3, 0x09, 0x09, 0xdf, 0x09, 0x09, 0x00, 0xe3, 0x1d, 0xeb, 0x09, 0x01, + 0xef, 0x05, 0x05, 0x00, 0xe3, 0x19, 0xf7, 0xff, 0x0d, 0xff, 0xdb, 0x25, + 0xff, 0xef, 0xff, 0x19, 0xeb, 0xff, 0x0d, 0x01, 0xef, 0x00, 0x15, 0xe3, + 0x09, 0x05, 0x00, 0xe7, 0x11, 0xff, 0x00, 0xfb, 0x09, 0xfb, 0xf3, 0x11, + 0x01, 0xdb, 0x1d, 0x00, 0xff, 0xf3, 0x15, 0xfb, 0xf3, 0x09, 0x05, 0xe7, + 0x01, 0x0d, 0xff, 0xeb, 0x0d, 0x01, 0xfb, 0xfb, 0x05, 0x00, 0xfb, 0x01, + 0x01, 0xf3, 0x05, 0x05, 0xff, 0xef, 0x15, 0xfb, 0xef, 0x0d, 0x00, 0xfb, + 0x0d, 0xf3, 0xf3, 0x19, 0xff, 0xe7, 0x0d, 0x01, 0xff, 0xf7, 0x09, 0xf7, + 0x05, 0x05, 0xef, 0x01, 0x00, 0x09, 0xf7, 0xf7, 0x15, 0xe7, 0x15, 0xf7, + 0xeb, 0x15, 0xff, 0xf7, 0x00, 0x01, 0x00, 0x00, 0x00, 0xeb, 0x15, 0xfb, + 0xfb, 0x01, 0xff, 0x05, 0x01, 0xeb, 0x19, 0x00, 0xf3, 0xff, 0x11, 0xf3, + 0xfb, 0x09, 0x09, 0xe3, 0x11, 0xf7, 0x00, 0x00, 0x09, 0xf7, 0xf3, 0x11, + 0x01, 0xe3, 0x0d, 0x00, 0x01, 0x01, 0xe3, 0x11, 0x01, 0xfb, 0xf7, 0x0d, + 0xff, 0xfb, 0xff, 0x00, 0x01, 0x05, 0xe7, 0x0d, 0xf7, 0x09, 0xf7, 0x01, + 0x01, 0xeb, 0x11, 0x01, 0xe7, 0x01, 0x0d, 0xff, 0xe7, 0x21, 0xfb, 0xe7, + 0x11, 0x00, 0xfb, 0xff, 0x0d, 0xef, 0xfb, 0x09, 0x00, 0x05, 0xef, 0x0d, + 0x01, 0xe7, 0x0d, 0xfb, 0x00, 0x05, 0xf7, 0xff, 0x0d, 0xfb, 0xf3, 0x11, + 0x05, 0xeb, 0x01, 0x05, 0x00, 0x01, 0xe7, 0x09, 0x01, 0x01, 0xfb, 0xeb, + 0x15, 0xff, 0x01, 0xef, 0x11, 0x00, 0xf7, 0xff, 0x05, 0x09, 0xeb, 0x05, + 0xff, 0x00, 0x05, 0xf7, 0xfb, 0x09, 0x05, 0xf3, 0xf3, 0x15, 0x00, 0xe7, + 0x09, 0x01, 0xff, 0xf3, 0x0d, 0x00, 0xfb, 0x00, 0x01, 0xff, 0x01, 0x09, + 0xe7, 0xff, 0x11, 0xf3, 0x05, 0x00, 0xfb, 0x00, 0xff, 0x01, 0x05, 0xf3, + 0x00, 0x05, 0xf7, 0x05, 0xff, 0xf7, 0x01, 0x09, 0xef, 0xf7, 0x15, 0xf7, + 0xff, 0x0d, 0xf7, 0xeb, 0x21, 0xfb, 0xeb, 0x05, 0x01, 0x05, 0xe3, 0x11, + 0x01, 0xff, 0xeb, 0x21, 0xe3, 0x00, 0x0d, 0x00, 0xe7, 0x0d, 0x01, 0x01, + 0xe3, 0x19, 0x00, 0xf7, 0xff, 0x05, 0xfb, 0x05, 0xf7, 0x00, 0x00, 0xfb, + 0x00, 0x0d, 0xf7, 0xef, 0x15, 0xfb, 0xfb, 0x09, 0x01, 0xe3, 0x11, 0x01, + 0xff, 0xef, 0x15, 0xff, 0xf7, 0x01, 0x00, 0xff, 0x09, 0xfb, 0xeb, 0x15, + 0xff, 0xef, 0x01, 0x01, 0x00, 0x09, 0xe3, 0x09, 0x05, 0x01, 0xe3, 0x19, + 0x00, 0xf7, 0xfb, 0x05, 0xf7, 0x09, 0x00, 0xe7, 0x11, 0xfb, 0x05, 0xf7, + 0x01, 0x01, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0xe3, 0x15, 0x00, 0x00, + 0xeb, 0x19, 0xff, 0xeb, 0x0d, 0x09, 0xef, 0x00, 0x09, 0x01, 0xe3, 0x11, + 0x01, 0xf7, 0xf3, 0x1d, 0xe3, 0x01, 0x09, 0x01, 0xe7, 0x11, 0xf7, 0x09, + 0xfb, 0x01, 0x09, 0xe3, 0x09, 0x05, 0xff, 0xe7, 0x15, 0x00, 0x00, 0xe7, + 0x1d, 0xff, 0xef, 0x01, 0x09, 0xfb, 0xfb, 0x00, 0xff, 0x09, 0xfb, 0xf7, + 0x09, 0x00, 0xff, 0xff, 0x01, 0xf3, 0x0d, 0x01, 0xef, 0xff, 0x0d, 0x00, + 0xe7, 0x11, 0x01, 0xe7, 0x11, 0x01, 0xfb, 0xfb, 0x0d, 0xfb, 0xfb, 0x05, + 0x00, 0xfb, 0xff, 0x01, 0x05, 0xfb, 0xef, 0x15, 0xef, 0x01, 0x0d, 0xfb, + 0xeb, 0x21, 0xeb, 0xfb, 0x0d, 0x01, 0xeb, 0x09, 0x05, 0xff, 0xf3, 0x09, + 0xff, 0x00, 0x01, 0xfb, 0xf3, 0x15, 0xfb, 0xf3, 0x09, 0x00, 0x05, 0xeb, + 0x0d, 0x00, 0xfb, 0x05, 0xfb, 0x01, 0xff, 0x00, 0xff, 0xff, 0x01, 0x05, + 0xef, 0xff, 0x0d, 0x00, 0xeb, 0x19, 0xff, 0xeb, 0x0d, 0x00, 0xf7, 0xff, + 0x09, 0xff, 0xf3, 0x11, 0x00, 0xe7, 0x11, 0x00, 0x05, 0xe7, 0x11, 0x01, + 0xf3, 0x05, 0x00, 0x09, 0xe3, 0x11, 0x01, 0xeb, 0x0d, 0xfb, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0xff, 0x05, 0x05, 0xdf, 0x15, 0x00, 0xf7, 0xff, + 0x0d, 0xfb, 0xf7, 0x05, 0x00, 0x00, 0xfb, 0x01, 0xfb, 0x00, 0x01, 0x05, + 0xef, 0x09, 0xfb, 0x09, 0x00, 0xeb, 0x0d, 0xfb, 0x09, 0xeb, 0x09, 0x00, + 0x09, 0xe7, 0x05, 0x01, 0x01, 0xe3, 0x15, 0x00, 0xff, 0xf7, 0x0d, 0xf7, + 0x00, 0x09, 0xef, 0x01, 0x11, 0xef, 0xf7, 0x11, 0xff, 0xef, 0x09, 0xfb, + 0x01, 0x01, 0x00, 0xeb, 0x15, 0xff, 0xf7, 0x01, 0x00, 0x09, 0xf7, 0xf3, + 0x0d, 0x01, 0xf3, 0xfb, 0x11, 0x00, 0xeb, 0x0d, 0xfb, 0x00, 0x01, 0x00, + 0xf7, 0x00, 0x05, 0x01, 0xef, 0x09, 0x00, 0xff, 0xff, 0x09, 0xeb, 0x00, + 0x11, 0xfb, 0xe7, 0x19, 0xff, 0xfb, 0xfb, 0x11, 0xfb, 0xfb, 0x01, 0xfb, + 0x01, 0x05, 0xff, 0xf7, 0x0d, 0xff, 0xfb, 0x01, 0x00, 0xf7, 0x05, 0x05, + 0xf7, 0xff, 0x09, 0xf7, 0x00, 0x01, 0x05, 0xeb, 0x05, 0x09, 0xff, 0xeb, + 0x15, 0xfb, 0x05, 0xf7, 0xf3, 0x19, 0xff, 0xeb, 0x0d, 0x00, 0xff, 0xf3, + 0x09, 0xfb, 0x09, 0xef, 0x00, 0x01, 0xff, 0x00, 0xff, 0x09, 0xe7, 0x09, + 0x05, 0xf3, 0xff, 0x0d, 0x00, 0xe7, 0x11, 0x00, 0xf3, 0xfb, 0x0d, 0x00, + 0xeb, 0x0d, 0x01, 0xff, 0xf7, 0x09, 0xfb, 0x00, 0x01, 0x01, 0xef, 0x05, + 0x00, 0xff, 0x00, 0x09, 0xeb, 0x05, 0x09, 0xef, 0x01, 0x05, 0x00, 0xeb, + 0x0d, 0x00, 0xfb, 0xf3, 0x11, 0xfb, 0x00, 0x00, 0xfb, 0x05, 0xff, 0xff, + 0x00, 0x00, 0xff, 0x01, 0xef, 0x05, 0x09, 0xfb, 0xf3, 0x0d, 0xfb, 0x01, + 0xff, 0x00, 0xff, 0x01, 0x05, 0xef, 0x00, 0x0d, 0xfb, 0xf3, 0x09, 0x00, + 0xfb, 0xff, 0x01, 0x05, 0xf3, 0xff, 0x09, 0x00, 0xfb, 0xf7, 0x09, 0x01, + 0xf3, 0x01, 0x05, 0xf3, 0xff, 0x01, 0xfb, 0x05, 0x00, 0xf7, 0x05, 0xfb, + 0x01, 0x00, 0xf7, 0x05, 0x00, 0xf7, 0x09, 0x00, 0xeb, 0x0d, 0x01, 0xff, + 0xeb, 0x1d, 0xf7, 0xff, 0xf3, 0x11, 0xfb, 0xf7, 0x05, 0x00, 0xfb, 0xff, + 0x01, 0xfb, 0x00, 0x01, 0x01, 0xe7, 0x0d, 0xff, 0x05, 0xe7, 0x09, 0x01, + 0xff, 0xf3, 0x09, 0xfb, 0x09, 0xf7, 0xfb, 0x09, 0x00, 0xeb, 0x0d, 0x00, + 0xff, 0xef, 0x15, 0xff, 0xef, 0x09, 0x05, 0xef, 0x00, 0x09, 0xf3, 0xfb, + 0x09, 0x00, 0xf3, 0x05, 0xff, 0x09, 0xf3, 0xfb, 0x09, 0x01, 0xeb, 0x09, + 0x01, 0xeb, 0x0d, 0x00, 0xeb, 0x11, 0xff, 0xf7, 0x01, 0x05, 0xef, 0x01, + 0x05, 0xf3, 0x05, 0x00, 0x00, 0xff, 0xef, 0x11, 0x00, 0xf3, 0x09, 0xff, + 0x01, 0xff, 0xef, 0x09, 0x00, 0x01, 0xef, 0x09, 0x00, 0xfb, 0xff, 0x09, + 0xf3, 0x01, 0x05, 0xf7, 0xff, 0x01, 0x09, 0xef, 0xfb, 0x11, 0x00, 0xe7, + 0x11, 0x00, 0xef, 0x09, 0x00, 0x00, 0xef, 0x0d, 0xff, 0x00, 0x00, 0x05, + 0xe7, 0x05, 0x09, 0xff, 0xef, 0x0d, 0xff, 0x05, 0xe7, 0x0d, 0x01, 0x00, + 0xeb, 0x11, 0xfb, 0x00, 0x00, 0xf3, 0x09, 0x01, 0xff, 0xf3, 0x0d, 0xfb, + 0xff, 0x05, 0xff, 0xfb, 0x05, 0x01, 0xeb, 0x09, 0x01, 0xfb, 0xf7, 0x0d, + 0x00, 0xe7, 0x11, 0x00, 0x01, 0xeb, 0x15, 0xff, 0xf7, 0xff, 0x0d, 0xfb, + 0xef, 0x11, 0x00, 0xef, 0x01, 0x0d, 0xeb, 0x09, 0x01, 0x00, 0xef, 0x0d, + 0xf7, 0x09, 0xff, 0xf3, 0x09, 0xff, 0xfb, 0xff, 0x05, 0xfb, 0x00, 0x05, + 0x01, 0xdf, 0x1d, 0xfb, 0xfb, 0xfb, 0x0d, 0xfb, 0xf3, 0x09, 0xfb, 0x01, + 0x01, 0xef, 0x05, 0x01, 0x05, 0xeb, 0x09, 0x00, 0x05, 0xf7, 0xf7, 0x15, + 0xff, 0xef, 0x09, 0x05, 0xef, 0x09, 0x00, 0x00, 0xf3, 0x05, 0x00, 0xfb, + 0x00, 0x05, 0xfb, 0xeb, 0x19, 0xf7, 0x01, 0xef, 0x0d, 0x00, 0xfb, 0xfb, + 0x05, 0x00, 0x01, 0xf3, 0x00, 0x09, 0xfb, 0xf7, 0x09, 0x01, 0xf3, 0x01, + 0x05, 0xfb, 0xff, 0x0d, 0xf3, 0xf7, 0x11, 0x00, 0xef, 0x05, 0x00, 0x05, + 0xf3, 0xff, 0x05, 0xff, 0xff, 0x05, 0xef, 0x05, 0x05, 0xf3, 0xfb, 0x0d, + 0xff, 0x01, 0xef, 0x09, 0x01, 0xff, 0xf7, 0x05, 0x01, 0xf7, 0x05, 0x01, + 0xf7, 0xfb, 0x0d, 0xfb, 0xf7, 0x05, 0x00, 0xff, 0xff, 0x01, 0x05, 0xf7, + 0xf7, 0x11, 0xf7, 0xf7, 0x05, 0x05, 0xf7, 0xfb, 0x09, 0x00, 0xff, 0xfb, + 0x09, 0xf7, 0xfb, 0x0d, 0x00, 0xf3, 0x00, 0x0d, 0xf3, 0xf7, 0x11, 0xfb, + 0xff, 0x01, 0xff, 0xff, 0x09, 0xf3, 0xff, 0x09, 0x00, 0xf3, 0x01, 0x00, + 0x05, 0xfb, 0xff, 0x05, 0xfb, 0xf7, 0x09, 0x01, 0xe7, 0x11, 0x00, 0xff, + 0xef, 0x11, 0xff, 0xf3, 0x09, 0x00, 0xff, 0x00, 0xff, 0x00, 0x01, 0x00, + 0xf3, 0x09, 0x01, 0xfb, 0xf3, 0x15, 0xff, 0xeb, 0x11, 0x00, 0xef, 0x05, + 0xfb, 0x09, 0xf7, 0x01, 0x01, 0xf7, 0xff, 0x09, 0xfb, 0xfb, 0x01, 0x01, + 0x01, 0xe3, 0x15, 0xff, 0xff, 0xef, 0x11, 0xff, 0xf3, 0x00, 0x00, 0x05, + 0xfb, 0xf3, 0x11, 0xf3, 0x09, 0xfb, 0xf7, 0x0d, 0xfb, 0x00, 0xff, 0x05, + 0xff, 0xe7, 0x21, 0xef, 0x05, 0xfb, 0xff, 0x01, 0x01, 0xfb, 0xff, 0x01, + 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x05, 0xeb, 0x11, 0xff, 0xf3, 0x09, + 0x00, 0x01, 0xeb, 0x11, 0xfb, 0xf7, 0x09, 0xf7, 0x01, 0x01, 0xff, 0xfb, + 0x01, 0x00, 0xfb, 0x01, 0x01, 0xfb, 0xef, 0x19, 0xff, 0xeb, 0x09, 0x00, + 0x01, 0xfb, 0xf3, 0x11, 0x00, 0xf3, 0x00, 0x01, 0x01, 0x00, 0xf3, 0x09, + 0xfb, 0x09, 0xfb, 0xef, 0x15, 0xf7, 0x00, 0x00, 0xf7, 0x01, 0x01, 0xf7, + 0x05, 0x00, 0xff, 0xfb, 0xff, 0x09, 0x00, 0xeb, 0x0d, 0xff, 0x05, 0xf3, + 0xff, 0x0d, 0xfb, 0xf3, 0x09, 0x01, 0xf7, 0xff, 0x05, 0xf7, 0x01, 0xfb, + 0x00, 0x05, 0xf3, 0x01, 0x01, 0xf7, 0xff, 0x01, 0x01, 0xfb, 0xf3, 0x15, + 0xff, 0xf3, 0x05, 0x00, 0xfb, 0xff, 0x05, 0xf3, 0x05, 0x00, 0xfb, 0xff, + 0x01, 0x01, 0xfb, 0x01, 0xfb, 0x01, 0x01, 0xeb, 0x05, 0x01, 0xff, 0xfb, + 0x05, 0xff, 0x09, 0xef, 0x00, 0x09, 0x00, 0xef, 0x0d, 0x00, 0xf3, 0x05, + 0x00, 0x00, 0xf3, 0x15, 0xf3, 0xf3, 0x15, 0xf3, 0xfb, 0x09, 0x01, 0xef, + 0x05, 0xff, 0x01, 0x00, 0xf7, 0x01, 0x05, 0xf7, 0x00, 0x09, 0xe7, 0x0d, + 0x01, 0xfb, 0xf7, 0x09, 0x00, 0xef, 0x05, 0x01, 0xff, 0xf7, 0x05, 0xfb, + 0x05, 0xfb, 0xfb, 0x05, 0xfb, 0x01, 0x00, 0x00, 0xff, 0xff, 0x05, 0xff, + 0xfb, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xf7, 0x09, 0xff, 0x01, 0xef, + 0x09, 0xfb, 0x09, 0xef, 0x00, 0x01, 0x01, 0xfb, 0xf7, 0x0d, 0xff, 0xf3, + 0x05, 0xff, 0x01, 0x00, 0xef, 0x0d, 0xff, 0x05, 0xff, 0xf3, 0x0d, 0x00, + 0xf7, 0xff, 0x05, 0xff, 0x05, 0xf7, 0xfb, 0x09, 0x01, 0xef, 0x01, 0x05, + 0x00, 0xef, 0x09, 0x00, 0x01, 0xeb, 0x0d, 0x00, 0xf3, 0x01, 0x05, 0x00, + 0xf3, 0x11, 0xff, 0xef, 0x11, 0xff, 0xff, 0xf7, 0x0d, 0xff, 0xef, 0x0d, + 0xff, 0x01, 0xeb, 0x0d, 0xff, 0x00, 0xfb, 0xff, 0x01, 0xfb, 0x00, 0x01, + 0x00, 0xe7, 0x19, 0xf7, 0xfb, 0x05, 0x00, 0x00, 0xf7, 0x01, 0x00, 0x00, + 0x00, 0xff, 0xfb, 0x05, 0xff, 0xff, 0x00, 0x00, 0x01, 0x05, 0xe7, 0x15, + 0x00, 0xfb, 0xfb, 0x01, 0x05, 0xf7, 0xfb, 0x09, 0x00, 0xff, 0x00, 0x01, + 0xf3, 0x0d, 0xff, 0xf3, 0x0d, 0x00, 0xff, 0xf3, 0x11, 0xff, 0xf7, 0x00, + 0x05, 0xff, 0xfb, 0xff, 0x05, 0x01, 0xf7, 0xf7, 0x11, 0x00, 0xf3, 0xff, + 0x09, 0xff, 0xff, 0x00, 0xff, 0x00, 0x01, 0xfb, 0xf7, 0x0d, 0x00, 0xf7, + 0x00, 0x00, 0x01, 0xff, 0xf7, 0x09, 0x00, 0xf3, 0x00, 0x05, 0xff, 0xef, + 0x11, 0xff, 0xf3, 0x05, 0x01, 0x00, 0xef, 0x11, 0xff, 0xf3, 0x05, 0x01, + 0xf7, 0xf7, 0x11, 0xff, 0xef, 0x0d, 0x00, 0xfb, 0xf7, 0x0d, 0xff, 0xef, + 0x0d, 0x00, 0x00, 0xf7, 0x09, 0x01, 0xf3, 0x01, 0x00, 0x05, 0xef, 0x01, + 0x05, 0x00, 0xef, 0x0d, 0xff, 0xff, 0xff, 0x05, 0xfb, 0x00, 0x01, 0x05, + 0xe3, 0x11, 0xff, 0x01, 0xff, 0xf3, 0x11, 0x00, 0xef, 0x09, 0x00, 0x00, + 0xef, 0x0d, 0xff, 0xfb, 0x01, 0x01, 0xf3, 0x00, 0x09, 0xfb, 0xfb, 0x00, + 0x00, 0x05, 0xf3, 0x05, 0x01, 0xf7, 0x00, 0x05, 0xfb, 0xfb, 0x05, 0x00, + 0xfb, 0xfb, 0x0d, 0xef, 0xfb, 0x0d, 0xff, 0xef, 0x09, 0x01, 0xfb, 0xf7, + 0x09, 0x01, 0xf7, 0xfb, 0x0d, 0xf7, 0xfb, 0x09, 0x00, 0xf3, 0x01, 0x09, + 0xfb, 0xf3, 0x11, 0xff, 0xef, 0x09, 0xff, 0x01, 0xef, 0x09, 0xff, 0x01, + 0xff, 0xff, 0xff, 0x01, 0x00, 0xff, 0x00, 0x00, 0x00, 0x05, 0xef, 0xff, + 0x0d, 0xfb, 0xff, 0x01, 0xff, 0xfb, 0x00, 0x00, 0x01, 0xfb, 0xff, 0x0d, + 0xeb, 0x05, 0x01, 0x05, 0xeb, 0x09, 0x01, 0xfb, 0xf7, 0x0d, 0xf7, 0xff, + 0x09, 0x00, 0xf7, 0x00, 0x01, 0x01, 0xff, 0xf3, 0x11, 0xfb, 0xfb, 0xff, + 0x09, 0xf7, 0xf7, 0x11, 0xff, 0xef, 0x09, 0x00, 0x01, 0xef, 0x0d, 0xff, + 0x01, 0xf3, 0x05, 0x01, 0x00, 0xf3, 0x09, 0x00, 0xff, 0xff, 0x05, 0xff, + 0x00, 0x05, 0xfb, 0xef, 0x15, 0xff, 0xf3, 0x05, 0x05, 0xfb, 0xf3, 0x0d, + 0x00, 0xff, 0xf7, 0x09, 0xfb, 0xf7, 0x11, 0xf7, 0xfb, 0x05, 0x01, 0xfb, + 0xf7, 0x15, 0xf7, 0xef, 0x11, 0xff, 0xff, 0xfb, 0x01, 0x01, 0xff, 0xf7, + 0x09, 0xff, 0x00, 0xfb, 0x00, 0x01, 0xff, 0x05, 0xff, 0xf3, 0x11, 0xff, + 0xf3, 0x05, 0x00, 0x01, 0xef, 0x05, 0xff, 0x01, 0xfb, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x01, 0xe7, 0x0d, 0x00, 0xff, 0xf7, + 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x01, + 0xf3, 0x00, 0x01, 0x01, 0xef, 0x09, 0x00, 0xf7, 0x00, 0xff, 0x09, 0xf3, + 0xff, 0x05, 0x01, 0xef, 0x05, 0x01, 0x00, 0xef, 0x0d, 0xff, 0xfb, 0x01, + 0x05, 0xeb, 0x09, 0x00, 0xff, 0xf3, 0x0d, 0x00, 0xf7, 0x00, 0x01, 0x00, + 0xff, 0x01, 0xff, 0x00, 0x01, 0xff, 0xef, 0x0d, 0xfb, 0x01, 0xff, 0xfb, + 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xf7, 0x09, 0x00, 0xff, 0xfb, + 0x09, 0xf3, 0x05, 0xff, 0xff, 0x00, 0x00, 0x00, 0xfb, 0x01, 0x01, 0xfb, + 0xfb, 0x09, 0x00, 0xfb, 0xff, 0x05, 0x01, 0xf3, 0x00, 0x09, 0xf7, 0x01, + 0xff, 0x00, 0x00, 0x00, 0x01, 0xf7, 0xff, 0x09, 0xff, 0xfb, 0x01, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x01, 0x00, 0xf3, 0x05, 0x00, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x05, 0xeb, 0x05, 0x01, 0xff, 0xf3, 0x09, 0xff, 0xf7, 0x05, + 0xfb, 0x05, 0xfb, 0xff, 0x05, 0xf7, 0x01, 0x01, 0x01, 0xef, 0x11, 0xff, + 0xf3, 0x05, 0x01, 0x00, 0xef, 0x11, 0xff, 0xf3, 0x05, 0xfb, 0x09, 0xf3, + 0x00, 0x05, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x01, 0x00, 0xfb, 0xfb, + 0x0d, 0xf7, 0xff, 0x05, 0x00, 0xf7, 0x00, 0x01, 0x01, 0xf7, 0x00, 0x00, + 0x01, 0x00, 0xfb, 0x01, 0x00, 0x00, 0x01, 0x00, 0xeb, 0x11, 0xfb, 0x05, + 0xf3, 0x05, 0x01, 0xf3, 0x01, 0x00, 0x00, 0xef, 0x11, 0xfb, 0xf7, 0x09, + 0xfb, 0xff, 0x01, 0x01, 0xf3, 0x01, 0x05, 0x00, 0xf7, 0x05, 0x00, 0xff, + 0xff, 0x00, 0x05, 0xfb, 0xfb, 0x05, 0x01, 0xfb, 0xf7, 0x11, 0xfb, 0xfb, + 0x05, 0x00, 0xf7, 0x00, 0x09, 0xf3, 0xff, 0x09, 0x00, 0xf3, 0x01, 0x05, + 0xff, 0xf7, 0x11, 0xfb, 0xf3, 0x11, 0xf3, 0x01, 0x00, 0x00, 0x01, 0xfb, + 0xf3, 0x11, 0xf7, 0x01, 0xfb, 0x00, 0x05, 0x00, 0xfb, 0xff, 0x01, 0x01, + 0xff, 0xf7, 0x05, 0x00, 0x01, 0xf3, 0x09, 0x01, 0xf7, 0x00, 0x01, 0x01, + 0xf7, 0xfb, 0x09, 0x01, 0xef, 0x01, 0x01, 0x01, 0xef, 0x05, 0x01, 0xf7, + 0x00, 0x05, 0x00, 0xf3, 0x0d, 0xff, 0xf3, 0x09, 0x01, 0xfb, 0xf7, 0x09, + 0x01, 0xf3, 0x05, 0xff, 0x05, 0xff, 0xef, 0x11, 0xfb, 0xff, 0xff, 0x05, + 0xfb, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x01, 0xff, 0xff, 0x00, 0x01, 0x00, + 0xeb, 0x19, 0xf7, 0xfb, 0x05, 0x00, 0xef, 0x0d, 0x00, 0x00, 0xef, 0x15, + 0xfb, 0xf3, 0x09, 0xff, 0xff, 0xf7, 0x0d, 0xfb, 0xf3, 0x09, 0xff, 0x01, + 0xef, 0x0d, 0x00, 0xf7, 0x05, 0x01, 0xfb, 0xfb, 0x09, 0x00, 0xef, 0x09, + 0xff, 0x01, 0xef, 0x09, 0xff, 0x01, 0xf7, 0xff, 0x05, 0xff, 0x00, 0xf3, + 0x0d, 0xff, 0xff, 0x00, 0x01, 0xff, 0x00, 0x01, 0xef, 0x05, 0x00, 0xff, + 0xfb, 0x00, 0x01, 0xfb, 0x00, 0x01, 0x01, 0xf3, 0x01, 0x05, 0xf3, 0x01, + 0x01, 0x00, 0xf3, 0x11, 0xfb, 0xf3, 0x09, 0xff, 0xff, 0xfb, 0x0d, 0xff, + 0xf3, 0x09, 0xff, 0x05, 0xef, 0x05, 0x01, 0xff, 0xf3, 0x09, 0x00, 0xf7, + 0x00, 0x09, 0xef, 0x01, 0x00, 0x05, 0xef, 0x05, 0x00, 0x01, 0xef, 0x09, + 0xff, 0x00, 0xef, 0x11, 0xfb, 0xff, 0xff, 0x01, 0xff, 0xff, 0x01, 0x05, + 0xeb, 0x09, 0x01, 0xfb, 0xfb, 0x09, 0xfb, 0xf3, 0x09, 0xff, 0x00, 0xff, + 0x00, 0x01, 0x00, 0xef, 0x09, 0xff, 0x01, 0x00, 0x00, 0xfb, 0x05, 0xff, + 0xef, 0x11, 0xff, 0xff, 0xfb, 0x05, 0xff, 0x05, 0xf7, 0xfb, 0x09, 0x00, + 0xfb, 0xf7, 0x0d, 0xfb, 0xff, 0x01, 0xff, 0xfb, 0x05, 0x01, 0xf3, 0x05, + 0x01, 0x01, 0xef, 0x09, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xf7, 0x09, 0x00, + 0xf3, 0x09, 0x00, 0x01, 0xef, 0x09, 0xff, 0x01, 0xf3, 0x05, 0x00, 0x00, + 0xfb, 0xff, 0x01, 0xff, 0xff, 0x05, 0xf7, 0xff, 0x05, 0xff, 0xff, 0xff, + 0x05, 0xef, 0x05, 0x05, 0xfb, 0xf3, 0x09, 0x01, 0xfb, 0xf7, 0x09, 0x00, + 0xff, 0xf7, 0x0d, 0xff, 0xf7, 0x00, 0x05, 0xfb, 0xff, 0x09, 0xef, 0x00, + 0x05, 0x00, 0xef, 0x0d, 0x00, 0xfb, 0xfb, 0x09, 0x00, 0xf3, 0x01, 0x01, + 0xff, 0xf7, 0x05, 0xff, 0xff, 0xff, 0x01, 0xff, 0x00, 0xff, 0xff, 0x00, + 0xff, 0xff, 0x00, 0x01, 0xef, 0x01, 0x05, 0x00, 0xf7, 0x09, 0xf3, 0x05, + 0x00, 0x01, 0xf7, 0x00, 0x05, 0x00, 0xff, 0xf7, 0x0d, 0xfb, 0xff, 0x01, + 0x01, 0xf7, 0xfb, 0x0d, 0xfb, 0xf3, 0x11, 0xf7, 0x00, 0x01, 0xff, 0xff, + 0x00, 0x01, 0xff, 0xef, 0x19, 0xf7, 0xf7, 0x09, 0x00, 0xff, 0xfb, 0x05, + 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x09, 0x00, + 0xf3, 0x05, 0x00, 0x00, 0xf3, 0x0d, 0xff, 0xf7, 0x05, 0xff, 0x05, 0xf3, + 0x05, 0x05, 0xf7, 0x00, 0x05, 0xff, 0xfb, 0x05, 0x01, 0xf3, 0x01, 0x01, + 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xfb, 0x0d, 0xff, 0xf3, 0x0d, 0xfb, + 0x01, 0x00, 0xef, 0x0d, 0xfb, 0x01, 0xf7, 0xff, 0x01, 0xff, 0x00, 0xff, + 0x01, 0x01, 0xfb, 0xff, 0x01, 0x01, 0xff, 0xfb, 0x09, 0xf3, 0x01, 0x00, + 0x01, 0xf3, 0x01, 0x05, 0xf7, 0x00, 0x05, 0x01, 0xef, 0x09, 0x00, 0x00, + 0xf7, 0x05, 0x00, 0x00, 0xf7, 0x09, 0xfb, 0xfb, 0x01, 0x00, 0xfb, 0x00, + 0x05, 0xff, 0xf3, 0x11, 0xfb, 0xfb, 0x00, 0x01, 0x00, 0x05, 0xef, 0x09, + 0x01, 0xfb, 0xff, 0x05, 0x00, 0xff, 0xfb, 0x05, 0xff, 0x00, 0x00, 0xf3, + 0x05, 0x01, 0xf7, 0x00, 0x01, 0x01, 0xf3, 0x01, 0x00, 0x01, 0xf7, 0x09, + 0xfb, 0xff, 0x01, 0x01, 0xf3, 0x01, 0x00, 0x01, 0xf3, 0x00, 0x05, 0x00, + 0xef, 0x0d, 0xff, 0xff, 0xff, 0x01, 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, + 0xfb, 0x05, 0xff, 0xff, 0x01, 0xff, 0x00, 0xff, 0x00, 0x01, 0xf3, 0x09, + 0x00, 0x00, 0xf7, 0x09, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0xfc, 0xf0, 0x10, 0xfc, 0xf8, 0x04, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0c, 0xfc, 0x00, 0x00, 0x04, + 0xfc, 0xf8, 0x0b, 0x00, 0xf8, 0x00, 0x04, 0x00, 0xf8, 0x00, 0x00, 0x00, + 0xfc, 0x04, 0x00, 0xf5, 0x00, 0x00, 0x00, 0xf2, 0x07, 0x00, 0xf9, 0x00, + 0x04, 0x00, 0xf9, 0x04, 0x00, 0x00, 0xfc, 0x04, 0x00, 0x00, 0xf6, 0x07, + 0x00, 0x00, 0xf6, 0x07, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfd, 0x00, + 0x00, 0x00, 0xfd, 0xfd, 0x00, 0xfd, 0x03, 0x00, 0xf7, 0x06, 0x00, 0xfd, + 0x00, 0x03, 0x00, 0x00, 0x00, 0xf7, 0x03, 0x00, 0xfa, 0x00, 0x00, 0x00, + 0xf7, 0x03, 0x00, 0x00, 0xf7, 0x06, 0x00, 0xfa, 0x00, 0x00, 0x00, 0xf5, + 0x09, 0x00, 0xfa, 0x00, 0x00, 0x00, 0xfa, 0x08, 0xfd, 0xfa, 0x06, 0xfd, + 0x05, 0xfb, 0x00, 0x03, 0x00, 0xfd, 0xfd, 0x08, 0x00, 0xfb, 0x03, 0x00, + 0xfb, 0x00, 0x00, 0x00, 0xfd, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, + 0x00, 0xf7, 0x07, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x04, 0x00, 0xf8, 0x04, 0x00, 0x00, 0xfa, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x09, 0xfc, 0xfe, 0x02, 0x00, 0xfe, + 0xfe, 0x04, 0x00, 0xfb, 0x03, 0x00, 0xfe, 0x00, 0x03, 0x00, 0xfd, 0x03, + 0x00, 0xfe, 0xfe, 0x05, 0x00, 0xfb, 0x03, 0x00, 0xfd, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0xfc, + 0x04, 0xff, 0xff, 0x01, 0x00, 0x00, 0xfd, 0x01, 0x00, 0x00, 0xfc, 0x02, + 0x00, 0x00, 0xff, 0x02, 0xff, 0x00, 0x01, 0x00, 0xfd, 0x02, 0x00, 0x00, + 0xfa, 0x03, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0xfe, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x01, 0x00, 0x00, 0xfd, 0x01, + 0x00, 0xff, 0x00, 0x01, 0x00, 0xfe, 0x02, 0x00, 0xff, 0x01, 0x00, 0x00, + 0xff, 0x02, 0x00, 0xfe, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, + 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, + 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfd, 0x01, 0xf8, 0xf9, 0xf6, 0xee, 0xff, + 0xfb, 0xf7, 0xf5, 0xf5, 0x09, 0xea, 0x0f, 0x27, 0x48, 0x00, 0x25, 0xd5, + 0xe7, 0x23, 0x1c, 0xe7, 0x02, 0xc2, 0xab, 0xb6, 0xaf, 0xb5, 0xc8, 0xa1, + 0x07, 0x1a, 0xce, 0xeb, 0x0a, 0x33, 0x5f, 0x73, 0x63, 0x7f, 0x7f, 0x7d, + 0x7c, 0x52, 0x5b, 0x73, 0x64, 0xf2, 0xc9, 0xdf, 0xf8, 0xdb, 0xef, 0xd0, + 0xa4, 0x80, 0x8b, 0x80, 0x80, 0x80, 0x80, 0x89, 0xb2, 0xd3, 0xf7, 0xff, + 0xf1, 0xfe, 0x3f, 0x74, 0x77, 0x7f, 0x79, 0x68, 0x42, 0x10, 0xf7, 0xf1, + 0xf9, 0xf8, 0xdc, 0xa2, 0x9d, 0xc7, 0xb0, 0x80, 0x80, 0x97, 0xa2, 0xbf, + 0x17, 0x4d, 0x5f, 0x51, 0x5e, 0x7f, 0x7f, 0x7f, 0x7f, 0x72, 0x5a, 0x54, + 0x4d, 0x30, 0x16, 0xfc, 0xe8, 0xcf, 0xc0, 0xa0, 0x8d, 0x80, 0x80, 0x80, + 0x8d, 0xb3, 0xc3, 0xa0, 0xa3, 0xca, 0xdd, 0xe7, 0xf7, 0x03, 0x0a, 0x0b, + 0x1d, 0x30, 0x3d, 0x4f, 0x5d, 0x54, 0x51, 0x5a, 0x55, 0x46, 0x30, 0x2d, + 0x28, 0x04, 0xe6, 0xc7, 0xc3, 0xcf, 0xc7, 0xb5, 0xa8, 0xb0, 0xc7, 0xec, + 0xea, 0xf2, 0xfb, 0x09, 0x0a, 0x29, 0x49, 0x4b, 0x51, 0x36, 0x45, 0x5a, + 0x30, 0x00, 0xcc, 0xd2, 0xd1, 0xbe, 0xbc, 0xa8, 0x94, 0xa9, 0xd5, 0xe7, + 0xd6, 0xdf, 0xf7, 0x09, 0x19, 0x0d, 0x25, 0x3f, 0x49, 0x44, 0x3c, 0x39, + 0x2e, 0x30, 0x19, 0x08, 0x02, 0xf9, 0xff, 0x0c, 0x02, 0xfc, 0xf3, 0xe3, + 0xd2, 0xd3, 0xcc, 0xcd, 0xe1, 0xf0, 0xec, 0xe0, 0xc7, 0xcd, 0xd8, 0xe1, + 0xde, 0xeb, 0x0d, 0x2d, 0x39, 0x43, 0x43, 0x3f, 0x3a, 0x3e, 0x3f, 0x3c, + 0x22, 0x1c, 0x0d, 0xfe, 0xf0, 0xd1, 0xc6, 0xb6, 0xaa, 0xad, 0xb2, 0xb3, + 0xc5, 0xef, 0x03, 0x11, 0x1c, 0x19, 0x17, 0x1a, 0x17, 0x23, 0x31, 0x2e, + 0x37, 0x32, 0x1b, 0x06, 0xf8, 0xe5, 0xca, 0xcd, 0xd2, 0xd3, 0xd4, 0xd7, + 0xef, 0x06, 0xf0, 0xec, 0xf8, 0xf1, 0x07, 0x08, 0x0d, 0x14, 0x19, 0x10, + 0x0a, 0x04, 0xfc, 0x0c, 0x10, 0x0b, 0x12, 0x12, 0x22, 0x1e, 0x22, 0x10, + 0x04, 0x05, 0x00, 0xf0, 0xdf, 0xd4, 0xc6, 0xc9, 0xd3, 0xd3, 0xd5, 0xca, + 0xcc, 0xd1, 0xe5, 0xf3, 0x01, 0x0d, 0x2a, 0x39, 0x43, 0x43, 0x39, 0x28, + 0x1c, 0x1e, 0x18, 0x13, 0x08, 0x01, 0xf5, 0xe3, 0xd5, 0xd3, 0xce, 0xc2, + 0xbf, 0xcb, 0xdf, 0xf7, 0x07, 0x06, 0x0e, 0x1c, 0x12, 0x12, 0x10, 0x0c, + 0x08, 0x0d, 0x0b, 0x10, 0x0a, 0xfb, 0xfa, 0x00, 0xf8, 0xf1, 0xfb, 0xfc, + 0xfe, 0x07, 0x15, 0x10, 0x09, 0x00, 0xee, 0xe6, 0xdf, 0xdb, 0xdf, 0xdf, + 0xe8, 0xfa, 0xfc, 0xf3, 0xfa, 0xf4, 0xf8, 0x0a, 0x17, 0x20, 0x2a, 0x2b, + 0x33, 0x32, 0x21, 0x15, 0x06, 0xfc, 0xf2, 0xed, 0xe3, 0xda, 0xce, 0xc5, + 0xc2, 0xc3, 0xc8, 0xca, 0xd4, 0xe1, 0xec, 0xff, 0x15, 0x1d, 0x28, 0x30, + 0x31, 0x2e, 0x2e, 0x20, 0x12, 0x0c, 0x11, 0x16, 0x14, 0x14, 0x01, 0xf2, + 0xf4, 0xf5, 0xf6, 0xec, 0xe0, 0xe6, 0xe9, 0xf1, 0xfd, 0xf8, 0xf1, 0xec, + 0xe8, 0xe7, 0xee, 0xf6, 0xfb, 0x04, 0x00, 0xfd, 0x06, 0x0a, 0x0d, 0x0a, + 0x04, 0x0f, 0x1e, 0x24, 0x21, 0x08, 0xff, 0xfa, 0xf5, 0xee, 0xec, 0xe0, + 0xd5, 0xd0, 0xda, 0xed, 0xf7, 0xf7, 0xf4, 0xf9, 0x03, 0x05, 0x0d, 0x12, + 0x17, 0x1f, 0x25, 0x2c, 0x28, 0x1c, 0x08, 0xf7, 0xec, 0xe3, 0xe4, 0xea, + 0xef, 0xed, 0xef, 0xe8, 0xe1, 0xe0, 0xdf, 0xe0, 0xed, 0xf4, 0xff, 0x0b, + 0x11, 0x0d, 0x04, 0x05, 0x10, 0x10, 0x12, 0x12, 0x10, 0x09, 0x0a, 0x13, + 0x13, 0x14, 0x10, 0x0d, 0x0a, 0x03, 0x00, 0xf9, 0xf4, 0xf5, 0xf5, 0xf2, + 0xe7, 0xdf, 0xe3, 0xdd, 0xd3, 0xde, 0xe4, 0xec, 0xf3, 0xfd, 0xfb, 0x03, + 0x08, 0x0b, 0x08, 0x06, 0x0c, 0x17, 0x1b, 0x1c, 0x19, 0x11, 0x05, 0x01, + 0x04, 0x00, 0xf6, 0xf9, 0xf1, 0xf1, 0xf3, 0xef, 0xea, 0xef, 0xf7, 0x02, + 0x00, 0xfc, 0x00, 0xfe, 0x07, 0x18, 0x19, 0x16, 0x0e, 0x08, 0xfc, 0xf6, + 0xec, 0xea, 0xf0, 0xf1, 0xfa, 0xf7, 0xf8, 0xef, 0xe9, 0xe5, 0xeb, 0xe8, + 0xea, 0xf2, 0xfe, 0x04, 0x06, 0x0c, 0x11, 0x0d, 0x09, 0x08, 0x06, 0x0a, + 0x10, 0x12, 0x0e, 0x10, 0x0a, 0x05, 0x04, 0x05, 0x03, 0xff, 0xfe, 0x04, + 0xff, 0xfa, 0xf4, 0xf3, 0xf1, 0xea, 0xe7, 0xe6, 0xe4, 0xe7, 0xe7, 0xf7, + 0xfa, 0xfc, 0x03, 0x06, 0x03, 0x06, 0x00, 0xff, 0x04, 0x10, 0x13, 0x13, + 0x12, 0x08, 0x00, 0xfa, 0xf1, 0xea, 0xe7, 0xe7, 0xf2, 0xfd, 0xfc, 0xfc, + 0xfd, 0x06, 0x08, 0x0d, 0x13, 0x12, 0x12, 0x10, 0x12, 0x11, 0x0c, 0x06, + 0xfd, 0xf9, 0xf2, 0xe9, 0xe7, 0xe6, 0xe1, 0xe5, 0xe7, 0xeb, 0xf5, 0x04, + 0x05, 0x04, 0x04, 0x06, 0x0c, 0x0c, 0x09, 0x07, 0x04, 0xff, 0xf8, 0xef, + 0xe9, 0xe4, 0xeb, 0xf4, 0xfa, 0x01, 0x0b, 0x0a, 0x07, 0x06, 0x0a, 0x0b, + 0x0c, 0x0c, 0x10, 0x10, 0x09, 0x00, 0xf7, 0xef, 0xef, 0xe9, 0xe6, 0xe5, + 0xf1, 0xf2, 0xf5, 0xf9, 0xff, 0x0b, 0x15, 0x16, 0x13, 0x15, 0x14, 0x11, + 0x0c, 0x0b, 0x05, 0x00, 0xf6, 0xec, 0xe4, 0xd7, 0xd9, 0xd9, 0xdf, 0xef, + 0xfa, 0xff, 0x03, 0x0a, 0x10, 0x10, 0x10, 0x12, 0x0c, 0x0c, 0x10, 0x0a, + 0x02, 0xfb, 0xfc, 0xf7, 0xf0, 0xee, 0xf5, 0xfd, 0xff, 0xff, 0x01, 0xfe, + 0xff, 0x05, 0x08, 0x07, 0x07, 0x01, 0xf8, 0xf0, 0xef, 0xeb, 0xe4, 0xe4, + 0xe2, 0xe6, 0xe7, 0xef, 0xf1, 0xf8, 0x04, 0x10, 0x1d, 0x28, 0x2c, 0x29, + 0x20, 0x18, 0x16, 0x10, 0x05, 0xff, 0xf4, 0xea, 0xe6, 0xe4, 0xe2, 0xdc, + 0xdf, 0xe4, 0xec, 0xf3, 0xff, 0x08, 0x0c, 0x10, 0x17, 0x17, 0x14, 0x10, + 0x0b, 0x00, 0xf4, 0xf6, 0xf6, 0xf3, 0xf5, 0xef, 0xe8, 0xe7, 0xed, 0xf7, + 0x00, 0x04, 0x09, 0x09, 0x0b, 0x11, 0x14, 0x11, 0x08, 0xfe, 0xfa, 0xf1, + 0xf4, 0xf0, 0xea, 0xe9, 0xe9, 0xeb, 0xee, 0xf4, 0xfb, 0xff, 0x03, 0x12, + 0x1e, 0x29, 0x28, 0x22, 0x12, 0x07, 0xfe, 0xf1, 0xef, 0xea, 0xe3, 0xdd, + 0xd8, 0xdd, 0xe2, 0xe3, 0xec, 0xf5, 0xfb, 0x06, 0x12, 0x18, 0x18, 0x19, + 0x1b, 0x1c, 0x1d, 0x1b, 0x10, 0x08, 0xfd, 0xee, 0xe8, 0xe5, 0xe7, 0xea, + 0xec, 0xec, 0xef, 0xf9, 0xfb, 0xff, 0x09, 0x12, 0x10, 0x10, 0x18, 0x12, + 0x05, 0xfa, 0xf4, 0xec, 0xea, 0xea, 0xed, 0xec, 0xf1, 0xf6, 0xfb, 0xfd, + 0x06, 0x0b, 0x0f, 0x10, 0x13, 0x10, 0x10, 0x0c, 0x01, 0xfa, 0xf4, 0xee, + 0xe5, 0xe0, 0xde, 0xde, 0xdd, 0xe1, 0xef, 0xff, 0x08, 0x0d, 0x11, 0x12, + 0x16, 0x1d, 0x1e, 0x23, 0x26, 0x20, 0x16, 0x09, 0xfc, 0xec, 0xe3, 0xdf, + 0xe1, 0xe2, 0xe4, 0xe7, 0xeb, 0xf3, 0xf5, 0xf5, 0xf6, 0xfc, 0x04, 0x0d, + 0x11, 0x0d, 0x09, 0x0a, 0x08, 0x04, 0xfe, 0xf7, 0xf2, 0xf2, 0xf7, 0xfa, + 0x01, 0x05, 0x08, 0x08, 0x0a, 0x0c, 0x0c, 0x0c, 0x0a, 0x00, 0xfd, 0xfd, + 0xfa, 0xf6, 0xee, 0xe7, 0xdf, 0xe1, 0xe6, 0xed, 0xf1, 0xf6, 0x01, 0x0a, + 0x0f, 0x12, 0x12, 0x10, 0x13, 0x12, 0x0d, 0x0c, 0x08, 0x02, 0xfe, 0xf5, + 0xeb, 0xe1, 0xe1, 0xe3, 0xe8, 0xeb, 0xf1, 0xf6, 0xfb, 0x04, 0x0d, 0x0e, + 0x0c, 0x0f, 0x10, 0x14, 0x16, 0x10, 0x02, 0xfd, 0xfa, 0xf7, 0xf6, 0xf2, + 0xf0, 0xf3, 0xf3, 0xf5, 0xfb, 0x00, 0x02, 0x06, 0x08, 0x06, 0x05, 0x00, + 0xfe, 0xfc, 0xf8, 0xf7, 0xf7, 0xf5, 0xf7, 0xf3, 0xed, 0xed, 0xef, 0xf4, + 0xf7, 0x00, 0x06, 0x0a, 0x12, 0x13, 0x11, 0x0d, 0x0b, 0x0c, 0x05, 0x03, + 0xff, 0xf4, 0xee, 0xed, 0xea, 0xea, 0xe9, 0xed, 0xf2, 0xf8, 0xfa, 0x01, + 0x05, 0x0c, 0x13, 0x15, 0x16, 0x15, 0x10, 0x09, 0x04, 0xff, 0xfb, 0xf9, + 0xf8, 0xf5, 0xf1, 0xed, 0xe8, 0xeb, 0xf2, 0xf3, 0xf7, 0xfd, 0xff, 0x03, + 0x08, 0x07, 0x04, 0x06, 0x05, 0x08, 0x0a, 0x06, 0x01, 0xfa, 0xf7, 0xfb, + 0xfe, 0xf9, 0xfb, 0xfc, 0xfb, 0xf9, 0xf8, 0xf7, 0xf9, 0xfb, 0xfc, 0xfd, + 0xff, 0xfc, 0xf7, 0xf8, 0xf9, 0xf2, 0xf3, 0xf8, 0xfd, 0xff, 0xfe, 0x03, + 0x05, 0x0a, 0x0e, 0x10, 0x0d, 0x0e, 0x0d, 0x0b, 0x09, 0x08, 0x01, 0xfb, + 0xf7, 0xf9, 0xf5, 0xf1, 0xf1, 0xf5, 0xf7, 0xf7, 0xf7, 0xfb, 0xfd, 0xfd, + 0xff, 0xff, 0xfd, 0xff, 0x05, 0x07, 0x05, 0x02, 0x04, 0x02, 0xfd, 0xf8, + 0xf4, 0xf3, 0xf3, 0xf3, 0xf4, 0xf5, 0xf6, 0xf5, 0xf7, 0xf8, 0xfa, 0xfb, + 0xfc, 0x02, 0x05, 0x05, 0x08, 0x09, 0x08, 0x07, 0x07, 0x05, 0x04, 0x07, + 0x0b, 0x0b, 0x0b, 0x09, 0x08, 0x03, 0x00, 0x00, 0xfe, 0xfd, 0xfc, 0xfc, + 0xf7, 0xf6, 0xf5, 0xef, 0xed, 0xef, 0xf1, 0xf1, 0xf1, 0xef, 0xf0, 0xef, + 0xf2, 0xf5, 0xf6, 0xfb, 0x02, 0x04, 0x03, 0x05, 0x07, 0x09, 0x0b, 0x0a, + 0x08, 0x09, 0x06, 0x03, 0x01, 0xfe, 0xfe, 0xfb, 0xfd, 0xfd, 0xff, 0x00, + 0xfc, 0xfb, 0xfe, 0xff, 0xff, 0x00, 0xff, 0x01, 0x00, 0x00, 0x01, 0x00, + 0xff, 0x01, 0xff, 0xfd, 0xfe, 0xfb, 0xf6, 0xf4, 0xf4, 0xf2, 0xf5, 0xf9, + 0xfb, 0xf8, 0xf7, 0xfa, 0xfa, 0xfb, 0xff, 0x02, 0x02, 0x01, 0xff, 0xfd, + 0xfd, 0xfc, 0xfb, 0xfe, 0x02, 0x03, 0x05, 0x04, 0x01, 0xfe, 0x00, 0x03, + 0x04, 0x04, 0x07, 0x08, 0x06, 0x04, 0x04, 0x00, 0xfe, 0xfd, 0xfd, 0xf9, + 0xf7, 0xf7, 0xf3, 0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf5, 0xf6, 0xf5, 0xf5, + 0xf8, 0xff, 0x01, 0x00, 0x03, 0x06, 0x02, 0xfe, 0xff, 0x01, 0x01, 0x02, + 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x06, 0x06, 0x06, 0x06, 0x05, 0x00, + 0xfd, 0xfc, 0xfb, 0xf9, 0xf8, 0xf7, 0xf8, 0xf7, 0xf9, 0xf9, 0xfb, 0xfd, + 0xfc, 0xfd, 0xff, 0xff, 0x00, 0x02, 0x02, 0x01, 0xff, 0xfc, 0xf7, 0xf6, + 0xf5, 0xf2, 0xf2, 0xf1, 0xf1, 0xf1, 0xf4, 0xf5, 0xfa, 0xff, 0x02, 0x07, + 0x0d, 0x10, 0x11, 0x13, 0x13, 0x11, 0x0f, 0x10, 0x0c, 0x06, 0x00, 0xfb, + 0xf7, 0xf4, 0xf3, 0xf1, 0xf1, 0xf2, 0xf4, 0xf6, 0xf7, 0xf9, 0xfa, 0xfa, + 0xfa, 0xfe, 0x00, 0x01, 0x00, 0x01, 0x00, 0xfd, 0xfd, 0xfb, 0xfc, 0xfd, + 0xfc, 0xfc, 0xfd, 0xff, 0x01, 0x01, 0x04, 0x05, 0x05, 0x05, 0x06, 0x04, + 0x00, 0xff, 0xfe, 0xfb, 0xf9, 0xf8, 0xf5, 0xf2, 0xf0, 0xf3, 0xf7, 0xfc, + 0xff, 0x00, 0x04, 0x07, 0x0a, 0x0a, 0x07, 0x07, 0x07, 0x05, 0x02, 0xfe, + 0xf8, 0xf5, 0xef, 0xed, 0xee, 0xef, 0xef, 0xf2, 0xf5, 0xf8, 0xfc, 0xfe, + 0xff, 0x04, 0x09, 0x0e, 0x11, 0x10, 0x0c, 0x08, 0x06, 0x03, 0x01, 0x02, + 0x00, 0xfe, 0xfc, 0xfd, 0xfc, 0xfb, 0xfa, 0xfb, 0xfc, 0xff, 0xfe, 0xfe, + 0xfe, 0xfb, 0xf9, 0xf7, 0xf6, 0xf6, 0xf5, 0xf2, 0xef, 0xf0, 0xf2, 0xf5, + 0xfa, 0xfe, 0xff, 0x04, 0x09, 0x0f, 0x10, 0x10, 0x10, 0x0e, 0x0b, 0x07, + 0x03, 0xff, 0xf8, 0xf3, 0xef, 0xee, 0xf0, 0xf1, 0xef, 0xf2, 0xf5, 0xf5, + 0xf9, 0xfe, 0x03, 0x07, 0x0b, 0x0d, 0x10, 0x11, 0x10, 0x09, 0x02, 0xfe, + 0xfc, 0xfb, 0xfa, 0xf8, 0xf3, 0xf2, 0xf4, 0xf2, 0xf2, 0xf4, 0xf7, 0xf9, + 0xfa, 0xfc, 0xfe, 0x00, 0x00, 0xff, 0xfd, 0xfc, 0xfd, 0xfd, 0xfc, 0xfc, + 0xfb, 0xfd, 0x00, 0x01, 0x07, 0x0b, 0x0b, 0x0c, 0x0d, 0x0c, 0x0c, 0x08, + 0x06, 0x03, 0xff, 0xfb, 0xf7, 0xf1, 0xee, 0xed, 0xeb, 0xea, 0xed, 0xf0, + 0xf3, 0xf6, 0xfc, 0x01, 0x04, 0x07, 0x0b, 0x0e, 0x10, 0x10, 0x0e, 0x09, + 0x05, 0x02, 0xfd, 0xf9, 0xf5, 0xf0, 0xee, 0xef, 0xef, 0xef, 0xf1, 0xf3, + 0xf9, 0xfe, 0x00, 0x05, 0x06, 0x05, 0x07, 0x08, 0x07, 0x05, 0x04, 0x02, + 0x00, 0xff, 0xfd, 0xfc, 0xfb, 0xfd, 0xff, 0xff, 0x01, 0x02, 0x02, 0x01, + 0x00, 0xff, 0xfb, 0xf9, 0xf9, 0xf9, 0xf7, 0xf5, 0xf3, 0xf0, 0xef, 0xf0, + 0xf2, 0xf5, 0xf9, 0xff, 0x05, 0x08, 0x0d, 0x10, 0x11, 0x12, 0x11, 0x10, + 0x0d, 0x0a, 0x06, 0x00, 0xfa, 0xf6, 0xf3, 0xef, 0xed, 0xed, 0xeb, 0xec, + 0xf0, 0xf4, 0xf9, 0xfe, 0x02, 0x06, 0x08, 0x08, 0x08, 0x07, 0x04, 0x03, + 0x03, 0x03, 0x01, 0x00, 0xfd, 0xf9, 0xf7, 0xfa, 0xfc, 0xfc, 0xfd, 0xfc, + 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfe, 0xff, 0xff, 0xfe, 0xfc, 0xfc, 0xfb, + 0xf9, 0xfb, 0xfd, 0x00, 0x01, 0x02, 0x04, 0x06, 0x07, 0x08, 0x09, 0x08, + 0x07, 0x06, 0x05, 0x02, 0x00, 0xfb, 0xf7, 0xf5, 0xf2, 0xf2, 0xf2, 0xf2, + 0xf2, 0xf5, 0xf8, 0xfb, 0xfe, 0x00, 0x02, 0x05, 0x07, 0x07, 0x05, 0x04, + 0x04, 0x01, 0x00, 0xff, 0xfd, 0xfc, 0xfd, 0xfd, 0xfc, 0xfc, 0xfd, 0xfd, + 0xfd, 0xfd, 0xfd, 0xff, 0x00, 0x01, 0x03, 0x04, 0x03, 0x03, 0x01, 0xff, + 0xfc, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfe, 0xfe, 0xff, + 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfd, 0xfc, 0xfc, + 0xfc, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, + 0x03, 0x03, 0x01, 0x00, 0x00, 0xff, 0xfd, 0xfc, 0xfa, 0xf9, 0xf9, 0xf9, + 0xf9, 0xfa, 0xfb, 0xfc, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0xfe, 0xfe, 0xff, 0xfe, 0xfe, 0xfe, + 0xfe, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0xff, 0xfe, 0xfe, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xfb, 0xfc, 0xfb, 0xfc, + 0xfb, 0xfb, 0xfd, 0xfe, 0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x03, + 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0xfe, 0xfd, 0xfe, + 0xfe, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x43, 0xc8, 0x18, 0x65, 0xbb, 0xbb, 0x2b, 0x07, + 0xfd, 0xe1, 0xb4, 0x5f, 0x38, 0xb2, 0xd0, 0x40, 0x06, 0x7f, 0x0f, 0x37, + 0xfc, 0xb7, 0x13, 0x64, 0x08, 0x0f, 0x1f, 0x40, 0xf3, 0xd2, 0xa8, 0x44, + 0x63, 0x2e, 0x1a, 0x01, 0x99, 0xfc, 0x57, 0xe3, 0x30, 0xe3, 0xa7, 0xb5, + 0x61, 0x4e, 0xf3, 0x33, 0xf1, 0xea, 0x09, 0xc3, 0xd0, 0x62, 0xbb, 0xe3, + 0xcc, 0xba, 0x24, 0xb1, 0xe0, 0xca, 0x07, 0x02, 0xa2, 0xcf, 0xee, 0xd6, + 0xc3, 0x01, 0xf6, 0xd5, 0xac, 0xe4, 0xa8, 0xec, 0x2a, 0xed, 0xc3, 0x2c, + 0x03, 0xf6, 0xce, 0xf6, 0xff, 0x35, 0xf1, 0xa0, 0x0e, 0xba, 0x0f, 0x2e, + 0x3a, 0x48, 0xf0, 0xaa, 0xcd, 0x01, 0xe4, 0xf6, 0xf3, 0x02, 0x01, 0x17, + 0x13, 0x22, 0x61, 0xf8, 0xdb, 0x37, 0xee, 0x12, 0x35, 0x3f, 0x20, 0x49, + 0x58, 0x42, 0x6e, 0x63, 0x3e, 0xfc, 0x5f, 0x43, 0x42, 0x08, 0x33, 0x7f, + 0x22, 0x49, 0x54, 0x37, 0x35, 0xf2, 0x5e, 0x18, 0x59, 0x38, 0x20, 0x04, + 0x53, 0x03, 0x2a, 0x27, 0x1a, 0x1c, 0x15, 0x0f, 0x0d, 0x06, 0x0a, 0xfe, + 0xfb, 0xff, 0xfc, 0xf9, 0xfc, 0xf9, 0xf2, 0xec, 0xed, 0xed, 0xe2, 0xd9, + 0xe6, 0xdd, 0xd8, 0xd6, 0xe3, 0xd4, 0xcb, 0xd4, 0xdd, 0xea, 0xbf, 0x9e, + 0x9b, 0x84, 0x9a, 0xa2, 0xa7, 0xad, 0x9d, 0xa3, 0xa3, 0xae, 0xa9, 0xa9, + 0xc3, 0xbe, 0xc5, 0xc4, 0xa6, 0xd1, 0xbb, 0xd4, 0xd7, 0xdc, 0xed, 0xd1, + 0xe0, 0x18, 0xf8, 0xc5, 0x18, 0x07, 0xeb, 0x04, 0x1b, 0x7f, 0x00, 0x28, + 0x7f, 0x0f, 0x1b, 0x4b, 0x51, 0x14, 0xc8, 0x3e, 0x7c, 0x2d, 0x15, 0x35, + 0x4a, 0xd4, 0xbb, 0x1b, 0xee, 0x2d, 0x0c, 0x0d, 0x2b, 0x50, 0x02, 0xec, + 0x0c, 0xfd, 0x05, 0x22, 0x31, 0x14, 0x2a, 0x25, 0x13, 0x3e, 0x48, 0x36, + 0x20, 0xd4, 0x26, 0x3d, 0x1d, 0x25, 0x2f, 0x1c, 0x26, 0x2b, 0x11, 0xf2, + 0x0a, 0x32, 0x2a, 0xda, 0xea, 0x19, 0xec, 0x04, 0x17, 0x01, 0x1e, 0xf1, + 0xd1, 0xe6, 0xeb, 0x04, 0x23, 0xfb, 0xec, 0xcc, 0x9b, 0xec, 0x15, 0xea, + 0x04, 0xb9, 0xc4, 0x06, 0xb7, 0x88, 0xb9, 0xcc, 0xd9, 0xc0, 0xae, 0xaf, + 0xba, 0xb8, 0xc3, 0xd7, 0xc8, 0xbb, 0xd4, 0xc9, 0xd9, 0xd6, 0xe0, 0xe1, + 0x1b, 0xc4, 0xd0, 0xf0, 0xdb, 0xed, 0x0e, 0x25, 0x05, 0xfd, 0x05, 0x0f, + 0x06, 0xf6, 0x0a, 0x0a, 0x1c, 0x0e, 0x1f, 0x1f, 0x0d, 0x17, 0x1d, 0x1c, + 0x23, 0x25, 0x32, 0x4e, 0x4f, 0x2d, 0xd8, 0x5b, 0x54, 0x7f, 0x43, 0x3f, + 0x3f, 0x51, 0x29, 0x4e, 0x4f, 0x34, 0x3c, 0x35, 0x3d, 0x2a, 0x2d, 0x30, + 0x01, 0x07, 0x32, 0x0e, 0xfc, 0x61, 0x21, 0x27, 0x0e, 0x1a, 0x24, 0x01, + 0xc3, 0x98, 0x20, 0xe7, 0xc9, 0xfb, 0xec, 0x39, 0xff, 0xb7, 0xf6, 0x18, + 0xec, 0xfa, 0x00, 0x1f, 0xee, 0xf9, 0xfc, 0x01, 0x08, 0xf6, 0xd4, 0xdb, + 0xfc, 0xf9, 0xf2, 0xfe, 0xf9, 0xf6, 0xdc, 0xe1, 0xec, 0xe7, 0xe4, 0x0c, + 0xe0, 0x01, 0xdb, 0xa7, 0xe2, 0x25, 0xcd, 0x8e, 0xbe, 0xfe, 0xf7, 0xc3, + 0xbb, 0xc9, 0xd6, 0x1b, 0xf1, 0x9e, 0x00, 0x18, 0xe8, 0xbd, 0x01, 0x02, + 0xd6, 0xf0, 0xfc, 0x00, 0xc1, 0xf8, 0xe9, 0x0e, 0x1d, 0xe6, 0x10, 0x0a, + 0xee, 0xe8, 0xf1, 0xfb, 0x19, 0x10, 0x17, 0x21, 0x22, 0x17, 0x50, 0xf8, + 0x21, 0x56, 0x09, 0x0b, 0xe5, 0x2b, 0x70, 0x63, 0x27, 0xeb, 0x3d, 0x4a, + 0xea, 0x1c, 0x2f, 0x0a, 0x01, 0x3b, 0x01, 0x07, 0x19, 0x07, 0xf1, 0x46, + 0x0b, 0x4d, 0x2c, 0x1f, 0x04, 0xdb, 0x22, 0x28, 0x0f, 0x1e, 0x2d, 0xe6, + 0xf6, 0x33, 0x16, 0x03, 0xfd, 0x1b, 0xeb, 0xd9, 0xbe, 0x35, 0xfe, 0xf3, + 0x16, 0xec, 0xfe, 0xe6, 0xed, 0xc9, 0xf8, 0x14, 0xe9, 0x10, 0xdb, 0xfa, + 0xd2, 0xdf, 0x15, 0xc6, 0xd6, 0xf6, 0x02, 0x8c, 0x16, 0x47, 0xe6, 0x12, + 0xb6, 0xdd, 0x0b, 0xcc, 0x05, 0x0d, 0xd7, 0xb2, 0xb0, 0x03, 0xbc, 0x0e, + 0xae, 0xdc, 0xfe, 0xb4, 0x0f, 0x3c, 0xd5, 0xa5, 0xfb, 0x1c, 0xfc, 0xb2, + 0xec, 0xeb, 0xed, 0x35, 0x12, 0xa1, 0x22, 0x1f, 0xde, 0xd8, 0x08, 0x01, + 0x3f, 0x0f, 0xb4, 0x26, 0x2f, 0x2a, 0x1d, 0xe1, 0xfc, 0x4c, 0x47, 0xef, + 0xfb, 0xdb, 0xfb, 0xfd, 0x2f, 0x27, 0x25, 0x0b, 0xc0, 0x2b, 0xff, 0xcf, + 0x1a, 0xfe, 0x0c, 0x57, 0x11, 0x0d, 0x74, 0xc5, 0xdd, 0x57, 0x3c, 0xe9, + 0xdb, 0x4f, 0x06, 0xe5, 0x11, 0xfd, 0x0c, 0x2e, 0x16, 0x2a, 0x16, 0xab, + 0x3a, 0x3e, 0x2a, 0xfe, 0xbb, 0x38, 0xcd, 0xd4, 0x17, 0x3d, 0x3e, 0xf6, + 0xf3, 0x29, 0xe8, 0xe8, 0x5f, 0xd7, 0x15, 0xc9, 0x1a, 0x1f, 0xbd, 0xdd, + 0x58, 0xc2, 0xf1, 0x40, 0x1f, 0xf7, 0x09, 0x07, 0xd4, 0xff, 0xe7, 0xf9, + 0xce, 0xcb, 0x04, 0x12, 0xc9, 0xdc, 0x15, 0xd7, 0xc1, 0xc0, 0xe1, 0x15, + 0xa0, 0xc4, 0xec, 0xcb, 0x0c, 0x26, 0xf7, 0x34, 0xa7, 0xf0, 0x05, 0xb2, + 0xec, 0xc0, 0xfe, 0x03, 0xd0, 0xc7, 0x21, 0xfc, 0xaa, 0x21, 0xf8, 0x31, + 0xff, 0xf2, 0x29, 0x5d, 0xf9, 0xcd, 0xf2, 0x0d, 0xf2, 0x3a, 0x61, 0x3d, + 0xf9, 0x00, 0xcc, 0x0b, 0x3f, 0x0f, 0x25, 0xdc, 0xfc, 0x49, 0x3c, 0xfe, + 0xe6, 0x44, 0xf4, 0xc4, 0xf8, 0x1b, 0xe8, 0xf0, 0x52, 0x3c, 0xb5, 0xe9, + 0x4a, 0xf3, 0xe5, 0x00, 0x0d, 0x0d, 0xfe, 0x4e, 0xb1, 0xe9, 0x46, 0x3a, + 0x1d, 0x1b, 0xfb, 0x00, 0x05, 0xdc, 0xfa, 0xe4, 0xb8, 0xf4, 0xdf, 0x07, + 0x3c, 0x10, 0x13, 0x1e, 0xc9, 0x9a, 0x26, 0xfc, 0xbd, 0xea, 0x31, 0x3b, + 0x33, 0xf4, 0xd6, 0xed, 0x15, 0xe2, 0x28, 0x0d, 0xc4, 0xef, 0x45, 0xeb, + 0x32, 0xc2, 0xfe, 0xf6, 0x25, 0x1c, 0xf4, 0x18, 0x0c, 0x0d, 0x06, 0xfa, + 0xe6, 0xe7, 0xdc, 0xc9, 0xdc, 0x09, 0xf4, 0x01, 0x1b, 0xd8, 0xfe, 0xdb, + 0xec, 0xdf, 0xd7, 0xe6, 0xf6, 0x08, 0x4a, 0xb9, 0xd3, 0xf7, 0xfb, 0xf2, + 0xf6, 0xfd, 0x01, 0x05, 0xcb, 0x1a, 0x06, 0xdc, 0x31, 0x1f, 0xfa, 0xb9, + 0xfe, 0x3f, 0x42, 0xca, 0xf0, 0x44, 0xf2, 0xf8, 0xe7, 0x49, 0xff, 0xd3, + 0x36, 0x13, 0xf6, 0x62, 0x29, 0x0c, 0x2c, 0xf7, 0xd2, 0x00, 0x0e, 0x48, + 0xda, 0xf4, 0x5d, 0xfb, 0xfd, 0x23, 0x31, 0x1c, 0xca, 0x24, 0x25, 0xc3, + 0xfa, 0xf6, 0x4d, 0xfe, 0x15, 0x3b, 0xf2, 0xc8, 0xaa, 0x0a, 0x19, 0xfa, + 0x94, 0xef, 0x38, 0x27, 0xd0, 0x02, 0x27, 0xb5, 0xac, 0xe9, 0xba, 0x1c, + 0x41, 0xf2, 0xa7, 0xef, 0xcb, 0x11, 0xb4, 0xe0, 0x08, 0xe5, 0x00, 0x27, + 0xf0, 0xf2, 0xd9, 0xf8, 0xd3, 0xdb, 0x08, 0x34, 0xf5, 0x23, 0xe9, 0xc4, + 0x0e, 0x3f, 0xf4, 0xe5, 0x04, 0x31, 0x3d, 0x1d, 0x33, 0x23, 0x0b, 0x17, + 0xfa, 0x09, 0xfd, 0x38, 0xe1, 0x05, 0x3b, 0xef, 0xf5, 0x25, 0x47, 0x01, + 0xfe, 0x2a, 0x1f, 0xd2, 0xc8, 0x3d, 0x12, 0xbb, 0x0b, 0x0c, 0xcd, 0xdf, + 0x4f, 0x2e, 0xbc, 0xfe, 0xbf, 0x1d, 0x06, 0xdf, 0xea, 0x05, 0xff, 0x05, + 0xdc, 0x37, 0x0b, 0x97, 0xf5, 0x1e, 0x2c, 0xdb, 0xe7, 0x05, 0xc8, 0x14, + 0xf2, 0xe7, 0x24, 0xe2, 0x04, 0x30, 0xc6, 0x16, 0x44, 0xa3, 0x0a, 0xf5, + 0xd8, 0xde, 0x0d, 0xd9, 0xe8, 0x37, 0x2a, 0xd3, 0x07, 0x1b, 0xb7, 0xf5, + 0x04, 0x00, 0xb9, 0xce, 0xf5, 0x33, 0x41, 0x9f, 0x00, 0x43, 0xeb, 0xe3, + 0xee, 0xfc, 0x12, 0xed, 0x0c, 0xc6, 0x02, 0x5b, 0xee, 0xda, 0x1b, 0x1f, + 0xe9, 0x04, 0xf0, 0x0c, 0xfd, 0x0c, 0xff, 0x0c, 0x3d, 0x00, 0x0d, 0xfc, + 0x2a, 0x25, 0xdf, 0x06, 0xfb, 0x39, 0x3f, 0x09, 0x08, 0xee, 0x0f, 0x1c, + 0x0e, 0x2c, 0x1d, 0x01, 0xfd, 0x23, 0xba, 0x04, 0x63, 0xe0, 0xd8, 0x07, + 0x01, 0x04, 0x33, 0xde, 0xf4, 0xf6, 0xeb, 0xf0, 0xda, 0x09, 0x10, 0x2d, + 0x03, 0x0a, 0xaf, 0xf8, 0xff, 0xf1, 0xfe, 0xe6, 0xdf, 0xf0, 0xd4, 0xf5, + 0x1f, 0xd8, 0xe1, 0xf3, 0xe9, 0xd5, 0xca, 0x07, 0xf9, 0xdf, 0xf6, 0xc0, + 0xea, 0x07, 0xf8, 0xdf, 0xe4, 0x26, 0xfa, 0xf4, 0x25, 0x06, 0xea, 0xff, + 0x39, 0x02, 0xbe, 0x11, 0x0f, 0x1f, 0xe2, 0x11, 0xf5, 0x21, 0xfb, 0x01, + 0x3f, 0x13, 0x28, 0x16, 0x03, 0xd4, 0x11, 0x0a, 0xea, 0x05, 0x2e, 0x32, + 0xe0, 0xb2, 0x37, 0xe8, 0xb9, 0x0a, 0x11, 0xed, 0xf0, 0x10, 0x11, 0xdd, + 0xee, 0xff, 0x1c, 0xd8, 0x02, 0xf5, 0xe7, 0xf9, 0xbc, 0x22, 0x3f, 0xf3, + 0xcc, 0xfe, 0x16, 0x09, 0xe6, 0xed, 0x06, 0x04, 0x2d, 0x32, 0xf9, 0xfe, + 0x0c, 0x48, 0x20, 0xf6, 0x09, 0xee, 0x0c, 0x3e, 0x1e, 0xe4, 0xda, 0xfc, + 0x12, 0xfd, 0x08, 0x3a, 0x29, 0x11, 0xe3, 0xed, 0xe6, 0x34, 0x0b, 0xe1, + 0xfc, 0x1d, 0xe3, 0xf8, 0x21, 0xdf, 0xea, 0xd1, 0x1a, 0x1c, 0xe2, 0x1c, + 0x08, 0x11, 0xdd, 0x07, 0xf0, 0xd3, 0xdb, 0xf5, 0x10, 0xf9, 0xfc, 0xdb, + 0x06, 0x14, 0xd9, 0x02, 0x09, 0xf6, 0xfc, 0x09, 0xd0, 0xb7, 0x0b, 0xfc, + 0x11, 0xc9, 0xd9, 0x09, 0x3f, 0x17, 0x8d, 0xe1, 0x0b, 0x01, 0x00, 0x0c, + 0xd0, 0xfc, 0x21, 0xcc, 0x19, 0xcf, 0xfc, 0x2d, 0x04, 0xd0, 0xe6, 0xef, + 0x33, 0x3e, 0xe9, 0x00, 0x27, 0xd9, 0x3a, 0xed, 0xf9, 0x36, 0x15, 0xf9, + 0x31, 0x03, 0x0a, 0x0a, 0xf9, 0x0d, 0x28, 0xf7, 0xe5, 0x45, 0x24, 0xbe, + 0x0a, 0x47, 0xed, 0xe2, 0x55, 0x10, 0x12, 0xf7, 0x06, 0xf7, 0xe7, 0xf1, + 0x1b, 0xeb, 0xc0, 0x25, 0x16, 0xd4, 0xe1, 0x07, 0x0c, 0xf1, 0xef, 0xd4, + 0x08, 0x1b, 0x0f, 0xdd, 0xf9, 0xd8, 0xed, 0x19, 0x01, 0xb4, 0x0d, 0x23, + 0x11, 0xd5, 0x1f, 0x1a, 0xc6, 0xf2, 0x09, 0xf3, 0x01, 0x14, 0xf7, 0x02, + 0xf7, 0x32, 0x16, 0xf5, 0xea, 0xff, 0xff, 0x4b, 0x14, 0xde, 0xf1, 0x2e, + 0x3e, 0x0a, 0xe0, 0x00, 0xfc, 0xea, 0x40, 0x05, 0xed, 0xd9, 0x07, 0xd2, + 0xe6, 0xcb, 0x03, 0xf2, 0x08, 0x01, 0xe1, 0x34, 0xd8, 0x0b, 0xcf, 0xd2, + 0x06, 0x02, 0xcc, 0x09, 0xf8, 0xf2, 0x08, 0xe4, 0x0a, 0x01, 0xdd, 0xef, + 0x11, 0xe2, 0xe3, 0x2a, 0xe9, 0x22, 0x28, 0xf7, 0xec, 0xd0, 0xf6, 0xf7, + 0x07, 0xfa, 0xf5, 0xe7, 0x12, 0x35, 0xfa, 0xe0, 0xfd, 0x01, 0x2a, 0x0c, + 0x09, 0x1c, 0x03, 0x00, 0x1b, 0xfb, 0xf0, 0x03, 0x26, 0xfe, 0xdc, 0xef, + 0x2b, 0x26, 0x2f, 0xfa, 0xfa, 0x48, 0xf3, 0x01, 0x1f, 0x12, 0x13, 0x2f, + 0xe6, 0x13, 0x3c, 0x17, 0x0a, 0x06, 0xf2, 0x37, 0xff, 0xd8, 0x36, 0xf2, + 0xe6, 0xdf, 0xda, 0x0e, 0xe4, 0xed, 0xf4, 0x08, 0xef, 0xec, 0xf4, 0xe4, + 0x0f, 0xd0, 0xdb, 0x04, 0xd7, 0xf8, 0xfe, 0xf1, 0xf6, 0x0f, 0xdf, 0xd2, + 0xfe, 0xf3, 0xd5, 0xea, 0x07, 0xe8, 0xd1, 0x26, 0x07, 0xdb, 0xef, 0x06, + 0x26, 0x14, 0xbf, 0x11, 0x29, 0xcd, 0xdb, 0xe6, 0xe7, 0xf9, 0x01, 0x31, + 0x03, 0xc6, 0xec, 0x06, 0xf8, 0xea, 0xea, 0x1d, 0xfa, 0xd6, 0x08, 0x23, + 0x1c, 0x0a, 0xba, 0xdf, 0x09, 0xf8, 0xea, 0xf8, 0x0b, 0x19, 0xfa, 0x0c, + 0xea, 0xe9, 0x0a, 0x64, 0xfc, 0xe2, 0x2c, 0x22, 0x10, 0x10, 0xf7, 0x35, + 0x2d, 0xdd, 0x2b, 0x38, 0xf9, 0x22, 0x31, 0x20, 0x10, 0x2c, 0x1a, 0x19, + 0x0e, 0x01, 0x07, 0x16, 0xfa, 0x0c, 0x24, 0x05, 0xd3, 0x1c, 0xf7, 0xf9, + 0x0a, 0xf6, 0x24, 0xfb, 0xf0, 0x08, 0xff, 0xd6, 0xfc, 0x1a, 0xeb, 0xf0, + 0xde, 0xec, 0x00, 0x11, 0xcf, 0xea, 0xea, 0x00, 0x09, 0xd4, 0x08, 0xfb, + 0xc5, 0xe1, 0xfc, 0x16, 0xf0, 0x29, 0xf9, 0xec, 0xe9, 0xce, 0x0a, 0x1b, + 0xd8, 0xf3, 0x10, 0xdb, 0xfa, 0xe7, 0x04, 0xfc, 0xe6, 0xe3, 0xf6, 0xf0, + 0xf0, 0x02, 0xfc, 0xfc, 0x01, 0xec, 0x02, 0x01, 0xdd, 0xf3, 0x05, 0x17, + 0xe8, 0xda, 0x11, 0x04, 0x01, 0x08, 0x04, 0x04, 0xdc, 0x0f, 0x21, 0x0d, + 0xd2, 0x0d, 0xff, 0x1b, 0x45, 0xf0, 0xe9, 0xff, 0x35, 0x3c, 0xf2, 0xec, + 0x0c, 0xf6, 0xf2, 0xf6, 0xf3, 0xec, 0x09, 0x0b, 0xf9, 0x18, 0xeb, 0xf6, + 0x0b, 0x21, 0x06, 0x15, 0xe8, 0x02, 0x18, 0x04, 0xee, 0x1b, 0x1e, 0x0a, + 0xfe, 0x00, 0x14, 0x1b, 0x2a, 0xf5, 0xf8, 0xfc, 0x09, 0x12, 0x26, 0x1f, + 0x01, 0xf2, 0x12, 0xed, 0x17, 0x05, 0xfa, 0xff, 0x09, 0x00, 0xf0, 0xfa, + 0x0e, 0xf1, 0xdc, 0xf7, 0x13, 0xfc, 0xed, 0xc8, 0xf0, 0x05, 0xff, 0x05, + 0xef, 0xcf, 0xef, 0xf1, 0xff, 0x01, 0xd2, 0xfc, 0x03, 0xcc, 0xe3, 0x09, + 0xff, 0x01, 0xe8, 0xd7, 0xfc, 0x0f, 0x11, 0xe5, 0xd7, 0xf5, 0xda, 0xed, + 0xdf, 0x07, 0x05, 0xe4, 0xf5, 0x03, 0x00, 0xd6, 0x03, 0x24, 0xfe, 0xfa, + 0xf9, 0x03, 0x08, 0x07, 0x07, 0x21, 0x0d, 0x10, 0xec, 0x22, 0x19, 0xd7, + 0x17, 0x38, 0xf9, 0xf3, 0x0b, 0xe3, 0x1d, 0x08, 0x28, 0x17, 0x1c, 0xed, + 0xeb, 0x0d, 0xf2, 0xf3, 0x0f, 0x1c, 0x32, 0x20, 0x1f, 0xe5, 0xe9, 0x06, + 0x22, 0x29, 0xf7, 0x00, 0x26, 0xec, 0x03, 0x17, 0x10, 0xfb, 0x10, 0x06, + 0x2c, 0xfc, 0xfa, 0xfc, 0x1c, 0xee, 0xbf, 0x04, 0x01, 0xe1, 0x12, 0xf1, + 0xf6, 0x01, 0xed, 0xfb, 0xf2, 0xfe, 0xea, 0xf4, 0x03, 0xf0, 0xd5, 0xfc, + 0x1e, 0xee, 0x03, 0xf0, 0x04, 0xff, 0xff, 0xe9, 0xe2, 0xe1, 0x06, 0x18, + 0xd9, 0xef, 0xea, 0x00, 0xe6, 0x12, 0x07, 0x04, 0x07, 0xff, 0xe9, 0xed, + 0xf4, 0xf0, 0xf3, 0xfe, 0x18, 0xf3, 0x01, 0x05, 0xff, 0xff, 0xfc, 0xed, + 0x04, 0xf0, 0x0f, 0x03, 0xe8, 0x06, 0x1f, 0xf1, 0xf6, 0xe7, 0x0e, 0x00, + 0x01, 0x01, 0xec, 0x09, 0xfa, 0xf5, 0x29, 0x05, 0xee, 0xf6, 0x25, 0xfe, + 0xe8, 0x18, 0x17, 0x00, 0x0f, 0xe2, 0x0a, 0x13, 0x0d, 0x0a, 0xe6, 0x2b, + 0x22, 0xfd, 0xd9, 0x18, 0x23, 0xfa, 0x00, 0x01, 0x04, 0x13, 0x1f, 0x06, + 0x07, 0xfa, 0x02, 0x2e, 0xf8, 0xe8, 0x04, 0x05, 0x25, 0xf4, 0x06, 0x29, + 0x0c, 0xe5, 0xff, 0x24, 0x06, 0xe6, 0xf4, 0x08, 0xf3, 0x12, 0x14, 0xfa, + 0xed, 0x04, 0xec, 0x02, 0xe5, 0x00, 0x18, 0xf7, 0xd3, 0xc2, 0xfe, 0x08, + 0xef, 0xfe, 0xf9, 0xbf, 0xc3, 0xf7, 0x03, 0xf8, 0xdb, 0x10, 0xf6, 0xea, + 0xd7, 0xf5, 0x18, 0x05, 0xdc, 0xdd, 0x1c, 0xfe, 0x00, 0x23, 0x1f, 0xec, + 0xe7, 0x28, 0x23, 0xf3, 0xfc, 0xf5, 0x01, 0x14, 0xf0, 0xf6, 0x01, 0x00, + 0xf8, 0xfc, 0xf1, 0x03, 0xe1, 0x06, 0x14, 0x0d, 0x0d, 0xcc, 0x21, 0xe0, + 0xf1, 0x47, 0xff, 0xfd, 0xff, 0xfc, 0x1c, 0x13, 0x01, 0x13, 0xec, 0xf6, + 0x03, 0x04, 0x07, 0x04, 0x2d, 0x07, 0xde, 0x01, 0x11, 0x10, 0x05, 0xeb, + 0xed, 0xed, 0x15, 0xed, 0xd9, 0xff, 0x12, 0x06, 0xdf, 0x07, 0x10, 0xfe, + 0x0c, 0xf1, 0x21, 0x12, 0x1a, 0x19, 0xe6, 0xe9, 0x15, 0x1c, 0x07, 0xee, + 0x1e, 0x0b, 0xf1, 0x07, 0x07, 0xfd, 0x00, 0x01, 0x00, 0x01, 0x1b, 0x19, + 0xf5, 0xde, 0xf6, 0x03, 0xf8, 0xf9, 0x01, 0xdd, 0x07, 0x23, 0xf4, 0xdb, + 0xe4, 0x05, 0x00, 0xec, 0xf0, 0x04, 0xf8, 0xe7, 0x06, 0x0c, 0xf1, 0xdc, + 0xd7, 0xea, 0x16, 0xfe, 0xfb, 0x01, 0x08, 0x0e, 0x10, 0x0d, 0xde, 0x01, + 0xff, 0xf8, 0xf6, 0xf9, 0xfc, 0xfc, 0xf1, 0xec, 0x20, 0x07, 0xf5, 0xf6, + 0xf9, 0x12, 0xf8, 0xe2, 0x0b, 0x07, 0x16, 0xcd, 0xfc, 0x01, 0x09, 0xee, + 0x03, 0x05, 0xf7, 0xfc, 0xff, 0x27, 0x09, 0x06, 0x00, 0xff, 0xf0, 0x22, + 0x07, 0x0a, 0x0a, 0xfe, 0x17, 0x10, 0xf4, 0x00, 0x01, 0x26, 0x2c, 0xf1, + 0xdb, 0x1b, 0x0d, 0xed, 0x13, 0xe9, 0x02, 0x00, 0xff, 0x1b, 0x04, 0xeb, + 0xf0, 0x02, 0x09, 0x07, 0xf2, 0xf9, 0xfc, 0xed, 0x05, 0x1f, 0xff, 0xe4, + 0x2c, 0x05, 0xf9, 0xf1, 0xfe, 0x24, 0xe5, 0xe1, 0x0f, 0x00, 0xfb, 0xff, + 0xf0, 0x0f, 0xff, 0xf4, 0x01, 0xf4, 0x03, 0xf7, 0x0a, 0xeb, 0xff, 0x02, + 0xdd, 0x05, 0xed, 0x02, 0x1f, 0xee, 0xe7, 0xed, 0x20, 0xfb, 0xf0, 0x04, + 0x0c, 0xee, 0xf6, 0x07, 0x0b, 0xf5, 0xf9, 0x12, 0xfe, 0xff, 0x01, 0xec, + 0xff, 0x02, 0xf7, 0xf2, 0xdd, 0x02, 0x02, 0xf7, 0xfc, 0xf1, 0xf6, 0xfd, + 0xea, 0x0d, 0x00, 0xe5, 0xf1, 0xf7, 0xeb, 0x0d, 0x0a, 0xee, 0xf0, 0x09, + 0xfe, 0xf4, 0xfd, 0x15, 0x17, 0xfa, 0xe5, 0x06, 0xf7, 0xf2, 0x1b, 0x01, + 0x2d, 0xf7, 0xf0, 0x0f, 0xff, 0xe1, 0x01, 0x20, 0x0a, 0xf4, 0x06, 0x0f, + 0x1c, 0xee, 0x0b, 0x07, 0x12, 0x22, 0xf7, 0xff, 0x14, 0xfe, 0x22, 0x11, + 0x13, 0x16, 0x07, 0x0d, 0x02, 0xff, 0x2e, 0x00, 0x19, 0x07, 0x07, 0x19, + 0x07, 0xf5, 0x01, 0x01, 0x22, 0x02, 0xeb, 0xed, 0xea, 0x21, 0x00, 0xd9, + 0x06, 0xf0, 0x02, 0xe5, 0xd1, 0xdc, 0xde, 0xf4, 0xfb, 0x00, 0x01, 0xff, + 0xe9, 0xed, 0xf8, 0xeb, 0x03, 0x00, 0xff, 0xf0, 0xfa, 0xfc, 0xf1, 0xf6, + 0x01, 0xf4, 0xfd, 0xf9, 0xe3, 0xea, 0xf5, 0x08, 0xf7, 0xdb, 0xe8, 0x05, + 0x00, 0x05, 0xf7, 0x03, 0x10, 0xfd, 0x01, 0x1b, 0xe3, 0xed, 0x27, 0x06, + 0x03, 0xf3, 0xfd, 0x01, 0x0c, 0x1c, 0xe6, 0xfb, 0x0e, 0xfe, 0x01, 0x01, + 0x10, 0xf8, 0x02, 0x01, 0x04, 0xfa, 0x11, 0xfd, 0x00, 0x10, 0xfc, 0xff, + 0x09, 0xee, 0xf3, 0xfe, 0x02, 0x00, 0x01, 0x04, 0x0b, 0xf5, 0xfc, 0xf1, + 0x04, 0x1f, 0x07, 0xf9, 0xfc, 0xfc, 0x11, 0x02, 0xef, 0xfe, 0x15, 0xf7, + 0x15, 0xfb, 0xed, 0x18, 0x0d, 0x10, 0x01, 0x1a, 0x0b, 0xf4, 0xf9, 0x0e, + 0x1c, 0x0e, 0x17, 0x0f, 0xf0, 0x07, 0x0b, 0xff, 0x04, 0xfe, 0xe5, 0xea, + 0xed, 0xe6, 0xf2, 0xde, 0x09, 0x17, 0xeb, 0xe8, 0xed, 0xf4, 0xe1, 0xef, + 0xf8, 0x0f, 0xf5, 0xe7, 0x04, 0xe9, 0xe6, 0xe0, 0x07, 0x1f, 0x16, 0xfb, + 0xf0, 0xf3, 0xfa, 0x00, 0x05, 0x25, 0x01, 0x00, 0xf4, 0xfd, 0x02, 0x1f, + 0x03, 0xeb, 0x09, 0x04, 0x01, 0x04, 0xfe, 0xf4, 0xf6, 0xf3, 0xfe, 0x01, + 0x00, 0x23, 0xf9, 0x00, 0xf8, 0xf6, 0x12, 0xf8, 0xea, 0xf4, 0x0f, 0x0d, + 0xf8, 0xe6, 0xf5, 0x03, 0x05, 0x04, 0x07, 0x04, 0x0b, 0x07, 0xff, 0xf8, + 0x00, 0x05, 0x01, 0xf0, 0xf3, 0x02, 0x10, 0x0a, 0xf5, 0xee, 0xf3, 0x0c, + 0xfd, 0xf4, 0x07, 0x04, 0x0b, 0x19, 0xee, 0x02, 0x17, 0xf7, 0x09, 0x0a, + 0x2b, 0x25, 0xf6, 0xf8, 0xf9, 0x06, 0x04, 0x01, 0xff, 0xf8, 0x06, 0x0b, + 0xd7, 0xfb, 0x02, 0xf4, 0xe4, 0x16, 0x2b, 0xdc, 0xe7, 0x0b, 0x01, 0xff, + 0xfc, 0xf1, 0x1b, 0x16, 0xf6, 0xfc, 0x06, 0x0f, 0x06, 0xeb, 0xf7, 0x0f, + 0xfd, 0xfc, 0x01, 0x26, 0x18, 0xf5, 0x02, 0x01, 0x08, 0xeb, 0xf3, 0x03, + 0xf8, 0xf9, 0xdb, 0xda, 0x0e, 0x0b, 0xea, 0xf7, 0x02, 0xf8, 0xfc, 0xde, + 0xe4, 0xf6, 0xf3, 0x03, 0xff, 0x00, 0x01, 0xfb, 0xf1, 0xfe, 0x09, 0x12, + 0x0f, 0xfd, 0x00, 0x00, 0x00, 0x12, 0xf5, 0x01, 0x21, 0x14, 0xf7, 0xfd, + 0x00, 0x07, 0xff, 0xf5, 0xfa, 0xfd, 0x0f, 0x1b, 0xfa, 0xee, 0xf1, 0xea, + 0xfa, 0x02, 0xf9, 0xf7, 0xec, 0x04, 0xfd, 0xf6, 0xfe, 0x00, 0x07, 0xec, + 0xee, 0xf1, 0x03, 0x16, 0xf4, 0xe1, 0x0e, 0x11, 0xfd, 0x00, 0x00, 0x00, + 0x07, 0x06, 0x13, 0x00, 0xfc, 0x00, 0x00, 0xeb, 0x08, 0x18, 0x0d, 0xf9, + 0x08, 0x06, 0xff, 0xf1, 0xfb, 0xfd, 0x00, 0x1c, 0xfe, 0x00, 0x07, 0x0d, + 0x09, 0xdf, 0xf8, 0x0e, 0x06, 0xf7, 0xed, 0x0b, 0x1a, 0x02, 0x13, 0x07, + 0xfe, 0x00, 0x00, 0xfd, 0xfd, 0x00, 0x00, 0x11, 0x0e, 0xfd, 0xeb, 0xf2, + 0xfc, 0x01, 0x07, 0xff, 0x03, 0xf8, 0xf4, 0x0a, 0x12, 0x1d, 0xfa, 0xdf, + 0xeb, 0x05, 0x03, 0x00, 0x00, 0xef, 0xea, 0x05, 0xfd, 0x04, 0x06, 0xf1, + 0x02, 0xf6, 0x02, 0xf6, 0xf5, 0xeb, 0xf0, 0x04, 0xf3, 0xff, 0x0a, 0xf1, + 0x02, 0x00, 0x00, 0x03, 0x0f, 0xfd, 0x00, 0x00, 0x03, 0x00, 0x0d, 0x0d, + 0xfd, 0xea, 0xf0, 0xf3, 0xff, 0x00, 0x00, 0xf6, 0x02, 0x00, 0x0a, 0xfe, + 0xf6, 0x02, 0x0c, 0xfe, 0x03, 0xf9, 0x01, 0x03, 0xfc, 0x00, 0x0c, 0x08, + 0x02, 0x09, 0x0a, 0xfe, 0xf6, 0xfe, 0x00, 0x0a, 0x05, 0xff, 0x00, 0x00, + 0x00, 0xf1, 0xdf, 0x03, 0x07, 0x05, 0x03, 0xfc, 0xfb, 0x01, 0x03, 0x00, + 0x00, 0x06, 0x03, 0x00, 0x00, 0x0f, 0x04, 0xff, 0x06, 0xff, 0xfd, 0xf5, + 0x11, 0x04, 0xf9, 0x07, 0xff, 0x00, 0xfd, 0xec, 0x10, 0x0a, 0xef, 0xf2, + 0xec, 0xdb, 0xf7, 0xff, 0x00, 0x06, 0x03, 0x05, 0x03, 0xf9, 0xf6, 0x0b, + 0x0d, 0xfd, 0x00, 0x0b, 0x1d, 0x0c, 0x03, 0xf4, 0xff, 0x06, 0x07, 0xff, + 0x00, 0x14, 0x10, 0x05, 0x07, 0x12, 0x0d, 0xf4, 0xf9, 0xff, 0xf8, 0x01, + 0x00, 0x06, 0xf6, 0xf4, 0x00, 0x09, 0xf8, 0x03, 0x00, 0xf0, 0x00, 0xec, + 0xf1, 0x03, 0x08, 0xf6, 0xf4, 0xf7, 0x02, 0x05, 0xfd, 0x00, 0xf3, 0xf3, + 0xf8, 0xff, 0xee, 0xf3, 0xfb, 0x06, 0x04, 0x04, 0xfa, 0x01, 0x00, 0xfe, + 0xfe, 0x00, 0xee, 0xf9, 0x04, 0x00, 0xfb, 0xfa, 0x01, 0x12, 0x04, 0xff, + 0xfb, 0xf2, 0x03, 0x0c, 0xfe, 0xf9, 0xee, 0xff, 0x03, 0x00, 0x05, 0xfd, + 0x03, 0x09, 0x14, 0x08, 0xf9, 0x01, 0x0a, 0xfe, 0x05, 0x02, 0x00, 0xfb, + 0x01, 0xfb, 0x12, 0x0c, 0xfd, 0x00, 0x05, 0xff, 0xfb, 0x01, 0x0a, 0x06, + 0xfc, 0xfc, 0x01, 0xfb, 0xfc, 0x10, 0x0d, 0xfd, 0xf4, 0xfd, 0x01, 0xf6, + 0xfa, 0xff, 0x05, 0xff, 0xfe, 0x05, 0xff, 0xee, 0xfc, 0x01, 0x05, 0xff, + 0xfe, 0x00, 0x02, 0xfd, 0xfc, 0x06, 0x0c, 0x06, 0x01, 0xf2, 0xf5, 0x02, + 0x07, 0x0c, 0xfe, 0xfb, 0x0e, 0x06, 0xff, 0xfa, 0x01, 0x02, 0xf2, 0xf7, + 0xf5, 0xf4, 0xfa, 0x01, 0xfe, 0xf8, 0xf9, 0xff, 0x05, 0xf9, 0x0a, 0x0a, + 0xf9, 0xf0, 0x01, 0xfc, 0xf6, 0xfd, 0x04, 0x03, 0x02, 0x03, 0x02, 0x00, + 0x03, 0x02, 0x00, 0xfa, 0xf5, 0xf8, 0x0c, 0x0d, 0xfd, 0xfa, 0xf8, 0x02, + 0x03, 0x0e, 0x06, 0xff, 0x00, 0x00, 0xf3, 0x00, 0x06, 0x03, 0xfc, 0xfb, + 0x05, 0x00, 0xfa, 0xfa, 0xff, 0x08, 0xff, 0x02, 0xfd, 0xfd, 0x08, 0x01, + 0xfa, 0x05, 0x06, 0xf9, 0xfd, 0x07, 0xfd, 0xf7, 0xfe, 0xfe, 0x06, 0x03, + 0xf9, 0xfd, 0x00, 0x02, 0x02, 0x00, 0x02, 0x09, 0x01, 0x05, 0xff, 0x03, + 0x03, 0x08, 0x0d, 0x02, 0xfe, 0x00, 0x01, 0x07, 0x06, 0xf7, 0x01, 0x0b, + 0xfe, 0x01, 0x07, 0x00, 0xff, 0xf8, 0xf9, 0xfe, 0xfc, 0xf6, 0xfd, 0x08, + 0x04, 0xff, 0xfb, 0xfd, 0xfc, 0x01, 0x03, 0xfb, 0xfa, 0x01, 0x00, 0x00, + 0xfd, 0xfc, 0xfd, 0xf8, 0xfe, 0x00, 0xff, 0xf8, 0xf9, 0x01, 0xfd, 0xfb, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x1f, 0x23, 0xd4, 0xaf, 0xdd, 0x2e, 0x53, + 0x16, 0xd0, 0xd6, 0x30, 0xe5, 0xb1, 0xa0, 0xd4, 0x07, 0xc9, 0xf0, 0xb8, + 0xa4, 0xda, 0x0c, 0xcf, 0xbc, 0x9b, 0x99, 0xee, 0xc0, 0xb5, 0xd2, 0x0c, + 0xc7, 0xf7, 0xd6, 0xee, 0xcd, 0x25, 0x33, 0xda, 0xe7, 0xf5, 0x4a, 0x19, + 0xcf, 0x18, 0x25, 0x28, 0x4b, 0xff, 0x16, 0x37, 0xfb, 0xd2, 0x14, 0x4b, + 0x4a, 0x16, 0x5e, 0x7a, 0x7d, 0x39, 0x37, 0x1b, 0x51, 0x2a, 0x14, 0x53, + 0x3d, 0x18, 0x4b, 0x5c, 0x5e, 0x56, 0x4b, 0x37, 0x40, 0x4f, 0x48, 0x37, + 0x3d, 0x37, 0x37, 0x39, 0x28, 0x16, 0x28, 0x23, 0x07, 0x10, 0xf9, 0x18, + 0xf7, 0x28, 0x0b, 0xea, 0xe7, 0x07, 0xe3, 0xd6, 0xc5, 0xc2, 0xd4, 0xc2, + 0xc9, 0xe1, 0xf5, 0xd0, 0xd8, 0xc7, 0xb8, 0xbc, 0xd2, 0xc5, 0xc5, 0xad, + 0xcd, 0xba, 0xc5, 0xbc, 0xcb, 0xda, 0xd2, 0xcf, 0xd0, 0xd2, 0xd2, 0xd8, + 0xee, 0xec, 0xdf, 0xe5, 0xf0, 0xf9, 0xf5, 0xfb, 0x03, 0x0c, 0xfb, 0x1b, + 0x16, 0x05, 0x37, 0x2e, 0x19, 0x14, 0x26, 0x2a, 0x4f, 0x67, 0x16, 0x28, + 0x58, 0x6d, 0x4d, 0x31, 0xf2, 0x3b, 0x40, 0x07, 0x4d, 0x2a, 0x1d, 0x18, + 0x2c, 0x55, 0x58, 0x39, 0x30, 0x31, 0x46, 0x3d, 0x31, 0x30, 0x2c, 0x2a, + 0x2e, 0x19, 0x10, 0x2e, 0x25, 0x1d, 0x12, 0x07, 0x07, 0x1f, 0x19, 0x0e, + 0xff, 0xdf, 0xe8, 0x14, 0xff, 0xe7, 0xd0, 0xf2, 0xdd, 0xd2, 0xe8, 0xf5, + 0xee, 0xc0, 0xe1, 0xc7, 0xb8, 0xf9, 0xbe, 0xa4, 0xd2, 0xc9, 0xc2, 0xbc, + 0xc5, 0xcd, 0xd0, 0xb8, 0xc5, 0xcd, 0xd6, 0xcf, 0xc9, 0xd4, 0xe3, 0xd4, + 0xe7, 0xea, 0xe1, 0xea, 0xe8, 0xe1, 0xf2, 0x01, 0xf4, 0xf5, 0xea, 0x03, + 0x00, 0x03, 0x07, 0x10, 0xff, 0x10, 0x07, 0x0e, 0x10, 0x25, 0x33, 0x23, + 0x23, 0x01, 0x23, 0x2c, 0x2a, 0x23, 0x3b, 0x37, 0x1f, 0x3d, 0x3b, 0x1d, + 0x21, 0x3d, 0x28, 0x23, 0x30, 0x23, 0x28, 0x23, 0x19, 0x1d, 0x1d, 0x19, + 0x1d, 0x1b, 0x14, 0x0e, 0x0b, 0x0c, 0x10, 0x0e, 0x01, 0xf2, 0x0b, 0x05, + 0x12, 0x03, 0xfd, 0xdf, 0xf2, 0xf0, 0xbc, 0xe1, 0xff, 0xf9, 0xc0, 0xc3, + 0xd2, 0xf9, 0xe5, 0xd4, 0xbc, 0xcf, 0xd0, 0xcf, 0xcb, 0xdb, 0xc5, 0xc2, + 0xc9, 0xf2, 0xe8, 0xba, 0xc9, 0xd2, 0xd0, 0xcf, 0xd8, 0xdd, 0xdb, 0xdd, + 0xd4, 0xe8, 0xe1, 0xe3, 0xee, 0xee, 0xf4, 0xe1, 0xe7, 0xec, 0x00, 0xf9, + 0xea, 0xf9, 0x0e, 0xfd, 0x01, 0x10, 0xf2, 0xf9, 0x10, 0x01, 0x09, 0x18, + 0x19, 0x05, 0x2c, 0x23, 0x1b, 0x16, 0x0c, 0x25, 0x28, 0x1d, 0x31, 0x33, + 0x42, 0x21, 0x31, 0x39, 0x33, 0x30, 0x1d, 0x2c, 0x1b, 0x1d, 0x23, 0x2a, + 0x25, 0x1d, 0x1d, 0x18, 0x18, 0x18, 0x18, 0x10, 0x0e, 0x0b, 0x07, 0x09, + 0x05, 0x0b, 0x10, 0x07, 0xfd, 0xff, 0xf5, 0xf7, 0xf0, 0xf5, 0x07, 0x00, + 0xf5, 0xf5, 0xee, 0xda, 0xc9, 0xea, 0xdd, 0x07, 0xda, 0xba, 0xbc, 0xdb, + 0xcf, 0xd0, 0xd8, 0xc9, 0xc7, 0xd4, 0xcf, 0xd4, 0xc7, 0xc5, 0xd0, 0xd2, + 0xd6, 0xd4, 0xd2, 0xe5, 0xe1, 0xdb, 0xe5, 0xe7, 0xe1, 0xe7, 0xea, 0xee, + 0xee, 0xec, 0xf5, 0x00, 0xee, 0xf2, 0x05, 0xf5, 0xf4, 0x09, 0x19, 0x03, + 0x0e, 0x03, 0x16, 0x12, 0x0c, 0x0c, 0x19, 0x30, 0x1f, 0x16, 0x30, 0x23, + 0x21, 0x16, 0x10, 0x35, 0x2c, 0x1b, 0x19, 0x1d, 0x1f, 0x2c, 0x1d, 0x1d, + 0x0b, 0x23, 0x2c, 0x19, 0x1b, 0x18, 0x10, 0x1b, 0x0e, 0x0c, 0x10, 0x0c, + 0x10, 0x0e, 0x0e, 0x14, 0x12, 0x01, 0x00, 0x05, 0xfd, 0xf9, 0xff, 0xfb, + 0x00, 0xf5, 0xe7, 0xea, 0xf0, 0xf7, 0xe8, 0xe3, 0xda, 0xf0, 0xdb, 0xe1, + 0xdb, 0xc2, 0xcf, 0xdb, 0xe1, 0xd8, 0xd0, 0xd8, 0xdb, 0xcf, 0xd8, 0xe5, + 0xcd, 0xd8, 0xd6, 0xd8, 0xe3, 0xdd, 0xda, 0xdb, 0xe7, 0xd8, 0xdd, 0xe3, + 0xec, 0xf4, 0xf0, 0xf0, 0xf2, 0xec, 0xf0, 0xfb, 0xfd, 0xff, 0xf5, 0xfd, + 0x18, 0x09, 0xf4, 0x05, 0x10, 0x0b, 0x12, 0x10, 0x1f, 0x0e, 0x16, 0x19, + 0x0e, 0x14, 0x09, 0x14, 0x10, 0x0b, 0x2e, 0x1d, 0x1d, 0x28, 0x21, 0x26, + 0x28, 0x1f, 0x2c, 0x2c, 0x19, 0x16, 0x19, 0x1f, 0x26, 0x1b, 0x0c, 0x1d, + 0x21, 0x21, 0x1b, 0x12, 0x14, 0x10, 0x0c, 0x09, 0x09, 0x07, 0x03, 0x0b, + 0x09, 0x03, 0x03, 0xf9, 0xf2, 0xfb, 0x03, 0xf4, 0xec, 0xff, 0xff, 0xf2, + 0xec, 0xf0, 0xf2, 0xf5, 0xf7, 0xe5, 0xea, 0xe3, 0xe3, 0xe5, 0xe3, 0xd6, + 0xe3, 0xe8, 0xdd, 0xe3, 0xe5, 0xdf, 0xda, 0xd8, 0xe5, 0xea, 0xdf, 0xdd, + 0xdf, 0xe1, 0xe8, 0xe7, 0xe7, 0xee, 0xf0, 0xe3, 0xec, 0xf5, 0xf5, 0xee, + 0xea, 0xf5, 0xf9, 0xff, 0x09, 0xee, 0xe8, 0xf5, 0xfd, 0xec, 0x07, 0xff, + 0x00, 0xf5, 0x03, 0x05, 0xf9, 0x00, 0x23, 0x2e, 0x1b, 0x0e, 0xf0, 0x19, + 0x1b, 0x30, 0xfb, 0x0c, 0x35, 0x18, 0x0c, 0x26, 0x01, 0x18, 0x25, 0x12, + 0x1b, 0x25, 0x25, 0x12, 0x12, 0x25, 0x26, 0x0e, 0x12, 0x1f, 0x18, 0x16, + 0x1d, 0x1d, 0x14, 0x12, 0x10, 0x12, 0x0c, 0xff, 0x03, 0x10, 0x0c, 0xff, + 0xf7, 0xff, 0x00, 0x10, 0xfd, 0x09, 0xfd, 0x00, 0x03, 0xff, 0xdf, 0xec, + 0xf7, 0xff, 0xe1, 0xdd, 0xf2, 0xe8, 0xdd, 0xda, 0xe3, 0xdd, 0xe5, 0xda, + 0xdd, 0xdf, 0xd8, 0xd6, 0xd4, 0xdf, 0xe3, 0xd8, 0xd6, 0xe5, 0xe5, 0xea, + 0xe3, 0xe7, 0xee, 0xe7, 0xea, 0xee, 0xf0, 0xe7, 0xea, 0xf4, 0xf5, 0xf2, + 0xf7, 0xf2, 0x03, 0x01, 0xf5, 0xf7, 0xfd, 0xfd, 0x07, 0xfb, 0x0b, 0x01, + 0xf9, 0x03, 0x0e, 0x00, 0x03, 0x09, 0x05, 0x07, 0x05, 0x26, 0x19, 0x0b, + 0x2e, 0x1b, 0xfd, 0x0c, 0x30, 0x21, 0x03, 0x0e, 0x2a, 0x30, 0x28, 0x1b, + 0x1f, 0x18, 0x1d, 0x2a, 0x33, 0x19, 0x14, 0x1d, 0x16, 0x19, 0x19, 0x14, + 0x16, 0x16, 0x19, 0x14, 0x14, 0x12, 0x0e, 0x0b, 0x00, 0x10, 0x16, 0x0c, + 0x07, 0x05, 0x09, 0x01, 0xfb, 0xfb, 0x05, 0xf5, 0xf4, 0xf7, 0xe8, 0xff, + 0xee, 0xf0, 0xf2, 0xea, 0xdf, 0xdf, 0xe8, 0xe8, 0xdf, 0xd6, 0xdd, 0xe1, + 0xe8, 0xe1, 0xd6, 0xd2, 0xd6, 0xdf, 0xdd, 0xea, 0xe8, 0xdb, 0xdb, 0xd6, + 0xda, 0xe7, 0xe1, 0xe7, 0xe1, 0xe3, 0xe7, 0xec, 0xe8, 0xf2, 0xf0, 0xf7, + 0xf2, 0xf5, 0xf4, 0xee, 0xf0, 0xf7, 0xfd, 0xfb, 0xf7, 0x05, 0x0b, 0xff, + 0xff, 0x09, 0x1f, 0x0c, 0x12, 0x18, 0x14, 0x07, 0x16, 0x2a, 0x23, 0x1f, + 0x1d, 0x0c, 0x19, 0x25, 0x2a, 0x19, 0x16, 0x2a, 0x37, 0x1f, 0x28, 0x30, + 0x28, 0x1f, 0x25, 0x25, 0x16, 0x23, 0x21, 0x1d, 0x1b, 0x19, 0x21, 0x1b, + 0x12, 0x18, 0x16, 0x07, 0x12, 0x14, 0x0c, 0xff, 0xfd, 0x0b, 0x0c, 0x0c, + 0x07, 0x00, 0x03, 0xf5, 0xf2, 0xf0, 0xf2, 0xf0, 0xdf, 0xff, 0xec, 0xf2, + 0xe7, 0xdb, 0xe3, 0xe5, 0xd2, 0xdb, 0xe1, 0xdf, 0xdd, 0xd6, 0xd2, 0xd4, + 0xd0, 0xcf, 0xd8, 0xda, 0xe1, 0xdb, 0xd6, 0xd0, 0xd6, 0xda, 0xe1, 0xda, + 0xdb, 0xe3, 0xf0, 0xe8, 0xdf, 0xe1, 0xea, 0xee, 0xf0, 0xf4, 0xee, 0xf5, + 0xfb, 0xf4, 0xf4, 0xf4, 0xfb, 0xf9, 0x00, 0x01, 0x00, 0x03, 0x03, 0x12, + 0x18, 0x0b, 0x0e, 0x14, 0x12, 0x18, 0x21, 0x1f, 0x12, 0x21, 0x26, 0x21, + 0x1f, 0x26, 0x2a, 0x2c, 0x28, 0x1d, 0x1f, 0x25, 0x37, 0x2c, 0x21, 0x23, + 0x2e, 0x2a, 0x25, 0x1d, 0x16, 0x1f, 0x23, 0x23, 0x16, 0x14, 0x16, 0x1d, + 0x23, 0x12, 0x09, 0x12, 0x1d, 0x16, 0x0c, 0x07, 0x0e, 0x03, 0x03, 0x01, + 0x01, 0xfd, 0xf4, 0xf7, 0x01, 0xfd, 0xf7, 0xea, 0xe3, 0xea, 0xe8, 0xdd, + 0xe1, 0xe1, 0xdf, 0xe5, 0xdd, 0xda, 0xd2, 0xd4, 0xcd, 0xd6, 0xd4, 0xd0, + 0xda, 0xd6, 0xd8, 0xdd, 0xd8, 0xd4, 0xd8, 0xdb, 0xdd, 0xd8, 0xdf, 0xdf, + 0xe1, 0xdd, 0xe5, 0xea, 0xea, 0xea, 0xea, 0xea, 0xf0, 0xf0, 0xf2, 0xf9, + 0xff, 0xfd, 0xff, 0x00, 0x09, 0x05, 0x00, 0x07, 0x03, 0x01, 0x07, 0x10, + 0x18, 0x18, 0x12, 0x18, 0x1f, 0x14, 0x19, 0x21, 0x23, 0x23, 0x2c, 0x23, + 0x21, 0x23, 0x2a, 0x2a, 0x23, 0x21, 0x23, 0x21, 0x25, 0x1d, 0x21, 0x1f, + 0x18, 0x19, 0x1b, 0x1d, 0x23, 0x1b, 0x0c, 0x19, 0x1b, 0x19, 0x1b, 0x14, + 0x0e, 0x0e, 0x0c, 0x0b, 0x0b, 0x07, 0x05, 0x01, 0x01, 0x01, 0xff, 0xf7, + 0xf5, 0xf2, 0xf0, 0xf2, 0xee, 0xec, 0xea, 0xf0, 0xe5, 0xea, 0xee, 0xe7, + 0xdd, 0xe1, 0xe5, 0xe3, 0xe1, 0xe3, 0xd6, 0xd0, 0xdb, 0xe5, 0xe5, 0xd4, + 0xd8, 0xdf, 0xdb, 0xe5, 0xe5, 0xdf, 0xdd, 0xe7, 0xe5, 0xe7, 0xe8, 0xe7, + 0xee, 0xee, 0xea, 0xea, 0xea, 0xf5, 0xf5, 0xf4, 0xf4, 0xf5, 0xfb, 0xff, + 0x00, 0x01, 0x01, 0xff, 0x05, 0x09, 0x09, 0x07, 0x09, 0x10, 0x0c, 0x12, + 0x14, 0x12, 0x0c, 0x12, 0x14, 0x16, 0x18, 0x16, 0x10, 0x14, 0x12, 0x10, + 0x1b, 0x1f, 0x25, 0x16, 0x12, 0x12, 0x18, 0x18, 0x16, 0x12, 0x18, 0x19, + 0x1b, 0x19, 0x10, 0x0e, 0x14, 0x10, 0x14, 0x18, 0x12, 0x10, 0x18, 0x10, + 0x0b, 0x09, 0x10, 0x0e, 0x03, 0xfd, 0x07, 0x07, 0x0c, 0x05, 0xf9, 0xf9, + 0x05, 0xff, 0xf5, 0xfd, 0xf5, 0xf9, 0xf5, 0xee, 0xf5, 0xf4, 0xf4, 0xf0, + 0xf5, 0xf9, 0xf2, 0xec, 0xea, 0xe1, 0xe5, 0xee, 0xec, 0xec, 0xe7, 0xf0, + 0xec, 0xee, 0xf0, 0xee, 0xe8, 0xe7, 0xec, 0xf0, 0xf0, 0xf0, 0xf4, 0xf2, + 0xee, 0xe8, 0xf4, 0xf7, 0xf7, 0xf5, 0xf2, 0xf7, 0xf9, 0xf5, 0xf4, 0xf9, + 0xff, 0xf9, 0xf4, 0xfb, 0xf7, 0xf4, 0xf7, 0xfd, 0xff, 0x03, 0x01, 0x00, + 0x01, 0x05, 0x00, 0x07, 0x03, 0x01, 0x07, 0x07, 0x0b, 0x09, 0x0c, 0x10, + 0x0e, 0x0b, 0x10, 0x0e, 0x0b, 0x09, 0x03, 0x03, 0x0b, 0x0c, 0x0b, 0x12, + 0x0e, 0x12, 0x14, 0x12, 0x10, 0x0e, 0x16, 0x14, 0x12, 0x0e, 0x12, 0x16, + 0x16, 0x12, 0x18, 0x14, 0x12, 0x14, 0x18, 0x0e, 0x0e, 0x16, 0x12, 0x01, + 0x09, 0x12, 0x10, 0x09, 0x07, 0x09, 0x10, 0x07, 0xfd, 0xfd, 0x09, 0x05, + 0xf9, 0xf5, 0x03, 0x03, 0xfb, 0xf2, 0xf9, 0xf2, 0xfb, 0xff, 0xf0, 0xec, + 0xf0, 0xee, 0xf0, 0xec, 0xea, 0xfb, 0xf2, 0xe3, 0xe7, 0xe8, 0xe7, 0xe5, + 0xea, 0xea, 0xe7, 0xec, 0xe8, 0xe8, 0xe8, 0xf0, 0xec, 0xe7, 0xea, 0xec, + 0xec, 0xe5, 0xea, 0xec, 0xf4, 0xf4, 0xf2, 0xf2, 0xf2, 0xf5, 0xf5, 0xf0, + 0xf2, 0xf2, 0xf4, 0xfb, 0xfd, 0xfb, 0xf5, 0xf4, 0xf9, 0xf7, 0xfb, 0xf7, + 0xf5, 0x00, 0x05, 0x07, 0x07, 0x07, 0x0c, 0x09, 0x0b, 0x0c, 0x10, 0x10, + 0x14, 0x16, 0x14, 0x12, 0x14, 0x1b, 0x1f, 0x21, 0x23, 0x23, 0x21, 0x1d, + 0x1b, 0x1b, 0x21, 0x1d, 0x1d, 0x21, 0x1b, 0x1d, 0x16, 0x1d, 0x1b, 0x19, + 0x1b, 0x18, 0x12, 0x12, 0x16, 0x0e, 0x0e, 0x0b, 0x05, 0x0e, 0x10, 0x07, + 0x05, 0x03, 0x05, 0x00, 0xf7, 0xff, 0x00, 0xfb, 0xf9, 0xf9, 0xfb, 0xf9, + 0xf4, 0xf4, 0xf2, 0xe8, 0xf0, 0xea, 0xec, 0xea, 0xe8, 0xe7, 0xe3, 0xdd, + 0xdb, 0xdf, 0xe7, 0xdf, 0xda, 0xe3, 0xdd, 0xe5, 0xe1, 0xdd, 0xdf, 0xe3, + 0xe1, 0xe5, 0xe7, 0xe5, 0xe5, 0xdd, 0xe7, 0xee, 0xe7, 0xe8, 0xea, 0xf2, + 0xf4, 0xee, 0xf0, 0xf5, 0xf7, 0xf5, 0xf7, 0xf7, 0xff, 0x00, 0x01, 0x03, + 0xfd, 0x00, 0x0b, 0x10, 0x0e, 0x05, 0x12, 0x14, 0x12, 0x18, 0x16, 0x16, + 0x18, 0x16, 0x19, 0x1f, 0x21, 0x1d, 0x1f, 0x1d, 0x23, 0x1f, 0x21, 0x23, + 0x23, 0x21, 0x1f, 0x21, 0x23, 0x1f, 0x21, 0x1b, 0x1b, 0x19, 0x23, 0x23, + 0x1d, 0x14, 0x16, 0x1d, 0x18, 0x18, 0x12, 0x10, 0x0e, 0x16, 0x10, 0x0e, + 0x07, 0x05, 0x07, 0x05, 0x05, 0xff, 0xfd, 0x01, 0xfd, 0xfb, 0xf7, 0xf4, + 0xf2, 0xee, 0xee, 0xf7, 0xea, 0xe3, 0xe7, 0xee, 0xea, 0xe5, 0xe3, 0xea, + 0xe8, 0xe3, 0xe3, 0xe7, 0xdd, 0xe3, 0xe5, 0xe5, 0xdf, 0xdd, 0xdd, 0xdb, + 0xe1, 0xdf, 0xdb, 0xe3, 0xe5, 0xe3, 0xe7, 0xe3, 0xdf, 0xe3, 0xe5, 0xea, + 0xea, 0xe7, 0xec, 0xf0, 0xee, 0xf0, 0xf4, 0xf4, 0xf2, 0xf0, 0x00, 0x01, + 0xf9, 0xf9, 0x00, 0x09, 0x09, 0x05, 0x03, 0x09, 0x0c, 0x12, 0x14, 0x14, + 0x12, 0x12, 0x16, 0x19, 0x10, 0x12, 0x12, 0x14, 0x18, 0x1b, 0x1b, 0x19, + 0x1b, 0x1d, 0x21, 0x1f, 0x1b, 0x19, 0x1f, 0x23, 0x1b, 0x19, 0x1b, 0x16, + 0x1d, 0x18, 0x14, 0x18, 0x16, 0x14, 0x14, 0x16, 0x10, 0x0e, 0x0e, 0x14, + 0x12, 0x0c, 0x0b, 0x03, 0x0b, 0x07, 0x01, 0x01, 0x03, 0x01, 0x03, 0xfb, + 0xfd, 0xf9, 0xf9, 0xf5, 0xf2, 0xf2, 0xf5, 0xf7, 0xf0, 0xea, 0xf0, 0xf9, + 0xf2, 0xea, 0xf0, 0xf7, 0xf2, 0xe7, 0xe8, 0xf0, 0xf0, 0xee, 0xea, 0xea, + 0xf4, 0xf4, 0xe8, 0xec, 0xee, 0xe8, 0xe7, 0xea, 0xea, 0xee, 0xe5, 0xec, + 0xf2, 0xf2, 0xf0, 0xf0, 0xf2, 0xf9, 0xf2, 0xf4, 0xfb, 0xf5, 0xee, 0xf0, + 0xfd, 0xff, 0xfd, 0xf7, 0xfb, 0xff, 0x00, 0x01, 0x03, 0x03, 0x01, 0x01, + 0x01, 0x05, 0x09, 0x0e, 0x0c, 0x03, 0x07, 0x09, 0x0e, 0x0e, 0x0e, 0x07, + 0x07, 0x0c, 0x0b, 0x0c, 0x14, 0x10, 0x0c, 0x0c, 0x09, 0x12, 0x0c, 0x09, + 0x09, 0x0e, 0x12, 0x0c, 0x0c, 0x0e, 0x0c, 0x0e, 0x0e, 0x0b, 0x0c, 0x0b, + 0x0b, 0x09, 0x0b, 0x0b, 0x0b, 0x07, 0x05, 0x05, 0x0c, 0x05, 0x07, 0x05, + 0x09, 0x09, 0x09, 0x07, 0x05, 0x07, 0x03, 0x03, 0x09, 0x09, 0x05, 0x00, + 0x00, 0xff, 0xff, 0x03, 0x01, 0xff, 0x00, 0x01, 0xfd, 0xf5, 0xf9, 0x00, + 0xfb, 0xf5, 0xf4, 0xf7, 0xfb, 0xf7, 0xfb, 0xfb, 0xfb, 0xf0, 0xf4, 0xf5, + 0xf7, 0xf4, 0xec, 0xf2, 0xf2, 0xf5, 0xf5, 0xf2, 0xee, 0xec, 0xf0, 0xee, + 0xf2, 0xf5, 0xf2, 0xec, 0xf4, 0xf7, 0xf0, 0xf4, 0xf9, 0xf7, 0xf2, 0xf4, + 0xf5, 0xf5, 0xf7, 0xf5, 0xf9, 0xf4, 0xf5, 0xfd, 0x00, 0xf9, 0xf9, 0xf9, + 0xf9, 0xff, 0x01, 0xfd, 0x00, 0xfd, 0x03, 0x05, 0xfd, 0x01, 0x03, 0x03, + 0x01, 0x03, 0x01, 0x05, 0x0c, 0x0b, 0x09, 0x05, 0x09, 0x0b, 0x09, 0x0c, + 0x10, 0x0c, 0x09, 0x0c, 0x0b, 0x12, 0x0b, 0x09, 0x0c, 0x0c, 0x0e, 0x12, + 0x0e, 0x0e, 0x0c, 0x0b, 0x0e, 0x14, 0x0c, 0x10, 0x12, 0x18, 0x16, 0x0b, + 0x03, 0x07, 0x0b, 0x0c, 0x0b, 0x0c, 0x0e, 0x09, 0x09, 0x01, 0x05, 0x0c, + 0x05, 0x05, 0x0b, 0x03, 0xfd, 0xfd, 0x00, 0xfb, 0xff, 0xfd, 0xfd, 0xff, + 0xfd, 0xff, 0xf9, 0xf5, 0xf4, 0xf5, 0xf5, 0xf5, 0xf9, 0xf7, 0xf2, 0xf2, + 0xea, 0xf0, 0xf4, 0xf2, 0xee, 0xec, 0xf0, 0xf2, 0xe8, 0xe8, 0xee, 0xea, + 0xe5, 0xe8, 0xe8, 0xee, 0xe8, 0xec, 0xe7, 0xe8, 0xe8, 0xee, 0xf0, 0xf4, + 0xf2, 0xf4, 0xf4, 0xf4, 0xf2, 0xf2, 0xf5, 0xf7, 0xf9, 0xf9, 0xff, 0x00, + 0xfb, 0xfd, 0x01, 0x03, 0x03, 0x09, 0x01, 0x01, 0x05, 0x09, 0x09, 0x07, + 0x03, 0x07, 0x0c, 0x0e, 0x0b, 0x10, 0x0e, 0x09, 0x0c, 0x0c, 0x0e, 0x0e, + 0x0e, 0x0c, 0x10, 0x12, 0x14, 0x16, 0x10, 0x0e, 0x0e, 0x0e, 0x0c, 0x0e, + 0x12, 0x10, 0x0b, 0x12, 0x10, 0x0e, 0x0c, 0x0e, 0x0e, 0x10, 0x0b, 0x0e, + 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x03, 0x0b, 0x09, 0x01, 0x01, 0x01, + 0x01, 0x05, 0x05, 0x00, 0x01, 0x00, 0x05, 0xff, 0xfd, 0xfb, 0xf9, 0xfd, + 0xfb, 0xf0, 0xf9, 0xf5, 0xfb, 0xf5, 0xf2, 0xf0, 0xfb, 0xf7, 0xf4, 0xee, + 0xf0, 0xea, 0xea, 0xe5, 0xec, 0xf0, 0xec, 0xe8, 0xee, 0xf5, 0xf4, 0xee, + 0xee, 0xf0, 0xee, 0xea, 0xec, 0xec, 0xf4, 0xf5, 0xec, 0xf2, 0xf2, 0xf4, + 0xf0, 0xee, 0xf0, 0xf5, 0xf2, 0xf4, 0xf5, 0xf9, 0xfd, 0xfb, 0xf4, 0xff, + 0xff, 0xfd, 0xfb, 0xfd, 0x01, 0x00, 0xff, 0x00, 0x09, 0x00, 0x05, 0x09, + 0x09, 0x09, 0x0c, 0x05, 0x03, 0xff, 0x03, 0x0c, 0x0c, 0x00, 0x01, 0x09, + 0x0e, 0x0b, 0x09, 0x10, 0x10, 0x0b, 0x0e, 0x0b, 0x07, 0x0b, 0x0c, 0x0b, + 0x0e, 0x12, 0x10, 0x0e, 0x0c, 0x0e, 0x0e, 0x0c, 0x0c, 0x0e, 0x09, 0x10, + 0x0c, 0x14, 0x14, 0x10, 0x0e, 0x0c, 0x0b, 0x0e, 0x0e, 0x0e, 0x09, 0x09, + 0x0c, 0x0c, 0x0b, 0x0c, 0x07, 0x07, 0x0b, 0x05, 0x01, 0xff, 0x00, 0xfb, + 0x03, 0x01, 0x00, 0x01, 0x05, 0x05, 0xff, 0xf9, 0xf5, 0xfb, 0xf9, 0xf7, + 0xfb, 0xf2, 0xf4, 0xf4, 0xf5, 0xf2, 0xf4, 0xf5, 0xf2, 0xec, 0xee, 0xf0, + 0xea, 0xe7, 0xec, 0xee, 0xec, 0xea, 0xec, 0xf0, 0xee, 0xea, 0xec, 0xea, + 0xec, 0xea, 0xea, 0xf0, 0xec, 0xee, 0xea, 0xec, 0xf2, 0xf4, 0xf4, 0xee, + 0xf4, 0xf5, 0xf0, 0xf0, 0xf7, 0xfb, 0xfb, 0xf7, 0xf5, 0xf9, 0xfd, 0xfb, + 0xfd, 0x00, 0x00, 0xff, 0x00, 0x03, 0x01, 0x01, 0x05, 0x05, 0x01, 0x05, + 0x0b, 0x0e, 0x09, 0x05, 0x0b, 0x10, 0x09, 0x09, 0x0b, 0x10, 0x18, 0x14, + 0x12, 0x12, 0x12, 0x16, 0x12, 0x0c, 0x14, 0x19, 0x18, 0x18, 0x19, 0x1b, + 0x1b, 0x19, 0x16, 0x16, 0x1b, 0x1d, 0x1d, 0x1f, 0x16, 0x12, 0x16, 0x18, + 0x18, 0x12, 0x16, 0x19, 0x10, 0x12, 0x12, 0x10, 0x0e, 0x0b, 0x07, 0x09, + 0x0c, 0x05, 0x03, 0x03, 0x03, 0x05, 0x00, 0xfb, 0xfb, 0xfd, 0xf9, 0xf4, + 0xf5, 0xf7, 0xf4, 0xec, 0xea, 0xea, 0xf0, 0xee, 0xec, 0xe5, 0xe3, 0xea, + 0xe5, 0xe8, 0xdf, 0xdd, 0xe1, 0xe3, 0xdd, 0xdd, 0xe1, 0xe5, 0xdd, 0xdd, + 0xdd, 0xe1, 0xe3, 0xe7, 0xe3, 0xe5, 0xe3, 0xe1, 0xe3, 0xe8, 0xe1, 0xe7, + 0xec, 0xec, 0xe8, 0xec, 0xf0, 0xf2, 0xee, 0xec, 0xee, 0xfb, 0xff, 0xf9, + 0xf5, 0xff, 0xff, 0xff, 0xff, 0x03, 0x03, 0x05, 0x09, 0x09, 0x0b, 0x07, + 0x07, 0x0c, 0x10, 0x10, 0x0e, 0x0e, 0x16, 0x16, 0x10, 0x10, 0x14, 0x18, + 0x16, 0x16, 0x18, 0x18, 0x19, 0x16, 0x16, 0x12, 0x16, 0x19, 0x19, 0x1b, + 0x1b, 0x18, 0x18, 0x19, 0x1f, 0x18, 0x18, 0x19, 0x18, 0x1d, 0x19, 0x18, + 0x16, 0x18, 0x18, 0x19, 0x16, 0x12, 0x0c, 0x0e, 0x10, 0x0c, 0x0c, 0x0b, + 0x09, 0x05, 0x09, 0x05, 0xff, 0x00, 0xfb, 0xfd, 0xff, 0xf7, 0xf4, 0xf7, + 0xf7, 0xf7, 0xf4, 0xf0, 0xf4, 0xf0, 0xf0, 0xe7, 0xe5, 0xe8, 0xe7, 0xe7, + 0xea, 0xe8, 0xe7, 0xe7, 0xe7, 0xe5, 0xe3, 0xe1, 0xe3, 0xe1, 0xe3, 0xe5, + 0xe1, 0xdf, 0xe1, 0xe5, 0xea, 0xe7, 0xe3, 0xe5, 0xe8, 0xee, 0xf2, 0xec, + 0xe8, 0xe7, 0xec, 0xf4, 0xf7, 0xf5, 0xf7, 0xf4, 0xf9, 0xfd, 0xfd, 0xfb, + 0xfb, 0xfb, 0xff, 0x01, 0x01, 0x03, 0x03, 0x01, 0x00, 0x01, 0x07, 0x0b, + 0x05, 0x05, 0x09, 0x07, 0x0c, 0x0c, 0x0c, 0x14, 0x14, 0x14, 0x0c, 0x0c, + 0x0e, 0x0e, 0x10, 0x0c, 0x10, 0x16, 0x16, 0x10, 0x14, 0x16, 0x14, 0x16, + 0x14, 0x12, 0x18, 0x19, 0x14, 0x10, 0x1b, 0x1b, 0x19, 0x18, 0x14, 0x19, + 0x18, 0x14, 0x12, 0x14, 0x16, 0x12, 0x0c, 0x10, 0x12, 0x10, 0x0e, 0x0c, + 0x0b, 0x09, 0x07, 0x07, 0x07, 0x05, 0x03, 0x05, 0x03, 0x07, 0x00, 0xfb, + 0xf9, 0xff, 0x00, 0xfd, 0xf7, 0xf9, 0xf4, 0xf2, 0xf5, 0xf4, 0xf0, 0xf5, + 0xf2, 0xee, 0xea, 0xec, 0xec, 0xea, 0xe8, 0xea, 0xe3, 0xe5, 0xe7, 0xea, + 0xe8, 0xe5, 0xe7, 0xe8, 0xe7, 0xe1, 0xdf, 0xe3, 0xe7, 0xe3, 0xe5, 0xea, + 0xe8, 0xe8, 0xea, 0xee, 0xea, 0xe5, 0xe8, 0xee, 0xee, 0xf0, 0xf0, 0xf0, + 0xf4, 0xf4, 0xf0, 0xf2, 0xf2, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xfb, + 0x00, 0x00, 0xfb, 0xff, 0x05, 0x09, 0x01, 0x09, 0x09, 0x07, 0x07, 0x0b, + 0x0e, 0x10, 0x0c, 0x12, 0x16, 0x12, 0x0e, 0x14, 0x16, 0x19, 0x1b, 0x18, + 0x18, 0x19, 0x1b, 0x1b, 0x1b, 0x18, 0x1b, 0x1d, 0x1f, 0x23, 0x1f, 0x1b, + 0x1b, 0x18, 0x19, 0x1b, 0x1d, 0x1f, 0x1d, 0x1b, 0x1d, 0x1b, 0x18, 0x18, + 0x16, 0x14, 0x16, 0x12, 0x12, 0x14, 0x10, 0x0e, 0x0e, 0x0c, 0x09, 0x05, + 0x07, 0x09, 0x07, 0x00, 0xfb, 0xfd, 0xf9, 0xf7, 0xf5, 0xf2, 0xf0, 0xf0, + 0xf0, 0xea, 0xec, 0xe7, 0xe8, 0xe5, 0xe5, 0xe7, 0xe3, 0xe3, 0xe1, 0xe1, + 0xda, 0xdb, 0xe5, 0xdf, 0xdb, 0xdd, 0xdb, 0xdf, 0xdd, 0xdd, 0xdb, 0xdd, + 0xdb, 0xdd, 0xdb, 0xdd, 0xe3, 0xe5, 0xe5, 0xe3, 0xe1, 0xe5, 0xe5, 0xe7, + 0xea, 0xea, 0xee, 0xf2, 0xf4, 0xf5, 0xf2, 0xf4, 0xf7, 0xfb, 0xfd, 0xfd, + 0xfd, 0xff, 0x01, 0x05, 0x07, 0x07, 0x07, 0x09, 0x07, 0x0c, 0x0b, 0x0e, + 0x0e, 0x12, 0x16, 0x16, 0x14, 0x19, 0x1b, 0x1b, 0x19, 0x19, 0x1b, 0x1b, + 0x1d, 0x1d, 0x1b, 0x1b, 0x1f, 0x23, 0x21, 0x1b, 0x1b, 0x1d, 0x19, 0x1b, + 0x1d, 0x1d, 0x1b, 0x1b, 0x1b, 0x1b, 0x18, 0x16, 0x18, 0x16, 0x12, 0x12, + 0x12, 0x10, 0x0e, 0x0c, 0x09, 0x0b, 0x0b, 0x09, 0x05, 0x00, 0x03, 0xff, + 0x00, 0xfd, 0xfd, 0xfb, 0xf7, 0xfd, 0xf9, 0xf4, 0xf4, 0xf2, 0xf0, 0xee, + 0xea, 0xea, 0xea, 0xea, 0xe7, 0xe7, 0xe5, 0xe7, 0xe5, 0xe3, 0xe1, 0xe1, + 0xe3, 0xe3, 0xe3, 0xe5, 0xe1, 0xe1, 0xe3, 0xe7, 0xe7, 0xe7, 0xe8, 0xe5, + 0xe7, 0xe8, 0xea, 0xec, 0xea, 0xee, 0xf2, 0xf2, 0xf2, 0xee, 0xf4, 0xf4, + 0xf4, 0xf2, 0xf4, 0xf7, 0xf9, 0xf9, 0xf9, 0xfb, 0x00, 0x03, 0x01, 0x00, + 0x00, 0x03, 0x05, 0x05, 0x07, 0x0b, 0x0e, 0x0c, 0x0c, 0x10, 0x10, 0x0e, + 0x0c, 0x10, 0x14, 0x14, 0x12, 0x12, 0x12, 0x12, 0x12, 0x14, 0x12, 0x14, + 0x14, 0x12, 0x10, 0x10, 0x12, 0x0e, 0x0c, 0x0c, 0x10, 0x10, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0e, 0x0c, 0x0e, 0x09, 0x09, 0x0b, 0x09, 0x07, 0x05, 0x09, + 0x0c, 0x0b, 0x01, 0x07, 0x09, 0x05, 0x07, 0x01, 0x01, 0x00, 0xff, 0x00, + 0xff, 0xfb, 0xfb, 0xfd, 0xfd, 0xfb, 0xf7, 0xfb, 0xfd, 0xf7, 0xf5, 0xf5, + 0xf5, 0xf9, 0xf5, 0xf5, 0xf7, 0xf5, 0xf7, 0xf7, 0xf7, 0xf4, 0xf4, 0xf4, + 0xf9, 0xf7, 0xf4, 0xf5, 0xf9, 0xfb, 0xf9, 0xf5, 0xf4, 0xf7, 0xf2, 0xf5, + 0xf4, 0xf4, 0xf2, 0xf2, 0xf5, 0xf5, 0xf7, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, + 0xf5, 0xfb, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfb, 0xff, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x01, 0xff, 0x00, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, + 0x01, 0x00, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0xfd, 0xff, 0x03, 0x01, + 0x01, 0x01, 0x01, 0x03, 0x05, 0x01, 0x01, 0x05, 0x05, 0x05, 0x07, 0x07, + 0x07, 0x09, 0x07, 0x07, 0x05, 0x05, 0x0b, 0x09, 0x07, 0x09, 0x07, 0x09, + 0x09, 0x07, 0x05, 0x03, 0x05, 0x09, 0x07, 0x07, 0x09, 0x07, 0x05, 0x01, + 0x00, 0x03, 0x07, 0x07, 0x05, 0x03, 0x05, 0x01, 0x01, 0x03, 0x03, 0x01, + 0x07, 0x07, 0x03, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0xfd, + 0xfb, 0xfd, 0xfb, 0xfb, 0xfb, 0xf9, 0xfb, 0xf9, 0xf5, 0xf5, 0xf5, 0xf7, + 0xf5, 0xf5, 0xf9, 0xf7, 0xf9, 0xf7, 0xf4, 0xf4, 0xf5, 0xf7, 0xf5, 0xf4, + 0xf2, 0xf4, 0xf7, 0xf7, 0xf9, 0xfb, 0xf9, 0xf4, 0xf5, 0xf9, 0xf9, 0xf7, + 0xf7, 0xf7, 0xfb, 0xfd, 0xfd, 0xfb, 0xf9, 0xfb, 0xfd, 0xfd, 0xfb, 0xfb, + 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0x00, 0x01, 0x01, 0x00, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x01, 0x05, 0x05, 0x07, 0x09, 0x07, 0x07, 0x0b, 0x09, + 0x09, 0x07, 0x07, 0x07, 0x0b, 0x0c, 0x09, 0x05, 0x07, 0x09, 0x09, 0x07, + 0x07, 0x07, 0x05, 0x05, 0x05, 0x07, 0x07, 0x03, 0x03, 0x03, 0x09, 0x05, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x05, 0x03, 0x00, 0x01, 0x03, + 0x01, 0x01, 0x00, 0xfd, 0xff, 0x00, 0xff, 0xfd, 0xf9, 0xfb, 0xfb, 0xf9, + 0xf9, 0xf9, 0xf7, 0xf7, 0xf5, 0xf5, 0xf7, 0xfb, 0xf7, 0xf7, 0xf5, 0xf7, + 0xf9, 0xfb, 0xf9, 0xf9, 0xf9, 0xfb, 0xfb, 0xfb, 0xff, 0xfb, 0xf7, 0xfb, + 0xfd, 0xff, 0xfd, 0xf7, 0xf7, 0xf9, 0xfd, 0xfd, 0xfd, 0xfd, 0x00, 0x00, + 0x01, 0x00, 0xff, 0x00, 0xff, 0x01, 0x01, 0x00, 0x03, 0x03, 0x01, 0x03, + 0x03, 0x03, 0x07, 0x05, 0x05, 0x05, 0x07, 0x07, 0x07, 0x09, 0x09, 0x07, + 0x07, 0x07, 0x05, 0x07, 0x09, 0x09, 0x07, 0x05, 0x07, 0x05, 0x07, 0x05, + 0x03, 0x03, 0x01, 0x00, 0x01, 0x05, 0x03, 0x00, 0xff, 0x01, 0x03, 0xff, + 0xfb, 0x00, 0xff, 0xfb, 0xfb, 0xff, 0xfd, 0xf9, 0xf9, 0xf7, 0xf9, 0xf7, + 0xf7, 0xf9, 0xfb, 0xf9, 0xf9, 0xf7, 0xf9, 0xf9, 0xf7, 0xf7, 0x00, 0x00, + 0xfe, 0xfc, 0xf4, 0xf4, 0xeb, 0xf4, 0xe4, 0xff, 0x01, 0xe7, 0xf4, 0xdb, + 0xff, 0xe3, 0x17, 0xfd, 0xfb, 0xe5, 0x02, 0x18, 0xdc, 0xf9, 0x0d, 0x0b, + 0x0b, 0x26, 0xe1, 0x34, 0x38, 0x24, 0xff, 0x22, 0x03, 0x26, 0x09, 0x4d, + 0x09, 0x34, 0x28, 0x22, 0x11, 0x3a, 0x20, 0x30, 0x1b, 0x30, 0x1d, 0x1d, + 0x2e, 0x32, 0x4f, 0x57, 0x38, 0x68, 0x20, 0x3c, 0xe1, 0x40, 0x2a, 0x40, + 0x3c, 0x26, 0x2e, 0x40, 0x53, 0x61, 0x1b, 0x45, 0x05, 0x49, 0x0b, 0x4b, + 0x4b, 0x40, 0x49, 0x32, 0x30, 0x2e, 0x59, 0x3a, 0x4d, 0xff, 0x1f, 0x4d, + 0x22, 0x4b, 0x00, 0x05, 0x3e, 0x4b, 0x1d, 0x03, 0x07, 0x45, 0x2e, 0x1d, + 0x34, 0x01, 0x20, 0x11, 0x0b, 0xfb, 0x30, 0x0b, 0xe5, 0x09, 0x13, 0x1b, + 0x0d, 0xff, 0xc8, 0x0b, 0xd4, 0x26, 0x11, 0xe3, 0xc0, 0xd2, 0x0d, 0xfb, + 0xc2, 0xda, 0xcc, 0xef, 0xd6, 0xfb, 0xd2, 0xed, 0xb1, 0xca, 0xe5, 0xc0, + 0xd4, 0xbb, 0xb9, 0xbd, 0xd6, 0xcc, 0xb3, 0xd6, 0xb5, 0xc0, 0xce, 0xce, + 0xbb, 0xbd, 0xb3, 0xd0, 0xbf, 0xb5, 0xb3, 0xbd, 0xbd, 0xc4, 0xc4, 0xc4, + 0xa7, 0xc2, 0xab, 0xd8, 0xb7, 0xc6, 0xc2, 0xb1, 0xbd, 0xd6, 0xca, 0xc4, + 0xbb, 0xc4, 0xe3, 0xb5, 0xe1, 0xbb, 0xd6, 0xdc, 0xde, 0xc0, 0xca, 0xd4, + 0xeb, 0xd8, 0xd6, 0xcc, 0xcc, 0xed, 0xde, 0xe9, 0xe1, 0xe1, 0xf5, 0xdc, + 0xda, 0xed, 0xf1, 0xf1, 0xe3, 0xda, 0xe9, 0xf5, 0xf7, 0xf3, 0xff, 0x03, + 0x0f, 0x07, 0xff, 0xff, 0x03, 0x07, 0x1b, 0x07, 0x07, 0x05, 0x24, 0x13, + 0x19, 0x0f, 0x1f, 0x0d, 0x1f, 0x20, 0x11, 0x20, 0x1f, 0x32, 0x28, 0x3a, + 0x20, 0x2e, 0x1b, 0x30, 0x2c, 0x3c, 0x2e, 0x2a, 0x30, 0x3e, 0x38, 0x34, + 0x24, 0x2e, 0x22, 0x2e, 0x32, 0x47, 0x30, 0x34, 0x38, 0x2c, 0x3a, 0x41, + 0x38, 0x2c, 0x45, 0x2c, 0x26, 0x38, 0x24, 0x22, 0x3e, 0x36, 0x3e, 0x28, + 0x24, 0x20, 0x2e, 0x28, 0x3a, 0x32, 0x32, 0x2c, 0x34, 0x17, 0x2e, 0x1d, + 0x2e, 0x2e, 0x32, 0x30, 0x2a, 0x26, 0x28, 0x19, 0x28, 0x24, 0x26, 0x32, + 0x1d, 0x1f, 0x26, 0x20, 0x24, 0x22, 0x1b, 0x17, 0x17, 0x1f, 0x24, 0x24, + 0x17, 0x1b, 0x17, 0x19, 0x13, 0x1d, 0x0f, 0x11, 0x0f, 0x0f, 0x0d, 0x0f, + 0x09, 0x11, 0x00, 0x0b, 0x05, 0x0d, 0x00, 0x0d, 0x01, 0x03, 0x03, 0xf7, + 0x01, 0xfd, 0x03, 0x07, 0xfb, 0x01, 0xf9, 0xf7, 0xf5, 0xfd, 0xf7, 0xf5, + 0xf7, 0xe9, 0xf1, 0x00, 0xf7, 0xeb, 0xde, 0xe1, 0xde, 0xe9, 0xf1, 0xef, + 0xed, 0xe3, 0xd4, 0xde, 0xe3, 0xe3, 0xe0, 0xe0, 0xdc, 0xde, 0xd8, 0xda, + 0xd8, 0xd8, 0xd4, 0xd2, 0xcc, 0xd0, 0xcc, 0xc8, 0xce, 0xd6, 0xcc, 0xca, + 0xc8, 0xc8, 0xc6, 0xcc, 0xc4, 0xca, 0xc4, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc, + 0xc2, 0xc0, 0xc4, 0xc8, 0xca, 0xcc, 0xca, 0xc4, 0xc8, 0xc6, 0xce, 0xc4, + 0xce, 0xc8, 0xc6, 0xce, 0xce, 0xd0, 0xd4, 0xd4, 0xd4, 0xd6, 0xd6, 0xd8, + 0xd8, 0xd4, 0xd8, 0xde, 0xde, 0xde, 0xe0, 0xe1, 0xde, 0xe1, 0xe1, 0xe5, + 0xe7, 0xeb, 0xed, 0xed, 0xe9, 0xeb, 0xef, 0xf1, 0xf3, 0xef, 0xf7, 0xfd, + 0xfb, 0xf7, 0xf5, 0xf9, 0xff, 0xfd, 0xff, 0xff, 0x03, 0x07, 0x05, 0x00, + 0x09, 0x07, 0x0d, 0x09, 0x0d, 0x09, 0x11, 0x15, 0x1b, 0x15, 0x0f, 0x0d, + 0x13, 0x13, 0x15, 0x17, 0x1d, 0x17, 0x17, 0x17, 0x1d, 0x1d, 0x24, 0x24, + 0x22, 0x1d, 0x1d, 0x22, 0x26, 0x26, 0x26, 0x20, 0x22, 0x22, 0x22, 0x24, + 0x26, 0x26, 0x28, 0x2a, 0x28, 0x20, 0x22, 0x26, 0x26, 0x2a, 0x2a, 0x2a, + 0x28, 0x2a, 0x26, 0x24, 0x22, 0x28, 0x2a, 0x2a, 0x28, 0x2a, 0x2c, 0x2e, + 0x2c, 0x28, 0x26, 0x26, 0x26, 0x26, 0x2a, 0x28, 0x26, 0x26, 0x26, 0x22, + 0x1f, 0x24, 0x28, 0x2a, 0x2a, 0x22, 0x24, 0x26, 0x24, 0x20, 0x1f, 0x20, + 0x1f, 0x1d, 0x1d, 0x19, 0x1b, 0x1b, 0x1f, 0x1f, 0x1b, 0x15, 0x17, 0x1b, + 0x1f, 0x1b, 0x15, 0x13, 0x13, 0x11, 0x11, 0x13, 0x15, 0x13, 0x11, 0x0d, + 0x0b, 0x0d, 0x0d, 0x0b, 0x0d, 0x0b, 0x05, 0x03, 0x03, 0x03, 0x05, 0x09, + 0x09, 0x05, 0xff, 0xf9, 0xf7, 0xfd, 0x01, 0x01, 0x00, 0xff, 0xfb, 0xf9, + 0xf9, 0xf9, 0xf5, 0xf5, 0xf9, 0xf9, 0xf5, 0xef, 0xef, 0xed, 0xf1, 0xf3, + 0xf1, 0xef, 0xeb, 0xe9, 0xe9, 0xeb, 0xeb, 0xeb, 0xe7, 0xe7, 0xe5, 0xe7, + 0xed, 0xeb, 0xe3, 0xe0, 0xe1, 0xe3, 0xe3, 0xe1, 0xe3, 0xe5, 0xe7, 0xe7, + 0xe1, 0xe0, 0xde, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe3, 0xe3, 0xe5, 0xe7, + 0xe3, 0xde, 0xde, 0xe1, 0xe1, 0xe1, 0xe1, 0xe0, 0xdc, 0xe1, 0xe3, 0xe1, + 0xe3, 0xe1, 0xe1, 0xe0, 0xe0, 0xe1, 0xe0, 0xe1, 0xe3, 0xe7, 0xeb, 0xe7, + 0xe3, 0xe0, 0xe0, 0xe3, 0xe5, 0xe7, 0xe3, 0xe1, 0xe3, 0xe7, 0xed, 0xed, + 0xeb, 0xe9, 0xed, 0xed, 0xef, 0xed, 0xef, 0xed, 0xeb, 0xed, 0xf1, 0xf3, + 0xf3, 0xf5, 0xf5, 0xf3, 0xf1, 0xef, 0xef, 0xf1, 0xf5, 0xf5, 0xf3, 0xf1, + 0xed, 0xf1, 0xf5, 0xf9, 0xfd, 0xfd, 0xf7, 0xf3, 0xf3, 0xf7, 0xf9, 0xfb, + 0xfb, 0xfb, 0xf9, 0xf9, 0xf9, 0xf9, 0xfb, 0xfd, 0xff, 0xfd, 0xff, 0xfd, + 0xfd, 0xfd, 0x00, 0xff, 0xfd, 0xfd, 0xfd, 0x00, 0x01, 0x01, 0xff, 0xfd, + 0xfd, 0x00, 0x01, 0x03, 0x03, 0x03, 0x01, 0x00, 0xff, 0x01, 0x01, 0x03, + 0x03, 0x00, 0x00, 0x01, 0x05, 0x05, 0x05, 0x03, 0x03, 0x05, 0x03, 0x01, + 0x03, 0x07, 0x09, 0x07, 0x03, 0x01, 0x05, 0x07, 0x09, 0x07, 0x05, 0x05, + 0x07, 0x0b, 0x09, 0x05, 0x03, 0x01, 0x03, 0x07, 0x09, 0x0b, 0x09, 0x09, + 0x0b, 0x0b, 0x0b, 0x0d, 0x0b, 0x0d, 0x0d, 0x0d, 0x0d, 0x0b, 0x07, 0x09, + 0x0b, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x13, 0x13, 0x11, 0x0f, 0x0d, 0x0d, + 0x0f, 0x11, 0x11, 0x0f, 0x0d, 0x0f, 0x0f, 0x11, 0x0f, 0x11, 0x13, 0x0f, + 0x0f, 0x0f, 0x13, 0x13, 0x15, 0x13, 0x11, 0x11, 0x11, 0x0f, 0x0f, 0x0d, + 0x13, 0x17, 0x13, 0x11, 0x11, 0x13, 0x15, 0x13, 0x13, 0x15, 0x15, 0x17, + 0x15, 0x11, 0x11, 0x15, 0x17, 0x15, 0x13, 0x15, 0x19, 0x19, 0x19, 0x15, + 0x13, 0x13, 0x15, 0x15, 0x15, 0x17, 0x17, 0x15, 0x13, 0x13, 0x13, 0x13, + 0x11, 0x15, 0x15, 0x15, 0x15, 0x15, 0x17, 0x17, 0x15, 0x15, 0x13, 0x0f, + 0x0f, 0x17, 0x1d, 0x1b, 0x17, 0x15, 0x13, 0x15, 0x1b, 0x1b, 0x17, 0x17, + 0x17, 0x17, 0x15, 0x15, 0x13, 0x11, 0x11, 0x13, 0x15, 0x17, 0x11, 0x0d, + 0x0d, 0x0f, 0x0f, 0x0f, 0x0d, 0x0b, 0x09, 0x0b, 0x0f, 0x0d, 0x09, 0x09, + 0x07, 0x09, 0x0b, 0x0b, 0x09, 0x01, 0x00, 0x01, 0x03, 0x03, 0x03, 0x00, + 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xfb, 0xfb, 0xfb, 0xf9, 0xf9, 0xf7, 0xf3, + 0xf3, 0xf5, 0xf7, 0xf5, 0xf1, 0xf1, 0xf3, 0xf3, 0xf1, 0xed, 0xeb, 0xe9, + 0xed, 0xed, 0xed, 0xeb, 0xe9, 0xe7, 0xe7, 0xe5, 0xe7, 0xe7, 0xe7, 0xe7, + 0xe7, 0xe7, 0xe7, 0xe5, 0xe3, 0xe0, 0xe0, 0xe0, 0xe0, 0xde, 0xdc, 0xde, + 0xe0, 0xe0, 0xdc, 0xd8, 0xd8, 0xdc, 0xde, 0xda, 0xd8, 0xd8, 0xde, 0xe0, + 0xdc, 0xda, 0xda, 0xdc, 0xde, 0xe0, 0xde, 0xdc, 0xdc, 0xde, 0xde, 0xdc, + 0xdc, 0xde, 0xde, 0xdc, 0xdc, 0xdc, 0xde, 0xe1, 0xe3, 0xe1, 0xe0, 0xe0, + 0xde, 0xe0, 0xe0, 0xe1, 0xe3, 0xe5, 0xe1, 0xe0, 0xe1, 0xe3, 0xe7, 0xe9, + 0xe9, 0xe9, 0xeb, 0xeb, 0xe9, 0xe7, 0xe5, 0xe9, 0xed, 0xed, 0xe9, 0xe5, + 0xe3, 0xe7, 0xeb, 0xed, 0xeb, 0xeb, 0xeb, 0xe9, 0xeb, 0xed, 0xf1, 0xf1, + 0xf1, 0xef, 0xed, 0xeb, 0xed, 0xf1, 0xf3, 0xf1, 0xed, 0xed, 0xef, 0xf1, + 0xf5, 0xf3, 0xf3, 0xf5, 0xf5, 0xf5, 0xf7, 0xf7, 0xf9, 0xf9, 0xf9, 0xf9, + 0xfb, 0xfd, 0xfd, 0xff, 0xfd, 0xfb, 0xf9, 0xfd, 0xfd, 0xff, 0xfd, 0xfd, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, + 0x03, 0x01, 0x01, 0x05, 0x07, 0x07, 0x09, 0x09, 0x05, 0x05, 0x01, 0x03, + 0x05, 0x07, 0x05, 0x05, 0x05, 0x07, 0x0b, 0x0d, 0x07, 0x05, 0x05, 0x07, + 0x0d, 0x0d, 0x0b, 0x09, 0x0d, 0x0f, 0x0f, 0x0d, 0x0d, 0x0f, 0x0f, 0x0f, + 0x0d, 0x0d, 0x0f, 0x0f, 0x13, 0x17, 0x15, 0x11, 0x0f, 0x11, 0x13, 0x15, + 0x15, 0x17, 0x17, 0x19, 0x19, 0x19, 0x15, 0x11, 0x11, 0x15, 0x1b, 0x1f, + 0x1b, 0x17, 0x11, 0x15, 0x19, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1b, 0x19, + 0x19, 0x19, 0x1b, 0x1f, 0x1f, 0x1d, 0x1d, 0x1d, 0x1b, 0x19, 0x1b, 0x1d, + 0x1d, 0x1b, 0x1d, 0x1f, 0x1f, 0x1f, 0x1d, 0x1b, 0x19, 0x19, 0x1b, 0x1b, + 0x1d, 0x1d, 0x1b, 0x1d, 0x1d, 0x1f, 0x1f, 0x19, 0x15, 0x17, 0x1b, 0x20, + 0x22, 0x1f, 0x1b, 0x19, 0x19, 0x19, 0x19, 0x19, 0x1b, 0x1b, 0x19, 0x17, + 0x17, 0x19, 0x19, 0x17, 0x15, 0x15, 0x17, 0x19, 0x17, 0x13, 0x11, 0x11, + 0x13, 0x15, 0x13, 0x0f, 0x0f, 0x0d, 0x09, 0x07, 0x09, 0x0d, 0x0f, 0x0f, + 0x0d, 0x07, 0x07, 0x07, 0x09, 0x09, 0x09, 0x05, 0x05, 0x03, 0x05, 0x07, + 0x07, 0x03, 0x01, 0x00, 0x01, 0x03, 0x05, 0x05, 0x03, 0x00, 0xff, 0xff, + 0x00, 0x01, 0x01, 0xff, 0xff, 0xfd, 0xfb, 0xfb, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfd, 0xfb, 0xfb, 0xfb, 0xf9, 0xf9, 0xfb, 0xfd, 0xfd, 0xfd, 0xfd, + 0xf9, 0xf7, 0xf9, 0xfb, 0xfd, 0xfb, 0xf9, 0xf9, 0xf9, 0xf7, 0xf5, 0xf1, + 0xf1, 0xf3, 0xf7, 0xf9, 0xf5, 0xf1, 0xf1, 0xf3, 0xf5, 0xf5, 0xf1, 0xef, + 0xef, 0xf1, 0xf1, 0xf1, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf1, 0xf3, + 0xf1, 0xef, 0xed, 0xeb, 0xeb, 0xeb, 0xef, 0xef, 0xed, 0xeb, 0xe7, 0xe9, + 0xe9, 0xeb, 0xed, 0xed, 0xeb, 0xe9, 0xeb, 0xeb, 0xe5, 0xe3, 0xe5, 0xe9, + 0xed, 0xed, 0xe7, 0xe1, 0xe1, 0xe5, 0xe7, 0xe7, 0xe7, 0xeb, 0xe9, 0xe5, + 0xe3, 0xe1, 0xe3, 0xe9, 0xeb, 0xe9, 0xe3, 0xe1, 0xe3, 0xe3, 0xe3, 0xe3, + 0xe3, 0xe5, 0xe3, 0xe1, 0xe3, 0xe7, 0xe9, 0xe7, 0xe3, 0xe1, 0xe1, 0xe3, + 0xe5, 0xe5, 0xe3, 0xe5, 0xe7, 0xe7, 0xe7, 0xe7, 0xe3, 0xe3, 0xe7, 0xe9, + 0xed, 0xeb, 0xe9, 0xeb, 0xe9, 0xe7, 0xe5, 0xe5, 0xe9, 0xeb, 0xeb, 0xe9, + 0xeb, 0xed, 0xed, 0xed, 0xeb, 0xeb, 0xeb, 0xe7, 0xe9, 0xe9, 0xf1, 0xf7, + 0xf7, 0xf1, 0xeb, 0xeb, 0xf3, 0xf7, 0xf5, 0xf1, 0xef, 0xf1, 0xf3, 0xf3, + 0xf3, 0xf3, 0xf5, 0xf7, 0xf7, 0xf3, 0xf3, 0xf5, 0xf9, 0xf9, 0xf7, 0xf7, + 0xfb, 0xfb, 0xfb, 0xfb, 0xf9, 0xf9, 0xf7, 0xf7, 0xf7, 0xfb, 0xfd, 0x00, + 0x01, 0x00, 0xfd, 0xf9, 0xfb, 0xff, 0x01, 0x07, 0x09, 0x07, 0x03, 0xfd, + 0xf9, 0xfb, 0x03, 0x09, 0x07, 0x03, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, + 0x09, 0x07, 0x05, 0x05, 0x05, 0x0b, 0x0d, 0x0b, 0x07, 0x07, 0x0b, 0x0d, + 0x0f, 0x0d, 0x09, 0x09, 0x07, 0x07, 0x0b, 0x0f, 0x11, 0x11, 0x0d, 0x0b, + 0x0b, 0x0d, 0x0d, 0x0f, 0x0f, 0x0f, 0x0d, 0x0f, 0x15, 0x17, 0x15, 0x0f, + 0x0b, 0x0f, 0x11, 0x13, 0x13, 0x15, 0x15, 0x15, 0x13, 0x11, 0x13, 0x19, + 0x1d, 0x19, 0x13, 0x0d, 0x11, 0x17, 0x19, 0x17, 0x13, 0x11, 0x17, 0x1d, + 0x1f, 0x19, 0x17, 0x15, 0x15, 0x17, 0x1d, 0x1f, 0x1f, 0x1b, 0x00, 0x00, + 0xff, 0xf6, 0x01, 0xff, 0xff, 0xf9, 0x01, 0xf6, 0x09, 0xff, 0xf1, 0x03, + 0x01, 0xfb, 0xfd, 0x02, 0xf3, 0x07, 0xfa, 0xdd, 0x16, 0xf0, 0xee, 0xf2, + 0x13, 0xf1, 0xf5, 0x01, 0xf6, 0xf9, 0xf9, 0x00, 0x01, 0xea, 0xfb, 0x10, + 0x09, 0x0b, 0x46, 0x14, 0xea, 0x27, 0x0a, 0xee, 0xdd, 0xff, 0x00, 0x0f, + 0x0a, 0x14, 0xf2, 0xfe, 0xe0, 0xfd, 0xd3, 0xbd, 0xcb, 0xe0, 0xcc, 0xb6, + 0xe1, 0xd4, 0xca, 0xdc, 0xd0, 0xe8, 0x09, 0x16, 0xf2, 0xdb, 0xf6, 0xf6, + 0x05, 0x14, 0x24, 0x35, 0x42, 0x48, 0x43, 0x42, 0x4c, 0x51, 0x54, 0x46, + 0x5d, 0x50, 0x28, 0x4c, 0x37, 0x28, 0x50, 0x48, 0x41, 0x09, 0x12, 0xdb, + 0xcc, 0xfb, 0xe9, 0x00, 0xee, 0xea, 0xf3, 0xf0, 0xc9, 0xe3, 0xbd, 0xb2, + 0xb0, 0xad, 0xb0, 0xb5, 0x9c, 0xb0, 0xb2, 0xb0, 0xa0, 0xa8, 0xd0, 0xc5, + 0xc7, 0xf2, 0xf6, 0xf1, 0xfe, 0x02, 0xee, 0x03, 0x09, 0x0e, 0x3f, 0x47, + 0x59, 0x42, 0x46, 0x62, 0x47, 0x4c, 0x30, 0x32, 0x20, 0x0e, 0xf1, 0xf9, + 0x09, 0xf5, 0xe8, 0x0a, 0xf9, 0xed, 0xd4, 0xc9, 0xc7, 0xc2, 0xba, 0xee, + 0xca, 0xb4, 0xb2, 0xb2, 0xa8, 0xb4, 0xc2, 0xc3, 0xd7, 0xd6, 0x03, 0x2d, + 0x1c, 0x41, 0x41, 0x30, 0x29, 0x4f, 0x48, 0x41, 0x51, 0x5e, 0x48, 0x51, + 0x50, 0x4b, 0x43, 0x37, 0x3a, 0x35, 0x31, 0x2a, 0x20, 0x16, 0x09, 0x02, + 0xfa, 0xf5, 0xe0, 0xd2, 0xf0, 0xd0, 0xbe, 0xaf, 0xca, 0xb0, 0x9a, 0xad, + 0xb5, 0xad, 0x9c, 0xcc, 0xc6, 0xcf, 0xd8, 0xd3, 0xb6, 0xbd, 0xd7, 0xdc, + 0xdb, 0xed, 0xf6, 0xe5, 0xf1, 0x0e, 0xfa, 0x0a, 0xfb, 0x06, 0x0f, 0x13, + 0x1a, 0x1b, 0x27, 0x32, 0x20, 0x3b, 0x3f, 0x36, 0x1f, 0x47, 0x37, 0x2d, + 0x36, 0x3d, 0x27, 0x25, 0x24, 0x05, 0x27, 0x1f, 0x06, 0xf7, 0xff, 0xe8, + 0xd6, 0xd8, 0xdf, 0xdb, 0xd8, 0xec, 0xc5, 0xcb, 0xd4, 0xc9, 0xb6, 0xdd, + 0xdc, 0xf1, 0xe5, 0xf1, 0x01, 0xf3, 0xf0, 0x06, 0xfe, 0x06, 0x09, 0x0b, + 0x1f, 0x2d, 0x27, 0x30, 0x37, 0x23, 0x29, 0x27, 0x2c, 0x20, 0x48, 0x25, + 0x03, 0x0d, 0xe6, 0xec, 0xdd, 0xd2, 0xf5, 0xd3, 0xcf, 0xd7, 0xd6, 0xc2, + 0xb2, 0xce, 0xc2, 0xc3, 0xdf, 0xf1, 0xe9, 0xee, 0xe5, 0xcf, 0x0a, 0xf6, + 0xf6, 0x06, 0x16, 0x0d, 0xf1, 0x2a, 0x0f, 0x16, 0x3a, 0x2e, 0x1c, 0x32, + 0x28, 0x2c, 0x0f, 0x27, 0x23, 0x1f, 0x02, 0x1f, 0x0a, 0x01, 0xfa, 0x0d, + 0xf3, 0xf2, 0x07, 0x05, 0x05, 0xf5, 0x0d, 0xfd, 0xf6, 0xf0, 0xf5, 0xe9, + 0xdf, 0xd7, 0xf2, 0xdf, 0xcb, 0xec, 0xe5, 0xe0, 0xfe, 0xe9, 0xf6, 0xf7, + 0xd9, 0xe0, 0xe1, 0xdf, 0xdf, 0xe6, 0xe9, 0xec, 0xed, 0xdd, 0xf3, 0x0b, + 0x0d, 0x03, 0x2a, 0x28, 0x28, 0x1c, 0x35, 0x29, 0x2e, 0x18, 0x25, 0x27, + 0x30, 0x1a, 0x27, 0x29, 0x1a, 0x0e, 0x0b, 0x14, 0x03, 0x09, 0xf6, 0xe4, + 0x02, 0xdd, 0xcc, 0xdb, 0xd9, 0xcc, 0xb0, 0xdf, 0xc7, 0xca, 0xc7, 0xd9, + 0xd2, 0xdc, 0xf3, 0xfa, 0xff, 0x06, 0x0f, 0x13, 0x05, 0x0a, 0x1c, 0xff, + 0x16, 0x17, 0x03, 0x0a, 0x30, 0x05, 0x1f, 0x23, 0x20, 0x0d, 0x2e, 0x1b, + 0x12, 0x03, 0x07, 0xfa, 0xf7, 0xf0, 0xe5, 0xdd, 0xdd, 0xe3, 0xe1, 0xd2, + 0xf3, 0xe4, 0xd0, 0xf0, 0xee, 0xf5, 0xea, 0x0e, 0xf2, 0xff, 0xed, 0xe6, + 0x09, 0xf6, 0xfb, 0xee, 0x1c, 0xfa, 0x01, 0x0f, 0x0b, 0x0a, 0x0b, 0x10, + 0x05, 0x00, 0x0a, 0x01, 0xfb, 0x00, 0x0b, 0x07, 0xf2, 0x1a, 0x01, 0x0d, + 0x02, 0x10, 0x17, 0x00, 0x18, 0x1a, 0x14, 0xfd, 0x1b, 0xf6, 0x07, 0x02, + 0xf6, 0x01, 0xfb, 0xf2, 0xd8, 0xf7, 0xdc, 0xdc, 0xe3, 0xdb, 0xc7, 0xfb, + 0xe3, 0xd8, 0xe3, 0xf1, 0xcf, 0xdd, 0xe8, 0xe1, 0xdc, 0xee, 0x01, 0xe6, + 0x03, 0x06, 0x07, 0x02, 0x27, 0x21, 0x27, 0x27, 0x30, 0x27, 0x1d, 0x2c, + 0x1a, 0xfe, 0x24, 0x12, 0x10, 0x06, 0x1b, 0x07, 0xff, 0x09, 0x03, 0xed, + 0xf9, 0xf9, 0xea, 0xd7, 0xec, 0xe3, 0xdd, 0xdb, 0xdc, 0xd7, 0xd3, 0xdb, + 0xe1, 0xe0, 0xf3, 0xfd, 0xff, 0xf9, 0x10, 0x01, 0xfe, 0x16, 0x10, 0x09, + 0x13, 0x02, 0x01, 0x1a, 0x07, 0xf6, 0x0d, 0x06, 0x06, 0x01, 0x0d, 0x03, + 0x0b, 0x09, 0xf5, 0xfd, 0xfd, 0x02, 0xfa, 0xf6, 0x06, 0xe6, 0x06, 0xf7, + 0xf0, 0x0a, 0xfe, 0xfb, 0x03, 0x0a, 0x0d, 0x0a, 0x07, 0xf9, 0x0f, 0xfb, + 0xf3, 0xf3, 0xee, 0xf0, 0xea, 0xdb, 0xf9, 0xea, 0xe3, 0xea, 0xfa, 0xea, + 0xf7, 0x01, 0x02, 0xe6, 0x02, 0xf5, 0xfa, 0xf9, 0xff, 0xf7, 0xfb, 0x14, + 0x0e, 0xff, 0x1d, 0x18, 0x1b, 0x1b, 0x0b, 0x2a, 0x20, 0x18, 0x0f, 0x18, + 0x0b, 0x02, 0x00, 0xfe, 0xfa, 0xfa, 0xe4, 0xfa, 0xe8, 0xf0, 0xe1, 0xe3, + 0xdf, 0xcc, 0xe4, 0xd8, 0xc7, 0xd9, 0xe4, 0xdb, 0xcc, 0xf6, 0xe1, 0xd9, + 0xfa, 0xf2, 0xf6, 0x00, 0x12, 0x03, 0x0e, 0x1b, 0x1a, 0x20, 0x13, 0x27, + 0x1f, 0x0d, 0x25, 0x17, 0x14, 0x13, 0x05, 0x07, 0x10, 0x06, 0x03, 0x18, + 0x0f, 0xff, 0x0d, 0x0a, 0x00, 0xfb, 0xe6, 0xfe, 0xf9, 0xf9, 0xf6, 0xea, + 0x01, 0xf0, 0xec, 0xe3, 0xfa, 0xf1, 0xed, 0xf5, 0xfe, 0x02, 0xee, 0xfd, + 0xf6, 0xf5, 0xf6, 0xec, 0xed, 0xf6, 0xf5, 0xec, 0xf0, 0x07, 0xfd, 0xf0, + 0x07, 0x01, 0xff, 0xf6, 0x07, 0x03, 0x01, 0x06, 0x07, 0x06, 0x06, 0x09, + 0xf3, 0x06, 0x17, 0x0a, 0x18, 0x16, 0x12, 0x0f, 0x05, 0x02, 0x01, 0xf5, + 0xfb, 0xfd, 0xf1, 0xf7, 0xf2, 0xea, 0xed, 0xed, 0xd8, 0xdc, 0xf0, 0xe0, + 0xec, 0xfd, 0xf2, 0xed, 0x0f, 0xf6, 0xea, 0xfd, 0xfd, 0x02, 0xf0, 0x0d, + 0x06, 0x07, 0xfd, 0x21, 0xfb, 0x10, 0x1c, 0x16, 0x09, 0x24, 0x1b, 0x18, + 0x01, 0x1d, 0x06, 0xfa, 0xf9, 0xf9, 0xee, 0xf1, 0xe8, 0xee, 0xf0, 0xf0, + 0xf5, 0xfd, 0xee, 0xe9, 0x01, 0xee, 0xec, 0xf2, 0xec, 0xd8, 0xf6, 0xec, + 0xea, 0xe5, 0x01, 0xf6, 0xf5, 0xff, 0x02, 0x06, 0x0f, 0x06, 0xfb, 0x12, + 0x01, 0xf7, 0x05, 0x09, 0x09, 0x0f, 0xf9, 0x10, 0x0e, 0x0b, 0xf7, 0x17, + 0x05, 0x00, 0x05, 0x0e, 0x05, 0x12, 0x0b, 0xfb, 0x14, 0x05, 0x0a, 0x00, + 0x05, 0x02, 0x00, 0xff, 0xfd, 0xfa, 0xf9, 0xf9, 0xe6, 0x06, 0xf9, 0xf7, + 0xe5, 0xff, 0xec, 0xdd, 0xf5, 0xf1, 0xdd, 0xe5, 0xea, 0xe9, 0xd8, 0xf9, + 0xf1, 0xee, 0xee, 0x0b, 0xea, 0xfe, 0x02, 0x01, 0xf2, 0x0f, 0x00, 0x0b, + 0x01, 0x05, 0x09, 0xf3, 0x0e, 0x0f, 0x0e, 0x00, 0x1f, 0x10, 0x0f, 0xfe, + 0x1d, 0x06, 0xf7, 0x01, 0x06, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xf7, 0xf3, + 0xfd, 0xf6, 0xf6, 0xf6, 0xf7, 0xed, 0xfb, 0xf2, 0xe9, 0xf6, 0x01, 0xfe, + 0xf1, 0x0a, 0xff, 0xed, 0x09, 0x00, 0xfb, 0xfd, 0x0b, 0x06, 0x0b, 0x12, + 0x0f, 0x0a, 0x0a, 0x09, 0x09, 0x00, 0xf3, 0x09, 0xee, 0xf6, 0xfb, 0xee, + 0xe5, 0x0a, 0xe8, 0xf3, 0x02, 0xfb, 0xed, 0x00, 0xfd, 0xf6, 0xea, 0xf7, + 0xee, 0xee, 0xf2, 0xee, 0xe8, 0xfe, 0xee, 0xed, 0xff, 0xfe, 0x02, 0xf5, + 0x0b, 0x03, 0x03, 0x0b, 0x06, 0x09, 0x06, 0x05, 0x03, 0x03, 0x03, 0x06, + 0xfb, 0x06, 0x12, 0x0a, 0xfe, 0x18, 0x07, 0xfd, 0x0f, 0x05, 0xfe, 0x01, + 0x07, 0x01, 0xfa, 0x0d, 0x00, 0xf0, 0x09, 0xff, 0x03, 0xf1, 0x0a, 0xfe, + 0xf3, 0xfd, 0xf7, 0xfe, 0xe4, 0x00, 0xf3, 0xe4, 0xf9, 0xec, 0xf0, 0xee, + 0xee, 0xee, 0xf0, 0xf0, 0xf5, 0xfe, 0xff, 0xe6, 0x0a, 0xff, 0xfd, 0x02, + 0x0b, 0xff, 0xfd, 0x06, 0x00, 0xff, 0xfd, 0x01, 0xff, 0x06, 0x0a, 0x0e, + 0x00, 0x10, 0x07, 0x0f, 0x05, 0xf5, 0x07, 0xfa, 0x00, 0xe9, 0xfa, 0xf2, + 0xf6, 0xe0, 0xf3, 0xf2, 0xf7, 0xe8, 0x0a, 0xfe, 0xfd, 0xf7, 0x05, 0xf9, + 0x01, 0x09, 0xfa, 0x06, 0x13, 0x00, 0x05, 0x16, 0x0a, 0x00, 0x0f, 0x06, + 0x0b, 0x0b, 0x0a, 0xfb, 0x13, 0x03, 0xfb, 0xff, 0xfd, 0x00, 0xf2, 0xec, + 0xfa, 0xf1, 0xe6, 0xec, 0xf9, 0xec, 0xe0, 0xf7, 0xec, 0xf1, 0xf2, 0xf6, + 0xf3, 0xff, 0x05, 0x02, 0xf7, 0x07, 0x01, 0x01, 0x02, 0x0a, 0xfa, 0x06, + 0x12, 0x02, 0xf5, 0x13, 0x02, 0xff, 0xfd, 0x07, 0xf7, 0xf3, 0xf5, 0xee, + 0xf1, 0xf1, 0xf0, 0xed, 0xff, 0xf9, 0xf9, 0xff, 0x01, 0xff, 0x09, 0x09, + 0xff, 0x02, 0x09, 0xff, 0x05, 0x06, 0x0a, 0xfa, 0x0a, 0x0d, 0x07, 0xfd, + 0x17, 0x05, 0x09, 0xfe, 0xf7, 0x0b, 0xf9, 0xe8, 0xfe, 0xf5, 0xf2, 0xe8, + 0xf5, 0xec, 0xf5, 0xe8, 0xf6, 0xf7, 0xf6, 0xf9, 0xfa, 0x01, 0xee, 0x06, + 0x09, 0x01, 0x0d, 0x16, 0x0d, 0xfd, 0x17, 0x0d, 0x03, 0x09, 0x13, 0x09, + 0xfa, 0x0f, 0x06, 0x02, 0xfd, 0x05, 0xf9, 0xf9, 0xf5, 0xf2, 0xe3, 0xec, + 0xe5, 0xe5, 0xe6, 0xed, 0xdb, 0xee, 0xf7, 0xec, 0xfb, 0x00, 0xff, 0xf3, + 0x0a, 0x05, 0x03, 0x01, 0x14, 0x06, 0x09, 0x0a, 0x07, 0x0b, 0x06, 0x06, + 0x07, 0x09, 0x06, 0x05, 0xf7, 0x02, 0x02, 0xfa, 0xf5, 0x02, 0xf5, 0xf6, + 0xf3, 0xf5, 0xf7, 0xfb, 0x00, 0xf3, 0xff, 0x07, 0xfd, 0xf7, 0x05, 0xff, + 0xfb, 0xff, 0x02, 0x06, 0xfd, 0x03, 0x09, 0x03, 0xff, 0xfa, 0x02, 0xfa, + 0xee, 0xf6, 0xf9, 0xea, 0xf1, 0xf0, 0xea, 0xf1, 0xed, 0xe6, 0xf1, 0xec, + 0xf0, 0xf2, 0xf0, 0xf9, 0xf7, 0xf5, 0x03, 0x02, 0xfa, 0x14, 0x12, 0x14, + 0x0b, 0x2d, 0x16, 0x1a, 0x0f, 0x1f, 0x0d, 0x09, 0x10, 0x0b, 0x06, 0x05, + 0x02, 0xfd, 0xfd, 0xf9, 0xf5, 0xe1, 0xf7, 0xee, 0xf1, 0xdc, 0xf2, 0xea, + 0xe8, 0xe1, 0xf2, 0xea, 0xf7, 0xee, 0xf3, 0x00, 0xff, 0xf6, 0x0e, 0x06, + 0x07, 0xff, 0x1a, 0x0d, 0x02, 0x13, 0x0f, 0x00, 0x09, 0x0d, 0xfb, 0xfd, + 0x01, 0xf9, 0xf1, 0xfd, 0xf9, 0xfe, 0xf0, 0xf5, 0xfd, 0xf6, 0xe5, 0xf6, + 0xf1, 0xe3, 0xfb, 0xf6, 0xed, 0x09, 0x00, 0xfd, 0x03, 0x07, 0xfa, 0x06, + 0x09, 0x00, 0x0e, 0x0b, 0x0b, 0x0a, 0xfe, 0x0f, 0x01, 0xf6, 0x01, 0xf9, + 0xf7, 0xf6, 0xed, 0xfb, 0xf3, 0xf2, 0xe6, 0xf7, 0xf1, 0xee, 0xf1, 0xf9, + 0xec, 0xf7, 0xfd, 0xf6, 0xfd, 0x00, 0x06, 0xf9, 0x06, 0x1a, 0x13, 0x07, + 0x24, 0x1a, 0x0d, 0x1b, 0x0f, 0x09, 0xfb, 0x0a, 0xfe, 0xfa, 0xf6, 0xf9, + 0xe4, 0xf5, 0xf5, 0xec, 0xdf, 0xf1, 0xe5, 0xea, 0xd9, 0xf3, 0xed, 0xed, + 0xe3, 0xfe, 0xf3, 0xfa, 0xfd, 0xf7, 0x09, 0x09, 0x0b, 0x06, 0x17, 0x0b, + 0x0e, 0x13, 0x0f, 0x0e, 0x14, 0x12, 0x03, 0x17, 0x0e, 0x06, 0x01, 0x0b, + 0xff, 0xea, 0xff, 0xf2, 0xf1, 0xe1, 0xfd, 0xee, 0xea, 0xf1, 0xfb, 0xf0, + 0xe8, 0xff, 0xf5, 0xee, 0xfd, 0x03, 0xf0, 0x05, 0x03, 0x06, 0xff, 0x13, + 0x03, 0x0f, 0x0a, 0x05, 0x13, 0x0a, 0x02, 0x00, 0x00, 0xf7, 0xf9, 0xf9, + 0xf3, 0xdc, 0x03, 0xee, 0xf0, 0xf0, 0xfb, 0xf1, 0xed, 0xfe, 0xf6, 0xfd, + 0xfe, 0xf2, 0x03, 0x03, 0x09, 0xfa, 0x0e, 0x09, 0x0d, 0x05, 0x05, 0x17, + 0x09, 0xff, 0x0e, 0x09, 0xf7, 0x03, 0xfd, 0xfa, 0xee, 0xf9, 0xf2, 0xec, + 0xed, 0xee, 0xe6, 0xdc, 0xfa, 0xe4, 0xea, 0xe0, 0xf7, 0xf3, 0xf6, 0xfd, + 0x06, 0x05, 0x07, 0x00, 0x0a, 0x10, 0x07, 0x07, 0x16, 0x13, 0x0a, 0x14, + 0x18, 0x13, 0x17, 0x1d, 0x0a, 0x09, 0x16, 0x05, 0xf6, 0xff, 0xf6, 0xf3, + 0xe5, 0xea, 0xee, 0xea, 0xec, 0xf0, 0xe3, 0xf1, 0xf2, 0xe8, 0xee, 0xfd, + 0xf7, 0xf9, 0xee, 0xff, 0xfa, 0xf9, 0xf6, 0x01, 0x01, 0xff, 0x0b, 0x0a, + 0x03, 0x05, 0x0f, 0x02, 0x00, 0x09, 0x05, 0x02, 0x01, 0x00, 0x01, 0xf5, + 0xf3, 0x01, 0xf1, 0xf1, 0xfd, 0xfe, 0xf6, 0xfb, 0x06, 0x01, 0x02, 0x01, + 0x0a, 0xff, 0x02, 0x0e, 0x06, 0xff, 0x06, 0x0f, 0xff, 0x00, 0x0e, 0xfd, + 0xfe, 0xff, 0xfe, 0xfd, 0x01, 0xf2, 0xf7, 0xfb, 0xf2, 0xe8, 0xed, 0xea, + 0xee, 0xe9, 0xee, 0xf5, 0xf1, 0xf0, 0xfd, 0xfa, 0xed, 0x0b, 0x03, 0x06, + 0xfe, 0x14, 0x0a, 0x02, 0x10, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x09, 0x07, + 0xff, 0x0b, 0x03, 0xff, 0xf7, 0x0b, 0xfb, 0xea, 0xff, 0xf0, 0xe1, 0xf0, + 0xe9, 0xf2, 0xe8, 0xf1, 0xf2, 0xed, 0xf5, 0xfd, 0xf6, 0xf7, 0xfe, 0x00, + 0x03, 0xf5, 0x16, 0x07, 0x06, 0xfd, 0x13, 0x09, 0x01, 0x0b, 0x0d, 0x10, + 0x09, 0x01, 0x0f, 0xf9, 0x03, 0xfa, 0xf6, 0x02, 0xf6, 0xfa, 0xf7, 0xfa, + 0xf5, 0xe5, 0x0b, 0xed, 0xfb, 0xf5, 0xf9, 0xfd, 0xfe, 0xfd, 0xff, 0x01, + 0x01, 0x02, 0x03, 0x03, 0x02, 0x02, 0x05, 0xf3, 0x0a, 0xfe, 0xf5, 0x02, + 0xfb, 0xfb, 0xed, 0x05, 0xf6, 0xf3, 0xff, 0xf3, 0xf9, 0xf7, 0xf3, 0xf1, + 0xf5, 0xf3, 0xf2, 0xf7, 0xf9, 0xf6, 0xf2, 0x0f, 0x01, 0xf6, 0x0b, 0x07, + 0x0b, 0x07, 0x02, 0x16, 0x09, 0xff, 0x06, 0x07, 0x07, 0x05, 0xfb, 0x07, + 0xfe, 0x05, 0xfa, 0xed, 0x02, 0xee, 0xf3, 0xf3, 0xec, 0xf2, 0xf2, 0xec, + 0xf5, 0xf3, 0xf5, 0xf3, 0xf9, 0x00, 0xfb, 0xf1, 0x09, 0x01, 0x06, 0xfe, + 0x07, 0x14, 0x09, 0x05, 0x13, 0x0e, 0x07, 0x0a, 0x0b, 0x00, 0x05, 0xff, + 0x00, 0x01, 0xf5, 0xfd, 0xfd, 0xf5, 0xfa, 0xfa, 0xf9, 0xf3, 0xed, 0x00, + 0xf1, 0xe8, 0xf5, 0xf5, 0xf3, 0xf6, 0xfb, 0xf1, 0xff, 0xfe, 0xfb, 0xff, + 0x01, 0x03, 0x01, 0x05, 0x00, 0x02, 0x02, 0xf6, 0x06, 0x03, 0x03, 0x01, + 0x09, 0x03, 0x09, 0xf6, 0xff, 0x01, 0xfb, 0xf0, 0x03, 0xfd, 0xf6, 0x00, + 0xfb, 0xfd, 0xf5, 0x0a, 0xf5, 0xf3, 0x09, 0xf2, 0xf7, 0x00, 0xfb, 0xf0, + 0xff, 0xfb, 0xfe, 0xfd, 0xf7, 0xff, 0x01, 0xf9, 0xfe, 0x01, 0xea, 0x02, + 0xfb, 0xf7, 0xf3, 0xfd, 0xf7, 0xed, 0xfe, 0xfd, 0xfe, 0xf9, 0x01, 0xfb, + 0x02, 0xff, 0xff, 0x06, 0x02, 0x07, 0x09, 0x09, 0x09, 0x07, 0x0b, 0x07, + 0x05, 0x07, 0x06, 0x05, 0x05, 0x05, 0x03, 0xfb, 0x03, 0xfd, 0xfb, 0xf0, + 0x00, 0xf7, 0xff, 0xec, 0xf6, 0xf7, 0xf7, 0xf5, 0xf3, 0x02, 0xfa, 0xf2, + 0xfe, 0xfa, 0xfe, 0xfe, 0xf3, 0x06, 0xfe, 0x02, 0xff, 0xf6, 0x06, 0xfe, + 0xf9, 0x00, 0x06, 0x02, 0x06, 0xfe, 0xff, 0x06, 0x02, 0xf7, 0x01, 0x02, + 0xfe, 0xf1, 0xff, 0xf9, 0xf9, 0xea, 0x00, 0xf7, 0xf0, 0xf9, 0xfb, 0xf9, + 0xf1, 0x03, 0xf9, 0xee, 0x03, 0xfa, 0xfa, 0xf5, 0x03, 0xfb, 0xf2, 0x05, + 0xfe, 0x01, 0xf5, 0x0a, 0x01, 0x03, 0x01, 0x03, 0x05, 0x01, 0x03, 0x05, + 0x03, 0xf3, 0x13, 0xfd, 0xff, 0x06, 0x03, 0x05, 0x00, 0x06, 0x06, 0x06, + 0x05, 0x03, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xee, 0x0a, + 0xfe, 0xfa, 0xfa, 0xfd, 0xfd, 0xf3, 0xf6, 0xff, 0xf6, 0xf3, 0xf3, 0xf5, + 0xec, 0xfe, 0xf6, 0xee, 0xff, 0xf6, 0xf5, 0xed, 0x00, 0xf5, 0xf0, 0xf6, + 0xfa, 0xf7, 0xf6, 0xf9, 0xfe, 0xfe, 0xfa, 0xfb, 0x0d, 0x01, 0xfa, 0x01, + 0x09, 0x02, 0x03, 0x05, 0x05, 0x06, 0x06, 0x02, 0xff, 0x0d, 0x05, 0xfe, + 0x02, 0x01, 0x01, 0xff, 0xf9, 0x03, 0xff, 0xf5, 0xfd, 0x00, 0xfe, 0xf3, + 0x09, 0xff, 0xf7, 0x02, 0xfe, 0xfd, 0xf2, 0x07, 0xfe, 0xf6, 0x02, 0x00, + 0xfa, 0xfa, 0x0a, 0xff, 0xf5, 0x07, 0x00, 0xfd, 0xfa, 0x07, 0xff, 0xf5, + 0x07, 0xff, 0x00, 0xfa, 0x03, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf0, 0xfa, + 0xfb, 0xf9, 0xed, 0xff, 0xf6, 0xf7, 0xf9, 0xfe, 0xf9, 0xfd, 0xfb, 0xfe, + 0xe8, 0x05, 0xfb, 0xfd, 0xfb, 0xf3, 0x09, 0xff, 0xf6, 0x06, 0x00, 0x00, + 0xf5, 0x07, 0xfe, 0xfb, 0xff, 0xfe, 0xf5, 0xfd, 0x02, 0xfa, 0xfb, 0x00, + 0x01, 0x03, 0xfa, 0x05, 0x02, 0xfd, 0x00, 0x02, 0xfb, 0xfd, 0x02, 0x01, + 0xff, 0xff, 0x0a, 0xf7, 0x00, 0x0d, 0x03, 0xf9, 0x09, 0x02, 0xff, 0xfd, + 0x06, 0x00, 0xf9, 0xfb, 0x06, 0xf9, 0xfa, 0x01, 0xfb, 0xf2, 0xfb, 0xff, + 0xf5, 0xee, 0x01, 0xf6, 0xec, 0xfd, 0xf6, 0xf7, 0xed, 0xfe, 0xf7, 0xfa, + 0xf9, 0xf9, 0xf9, 0xfa, 0xf9, 0xfa, 0xfd, 0xff, 0xff, 0x02, 0xf5, 0xff, + 0x09, 0xff, 0x02, 0x02, 0xff, 0xfb, 0xff, 0xff, 0x00, 0xfd, 0xff, 0x09, + 0xf3, 0x03, 0x01, 0x03, 0xf3, 0x06, 0x01, 0xfe, 0xfb, 0x0a, 0xfd, 0x02, + 0x09, 0x02, 0xfe, 0x02, 0x03, 0x03, 0x02, 0xfa, 0x0a, 0xfb, 0xfa, 0xfd, + 0x02, 0xf7, 0xf6, 0x05, 0xfa, 0xf0, 0x00, 0xfa, 0xfb, 0xf0, 0x02, 0xfa, + 0xfd, 0xf3, 0xff, 0xfe, 0xfe, 0xf5, 0x02, 0xfe, 0xfe, 0xfe, 0x02, 0xff, + 0xff, 0x02, 0xfe, 0xf6, 0x0e, 0x00, 0xf7, 0x02, 0x01, 0xfa, 0xf3, 0x01, + 0xfa, 0xf9, 0xf3, 0xfe, 0xf3, 0xf1, 0x01, 0xf1, 0xf3, 0xfa, 0xf7, 0xf3, + 0xf2, 0x05, 0xf2, 0xf0, 0x06, 0xfe, 0xff, 0xfe, 0x02, 0x05, 0x06, 0x02, + 0x0f, 0x09, 0x0a, 0x07, 0x0b, 0x0b, 0x0a, 0x0d, 0x09, 0x01, 0x14, 0x07, + 0xff, 0x07, 0x02, 0x00, 0xf3, 0xff, 0xfa, 0xfa, 0xf5, 0xf7, 0xf7, 0xf6, + 0xf6, 0xf6, 0xf6, 0xf6, 0xf7, 0xf9, 0xfa, 0xe9, 0x01, 0xfb, 0xfb, 0xf6, + 0x01, 0xfb, 0xfb, 0xfd, 0xfe, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, + 0xf7, 0xff, 0xff, 0xff, 0xf3, 0x02, 0xfd, 0xf7, 0xfe, 0xfd, 0x02, 0xf5, + 0xfd, 0x00, 0xfe, 0xf3, 0x01, 0x00, 0x00, 0xf5, 0x09, 0x01, 0xff, 0x02, + 0x05, 0xf5, 0x07, 0x02, 0x02, 0xfa, 0x09, 0x00, 0xfa, 0xff, 0xff, 0xfe, + 0xfd, 0xfd, 0xfa, 0xfb, 0xfb, 0xf9, 0xed, 0xff, 0xf2, 0xf6, 0xf6, 0xf5, + 0xff, 0xfb, 0xfd, 0xff, 0xff, 0xff, 0x00, 0xfd, 0x09, 0x03, 0x05, 0x02, + 0x0b, 0xfd, 0x06, 0x02, 0x02, 0x03, 0x02, 0x02, 0xfe, 0x00, 0xff, 0xf9, + 0xf7, 0xff, 0xf7, 0xf1, 0xf3, 0xf7, 0xf5, 0xec, 0xf5, 0xfb, 0xf0, 0xf7, + 0xf7, 0xf9, 0xfa, 0xfb, 0xfd, 0xf7, 0xfe, 0x03, 0xff, 0xfe, 0x03, 0x05, + 0x06, 0x07, 0x0a, 0x0a, 0x0a, 0x09, 0xff, 0x09, 0x03, 0x02, 0x02, 0x01, + 0x00, 0x00, 0x03, 0xf3, 0x02, 0xff, 0xfe, 0xf5, 0x02, 0xfd, 0xf7, 0x00, + 0xfa, 0xff, 0xf9, 0xfb, 0x00, 0xf7, 0xfe, 0xff, 0xff, 0xf3, 0x09, 0xfe, + 0xf6, 0x00, 0xfd, 0xfb, 0xf0, 0x05, 0xf9, 0xf1, 0xfd, 0xf6, 0xff, 0xf0, + 0xf6, 0xf9, 0xf5, 0xf5, 0xf6, 0xf6, 0xf7, 0xf9, 0xfb, 0xfd, 0xfb, 0xfb, + 0x07, 0xfb, 0x02, 0x07, 0x07, 0x03, 0x09, 0x0a, 0x0a, 0x03, 0x09, 0x09, + 0x09, 0x06, 0x02, 0x03, 0x02, 0x01, 0x00, 0xfd, 0xed, 0x02, 0xf3, 0xf9, + 0xec, 0xf7, 0xf6, 0xed, 0xf6, 0xf6, 0xf5, 0xea, 0x01, 0xf5, 0xf3, 0xff, + 0xf7, 0xfb, 0xfe, 0x00, 0xf9, 0x03, 0x07, 0x05, 0x01, 0x0a, 0x09, 0x09, + 0x09, 0x0a, 0x0d, 0x03, 0x01, 0x05, 0x01, 0xfb, 0xf9, 0x07, 0xfa, 0xf9, + 0xff, 0xfb, 0xf5, 0xf9, 0xfd, 0xee, 0xf6, 0xfe, 0xf7, 0xee, 0xf7, 0xfa, + 0xf7, 0xf3, 0x05, 0xf7, 0xf3, 0x06, 0xf3, 0xfe, 0xfe, 0xff, 0x00, 0xfd, + 0xf7, 0x0a, 0xf9, 0xff, 0xfa, 0xfe, 0x00, 0xfe, 0xfb, 0xfd, 0xfe, 0xfe, + 0xfd, 0xf7, 0x00, 0xfe, 0xff, 0xf7, 0x05, 0x02, 0xfe, 0x05, 0x06, 0x06, + 0x01, 0x03, 0x0d, 0x07, 0xfd, 0x07, 0x07, 0x06, 0xfa, 0x06, 0x03, 0xfd, + 0x00, 0x01, 0xfe, 0xf3, 0x02, 0xf7, 0xed, 0xfb, 0xf5, 0xf1, 0xed, 0xf9, + 0xf2, 0xe9, 0xf6, 0xf3, 0xf9, 0xf6, 0xed, 0x03, 0xf7, 0xfd, 0xfe, 0x03, + 0xff, 0x02, 0x03, 0x05, 0x03, 0x07, 0x09, 0x09, 0x09, 0x09, 0x09, 0x07, + 0xf9, 0x14, 0xfd, 0xff, 0x02, 0xfe, 0xf2, 0x02, 0xfa, 0xf9, 0xec, 0x02, + 0xf1, 0xec, 0xfb, 0xf5, 0xf5, 0xf0, 0xfe, 0xf3, 0xee, 0xfe, 0xfa, 0xfe, + 0xf3, 0x07, 0x00, 0xfd, 0x06, 0x03, 0x00, 0x00, 0x09, 0x03, 0xfa, 0x0a, + 0x02, 0x03, 0xf7, 0x07, 0x00, 0x01, 0xfa, 0xff, 0x02, 0xfe, 0xfe, 0xf5, + 0x05, 0xfd, 0xfd, 0xfe, 0xff, 0xff, 0xff, 0x00, 0xf6, 0x03, 0x00, 0x00, + 0xfe, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xfd, 0xf3, 0xfd, 0xff, 0xf3, 0xfb, + 0xfb, 0xfa, 0xf1, 0x02, 0xf3, 0xee, 0xfb, 0xf5, 0xf5, 0xf2, 0xff, 0xf6, + 0xf0, 0xff, 0xfa, 0x00, 0xf5, 0x05, 0x03, 0x03, 0xfe, 0x0e, 0x09, 0x03, + 0x0a, 0x10, 0x00, 0x0b, 0x0a, 0x0d, 0xfe, 0x0a, 0x06, 0x06, 0xf9, 0x07, + 0xff, 0xfe, 0xf1, 0x03, 0xf5, 0xf7, 0xf5, 0xf5, 0xf3, 0xf3, 0xf5, 0xf6, + 0xe5, 0xf9, 0xf5, 0xf2, 0xf3, 0xfe, 0xf7, 0xf3, 0x03, 0xff, 0x01, 0x01, + 0x03, 0x05, 0x03, 0xfa, 0x0a, 0x03, 0x05, 0x03, 0x02, 0xff, 0x05, 0x01, + 0xf7, 0x0d, 0x00, 0x00, 0xfd, 0x01, 0xfd, 0xff, 0xf5, 0xf6, 0x00, 0xfb, + 0xf9, 0xf7, 0x05, 0xfa, 0xfd, 0xfe, 0xfd, 0xfa, 0x00, 0xfe, 0xf5, 0x00, + 0xfe, 0xfe, 0xf2, 0x02, 0xfe, 0xfb, 0xfe, 0xff, 0xfe, 0xf7, 0x02, 0xfd, + 0xf5, 0x01, 0xfd, 0xfb, 0xf0, 0x01, 0xfb, 0xfe, 0xf6, 0x02, 0x00, 0x01, + 0xfe, 0x01, 0x03, 0x02, 0x03, 0x07, 0x00, 0x05, 0x09, 0x05, 0x05, 0x05, + 0x07, 0xfa, 0x06, 0x06, 0xff, 0xf9, 0x05, 0xff, 0xf9, 0xf5, 0xfe, 0xf7, + 0xf6, 0xf0, 0xfe, 0xf5, 0xf0, 0xf5, 0xf9, 0xf2, 0xf5, 0xfb, 0xec, 0xf9, + 0xfd, 0xfb, 0xf2, 0x06, 0xff, 0xfd, 0xfe, 0x07, 0x03, 0xfd, 0x05, 0x05, + 0x03, 0xfe, 0x06, 0x02, 0x02, 0x01, 0x01, 0xff, 0xff, 0xfe, 0xfe, 0xfd, + 0xfd, 0xfd, 0xfd, 0xfe, 0xf2, 0xfd, 0xff, 0xfd, 0xf6, 0x01, 0xf5, 0x00, + 0xfe, 0xfe, 0xf7, 0xfd, 0x00, 0xfe, 0xfe, 0xf9, 0x07, 0xfe, 0x01, 0x03, + 0x03, 0xfe, 0xff, 0x0a, 0xff, 0xf9, 0x0a, 0xf9, 0xfd, 0xfd, 0xfa, 0xfa, + 0xfa, 0xfb, 0xfa, 0xf0, 0x0b, 0xf6, 0xf6, 0x01, 0xfd, 0xfb, 0xf9, 0x00, + 0xfd, 0xfd, 0xfe, 0xff, 0xfe, 0xff, 0x01, 0x01, 0xfe, 0x00, 0x06, 0x00, + 0xf7, 0x02, 0xff, 0xff, 0xf6, 0x05, 0xfe, 0xf8, 0x00, 0xfc, 0x00, 0xf4, + 0x00, 0x00, 0xf7, 0xff, 0x00, 0xff, 0xfc, 0x01, 0x00, 0xf8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x01, 0xfc, 0x09, 0x00, + 0x01, 0x00, 0xf7, 0x06, 0xfc, 0x00, 0xf9, 0xfe, 0xfe, 0xfb, 0xfb, 0xf9, + 0xfb, 0xfb, 0xf7, 0xf9, 0xfb, 0xfb, 0xf9, 0xf8, 0x00, 0xf5, 0xfc, 0xfc, + 0xff, 0xf8, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x00, 0xf8, 0x04, 0x00, 0x00, + 0xfd, 0x01, 0x00, 0x00, 0xfc, 0x03, 0xfe, 0xfd, 0x00, 0xff, 0xfc, 0xfe, + 0x00, 0xfe, 0xf9, 0x05, 0xfc, 0xfc, 0xff, 0xff, 0xff, 0x00, 0xf7, 0x02, + 0x00, 0xfe, 0x00, 0x01, 0x00, 0xff, 0xfd, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0x01, 0x00, 0xfd, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00, 0xfd, 0x03, + 0xff, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, + 0xfa, 0x03, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xfe, 0xfe, 0xfd, 0xfd, 0xfd, + 0xfb, 0xff, 0xfc, 0xfc, 0xfd, 0xfc, 0xfd, 0xfc, 0xfd, 0xfd, 0xf9, 0x00, + 0xfc, 0xfe, 0xfb, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x01, + 0x01, 0x01, 0x02, 0x02, 0x00, 0x05, 0x00, 0xfe, 0x05, 0x00, 0xff, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x01, 0xfe, 0xff, 0xff, 0x00, + 0xfd, 0xfd, 0x00, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfd, 0x01, 0x00, 0xff, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xfe, 0x00, + 0x00, 0x00, 0xfe, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xf8, 0xfc, 0x06, + 0x25, 0x29, 0x21, 0xe6, 0xcb, 0x1b, 0x37, 0x30, 0x07, 0x01, 0xc7, 0x02, + 0x08, 0xe2, 0x07, 0xdf, 0x48, 0x3e, 0xf7, 0xb2, 0x09, 0x2e, 0x5e, 0x5d, + 0x0e, 0xff, 0xd8, 0x07, 0xd8, 0x0d, 0xe3, 0x06, 0xbb, 0xee, 0x52, 0x5d, + 0x01, 0xce, 0xfa, 0x31, 0x11, 0x7a, 0x54, 0x1f, 0x05, 0x0e, 0x1e, 0x18, + 0x12, 0xc7, 0xaf, 0xb1, 0xb0, 0xb5, 0xd4, 0xb7, 0xb3, 0xc2, 0xc7, 0xe1, + 0xc9, 0xc2, 0xc3, 0x10, 0x18, 0x13, 0xe5, 0xe4, 0xc9, 0xf0, 0xee, 0xf2, + 0xd0, 0x9f, 0xc9, 0xff, 0xe8, 0x0f, 0xf7, 0xe2, 0x03, 0x06, 0xfb, 0xfa, + 0x25, 0x29, 0xf3, 0xa5, 0xc6, 0xc7, 0x28, 0xdb, 0xcd, 0xea, 0xe3, 0xdb, + 0xe7, 0xc0, 0x9f, 0xe4, 0xcd, 0xf3, 0xef, 0xc4, 0xf8, 0xdb, 0x28, 0x1c, + 0x1e, 0x2a, 0x3c, 0x40, 0x12, 0x10, 0x32, 0x14, 0xed, 0xfa, 0xbe, 0xd7, + 0xf0, 0xf9, 0xd4, 0xed, 0xe8, 0x0e, 0x1a, 0x29, 0xf4, 0x21, 0x43, 0x2c, + 0x54, 0x45, 0x25, 0x01, 0xef, 0xff, 0x10, 0xf7, 0xfe, 0x1a, 0x55, 0x60, + 0x43, 0x70, 0x51, 0x5d, 0x26, 0x5e, 0x4e, 0x3e, 0x3e, 0x05, 0x00, 0x27, + 0x4d, 0x6a, 0x29, 0x05, 0xf2, 0x04, 0xf1, 0x58, 0x42, 0x4b, 0x49, 0x2c, + 0x2a, 0x27, 0x35, 0x2e, 0x48, 0x09, 0x10, 0x1b, 0xe5, 0xef, 0xc7, 0xc7, + 0xf8, 0x16, 0x11, 0x2c, 0x32, 0x4d, 0x3c, 0x42, 0x5b, 0x3d, 0x45, 0x09, + 0xdf, 0xd8, 0xef, 0xcb, 0xc4, 0xf4, 0x08, 0x07, 0xf1, 0xdc, 0xd0, 0xd8, + 0xf0, 0xfc, 0xdb, 0xde, 0xd8, 0xf1, 0x40, 0x30, 0xde, 0xea, 0xe8, 0xc7, + 0xb2, 0xcd, 0xbc, 0xdf, 0xd0, 0xed, 0xfc, 0xde, 0xd9, 0xbc, 0xcf, 0xe4, + 0xfd, 0xf7, 0xe3, 0xec, 0xd3, 0xd6, 0xcf, 0xcf, 0xc0, 0xa8, 0xb3, 0xb2, + 0xd8, 0xf1, 0x09, 0x10, 0x0f, 0x11, 0x0d, 0xf8, 0xda, 0xed, 0xdc, 0xf1, + 0xf0, 0x0d, 0xff, 0xe3, 0xea, 0xcf, 0xc4, 0xd3, 0xd4, 0xcd, 0xd6, 0xbe, + 0xf7, 0xf8, 0x03, 0xfa, 0xef, 0xc8, 0xc0, 0xc6, 0xd0, 0xd0, 0xd9, 0xde, + 0xf2, 0x1d, 0x1e, 0x2a, 0x1f, 0x08, 0x03, 0xe4, 0xbb, 0xb7, 0xbe, 0xc3, + 0xe1, 0xf9, 0xf7, 0xe3, 0xd0, 0xc8, 0xcd, 0xcd, 0xde, 0xf0, 0x0c, 0x27, + 0x32, 0x30, 0x25, 0x0d, 0x18, 0x26, 0x43, 0x3e, 0x34, 0x1e, 0x19, 0xff, + 0x07, 0x12, 0xfc, 0xf2, 0xf7, 0x04, 0xfa, 0xfd, 0xfa, 0x18, 0x0d, 0x12, + 0x07, 0x11, 0x1b, 0x2a, 0x31, 0x31, 0x30, 0x27, 0x18, 0x1a, 0xfb, 0x0d, + 0x26, 0x45, 0x3c, 0x38, 0x26, 0x06, 0xfa, 0xf2, 0xe8, 0xdc, 0xf1, 0xfc, + 0x09, 0x13, 0x1b, 0x31, 0x55, 0x5a, 0x5e, 0x43, 0x29, 0x1c, 0x1c, 0x10, + 0x16, 0x1c, 0x22, 0x1b, 0x22, 0x0c, 0x1e, 0x01, 0xf2, 0xf1, 0xf9, 0xf2, + 0xfe, 0x16, 0x21, 0x1c, 0x43, 0x46, 0x44, 0x46, 0x27, 0xfd, 0xe1, 0xe5, + 0xfb, 0x07, 0x1e, 0x25, 0x1e, 0x22, 0xfe, 0xe2, 0xe5, 0xff, 0xef, 0xed, + 0x06, 0x22, 0x28, 0x3a, 0x34, 0x24, 0x12, 0xf4, 0xda, 0xd7, 0xd0, 0xdc, + 0xef, 0xea, 0x0d, 0x0c, 0x08, 0x1c, 0x16, 0xfc, 0xf8, 0xf9, 0x0d, 0x26, + 0x26, 0x32, 0x33, 0x32, 0x16, 0xf0, 0xd8, 0xde, 0xdf, 0xbe, 0xb7, 0xc9, + 0xcc, 0xd6, 0xd4, 0xd4, 0xe5, 0xf0, 0xf9, 0xf8, 0xf9, 0xf9, 0xe8, 0xe7, + 0xf2, 0xff, 0xfc, 0xf1, 0xea, 0xe6, 0xdb, 0xe1, 0xf1, 0xf8, 0xf0, 0x01, + 0x01, 0xf2, 0xf3, 0xfc, 0xef, 0xef, 0xf2, 0xf7, 0xe7, 0xc7, 0xcc, 0xd6, + 0xbc, 0xc2, 0xcb, 0xc8, 0xba, 0xd4, 0xf9, 0xf7, 0xee, 0xff, 0xf8, 0xf0, + 0xe2, 0xd9, 0xcf, 0xbc, 0xd9, 0xec, 0xec, 0xdc, 0xda, 0xc3, 0xd2, 0xfb, + 0xef, 0xf2, 0xff, 0x02, 0x09, 0xf8, 0xe7, 0xdb, 0xdc, 0xe4, 0xf2, 0xf7, + 0xed, 0xed, 0xde, 0xd8, 0xf0, 0xf4, 0xfd, 0xfa, 0xf0, 0xf8, 0xf7, 0xea, + 0xee, 0xe6, 0xd8, 0xdb, 0xe2, 0xdc, 0xd7, 0xd6, 0xe6, 0xf3, 0xfa, 0x08, + 0xfc, 0xfe, 0x10, 0x27, 0x37, 0x3d, 0x35, 0x09, 0xf8, 0x18, 0x12, 0xfa, + 0xf8, 0x03, 0xfc, 0xfc, 0xf7, 0xf2, 0xfb, 0x07, 0x13, 0x16, 0x13, 0x08, + 0x0c, 0x19, 0x10, 0x0d, 0x0e, 0x09, 0x1b, 0x1b, 0x18, 0x13, 0x0d, 0x13, + 0x1f, 0x1a, 0x1a, 0x1b, 0x1f, 0x0d, 0xfd, 0x27, 0x2c, 0x2d, 0x33, 0x1a, + 0x05, 0x08, 0x16, 0x1f, 0x18, 0x19, 0x1b, 0x0c, 0xfd, 0x06, 0x01, 0x14, + 0x18, 0x1b, 0x27, 0x2d, 0x1b, 0x12, 0x1b, 0x1d, 0x1c, 0x25, 0x28, 0x2d, + 0x21, 0x0e, 0x0f, 0x0c, 0x10, 0x0f, 0x09, 0x10, 0x1e, 0x22, 0x13, 0x12, + 0x22, 0x10, 0x03, 0x0f, 0x26, 0x32, 0x34, 0x44, 0x3d, 0x28, 0x1d, 0x0d, + 0x02, 0x06, 0x08, 0x07, 0xfc, 0x02, 0x09, 0x0f, 0x00, 0x00, 0x00, 0x02, + 0x01, 0xfb, 0x05, 0x18, 0x11, 0x18, 0x34, 0x11, 0xfc, 0xec, 0xe5, 0xde, + 0xd3, 0xed, 0xfd, 0x01, 0x12, 0x11, 0x04, 0x0d, 0xfd, 0xe7, 0xf1, 0xdf, + 0xf7, 0x03, 0x11, 0x26, 0x2a, 0x16, 0x0c, 0x16, 0x0e, 0xfa, 0xf9, 0xf7, + 0xf1, 0xfc, 0xfb, 0x02, 0xfa, 0xfc, 0x00, 0xf9, 0xf8, 0xfa, 0xfb, 0xff, + 0x07, 0x0d, 0xf8, 0xf8, 0xfb, 0xf0, 0xe7, 0xf4, 0xf7, 0xf3, 0xf2, 0xde, + 0xd7, 0xe8, 0xe2, 0xd9, 0xe5, 0xf4, 0xfa, 0xee, 0xe6, 0xe6, 0xef, 0xfa, + 0xfa, 0xfc, 0xfd, 0xee, 0xdc, 0xe5, 0xf9, 0xfc, 0xf8, 0xee, 0xed, 0xed, + 0xf1, 0xe4, 0xd7, 0xdb, 0xdb, 0xdf, 0xe6, 0xf1, 0xf9, 0xf3, 0xf8, 0xef, + 0xe7, 0xf2, 0xe4, 0xd4, 0xe3, 0xfa, 0xfb, 0x02, 0x04, 0xef, 0xe4, 0xec, + 0xf3, 0xf4, 0xec, 0xf4, 0xe7, 0xf8, 0x00, 0x09, 0x07, 0x00, 0xfe, 0xfa, + 0xfa, 0xf2, 0xe4, 0xec, 0xef, 0xf1, 0xed, 0xfa, 0xf9, 0xf9, 0xf3, 0xf9, + 0x00, 0xe4, 0xd4, 0xf1, 0x04, 0x00, 0xf3, 0xfe, 0xf9, 0xea, 0xe3, 0xe4, + 0x01, 0xf4, 0xe6, 0xf2, 0xfd, 0x03, 0xfd, 0xec, 0xec, 0xf4, 0xfc, 0xfc, + 0xfd, 0xfc, 0x00, 0x01, 0xf9, 0xfe, 0xf9, 0xe5, 0xe7, 0xea, 0xe8, 0xf8, + 0x00, 0x04, 0x0d, 0x01, 0x04, 0xf9, 0xf1, 0xff, 0x00, 0x00, 0xff, 0x00, + 0x00, 0x00, 0x08, 0xff, 0xfc, 0x03, 0xf4, 0x02, 0x01, 0xe7, 0xed, 0x03, + 0x08, 0x03, 0x16, 0x24, 0x0f, 0xfb, 0x07, 0x0d, 0xf1, 0x03, 0x02, 0xed, + 0x07, 0x1d, 0x0e, 0x09, 0x01, 0xee, 0xfb, 0x08, 0x0f, 0x06, 0xfc, 0x05, + 0x03, 0x02, 0x0c, 0x14, 0x02, 0xf4, 0xf9, 0x01, 0x05, 0xfd, 0xf2, 0x0e, + 0x08, 0x05, 0x08, 0x03, 0xf8, 0xf9, 0xfb, 0xfd, 0x0e, 0x0e, 0xff, 0x02, + 0x04, 0x05, 0x26, 0x35, 0x2c, 0x1f, 0x16, 0x09, 0xf2, 0xfd, 0x03, 0xfa, + 0xfd, 0x02, 0xf1, 0xe8, 0xef, 0xf3, 0xf4, 0xf4, 0x06, 0x12, 0x16, 0x02, + 0x09, 0x18, 0x1b, 0x1b, 0x1f, 0x27, 0x1f, 0xff, 0xf3, 0x04, 0x00, 0xf7, + 0xf7, 0x0e, 0x1b, 0x06, 0x07, 0xff, 0xfc, 0x19, 0x1d, 0x11, 0x1b, 0x18, + 0xff, 0x03, 0x13, 0x0d, 0x0e, 0x09, 0xff, 0x00, 0x09, 0xff, 0xee, 0xfb, + 0x07, 0x0e, 0x09, 0x03, 0x14, 0x13, 0x1b, 0x10, 0x07, 0x0d, 0x16, 0x04, + 0xf2, 0x06, 0x1a, 0x10, 0x0f, 0x18, 0x09, 0x03, 0x11, 0x13, 0x13, 0x13, + 0x22, 0x27, 0x1d, 0x13, 0x0f, 0x16, 0x14, 0xfd, 0xf0, 0x03, 0x09, 0x02, + 0xf7, 0x07, 0x13, 0x1a, 0x14, 0x08, 0x08, 0x14, 0x16, 0x13, 0x18, 0x13, + 0x05, 0xf4, 0xf8, 0x06, 0x04, 0xfc, 0x01, 0x0e, 0x09, 0x03, 0x02, 0x04, + 0x16, 0x09, 0xfd, 0x08, 0x00, 0x07, 0x05, 0xfb, 0xf7, 0xfb, 0xf1, 0xe1, + 0xea, 0xf1, 0xed, 0x06, 0x0c, 0x08, 0x08, 0x02, 0x0c, 0x05, 0x01, 0x09, + 0x04, 0xf3, 0xf4, 0xfc, 0xfe, 0xff, 0xf3, 0xea, 0xe6, 0xe3, 0xd9, 0xd9, + 0xe6, 0xe7, 0xea, 0xfa, 0x07, 0x00, 0xf3, 0xf8, 0xf9, 0xe8, 0xd9, 0xdb, + 0xe6, 0xe8, 0xe4, 0xed, 0xf7, 0xf2, 0xf8, 0xf0, 0xe3, 0xea, 0xea, 0xdf, + 0xf4, 0xfd, 0xf4, 0xff, 0xf8, 0xef, 0xf0, 0xef, 0xea, 0xe6, 0xe3, 0xe2, + 0xe4, 0xe8, 0xe1, 0xd9, 0xec, 0xf2, 0xf9, 0xfa, 0xf9, 0xfb, 0x09, 0x08, + 0xfa, 0xfa, 0xfa, 0xea, 0xee, 0xfa, 0xec, 0xd9, 0xe1, 0xde, 0xde, 0xdf, + 0xee, 0xff, 0xf7, 0xf7, 0xfd, 0xfb, 0x07, 0x09, 0xf3, 0xea, 0xf9, 0xfc, + 0xef, 0xf1, 0xe7, 0xf3, 0xf1, 0xec, 0xfa, 0xf4, 0xe5, 0xf0, 0xf9, 0xfd, + 0xf9, 0xf3, 0xfd, 0x00, 0xf8, 0xf1, 0xf7, 0xef, 0xe7, 0xdf, 0xdc, 0xe3, + 0xea, 0xec, 0xef, 0xef, 0xf4, 0xff, 0x0d, 0x19, 0x07, 0xfc, 0xfe, 0x09, + 0x0f, 0x07, 0x03, 0x03, 0x06, 0xfb, 0xe2, 0xf3, 0xe8, 0xdf, 0xef, 0xf0, + 0xf8, 0xfd, 0xff, 0x08, 0x14, 0x16, 0x06, 0x04, 0x0d, 0x02, 0xf4, 0xfa, + 0xfe, 0x03, 0x00, 0xf1, 0xf9, 0x01, 0xff, 0xf8, 0xf3, 0x00, 0x12, 0x13, + 0x07, 0x19, 0x10, 0x0c, 0x05, 0x10, 0x05, 0x01, 0x01, 0x00, 0xff, 0x00, + 0x05, 0x11, 0x0d, 0x03, 0x03, 0x08, 0x00, 0xf3, 0xf0, 0x00, 0xfe, 0xf7, + 0x07, 0x16, 0x13, 0x11, 0x07, 0x02, 0x0c, 0xfd, 0xf2, 0xfd, 0x04, 0x01, + 0x06, 0x05, 0x07, 0x09, 0x09, 0x14, 0x1f, 0x19, 0x10, 0x13, 0x1a, 0x22, + 0x1b, 0x19, 0x14, 0x0e, 0x0d, 0x0f, 0x0e, 0x0d, 0x08, 0x01, 0x00, 0x00, + 0xf9, 0x01, 0x0d, 0x0e, 0x13, 0x13, 0x0c, 0x0d, 0x0f, 0x0e, 0x12, 0x19, + 0x1a, 0x18, 0x1c, 0x24, 0x14, 0xfd, 0x05, 0x1c, 0x11, 0x05, 0x0c, 0x0c, + 0x06, 0x06, 0x03, 0x04, 0x02, 0x09, 0x16, 0x1a, 0x1d, 0x1f, 0x10, 0x06, + 0x07, 0x08, 0x04, 0xfd, 0xfb, 0x03, 0x0c, 0x12, 0x0d, 0xfe, 0x03, 0x11, + 0x1a, 0x16, 0x0d, 0x0c, 0x16, 0x12, 0x0d, 0x11, 0x0f, 0x0e, 0x13, 0x10, + 0x0d, 0x0c, 0x05, 0x00, 0x03, 0x00, 0x04, 0x13, 0x14, 0x11, 0x13, 0x0d, + 0x08, 0x08, 0x12, 0x05, 0x05, 0x11, 0x00, 0xfb, 0x02, 0x03, 0x05, 0x05, + 0x03, 0x03, 0x04, 0x02, 0xfe, 0xfe, 0xff, 0x09, 0x07, 0x04, 0x08, 0xff, + 0xfc, 0x02, 0x03, 0x08, 0x0c, 0xfa, 0xfa, 0xfe, 0xf1, 0xfe, 0xf0, 0xfd, + 0x05, 0xfa, 0xef, 0xf8, 0x04, 0x03, 0xfa, 0xff, 0x0e, 0x06, 0xfe, 0x07, + 0x03, 0xfb, 0xfb, 0x04, 0x03, 0xf8, 0xed, 0xea, 0xf9, 0xfe, 0xfc, 0xfb, + 0xf3, 0xff, 0x0c, 0xf9, 0xf8, 0xfb, 0xfe, 0xfc, 0xf4, 0xf8, 0x04, 0x02, + 0xfb, 0xfd, 0xee, 0xea, 0xf1, 0xe8, 0xe1, 0xed, 0xfa, 0xf1, 0xf2, 0xfb, + 0xfb, 0xfb, 0x00, 0xfb, 0xf0, 0xf4, 0xfb, 0xf8, 0xf4, 0xea, 0xe4, 0xea, + 0xef, 0xee, 0xed, 0xf4, 0xfc, 0xf4, 0xe7, 0xef, 0xfa, 0xf9, 0xf8, 0xfe, + 0x09, 0x01, 0xfa, 0xf7, 0xef, 0xe4, 0xe2, 0xe6, 0xe6, 0xf2, 0xf9, 0xea, + 0xfb, 0xfe, 0xf0, 0xf1, 0xf2, 0xf8, 0xf9, 0xf3, 0xef, 0xf1, 0xf2, 0xf2, + 0xfb, 0x00, 0xf2, 0xee, 0xed, 0xdc, 0xdc, 0xe5, 0xed, 0xee, 0xe4, 0xe4, + 0xee, 0xee, 0xe8, 0xf1, 0xf0, 0xe5, 0xe4, 0xe5, 0xe6, 0xe1, 0xed, 0xfa, + 0xfc, 0xfc, 0xfb, 0xf2, 0xee, 0xf0, 0xf2, 0xf1, 0xf4, 0xf3, 0xee, 0xea, + 0xe1, 0xdc, 0xe8, 0xea, 0xea, 0xf1, 0xf2, 0xec, 0xef, 0xfc, 0xfd, 0xff, + 0xff, 0x02, 0x01, 0xf2, 0xfa, 0xf4, 0xf3, 0xf2, 0xf1, 0xee, 0xea, 0xea, + 0xf0, 0xf2, 0xf7, 0xf9, 0xef, 0xf0, 0xee, 0xea, 0xf4, 0xfc, 0x03, 0x06, + 0x03, 0xfe, 0xfc, 0xfa, 0xf1, 0xec, 0xf2, 0xf2, 0xf7, 0xf4, 0xf7, 0xfe, + 0xff, 0xfb, 0xfe, 0x05, 0xfb, 0xfc, 0x07, 0x06, 0x09, 0x01, 0x04, 0x03, + 0xfc, 0xfc, 0xff, 0x00, 0xf8, 0xf2, 0xee, 0xed, 0xf1, 0xf3, 0xfe, 0x03, + 0x07, 0x0e, 0x0e, 0x0d, 0x0e, 0x05, 0x08, 0x19, 0x11, 0x02, 0x01, 0x00, + 0xfc, 0xfd, 0x07, 0x0c, 0xf9, 0xff, 0x03, 0x04, 0x08, 0x07, 0x06, 0x0f, + 0x16, 0x18, 0x16, 0x12, 0x03, 0xfe, 0xff, 0x00, 0xfe, 0xf7, 0xfa, 0x00, + 0xfe, 0x00, 0x05, 0x08, 0x0e, 0x0c, 0x0f, 0x0f, 0x04, 0x08, 0x13, 0x19, + 0x0d, 0x0c, 0x0c, 0x0c, 0x09, 0x10, 0x0e, 0x06, 0x0f, 0x12, 0x09, 0x04, + 0x10, 0x14, 0x0d, 0x0c, 0x0e, 0x01, 0x08, 0x19, 0x0d, 0x06, 0x19, 0x14, + 0x0d, 0x05, 0x10, 0x13, 0x19, 0x16, 0x0f, 0x0f, 0x10, 0x10, 0x07, 0x06, + 0x10, 0x0e, 0x06, 0x0c, 0x0f, 0x07, 0x0e, 0x0d, 0x07, 0x14, 0x16, 0x0f, + 0x10, 0x11, 0x10, 0x10, 0x0e, 0x07, 0x07, 0x0d, 0x11, 0x07, 0x0c, 0x09, + 0x05, 0x0d, 0x14, 0x1a, 0x1c, 0x18, 0x11, 0x10, 0x11, 0x19, 0x1f, 0x19, + 0x10, 0x0c, 0x09, 0x0f, 0x10, 0x10, 0x0f, 0x0d, 0x08, 0x0d, 0x18, 0x10, + 0x10, 0x13, 0x12, 0x10, 0x13, 0x12, 0x13, 0x16, 0x09, 0x05, 0x04, 0x01, + 0x05, 0x05, 0x01, 0x00, 0x05, 0x01, 0xf9, 0x01, 0x03, 0x08, 0x06, 0x00, + 0xff, 0x00, 0x00, 0x03, 0x03, 0x04, 0x09, 0x01, 0xfd, 0xf1, 0xf8, 0xfc, + 0xf7, 0xff, 0xff, 0xf9, 0xfd, 0x02, 0xfb, 0xf3, 0xfd, 0x01, 0xfe, 0x01, + 0xff, 0xfb, 0xfb, 0xfc, 0xff, 0xfa, 0xff, 0x03, 0xfc, 0xf8, 0xfa, 0xf7, + 0xf2, 0xfc, 0xfb, 0xf1, 0xf8, 0xee, 0xee, 0xf2, 0xf1, 0xec, 0xf1, 0xf3, + 0xf7, 0xfe, 0xfe, 0xf8, 0xf2, 0xef, 0xfd, 0xfe, 0xf2, 0xf1, 0xef, 0xf0, + 0xf1, 0xed, 0xee, 0xec, 0xf2, 0xf2, 0xe5, 0xee, 0xf8, 0xf1, 0xed, 0xee, + 0xf1, 0xef, 0xf0, 0xfb, 0xfb, 0xf4, 0xf2, 0xee, 0xf1, 0xf2, 0xe8, 0xed, + 0xf1, 0xe8, 0xee, 0xf3, 0xea, 0xf1, 0xfd, 0xf8, 0xf3, 0xf8, 0xf8, 0xfa, + 0xee, 0xf0, 0xef, 0xf0, 0xee, 0xef, 0xf2, 0xf2, 0xed, 0xef, 0xee, 0xed, + 0xf2, 0xf8, 0xee, 0xf0, 0xf3, 0xf1, 0xfa, 0xf9, 0xf9, 0xfb, 0xfc, 0xf4, + 0xf2, 0xf7, 0xfb, 0xfd, 0xf8, 0xf4, 0xf9, 0x00, 0x03, 0x02, 0xfe, 0xf8, + 0xf7, 0xfc, 0x00, 0x02, 0x05, 0x05, 0x05, 0xfe, 0xfd, 0xfc, 0xfe, 0x03, + 0x05, 0x07, 0xff, 0xf9, 0xfa, 0xff, 0x01, 0x01, 0x00, 0xfc, 0xfd, 0x04, + 0x09, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfb, 0xfc, 0x04, 0x06, 0x01, + 0x02, 0x05, 0x03, 0x08, 0x08, 0x08, 0x01, 0xfb, 0xfb, 0xfd, 0xfd, 0xf8, + 0xf8, 0xfe, 0xfb, 0xfd, 0x07, 0x05, 0xfd, 0x00, 0x03, 0x05, 0x05, 0x08, + 0x03, 0x03, 0x08, 0x06, 0x06, 0x05, 0x00, 0x01, 0x04, 0x08, 0x0d, 0x0e, + 0x06, 0x00, 0xfe, 0x02, 0x02, 0x03, 0x02, 0xff, 0xfd, 0xf9, 0xf4, 0x03, + 0x00, 0xfd, 0x03, 0x08, 0x04, 0x03, 0x06, 0x07, 0x06, 0x00, 0x00, 0x04, + 0x01, 0x01, 0x07, 0x05, 0x02, 0x01, 0x00, 0xf9, 0xfa, 0xfe, 0xff, 0xfe, + 0xfc, 0x01, 0x03, 0x05, 0x06, 0x00, 0x05, 0x04, 0x01, 0x03, 0x00, 0xfe, + 0xff, 0x01, 0x01, 0xff, 0x01, 0xff, 0xf7, 0xfd, 0xff, 0x03, 0x04, 0x06, + 0x08, 0x05, 0x01, 0x02, 0x07, 0x08, 0x02, 0xfe, 0xfe, 0xfa, 0xfe, 0x02, + 0xfd, 0x00, 0x03, 0x04, 0x03, 0xfe, 0xf9, 0xfa, 0x01, 0x03, 0x04, 0x0c, + 0x07, 0xfd, 0xfa, 0xf8, 0xfb, 0xfe, 0xff, 0xff, 0xfd, 0xfb, 0xfc, 0xfd, + 0xff, 0x00, 0x00, 0xff, 0x03, 0x04, 0x04, 0x01, 0x01, 0x01, 0x00, 0xfd, + 0xff, 0x01, 0xfe, 0x00, 0x02, 0x01, 0xff, 0x03, 0x04, 0x02, 0x00, 0x01, + 0xfc, 0xfa, 0xfd, 0xfe, 0xff, 0xfe, 0xfc, 0xfd, 0xfe, 0x01, 0x06, 0x0d, + 0x09, 0x02, 0x03, 0x04, 0x02, 0xfd, 0xff, 0x03, 0x03, 0x04, 0x05, 0x00, + 0x02, 0x02, 0x03, 0x03, 0x03, 0x05, 0x04, 0x00, 0x01, 0x03, 0x02, 0x05, + 0x08, 0x0e, 0x08, 0x04, 0x04, 0x05, 0x05, 0x02, 0x07, 0x0c, 0x07, 0x07, + 0x07, 0x09, 0x09, 0x04, 0x02, 0x03, 0x09, 0x08, 0x0e, 0x10, 0x09, 0x09, + 0x06, 0x00, 0xfc, 0xfd, 0x03, 0x05, 0xfd, 0xfb, 0x02, 0x01, 0x06, 0x12, + 0x16, 0x0c, 0x05, 0x02, 0xff, 0xfc, 0xfb, 0xf9, 0xfd, 0x03, 0x01, 0x00, + 0x01, 0x03, 0x00, 0xfc, 0xfc, 0xfe, 0xff, 0x00, 0x04, 0x09, 0x05, 0x04, + 0x02, 0x02, 0x01, 0x01, 0x00, 0xfe, 0x04, 0x03, 0x00, 0x03, 0x02, 0x00, + 0x00, 0x02, 0x03, 0x03, 0xfe, 0xfe, 0x00, 0x02, 0x05, 0x01, 0x00, 0x00, + 0xfb, 0xfc, 0xfe, 0xfb, 0xfa, 0xfb, 0xfc, 0xff, 0x02, 0x01, 0x00, 0xff, + 0xfc, 0xf3, 0xf8, 0xfe, 0xfe, 0xff, 0xff, 0xfc, 0xf9, 0xf7, 0xf9, 0xf4, + 0xfb, 0xfc, 0xf9, 0xfa, 0xfb, 0xf9, 0xfb, 0xfd, 0xfb, 0xfc, 0xff, 0x01, + 0xfc, 0xf3, 0xf4, 0xfc, 0xff, 0xfd, 0xf7, 0xf9, 0xfb, 0xfb, 0xf8, 0xf4, + 0xf4, 0xfc, 0xff, 0xfe, 0xfe, 0xfe, 0xff, 0xf8, 0xfa, 0xfc, 0xf9, 0xfc, + 0xfe, 0xf9, 0xf9, 0xfe, 0xfb, 0xf7, 0xfa, 0xfc, 0xfc, 0xf7, 0xf8, 0xf9, + 0xf9, 0xf9, 0xf9, 0xfd, 0xff, 0xfd, 0xfa, 0xf9, 0xf8, 0xf7, 0xf4, 0xf3, + 0xf7, 0xf8, 0xfc, 0xff, 0x00, 0xfe, 0xfb, 0xfa, 0xfb, 0xff, 0xfe, 0xfd, + 0xff, 0xfb, 0xf3, 0xf7, 0xf3, 0xf4, 0xf8, 0xfe, 0x04, 0x04, 0xfc, 0xf7, + 0xfa, 0xfe, 0xff, 0xfd, 0xfe, 0x00, 0xfd, 0xfe, 0xfc, 0xf8, 0xf3, 0xfa, + 0xfe, 0xfe, 0xfa, 0xfb, 0xfc, 0xfa, 0xfc, 0x01, 0xff, 0xfc, 0xf9, 0xfa, + 0xfc, 0xff, 0xfb, 0xf2, 0xf3, 0xf7, 0xfb, 0xfc, 0xfa, 0xfb, 0xf4, 0xf2, + 0xef, 0xf1, 0xf4, 0xf1, 0xea, 0xed, 0xf3, 0xfc, 0xfd, 0xfc, 0xff, 0xff, + 0xfc, 0xfd, 0xfc, 0xf4, 0xf8, 0xfc, 0xf9, 0xfa, 0xf4, 0xed, 0xf0, 0xfb, + 0xfb, 0xf1, 0xef, 0xfa, 0x04, 0x08, 0x07, 0x01, 0xfe, 0x01, 0x02, 0xfe, + 0xfc, 0xfd, 0xfc, 0xf7, 0xf2, 0xf8, 0xf8, 0xf9, 0xfa, 0xf7, 0xf9, 0xfb, + 0xfe, 0xfe, 0xff, 0xfe, 0x00, 0x03, 0x04, 0x03, 0x05, 0x00, 0xfc, 0xfc, + 0xff, 0xfd, 0xfc, 0xfd, 0x00, 0xff, 0xfe, 0xfd, 0xfd, 0xfd, 0xff, 0xfd, + 0xfd, 0xfe, 0xfe, 0xfd, 0xf9, 0xfc, 0x02, 0x05, 0x03, 0x01, 0xfd, 0xfc, + 0xfe, 0xfd, 0x04, 0x0c, 0x06, 0x08, 0x08, 0x07, 0x03, 0x02, 0x02, 0x01, + 0x01, 0xff, 0x00, 0x06, 0x04, 0x00, 0x06, 0x0d, 0x0e, 0x0e, 0x0e, 0x0c, + 0x08, 0x0c, 0x0e, 0x0d, 0x0e, 0x0f, 0x09, 0x05, 0x03, 0x04, 0x04, 0xfc, + 0x00, 0x08, 0x0c, 0x09, 0x0c, 0x11, 0x18, 0x18, 0x13, 0x14, 0x0f, 0x08, + 0x08, 0x08, 0x07, 0x06, 0x06, 0x06, 0x07, 0x07, 0x03, 0x03, 0x05, 0x08, + 0x0e, 0x11, 0x13, 0x12, 0x13, 0x12, 0x0f, 0x0e, 0x0c, 0x08, 0x07, 0x05, + 0x07, 0x07, 0x08, 0x06, 0x06, 0x04, 0x03, 0x05, 0x08, 0x05, 0x02, 0x08, + 0x0e, 0x09, 0x09, 0x0e, 0x0c, 0x10, 0x11, 0x0e, 0x0e, 0x0d, 0x09, 0x04, + 0x04, 0x07, 0x04, 0x01, 0x03, 0x06, 0x03, 0xfe, 0xfc, 0xfe, 0x01, 0x03, + 0x08, 0x0c, 0x0c, 0x08, 0x07, 0x06, 0x05, 0x03, 0x02, 0x02, 0x02, 0x01, + 0x01, 0xfe, 0xf8, 0xfc, 0xff, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x05, + 0x04, 0x00, 0xfc, 0xf8, 0xf4, 0xfb, 0xff, 0xfd, 0xf8, 0xfd, 0x01, 0x01, + 0x00, 0x00, 0x00, 0xfd, 0xfe, 0x00, 0x00, 0x03, 0x00, 0xfb, 0xfb, 0xfb, + 0xfa, 0xfc, 0xff, 0xfe, 0xfe, 0xfe, 0xff, 0xfd, 0xff, 0x00, 0x00, 0x00, + 0xfe, 0xfe, 0xfc, 0xfe, 0x00, 0x01, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0xfd, 0xff, 0x00, 0xfc, 0xfb, 0xfe, 0xff, 0x00, 0x02, 0x00, 0xfe, + 0xfe, 0xfb, 0xfb, 0xfc, 0xfb, 0xfd, 0xfe, 0xfe, 0x00, 0xff, 0xfb, 0xfc, + 0x00, 0x00, 0xff, 0xfc, 0xfc, 0xfe, 0xfe, 0xfb, 0xfc, 0x00, 0x03, 0x02, + 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfe, 0xfd, 0xfb, + 0xfc, 0xfd, 0xf9, 0xf6, 0xf7, 0xf7, 0xf7, 0xfb, 0xfd, 0xfd, 0xfd, 0x00, + 0x02, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0xfd, 0xfd, 0xff, 0x00, 0x00, + 0x00, 0xfc, 0xfb, 0xfa, 0xfb, 0xfe, 0xff, 0xfe, 0xfe, 0xff, 0x00, 0x00, + 0x00, 0x01, 0x00, 0xfd, 0xf8, 0xf5, 0xf7, 0xfa, 0xfd, 0xfe, 0xfe, 0xfd, + 0xfe, 0x00, 0x00, 0xfe, 0xfd, 0xfe, 0xfc, 0xff, 0x02, 0x02, 0x03, 0x04, + 0x00, 0xfe, 0xfe, 0xfd, 0xfd, 0xfe, 0xfd, 0xfe, 0xff, 0x00, 0x00, 0xff, + 0xfe, 0xfe, 0xff, 0xff, 0xfe, 0xff, 0x01, 0x03, 0x01, 0x01, 0x04, 0x04, + 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x04, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0xff, + 0xfd, 0xfc, 0xfc, 0xfd, 0xfe, 0xff, 0x00, 0x02, 0x05, 0x05, 0x05, 0x02, + 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x03, 0x04, 0x01, 0x00, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x04, 0x07, 0x04, 0x01, 0x01, 0x01, + 0x00, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x01, 0x02, 0x01, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xfc, 0xfe, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xfd, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, + 0xfe, 0xfd, 0xfd, 0xff, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0xff, 0xfe, 0xfe, + 0xfe, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0xff, + 0x00, 0xff, 0xff, 0xfe, 0xfe, 0xfc, 0xfe, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xfe, + 0xff, 0xff, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, + 0x01, 0x0a, 0x0e, 0x0b, 0x08, 0x06, 0x07, 0x06, 0xf8, 0x02, 0x09, 0x09, + 0x07, 0x0e, 0x0e, 0x09, 0x11, 0x06, 0x00, 0x0a, 0x0f, 0x09, 0xfd, 0xfa, + 0xfb, 0xfc, 0xf6, 0xf9, 0xfc, 0xfc, 0xfb, 0xff, 0xfb, 0xf8, 0xfc, 0xfc, + 0xff, 0x01, 0x04, 0x07, 0x04, 0x04, 0xff, 0x01, 0x00, 0xfb, 0x00, 0x05, + 0x09, 0x09, 0x03, 0x05, 0x0e, 0x11, 0x0d, 0x07, 0x04, 0x14, 0x03, 0xfd, + 0x07, 0x0d, 0x0d, 0x08, 0x00, 0xfb, 0x04, 0x0c, 0x02, 0xfe, 0xfd, 0xfd, + 0x00, 0xf8, 0xf7, 0xff, 0x07, 0x02, 0xfc, 0xfe, 0xf5, 0xfb, 0xfd, 0xfc, + 0x02, 0xfd, 0x01, 0x06, 0x03, 0x0d, 0x11, 0x01, 0xf6, 0xff, 0x11, 0x07, + 0x08, 0x03, 0xff, 0x10, 0x0e, 0x09, 0x05, 0x03, 0x02, 0xf5, 0xfa, 0x00, + 0xfc, 0x07, 0x05, 0x05, 0x07, 0x02, 0x03, 0x09, 0x06, 0x01, 0x06, 0xff, + 0xfa, 0xfc, 0x00, 0xfb, 0xfc, 0xf7, 0xfa, 0xfb, 0xfb, 0xf1, 0xf6, 0x03, + 0xfa, 0x05, 0x07, 0x07, 0x19, 0x0e, 0x0d, 0x0a, 0x07, 0x03, 0x10, 0x12, + 0x08, 0x08, 0x0b, 0x11, 0x15, 0x13, 0x09, 0x08, 0x0c, 0xff, 0x00, 0x00, + 0x01, 0x06, 0x08, 0x05, 0xf9, 0xf0, 0xf6, 0xfe, 0xfc, 0xfa, 0xf5, 0xfb, + 0xfe, 0xff, 0xf8, 0xef, 0xf6, 0xf9, 0xf9, 0xf5, 0xf4, 0xf5, 0xf5, 0xfc, + 0x00, 0x02, 0x04, 0x0a, 0x0d, 0x1e, 0x0c, 0xfb, 0x02, 0x10, 0x13, 0x0f, + 0x08, 0x01, 0x09, 0x11, 0x11, 0x0f, 0x09, 0x11, 0x0c, 0x01, 0xfb, 0xfe, + 0x02, 0x02, 0x07, 0x09, 0x02, 0x01, 0xfc, 0xfd, 0x03, 0x02, 0x01, 0x01, + 0x00, 0x02, 0xfc, 0xf7, 0xf5, 0xfe, 0xfd, 0xf3, 0xef, 0xfa, 0x0d, 0x04, + 0x08, 0x0c, 0x0a, 0x13, 0x0b, 0x07, 0x05, 0xf8, 0xf8, 0xfb, 0x06, 0x08, + 0xff, 0x04, 0x0f, 0x13, 0x10, 0x04, 0x0d, 0x0a, 0x01, 0xfa, 0xf7, 0xfc, + 0xfc, 0x00, 0xfe, 0xfb, 0x01, 0xfe, 0xfe, 0xfd, 0x03, 0x08, 0x09, 0x08, + 0x09, 0xfb, 0xf2, 0xf5, 0xf9, 0xf5, 0xf7, 0xf7, 0xf6, 0xfa, 0xfc, 0xf9, + 0x00, 0xfc, 0x0e, 0x0e, 0x0a, 0x05, 0x03, 0x08, 0x0f, 0x14, 0x18, 0x0e, + 0x03, 0x0b, 0x0e, 0x08, 0x0a, 0x03, 0x0e, 0x0d, 0x09, 0x09, 0x0e, 0x08, + 0x04, 0x05, 0x08, 0x03, 0x07, 0x06, 0x00, 0x00, 0x01, 0xfc, 0xfc, 0xfa, + 0xfd, 0xf7, 0xf5, 0xf2, 0x00, 0x02, 0xfd, 0xf9, 0xfd, 0xf7, 0xed, 0xf4, + 0xf8, 0x00, 0x11, 0x0d, 0x02, 0x02, 0xfd, 0x00, 0x0b, 0x12, 0x09, 0xff, + 0x01, 0x03, 0x0e, 0x0b, 0x08, 0x0e, 0x08, 0xfd, 0xfe, 0x02, 0x04, 0x00, + 0xfe, 0xfb, 0xf8, 0xfe, 0x02, 0x00, 0x04, 0x07, 0x08, 0x00, 0xfe, 0x06, + 0x07, 0xf8, 0xf9, 0x04, 0x00, 0x05, 0x05, 0xfb, 0xfe, 0x05, 0x04, 0xfb, + 0x08, 0x16, 0x0e, 0x10, 0x06, 0x04, 0x03, 0x00, 0xfb, 0x09, 0x0b, 0x07, + 0x0b, 0x0e, 0x07, 0x00, 0xf9, 0x01, 0xfe, 0x03, 0x03, 0x07, 0x05, 0x04, + 0x06, 0x02, 0x01, 0x01, 0xf7, 0xfb, 0x04, 0x0a, 0x09, 0x0a, 0xf5, 0xf6, + 0xf9, 0xf8, 0xfa, 0x06, 0x01, 0x05, 0xfd, 0x05, 0x08, 0x00, 0xfe, 0xfd, + 0x06, 0x10, 0x07, 0x00, 0xfa, 0x01, 0x06, 0x03, 0x08, 0x0c, 0x05, 0x0b, + 0x0c, 0x0d, 0x09, 0x06, 0x0f, 0x0a, 0x00, 0x00, 0x02, 0x04, 0x09, 0x09, + 0x03, 0xf9, 0xfe, 0x05, 0xf4, 0xe8, 0xf4, 0x02, 0x08, 0xff, 0x00, 0xfe, + 0xfc, 0xfd, 0xff, 0xef, 0xee, 0xf1, 0xee, 0xfb, 0xfc, 0xfa, 0xfc, 0x04, + 0x15, 0x13, 0x0c, 0x07, 0x05, 0x09, 0x14, 0x17, 0x14, 0x11, 0x0c, 0x14, + 0x1a, 0x0e, 0x07, 0x11, 0x11, 0x06, 0x06, 0x03, 0x01, 0x04, 0x06, 0xfa, + 0xfd, 0x04, 0xff, 0xff, 0xff, 0xf3, 0xf7, 0xfa, 0x03, 0x04, 0xfc, 0xef, + 0xf4, 0xef, 0xf0, 0xf9, 0xfc, 0xfa, 0xfc, 0x08, 0x02, 0x03, 0x01, 0x09, + 0x12, 0x08, 0xfe, 0xf9, 0xfe, 0x02, 0x00, 0x00, 0x0f, 0x12, 0x1b, 0x1a, + 0x0c, 0x0c, 0x0d, 0x12, 0x0b, 0x0a, 0x07, 0x00, 0xf9, 0xf3, 0xf4, 0xf5, + 0x02, 0x0f, 0xff, 0xf1, 0xec, 0xf7, 0xff, 0xfe, 0xfe, 0xf9, 0xf2, 0xfe, + 0xfb, 0xfa, 0xf6, 0xf7, 0xf9, 0xf9, 0x1a, 0x13, 0xff, 0xfe, 0xfe, 0x0e, + 0x17, 0x17, 0x13, 0x15, 0x0e, 0xff, 0x04, 0x0b, 0x07, 0x12, 0x18, 0x06, + 0x07, 0x08, 0x08, 0x0d, 0x0e, 0x09, 0x11, 0x13, 0x08, 0x04, 0x08, 0x04, + 0x08, 0x09, 0xff, 0xf9, 0xf5, 0xe3, 0xe5, 0xf3, 0xef, 0xef, 0xf4, 0xf3, + 0xf8, 0xf6, 0xef, 0xf2, 0xed, 0xea, 0x03, 0x01, 0xf9, 0xfe, 0x05, 0xff, + 0xfc, 0x09, 0x0c, 0x07, 0x0b, 0x06, 0x04, 0x0f, 0x0a, 0x0e, 0x19, 0x1f, + 0x18, 0x0d, 0x0c, 0x0f, 0x13, 0x0e, 0x04, 0x00, 0xfc, 0x00, 0xfe, 0xfb, + 0xf9, 0x02, 0x05, 0xff, 0xff, 0x05, 0x01, 0xfd, 0x04, 0x02, 0x00, 0x06, + 0x05, 0x00, 0xfe, 0xf5, 0xf7, 0x05, 0x10, 0x08, 0x03, 0x08, 0x15, 0x12, + 0x04, 0x02, 0x03, 0x07, 0x0e, 0x10, 0x07, 0x06, 0x02, 0xfe, 0x04, 0x0e, + 0x02, 0xff, 0xfb, 0xf8, 0x04, 0x0e, 0x05, 0xff, 0xfe, 0xfe, 0xf8, 0xfe, + 0xf9, 0xf4, 0xf1, 0xf0, 0xe3, 0xe7, 0xf2, 0xf5, 0xee, 0xf6, 0xf7, 0xfe, + 0xff, 0xfc, 0x03, 0xf6, 0xf2, 0x13, 0x1f, 0x19, 0x10, 0x0a, 0x0e, 0x13, + 0x10, 0x0e, 0x0a, 0x08, 0x06, 0x06, 0x0e, 0x12, 0x0d, 0x09, 0x0d, 0x0e, + 0x0b, 0x0d, 0x0e, 0x13, 0x15, 0x12, 0x08, 0x01, 0x09, 0x07, 0x00, 0xf7, + 0xf6, 0xf8, 0xfc, 0xfe, 0xfb, 0xee, 0xee, 0xfc, 0xfe, 0xf6, 0xed, 0xed, + 0xe6, 0xe5, 0xe3, 0xde, 0xed, 0x0b, 0x13, 0x15, 0x0c, 0x0a, 0x10, 0x09, + 0x09, 0x06, 0x08, 0x0f, 0x16, 0x1d, 0x1c, 0x1b, 0x14, 0x12, 0x0f, 0x12, + 0x0f, 0x0e, 0x16, 0x13, 0x0e, 0x02, 0xf9, 0xfb, 0xfa, 0xf9, 0xfb, 0xfc, + 0xf6, 0xf0, 0xf4, 0xf5, 0xef, 0xe6, 0xe8, 0xeb, 0xf5, 0xf3, 0xf8, 0xfd, + 0x01, 0xfd, 0xf7, 0xf9, 0x14, 0x28, 0x1a, 0x0b, 0x09, 0x07, 0x08, 0x00, + 0x00, 0x0a, 0x0d, 0x0e, 0x0e, 0x0d, 0x16, 0x17, 0x09, 0x07, 0x0d, 0x18, + 0x12, 0x06, 0x02, 0x04, 0x07, 0xfe, 0xf5, 0xf6, 0xf3, 0xf9, 0xf8, 0xf9, + 0xf8, 0xf0, 0xee, 0xee, 0xf4, 0xf9, 0xf8, 0xf4, 0xf2, 0xf8, 0xf8, 0xf0, + 0xf8, 0xf8, 0xed, 0xf8, 0x19, 0x19, 0x1a, 0x19, 0x12, 0x15, 0x13, 0x11, + 0x15, 0x18, 0x0a, 0x05, 0x06, 0x03, 0x1c, 0x1e, 0x0d, 0x0c, 0x0d, 0x15, + 0x16, 0x0e, 0x07, 0x0c, 0x0b, 0x05, 0x0a, 0x09, 0x06, 0x07, 0xfc, 0xf4, + 0xf4, 0xfc, 0xff, 0xf7, 0xee, 0xe8, 0xe3, 0xe5, 0xe7, 0xf4, 0xe5, 0xe2, + 0xe2, 0xde, 0xe3, 0xfc, 0x19, 0x0a, 0x02, 0x05, 0x05, 0x06, 0xfd, 0x00, + 0x04, 0x07, 0x09, 0x19, 0x1b, 0x1b, 0x32, 0x32, 0x25, 0x23, 0x21, 0x1c, + 0x0d, 0x0a, 0x02, 0x05, 0xfe, 0xfb, 0xfe, 0xfd, 0x01, 0x08, 0x06, 0xfe, + 0xf5, 0xf2, 0xf2, 0xf7, 0xf2, 0xed, 0xef, 0xf2, 0xf6, 0xf5, 0xf5, 0xf3, + 0xe8, 0xe7, 0xf2, 0x20, 0x23, 0x11, 0x07, 0x01, 0x0b, 0x14, 0x0d, 0x06, + 0x0b, 0x0a, 0x03, 0xfe, 0xf8, 0xfa, 0x15, 0x1e, 0x15, 0x10, 0x12, 0x0a, + 0x0b, 0x0e, 0x08, 0x04, 0xfc, 0xfc, 0x03, 0xfc, 0xf1, 0xea, 0xeb, 0xe7, + 0xef, 0xf2, 0xf7, 0x02, 0xff, 0x00, 0x03, 0xf9, 0xfc, 0xfc, 0xf9, 0xef, + 0xf0, 0xf1, 0x01, 0x1f, 0x15, 0x11, 0x0f, 0x0c, 0x13, 0x17, 0x10, 0x0f, + 0x0e, 0x10, 0x0d, 0x00, 0x02, 0x01, 0x11, 0x15, 0x0f, 0x19, 0x21, 0x10, + 0x01, 0xfd, 0x07, 0x0c, 0x10, 0x0c, 0x02, 0x01, 0x06, 0x08, 0xff, 0xf8, + 0xfb, 0x00, 0xfc, 0xf7, 0xf5, 0xf1, 0xe4, 0xde, 0xe5, 0xe4, 0xe3, 0xe3, + 0xea, 0xf1, 0x11, 0x0e, 0xff, 0xfa, 0xfc, 0x03, 0x07, 0x05, 0x04, 0x05, + 0x00, 0x05, 0x10, 0x0e, 0x0b, 0x0c, 0x1c, 0x1a, 0x10, 0x1a, 0x1d, 0x11, + 0x0f, 0x09, 0x00, 0xfb, 0xfc, 0x00, 0x0b, 0x0a, 0x04, 0x01, 0x00, 0xfc, + 0x02, 0xff, 0xf8, 0xfd, 0x02, 0xfa, 0xff, 0x07, 0xf7, 0xf1, 0xf3, 0xf7, + 0xfe, 0x0a, 0x21, 0x14, 0x10, 0x0b, 0x01, 0x07, 0x11, 0x12, 0x12, 0x10, + 0x08, 0x02, 0x00, 0xff, 0xfb, 0xff, 0x0e, 0x0a, 0x06, 0x05, 0xfc, 0xfb, + 0xfa, 0xf8, 0xf7, 0xf8, 0xf6, 0xf2, 0xf2, 0xf3, 0xf5, 0xf1, 0xec, 0xe6, + 0xea, 0xff, 0x17, 0x12, 0x01, 0xfa, 0xfa, 0xfa, 0xfd, 0xf8, 0xf1, 0xf9, + 0xff, 0x20, 0x27, 0x1d, 0x17, 0x1c, 0x14, 0x0e, 0x14, 0x12, 0x0f, 0x07, + 0x06, 0x0b, 0x0b, 0x06, 0x04, 0x08, 0x19, 0x1b, 0x1f, 0x13, 0x0d, 0x10, + 0x0b, 0x04, 0x01, 0x06, 0x06, 0x04, 0x01, 0xfd, 0xf4, 0xf0, 0xf7, 0xf7, + 0xf2, 0xf3, 0xf0, 0xee, 0xec, 0xe8, 0xe2, 0xdc, 0xda, 0xd7, 0xe7, 0xf8, + 0x05, 0x07, 0xfa, 0x00, 0x00, 0x04, 0x00, 0x04, 0x11, 0x0f, 0x05, 0x0e, + 0x27, 0x28, 0x21, 0x18, 0x0e, 0x11, 0x1e, 0x1f, 0x16, 0x0c, 0x0b, 0x0b, + 0x0e, 0x09, 0x04, 0x02, 0xff, 0x07, 0x0c, 0x04, 0xf9, 0xf7, 0xf7, 0xf7, + 0xfa, 0xef, 0xe7, 0xe6, 0xe7, 0xe8, 0xe3, 0xe7, 0xed, 0xe6, 0xe2, 0xf1, + 0x10, 0x08, 0x09, 0x0f, 0x09, 0x07, 0x0a, 0x2e, 0x33, 0x1f, 0x17, 0x1a, + 0x13, 0x0d, 0x0a, 0x0a, 0x06, 0x13, 0x23, 0x1c, 0x1a, 0x1a, 0x16, 0x0e, + 0x0c, 0x07, 0xff, 0xf7, 0xf6, 0xf9, 0xfd, 0xf5, 0xeb, 0xe9, 0xf0, 0x07, + 0x06, 0xf1, 0xf3, 0xf8, 0xf1, 0xea, 0xe6, 0xe5, 0xdf, 0xe4, 0xe8, 0x07, + 0x0d, 0x01, 0xf8, 0xfa, 0x00, 0x03, 0x01, 0x09, 0x14, 0x0f, 0x0a, 0x05, + 0xff, 0xfc, 0xfe, 0x19, 0x1b, 0x20, 0x2b, 0x23, 0x15, 0x10, 0x12, 0x17, + 0x08, 0x00, 0x04, 0x03, 0x06, 0x16, 0x15, 0x05, 0xfc, 0xfe, 0x02, 0xfc, + 0xf9, 0xee, 0xef, 0xef, 0xf2, 0xe9, 0xe6, 0xe4, 0xdf, 0xdf, 0xfc, 0x19, + 0x06, 0xfd, 0xfd, 0xfa, 0xfd, 0x06, 0x08, 0x12, 0x15, 0x0a, 0x10, 0x10, + 0x10, 0x12, 0x13, 0x0d, 0x0e, 0x1d, 0x23, 0x1d, 0x10, 0x07, 0x03, 0x15, + 0x21, 0x09, 0xf9, 0xfa, 0xff, 0xfb, 0xfb, 0xff, 0xf9, 0xfe, 0xfb, 0xf3, + 0xf0, 0xf4, 0x04, 0x01, 0xf8, 0xf5, 0xf6, 0xef, 0xea, 0xf1, 0x0e, 0x06, + 0xff, 0x03, 0x0a, 0x08, 0x0b, 0x0f, 0x0e, 0x13, 0x17, 0x11, 0x0a, 0x02, + 0xfb, 0xf9, 0xfa, 0xf9, 0xfa, 0x08, 0x02, 0xfc, 0x01, 0xfe, 0xf8, 0xf3, + 0xf5, 0xf6, 0xed, 0xea, 0xea, 0xe9, 0xea, 0xfc, 0x1b, 0x20, 0x1c, 0x0e, + 0x03, 0x02, 0x04, 0x09, 0xfb, 0xfa, 0xff, 0xfb, 0xff, 0x1b, 0x24, 0x28, + 0x1d, 0x16, 0x10, 0x11, 0x16, 0x27, 0x24, 0x27, 0x24, 0x19, 0x11, 0x09, + 0x03, 0xfc, 0xeb, 0xea, 0xfa, 0x11, 0x09, 0x09, 0x0a, 0x06, 0x03, 0xfd, + 0xfc, 0xfd, 0xf9, 0xf1, 0xef, 0xee, 0xea, 0xf0, 0xf1, 0xeb, 0xe9, 0xe4, + 0xdf, 0xde, 0xde, 0xe5, 0xfe, 0xfd, 0xf5, 0xf0, 0x03, 0x06, 0xfc, 0xfd, + 0xf9, 0xf4, 0xf0, 0xeb, 0xf6, 0x10, 0x11, 0x27, 0x32, 0x22, 0x17, 0x15, + 0x15, 0x12, 0x12, 0x16, 0x26, 0x17, 0x0d, 0x18, 0x1c, 0x18, 0x11, 0x10, + 0x09, 0xfd, 0x03, 0x06, 0x0a, 0x06, 0x08, 0x0a, 0x03, 0x02, 0x01, 0xf9, + 0xf6, 0xf7, 0xf6, 0xf0, 0xf4, 0xf6, 0xf4, 0x03, 0x13, 0x06, 0xf7, 0xf8, + 0x22, 0x1a, 0xfe, 0xf4, 0xfc, 0x0b, 0x03, 0x0e, 0x0d, 0x04, 0x05, 0x04, + 0xfb, 0xf7, 0xf5, 0x0d, 0x1f, 0x08, 0x01, 0x02, 0x06, 0xff, 0xfe, 0x01, + 0xf9, 0xf0, 0xe8, 0xe9, 0xea, 0xf5, 0x01, 0x03, 0xfe, 0xf9, 0xf2, 0xf6, + 0xf9, 0xf4, 0xf6, 0xf2, 0xe8, 0xe6, 0xf3, 0x0e, 0x08, 0x02, 0xf9, 0xfb, + 0xfc, 0xfb, 0xfe, 0xfc, 0x04, 0x0f, 0x0d, 0x15, 0x2a, 0x34, 0x2b, 0x20, + 0x15, 0x10, 0x14, 0x2a, 0x21, 0x11, 0x0f, 0x13, 0x1a, 0x18, 0x18, 0x1b, + 0x27, 0x1e, 0x14, 0x0d, 0x0b, 0x08, 0x04, 0xff, 0x03, 0x03, 0xf6, 0xea, + 0xe6, 0xe8, 0xd8, 0xcc, 0xd1, 0xd7, 0xef, 0xeb, 0xf6, 0xf4, 0xf0, 0xf0, + 0xeb, 0xe3, 0xe2, 0xea, 0xf3, 0x09, 0x16, 0x11, 0x0a, 0x09, 0x08, 0x07, + 0x03, 0xfc, 0x13, 0x18, 0x1e, 0x22, 0x1a, 0x1d, 0x1c, 0x17, 0x10, 0x0c, + 0x0b, 0x02, 0xfc, 0xfb, 0x02, 0x01, 0xfa, 0xfb, 0x0a, 0x06, 0xfb, 0xf8, + 0xf6, 0xed, 0xeb, 0xee, 0xf9, 0x16, 0x0d, 0x03, 0xfe, 0x02, 0x13, 0x0d, + 0x06, 0xfc, 0xfb, 0xfd, 0x03, 0x1b, 0x1e, 0x1b, 0x12, 0x0e, 0x0b, 0x05, + 0x04, 0x10, 0x1e, 0x0b, 0x05, 0xff, 0xff, 0x06, 0x06, 0x03, 0xfb, 0xf0, + 0x03, 0x0a, 0xf1, 0xf2, 0xfd, 0xfd, 0xf6, 0xfa, 0xfd, 0xf4, 0xef, 0xf0, + 0xef, 0xed, 0xee, 0xf2, 0x12, 0x1c, 0x09, 0x04, 0xfe, 0x01, 0xff, 0xff, + 0xff, 0xfd, 0x00, 0xfb, 0x04, 0x11, 0x17, 0x1e, 0x1c, 0x14, 0x0b, 0x03, + 0x05, 0x1c, 0x16, 0x0d, 0x05, 0xfe, 0xf9, 0x03, 0x0a, 0x0b, 0x08, 0x01, + 0xfa, 0xf5, 0xf5, 0xfb, 0xf6, 0xf0, 0xee, 0xf6, 0x08, 0x0c, 0x03, 0xfa, + 0xf5, 0xf3, 0xf0, 0x06, 0x10, 0x07, 0xfe, 0xfb, 0xfb, 0xfb, 0xf7, 0xfa, + 0x00, 0x11, 0x12, 0x13, 0x1b, 0x1d, 0x1f, 0x19, 0x15, 0x17, 0x15, 0x0c, + 0x14, 0x15, 0xfa, 0xfa, 0x06, 0x01, 0xf7, 0x00, 0x04, 0x03, 0x08, 0x06, + 0xfc, 0xf5, 0xf6, 0xf7, 0xf8, 0xf2, 0xf1, 0xfa, 0xf3, 0xf1, 0xee, 0xea, + 0xea, 0xeb, 0xfb, 0x03, 0x15, 0x19, 0x0f, 0x10, 0x16, 0x0d, 0x04, 0xfe, + 0x05, 0x08, 0xfb, 0xfc, 0x0d, 0x09, 0x10, 0x09, 0x07, 0x0f, 0x0b, 0x10, + 0x10, 0xfe, 0xf9, 0xf6, 0xf9, 0xfc, 0xff, 0x04, 0xfd, 0xf7, 0xf0, 0xec, + 0xfd, 0x13, 0x0c, 0x02, 0xff, 0xfc, 0xfe, 0x00, 0x01, 0xf7, 0xf7, 0xf3, + 0xfe, 0x18, 0x12, 0x0f, 0x0c, 0x07, 0x0a, 0x0b, 0x08, 0x00, 0x02, 0x00, + 0x12, 0x15, 0xfe, 0x03, 0x0d, 0x11, 0x15, 0x08, 0x0c, 0x0e, 0x15, 0x1d, + 0x0b, 0x07, 0x01, 0x00, 0x04, 0x0c, 0x13, 0x1a, 0x0d, 0x02, 0xfc, 0xf7, + 0xf6, 0xfe, 0xfe, 0xf5, 0xf2, 0xee, 0xea, 0xef, 0xf4, 0xf9, 0xf1, 0xe7, + 0xfb, 0xfd, 0xf8, 0xf3, 0xf6, 0xf9, 0xf3, 0xee, 0xe6, 0xe4, 0xe7, 0xf8, + 0xfc, 0xfa, 0xf9, 0x05, 0x02, 0x08, 0x0f, 0x0c, 0x1d, 0x2b, 0x30, 0x22, + 0x1c, 0x17, 0x11, 0x0e, 0x0d, 0x12, 0x1b, 0x1b, 0x12, 0x0c, 0x06, 0x04, + 0x0b, 0x1b, 0x17, 0x10, 0x09, 0x06, 0xff, 0x00, 0xfc, 0xfe, 0xfe, 0x0e, + 0x07, 0xf5, 0xe7, 0xe5, 0xf5, 0x07, 0x02, 0xf6, 0xef, 0xf0, 0xf3, 0xf1, + 0xf2, 0xf7, 0x02, 0xfd, 0xfc, 0x05, 0x05, 0xff, 0x05, 0x10, 0x06, 0xfe, + 0xfd, 0xf8, 0xf5, 0xf7, 0x0b, 0x12, 0x14, 0x08, 0x02, 0x06, 0x0d, 0x05, + 0x02, 0x06, 0x07, 0x07, 0x02, 0xfa, 0xfa, 0xf4, 0xec, 0xfd, 0x1a, 0x18, + 0x08, 0x04, 0x01, 0xfc, 0xfe, 0xff, 0xff, 0xfd, 0xfd, 0x00, 0xff, 0xf8, + 0xf5, 0x02, 0x10, 0x07, 0x04, 0x0c, 0x0c, 0x10, 0x19, 0x18, 0x1b, 0x15, + 0x10, 0x0d, 0x0a, 0x0c, 0x13, 0x1a, 0x16, 0x0b, 0x03, 0xff, 0xfc, 0xf7, + 0x10, 0x09, 0xf8, 0xf5, 0xf6, 0xf4, 0xf5, 0xf0, 0xed, 0xfc, 0xfd, 0xfb, + 0xf6, 0xf3, 0xee, 0xf6, 0xf8, 0x00, 0xfc, 0xf4, 0xfd, 0x03, 0x00, 0xf8, + 0xf8, 0x05, 0x00, 0xfa, 0x05, 0x07, 0x06, 0x12, 0x0e, 0x18, 0x1a, 0x13, + 0x0f, 0x09, 0x05, 0x01, 0x06, 0x09, 0x0b, 0x07, 0xfd, 0xf5, 0xf4, 0xf8, + 0xfc, 0xfe, 0xfe, 0xfb, 0xf4, 0xf4, 0xf2, 0xfb, 0x21, 0x1f, 0x15, 0x09, + 0x06, 0x04, 0x0a, 0x0e, 0x0a, 0x05, 0x01, 0x02, 0x0b, 0x0b, 0x06, 0x02, + 0x0d, 0x19, 0x15, 0x10, 0x11, 0x10, 0x1d, 0x15, 0x0f, 0x10, 0x03, 0xf9, + 0xfb, 0xed, 0xdf, 0xec, 0xf6, 0xf4, 0xfe, 0xff, 0xf7, 0xef, 0xef, 0xee, + 0xec, 0xeb, 0xf3, 0x00, 0xf9, 0xef, 0xeb, 0x01, 0x0a, 0x08, 0x05, 0xfe, + 0xfd, 0xfc, 0xfb, 0x04, 0x15, 0x0b, 0x09, 0x0d, 0x0c, 0x0b, 0x05, 0x09, + 0x0d, 0x0a, 0x06, 0x0f, 0x1c, 0x24, 0x1c, 0x14, 0x16, 0x15, 0x10, 0x0c, + 0x0e, 0x0c, 0x07, 0x0a, 0x08, 0x04, 0xfd, 0xf5, 0xf8, 0xf9, 0xf8, 0xf9, + 0xfa, 0xf3, 0xfa, 0xf8, 0xf1, 0xee, 0x01, 0x04, 0xfa, 0xf5, 0xf3, 0xfb, + 0xf9, 0xf9, 0xfb, 0xfe, 0xfd, 0x05, 0x0d, 0x07, 0x01, 0xfd, 0xfa, 0x06, + 0x0d, 0xfd, 0xfc, 0x17, 0x19, 0x0a, 0x0b, 0x19, 0x1c, 0x13, 0x0a, 0x08, + 0x04, 0x02, 0x09, 0x0e, 0x16, 0x0f, 0x07, 0x02, 0xfe, 0xfd, 0xf9, 0xfc, + 0x01, 0x01, 0xfd, 0xf1, 0xf1, 0x05, 0x09, 0x02, 0xff, 0xfa, 0x04, 0x08, + 0xff, 0xfd, 0xfe, 0xfd, 0xf8, 0xfa, 0xfa, 0x00, 0xfe, 0xf8, 0xfc, 0xf9, + 0xf6, 0xf7, 0x10, 0x13, 0x01, 0xfd, 0x01, 0x10, 0x19, 0x0f, 0x05, 0x01, + 0x07, 0x00, 0xff, 0x06, 0x09, 0x03, 0x04, 0x05, 0x01, 0xff, 0xfc, 0x07, + 0x19, 0x13, 0x0e, 0x06, 0x12, 0x1b, 0x14, 0x11, 0x0c, 0x04, 0xfc, 0xf8, + 0xf6, 0xeb, 0xeb, 0xf7, 0xfc, 0xf9, 0xf8, 0xfe, 0x01, 0x04, 0xf9, 0xf4, + 0xfb, 0x06, 0x0d, 0x07, 0x06, 0x07, 0x0c, 0x0d, 0x0d, 0x08, 0x08, 0x0a, + 0x03, 0x00, 0xfc, 0xfc, 0x0b, 0x06, 0x03, 0x01, 0x02, 0x02, 0xfb, 0xfb, + 0x03, 0xfe, 0xf9, 0x08, 0x0e, 0x06, 0x02, 0x0a, 0x08, 0xfc, 0xf2, 0xef, + 0xf2, 0xf6, 0x04, 0x07, 0xff, 0xfc, 0xfb, 0x00, 0x01, 0xf8, 0xf2, 0xfe, + 0x09, 0x13, 0x11, 0x09, 0x06, 0x0b, 0x14, 0x11, 0x0d, 0x08, 0x08, 0x06, + 0x08, 0x0f, 0x09, 0x06, 0x08, 0x04, 0x04, 0x06, 0xfd, 0xf3, 0xf1, 0x02, + 0x18, 0x01, 0x00, 0x0d, 0x09, 0x09, 0x09, 0x08, 0x03, 0x02, 0xff, 0xfa, + 0xf8, 0xfb, 0x06, 0x0a, 0x06, 0x08, 0x0b, 0x0c, 0x04, 0x03, 0x07, 0x03, + 0x0a, 0x0c, 0x02, 0xfb, 0xfc, 0xff, 0xfa, 0xfb, 0xfe, 0xfd, 0xfc, 0xfa, + 0xfd, 0x00, 0xfb, 0xf7, 0xf9, 0xfa, 0xf8, 0xf4, 0xed, 0xec, 0xed, 0xee, + 0xf2, 0xfd, 0x10, 0x0d, 0x07, 0x03, 0xfd, 0xfd, 0x0d, 0x0d, 0x08, 0xfd, + 0x05, 0x0b, 0x0c, 0x0b, 0x04, 0x08, 0x0d, 0x10, 0x18, 0x1a, 0x20, 0x21, + 0x27, 0x20, 0x1a, 0x1b, 0x24, 0x21, 0x1c, 0x11, 0x0a, 0x0d, 0x07, 0x07, + 0x01, 0xec, 0xe0, 0xec, 0xf6, 0xf9, 0xfc, 0xfc, 0xf3, 0xec, 0xef, 0xea, + 0xee, 0xfe, 0xf9, 0xf6, 0xf3, 0xf4, 0xf2, 0xe6, 0xea, 0xed, 0xe6, 0xf2, + 0x06, 0x00, 0xf5, 0xf5, 0x0c, 0x13, 0x0a, 0x10, 0x0b, 0x03, 0x02, 0x08, + 0x12, 0x11, 0x0e, 0x14, 0x1c, 0x1f, 0x22, 0x1c, 0x0f, 0x09, 0x07, 0x07, + 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0xff, 0xfb, 0xf5, 0xf1, 0xef, 0xf4, + 0x0f, 0x17, 0x16, 0x10, 0x0b, 0x03, 0xfa, 0xf9, 0xf9, 0xf8, 0xf8, 0xfe, + 0x04, 0x04, 0x09, 0x08, 0x09, 0x0d, 0x0f, 0x08, 0x05, 0x01, 0xfe, 0x0a, + 0x14, 0x0f, 0xfe, 0x01, 0xff, 0xfd, 0xff, 0x03, 0x02, 0x02, 0x03, 0x08, + 0x00, 0x06, 0x03, 0xfe, 0xfd, 0xfa, 0xf5, 0xef, 0xed, 0xf0, 0xef, 0xfe, + 0x17, 0x0d, 0x06, 0x05, 0x03, 0xfc, 0xf3, 0xef, 0xf2, 0xfa, 0xff, 0xff, + 0x00, 0x00, 0x05, 0x03, 0x0d, 0x10, 0x05, 0x00, 0x01, 0x04, 0x16, 0x14, + 0x10, 0x0f, 0x0e, 0x11, 0x0e, 0x0b, 0x05, 0x02, 0x0b, 0x16, 0x0e, 0x05, + 0x00, 0xff, 0xfc, 0x00, 0x02, 0x02, 0xff, 0xfd, 0x05, 0x05, 0x05, 0x18, + 0x18, 0x0d, 0x02, 0x03, 0x02, 0xfc, 0xf0, 0xed, 0xf5, 0xfd, 0x05, 0x06, + 0x09, 0x02, 0xf2, 0xfa, 0xfc, 0xff, 0x00, 0x02, 0x01, 0x05, 0x0b, 0x00, + 0xf9, 0xfe, 0x03, 0x01, 0xff, 0xff, 0x09, 0x08, 0xfd, 0xf6, 0xf9, 0xfc, + 0xfb, 0xf7, 0xf7, 0xf8, 0xfd, 0x07, 0x06, 0x00, 0xfc, 0xfc, 0x0e, 0x15, + 0x10, 0x08, 0x0a, 0x10, 0x18, 0x0f, 0x02, 0xff, 0x02, 0x01, 0x01, 0x07, + 0x0d, 0x0e, 0x19, 0x11, 0x0b, 0x05, 0x04, 0x01, 0x02, 0x0a, 0x03, 0xfd, + 0xff, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x00, 0x02, 0x03, 0xfd, 0xfa, + 0xf8, 0xf4, 0xfd, 0x01, 0xfb, 0xef, 0xec, 0xf4, 0xf4, 0xfc, 0x04, 0x03, + 0x0d, 0x19, 0x10, 0x02, 0xf9, 0xf4, 0xf5, 0xf6, 0xf7, 0xfb, 0x05, 0x11, + 0x24, 0x1f, 0x17, 0x0f, 0x0b, 0x09, 0x09, 0x09, 0x17, 0x12, 0x0c, 0x14, + 0x11, 0x0b, 0x08, 0x0c, 0x0d, 0x08, 0x01, 0x00, 0x06, 0x00, 0xf9, 0xf9, + 0xf9, 0xf8, 0xfa, 0xf5, 0xf0, 0xe6, 0xe0, 0xe2, 0xeb, 0xfa, 0xf9, 0x05, + 0x02, 0x00, 0xff, 0xfb, 0xf4, 0xf1, 0xef, 0xf1, 0xfd, 0x0c, 0x15, 0x13, + 0x11, 0x0b, 0x07, 0x05, 0x06, 0x09, 0x09, 0x1c, 0x28, 0x23, 0x1c, 0x1d, + 0x1d, 0x15, 0x11, 0x16, 0x0f, 0x07, 0x01, 0x06, 0x08, 0x04, 0x01, 0x05, + 0x01, 0x04, 0xff, 0xf7, 0xf0, 0xed, 0xf1, 0xf6, 0x06, 0x08, 0x06, 0x06, + 0x01, 0xf9, 0xf3, 0xee, 0xef, 0xec, 0xf3, 0xff, 0xfe, 0x01, 0x01, 0x02, + 0x09, 0x03, 0xfd, 0xfc, 0xfc, 0xfb, 0x13, 0x1a, 0x0c, 0x07, 0x04, 0x00, + 0xfc, 0xfe, 0x02, 0x0c, 0x08, 0x08, 0x0f, 0x14, 0x0b, 0x06, 0x02, 0xfc, + 0xfd, 0xfb, 0xfd, 0xfb, 0xfa, 0xf6, 0xee, 0xf8, 0x03, 0x03, 0x0f, 0x0a, + 0x06, 0x02, 0xfe, 0xfb, 0xfa, 0xff, 0x02, 0xff, 0x04, 0x0f, 0x0a, 0x06, + 0x08, 0x09, 0x0f, 0x18, 0x12, 0x12, 0x1c, 0x19, 0x16, 0x0f, 0x0d, 0x0c, + 0x0b, 0x0a, 0x18, 0x10, 0x04, 0xff, 0xfc, 0xfe, 0xfa, 0xf8, 0xfc, 0x06, + 0x06, 0xf9, 0xf6, 0xf5, 0xf1, 0xeb, 0xec, 0xf9, 0xf6, 0xf8, 0xf6, 0xf7, + 0xfb, 0xf9, 0xf6, 0xf7, 0xfc, 0x02, 0x05, 0xfd, 0x03, 0x02, 0xff, 0xfe, + 0xff, 0x05, 0x02, 0xfc, 0xfa, 0x05, 0x07, 0x06, 0x03, 0x08, 0x11, 0x1a, + 0x12, 0x0a, 0x05, 0x09, 0x0b, 0x04, 0x02, 0xfe, 0xf9, 0xf7, 0xfe, 0x0b, + 0x09, 0x02, 0x00, 0xfd, 0xf9, 0xfa, 0x09, 0x1a, 0x1b, 0x1d, 0x18, 0x16, + 0x19, 0x15, 0x0f, 0x0b, 0x04, 0xfb, 0xfa, 0x08, 0x0e, 0x0d, 0x0c, 0x05, + 0x0c, 0x14, 0x0f, 0x04, 0x05, 0x00, 0xff, 0xfd, 0xfa, 0xfe, 0xfc, 0xfb, + 0xf8, 0xf2, 0xf1, 0xf1, 0xf3, 0xf8, 0xfa, 0x04, 0xfd, 0xf7, 0xf1, 0xf2, + 0xf3, 0xee, 0xe6, 0xe2, 0xe1, 0xe5, 0xf9, 0x0b, 0x12, 0x0f, 0x08, 0x02, + 0x07, 0x06, 0xfe, 0x06, 0x07, 0x01, 0x08, 0x10, 0x0e, 0x0c, 0x0b, 0x0c, + 0x10, 0x14, 0x19, 0x26, 0x25, 0x20, 0x23, 0x1c, 0x18, 0x12, 0x0e, 0x09, + 0x07, 0x04, 0x02, 0x06, 0x00, 0xfb, 0xfc, 0xfc, 0x00, 0x00, 0xfe, 0xfa, + 0xf7, 0xf1, 0xf0, 0xf8, 0xf0, 0xee, 0xf2, 0xf7, 0xff, 0x00, 0xfe, 0xfe, + 0x02, 0xfd, 0xfa, 0xfc, 0x01, 0x00, 0x07, 0x05, 0x00, 0xfd, 0xff, 0x06, + 0x08, 0x09, 0x11, 0x0f, 0x0d, 0x0d, 0x14, 0x0e, 0x0b, 0x07, 0x00, 0x01, + 0x03, 0x04, 0x0e, 0x0a, 0x06, 0x04, 0x00, 0xfe, 0xfd, 0xfa, 0xfa, 0xf9, + 0xf1, 0xec, 0xeb, 0xeb, 0xf3, 0x02, 0x02, 0x05, 0x03, 0x02, 0x0c, 0x15, + 0x11, 0x09, 0x02, 0xfc, 0xfc, 0x0b, 0x0b, 0x02, 0xf8, 0xf9, 0xf8, 0xf8, + 0x0b, 0x23, 0x1b, 0x11, 0x0a, 0x0b, 0x0b, 0x10, 0x13, 0x12, 0x0e, 0x0b, + 0x08, 0x09, 0x09, 0x0e, 0x12, 0x01, 0xfd, 0x00, 0x00, 0xfc, 0x02, 0x02, + 0xf7, 0xf2, 0xf2, 0xf2, 0xfd, 0x00, 0xfa, 0x03, 0x00, 0xfe, 0x00, 0xff, + 0xfa, 0xef, 0xf0, 0xf1, 0xfb, 0xff, 0x00, 0x05, 0x00, 0x01, 0xfb, 0xff, + 0x1b, 0x1f, 0x18, 0x16, 0x0e, 0x0c, 0x0d, 0x06, 0x06, 0x0f, 0x0e, 0x09, + 0x02, 0x04, 0x02, 0x03, 0x08, 0x09, 0x07, 0x01, 0xfa, 0xf9, 0xf6, 0xf0, + 0xee, 0xec, 0xea, 0xec, 0xfc, 0x03, 0x12, 0x16, 0x0a, 0x04, 0x00, 0xfc, + 0xfa, 0xf8, 0xfb, 0x09, 0x0b, 0x01, 0xfe, 0xfd, 0xfe, 0xf9, 0xff, 0x13, + 0x1b, 0x1b, 0x1f, 0x29, 0x1f, 0x15, 0x0f, 0x06, 0x01, 0x08, 0x0c, 0x09, + 0x08, 0x02, 0x01, 0xff, 0xff, 0x07, 0x04, 0xf8, 0xfc, 0xfd, 0xf9, 0xfa, + 0xf7, 0xf4, 0xf4, 0xf7, 0x06, 0x0b, 0x0c, 0x05, 0x00, 0x03, 0xff, 0xfd, + 0xff, 0xfe, 0x06, 0x12, 0x0a, 0x03, 0xff, 0xfd, 0xfb, 0xfe, 0x0c, 0x09, + 0x07, 0x07, 0xfe, 0xfd, 0x02, 0x02, 0xfc, 0xfb, 0xfb, 0x00, 0x05, 0x08, + 0x05, 0x05, 0x04, 0x03, 0x01, 0x03, 0xfd, 0xf3, 0xec, 0xe7, 0xe5, 0xe3, + 0xe2, 0xed, 0xf9, 0x0d, 0x1e, 0x19, 0x0b, 0x06, 0x13, 0x15, 0x0e, 0x0b, + 0x08, 0x05, 0x0e, 0x11, 0x0b, 0x05, 0x06, 0x06, 0x0e, 0x24, 0x28, 0x28, + 0x2a, 0x26, 0x1e, 0x1a, 0x18, 0x14, 0x10, 0x06, 0xff, 0x02, 0xfd, 0xfb, + 0xf9, 0xf3, 0xf2, 0xf6, 0xf7, 0xf2, 0xf9, 0xfb, 0xec, 0xe8, 0xe4, 0xe0, + 0xe1, 0xe1, 0xe6, 0x00, 0x00, 0xfa, 0xf4, 0xf2, 0xf3, 0xef, 0xf3, 0xfe, + 0xfe, 0x04, 0x0c, 0x05, 0x00, 0x08, 0x0b, 0x0c, 0x15, 0x0d, 0x07, 0x0e, + 0x14, 0x11, 0x10, 0x17, 0x16, 0x18, 0x1b, 0x17, 0x11, 0x0d, 0x09, 0x05, + 0xff, 0x05, 0x06, 0x03, 0x02, 0xfe, 0xf9, 0xf3, 0xf6, 0xf9, 0xf3, 0xf2, + 0xf9, 0xfd, 0x16, 0x28, 0x1b, 0x12, 0x0c, 0x06, 0xff, 0xfd, 0xff, 0xff, + 0xfe, 0x07, 0x06, 0xff, 0xfe, 0x01, 0x03, 0x16, 0x15, 0x08, 0x01, 0x03, + 0x02, 0x07, 0x09, 0x05, 0x02, 0x01, 0xfd, 0xfc, 0xf9, 0xf5, 0xf9, 0xfc, + 0xff, 0x08, 0x0a, 0x08, 0x00, 0xfa, 0xf4, 0xeb, 0xe4, 0xe7, 0xf0, 0xed, + 0xee, 0xfb, 0x04, 0x06, 0x03, 0x00, 0xff, 0xfd, 0xfc, 0xfc, 0x04, 0x0d, + 0x09, 0x0a, 0x05, 0x05, 0x05, 0x08, 0x18, 0x17, 0x0e, 0x0c, 0x0d, 0x10, + 0x0d, 0x0f, 0x12, 0x12, 0x1b, 0x1d, 0x12, 0x0e, 0x0b, 0x0b, 0x11, 0x0e, + 0x0d, 0x07, 0x04, 0x02, 0xfd, 0xf8, 0xf7, 0xf4, 0xf0, 0xf2, 0xfa, 0xfc, + 0x07, 0x05, 0x08, 0x03, 0xfc, 0xfe, 0xfe, 0xfd, 0xfc, 0xf4, 0xf3, 0xf3, + 0xf5, 0xfa, 0xf5, 0xf0, 0xf0, 0x03, 0x14, 0x11, 0x0a, 0x08, 0x0c, 0x09, + 0x07, 0x0d, 0x09, 0x06, 0x05, 0x07, 0x06, 0x04, 0x02, 0xff, 0xfb, 0xfa, + 0xfc, 0x05, 0x05, 0xfe, 0xf9, 0xf9, 0xfb, 0x02, 0xfe, 0xf9, 0xfe, 0x07, + 0x01, 0xff, 0x0a, 0x0a, 0x0b, 0x11, 0x11, 0x06, 0x03, 0x0c, 0x07, 0x00, + 0x03, 0x05, 0x03, 0xfe, 0x0a, 0x13, 0x0d, 0x0a, 0x04, 0x04, 0x05, 0x01, + 0x04, 0x06, 0x14, 0x16, 0x12, 0x0e, 0x0f, 0x0d, 0x06, 0x00, 0xf8, 0xf9, + 0xfe, 0x01, 0xfe, 0xf5, 0xf6, 0xf3, 0xf1, 0xf6, 0xf4, 0xfc, 0x08, 0x02, + 0xf2, 0xee, 0xfb, 0x02, 0x03, 0xfd, 0xf8, 0xf9, 0xfb, 0xfa, 0xfb, 0xfb, + 0x03, 0x0c, 0x0f, 0x15, 0x1a, 0x18, 0x13, 0x12, 0x10, 0x10, 0x0d, 0x0d, + 0x0e, 0x0f, 0x10, 0x10, 0x0d, 0x0a, 0x0b, 0x07, 0x04, 0x03, 0x0c, 0x0f, + 0x08, 0xff, 0xf6, 0xf3, 0xf4, 0xf5, 0xec, 0xe1, 0xea, 0xf2, 0xf9, 0xf4, + 0xf1, 0xf7, 0xfa, 0xf6, 0xf8, 0xf6, 0xf8, 0x03, 0x03, 0x00, 0xf8, 0xfe, + 0x0f, 0x0c, 0x0d, 0x15, 0x0c, 0x0e, 0x16, 0x11, 0x13, 0x25, 0x21, 0x14, + 0x14, 0x17, 0x17, 0x16, 0x0d, 0x0b, 0x0d, 0x0c, 0x0a, 0x06, 0x06, 0x02, + 0xf3, 0xe8, 0xea, 0xed, 0xec, 0xeb, 0xf9, 0x07, 0x04, 0x08, 0x03, 0xfb, + 0xf6, 0x05, 0x03, 0xff, 0xfa, 0xfa, 0x00, 0x05, 0x06, 0xff, 0xf8, 0xf8, + 0xf8, 0xfd, 0x0c, 0x0a, 0x0c, 0x0a, 0x07, 0x06, 0x08, 0x08, 0x0b, 0x08, + 0x02, 0x02, 0x06, 0x03, 0x07, 0x10, 0x09, 0x04, 0x00, 0xff, 0xfd, 0xff, + 0xfe, 0xf5, 0xf4, 0xf6, 0xf6, 0xfc, 0x01, 0x04, 0x03, 0xfd, 0xf6, 0xf4, + 0xf7, 0x01, 0x0a, 0x10, 0x09, 0x0b, 0x10, 0x0f, 0x07, 0x08, 0x08, 0x01, + 0x02, 0x13, 0x14, 0x0f, 0x0f, 0x0e, 0x0f, 0x17, 0x15, 0x15, 0x14, 0x10, + 0x07, 0x07, 0x04, 0x06, 0x04, 0x03, 0x04, 0x02, 0xfb, 0xfa, 0xfb, 0xf9, + 0xf7, 0xfc, 0xfc, 0xf6, 0xfb, 0xfb, 0xf7, 0xfa, 0xf6, 0xf0, 0xed, 0xeb, + 0xee, 0xf4, 0xf9, 0xf9, 0xfe, 0xff, 0xfe, 0xf9, 0xf4, 0xf5, 0xfc, 0x0e, + 0x1a, 0x16, 0x0d, 0x11, 0x15, 0x10, 0x0f, 0x09, 0x07, 0x0a, 0x07, 0x06, + 0x0b, 0x0b, 0x0a, 0x0b, 0x08, 0x03, 0x02, 0x00, 0x03, 0x04, 0x06, 0x02, + 0xfd, 0xfb, 0xf8, 0x02, 0x02, 0xfe, 0x05, 0x0f, 0x0d, 0x0c, 0x0f, 0x06, + 0x07, 0x0c, 0x0b, 0x0c, 0x12, 0x0d, 0x06, 0x00, 0x00, 0xfe, 0xfe, 0x0a, + 0x0f, 0x00, 0xfa, 0xf4, 0xf7, 0x00, 0x02, 0x09, 0x06, 0x07, 0x05, 0x03, + 0x03, 0x00, 0x00, 0xfe, 0xfe, 0xfd, 0xfa, 0xf8, 0xfb, 0xfa, 0xfa, 0xf8, + 0xf5, 0xfa, 0x01, 0xfe, 0xfb, 0xfa, 0xfd, 0xff, 0xfb, 0xfa, 0xf8, 0xf2, + 0xf6, 0x09, 0x0e, 0x11, 0x0b, 0x06, 0x07, 0x03, 0xff, 0x01, 0x00, 0x14, + 0x12, 0x0b, 0x06, 0x05, 0x0e, 0x13, 0x14, 0x16, 0x10, 0x0e, 0x0d, 0x0a, + 0x0d, 0x0b, 0x0f, 0x18, 0x17, 0x0e, 0x09, 0x0b, 0x0c, 0x07, 0x05, 0xfc, + 0x02, 0x00, 0xfa, 0xf6, 0xf6, 0xf6, 0xf6, 0xf9, 0xf5, 0xf4, 0xed, 0xe7, + 0xef, 0xf7, 0xf7, 0xfb, 0xf9, 0xf2, 0xed, 0xe8, 0xeb, 0xf3, 0x0d, 0x16, + 0x10, 0x11, 0x16, 0x17, 0x14, 0x10, 0x09, 0x08, 0x0c, 0x0c, 0x09, 0x08, + 0x07, 0x09, 0x08, 0x0a, 0x06, 0x02, 0x02, 0x03, 0xfe, 0xff, 0x03, 0x13, + 0x12, 0x06, 0xff, 0xff, 0x01, 0x01, 0xff, 0x00, 0xfe, 0xfa, 0xf3, 0xf6, + 0x02, 0x0d, 0x09, 0x05, 0x02, 0xfe, 0xfd, 0xfb, 0xf9, 0xff, 0x06, 0x00, + 0x00, 0x0b, 0x0d, 0x07, 0x07, 0x08, 0x15, 0x11, 0x09, 0x0c, 0x0d, 0x0e, + 0x0c, 0x0c, 0x09, 0x07, 0xff, 0xfc, 0xfd, 0xfc, 0xfe, 0x01, 0x0b, 0x08, + 0x08, 0xfb, 0xf7, 0xf8, 0xf5, 0xee, 0xec, 0xf5, 0xfc, 0xf4, 0xf3, 0xfc, + 0x09, 0x0b, 0x06, 0x02, 0x00, 0xfd, 0xfe, 0xff, 0x02, 0x0e, 0x09, 0x05, + 0x07, 0x0c, 0x10, 0x0f, 0x0f, 0x0e, 0x0e, 0x0d, 0x0e, 0x0e, 0x12, 0x0e, + 0x0b, 0x13, 0x14, 0x0a, 0x06, 0x04, 0x03, 0x00, 0x05, 0x08, 0xfd, 0xf7, + 0xf3, 0xf3, 0xf5, 0xf4, 0xf3, 0xf1, 0xf0, 0xef, 0xe8, 0xe9, 0xf1, 0xf7, + 0xfa, 0x00, 0xfd, 0xfd, 0x06, 0x04, 0x00, 0x03, 0x18, 0x17, 0x09, 0x10, + 0x1f, 0x1c, 0x13, 0x14, 0x15, 0x10, 0x0b, 0x0a, 0x0c, 0x0f, 0x11, 0x0e, + 0x0d, 0x07, 0xfe, 0xfb, 0xfa, 0xf6, 0xf5, 0xff, 0x04, 0x08, 0x03, 0xfc, + 0xfd, 0x06, 0xff, 0xfb, 0xff, 0xfe, 0xfd, 0xf9, 0xf4, 0xf9, 0xfd, 0xff, + 0x05, 0x07, 0x03, 0x00, 0xff, 0xfc, 0xfc, 0x03, 0x09, 0x02, 0xff, 0x07, + 0x13, 0x19, 0x0b, 0x07, 0x08, 0x07, 0x07, 0x04, 0x03, 0x04, 0x04, 0x04, + 0xff, 0xff, 0xfe, 0xfd, 0xf8, 0xf6, 0x06, 0x08, 0x01, 0xfc, 0x01, 0x01, + 0xfb, 0xf9, 0xf7, 0xf9, 0xff, 0x05, 0xfe, 0xfc, 0x05, 0x09, 0x05, 0x06, + 0x07, 0x0e, 0x06, 0x05, 0x06, 0x02, 0x04, 0x0e, 0x0d, 0x0e, 0x0f, 0x13, + 0x14, 0x10, 0x05, 0x04, 0x07, 0x06, 0x0a, 0x09, 0x07, 0x14, 0x0f, 0x0b, + 0x0a, 0x09, 0x07, 0x01, 0xfe, 0x04, 0x06, 0x00, 0xfb, 0xfb, 0xfa, 0xf8, + 0xf6, 0xf5, 0xf4, 0xf3, 0xf1, 0xef, 0xef, 0xf6, 0xf9, 0xf3, 0xf1, 0xef, + 0xfd, 0x0a, 0xfb, 0xfa, 0x01, 0x05, 0x0d, 0x11, 0x09, 0x0d, 0x10, 0x11, + 0x0b, 0x07, 0x07, 0x09, 0x0b, 0x0c, 0x09, 0x06, 0x06, 0x0a, 0x0a, 0x05, + 0x02, 0x00, 0x00, 0x00, 0x06, 0x12, 0x0f, 0x08, 0x08, 0x09, 0x07, 0x04, + 0x02, 0x01, 0x01, 0x04, 0x01, 0x02, 0x08, 0x07, 0x01, 0xfd, 0xfd, 0x02, + 0x07, 0x08, 0xff, 0xf8, 0xf4, 0xf6, 0x02, 0x06, 0x0a, 0x04, 0x02, 0x05, + 0x0e, 0x0a, 0x06, 0x08, 0x05, 0x00, 0x01, 0x03, 0x01, 0xfe, 0xfe, 0xfd, + 0xfc, 0xfd, 0xfd, 0x07, 0x09, 0x01, 0xfb, 0xfa, 0xfe, 0x01, 0x00, 0x00, + 0xfc, 0xff, 0x00, 0xf9, 0xfb, 0xff, 0x00, 0xfe, 0xfe, 0xfd, 0x00, 0x02, + 0x00, 0x00, 0xfb, 0xfc, 0xfe, 0x09, 0x16, 0x13, 0x0c, 0x09, 0x09, 0x0a, + 0x0d, 0x0c, 0x0c, 0x0c, 0x14, 0x17, 0x18, 0x1b, 0x19, 0x12, 0x0f, 0x0e, + 0x0c, 0x06, 0x09, 0x0a, 0x06, 0x01, 0x02, 0xff, 0xfb, 0xfc, 0xfd, 0xfc, + 0xfb, 0xf5, 0xf0, 0xe8, 0xe6, 0xea, 0xec, 0xee, 0xee, 0xeb, 0xf4, 0xf3, + 0xf8, 0xf9, 0xfc, 0x00, 0x06, 0x19, 0x0f, 0x0e, 0x0f, 0x0a, 0x10, 0x0e, + 0x0f, 0x0e, 0x0e, 0x0d, 0x0b, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0b, 0x04, + 0x06, 0x0c, 0x06, 0x0a, 0x0b, 0x09, 0x09, 0x05, 0x01, 0x01, 0xfb, 0xf7, + 0xf6, 0xf6, 0xf7, 0xfb, 0xfe, 0xfb, 0xf9, 0xfa, 0xfa, 0xfa, 0xf7, 0xf5, + 0xfa, 0xf6, 0xf5, 0xfd, 0x0f, 0x11, 0x0a, 0x10, 0x08, 0x03, 0x09, 0x0c, + 0x0f, 0x0d, 0x0e, 0x10, 0x13, 0x11, 0x0d, 0x06, 0x04, 0x04, 0x01, 0xfe, + 0x06, 0x0d, 0x09, 0x05, 0xf9, 0xf2, 0xf5, 0xfa, 0xff, 0x05, 0x00, 0x00, + 0xff, 0xfc, 0xfe, 0x03, 0xfe, 0xfc, 0xf7, 0xf3, 0xf4, 0xf6, 0xf8, 0xfd, + 0xfd, 0xf8, 0xff, 0x0c, 0x1b, 0x19, 0x12, 0x09, 0x03, 0x06, 0x08, 0x0b, + 0x0e, 0x0d, 0x04, 0x0b, 0x1d, 0x14, 0x0c, 0x0b, 0x10, 0x0a, 0x07, 0x0c, + 0x10, 0x05, 0x03, 0xfe, 0xfa, 0xf9, 0xf7, 0xf7, 0xf5, 0xf5, 0xf2, 0xf3, + 0xf4, 0xf5, 0xfa, 0xfb, 0xfc, 0xfc, 0xf6, 0xf7, 0xf1, 0xf3, 0xf9, 0x00, + 0xff, 0x01, 0x07, 0x0a, 0x12, 0x0c, 0x12, 0x13, 0x0f, 0x11, 0x0e, 0x0a, + 0x11, 0x14, 0x11, 0x10, 0x0b, 0xfd, 0xf7, 0xfe, 0x03, 0xff, 0xff, 0x06, + 0x0f, 0x0c, 0x07, 0x07, 0x05, 0xff, 0xfe, 0x02, 0x02, 0x04, 0x00, 0xfe, + 0xfc, 0xfe, 0x02, 0x03, 0x02, 0xfe, 0xfb, 0xfb, 0xfb, 0xfb, 0xfe, 0x00, + 0x06, 0x11, 0x07, 0x11, 0x12, 0x0b, 0x0b, 0x09, 0x09, 0x07, 0x05, 0x02, + 0x02, 0x02, 0x04, 0x01, 0xff, 0xfd, 0xfa, 0xf7, 0xf4, 0xf9, 0x05, 0x03, + 0xfc, 0xf8, 0xf6, 0xf8, 0xfb, 0xfb, 0x00, 0xf7, 0xfa, 0x0c, 0x09, 0x04, + 0x04, 0x02, 0x04, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x05, + 0x0d, 0x0b, 0x0a, 0x1d, 0x1c, 0x15, 0x05, 0x05, 0x07, 0x11, 0x16, 0x15, + 0x15, 0x13, 0x0e, 0x0f, 0x0a, 0x08, 0x09, 0x05, 0x00, 0x07, 0x0b, 0x02, + 0x00, 0xfe, 0xf9, 0xf7, 0xf7, 0xf9, 0xfc, 0xfd, 0xfd, 0xf7, 0xed, 0xef, + 0xf5, 0xf2, 0xf1, 0xea, 0xe5, 0xef, 0xf8, 0xf5, 0xf1, 0xf5, 0xfd, 0x02, + 0xfe, 0xff, 0x0a, 0x14, 0x0b, 0x11, 0x11, 0x0e, 0x0b, 0x0b, 0x08, 0x0b, + 0x0f, 0x11, 0x0f, 0x0e, 0x0e, 0x15, 0x1b, 0x11, 0x08, 0x10, 0x10, 0x10, + 0x0c, 0x07, 0x08, 0x05, 0x01, 0xff, 0xff, 0x00, 0x02, 0x00, 0xfa, 0xfa, + 0xfe, 0x01, 0x01, 0x01, 0xfe, 0xf9, 0xf0, 0xe6, 0xe8, 0xf0, 0xfc, 0xf7, + 0xf5, 0xfa, 0x14, 0x1c, 0x0d, 0x06, 0x0d, 0x0d, 0x08, 0x09, 0x0d, 0x0f, + 0x0a, 0x06, 0x02, 0x00, 0x00, 0x00, 0xfe, 0xfd, 0x0b, 0x0d, 0x04, 0x02, + 0x01, 0x05, 0x0e, 0x05, 0x00, 0x01, 0x01, 0x07, 0x03, 0xfd, 0xfc, 0xfe, + 0xfc, 0xfb, 0xfa, 0xf5, 0xf4, 0xf4, 0xf2, 0xef, 0xf0, 0xff, 0x01, 0xfd, + 0x00, 0x04, 0x11, 0x0f, 0x09, 0x0c, 0x0b, 0x03, 0x00, 0x0d, 0x14, 0x22, + 0x1d, 0x14, 0x15, 0x14, 0x10, 0x0b, 0x0d, 0x12, 0x16, 0x0f, 0x0a, 0x06, + 0x01, 0x02, 0x03, 0xfd, 0xfd, 0x01, 0x05, 0xfb, 0xef, 0xef, 0x00, 0x05, + 0xfd, 0xf5, 0xef, 0xe8, 0xe9, 0xe7, 0xe8, 0xf2, 0xfb, 0x00, 0xfa, 0xf7, + 0xf8, 0xfd, 0x0e, 0x08, 0x0a, 0x0f, 0x0f, 0x11, 0x16, 0x16, 0x10, 0x09, + 0x07, 0x05, 0x04, 0x01, 0xfa, 0xfd, 0x03, 0x14, 0x1e, 0x17, 0x0e, 0x07, + 0x02, 0x02, 0x02, 0xff, 0x03, 0x04, 0x01, 0xfc, 0xfb, 0xfe, 0xfe, 0xfb, + 0xfc, 0xf7, 0xf9, 0xfd, 0xfd, 0xfe, 0x04, 0x11, 0x0d, 0x07, 0x04, 0x01, + 0x00, 0x0d, 0x17, 0x11, 0x11, 0x0f, 0x0d, 0x0c, 0x09, 0x06, 0x06, 0x03, + 0xfd, 0xfa, 0xfb, 0xfc, 0xfa, 0xfa, 0x02, 0x09, 0x02, 0xf0, 0xeb, 0xec, + 0xf1, 0xf2, 0xf7, 0xfa, 0x03, 0x10, 0x0b, 0x05, 0x02, 0x03, 0x00, 0xff, + 0xff, 0xfb, 0xfb, 0xfc, 0xfe, 0xfc, 0x01, 0x0a, 0x0b, 0x07, 0x07, 0x06, + 0x04, 0x17, 0x20, 0x24, 0x20, 0x16, 0x17, 0x14, 0x0f, 0x15, 0x0f, 0x0a, + 0x06, 0x06, 0x05, 0x03, 0x00, 0xfe, 0x05, 0x0c, 0x04, 0xfa, 0xf5, 0xf4, + 0xf8, 0xf9, 0xf9, 0xfe, 0xf7, 0xf2, 0xf4, 0xf3, 0xef, 0xed, 0xee, 0xf0, + 0xef, 0xf8, 0xff, 0xfd, 0xf6, 0xf5, 0x00, 0x04, 0x02, 0xfe, 0xfc, 0xfe, + 0x04, 0x17, 0x14, 0x14, 0x1e, 0x21, 0x1c, 0x18, 0x14, 0x0f, 0x0c, 0x0d, + 0x13, 0x14, 0x0f, 0x0b, 0x02, 0x02, 0x13, 0x12, 0x06, 0x02, 0x04, 0x02, + 0x01, 0xfe, 0x00, 0xfe, 0xfa, 0xf8, 0xf9, 0xfc, 0x00, 0xfd, 0xfa, 0xf9, + 0xf4, 0xf3, 0xf3, 0xf2, 0xf3, 0xf8, 0xf9, 0xfe, 0x01, 0xfd, 0x01, 0x07, + 0x08, 0x17, 0x13, 0x0c, 0x0e, 0x08, 0x08, 0x0a, 0x0a, 0x05, 0x00, 0x00, + 0xfe, 0xfc, 0xfc, 0xfd, 0xf9, 0xfe, 0x10, 0x14, 0x09, 0x08, 0x07, 0x04, + 0x02, 0x04, 0x06, 0x0c, 0x0c, 0x05, 0x00, 0x00, 0x00, 0xfe, 0xfc, 0xf8, + 0xf8, 0xf5, 0xf1, 0xf3, 0xfb, 0x07, 0x08, 0x08, 0x02, 0xfd, 0xfe, 0xfc, + 0xf8, 0x09, 0x0b, 0x0c, 0x12, 0x0d, 0x09, 0x11, 0x1a, 0x15, 0x0f, 0x0c, + 0x09, 0x04, 0x02, 0x06, 0x09, 0x0b, 0x12, 0x0b, 0x06, 0x08, 0x07, 0x05, + 0x03, 0x01, 0xfa, 0xfc, 0x02, 0x02, 0x03, 0xfd, 0xf8, 0xf4, 0xf5, 0xf2, + 0xf0, 0xe7, 0xe6, 0xe7, 0xef, 0xf8, 0xfb, 0xfc, 0xf9, 0xf5, 0xf3, 0xf4, + 0xfa, 0x0f, 0x15, 0x1a, 0x16, 0x0f, 0x0c, 0x08, 0x09, 0x04, 0x04, 0x04, + 0x09, 0x07, 0x03, 0x05, 0x11, 0x21, 0x1f, 0x12, 0x0c, 0x0a, 0x08, 0x08, + 0x0b, 0x05, 0x00, 0x00, 0x02, 0x02, 0x08, 0x0a, 0x00, 0xfc, 0xfd, 0xfc, + 0x01, 0xfd, 0xf7, 0x07, 0x0a, 0x06, 0x06, 0x05, 0x03, 0x03, 0xfa, 0xf6, + 0x04, 0x19, 0x13, 0x0c, 0x09, 0x05, 0x01, 0x02, 0x01, 0xfd, 0xfe, 0xfc, + 0xf7, 0xf5, 0xf3, 0xf1, 0xf4, 0x00, 0x06, 0xfb, 0xfa, 0xfb, 0xf9, 0xf9, + 0xf7, 0xff, 0x0b, 0x0a, 0x06, 0xfd, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xf9, + 0xf5, 0xf7, 0xff, 0x0a, 0x0b, 0x09, 0x06, 0x06, 0x0e, 0x12, 0x06, 0x05, + 0x1a, 0x2c, 0x29, 0x24, 0x23, 0x1c, 0x12, 0x0b, 0x07, 0x08, 0x0a, 0x0a, + 0x07, 0x03, 0x02, 0x02, 0x02, 0x07, 0x0b, 0x0a, 0x05, 0x00, 0x00, 0xff, + 0xfb, 0xf7, 0xed, 0xe4, 0xea, 0xf2, 0xf4, 0xec, 0xe8, 0xe8, 0xed, 0xf7, + 0xf3, 0xef, 0xf3, 0xf9, 0xfd, 0xff, 0x02, 0x02, 0xfd, 0xfa, 0xff, 0x08, + 0x13, 0x1d, 0x18, 0x1d, 0x1b, 0x1e, 0x1b, 0x13, 0x0d, 0x16, 0x11, 0x0d, + 0x0b, 0x05, 0x04, 0x06, 0x00, 0x04, 0x0b, 0x0b, 0x0a, 0x05, 0x00, 0xff, + 0xfd, 0xf9, 0xfd, 0xfe, 0xfa, 0xfc, 0xfa, 0xf6, 0xf8, 0xf6, 0xf1, 0xeb, + 0xf1, 0xf8, 0x06, 0x0b, 0x03, 0x04, 0x05, 0x08, 0x10, 0x08, 0x04, 0x06, + 0x0e, 0x1a, 0x12, 0x0e, 0x0e, 0x0b, 0x09, 0x09, 0x05, 0x05, 0x04, 0xff, + 0xfb, 0xfe, 0x03, 0x02, 0xf4, 0x00, 0x15, 0x0d, 0x08, 0x05, 0x02, 0x00, + 0xfc, 0xf5, 0xf8, 0x04, 0x04, 0x01, 0xfc, 0xf6, 0xf7, 0xf6, 0xf5, 0xf4, + 0xf3, 0xfa, 0x07, 0x02, 0x03, 0x07, 0x06, 0xfd, 0xfa, 0x01, 0x06, 0x03, + 0x09, 0x12, 0x0a, 0x0a, 0x10, 0x16, 0x0c, 0x0c, 0x0a, 0x09, 0x0a, 0x05, + 0x04, 0x05, 0x08, 0x07, 0x08, 0x0d, 0x14, 0x0a, 0x07, 0x08, 0x06, 0x03, + 0xff, 0xfe, 0x00, 0x07, 0x0b, 0x04, 0xfe, 0xfc, 0xfb, 0xf3, 0xe7, 0xe8, + 0xee, 0xf7, 0xfc, 0xf9, 0xf7, 0xff, 0x01, 0xfb, 0xfc, 0x02, 0x03, 0x02, + 0x0a, 0x13, 0x13, 0x13, 0x0c, 0x07, 0xff, 0x00, 0x02, 0x01, 0xff, 0xfd, + 0xfe, 0x02, 0x0f, 0x0d, 0x0b, 0x11, 0x18, 0x0f, 0x08, 0x08, 0x07, 0x04, + 0x02, 0x04, 0x01, 0x00, 0x03, 0x03, 0xff, 0xff, 0x06, 0x02, 0xfd, 0xfe, + 0x08, 0x0d, 0x0a, 0x0a, 0x09, 0x03, 0xff, 0xfc, 0xff, 0x01, 0x00, 0xff, + 0x06, 0x10, 0x0b, 0x07, 0x04, 0x02, 0x02, 0xfc, 0xfb, 0xfb, 0xf6, 0xf3, + 0xf1, 0xf0, 0xf4, 0xf6, 0xf8, 0x02, 0x0d, 0x04, 0xfd, 0xfb, 0x01, 0x0b, + 0x04, 0x00, 0x06, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0xff, 0xfe, 0x00, + 0x05, 0x0a, 0x10, 0x10, 0x14, 0x19, 0x13, 0x07, 0x07, 0x08, 0x0c, 0x0d, + 0x1c, 0x1f, 0x13, 0x11, 0x11, 0x0d, 0x0b, 0x07, 0x03, 0x00, 0x04, 0x06, + 0x02, 0x02, 0x00, 0xfc, 0xfc, 0x04, 0x0d, 0xff, 0xf8, 0xfa, 0xf8, 0xf7, + 0xf5, 0xf9, 0xf1, 0xea, 0xef, 0xeb, 0xe8, 0xef, 0xf7, 0xee, 0xee, 0xf1, + 0xf1, 0xf8, 0x01, 0xff, 0xff, 0x04, 0x05, 0x07, 0x0b, 0x06, 0x03, 0x05, + 0x17, 0x1d, 0x1f, 0x1d, 0x19, 0x0f, 0x12, 0x1a, 0x11, 0x0e, 0x10, 0x0d, + 0x0d, 0x0e, 0x0a, 0x06, 0x07, 0x14, 0x12, 0x03, 0x00, 0x04, 0x02, 0x00, + 0xfe, 0xfc, 0xfb, 0x00, 0xff, 0xfb, 0xfb, 0xf8, 0xed, 0xeb, 0xf5, 0xf9, + 0xf7, 0xfb, 0xff, 0xff, 0x04, 0x0e, 0x0a, 0x0a, 0x04, 0x00, 0x00, 0x04, + 0x15, 0x13, 0x0e, 0x0e, 0x0b, 0x07, 0x04, 0x01, 0xfd, 0xfd, 0xff, 0x04, + 0x02, 0xfc, 0xfa, 0x00, 0x03, 0x0c, 0x08, 0xfe, 0x00, 0x03, 0x00, 0xf8, + 0xf1, 0xf5, 0x00, 0x00, 0xfe, 0xfc, 0xfc, 0xfb, 0xf6, 0xf6, 0xf8, 0xfc, + 0x01, 0x06, 0x10, 0x0c, 0x05, 0x03, 0x06, 0x06, 0x00, 0xfd, 0x01, 0x09, + 0x1c, 0x20, 0x23, 0x16, 0x11, 0x0e, 0x0d, 0x08, 0x08, 0x0d, 0x0e, 0x0e, + 0x0a, 0x0c, 0x0a, 0x09, 0x08, 0x0f, 0x07, 0x01, 0x0c, 0x07, 0xf8, 0xf5, + 0xff, 0x00, 0xfc, 0xfc, 0xfd, 0xfb, 0xf8, 0xf2, 0xeb, 0xec, 0xee, 0xee, + 0xee, 0xf6, 0xfe, 0xf9, 0xfa, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfc, 0x03, + 0x12, 0x0c, 0x0a, 0x08, 0x08, 0x00, 0xfc, 0xfe, 0xfd, 0x00, 0x0e, 0x11, + 0x08, 0x08, 0x0c, 0x0a, 0x10, 0x14, 0x0c, 0x02, 0x04, 0x0a, 0x0a, 0x06, + 0x04, 0xff, 0xff, 0x07, 0x0b, 0x07, 0x00, 0xff, 0x02, 0x0b, 0x09, 0x07, + 0x09, 0x11, 0x14, 0x0e, 0x07, 0x03, 0x02, 0xfe, 0xff, 0x01, 0x01, 0x13, + 0x15, 0x08, 0x05, 0x06, 0x04, 0x00, 0xfb, 0xf9, 0xf9, 0xf9, 0xf3, 0xe9, + 0xe8, 0xed, 0xec, 0xec, 0xfe, 0x00, 0xf8, 0x04, 0x06, 0x01, 0xfd, 0xfa, + 0xfb, 0x00, 0xff, 0x01, 0x00, 0x00, 0x05, 0x05, 0x02, 0x01, 0x00, 0x03, + 0x06, 0x05, 0x11, 0x15, 0x13, 0x18, 0x11, 0x09, 0x09, 0x0d, 0x16, 0x25, + 0x19, 0x0d, 0x0a, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x05, 0x04, 0x04, 0x02, + 0x00, 0x00, 0x00, 0x04, 0x0c, 0x04, 0xfc, 0xf5, 0xf0, 0xf4, 0xf6, 0xf5, + 0xf3, 0xf2, 0xf4, 0xfa, 0x04, 0x00, 0xfb, 0xf6, 0xf4, 0xf4, 0xf2, 0xf2, + 0xf8, 0xfd, 0x07, 0x0f, 0x10, 0x0c, 0x06, 0x00, 0x01, 0x04, 0x0b, 0x13, + 0x0c, 0x14, 0x1c, 0x15, 0x0e, 0x10, 0x10, 0x12, 0x12, 0x0e, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x0e, 0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xfe, 0xfa, 0xfa, 0xfa, 0xfa, 0xf8, 0xf4, 0xf0, 0xf0, 0xf0, 0xf2, 0xf6, + 0x00, 0x0a, 0x0a, 0x0a, 0x0b, 0x0c, 0x05, 0x00, 0x00, 0x05, 0x15, 0x1a, + 0x16, 0x10, 0x0c, 0x08, 0x06, 0x04, 0x00, 0xff, 0x00, 0x00, 0x02, 0x06, + 0x01, 0x00, 0x06, 0x16, 0x10, 0x0a, 0xfe, 0xf6, 0xf6, 0xfc, 0xf8, 0xf9, + 0x00, 0x00, 0xfe, 0x00, 0x00, 0x02, 0x02, 0x02, 0xfd, 0xf9, 0xfb, 0x00, + 0xf8, 0xec, 0xf6, 0x00, 0x04, 0x04, 0x00, 0x00, 0x02, 0x16, 0x29, 0x20, + 0x18, 0x12, 0x0e, 0x0c, 0x08, 0x0a, 0x0d, 0x0b, 0x0a, 0x0b, 0x0a, 0x04, + 0x00, 0x00, 0x08, 0x07, 0x02, 0x00, 0x00, 0x03, 0x00, 0x06, 0x04, 0x00, + 0xff, 0x00, 0xf8, 0xf6, 0xf6, 0xf3, 0xf0, 0xec, 0xee, 0xf0, 0xf5, 0xf9, + 0xf6, 0xf6, 0x00, 0x08, 0x08, 0x01, 0xfc, 0xfd, 0xfe, 0x0a, 0x12, 0x0a, + 0x02, 0x07, 0x08, 0x06, 0x08, 0x12, 0x1c, 0x14, 0x0e, 0x0c, 0x07, 0x00, + 0x00, 0x07, 0x13, 0x12, 0x10, 0x0a, 0x0a, 0x0c, 0x08, 0x06, 0x04, 0x00, + 0x00, 0xf8, 0xf0, 0x04, 0x0e, 0x0b, 0x04, 0x00, 0x00, 0x03, 0x04, 0x00, + 0xff, 0xfa, 0x00, 0x03, 0x02, 0x00, 0x00, 0xfe, 0x02, 0x14, 0x10, 0x0a, + 0x06, 0x02, 0x00, 0xfe, 0xfc, 0xfa, 0xf4, 0xee, 0xe8, 0xea, 0xed, 0xec, + 0xf2, 0x02, 0x08, 0x0b, 0x00, 0xfc, 0xff, 0x00, 0xff, 0xff, 0x02, 0x05, + 0x04, 0x01, 0x05, 0x0c, 0x0d, 0x04, 0x00, 0xff, 0x00, 0x02, 0x04, 0x04, + 0x0c, 0x0e, 0x1a, 0x1e, 0x17, 0x16, 0x12, 0x10, 0x18, 0x23, 0x14, 0x0e, + 0x0c, 0x0a, 0x0c, 0x0c, 0x0c, 0x0a, 0x06, 0x08, 0x08, 0x04, 0xfc, 0xf8, + 0x00, 0x04, 0xf8, 0xea, 0xe9, 0xec, 0xf3, 0xf4, 0xf2, 0xf6, 0xf8, 0x05, + 0x01, 0xfa, 0xfa, 0xfa, 0xf6, 0xf2, 0xf0, 0xf0, 0xf0, 0xf6, 0xf8, 0xfc, + 0x01, 0xff, 0x00, 0xfe, 0x00, 0x05, 0x04, 0x02, 0x15, 0x1f, 0x24, 0x1c, + 0x16, 0x16, 0x12, 0x10, 0x0e, 0x0e, 0x0a, 0x04, 0x02, 0x00, 0xfe, 0x04, + 0x12, 0x0a, 0x08, 0x06, 0x02, 0x04, 0x06, 0x02, 0x00, 0x00, 0xfc, 0xfc, + 0xfa, 0xf9, 0xf5, 0xf5, 0xfd, 0xfb, 0xf9, 0x04, 0x0f, 0x07, 0x01, 0x03, + 0x04, 0x01, 0x05, 0x05, 0x03, 0x05, 0x05, 0x12, 0x23, 0x1d, 0x11, 0x04, + 0x01, 0x03, 0x02, 0xf5, 0xfd, 0x01, 0x07, 0x0b, 0x00, 0xf9, 0xfe, 0x0d, + 0x05, 0xfb, 0xf9, 0xf5, 0xf5, 0xfb, 0xfb, 0xf7, 0xfd, 0x07, 0x02, 0xff, + 0xfc, 0xfd, 0x01, 0x00, 0xfd, 0xf9, 0xf9, 0xf6, 0xf1, 0xed, 0xf1, 0xef, + 0xf7, 0x01, 0x09, 0x09, 0x17, 0x19, 0x15, 0x24, 0x21, 0x17, 0x11, 0x0d, + 0x0c, 0x0b, 0x0d, 0x12, 0x13, 0x0f, 0x0b, 0x03, 0xfd, 0x04, 0x11, 0x0d, + 0x0f, 0x0d, 0x09, 0x0d, 0x07, 0x05, 0x03, 0x03, 0x05, 0x01, 0xfd, 0xfb, + 0xf5, 0xf8, 0xfb, 0xf7, 0xf3, 0xf1, 0xf1, 0xf5, 0xf7, 0xfb, 0xf9, 0xf5, + 0xef, 0xf5, 0xfb, 0xee, 0xe3, 0xee, 0x01, 0x0f, 0x13, 0x13, 0x0b, 0x07, + 0x0f, 0x19, 0x15, 0x14, 0x0b, 0x07, 0x03, 0x00, 0x00, 0x0b, 0x0b, 0x09, + 0x08, 0x0b, 0x0b, 0x07, 0x05, 0x03, 0x03, 0x07, 0x06, 0x03, 0xfe, 0x01, + 0x0a, 0x0d, 0x07, 0x05, 0x03, 0xfc, 0xfd, 0x01, 0x00, 0xfd, 0xff, 0xfd, + 0xfd, 0x04, 0x05, 0x00, 0xfc, 0x02, 0x17, 0x14, 0x0e, 0x0a, 0x05, 0x00, + 0xfb, 0x00, 0x00, 0xfe, 0xf6, 0xf0, 0xf6, 0xf8, 0x0a, 0x16, 0x0a, 0x04, + 0x00, 0xfd, 0xfc, 0xfa, 0xfa, 0xfa, 0x00, 0x0e, 0x0e, 0x08, 0x00, 0x00, + 0x05, 0x02, 0x00, 0xfe, 0xfa, 0x00, 0x02, 0x02, 0x0a, 0x0e, 0x04, 0x02, + 0x06, 0x12, 0x0c, 0x08, 0x08, 0x17, 0x21, 0x16, 0x10, 0x0c, 0x08, 0x06, + 0x08, 0x0c, 0x08, 0x02, 0x00, 0xfe, 0x00, 0x06, 0xfa, 0xf4, 0xf3, 0xf2, + 0xf0, 0xf2, 0xf4, 0xf7, 0xf6, 0x00, 0x0a, 0x08, 0x00, 0xf9, 0xf6, 0xf8, + 0xfa, 0xfa, 0xf6, 0xf7, 0xfb, 0xfd, 0xff, 0xfd, 0xfc, 0xfc, 0xf8, 0xf8, + 0x06, 0x10, 0x06, 0x08, 0x10, 0x26, 0x28, 0x24, 0x1c, 0x18, 0x12, 0x0e, + 0x12, 0x10, 0x0c, 0x07, 0x04, 0x0a, 0x16, 0x10, 0x08, 0x04, 0x00, 0x00, + 0x06, 0x06, 0x01, 0xfd, 0xf8, 0xed, 0xf6, 0xf6, 0xf2, 0xf0, 0xf6, 0x00, + 0xfe, 0xff, 0x07, 0x02, 0x00, 0xff, 0xfe, 0xfe, 0xfc, 0xfa, 0xf5, 0xf8, + 0x05, 0x04, 0x00, 0xfa, 0x0a, 0x16, 0x12, 0x05, 0x08, 0x0a, 0x05, 0x07, + 0x04, 0x02, 0x04, 0x00, 0x06, 0x14, 0x0b, 0x02, 0xfc, 0xfc, 0xfa, 0xf9, + 0xf8, 0xfa, 0xfc, 0xfa, 0xfc, 0x0a, 0x0c, 0x02, 0xfe, 0xfc, 0xfe, 0x00, + 0x00, 0xfc, 0xf8, 0xfc, 0xff, 0xfe, 0xfa, 0xfe, 0xfe, 0xfe, 0x0d, 0x18, + 0x1a, 0x14, 0x0e, 0x14, 0x1f, 0x1a, 0x14, 0x0e, 0x13, 0x12, 0x0e, 0x0e, + 0x0a, 0x06, 0x04, 0x0a, 0x1a, 0x0a, 0x02, 0x00, 0x00, 0x00, 0x02, 0x02, + 0x00, 0xfe, 0xfc, 0xf8, 0xff, 0x00, 0xfc, 0xf6, 0xee, 0xef, 0xf8, 0xfc, + 0xf9, 0xf6, 0xf5, 0xf6, 0xf6, 0xf8, 0xf0, 0xe8, 0xe8, 0xe6, 0xe7, 0xf4, + 0xf6, 0xf0, 0xf5, 0x12, 0x1b, 0x16, 0x1c, 0x1f, 0x14, 0x10, 0x10, 0x0c, + 0x0a, 0x08, 0x11, 0x12, 0x0f, 0x13, 0x0b, 0x06, 0x04, 0x01, 0x06, 0x0e, + 0x14, 0x10, 0x0c, 0x0e, 0x0e, 0x08, 0x08, 0x02, 0xfe, 0x01, 0x0c, 0x08, + 0x02, 0x00, 0xfe, 0xfb, 0xfe, 0xfc, 0xfe, 0x00, 0xfd, 0xfa, 0xfe, 0x00, + 0x00, 0xfe, 0x0d, 0x0f, 0x08, 0x00, 0xf6, 0xf9, 0xf8, 0xf8, 0xf9, 0xfa, + 0x00, 0x10, 0x14, 0x14, 0x05, 0x00, 0x00, 0xfe, 0xf8, 0xf6, 0xf7, 0xf3, + 0xf6, 0xfc, 0x00, 0x08, 0x06, 0x03, 0xfc, 0xfa, 0xfe, 0x05, 0x04, 0x02, + 0x01, 0xfd, 0x00, 0x08, 0x06, 0x03, 0x04, 0x01, 0x00, 0x06, 0x10, 0x08, + 0x06, 0x13, 0x18, 0x12, 0x13, 0x15, 0x12, 0x0b, 0x0a, 0x0a, 0x06, 0x06, + 0x0f, 0x0b, 0x07, 0x03, 0x01, 0xfd, 0xfb, 0xf8, 0xf8, 0xfb, 0xfe, 0x05, + 0xff, 0x03, 0x09, 0x03, 0x00, 0xfe, 0xfa, 0xf7, 0xf8, 0xfd, 0x00, 0x01, + 0xff, 0xfb, 0xfc, 0x02, 0xfb, 0xf7, 0xee, 0xef, 0xf4, 0xfe, 0x00, 0x02, + 0x0d, 0x1e, 0x1f, 0x18, 0x14, 0x14, 0x10, 0x08, 0x02, 0x00, 0x0b, 0x12, + 0x11, 0x10, 0x0a, 0x06, 0x04, 0x00, 0xf8, 0xf8, 0xfc, 0xfd, 0xf7, 0xf7, + 0xf9, 0xfc, 0xf6, 0xfc, 0xfc, 0xfe, 0x00, 0x08, 0x02, 0x00, 0x01, 0x00, + 0xfa, 0xfa, 0xfc, 0xfb, 0xf9, 0xfe, 0x01, 0x00, 0x05, 0x01, 0x07, 0x0f, + 0x1c, 0x14, 0x11, 0x11, 0x15, 0x13, 0x0c, 0x06, 0x08, 0x19, 0x17, 0x14, + 0x0d, 0x0a, 0x06, 0x01, 0xfc, 0xf8, 0xf5, 0xf8, 0xf9, 0xf6, 0xf3, 0xf8, + 0x06, 0x07, 0x02, 0x00, 0xfc, 0xf8, 0xec, 0xed, 0xf0, 0xf3, 0xf4, 0xf3, + 0xf5, 0xfc, 0x06, 0x0e, 0x08, 0x04, 0x07, 0x12, 0x0e, 0x06, 0x0a, 0x1c, + 0x15, 0x0f, 0x11, 0x13, 0x13, 0x0b, 0x11, 0x0f, 0x14, 0x0d, 0x08, 0x06, + 0x08, 0x06, 0x04, 0x03, 0x03, 0x00, 0x00, 0xfc, 0xf9, 0xf2, 0xf3, 0xfb, + 0xfa, 0xf5, 0xf2, 0xf2, 0xf7, 0xfa, 0xf9, 0x01, 0xfe, 0xfe, 0xfa, 0xf2, + 0xf0, 0xf2, 0xf4, 0xf6, 0xf4, 0xf4, 0xfc, 0xfa, 0xf3, 0xf8, 0x17, 0x30, + 0x28, 0x1d, 0x19, 0x1b, 0x19, 0x13, 0x19, 0x17, 0x13, 0x0e, 0x0b, 0x0d, + 0x11, 0x1a, 0x1c, 0x12, 0x0a, 0x04, 0xfb, 0xfa, 0xf9, 0xfc, 0x02, 0x02, + 0x07, 0x04, 0x03, 0x00, 0x00, 0xfe, 0xfe, 0xfc, 0xf8, 0xf4, 0xf1, 0xed, + 0xef, 0xf6, 0xf8, 0xf6, 0xf1, 0xf8, 0xfc, 0xf6, 0xf0, 0xff, 0x04, 0xff, + 0x00, 0x00, 0x00, 0x03, 0x08, 0x15, 0x15, 0x1e, 0x17, 0x0c, 0x04, 0x02, + 0x04, 0x02, 0x00, 0xfa, 0xf6, 0xf8, 0xfa, 0xf7, 0xfd, 0x0f, 0x13, 0x0e, + 0x0a, 0x07, 0x06, 0x03, 0xfe, 0x00, 0x04, 0x02, 0x03, 0xff, 0xfd, 0xff, + 0x05, 0x07, 0x05, 0x04, 0x0e, 0x0d, 0x05, 0x01, 0x11, 0x15, 0x0e, 0x0f, + 0x0e, 0x0c, 0x10, 0x18, 0x1b, 0x09, 0xfc, 0xfa, 0xf9, 0xf9, 0xfa, 0xfc, + 0xfe, 0xfe, 0xfe, 0x08, 0x0c, 0x09, 0xfe, 0xf5, 0xf6, 0xf8, 0xfb, 0xfc, + 0xf8, 0xf8, 0xfd, 0xfa, 0xff, 0x03, 0x02, 0x03, 0xfa, 0xf5, 0xf1, 0xf2, + 0xf2, 0xf4, 0xf7, 0x02, 0x09, 0x00, 0xfc, 0x0c, 0x1a, 0x12, 0x0a, 0x08, + 0x06, 0x08, 0x15, 0x13, 0x0d, 0x06, 0x06, 0x07, 0x06, 0x05, 0x09, 0x0a, + 0x0a, 0x07, 0x03, 0x01, 0xff, 0xfd, 0xfc, 0xfb, 0xf8, 0xfd, 0x02, 0x12, + 0x16, 0x0f, 0x07, 0x04, 0x08, 0x04, 0x00, 0x00, 0xfc, 0xf9, 0xfa, 0x04, + 0x08, 0x03, 0x0a, 0x11, 0x0c, 0x00, 0x00, 0x08, 0x02, 0x00, 0xfe, 0x05, + 0x15, 0x21, 0x19, 0x11, 0x0b, 0x08, 0x02, 0x00, 0x00, 0xfa, 0xf7, 0xf8, + 0xf6, 0xf1, 0xed, 0xec, 0xec, 0xee, 0xf7, 0xfc, 0xf6, 0xf4, 0xf5, 0xf4, + 0xf3, 0xf4, 0xf7, 0xfd, 0xfe, 0xfa, 0xfe, 0x0b, 0x0a, 0x05, 0x04, 0x03, + 0x06, 0x0d, 0x0b, 0x08, 0x03, 0x0e, 0x1b, 0x23, 0x22, 0x18, 0x13, 0x1d, + 0x25, 0x20, 0x1b, 0x15, 0x0f, 0x09, 0x02, 0x03, 0x07, 0x09, 0x0b, 0x06, + 0x02, 0xff, 0xff, 0xfe, 0xfe, 0xf4, 0xef, 0xef, 0xf1, 0xf4, 0xf9, 0xfc, + 0xf8, 0xf5, 0xfb, 0x00, 0xfd, 0xf3, 0xe8, 0xe8, 0xe6, 0xe9, 0xeb, 0xee, + 0xf8, 0xf9, 0xfc, 0x0c, 0x19, 0x2a, 0x22, 0x18, 0x14, 0x0b, 0x0b, 0x15, + 0x18, 0x12, 0x0b, 0x10, 0x0d, 0x09, 0x08, 0x09, 0x0c, 0x0b, 0x0c, 0x0c, + 0x0a, 0x04, 0x04, 0x05, 0x02, 0x00, 0x00, 0xfc, 0xfc, 0xfb, 0xf9, 0xf8, + 0xf7, 0xf5, 0xf6, 0xf6, 0xf7, 0xf5, 0xf2, 0xf4, 0xf8, 0xf8, 0xf9, 0x00, + 0xfc, 0xfc, 0xf8, 0x04, 0x0f, 0x07, 0x02, 0x00, 0xff, 0x12, 0x1d, 0x2a, + 0x26, 0x1e, 0x17, 0x11, 0x0d, 0x0b, 0x06, 0x03, 0x02, 0x00, 0x02, 0x0a, + 0x08, 0x06, 0x03, 0x04, 0x0b, 0xfe, 0xf1, 0xf2, 0xf2, 0xf5, 0xfa, 0x00, + 0xfd, 0xff, 0x04, 0x01, 0xfe, 0xf8, 0xf7, 0xfb, 0xff, 0x03, 0x03, 0xff, + 0xfd, 0xfa, 0x00, 0x0b, 0x06, 0x01, 0x03, 0x05, 0x0b, 0x13, 0x0e, 0x0d, + 0x09, 0x08, 0x02, 0xff, 0xfe, 0x00, 0x04, 0x13, 0x11, 0x0a, 0x07, 0x07, + 0x09, 0x00, 0xf9, 0xf2, 0xee, 0xeb, 0xf4, 0x06, 0x08, 0x02, 0x02, 0x02, + 0x01, 0x01, 0x03, 0x03, 0xfe, 0xfb, 0xfd, 0xff, 0x02, 0xff, 0x00, 0xfc, + 0xfc, 0x07, 0x1b, 0x16, 0x11, 0x09, 0x04, 0x0d, 0x14, 0x12, 0x10, 0x10, + 0x0e, 0x0a, 0x04, 0x00, 0x00, 0xfc, 0xf8, 0xfd, 0x02, 0x01, 0x00, 0xff, + 0xfe, 0xfa, 0xfd, 0x09, 0x05, 0xff, 0x05, 0x05, 0x04, 0x02, 0xff, 0x00, + 0xfe, 0xfc, 0xf7, 0xfe, 0xfe, 0xf9, 0xfe, 0x09, 0x05, 0x03, 0x01, 0xfe, + 0x01, 0x13, 0x10, 0x08, 0x07, 0x08, 0x11, 0x1b, 0x14, 0x0d, 0x06, 0x03, + 0x01, 0xfc, 0xf7, 0xf5, 0xf6, 0xf9, 0xfa, 0xfa, 0xfb, 0xfd, 0xfa, 0xf7, + 0xf7, 0xfb, 0xf8, 0xf8, 0xf7, 0xf2, 0xf4, 0xf5, 0xf8, 0xf8, 0x01, 0x15, + 0x16, 0x10, 0x0d, 0x0a, 0x09, 0x0e, 0x14, 0x12, 0x0c, 0x05, 0x05, 0x15, + 0x24, 0x1b, 0x15, 0x15, 0x17, 0x12, 0x13, 0x13, 0x12, 0x15, 0x15, 0x0d, + 0x09, 0x04, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x03, 0x01, 0xf8, 0xf3, 0xec, + 0xed, 0xe9, 0xe4, 0xe1, 0xe6, 0xee, 0xec, 0xea, 0xe9, 0xf0, 0xf6, 0xf7, + 0xf5, 0xf5, 0xf7, 0xf8, 0xfb, 0xfb, 0x00, 0x0d, 0x07, 0x01, 0x06, 0x1c, + 0x1a, 0x12, 0x0d, 0x0d, 0x0f, 0x19, 0x1c, 0x1f, 0x18, 0x14, 0x13, 0x12, + 0x0e, 0x0e, 0x0a, 0x0b, 0x0e, 0x14, 0x16, 0x0f, 0x0b, 0x08, 0x00, 0xff, + 0x00, 0xfc, 0xfb, 0xfd, 0xfc, 0xf4, 0xf3, 0xf5, 0xf9, 0xfe, 0x01, 0xff, + 0xfc, 0xfb, 0x00, 0x01, 0xfe, 0xf1, 0xeb, 0xf0, 0xf1, 0xf5, 0x06, 0x02, + 0xff, 0xff, 0xfe, 0x14, 0x26, 0x25, 0x1d, 0x16, 0x13, 0x0d, 0x06, 0x02, + 0xff, 0xfe, 0xfb, 0x00, 0x03, 0x01, 0xff, 0x00, 0xfa, 0xfa, 0x00, 0x01, + 0x00, 0x02, 0xff, 0xfe, 0xfd, 0xf8, 0xf8, 0xfc, 0xff, 0xfb, 0xfa, 0xfc, + 0xfc, 0xfc, 0x04, 0x02, 0xfc, 0xfe, 0x01, 0xfd, 0xfc, 0x0e, 0x0d, 0x06, + 0x06, 0x03, 0x08, 0x15, 0x17, 0x10, 0x12, 0x11, 0x0c, 0x08, 0x07, 0x17, + 0x16, 0x14, 0x16, 0x16, 0x10, 0x0c, 0x0a, 0x03, 0xfc, 0xfa, 0xfb, 0xfd, + 0xfc, 0xfa, 0xfd, 0x00, 0xfa, 0xec, 0xea, 0xf4, 0xff, 0x02, 0xfd, 0xfd, + 0x00, 0x04, 0x03, 0xfe, 0xfb, 0xf6, 0xf1, 0xf6, 0x08, 0x0f, 0x04, 0x00, + 0xfe, 0xfe, 0x08, 0x10, 0x09, 0x09, 0x05, 0x03, 0x01, 0x02, 0x00, 0xff, + 0x00, 0x06, 0x07, 0x07, 0x07, 0x04, 0x02, 0x0c, 0x0d, 0x09, 0x05, 0x01, + 0xfe, 0xff, 0xff, 0xfc, 0xfa, 0xfb, 0xfe, 0x03, 0x09, 0x06, 0x06, 0x03, + 0x0d, 0x0f, 0x08, 0x03, 0x04, 0x06, 0xff, 0x0b, 0x13, 0x0a, 0x04, 0x01, + 0x03, 0x0c, 0x1a, 0x15, 0x10, 0x09, 0x06, 0x00, 0xfe, 0xfe, 0x01, 0xfd, + 0xff, 0x02, 0x03, 0x02, 0x00, 0xf2, 0xe4, 0xed, 0xf6, 0xf5, 0xf2, 0xf2, + 0xf7, 0xf8, 0xf8, 0x04, 0x08, 0x05, 0x03, 0x06, 0x06, 0x01, 0x05, 0x0e, + 0x0e, 0x0a, 0x06, 0x00, 0x02, 0x01, 0x0a, 0x16, 0x0d, 0x09, 0x05, 0x05, + 0x13, 0x27, 0x25, 0x1d, 0x19, 0x13, 0x0e, 0x09, 0x03, 0x05, 0x04, 0x05, + 0x02, 0xfc, 0xfc, 0xfa, 0xf7, 0xef, 0xee, 0xee, 0xed, 0xec, 0xec, 0xea, + 0xf2, 0xfa, 0xf2, 0xf1, 0xeb, 0xeb, 0xf2, 0xf5, 0xf7, 0xfb, 0x02, 0x0c, + 0x16, 0x10, 0x0d, 0x08, 0x00, 0x04, 0x20, 0x1e, 0x14, 0x0d, 0x0e, 0x13, + 0x1f, 0x28, 0x25, 0x1f, 0x16, 0x09, 0xfc, 0xfe, 0x07, 0x16, 0x18, 0x13, + 0x0c, 0x09, 0x09, 0x06, 0x00, 0xfc, 0xf9, 0xf7, 0xf2, 0xee, 0xf2, 0xf2, + 0xf3, 0xf3, 0xf4, 0xee, 0xe7, 0xed, 0xf2, 0xf5, 0xf9, 0x05, 0x02, 0xfb, + 0xfd, 0xfc, 0xfa, 0xf2, 0xf5, 0x08, 0x08, 0x0d, 0x13, 0x09, 0x0c, 0x12, + 0x1c, 0x18, 0x12, 0x10, 0x0c, 0x05, 0x03, 0x01, 0x04, 0x10, 0x0c, 0x06, + 0x01, 0x01, 0x01, 0xfb, 0xfd, 0x0a, 0x09, 0x05, 0x01, 0x00, 0xff, 0xfc, + 0xfd, 0xfe, 0xfe, 0xfc, 0xf6, 0xf2, 0xfb, 0x01, 0x07, 0x09, 0x06, 0x02, + 0x03, 0x03, 0x03, 0x00, 0x0e, 0x0f, 0xfc, 0xfa, 0xfd, 0x01, 0x02, 0x09, + 0x17, 0x13, 0x11, 0x18, 0x1f, 0x15, 0x11, 0x10, 0x13, 0x10, 0x09, 0x04, + 0x02, 0x00, 0xfb, 0xf6, 0xee, 0xf3, 0xf6, 0xf3, 0xf5, 0xf4, 0xef, 0xf4, + 0xfc, 0x00, 0xfb, 0xf9, 0xf9, 0xfb, 0xfb, 0xfd, 0x02, 0x01, 0xfd, 0xfc, + 0xf8, 0xf1, 0xf3, 0x04, 0x15, 0x09, 0x03, 0x04, 0x03, 0x04, 0x02, 0x0d, + 0x16, 0x12, 0x0d, 0x0a, 0x05, 0x03, 0x06, 0x0f, 0x12, 0x09, 0x06, 0x0b, + 0x1c, 0x13, 0x0c, 0x0b, 0x0b, 0x05, 0xfe, 0xfe, 0x03, 0x02, 0x00, 0x01, + 0x02, 0x01, 0x05, 0x04, 0xff, 0xff, 0xfc, 0x01, 0x06, 0x0a, 0x05, 0x02, + 0x03, 0x00, 0x03, 0x0f, 0x09, 0x03, 0x01, 0xff, 0xfb, 0xf4, 0xfc, 0x0c, + 0x09, 0x02, 0x00, 0xfa, 0xfb, 0xf6, 0xf7, 0xfd, 0xfd, 0xfa, 0xf6, 0xf7, + 0xf6, 0xf2, 0xf6, 0x00, 0x00, 0xfd, 0xfc, 0xfc, 0x05, 0x09, 0x07, 0x07, + 0x02, 0x00, 0xff, 0xfd, 0xfc, 0x00, 0x0c, 0x0e, 0x09, 0x06, 0x03, 0x09, + 0x0a, 0x09, 0x16, 0x16, 0x13, 0x11, 0x13, 0x12, 0x10, 0x0f, 0x13, 0x1c, + 0x18, 0x15, 0x11, 0x0f, 0x0c, 0x0a, 0x0d, 0x09, 0x02, 0x00, 0x00, 0xfb, + 0xf6, 0xf5, 0xf6, 0xf4, 0xf0, 0xed, 0xe7, 0xe2, 0xe7, 0xec, 0xf3, 0xf2, + 0xf2, 0xf5, 0xfc, 0xf7, 0xf9, 0x09, 0x0e, 0x07, 0x04, 0x02, 0x00, 0xfb, + 0xfb, 0x07, 0x1b, 0x18, 0x0f, 0x08, 0x01, 0xff, 0x09, 0x0a, 0x10, 0x16, + 0x13, 0x13, 0x14, 0x11, 0x11, 0x13, 0x10, 0x0f, 0x09, 0x06, 0x06, 0x02, + 0xfe, 0xfc, 0xf9, 0xf9, 0xf7, 0xf5, 0xf3, 0xf4, 0xf7, 0xf6, 0xf4, 0xf6, + 0xf8, 0xfa, 0xfb, 0xfa, 0xff, 0x04, 0x08, 0x04, 0x01, 0x02, 0x03, 0xfc, + 0x00, 0x1d, 0x21, 0x16, 0x0d, 0x0c, 0x0b, 0x08, 0x06, 0x04, 0x0f, 0x15, + 0x12, 0x0c, 0x07, 0x06, 0x07, 0x0c, 0x07, 0xfc, 0xfa, 0xfe, 0xff, 0xfe, + 0xfe, 0x07, 0x04, 0x01, 0xfe, 0xf8, 0xf8, 0xff, 0xfb, 0xf6, 0xf4, 0xf2, + 0xf2, 0xf3, 0xf6, 0xf9, 0xfc, 0x01, 0x04, 0x00, 0xfc, 0xfc, 0xf8, 0xf9, + 0x08, 0x18, 0x10, 0x0a, 0x04, 0x05, 0x0c, 0x0c, 0x06, 0x0d, 0x1e, 0x20, + 0x18, 0x16, 0x14, 0x17, 0x17, 0x0f, 0x05, 0xff, 0x02, 0x00, 0xf9, 0xf7, + 0xf4, 0xf7, 0xfc, 0xf9, 0xfb, 0xf7, 0xfb, 0x02, 0xfb, 0xf9, 0xfc, 0xfa, + 0xfb, 0xfc, 0xfc, 0xfc, 0x02, 0x07, 0x04, 0xfe, 0xf9, 0xf6, 0xf6, 0x00, + 0x1d, 0x1b, 0x0e, 0x08, 0x04, 0x06, 0x09, 0x03, 0xfa, 0xfc, 0x09, 0x0d, + 0x0b, 0x0a, 0x11, 0x16, 0x0f, 0x0b, 0x11, 0x10, 0x09, 0x07, 0x04, 0x00, + 0x02, 0x00, 0xfa, 0xf6, 0xf8, 0xfa, 0xfb, 0xf8, 0xf8, 0xf2, 0xf5, 0x01, + 0x02, 0x04, 0x05, 0x10, 0x11, 0x07, 0x06, 0x00, 0xfc, 0xfc, 0x00, 0x0b, + 0x14, 0x0c, 0x02, 0xfd, 0xfd, 0xfc, 0xfb, 0xf9, 0xf8, 0xfd, 0x0a, 0x06, + 0x00, 0x02, 0x07, 0x06, 0x03, 0x00, 0xfe, 0xfa, 0xfa, 0xf9, 0xfd, 0x05, + 0x05, 0x02, 0x05, 0x08, 0x05, 0x0c, 0x0a, 0x08, 0x05, 0x03, 0x02, 0xfe, + 0xfe, 0x01, 0x04, 0x10, 0x0a, 0x06, 0x03, 0x03, 0x07, 0x03, 0x09, 0x1b, + 0x1e, 0x16, 0x10, 0x0b, 0x08, 0x06, 0x05, 0x06, 0x07, 0x07, 0x0d, 0x0a, + 0x06, 0x08, 0x08, 0x05, 0x01, 0x00, 0xfc, 0xf4, 0xef, 0xf1, 0xf4, 0xf0, + 0xf1, 0xf3, 0xf2, 0xf2, 0xf2, 0xf0, 0xf4, 0xf4, 0xf4, 0xf9, 0xfc, 0x05, + 0x02, 0x01, 0x04, 0x08, 0x05, 0x05, 0x00, 0xfb, 0xfe, 0x01, 0x0d, 0x1c, + 0x13, 0x0a, 0x06, 0x0a, 0x0c, 0x13, 0x12, 0x10, 0x0d, 0x0f, 0x13, 0x16, + 0x11, 0x15, 0x16, 0x15, 0x0f, 0x0d, 0x09, 0x01, 0x00, 0x00, 0xfd, 0xfb, + 0xfd, 0xfe, 0xfe, 0xfe, 0xf9, 0xf2, 0xf5, 0xff, 0x01, 0xf7, 0xf1, 0xf5, + 0xfa, 0xfd, 0x05, 0x08, 0x00, 0x00, 0xfc, 0xfe, 0x0a, 0x07, 0x15, 0x12, + 0x0b, 0x07, 0x05, 0x01, 0xfc, 0xfb, 0xfa, 0xfa, 0xf8, 0xf9, 0x07, 0x0a, + 0x03, 0x03, 0x08, 0x09, 0x06, 0x06, 0x03, 0xfc, 0xfb, 0xfd, 0x00, 0x03, + 0x04, 0x03, 0x05, 0xfc, 0xf9, 0xfa, 0xfd, 0xfb, 0xfa, 0xfb, 0xfe, 0xff, + 0xfe, 0xf9, 0xfe, 0x04, 0x09, 0x0b, 0x06, 0x07, 0x05, 0x0a, 0x1c, 0x14, + 0x0d, 0x0f, 0x0e, 0x0d, 0x15, 0x16, 0x15, 0x10, 0x0f, 0x10, 0x14, 0x18, + 0x16, 0x12, 0x0b, 0x07, 0x04, 0x00, 0xfa, 0xf7, 0xf7, 0xf6, 0xef, 0xf1, + 0xfa, 0xfe, 0xfe, 0xf7, 0xf5, 0xf6, 0xf2, 0xef, 0xf1, 0xfa, 0xfe, 0xf8, + 0xf1, 0xed, 0xf2, 0xf6, 0xfa, 0xfa, 0xfb, 0xfb, 0xfa, 0x0c, 0x0f, 0x0b, + 0x0e, 0x10, 0x0e, 0x07, 0x05, 0x05, 0x06, 0x05, 0x05, 0x07, 0x0f, 0x12, + 0x14, 0x1e, 0x1b, 0x14, 0x0e, 0x0a, 0x05, 0x02, 0x04, 0x03, 0xff, 0xfd, + 0xff, 0x01, 0xfe, 0xfd, 0x00, 0xfe, 0xfc, 0xfb, 0x04, 0x09, 0x07, 0x05, + 0x06, 0x02, 0x05, 0x08, 0x07, 0x06, 0x07, 0x03, 0x01, 0x0e, 0x0d, 0x05, + 0x04, 0x05, 0x01, 0x00, 0xfc, 0xf8, 0xfa, 0xf8, 0xf8, 0x02, 0x0e, 0x01, + 0xfe, 0xfa, 0xfe, 0x02, 0xff, 0xfb, 0xf5, 0xf2, 0xfc, 0x09, 0x0f, 0x0b, + 0x0a, 0x03, 0xff, 0xff, 0xfe, 0xfc, 0xf8, 0xf9, 0xfb, 0xff, 0xff, 0xfd, + 0xfa, 0xfd, 0x02, 0x01, 0x03, 0x10, 0x0e, 0x08, 0x12, 0x1e, 0x17, 0x0f, + 0x0e, 0x0e, 0x11, 0x0e, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x06, 0x12, 0x11, + 0x0c, 0x06, 0x05, 0x00, 0xfc, 0xf8, 0xfb, 0xfe, 0xfe, 0xfc, 0xfb, 0xfd, + 0xf9, 0xfa, 0xf6, 0xf7, 0xfa, 0xf9, 0x00, 0x02, 0x00, 0x00, 0xff, 0xfc, + 0xfa, 0xfa, 0xfd, 0x00, 0x03, 0x02, 0xff, 0x03, 0x14, 0x13, 0x10, 0x0b, + 0x02, 0x03, 0x0c, 0x0c, 0x0b, 0x0c, 0x0c, 0x06, 0x00, 0x06, 0x12, 0x12, + 0x0c, 0x07, 0x03, 0x02, 0xff, 0xfd, 0xfe, 0xff, 0xfe, 0xfc, 0xfc, 0xff, + 0x00, 0x00, 0x00, 0x02, 0xfb, 0xf5, 0xf4, 0xfa, 0x00, 0x00, 0xfe, 0xfd, + 0xfd, 0xfe, 0x06, 0x16, 0x11, 0x07, 0x02, 0x04, 0x14, 0x12, 0x09, 0x05, + 0x05, 0x04, 0x04, 0x04, 0xff, 0xfe, 0xf9, 0xf3, 0xf6, 0x03, 0x11, 0x14, + 0x0d, 0x04, 0x01, 0x04, 0x03, 0xfe, 0xfb, 0x06, 0x0c, 0x07, 0x0a, 0x06, + 0x02, 0x01, 0x00, 0x00, 0xfb, 0xfb, 0xfc, 0xfd, 0xff, 0xfe, 0xfa, 0xfa, + 0xfa, 0xf2, 0xfc, 0x06, 0x0b, 0x08, 0x05, 0x07, 0x13, 0x10, 0x0f, 0x13, + 0x1c, 0x14, 0x0a, 0x06, 0x03, 0x01, 0xff, 0x00, 0x05, 0x10, 0x12, 0x10, + 0x09, 0x07, 0x01, 0xfa, 0xf9, 0xf3, 0xf2, 0xfe, 0x01, 0xff, 0xfc, 0xfa, + 0xfc, 0xfc, 0xf9, 0xf7, 0xfa, 0xf6, 0xf3, 0xf2, 0xf8, 0xfa, 0xf6, 0xf4, + 0xf5, 0xf2, 0xfd, 0x05, 0x04, 0xfe, 0x00, 0x0e, 0x1a, 0x18, 0x13, 0x11, + 0x11, 0x0f, 0x10, 0x0c, 0x09, 0x06, 0x05, 0x05, 0x15, 0x23, 0x16, 0x11, + 0x0d, 0x0b, 0x0e, 0x0b, 0x09, 0x07, 0x05, 0x04, 0x03, 0x06, 0x03, 0xfe, + 0xfa, 0xf8, 0xef, 0xf0, 0x01, 0x03, 0xff, 0xfb, 0xf8, 0xf8, 0xfe, 0xfd, + 0xff, 0x00, 0xff, 0x03, 0x01, 0xfd, 0xfc, 0x05, 0x08, 0x03, 0x05, 0x04, + 0x00, 0xff, 0x00, 0xfc, 0xf7, 0xf5, 0xf3, 0xf4, 0x05, 0x0d, 0x05, 0x03, + 0x01, 0x01, 0xfe, 0xfd, 0xff, 0x07, 0x0d, 0x0e, 0x0d, 0x0b, 0x0a, 0x0a, + 0x0b, 0x06, 0x03, 0x02, 0x00, 0xfe, 0xfd, 0xfc, 0xfa, 0xf7, 0xf9, 0xf9, + 0x04, 0x0b, 0x0b, 0x15, 0x11, 0x07, 0x08, 0x1d, 0x21, 0x1b, 0x15, 0x0d, + 0x09, 0x09, 0x09, 0x05, 0x02, 0x01, 0x03, 0x07, 0x13, 0x0c, 0x08, 0x07, + 0x04, 0xff, 0xfb, 0xf8, 0xef, 0xf6, 0xfd, 0xfd, 0x01, 0xf9, 0xf4, 0xf7, + 0xf7, 0xf6, 0xfe, 0xfd, 0xf7, 0xf2, 0xf2, 0xf8, 0xfb, 0xf6, 0xf4, 0xf3, + 0xf5, 0xf8, 0xfd, 0x01, 0x00, 0xfb, 0x06, 0x17, 0x17, 0x1b, 0x14, 0x10, + 0x0b, 0x06, 0x03, 0x04, 0x09, 0x0a, 0x09, 0x13, 0x13, 0x0b, 0x07, 0x08, + 0x08, 0x05, 0x05, 0x07, 0x04, 0x04, 0x05, 0x05, 0x05, 0x04, 0xff, 0xff, + 0x03, 0x00, 0x03, 0x04, 0x07, 0x07, 0x01, 0xfd, 0xfd, 0xfb, 0xfb, 0x05, + 0x07, 0x02, 0x04, 0x0b, 0x0d, 0x08, 0x0c, 0x15, 0x0b, 0x01, 0x00, 0xfe, + 0xfb, 0xf9, 0xf8, 0xf4, 0xf6, 0xf8, 0x05, 0x0d, 0x05, 0xfe, 0xf7, 0xfa, + 0xfe, 0x02, 0x05, 0x01, 0xff, 0x00, 0x05, 0x08, 0x01, 0xff, 0x03, 0x05, + 0x04, 0x03, 0x00, 0xfb, 0xfc, 0xfc, 0xfb, 0xf8, 0xf4, 0xf4, 0xf4, 0xfe, + 0x04, 0x04, 0x07, 0x0e, 0x0d, 0x09, 0x0b, 0x18, 0x1b, 0x18, 0x13, 0x10, + 0x0e, 0x0b, 0x09, 0x06, 0x04, 0x04, 0x0e, 0x0a, 0x07, 0x05, 0x08, 0x06, + 0x04, 0x03, 0x07, 0x06, 0x09, 0x04, 0x01, 0xff, 0xfa, 0xfa, 0x06, 0x07, + 0xff, 0xfb, 0xfa, 0xf7, 0xf8, 0xfa, 0xf9, 0xf6, 0xf0, 0xee, 0xf0, 0xf6, + 0xf4, 0xf9, 0x02, 0x05, 0xff, 0x05, 0x0e, 0x14, 0x15, 0x14, 0x0f, 0x06, + 0x01, 0x00, 0x00, 0x01, 0x00, 0x13, 0x18, 0x10, 0x0c, 0x07, 0x08, 0x09, + 0x07, 0x03, 0x02, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 0x01, 0x0a, 0x09, + 0x03, 0xfe, 0xfb, 0xfc, 0xfc, 0xfc, 0xff, 0x04, 0x00, 0xfd, 0x04, 0x00, + 0xfc, 0x02, 0x07, 0x05, 0x04, 0x02, 0x02, 0x0b, 0x05, 0x01, 0x03, 0xfe, + 0xfd, 0xf9, 0xf8, 0xfe, 0x08, 0x12, 0x0b, 0x06, 0x03, 0xff, 0xfc, 0xfa, + 0xf9, 0xfb, 0x0c, 0x0d, 0x0c, 0x10, 0x11, 0x0f, 0x0d, 0x0b, 0x02, 0xfd, + 0xfb, 0xfd, 0x00, 0x00, 0xfd, 0xfd, 0x00, 0x00, 0xf7, 0xfb, 0x00, 0xfc, + 0xff, 0x00, 0x09, 0x15, 0x15, 0x0d, 0x0c, 0x14, 0x0f, 0x0e, 0x0a, 0x01, + 0x00, 0x00, 0x02, 0x02, 0x0a, 0x0a, 0x06, 0x05, 0xff, 0xff, 0x00, 0x00, + 0xff, 0xfc, 0xfd, 0xfe, 0xfd, 0xfd, 0xfd, 0xfc, 0xfb, 0xfb, 0xfd, 0x03, + 0x05, 0x01, 0xfe, 0xfc, 0xfc, 0xf9, 0xef, 0xee, 0xf1, 0xf4, 0xf6, 0xfc, + 0xff, 0xfe, 0x09, 0x13, 0x0c, 0x0e, 0x19, 0x21, 0x19, 0x12, 0x0c, 0x09, + 0x08, 0x0e, 0x0d, 0x12, 0x13, 0x0e, 0x09, 0x07, 0x06, 0x08, 0x06, 0x03, + 0x00, 0x02, 0x05, 0x05, 0x03, 0x04, 0x03, 0x06, 0x08, 0x01, 0xfa, 0xfa, + 0xf9, 0xf9, 0xf9, 0xf7, 0xf7, 0xf6, 0xf6, 0xf6, 0x06, 0x0d, 0x08, 0x01, + 0xfc, 0xfb, 0x00, 0xff, 0xfa, 0xfb, 0x06, 0x12, 0x08, 0xfb, 0xfe, 0x03, + 0x00, 0x01, 0x09, 0x06, 0x03, 0xff, 0xfe, 0x02, 0x00, 0x06, 0x08, 0x04, + 0x05, 0x03, 0x03, 0x01, 0x08, 0x10, 0x0d, 0x09, 0x06, 0x03, 0xfe, 0xfc, + 0xfd, 0xfe, 0xfc, 0xff, 0xfe, 0xfd, 0xfe, 0x02, 0x08, 0x07, 0x06, 0x03, + 0xff, 0x02, 0x0c, 0x08, 0x04, 0x0f, 0x1c, 0x1f, 0x14, 0x0b, 0x06, 0x00, + 0x00, 0x06, 0x08, 0x0b, 0x0d, 0x08, 0x08, 0x0e, 0x0f, 0x0c, 0x09, 0xfc, + 0xf6, 0xf6, 0xf8, 0xfe, 0x01, 0x02, 0x06, 0x06, 0x02, 0xff, 0xfb, 0xf6, + 0xf6, 0xf6, 0xf2, 0xed, 0xef, 0xf3, 0xf8, 0xfa, 0xf1, 0xeb, 0xed, 0xf5, + 0xfb, 0xfe, 0x05, 0x05, 0x05, 0x07, 0x14, 0x17, 0x0c, 0x09, 0x07, 0x05, + 0x0c, 0x0e, 0x17, 0x16, 0x0f, 0x0a, 0x07, 0x05, 0x07, 0x07, 0x06, 0x09, + 0x09, 0x04, 0x07, 0x0e, 0x11, 0x0d, 0x0c, 0x09, 0x05, 0x02, 0x01, 0x03, + 0x00, 0xfb, 0xfc, 0x02, 0x03, 0x04, 0x08, 0x04, 0x02, 0x00, 0x00, 0xfb, + 0xf8, 0xfd, 0x00, 0x00, 0xfe, 0xfc, 0x03, 0x08, 0x03, 0x04, 0x06, 0x0f, + 0xfe, 0xf5, 0xf8, 0xfa, 0xfe, 0xfe, 0xfe, 0xff, 0xfe, 0xfb, 0xfa, 0x09, + 0x0a, 0x01, 0xfd, 0xff, 0x04, 0x07, 0x0a, 0x07, 0xff, 0xfa, 0x01, 0x06, + 0x02, 0x00, 0xfd, 0xf9, 0xfe, 0x05, 0x04, 0x06, 0x06, 0x06, 0x07, 0x08, + 0x0d, 0x13, 0x12, 0x0e, 0x09, 0x07, 0x10, 0x11, 0x0a, 0x09, 0x0d, 0x0a, + 0x07, 0x04, 0x01, 0x01, 0x02, 0x06, 0x0b, 0x0d, 0x08, 0x03, 0x02, 0x02, + 0xfe, 0xfe, 0xfc, 0xfd, 0xff, 0xf9, 0xf5, 0xf8, 0x01, 0x07, 0xfe, 0xf5, + 0xf2, 0xf2, 0xf0, 0xf5, 0x00, 0xff, 0x03, 0x04, 0x01, 0x02, 0x01, 0xff, + 0xfb, 0xfe, 0x00, 0x05, 0x06, 0x0a, 0x15, 0x15, 0x17, 0x1e, 0x18, 0x11, + 0x0f, 0x0d, 0x05, 0x01, 0x02, 0x07, 0x0b, 0x08, 0x01, 0xfc, 0x00, 0x02, + 0x01, 0x00, 0x02, 0x05, 0x04, 0x03, 0xff, 0xfb, 0xfa, 0xfd, 0xfb, 0xf9, + 0xf9, 0xf9, 0xf7, 0xff, 0x03, 0x0a, 0x08, 0x02, 0x00, 0xfc, 0xf9, 0xfc, + 0x01, 0x02, 0x09, 0x06, 0x01, 0x02, 0x0f, 0x14, 0x16, 0x0b, 0x08, 0x0b, + 0x0d, 0x06, 0x00, 0xfb, 0x03, 0x0b, 0x0b, 0x04, 0x03, 0x03, 0x07, 0x04, + 0x02, 0x01, 0x02, 0x00, 0x03, 0x06, 0x04, 0xff, 0xfc, 0xfd, 0xff, 0x00, + 0xfb, 0xfb, 0x02, 0xfc, 0xf5, 0xfa, 0x03, 0x04, 0x04, 0xff, 0xff, 0x03, + 0x03, 0x03, 0x09, 0x04, 0xff, 0x01, 0x14, 0x13, 0x0a, 0x08, 0x0f, 0x0e, + 0x0a, 0x08, 0x04, 0x00, 0x05, 0x08, 0x07, 0x08, 0x09, 0x05, 0x07, 0x02, + 0x02, 0x04, 0x02, 0x06, 0x06, 0x07, 0x04, 0xfe, 0xfa, 0xf7, 0xf4, 0xf3, + 0xf0, 0xf5, 0xfd, 0xfa, 0xf5, 0xf5, 0xfb, 0xfd, 0xfe, 0xfa, 0xfc, 0x02, + 0xfe, 0xfe, 0x02, 0x01, 0x06, 0x14, 0x19, 0x0e, 0x08, 0x08, 0x0f, 0x16, + 0x0f, 0x07, 0x05, 0x0a, 0x0f, 0x11, 0x10, 0x0d, 0x0c, 0x10, 0x14, 0x0c, + 0x00, 0xfd, 0x03, 0x0a, 0x02, 0xfe, 0x00, 0xfc, 0xfd, 0x01, 0x00, 0x00, + 0x06, 0x0a, 0x05, 0x01, 0xfd, 0xfd, 0xf8, 0xf3, 0xf1, 0xf4, 0xfa, 0xf8, + 0xf4, 0xf4, 0xf9, 0xfa, 0x05, 0x10, 0x0e, 0x06, 0x02, 0x01, 0x00, 0xff, + 0xff, 0xfa, 0xfc, 0xfd, 0xfe, 0xfb, 0x00, 0x05, 0x08, 0x06, 0x09, 0x04, + 0x03, 0x08, 0x07, 0x0b, 0x0d, 0x09, 0x04, 0xfe, 0xfe, 0x00, 0x02, 0x0a, + 0x14, 0x10, 0x0b, 0x03, 0x04, 0x09, 0x07, 0x04, 0x07, 0x0d, 0x0b, 0x08, + 0x05, 0x05, 0x05, 0x08, 0x08, 0x12, 0x0e, 0x09, 0x08, 0x08, 0x09, 0x04, + 0xfd, 0x00, 0x04, 0x01, 0x00, 0xfd, 0xf6, 0xf8, 0x00, 0x05, 0x03, 0xfc, + 0xf7, 0xf9, 0xf7, 0xf7, 0x01, 0xfb, 0xf1, 0xf2, 0xfb, 0xfb, 0xfc, 0x03, + 0x00, 0xfb, 0xfa, 0xf7, 0xf9, 0xfb, 0xfa, 0xfe, 0x08, 0x07, 0x02, 0xfc, + 0xfb, 0x07, 0x0f, 0x12, 0x1b, 0x20, 0x19, 0x17, 0x15, 0x12, 0x0f, 0x07, + 0x03, 0x00, 0x00, 0x04, 0x07, 0x06, 0x06, 0x05, 0x05, 0x08, 0x09, 0x06, + 0x01, 0xff, 0xfe, 0xfe, 0xfd, 0xfd, 0xf7, 0xf6, 0xf3, 0xf8, 0xff, 0x00, + 0x03, 0x0c, 0x08, 0x08, 0x0e, 0x0a, 0x06, 0x06, 0x05, 0x02, 0xff, 0x00, + 0x07, 0x06, 0x03, 0x07, 0x14, 0x13, 0x09, 0x03, 0x02, 0x02, 0x05, 0x07, + 0x02, 0xfe, 0x01, 0x05, 0x02, 0xfb, 0xf9, 0xf7, 0xf4, 0xf5, 0xfb, 0xfa, + 0xf8, 0xfa, 0x01, 0x04, 0xfc, 0xf9, 0xf8, 0xfb, 0x00, 0x04, 0x07, 0x03, + 0x01, 0xff, 0x02, 0x00, 0xff, 0xfe, 0x04, 0x03, 0x00, 0x02, 0x13, 0x1a, + 0x16, 0x0f, 0x09, 0x0a, 0x13, 0x11, 0x0d, 0x0c, 0x0d, 0x09, 0x0c, 0x0f, + 0x0e, 0x0d, 0x0a, 0x05, 0x04, 0x05, 0x09, 0x06, 0x06, 0x09, 0x08, 0x05, + 0x04, 0x00, 0x00, 0xfc, 0xf8, 0xf7, 0xf7, 0xf7, 0xfa, 0xfe, 0x02, 0xfd, + 0xf8, 0xf8, 0xf7, 0xf6, 0xfa, 0xfd, 0xfc, 0xf2, 0xf2, 0xfb, 0xfd, 0xfe, + 0xfb, 0xfb, 0x02, 0x07, 0x08, 0x04, 0x12, 0x1e, 0x14, 0x11, 0x0b, 0x05, + 0x05, 0x05, 0x02, 0x01, 0x04, 0x07, 0x05, 0x07, 0x09, 0x0a, 0x09, 0x02, + 0xff, 0xfe, 0x03, 0x01, 0x01, 0x01, 0x04, 0x08, 0x07, 0x0b, 0x0a, 0x07, + 0x02, 0xfd, 0xf9, 0xfb, 0xff, 0x04, 0x03, 0x05, 0x08, 0x00, 0xfd, 0xfd, + 0xfe, 0x00, 0x01, 0x09, 0x07, 0x05, 0x06, 0x02, 0x01, 0xfe, 0xfb, 0xfa, + 0xfc, 0xfc, 0x06, 0x12, 0x10, 0x0d, 0x06, 0x02, 0x03, 0x04, 0x01, 0xf9, + 0xf9, 0x04, 0x0a, 0x09, 0x0b, 0x0b, 0x0b, 0x05, 0x00, 0x03, 0x07, 0x08, + 0x08, 0x04, 0x01, 0x05, 0x07, 0x03, 0x08, 0x05, 0x00, 0xfd, 0xfa, 0xf8, + 0xf9, 0xfd, 0x07, 0x0e, 0x04, 0x02, 0x00, 0xff, 0x01, 0x01, 0xff, 0xfe, + 0xfc, 0xf8, 0xfa, 0xff, 0xff, 0xfe, 0xfc, 0xfd, 0xfd, 0x00, 0x04, 0x07, + 0x0a, 0x09, 0x08, 0x02, 0x02, 0x05, 0x00, 0xfd, 0xfe, 0x04, 0x07, 0x0c, + 0x0a, 0x07, 0x05, 0x02, 0x02, 0x0a, 0x09, 0x05, 0x05, 0x03, 0x03, 0x04, + 0x08, 0x0f, 0x1c, 0x1b, 0x12, 0x11, 0x0d, 0x06, 0x09, 0x0b, 0x08, 0x01, + 0xfc, 0xff, 0xff, 0xfd, 0xfd, 0xfd, 0xff, 0x03, 0xff, 0xf8, 0xf7, 0xf8, + 0xf9, 0xf5, 0xf2, 0xf2, 0xfb, 0xfd, 0x00, 0x00, 0x06, 0x07, 0x08, 0x04, + 0x02, 0x04, 0x05, 0x08, 0x0d, 0x02, 0x01, 0x07, 0x08, 0x05, 0x01, 0xff, + 0xff, 0x06, 0x10, 0x0a, 0x0a, 0x07, 0x08, 0x07, 0x07, 0x07, 0x04, 0x00, + 0xfd, 0xfd, 0xfc, 0xf7, 0xf8, 0xfb, 0xfb, 0xfa, 0xfa, 0xf9, 0xf9, 0xfc, + 0x00, 0x02, 0x00, 0x04, 0x06, 0x03, 0x01, 0x04, 0x08, 0x02, 0xff, 0x04, + 0x09, 0x0f, 0x12, 0x15, 0x14, 0x15, 0x12, 0x10, 0x0e, 0x0a, 0x08, 0x05, + 0x00, 0x0b, 0x11, 0x17, 0x18, 0x15, 0x0d, 0x06, 0x05, 0x03, 0xfe, 0xfc, + 0xfb, 0xff, 0xfd, 0xfd, 0xfa, 0xfc, 0xfc, 0xf7, 0xf4, 0xf7, 0xfa, 0xf8, + 0xf3, 0xf6, 0xf9, 0xfa, 0xfb, 0xf7, 0xf1, 0xf2, 0xfc, 0xf9, 0xf8, 0xfb, + 0xfd, 0xfe, 0x02, 0x00, 0xfb, 0xfc, 0xfc, 0xfd, 0xfb, 0x00, 0x05, 0x09, + 0x11, 0x25, 0x1f, 0x18, 0x16, 0x13, 0x0e, 0x0b, 0x07, 0x08, 0x06, 0x0c, + 0x10, 0x0a, 0x03, 0x02, 0x04, 0x06, 0x07, 0x07, 0x07, 0x07, 0x02, 0x00, + 0x05, 0x0c, 0x0e, 0x0b, 0x04, 0xfe, 0xfe, 0x02, 0x05, 0x06, 0x08, 0x02, + 0x05, 0x0c, 0x09, 0x03, 0xfe, 0xfd, 0xfd, 0xfc, 0xfb, 0xfa, 0xf5, 0xf7, + 0x01, 0xff, 0xfe, 0xfe, 0xfd, 0x00, 0xff, 0xff, 0xfc, 0x03, 0x02, 0xfc, + 0xfa, 0xf8, 0xf8, 0xf9, 0xf7, 0xf6, 0xfa, 0xff, 0x01, 0x03, 0x04, 0x03, + 0x0c, 0x11, 0x0c, 0x08, 0x02, 0x01, 0x02, 0x0a, 0x11, 0x0e, 0x0c, 0x0c, + 0x12, 0x10, 0x0c, 0x09, 0x07, 0x09, 0x05, 0x02, 0xff, 0x00, 0x04, 0x0a, + 0x0b, 0x05, 0x02, 0x02, 0x01, 0x00, 0xff, 0xfd, 0x01, 0x02, 0x00, 0x02, + 0x00, 0x05, 0x05, 0x01, 0xfd, 0x04, 0x0a, 0x04, 0x02, 0x05, 0x01, 0x02, + 0x08, 0x05, 0x00, 0x00, 0x03, 0x04, 0x08, 0x0e, 0x0f, 0x08, 0x02, 0x01, + 0x01, 0xfe, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xfb, 0xfb, 0x01, 0x09, 0x0f, + 0x0b, 0x07, 0x04, 0x03, 0x00, 0x02, 0x03, 0x01, 0x00, 0xf9, 0xf5, 0xf6, + 0xf8, 0xf9, 0xfa, 0xfa, 0xfb, 0xff, 0xff, 0xff, 0x00, 0x04, 0x02, 0x0b, + 0x09, 0x08, 0x0d, 0x07, 0x03, 0x02, 0x09, 0x0a, 0x08, 0x08, 0x0f, 0x14, + 0x12, 0x0a, 0x08, 0x0c, 0x0b, 0x05, 0x04, 0x04, 0x01, 0x02, 0x12, 0x14, + 0x0c, 0x07, 0x06, 0x06, 0x09, 0x0b, 0x05, 0x00, 0xff, 0xfe, 0xf9, 0xf5, + 0xf5, 0xf4, 0xf7, 0xf6, 0xf5, 0xf6, 0xf7, 0xf7, 0xfd, 0xfe, 0x03, 0xff, + 0xfd, 0xfb, 0xf6, 0xf7, 0x02, 0x0b, 0x07, 0x02, 0x01, 0x0a, 0x12, 0x12, + 0x09, 0x04, 0x0a, 0x0c, 0x07, 0x06, 0x09, 0x06, 0x08, 0x0f, 0x15, 0x11, + 0x0a, 0x08, 0x07, 0x03, 0x00, 0x01, 0x00, 0x03, 0x06, 0x03, 0x01, 0xff, + 0xff, 0xff, 0xff, 0xfc, 0xfb, 0xf8, 0xf8, 0xfa, 0xfb, 0x00, 0x03, 0xfe, + 0xfa, 0xf4, 0xf6, 0xff, 0xfe, 0xfb, 0xf8, 0xfa, 0x02, 0x08, 0x08, 0x05, + 0x02, 0x0b, 0x0b, 0x03, 0x04, 0x06, 0x0c, 0x12, 0x12, 0x1a, 0x18, 0x16, + 0x0d, 0x0c, 0x0e, 0x0b, 0x0c, 0x0b, 0x0f, 0x0f, 0x0b, 0x06, 0x03, 0xfc, + 0xf7, 0xfa, 0xfb, 0xff, 0xff, 0xfd, 0xfc, 0xfc, 0x01, 0x07, 0x06, 0x02, + 0xff, 0xfe, 0xfc, 0xf9, 0xf8, 0xf7, 0xf8, 0x04, 0x09, 0x05, 0x00, 0xfb, + 0xfa, 0xfb, 0xfc, 0xfc, 0xf8, 0xf8, 0xfa, 0xff, 0x08, 0x0a, 0x0d, 0x09, + 0x04, 0x03, 0x0a, 0x10, 0x08, 0x02, 0xff, 0x02, 0x01, 0x00, 0xfa, 0xf7, + 0xf9, 0xff, 0x00, 0xff, 0x01, 0x00, 0x06, 0x06, 0x0f, 0x12, 0x11, 0x0f, + 0x10, 0x10, 0x09, 0x07, 0x07, 0x07, 0x0c, 0x16, 0x14, 0x0c, 0x09, 0x0a, + 0x09, 0x07, 0x09, 0x07, 0x02, 0x00, 0x00, 0x0b, 0x0a, 0x06, 0x02, 0xf9, + 0xf2, 0xf6, 0xf3, 0xf2, 0xf6, 0xfb, 0x01, 0x00, 0xff, 0xfd, 0xf8, 0xfe, + 0xfa, 0xf7, 0xf6, 0xf8, 0xfa, 0xfc, 0xfb, 0x04, 0x06, 0x08, 0x09, 0x09, + 0x05, 0x04, 0x03, 0xfe, 0xfb, 0xfd, 0x08, 0x0e, 0x09, 0x09, 0x04, 0x03, + 0x06, 0x06, 0x04, 0x04, 0x08, 0x08, 0x0d, 0x12, 0x0d, 0x0a, 0x04, 0xff, + 0x00, 0x00, 0xfe, 0xfd, 0xfe, 0xfd, 0x00, 0xfe, 0xfd, 0xfc, 0xfc, 0xfe, + 0xff, 0x03, 0x0a, 0x08, 0x07, 0x04, 0x08, 0x17, 0x12, 0x0b, 0x0d, 0x0b, + 0x0a, 0x04, 0xff, 0xfe, 0xff, 0x0e, 0x19, 0x14, 0x0f, 0x09, 0x09, 0x03, + 0xff, 0xff, 0xfc, 0xf8, 0xf9, 0x01, 0x07, 0x03, 0x01, 0xff, 0xfc, 0xfb, + 0xff, 0x02, 0xff, 0xfb, 0xf4, 0xf0, 0xf3, 0xf8, 0xf8, 0xf3, 0xef, 0xef, + 0xef, 0xf3, 0xf6, 0xf6, 0xf5, 0xf6, 0x03, 0x09, 0x0b, 0x0c, 0x0d, 0x0d, + 0x0c, 0x08, 0x07, 0x0b, 0x0d, 0x13, 0x14, 0x11, 0x12, 0x11, 0x0d, 0x0c, + 0x0d, 0x0f, 0x14, 0x0d, 0x0b, 0x12, 0x14, 0x10, 0x0e, 0x0c, 0x09, 0x05, + 0x04, 0x02, 0x03, 0x06, 0x04, 0xff, 0xfe, 0x00, 0x01, 0xfe, 0xfe, 0xff, + 0xfc, 0xf4, 0xf1, 0xf3, 0xf3, 0xf9, 0x02, 0x01, 0xff, 0x02, 0x03, 0xfc, + 0xf2, 0xee, 0xec, 0xec, 0xf2, 0x01, 0x02, 0x03, 0x05, 0x04, 0x02, 0x08, + 0x05, 0x02, 0x03, 0x03, 0x0f, 0x12, 0x0f, 0x10, 0x0e, 0x0b, 0x0a, 0x06, + 0x04, 0x03, 0x05, 0x04, 0x03, 0x03, 0x06, 0x06, 0x05, 0x03, 0x01, 0x05, + 0x02, 0x00, 0x03, 0x02, 0x00, 0x0b, 0x11, 0x11, 0x05, 0x00, 0xfb, 0xf8, + 0xf6, 0xf6, 0xf7, 0xfb, 0x07, 0x0e, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0xff, 0x0b, 0x15, 0x0d, 0x08, 0x10, 0x0f, 0x08, 0x07, 0x08, + 0x07, 0x07, 0xfe, 0xfb, 0xfc, 0xfd, 0x02, 0x04, 0xfe, 0xfb, 0xfc, 0xfe, + 0xfb, 0xff, 0xfe, 0xfc, 0x02, 0x0c, 0x0d, 0x09, 0x05, 0x02, 0xfe, 0xfc, + 0xfb, 0xfc, 0xfe, 0x05, 0x0e, 0x0a, 0x06, 0x08, 0x09, 0x06, 0x03, 0x02, + 0x04, 0x04, 0x0a, 0x0b, 0x04, 0xfe, 0xfe, 0xfe, 0xfd, 0xfc, 0xfb, 0xfe, + 0x03, 0x06, 0x04, 0x0c, 0x0e, 0x07, 0x04, 0x00, 0xfe, 0xfc, 0xf8, 0xf9, + 0xfc, 0xfd, 0xfd, 0x00, 0x0a, 0x0d, 0x06, 0x06, 0x09, 0x0b, 0x0d, 0x0a, + 0x03, 0x02, 0x02, 0x09, 0x10, 0x0b, 0x04, 0x06, 0x06, 0x04, 0x05, 0x0c, + 0x0b, 0x0e, 0x0f, 0x09, 0x05, 0x03, 0x02, 0x04, 0x06, 0x02, 0xff, 0xfa, + 0xf6, 0xf5, 0xf2, 0xf2, 0xf5, 0xf8, 0xfb, 0xfd, 0xfb, 0xfb, 0x00, 0x0b, + 0x08, 0x02, 0xfe, 0x02, 0x0f, 0x0e, 0x06, 0x02, 0x02, 0x03, 0x02, 0xfe, + 0x03, 0x01, 0x02, 0x08, 0x0f, 0x0d, 0x0c, 0x0c, 0x09, 0x04, 0x01, 0x04, + 0x0c, 0x0c, 0x06, 0x02, 0x04, 0x05, 0x02, 0x01, 0x01, 0xff, 0xfd, 0xf8, + 0xf7, 0xf7, 0xf4, 0xf4, 0xf8, 0xfa, 0xf9, 0xf7, 0xf7, 0xfb, 0xff, 0xf8, + 0xf8, 0xfd, 0x01, 0x13, 0x16, 0x0e, 0x0e, 0x19, 0x15, 0x0f, 0x0c, 0x0c, + 0x0e, 0x0d, 0x0b, 0x0a, 0x12, 0x16, 0x10, 0x0b, 0x0e, 0x0e, 0x0b, 0x0e, + 0x0e, 0x09, 0x06, 0x09, 0x09, 0x05, 0xff, 0xfb, 0xfb, 0xf9, 0xf9, 0xf9, + 0xf7, 0xf7, 0xf6, 0xf7, 0xf9, 0xf6, 0xf7, 0xf5, 0xf4, 0xf3, 0xf2, 0xf2, + 0xf1, 0xf3, 0xfe, 0x05, 0x02, 0xff, 0xfa, 0xf7, 0xfc, 0x00, 0xfe, 0x00, + 0x00, 0xfd, 0xfc, 0x13, 0x1d, 0x15, 0x0e, 0x0b, 0x0f, 0x0c, 0x0e, 0x11, + 0x0d, 0x11, 0x0f, 0x0b, 0x0a, 0x0f, 0x0a, 0x08, 0x08, 0x05, 0x06, 0x07, + 0x07, 0x06, 0x04, 0x08, 0x0a, 0x07, 0x04, 0x09, 0x06, 0xff, 0xfe, 0xff, + 0xff, 0x03, 0x0f, 0x0e, 0x04, 0xfe, 0xfe, 0xfe, 0x00, 0xff, 0xfb, 0xf6, + 0xf4, 0xf3, 0xf3, 0xfe, 0x02, 0xfe, 0xfc, 0xfc, 0xf9, 0x00, 0x04, 0x08, + 0x08, 0x08, 0x07, 0x0a, 0x04, 0x01, 0x01, 0x00, 0xff, 0xfe, 0xfc, 0xf9, + 0xf7, 0xfc, 0x00, 0xfd, 0xfb, 0xfe, 0x06, 0x09, 0x04, 0x02, 0x01, 0x02, + 0x05, 0x09, 0x12, 0x11, 0x0d, 0x0a, 0x08, 0x07, 0x04, 0xfd, 0xfb, 0x01, + 0xff, 0xff, 0x07, 0x12, 0x11, 0x0b, 0x07, 0x08, 0x0f, 0x11, 0x08, 0x02, + 0x00, 0x04, 0x06, 0x05, 0x04, 0x04, 0x04, 0x0a, 0x06, 0x08, 0x09, 0x08, + 0x08, 0x06, 0x04, 0xfe, 0xfb, 0xff, 0xf7, 0xf3, 0xf2, 0xf3, 0xfa, 0xfa, + 0xfc, 0x02, 0x08, 0x03, 0x07, 0x07, 0x04, 0x04, 0x00, 0xf8, 0xf9, 0xfa, + 0xf7, 0xf7, 0xf9, 0x02, 0x04, 0x04, 0x0a, 0x0f, 0x0e, 0x08, 0x09, 0x07, + 0x06, 0x08, 0x05, 0x01, 0x02, 0x01, 0xff, 0xfd, 0xfb, 0xfb, 0xfb, 0x01, + 0x05, 0x02, 0x05, 0x0f, 0x0d, 0x09, 0x0c, 0x0e, 0x05, 0xfe, 0xfa, 0xff, + 0x03, 0x0c, 0x0d, 0x03, 0x02, 0x03, 0x04, 0x09, 0x08, 0x08, 0x05, 0x02, + 0x00, 0x03, 0x09, 0x0e, 0x0d, 0x07, 0x0a, 0x10, 0x09, 0x05, 0x03, 0x01, + 0x02, 0x00, 0x02, 0x03, 0x01, 0xff, 0xfe, 0xfb, 0xfa, 0xfa, 0xf8, 0xf1, + 0xf0, 0xf2, 0xf6, 0xf5, 0xf8, 0xfd, 0xfc, 0xf9, 0xf9, 0xf7, 0x00, 0x0a, + 0x05, 0x0c, 0x0f, 0x11, 0x13, 0x0c, 0x03, 0x01, 0x02, 0x01, 0x05, 0x05, + 0x02, 0x03, 0x08, 0x11, 0x19, 0x19, 0x18, 0x15, 0x0e, 0x0a, 0x0b, 0x0c, + 0x0b, 0x0b, 0x07, 0x04, 0x03, 0x04, 0x04, 0xfe, 0xf7, 0xf3, 0xf6, 0xf7, + 0xf9, 0x00, 0xfb, 0xf7, 0xf5, 0xf4, 0xf4, 0xf2, 0xf1, 0xf3, 0xf7, 0xfb, + 0xfc, 0x04, 0x03, 0x03, 0x04, 0x00, 0x02, 0x0d, 0x09, 0x09, 0x0a, 0x04, + 0x04, 0x0c, 0x0e, 0x13, 0x1b, 0x1d, 0x17, 0x0e, 0x03, 0x02, 0x06, 0x02, + 0x06, 0x0c, 0x07, 0x05, 0x05, 0x05, 0x05, 0x04, 0x01, 0x02, 0x06, 0x09, + 0x04, 0xfb, 0xfb, 0xfd, 0xfa, 0xf6, 0xf6, 0xf7, 0xfa, 0xff, 0x02, 0x00, + 0x06, 0x0b, 0x07, 0x05, 0x04, 0xfe, 0xfd, 0xfc, 0xfa, 0xfa, 0xfa, 0xf6, + 0xf9, 0xfd, 0x02, 0x12, 0x1a, 0x19, 0x11, 0x08, 0x01, 0x03, 0x06, 0x01, + 0x01, 0x01, 0xff, 0xfa, 0xfc, 0xfc, 0xfe, 0xfe, 0xfd, 0x04, 0x0c, 0x05, + 0x03, 0x05, 0x03, 0x02, 0x03, 0x03, 0x00, 0x03, 0x04, 0x06, 0x07, 0x07, + 0x0d, 0x0e, 0x09, 0x06, 0x05, 0x0a, 0x08, 0x07, 0x08, 0x02, 0xfb, 0xfa, + 0xfb, 0xfa, 0x03, 0x10, 0x0f, 0x0c, 0x08, 0x05, 0x03, 0x03, 0x05, 0x0b, + 0x0b, 0x0c, 0x06, 0x00, 0xff, 0x00, 0xfd, 0x00, 0xfe, 0xfd, 0xf9, 0xf6, + 0xf4, 0xf6, 0xf7, 0xf6, 0xf7, 0xfa, 0xfe, 0x00, 0xfd, 0xfe, 0x01, 0x04, + 0x0d, 0x0a, 0x04, 0x03, 0x05, 0x06, 0x01, 0xfe, 0xff, 0xfb, 0xfb, 0xff, + 0x01, 0x07, 0x15, 0x18, 0x13, 0x0e, 0x0a, 0x07, 0x07, 0x06, 0x08, 0x05, + 0x04, 0x06, 0x05, 0x04, 0x03, 0x02, 0x07, 0x14, 0x16, 0x11, 0x0e, 0x0a, + 0x02, 0x02, 0x00, 0x00, 0x06, 0x02, 0xfe, 0xfc, 0xff, 0x06, 0xfe, 0xfa, + 0x03, 0x00, 0xfc, 0x06, 0x07, 0x02, 0x00, 0xff, 0xfc, 0xf9, 0xf6, 0xf5, + 0xfa, 0x09, 0x09, 0x05, 0x01, 0x00, 0xff, 0xf8, 0xf7, 0xfd, 0xff, 0xfe, + 0x01, 0xff, 0xfd, 0xfd, 0xff, 0x05, 0x08, 0x05, 0x01, 0x00, 0x02, 0x04, + 0x01, 0x02, 0x03, 0x0d, 0x0f, 0x09, 0x05, 0x05, 0x06, 0x0a, 0x07, 0x07, + 0x0e, 0x0a, 0x05, 0x02, 0x02, 0x02, 0x07, 0x02, 0x00, 0xff, 0xff, 0x04, + 0x11, 0x14, 0x17, 0x1a, 0x12, 0x0c, 0x07, 0x05, 0x06, 0x0a, 0x09, 0x06, + 0x04, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0xfe, 0xff, 0xfc, 0xf8, 0xee, + 0xeb, 0xf0, 0xf2, 0xf5, 0xf7, 0xf2, 0xef, 0xf5, 0xfb, 0xfc, 0xff, 0x09, + 0x0f, 0x0a, 0x04, 0x02, 0xff, 0x00, 0x01, 0xfd, 0xfb, 0xfe, 0x00, 0x05, + 0x0c, 0x0b, 0x10, 0x10, 0x0e, 0x0a, 0x08, 0x07, 0x08, 0x0f, 0x10, 0x0f, + 0x0b, 0x09, 0x08, 0x0b, 0x11, 0x0b, 0x06, 0x03, 0x02, 0x01, 0xff, 0xfe, + 0xff, 0x00, 0xff, 0x00, 0x01, 0xfb, 0xfb, 0xfe, 0x03, 0x03, 0xfe, 0x03, + 0x10, 0x06, 0x04, 0x06, 0xff, 0xf9, 0xfa, 0x04, 0x06, 0x02, 0x04, 0x09, + 0x09, 0x0e, 0x0d, 0x08, 0x04, 0xff, 0xfd, 0xfd, 0xff, 0xfe, 0xfd, 0xfc, + 0xf7, 0xf3, 0xf6, 0xff, 0xff, 0x00, 0x05, 0x07, 0x08, 0x03, 0x00, 0x00, + 0x00, 0x05, 0x03, 0x00, 0xfe, 0xf8, 0xf5, 0xfb, 0x01, 0x00, 0x00, 0x09, + 0x10, 0x0b, 0x0b, 0x0c, 0x09, 0x03, 0x02, 0x05, 0x06, 0x0a, 0x13, 0x0d, + 0x0a, 0x11, 0x14, 0x1e, 0x15, 0x0a, 0x08, 0x09, 0x0b, 0x0a, 0x07, 0x03, + 0x01, 0x00, 0x05, 0x05, 0xfe, 0xf5, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf6, + 0xf8, 0xf8, 0xfb, 0xff, 0xf9, 0xf8, 0xfa, 0xfa, 0xfd, 0x03, 0x02, 0x06, + 0x09, 0x02, 0x01, 0x01, 0x02, 0x03, 0x05, 0x07, 0x0a, 0x10, 0x10, 0x0c, + 0x0b, 0x0e, 0x08, 0x02, 0x03, 0x04, 0x07, 0x07, 0x06, 0x04, 0x04, 0x0e, + 0x14, 0x16, 0x10, 0x08, 0x05, 0x04, 0xff, 0xfb, 0xfc, 0xf9, 0xfc, 0x01, + 0x03, 0xff, 0xfc, 0xf8, 0xf5, 0xfb, 0x00, 0x01, 0x05, 0x02, 0x03, 0x08, + 0x10, 0x0e, 0x0b, 0x04, 0xfd, 0xfb, 0xfc, 0xfd, 0x04, 0x04, 0x00, 0x00, + 0x07, 0x07, 0x04, 0x00, 0x00, 0xff, 0xfa, 0xfe, 0xfd, 0xfb, 0xfb, 0xfe, + 0x08, 0x0b, 0x0b, 0x01, 0x01, 0x03, 0x05, 0x0a, 0x0c, 0x0b, 0x0b, 0x08, + 0x06, 0x06, 0x02, 0xff, 0xff, 0xfd, 0x00, 0x04, 0x0b, 0x06, 0x05, 0x0a, + 0x06, 0x02, 0x06, 0x01, 0xf8, 0xf8, 0xfb, 0x00, 0x05, 0x0a, 0x0c, 0x0e, + 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x01, 0xfe, 0xfc, 0xfd, 0xff, 0xff, 0x03, + 0x07, 0x02, 0x01, 0xff, 0xfe, 0xfb, 0xfa, 0xfb, 0x00, 0x05, 0x07, 0x01, + 0xfd, 0xfa, 0xf8, 0xfd, 0x01, 0x02, 0xfd, 0xfd, 0x02, 0x00, 0x00, 0x09, + 0x09, 0x01, 0xfe, 0xfd, 0x05, 0x09, 0x05, 0x05, 0x02, 0xfd, 0x01, 0x0e, + 0x10, 0x0a, 0x08, 0x03, 0x02, 0x06, 0x0c, 0x0e, 0x0e, 0x0b, 0x0e, 0x14, + 0x0e, 0x04, 0x02, 0x02, 0x00, 0xff, 0x00, 0x01, 0x04, 0x07, 0x08, 0x07, + 0x02, 0xfc, 0xfb, 0xfc, 0x00, 0xff, 0xfd, 0x01, 0x00, 0xff, 0xfc, 0x08, + 0x0b, 0x0b, 0x07, 0x04, 0xff, 0xfd, 0x00, 0x02, 0xfd, 0xfa, 0xfb, 0xfd, + 0xff, 0x03, 0x02, 0xfe, 0xf9, 0xf8, 0xf7, 0xf8, 0xfb, 0x02, 0x07, 0x06, + 0x03, 0x01, 0x01, 0x07, 0x0e, 0x09, 0x08, 0x09, 0x04, 0x02, 0x02, 0xff, + 0x00, 0x00, 0xff, 0x02, 0x02, 0x03, 0x06, 0x06, 0x03, 0x00, 0x01, 0x0e, + 0x0e, 0x10, 0x0e, 0x05, 0x02, 0x04, 0x09, 0x0e, 0x0c, 0x10, 0x15, 0x10, + 0x0e, 0x0f, 0x0e, 0x0c, 0x08, 0x04, 0x01, 0xff, 0x02, 0x0a, 0x09, 0x04, + 0xfe, 0xf9, 0xf5, 0xf3, 0xf2, 0xf8, 0xf8, 0xf4, 0xf5, 0xf7, 0xf3, 0xf1, + 0xfc, 0xfd, 0xfe, 0xff, 0xf9, 0xf6, 0xf6, 0xf6, 0xf0, 0xf1, 0xfb, 0x07, + 0x05, 0x03, 0x05, 0x0b, 0x0b, 0x0c, 0x10, 0x0b, 0x0d, 0x11, 0x12, 0x10, + 0x11, 0x10, 0x0d, 0x12, 0x15, 0x11, 0x0f, 0x0c, 0x10, 0x0f, 0x0c, 0x0d, + 0x0b, 0x05, 0xfe, 0xfa, 0xfa, 0x00, 0x01, 0xfe, 0xfb, 0xfa, 0xf8, 0xf5, + 0xf6, 0xfe, 0x00, 0xf9, 0xf9, 0xfb, 0x00, 0xfe, 0xfe, 0x06, 0x0c, 0x0f, + 0x07, 0x03, 0x01, 0xfc, 0xfc, 0x05, 0x09, 0x04, 0x05, 0x03, 0x04, 0x05, + 0x05, 0x03, 0xff, 0x02, 0x04, 0x01, 0xff, 0x01, 0xff, 0x00, 0x00, 0x00, + 0x04, 0x02, 0x09, 0x0c, 0x07, 0x02, 0x05, 0x05, 0x00, 0xfe, 0xfb, 0xf6, + 0xf6, 0xfd, 0x01, 0x03, 0x03, 0x01, 0x02, 0xfb, 0xf9, 0xfe, 0x0a, 0x10, + 0x0d, 0x0b, 0x08, 0x04, 0x08, 0x10, 0x0f, 0x0f, 0x0e, 0x0a, 0x07, 0x0a, + 0x0a, 0x06, 0x05, 0x07, 0x06, 0x04, 0x04, 0x09, 0x05, 0xff, 0xff, 0x00, + 0x03, 0x02, 0x00, 0xfa, 0xfa, 0xfe, 0xfe, 0xfc, 0x00, 0xfd, 0xfe, 0x01, + 0xfe, 0xf9, 0xf9, 0xfd, 0x00, 0xfe, 0xfa, 0xf5, 0xf7, 0xfe, 0x09, 0x08, + 0x03, 0x04, 0x03, 0x00, 0x05, 0x05, 0x05, 0x0d, 0x0a, 0x06, 0x03, 0x06, + 0x05, 0x09, 0x13, 0x17, 0x0f, 0x07, 0x0a, 0x07, 0x03, 0x00, 0xff, 0x04, + 0x00, 0x02, 0x04, 0x00, 0x00, 0x01, 0x01, 0x04, 0x07, 0x06, 0x03, 0x05, + 0x04, 0x04, 0x00, 0xfd, 0x07, 0x08, 0x00, 0x04, 0x05, 0x00, 0x06, 0x07, + 0x04, 0x01, 0xff, 0x01, 0x05, 0x00, 0x05, 0xff, 0xf9, 0xfb, 0xfc, 0xfb, + 0xfa, 0xf8, 0xf8, 0xf9, 0xfc, 0x00, 0x02, 0x03, 0x02, 0x01, 0x02, 0x07, + 0x09, 0x05, 0x05, 0x03, 0x04, 0x06, 0x02, 0x02, 0x01, 0x02, 0x08, 0x08, + 0x04, 0x05, 0x08, 0x07, 0x0a, 0x08, 0x06, 0x04, 0x04, 0x08, 0x09, 0x01, + 0x02, 0x08, 0x07, 0x0f, 0x14, 0x14, 0x0d, 0x06, 0x05, 0x05, 0x04, 0x07, + 0x04, 0x02, 0x03, 0xff, 0xff, 0x03, 0x03, 0x00, 0xfe, 0xf8, 0xf7, 0xfd, + 0x02, 0x03, 0x00, 0xfd, 0xfc, 0xfb, 0xf9, 0xf5, 0xfb, 0xff, 0xff, 0xfb, + 0xf5, 0xf5, 0xf7, 0xf9, 0xf9, 0xf8, 0xfa, 0xfe, 0xfb, 0x00, 0x03, 0xff, + 0x05, 0x0c, 0x0f, 0x11, 0x12, 0x0e, 0x08, 0x09, 0x0a, 0x0e, 0x12, 0x14, + 0x19, 0x18, 0x12, 0x0d, 0x0c, 0x0c, 0x0b, 0x09, 0x03, 0x05, 0x08, 0x07, + 0x04, 0x00, 0x00, 0x01, 0xfd, 0xf8, 0xf7, 0xf9, 0x02, 0x05, 0x00, 0xf9, + 0xf5, 0xf6, 0xfc, 0xfd, 0xfe, 0x03, 0x01, 0xfa, 0xf9, 0x01, 0x00, 0xfc, + 0xfe, 0x00, 0x04, 0x09, 0x07, 0x01, 0x00, 0x02, 0x03, 0x09, 0x09, 0x06, + 0x02, 0x01, 0x01, 0x00, 0x00, 0x04, 0x0a, 0x0b, 0x05, 0x08, 0x09, 0x07, + 0x04, 0x05, 0x05, 0xff, 0xff, 0x03, 0x01, 0xfe, 0xff, 0xfc, 0xfb, 0xfb, + 0xfe, 0x00, 0xff, 0xfd, 0xfe, 0xfe, 0xfc, 0xfc, 0x01, 0x09, 0x08, 0x04, + 0x01, 0x0b, 0x1b, 0x17, 0x12, 0x0d, 0x0e, 0x0d, 0x0c, 0x0d, 0x09, 0x07, + 0x06, 0x05, 0x05, 0x05, 0x0c, 0x0d, 0x0b, 0x06, 0x05, 0x05, 0x05, 0x05, + 0xfb, 0xf5, 0xf5, 0xfb, 0xfd, 0xfe, 0xfe, 0xfd, 0xfd, 0xf6, 0xf2, 0xee, + 0xf1, 0xfc, 0xfe, 0xf9, 0xf4, 0xf2, 0xf3, 0xf5, 0x01, 0x02, 0xf9, 0xfb, + 0x07, 0x13, 0x16, 0x13, 0x12, 0x0e, 0x0d, 0x09, 0x09, 0x07, 0x0f, 0x12, + 0x0f, 0x0b, 0x09, 0x07, 0x0c, 0x09, 0x04, 0x02, 0x02, 0x03, 0x01, 0x00, + 0x00, 0x01, 0x04, 0x03, 0x04, 0x00, 0xff, 0x02, 0x00, 0xfe, 0xfd, 0x01, + 0x08, 0x0c, 0x0d, 0x0a, 0x02, 0xff, 0xfd, 0xfd, 0x09, 0x0a, 0x07, 0x06, + 0x06, 0x08, 0x08, 0x04, 0x04, 0x06, 0xfd, 0xfa, 0xfc, 0xfb, 0xfe, 0xff, + 0xfa, 0xf3, 0xf5, 0xf8, 0xfa, 0xf9, 0xfe, 0x09, 0x07, 0x01, 0xff, 0xff, + 0x02, 0x04, 0x04, 0xff, 0xfe, 0xfe, 0xfe, 0x04, 0x06, 0x06, 0x08, 0x0e, + 0x0e, 0x0e, 0x09, 0x02, 0xfe, 0xfd, 0xff, 0x09, 0x0f, 0x10, 0x10, 0x0d, + 0x11, 0x14, 0x14, 0x0f, 0x0f, 0x0c, 0x08, 0x04, 0x01, 0x00, 0xfc, 0xf7, + 0xf9, 0xfc, 0xfc, 0xff, 0x05, 0xfe, 0xfe, 0x02, 0x01, 0x00, 0xff, 0xfe, + 0xfa, 0xf9, 0xfa, 0xff, 0xfe, 0xff, 0xff, 0xfe, 0xfb, 0xfd, 0x00, 0xfe, + 0x00, 0xff, 0xfa, 0xf6, 0xf8, 0xfd, 0x04, 0x0f, 0x0b, 0x07, 0x08, 0x11, + 0x14, 0x11, 0x0a, 0x0a, 0x09, 0x07, 0x0a, 0x0b, 0x10, 0x10, 0x0c, 0x08, + 0x07, 0x05, 0x02, 0x02, 0x06, 0x02, 0x01, 0x00, 0xff, 0xfd, 0xfd, 0xff, + 0x01, 0xff, 0xfe, 0xfb, 0xf9, 0xfd, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x05, + 0x0a, 0x05, 0x03, 0xfd, 0xfd, 0x00, 0x08, 0x0d, 0x04, 0xff, 0xfc, 0x00, + 0x05, 0x09, 0x08, 0x09, 0x0d, 0x07, 0x00, 0xfc, 0xfa, 0xfb, 0xfd, 0xfe, + 0xfe, 0xfc, 0xfc, 0x03, 0x0b, 0x0f, 0x10, 0x0b, 0x03, 0x02, 0x08, 0x0a, + 0x07, 0x04, 0xfe, 0xf9, 0xfc, 0x01, 0x02, 0x07, 0x08, 0x03, 0x02, 0x05, + 0x03, 0x01, 0xf8, 0xf4, 0xf7, 0xfc, 0x0a, 0x06, 0x08, 0x09, 0x0a, 0x0a, + 0x0d, 0x12, 0x10, 0x0e, 0x09, 0x03, 0xff, 0xff, 0x01, 0x02, 0x02, 0x03, + 0x08, 0x08, 0x03, 0x07, 0x0b, 0x08, 0x05, 0x04, 0x01, 0x02, 0x00, 0xff, + 0x01, 0xff, 0xfd, 0xfa, 0xfd, 0xfd, 0xfc, 0xf9, 0xf6, 0xf5, 0xf8, 0xf9, + 0xf3, 0xee, 0xe9, 0xf1, 0xfd, 0x0a, 0x09, 0xfe, 0xfa, 0x02, 0x0e, 0x0d, + 0x12, 0x13, 0x0e, 0x0b, 0x10, 0x13, 0x0d, 0x0d, 0x0e, 0x0c, 0x0b, 0x09, + 0x04, 0x02, 0xfe, 0x06, 0x0f, 0x0d, 0x0b, 0x08, 0x09, 0x0d, 0x08, 0x04, + 0x00, 0xfe, 0xfc, 0xf6, 0xf6, 0xfd, 0xfe, 0xfc, 0x00, 0x06, 0x0c, 0x0b, + 0x05, 0x02, 0xff, 0x02, 0x04, 0x06, 0x02, 0x02, 0x00, 0xfd, 0xfa, 0x00, + 0x0a, 0x09, 0x04, 0x00, 0xfc, 0xfa, 0xf9, 0xf9, 0xfb, 0xfd, 0xfc, 0xf9, + 0xf8, 0xfc, 0xfd, 0xfd, 0x04, 0x07, 0x07, 0x02, 0x01, 0x04, 0x01, 0xfe, + 0xfb, 0xfb, 0xfc, 0xfb, 0x06, 0x0d, 0x0f, 0x0d, 0x08, 0x07, 0x06, 0x04, + 0x02, 0x04, 0x06, 0x07, 0x13, 0x12, 0x0f, 0x12, 0x15, 0x13, 0x12, 0x0f, + 0x12, 0x10, 0x0b, 0x0b, 0x08, 0x01, 0xfd, 0x02, 0x08, 0x09, 0x08, 0x01, + 0xf9, 0xf7, 0xfa, 0xf8, 0xfe, 0xff, 0xfe, 0xf9, 0xfb, 0x00, 0xff, 0xf3, + 0xf5, 0xf9, 0xf5, 0xf8, 0xfe, 0xf9, 0xf6, 0xf9, 0xfb, 0xfa, 0xf9, 0xfa, + 0xfc, 0xfc, 0xfd, 0x06, 0x0c, 0x05, 0x05, 0x07, 0x0d, 0x10, 0x10, 0x12, + 0x18, 0x15, 0x0c, 0x0c, 0x11, 0x0e, 0x09, 0x0a, 0x05, 0x02, 0xfd, 0xfc, + 0xfb, 0xf7, 0xf8, 0xfc, 0x08, 0x0c, 0x08, 0x04, 0x03, 0xff, 0xfb, 0xfa, + 0xfa, 0xfb, 0xfc, 0xff, 0x03, 0x07, 0x0c, 0x09, 0x0b, 0x0a, 0x0a, 0x0c, + 0x06, 0x03, 0x05, 0x10, 0x0d, 0x07, 0x04, 0x07, 0x07, 0x07, 0x09, 0x0c, + 0x0d, 0x08, 0x01, 0xfd, 0xf5, 0xf5, 0xf8, 0xf8, 0xfd, 0xfc, 0xf4, 0xf0, + 0xf1, 0xf9, 0xfc, 0xff, 0x06, 0x04, 0x03, 0x04, 0x03, 0x03, 0x01, 0xf8, + 0xf7, 0xfa, 0xfb, 0xfe, 0x01, 0x01, 0x05, 0x01, 0x02, 0x04, 0x06, 0x04, + 0x03, 0x07, 0x19, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x0a, 0x08, 0x06, 0x04, + 0x09, 0x0a, 0x07, 0x03, 0x02, 0x02, 0x05, 0x05, 0x06, 0x08, 0x04, 0xff, + 0xff, 0xff, 0x00, 0x05, 0x0f, 0x0b, 0x04, 0x01, 0x00, 0x01, 0xff, 0x00, + 0xfc, 0xf8, 0xf8, 0xfc, 0x01, 0x02, 0xff, 0xfb, 0xf9, 0xfb, 0x01, 0x01, + 0xff, 0x01, 0x03, 0xfb, 0xf8, 0xfd, 0x04, 0x03, 0x03, 0x06, 0x0d, 0x0e, + 0x0d, 0x07, 0x07, 0x09, 0x07, 0x02, 0x03, 0x04, 0x02, 0xff, 0x00, 0xff, + 0xff, 0xfd, 0x00, 0x06, 0x06, 0x05, 0x07, 0x06, 0x04, 0x04, 0x01, 0x00, + 0x03, 0x03, 0x00, 0x02, 0x06, 0x07, 0x0a, 0x09, 0x0a, 0x05, 0x03, 0x01, + 0x05, 0x0f, 0x08, 0x02, 0xfc, 0xfe, 0x03, 0x06, 0x06, 0x04, 0x03, 0x04, + 0x06, 0x02, 0x00, 0xfe, 0xfc, 0xf8, 0x01, 0x07, 0x02, 0xfd, 0xf9, 0xfa, + 0xfb, 0xfb, 0xfd, 0x03, 0x0d, 0x10, 0x0e, 0x09, 0x05, 0x03, 0xfe, 0xfb, + 0xfa, 0xfb, 0xfe, 0x02, 0x06, 0x03, 0x07, 0x08, 0x07, 0x03, 0x02, 0x06, + 0x0e, 0x0b, 0x08, 0x0c, 0x0c, 0x0d, 0x09, 0x0a, 0x0b, 0x07, 0x04, 0x06, + 0x09, 0x03, 0x02, 0x03, 0x05, 0x01, 0x00, 0xfc, 0xfc, 0xfb, 0xf6, 0xf7, + 0xfc, 0xfe, 0x01, 0x10, 0x0e, 0x07, 0x04, 0x05, 0xfd, 0xf6, 0xf3, 0xf1, + 0xf3, 0xf5, 0xfb, 0xf9, 0xfb, 0xfc, 0xfd, 0xfc, 0xf9, 0xf9, 0xfd, 0x09, + 0x12, 0x11, 0x0c, 0x10, 0x16, 0x10, 0x0a, 0x0c, 0x0b, 0x0a, 0x07, 0x0b, + 0x0f, 0x0c, 0x0e, 0x10, 0x0c, 0x0d, 0x0d, 0x05, 0x00, 0xfc, 0xfe, 0xff, + 0x04, 0x05, 0x08, 0x08, 0x07, 0xfe, 0xfa, 0xf5, 0xf4, 0xf5, 0xf8, 0xfe, + 0xfe, 0x00, 0xfc, 0x00, 0x09, 0x0b, 0x05, 0x02, 0xfe, 0xfc, 0x0c, 0x14, + 0x09, 0x04, 0x03, 0x00, 0xfc, 0xfc, 0xfb, 0xfd, 0xff, 0x02, 0x09, 0x0a, + 0x0c, 0x08, 0x02, 0xfe, 0xfc, 0xf8, 0xf8, 0xf8, 0xf9, 0xf6, 0xf5, 0xfb, + 0xfb, 0x04, 0x0d, 0x0d, 0x0b, 0x05, 0x00, 0xfa, 0xfa, 0xfd, 0xfb, 0xfa, + 0x00, 0x04, 0x00, 0x02, 0x0c, 0x0d, 0x0f, 0x15, 0x0e, 0x13, 0x20, 0x19, + 0x15, 0x0d, 0x0c, 0x0d, 0x0b, 0x0a, 0x0c, 0x0e, 0x0b, 0x07, 0x05, 0x08, + 0x07, 0x04, 0x04, 0x03, 0x01, 0xf9, 0xf7, 0xfc, 0xfb, 0xf7, 0xf6, 0xf8, + 0xf6, 0xff, 0x01, 0x00, 0xfe, 0x02, 0xfe, 0xfc, 0xfc, 0xf7, 0xf5, 0xf3, + 0xf4, 0xf1, 0xf4, 0xf7, 0xf9, 0xfe, 0xfd, 0xfa, 0xfe, 0x0b, 0x09, 0x06, + 0x06, 0x0c, 0x11, 0x18, 0x10, 0x08, 0x04, 0x09, 0x0b, 0x06, 0x05, 0x06, + 0x05, 0x06, 0x05, 0x04, 0x04, 0x02, 0x01, 0xfd, 0xfa, 0xfa, 0xfc, 0xfd, + 0x07, 0x10, 0x0e, 0x0f, 0x16, 0x11, 0x04, 0x00, 0xfe, 0xfe, 0xfe, 0x03, + 0x03, 0x05, 0x0b, 0x08, 0x0e, 0x11, 0x0c, 0x0b, 0x15, 0x11, 0x0b, 0x09, + 0x04, 0x03, 0x03, 0x04, 0x02, 0xfa, 0xfb, 0xfb, 0xf7, 0xf7, 0xfc, 0x09, + 0x02, 0xfd, 0xf6, 0xf5, 0xf8, 0xf7, 0xf2, 0xf1, 0xf3, 0xf4, 0xf6, 0xfd, + 0x06, 0x09, 0x05, 0x00, 0x00, 0xfa, 0xf5, 0xf6, 0xf8, 0xf7, 0xfb, 0xfe, + 0x03, 0x06, 0x07, 0x09, 0x09, 0x0d, 0x0f, 0x1d, 0x1b, 0x16, 0x1b, 0x11, + 0x0b, 0x0d, 0x0e, 0x09, 0x07, 0x06, 0x05, 0x06, 0x03, 0x00, 0x03, 0x08, + 0x0c, 0x0c, 0x07, 0x05, 0x04, 0x00, 0xff, 0x08, 0x03, 0xfe, 0xfe, 0x03, + 0x08, 0x0a, 0x07, 0x00, 0x01, 0x00, 0x00, 0xfb, 0xf7, 0xf9, 0xf9, 0xf5, + 0xf7, 0xf7, 0xf4, 0xf4, 0xf8, 0xfc, 0x09, 0x09, 0x07, 0x05, 0x0b, 0x0c, + 0x0a, 0x05, 0x01, 0x01, 0x01, 0x01, 0x08, 0x05, 0x03, 0x02, 0x08, 0x09, + 0x07, 0x04, 0x03, 0x01, 0xff, 0xfb, 0xfb, 0xf9, 0xfe, 0x03, 0x05, 0x09, + 0x07, 0x02, 0x04, 0x0d, 0x0d, 0x06, 0x00, 0xfd, 0xfc, 0x03, 0x06, 0x03, + 0x01, 0x01, 0x00, 0xfd, 0x04, 0x17, 0x12, 0x08, 0x03, 0x03, 0x03, 0x06, + 0x06, 0x08, 0x07, 0x04, 0x04, 0x09, 0x09, 0x09, 0x06, 0xfe, 0x02, 0x04, + 0x01, 0xfb, 0xff, 0xfc, 0xf7, 0xf9, 0xfb, 0x01, 0x06, 0x06, 0x0a, 0x0e, + 0x09, 0x01, 0xfe, 0xff, 0xfb, 0xf1, 0xf5, 0xfa, 0xfd, 0xf9, 0xfb, 0x09, + 0x07, 0x03, 0xfe, 0xfe, 0x15, 0x1d, 0x1a, 0x14, 0x0c, 0x0a, 0x0c, 0x09, + 0x04, 0x04, 0x02, 0x02, 0x02, 0x01, 0xfe, 0xfe, 0x00, 0x04, 0x09, 0x04, + 0xfe, 0xff, 0xff, 0xfb, 0xfb, 0xfb, 0xfb, 0xfd, 0xfe, 0x01, 0x0a, 0x0a, + 0x00, 0xfc, 0xfc, 0xfe, 0x01, 0xfc, 0xfb, 0xf9, 0xf8, 0xf5, 0xf6, 0xfb, + 0xfa, 0xf5, 0xf9, 0x0b, 0x16, 0x17, 0x18, 0x23, 0x1d, 0x17, 0x13, 0x0c, + 0x06, 0x0c, 0x0d, 0x0a, 0x09, 0x03, 0x05, 0x06, 0x06, 0x0b, 0x0b, 0x03, + 0x03, 0x03, 0xfb, 0xfa, 0xf8, 0xf8, 0xf8, 0xf8, 0xfc, 0x04, 0x04, 0x00, + 0xfb, 0xfd, 0xfe, 0x00, 0x01, 0xfb, 0xfe, 0x05, 0xff, 0xfc, 0xff, 0xff, + 0x02, 0x01, 0x0b, 0x0c, 0x10, 0x0f, 0x07, 0x05, 0x09, 0x07, 0x03, 0x02, + 0x02, 0x04, 0x08, 0x0c, 0x07, 0x04, 0x00, 0xfc, 0xfc, 0x06, 0x05, 0xfb, + 0xf6, 0xf3, 0xef, 0xf2, 0xf7, 0xff, 0xfc, 0xfb, 0x05, 0x04, 0x00, 0xfc, + 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0xfd, 0x04, 0x06, 0x04, 0x04, 0x0c, 0x0c, + 0x0c, 0x16, 0x15, 0x17, 0x1c, 0x1b, 0x15, 0x11, 0x12, 0x14, 0x14, 0x11, + 0x0e, 0x0d, 0x09, 0x04, 0xff, 0xfb, 0xfb, 0xfe, 0x01, 0x05, 0x0a, 0x0b, + 0xfd, 0xf9, 0xf4, 0xf7, 0xf9, 0xf8, 0xfa, 0x03, 0x00, 0xfe, 0xfa, 0xf4, + 0xf7, 0xf7, 0xf6, 0xf6, 0xf4, 0xf4, 0xf2, 0xf1, 0xef, 0xf5, 0xf8, 0xfb, + 0x05, 0x00, 0xfc, 0x07, 0x11, 0x0c, 0x0b, 0x14, 0x12, 0x0f, 0x11, 0x11, + 0x0a, 0x06, 0x03, 0xff, 0xfd, 0x05, 0x0c, 0x09, 0x0b, 0x0a, 0x04, 0x01, + 0x02, 0x02, 0xff, 0xff, 0x03, 0x06, 0x15, 0x1c, 0x15, 0x0f, 0x09, 0x06, + 0x03, 0x04, 0x07, 0x05, 0x01, 0x04, 0x03, 0xfe, 0xff, 0x04, 0x05, 0x11, + 0x0f, 0x06, 0x00, 0x06, 0x00, 0xfd, 0x01, 0x02, 0x00, 0xff, 0xfd, 0xff, + 0xfc, 0xf5, 0xf7, 0xff, 0xff, 0xfc, 0xff, 0x01, 0x01, 0xfb, 0xf5, 0xf0, + 0xec, 0xf1, 0x00, 0x01, 0xff, 0x04, 0x05, 0x06, 0x01, 0xfd, 0xfb, 0xfb, + 0xfb, 0xfd, 0x07, 0x0e, 0x09, 0x06, 0x01, 0x01, 0x02, 0x08, 0x1a, 0x19, + 0x0b, 0x06, 0x0b, 0x10, 0x0c, 0x0d, 0x0e, 0x0e, 0x0e, 0x0b, 0x08, 0x06, + 0x05, 0x05, 0x04, 0x04, 0x04, 0x03, 0x03, 0x04, 0x05, 0x02, 0x02, 0x03, + 0x04, 0xfe, 0x02, 0x04, 0x0c, 0x07, 0x03, 0xfe, 0xfa, 0xfb, 0xfd, 0x03, + 0x02, 0x01, 0x03, 0x00, 0xf2, 0xed, 0xed, 0xee, 0xed, 0x01, 0x14, 0x0f, + 0x07, 0x06, 0x0b, 0x0b, 0x08, 0x0d, 0x0c, 0x08, 0x08, 0x09, 0x09, 0x06, + 0x02, 0xfd, 0xfd, 0xff, 0x03, 0x03, 0x01, 0x01, 0xfd, 0xff, 0xfe, 0x00, + 0xfd, 0xf9, 0xff, 0x07, 0xff, 0xfe, 0x02, 0x04, 0x05, 0x05, 0x0a, 0x03, + 0x02, 0x08, 0x04, 0xfd, 0xf8, 0xfb, 0xfd, 0xfd, 0x0d, 0x16, 0x0e, 0x06, + 0x02, 0x05, 0x08, 0x04, 0x05, 0x06, 0x14, 0x18, 0x14, 0x10, 0x0f, 0x0d, + 0x06, 0x06, 0x00, 0xfe, 0xff, 0xff, 0x02, 0xff, 0xfc, 0xf9, 0xfa, 0x02, + 0x01, 0x05, 0x0b, 0x05, 0xf6, 0xf0, 0xf1, 0xf5, 0xf3, 0xf3, 0xf5, 0xf7, + 0xfa, 0xf9, 0xf9, 0xf9, 0xfd, 0x04, 0x05, 0x0c, 0x15, 0x13, 0x0b, 0x06, + 0x04, 0x09, 0x0a, 0x0c, 0x0f, 0x10, 0x12, 0x11, 0x0e, 0x0c, 0x0c, 0x09, + 0x05, 0x05, 0x0e, 0x12, 0x0c, 0x08, 0x05, 0x04, 0x02, 0x04, 0xfd, 0xf5, + 0xfd, 0x01, 0x03, 0xfe, 0xfa, 0xf9, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xfa, + 0xf9, 0xf9, 0xf4, 0xf3, 0xf4, 0xf1, 0xfa, 0x07, 0x00, 0x01, 0x09, 0x08, + 0x0e, 0x20, 0x1c, 0x0f, 0x0b, 0x0d, 0x0f, 0x10, 0x0b, 0x08, 0x09, 0x0a, + 0x0b, 0x0a, 0x0c, 0x0d, 0x02, 0xfd, 0xff, 0xfe, 0xfa, 0xf9, 0x06, 0x11, + 0x0e, 0x0e, 0x09, 0x00, 0xfd, 0x00, 0xfe, 0xff, 0xfe, 0xfe, 0x02, 0x05, + 0x05, 0x00, 0xfb, 0xf9, 0xf7, 0xfc, 0x0e, 0x07, 0xff, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x03, 0x02, 0xfd, 0xfd, 0x02, 0x01, 0x06, 0x0e, 0x09, 0x01, + 0xfd, 0xfb, 0xfa, 0xfb, 0xfa, 0xf8, 0xf7, 0xf8, 0xfd, 0x09, 0x0e, 0x0d, + 0x07, 0x03, 0xfe, 0xf9, 0xf8, 0xf9, 0x02, 0x0b, 0x08, 0x0c, 0x0f, 0x0f, + 0x08, 0x0a, 0x08, 0x00, 0x02, 0x12, 0x12, 0x0b, 0x0d, 0x0d, 0x0c, 0x14, + 0x13, 0x12, 0x11, 0x10, 0x07, 0x06, 0x04, 0x04, 0x00, 0xff, 0xfd, 0xfb, + 0xf7, 0xf7, 0xf8, 0xf7, 0xfe, 0x06, 0x04, 0x00, 0x06, 0x04, 0xff, 0xfd, + 0xfc, 0xf7, 0xf4, 0xf3, 0xf4, 0xf8, 0xfa, 0xfa, 0xfe, 0xfe, 0xfe, 0xfb, + 0xf7, 0xf6, 0xfa, 0x05, 0x0e, 0x0f, 0x06, 0x09, 0x11, 0x0e, 0x0d, 0x0b, + 0x0a, 0x09, 0x05, 0x05, 0x09, 0x09, 0x09, 0x0b, 0x09, 0x03, 0x01, 0x03, + 0x06, 0x05, 0x00, 0x02, 0x01, 0xfe, 0xfd, 0x05, 0x04, 0x01, 0x04, 0x09, + 0x0c, 0x0b, 0x0c, 0x05, 0x01, 0x00, 0x02, 0x05, 0x09, 0x07, 0x04, 0x00, + 0x00, 0x00, 0x01, 0x08, 0x0c, 0x01, 0xfc, 0xf8, 0xfb, 0x03, 0x03, 0x0b, + 0x0b, 0x0a, 0x09, 0x06, 0x06, 0x01, 0xff, 0xfe, 0x00, 0xfd, 0xfb, 0xfa, + 0xfd, 0xfb, 0xfc, 0xff, 0xfd, 0x00, 0x0a, 0x0d, 0x09, 0x05, 0xff, 0xfc, + 0xf9, 0xf9, 0xf7, 0xf2, 0xf2, 0xf8, 0xfe, 0x07, 0x04, 0x03, 0x06, 0x05, + 0x02, 0xff, 0xfe, 0x0e, 0x09, 0x02, 0xfc, 0xfd, 0x08, 0x11, 0x13, 0x12, + 0x0d, 0x0b, 0x0b, 0x0a, 0x0c, 0x0a, 0x0c, 0x15, 0x15, 0x0d, 0x0b, 0x0b, + 0x0c, 0x07, 0x08, 0x02, 0x0c, 0x07, 0x04, 0x07, 0x06, 0x01, 0x01, 0x02, + 0xff, 0xff, 0xf6, 0xf4, 0xf7, 0xf3, 0xf3, 0xf8, 0xf5, 0xf1, 0xee, 0xe9, + 0xeb, 0xee, 0x03, 0x09, 0xff, 0x02, 0x08, 0x0c, 0x0b, 0x08, 0x03, 0x02, + 0x05, 0x04, 0x03, 0x02, 0x03, 0x07, 0x0a, 0x0b, 0x08, 0x04, 0x05, 0x06, + 0x00, 0x05, 0x0b, 0x18, 0x17, 0x0c, 0x0a, 0x0c, 0x0b, 0x08, 0x04, 0x03, + 0x02, 0x00, 0xfa, 0xfd, 0x04, 0x04, 0x02, 0x02, 0x02, 0x00, 0x00, 0xfd, + 0xfb, 0x02, 0x09, 0xff, 0xfb, 0xfd, 0x01, 0xff, 0x00, 0x03, 0x0d, 0x09, + 0x05, 0x09, 0x09, 0x07, 0x04, 0x04, 0x02, 0x00, 0xfd, 0xfd, 0xfc, 0xfc, + 0xff, 0x05, 0x12, 0x0e, 0x0d, 0x04, 0x02, 0x01, 0xfa, 0xf5, 0xf5, 0xfc, + 0x03, 0xfc, 0xfa, 0x01, 0x08, 0x03, 0x01, 0x01, 0x00, 0xfe, 0xfe, 0x00, + 0x05, 0x10, 0x09, 0x01, 0x00, 0x09, 0x0f, 0x0f, 0x10, 0x0f, 0x0d, 0x0c, + 0x0d, 0x0b, 0x09, 0x06, 0x04, 0x0c, 0x0e, 0x05, 0x00, 0x02, 0x00, 0xfd, + 0x07, 0x0b, 0x02, 0xfd, 0xf9, 0xfb, 0xff, 0xfc, 0xf7, 0xf5, 0xf6, 0xf9, + 0xf3, 0xf4, 0xf8, 0xf9, 0xf8, 0xf8, 0xf8, 0xfb, 0x03, 0x00, 0xfd, 0x02, + 0x18, 0x17, 0x07, 0x07, 0x12, 0x10, 0x09, 0x0b, 0x0e, 0x0b, 0x0b, 0x0a, + 0x0a, 0x0f, 0x10, 0x0e, 0x0e, 0x09, 0xff, 0xfd, 0xfe, 0xfa, 0xf8, 0x02, + 0x0a, 0x0c, 0x08, 0x01, 0x02, 0x08, 0x05, 0xfe, 0xfd, 0xfc, 0xfa, 0xf8, + 0xf6, 0xfb, 0xfd, 0xfc, 0x00, 0x00, 0x01, 0x02, 0xff, 0xfc, 0xfc, 0x04, + 0x0b, 0x04, 0x00, 0x04, 0x0d, 0x11, 0x03, 0x03, 0x08, 0x08, 0x08, 0x06, + 0x03, 0x03, 0x05, 0x06, 0x00, 0xff, 0xfd, 0xfd, 0xf9, 0xf9, 0x0b, 0x10, + 0x09, 0x06, 0x09, 0x06, 0x01, 0x01, 0xff, 0xf9, 0xf9, 0xfe, 0xfc, 0xfc, + 0x06, 0x08, 0x01, 0x01, 0x00, 0x00, 0xfe, 0xff, 0xfe, 0xfb, 0xff, 0x0d, + 0x0d, 0x0d, 0x0f, 0x10, 0x0c, 0x08, 0xff, 0x02, 0x06, 0x03, 0x04, 0x06, + 0x08, 0x15, 0x0f, 0x0b, 0x09, 0x06, 0x05, 0x02, 0xfd, 0x04, 0x0a, 0x06, + 0x00, 0x00, 0x01, 0x01, 0xfe, 0xfe, 0xfe, 0xfb, 0xfa, 0xf9, 0xf9, 0x00, + 0x01, 0xfb, 0xf8, 0xf4, 0xfb, 0xff, 0xf3, 0xf2, 0xfc, 0x02, 0x0b, 0x0d, + 0x06, 0x0b, 0x0a, 0x04, 0x00, 0xfe, 0xff, 0x01, 0x04, 0x06, 0x05, 0x06, + 0x06, 0x0a, 0x0a, 0x05, 0x02, 0x01, 0x01, 0x00, 0x05, 0x15, 0x12, 0x0b, + 0x0c, 0x0d, 0x0b, 0x09, 0x08, 0x06, 0x06, 0x07, 0x04, 0x04, 0x09, 0x09, + 0x04, 0x02, 0x02, 0x05, 0x06, 0x05, 0xfc, 0xf5, 0xf2, 0xf7, 0x04, 0x07, + 0x0e, 0x09, 0x01, 0xff, 0x06, 0x02, 0x02, 0x02, 0xfd, 0xfb, 0xfc, 0xff, + 0xfd, 0xfb, 0xfa, 0xf8, 0xf8, 0xf8, 0xfa, 0x07, 0x0f, 0x08, 0x01, 0x02, + 0x06, 0x0a, 0x05, 0x02, 0xff, 0x02, 0x02, 0xfb, 0xfc, 0x01, 0x03, 0x02, + 0x03, 0x04, 0x03, 0x03, 0x02, 0xfe, 0xf9, 0xfb, 0xfe, 0x09, 0x16, 0x16, + 0x11, 0x0c, 0x09, 0x06, 0x08, 0x09, 0x0a, 0x09, 0x0f, 0x10, 0x10, 0x13, + 0x12, 0x0c, 0x0a, 0x0a, 0x04, 0xfe, 0x03, 0x07, 0x03, 0x02, 0x04, 0x01, + 0xfe, 0x02, 0x03, 0x03, 0x02, 0xfd, 0xf7, 0xef, 0xee, 0xf0, 0xf0, 0xf3, + 0xf3, 0xef, 0xf5, 0xf7, 0xf6, 0xf2, 0xf7, 0xfd, 0x05, 0x17, 0x0d, 0x0d, + 0x0f, 0x08, 0x07, 0x04, 0x07, 0x09, 0x0a, 0x08, 0x07, 0x0e, 0x12, 0x12, + 0x11, 0x0e, 0x0e, 0x08, 0x0a, 0x0e, 0x0a, 0x0d, 0x0a, 0x0a, 0x0c, 0x09, + 0x05, 0x01, 0xfc, 0xf8, 0xf7, 0xfa, 0xfc, 0x00, 0xfe, 0xfa, 0xfa, 0xfe, + 0xff, 0xfe, 0xf9, 0xf6, 0xf5, 0xf2, 0xf2, 0xfb, 0x0b, 0x0f, 0x08, 0x0e, + 0x07, 0x00, 0x02, 0x04, 0x0a, 0x0a, 0x0a, 0x0b, 0x0e, 0x0e, 0x0b, 0x05, + 0x02, 0x02, 0x00, 0xfe, 0x06, 0x10, 0x0f, 0x09, 0xfc, 0xf6, 0xfb, 0x02, + 0x07, 0x0a, 0x02, 0x04, 0x01, 0xfd, 0xff, 0x03, 0xfd, 0xf9, 0xf7, 0xf4, + 0xf6, 0xf7, 0xf9, 0xf9, 0xf5, 0xf2, 0xfb, 0x0b, 0x19, 0x18, 0x11, 0x0a, + 0x05, 0x04, 0x04, 0x06, 0x0b, 0x0a, 0x00, 0x07, 0x18, 0x11, 0x0a, 0x09, + 0x0e, 0x0a, 0x07, 0x0a, 0x11, 0x08, 0x06, 0x02, 0xff, 0xff, 0xff, 0xfe, + 0xfd, 0xfd, 0xfb, 0xfd, 0xfe, 0xfd, 0x00, 0x01, 0x00, 0x00, 0xfc, 0xfe, + 0xf4, 0xf1, 0xf5, 0xf9, 0xf8, 0xfa, 0xfe, 0x02, 0x0c, 0x07, 0x0c, 0x0e, + 0x08, 0x05, 0x04, 0x06, 0x0b, 0x0d, 0x0c, 0x0c, 0x09, 0xfc, 0xf7, 0xfc, + 0x02, 0xff, 0xfd, 0x07, 0x10, 0x0e, 0x09, 0x09, 0x07, 0x02, 0x02, 0x05, + 0x04, 0x07, 0x03, 0x02, 0x02, 0x03, 0x04, 0x03, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x02, 0xff, 0xfc, 0x04, 0x11, 0x08, 0x13, 0x14, 0x0a, 0x09, 0x08, + 0x03, 0x02, 0xff, 0xfc, 0xfc, 0xff, 0x03, 0x00, 0xfe, 0xfc, 0xfa, 0xf7, + 0xf3, 0xf7, 0x06, 0x05, 0xff, 0xfd, 0xf9, 0xfa, 0xfc, 0xfb, 0x00, 0xf7, + 0xfa, 0x0b, 0x09, 0x05, 0x07, 0x04, 0x05, 0x0c, 0x08, 0x03, 0x04, 0x03, + 0x02, 0xff, 0xfe, 0x02, 0x0b, 0x0a, 0x0a, 0x1d, 0x1b, 0x13, 0x05, 0x03, + 0x04, 0x10, 0x16, 0x13, 0x11, 0x11, 0x0a, 0x0a, 0x05, 0x03, 0x02, 0xfe, + 0xfc, 0x05, 0x09, 0x00, 0x00, 0xfe, 0xfa, 0xfc, 0xfb, 0xfc, 0xff, 0x00, + 0x02, 0xff, 0xf7, 0xf7, 0xfc, 0xf9, 0xf4, 0xec, 0xe8, 0xf2, 0xfc, 0xf9, + 0xf4, 0xf7, 0xfa, 0xff, 0xfe, 0xfe, 0x08, 0x12, 0x0a, 0x0f, 0x10, 0x0b, + 0x06, 0x06, 0x04, 0x08, 0x0d, 0x10, 0x10, 0x0d, 0x0e, 0x15, 0x1c, 0x11, + 0x09, 0x11, 0x0f, 0x0d, 0x0b, 0x07, 0x07, 0x02, 0xff, 0xff, 0xff, 0x01, + 0x04, 0x03, 0xff, 0x01, 0x03, 0x00, 0xff, 0x01, 0x00, 0xfc, 0xf3, 0xe9, + 0xe9, 0xed, 0xf5, 0xf1, 0xef, 0xf4, 0x10, 0x1b, 0x0c, 0x06, 0x0b, 0x0b, + 0x05, 0x06, 0x09, 0x0c, 0x08, 0x05, 0x01, 0xff, 0xff, 0x00, 0xff, 0xff, + 0x0c, 0x0e, 0x09, 0x09, 0x07, 0x0b, 0x14, 0x0b, 0x06, 0x09, 0x08, 0x07, + 0x02, 0xfe, 0xfc, 0xfd, 0xfc, 0xfc, 0xfb, 0xf8, 0xf9, 0xf9, 0xf6, 0xf4, + 0xf5, 0xfc, 0xfb, 0xf9, 0xfc, 0x00, 0x10, 0x0e, 0x07, 0x07, 0x06, 0xfe, + 0xfa, 0x06, 0x0d, 0x1c, 0x17, 0x10, 0x11, 0x10, 0x0d, 0x09, 0x0c, 0x11, + 0x14, 0x0d, 0x08, 0x07, 0x04, 0x03, 0x05, 0x02, 0x02, 0x05, 0x09, 0x00, + 0xf5, 0xf6, 0x07, 0x0b, 0x01, 0xfa, 0xf3, 0xed, 0xec, 0xe9, 0xe9, 0xf0, + 0xf8, 0xfa, 0xf4, 0xf1, 0xf5, 0xfb, 0x0b, 0x06, 0x07, 0x0b, 0x09, 0x0a, + 0x0f, 0x10, 0x0d, 0x09, 0x06, 0x04, 0x03, 0x00, 0xfa, 0xfe, 0x05, 0x15, + 0x1e, 0x17, 0x10, 0x09, 0x03, 0x04, 0x04, 0x01, 0x06, 0x07, 0x04, 0x00, + 0x01, 0x04, 0x01, 0xfd, 0xfc, 0xf9, 0xfb, 0x00, 0x01, 0x02, 0x09, 0x14, + 0x0c, 0x03, 0x03, 0x00, 0xfb, 0x09, 0x14, 0x0c, 0x09, 0x0a, 0x09, 0x07, + 0x05, 0x03, 0x03, 0x02, 0xfc, 0xf8, 0xf7, 0xf9, 0xfb, 0xfc, 0x02, 0x09, + 0x01, 0xf1, 0xec, 0xec, 0xf0, 0xf1, 0xf6, 0xf9, 0x07, 0x14, 0x0c, 0x09, + 0x06, 0x06, 0x02, 0x01, 0x02, 0xfe, 0xfd, 0xfe, 0x00, 0xfe, 0x03, 0x0b, + 0x09, 0x05, 0x06, 0x07, 0x05, 0x17, 0x21, 0x23, 0x20, 0x18, 0x1a, 0x14, + 0x0e, 0x0e, 0x08, 0x01, 0xff, 0x01, 0x01, 0x03, 0x03, 0x00, 0x08, 0x0d, + 0x04, 0xfc, 0xf8, 0xf6, 0xfa, 0xfb, 0xfb, 0xff, 0xf9, 0xf4, 0xf7, 0xf6, + 0xf1, 0xee, 0xee, 0xf0, 0xf1, 0xfa, 0x01, 0xfe, 0xf7, 0xf5, 0x00, 0x01, + 0xfe, 0xfc, 0xf9, 0xfd, 0x02, 0x14, 0x11, 0x13, 0x1c, 0x1d, 0x1a, 0x17, + 0x14, 0x0f, 0x0b, 0x0d, 0x11, 0x12, 0x10, 0x0e, 0x04, 0x03, 0x12, 0x0f, + 0x04, 0x02, 0x04, 0x02, 0x02, 0xfe, 0x02, 0x02, 0xfc, 0xfa, 0xfc, 0xfe, + 0x01, 0xfe, 0xfb, 0xfb, 0xf9, 0xf6, 0xf4, 0xf4, 0xf4, 0xf9, 0xf9, 0xfa, + 0xfe, 0xfc, 0x01, 0x06, 0x06, 0x14, 0x12, 0x0c, 0x0e, 0x08, 0x07, 0x0a, + 0x09, 0x04, 0x00, 0xff, 0xfd, 0xfc, 0xfd, 0xfe, 0xfa, 0x00, 0x12, 0x16, + 0x0b, 0x0a, 0x09, 0x06, 0x04, 0x05, 0x04, 0x08, 0x09, 0x04, 0x00, 0x01, + 0x02, 0x01, 0x00, 0xfe, 0xfc, 0xf7, 0xf3, 0xf5, 0xfc, 0x07, 0x05, 0x03, + 0x00, 0xfc, 0xfc, 0xf7, 0xf1, 0x05, 0x07, 0x08, 0x0e, 0x0a, 0x09, 0x10, + 0x17, 0x11, 0x0b, 0x08, 0x08, 0x05, 0x03, 0x06, 0x09, 0x0b, 0x12, 0x0b, + 0x06, 0x08, 0x08, 0x08, 0x08, 0x08, 0x01, 0x02, 0x09, 0x09, 0x0a, 0x04, + 0xfe, 0xf8, 0xf5, 0xf1, 0xf0, 0xe7, 0xe6, 0xe8, 0xf0, 0xf8, 0xfa, 0xfb, + 0xf7, 0xf3, 0xf0, 0xf1, 0xf8, 0x0d, 0x11, 0x15, 0x12, 0x0c, 0x08, 0x04, + 0x05, 0x00, 0x00, 0x00, 0x07, 0x06, 0x03, 0x06, 0x12, 0x21, 0x1e, 0x12, + 0x0c, 0x0b, 0x0a, 0x09, 0x0b, 0x06, 0x02, 0x03, 0x04, 0x03, 0x09, 0x0b, + 0x03, 0x00, 0x00, 0x00, 0x03, 0xfe, 0xf9, 0x08, 0x0a, 0x05, 0x04, 0x00, + 0xfe, 0xfe, 0xf7, 0xf5, 0x04, 0x19, 0x12, 0x0b, 0x07, 0x03, 0xfe, 0xfe, + 0xfe, 0xfc, 0xfc, 0xfc, 0xfa, 0xf6, 0xf3, 0xf1, 0xf4, 0x00, 0x06, 0xfc, + 0xfa, 0xfb, 0xfa, 0xfa, 0xf9, 0x00, 0x0b, 0x0c, 0x09, 0x01, 0x01, 0x02, + 0x00, 0x01, 0x00, 0xfc, 0xf7, 0xf8, 0x00, 0x0b, 0x0b, 0x08, 0x06, 0x05, + 0x0c, 0x11, 0x06, 0x05, 0x1a, 0x2a, 0x23, 0x1d, 0x1d, 0x16, 0x0e, 0x08, + 0x04, 0x06, 0x09, 0x0c, 0x08, 0x03, 0x02, 0x02, 0x02, 0x08, 0x0c, 0x0a, + 0x06, 0x01, 0x01, 0x00, 0xfb, 0xf7, 0xef, 0xe6, 0xec, 0xf4, 0xf7, 0xf0, + 0xec, 0xec, 0xf0, 0xf9, 0xf4, 0xf0, 0xf4, 0xf9, 0xfb, 0xfd, 0xff, 0xfe, + 0xfb, 0xf9, 0xfe, 0x06, 0x12, 0x1d, 0x18, 0x1c, 0x1c, 0x1f, 0x1c, 0x13, + 0x0d, 0x15, 0x10, 0x0b, 0x08, 0x05, 0x05, 0x06, 0x00, 0x04, 0x0c, 0x0c, + 0x0a, 0x07, 0x01, 0x00, 0xfe, 0xfc, 0xfe, 0xff, 0xfb, 0xfd, 0xfb, 0xf7, + 0xf8, 0xf6, 0xf1, 0xeb, 0xf1, 0xf8, 0x05, 0x08, 0x00, 0x00, 0x00, 0x04, + 0x0f, 0x08, 0x04, 0x06, 0x0d, 0x19, 0x11, 0x0d, 0x0d, 0x0a, 0x08, 0x07, + 0x04, 0x05, 0x06, 0x00, 0xfb, 0xff, 0x05, 0x03, 0xf5, 0xff, 0x16, 0x0d, + 0x08, 0x05, 0x03, 0x00, 0xfd, 0xf6, 0xfa, 0x05, 0x06, 0x04, 0xfe, 0xf7, + 0xf7, 0xf7, 0xf6, 0xf5, 0xf5, 0xfc, 0x06, 0x01, 0x01, 0x05, 0x05, 0xfd, + 0xfa, 0xff, 0x04, 0x02, 0x08, 0x11, 0x08, 0x08, 0x0f, 0x15, 0x0b, 0x0a, + 0x08, 0x09, 0x0b, 0x06, 0x04, 0x05, 0x08, 0x07, 0x08, 0x0d, 0x15, 0x0b, + 0x08, 0x0a, 0x09, 0x07, 0x00, 0xfe, 0x00, 0x06, 0x0b, 0x05, 0xff, 0xfc, + 0xfc, 0xf5, 0xea, 0xe9, 0xee, 0xf7, 0xfa, 0xf7, 0xf6, 0xfd, 0x00, 0xfa, + 0xfa, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x11, 0x0b, 0x06, 0xfe, 0x00, + 0x02, 0x01, 0xff, 0xfd, 0xfe, 0x02, 0x0f, 0x0d, 0x0b, 0x11, 0x18, 0x0f, + 0x08, 0x08, 0x08, 0x06, 0x05, 0x06, 0x02, 0x02, 0x06, 0x06, 0x02, 0x02, + 0x08, 0x03, 0xfe, 0xfe, 0x06, 0x0a, 0x09, 0x09, 0x07, 0x02, 0xfe, 0xfb, + 0xfe, 0x01, 0x00, 0xfe, 0x05, 0x0f, 0x0a, 0x06, 0x02, 0x00, 0x00, 0xfa, + 0xfb, 0xfa, 0xf6, 0xf3, 0xf1, 0xf0, 0xf4, 0xf6, 0xf8, 0x02, 0x0d, 0x04, + 0xff, 0xfd, 0x03, 0x0d, 0x04, 0x00, 0x07, 0x06, 0x03, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x0a, 0x10, 0x0f, 0x12, 0x16, 0x10, 0x06, + 0x06, 0x08, 0x0c, 0x0c, 0x1a, 0x1c, 0x11, 0x0f, 0x0f, 0x0c, 0x0a, 0x07, + 0x03, 0x01, 0x04, 0x06, 0x02, 0x02, 0x00, 0xfc, 0xfc, 0x04, 0x0e, 0x01, + 0xfa, 0xfc, 0xfa, 0xf7, 0xf6, 0xfa, 0xf2, 0xeb, 0xf0, 0xed, 0xe9, 0xf1, + 0xf8, 0xef, 0xee, 0xf0, 0xf1, 0xf8, 0x00, 0xfe, 0xfe, 0x03, 0x04, 0x07, + 0x0a, 0x06, 0x02, 0x03, 0x15, 0x1b, 0x1e, 0x1c, 0x15, 0x0c, 0x12, 0x1b, + 0x12, 0x0f, 0x10, 0x0d, 0x0d, 0x0f, 0x0b, 0x07, 0x07, 0x15, 0x14, 0x04, + 0x01, 0x04, 0x02, 0x00, 0xfe, 0xfd, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0xfa, + 0xef, 0xeb, 0xf4, 0xf8, 0xf7, 0xfa, 0xfe, 0xfe, 0x04, 0x0e, 0x0a, 0x0a, + 0x04, 0x00, 0x00, 0x03, 0x14, 0x12, 0x0d, 0x0d, 0x0a, 0x07, 0x04, 0x01, + 0xfe, 0xfe, 0x00, 0x05, 0x02, 0xfc, 0xfa, 0x00, 0x04, 0x0d, 0x08, 0xfe, + 0x00, 0x04, 0x01, 0xf9, 0xf3, 0xf7, 0x01, 0x01, 0xfe, 0xfc, 0xfc, 0xfa, + 0xf5, 0xf4, 0xf6, 0xfc, 0x00, 0x04, 0x0e, 0x0b, 0x04, 0x02, 0x06, 0x06, + 0x00, 0xfc, 0x00, 0x08, 0x1b, 0x1f, 0x22, 0x15, 0x10, 0x0f, 0x0d, 0x08, + 0x08, 0x0d, 0x0e, 0x0e, 0x0b, 0x0c, 0x0a, 0x09, 0x08, 0x10, 0x08, 0x03, + 0x0c, 0x07, 0xf8, 0xf6, 0x00, 0x00, 0xfc, 0xfc, 0xfd, 0xfc, 0xf8, 0xf2, + 0xeb, 0xec, 0xee, 0xee, 0xee, 0xf6, 0xfe, 0xf9, 0xfa, 0x00, 0x00, 0xfe, + 0x00, 0x00, 0xfc, 0x03, 0x11, 0x0b, 0x0a, 0x08, 0x08, 0x01, 0xfd, 0xfe, + 0xfd, 0x00, 0x0e, 0x11, 0x08, 0x09, 0x0c, 0x0a, 0x10, 0x14, 0x0c, 0x02, + 0x04, 0x0a, 0x0a, 0x06, 0x04, 0x00, 0x00, 0x08, 0x0b, 0x06, 0x00, 0xff, + 0x01, 0x0a, 0x08, 0x06, 0x08, 0x10, 0x14, 0x0e, 0x08, 0x04, 0x03, 0xfe, + 0xff, 0x00, 0x00, 0x12, 0x14, 0x07, 0x05, 0x06, 0x04, 0x00, 0xfc, 0xfa, + 0xfa, 0xfa, 0xf4, 0xea, 0xe9, 0xee, 0xec, 0xec, 0xfe, 0x00, 0xf8, 0x04, + 0x07, 0x02, 0xfe, 0xfa, 0xfc, 0x01, 0x00, 0x02, 0x00, 0x00, 0x04, 0x04, + 0x02, 0x01, 0x00, 0x02, 0x04, 0x04, 0x10, 0x15, 0x12, 0x16, 0x10, 0x08, + 0x08, 0x0c, 0x16, 0x25, 0x19, 0x0d, 0x0a, 0x0b, 0x0b, 0x09, 0x06, 0x04, + 0x05, 0x04, 0x04, 0x02, 0x00, 0x00, 0x00, 0x04, 0x0c, 0x04, 0xfc, 0xf6, + 0xf0, 0xf4, 0xf7, 0xf6, 0xf3, 0xf2, 0xf4, 0xfa, 0x04, 0x00, 0xfb, 0xf6, + 0xf4, 0xf4, 0xf2, 0xf2, 0xf8, 0xfd, 0x06, 0x0e, 0x10, 0x0c, 0x06, 0x00, + 0x00, 0x03, 0x0a, 0x12, 0x0c, 0x14, 0x1c, 0x15, 0x0e, 0x10, 0x10, 0x12, + 0x12, 0x0f, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0e, 0x05, 0x00, 0x00, + 0x01, 0x01, 0x01, 0x00, 0xfe, 0xfa, 0xfa, 0xfa, 0xfa, 0xf8, 0xf4, 0xf0, + 0xf0, 0xf0, 0xf2, 0xf6, 0x00, 0x0a, 0x0a, 0x0a, 0x0b, 0x0c, 0x05, 0x00, + 0x00, 0x04, 0x14, 0x1a, 0x16, 0x10, 0x0c, 0x08, 0x07, 0x05, 0x01, 0x00, + 0x00, 0x00, 0x02, 0x06, 0x00, 0x00, 0x06, 0x16, 0x10, 0x0b, 0xff, 0xf7, + 0xf6, 0xfc, 0xf8, 0xf9, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x02, 0x02, 0x02, + 0xfd, 0xf9, 0xfb, 0x00, 0xf8, 0xec, 0xf6, 0x00, 0x04, 0x04, 0x00, 0x00, + 0x02, 0x16, 0x29, 0x20, 0x18, 0x12, 0x0e, 0x0c, 0x08, 0x0a, 0x0d, 0x0b, + 0x0a, 0x0b, 0x0a, 0x04, 0x00, 0x00, 0x08, 0x07, 0x02, 0x00, 0x00, 0x03, + 0x00, 0x06, 0x04, 0x00, 0xff, 0x00, 0xf8, 0xf6, 0xf6, 0xf3, 0xf0, 0xec, + 0xee, 0xf0, 0xf4, 0xf8, 0xf6, 0xf6, 0x00, 0x08, 0x08, 0x01, 0xfc, 0xfd, + 0xfe, 0x0a, 0x12, 0x0a, 0x02, 0x07, 0x08, 0x06, 0x08, 0x12, 0x1c, 0x14, + 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x07, 0x13, 0x12, 0x10, 0x0a, 0x0a, 0x0c, + 0x08, 0x06, 0x04, 0x00, 0x00, 0xf8, 0xf0, 0x04, 0x0e, 0x0b, 0x04, 0x00, + 0x00, 0x03, 0x04, 0x00, 0xff, 0xfa, 0x00, 0x03, 0x02, 0x00, 0x00, 0xfe, + 0x02, 0x14, 0x10, 0x0a, 0x06, 0x02, 0x00, 0xfe, 0xfc, 0xfa, 0xf4, 0xee, + 0xe8, 0xea, 0xed, 0xec, 0xf2, 0x02, 0x08, 0x0b, 0x00, 0xfc, 0xff, 0x00, + 0xff, 0xff, 0x02, 0x05, 0x04, 0x01, 0x05, 0x0c, 0x0c, 0x04, 0x00, 0xff, + 0x00, 0x02, 0x04, 0x04, 0x0c, 0x0e, 0x1a, 0x1e, 0x17, 0x16, 0x12, 0x10, + 0x18, 0x23, 0x14, 0x0e, 0x0c, 0x0a, 0x0c, 0x0c, 0x0c, 0x0a, 0x06, 0x08, + 0x08, 0x04, 0xfc, 0xf8, 0x00, 0x04, 0xf8, 0xea, 0xe9, 0xec, 0xf3, 0xf4, + 0xf2, 0xf6, 0xf8, 0x05, 0x01, 0xfa, 0xfa, 0xfa, 0xf6, 0xf2, 0xf0, 0xf0, + 0xf0, 0xf6, 0xf8, 0xfc, 0x00, 0xff, 0x00, 0xfe, 0x00, 0x05, 0x04, 0x02, + 0x15, 0x1f, 0x24, 0x1c, 0x16, 0x16, 0x12, 0x10, 0x0e, 0x0e, 0x0a, 0x04, + 0x02, 0x00, 0xfe, 0x04, 0x12, 0x0a, 0x08, 0x06, 0x02, 0x04, 0x06, 0x02, + 0x00, 0x00, 0xfc, 0xfc, 0xfa, 0xf9, 0xf5, 0xf5, 0xfd, 0xfb, 0xf9, 0x04, + 0x0f, 0x07, 0x01, 0x03, 0x04, 0x01, 0x05, 0x05, 0x03, 0x05, 0x05, 0x12, + 0x23, 0x1d, 0x11, 0x04, 0x01, 0x03, 0x02, 0xf5, 0xfd, 0x01, 0x07, 0x0b, + 0x00, 0xf9, 0xfe, 0x0d, 0x05, 0xfb, 0xf9, 0xf5, 0xf5, 0xfb, 0xfb, 0xf7, + 0xfd, 0x07, 0x02, 0xff, 0xfc, 0xfd, 0x01, 0x00, 0xfd, 0xf9, 0xf9, 0xf6, + 0xf1, 0xed, 0xf1, 0xef, 0xf7, 0x01, 0x09, 0x09, 0x17, 0x19, 0x15, 0x24, + 0x21, 0x17, 0x11, 0x0d, 0x0c, 0x0b, 0x0d, 0x12, 0x13, 0x0f, 0x0b, 0x03, + 0x00, 0x00, 0xf5, 0xf9, 0xf5, 0xf1, 0xf1, 0xf5, 0xfb, 0xfb, 0xf7, 0xf7, + 0xfd, 0xfb, 0xf1, 0xf5, 0xfb, 0xfd, 0x05, 0x13, 0x19, 0x17, 0x13, 0x11, + 0x11, 0x17, 0x1f, 0x23, 0x23, 0x23, 0x21, 0x23, 0x21, 0x17, 0x09, 0x00, + 0xfb, 0xf1, 0xeb, 0xef, 0xef, 0xed, 0xe7, 0xe5, 0xeb, 0xf7, 0xf9, 0xf7, + 0xfb, 0xf9, 0xf5, 0xf9, 0xf9, 0xf8, 0xfd, 0x09, 0x0d, 0x07, 0x03, 0x03, + 0x00, 0x03, 0x0b, 0x0f, 0x07, 0x00, 0xfd, 0xf1, 0xeb, 0xf3, 0xfd, 0x09, + 0x0b, 0x05, 0x07, 0x18, 0x20, 0x1d, 0x1c, 0x21, 0x20, 0x17, 0x13, 0x13, + 0x0d, 0x05, 0xff, 0xf7, 0xf1, 0xf7, 0x02, 0x09, 0x08, 0x00, 0xf3, 0xed, + 0xed, 0xee, 0xf3, 0xfa, 0x01, 0x05, 0x00, 0xf5, 0xfb, 0x04, 0x03, 0xfd, + 0xf9, 0xf3, 0xf4, 0xfa, 0xf9, 0xf5, 0xfe, 0x08, 0x06, 0x00, 0x00, 0x02, + 0x01, 0x07, 0x0e, 0x0a, 0x08, 0x12, 0x1c, 0x1a, 0x16, 0x12, 0x0e, 0x0e, + 0x0b, 0x06, 0x10, 0x1d, 0x1c, 0x0d, 0x02, 0xfd, 0xfe, 0x00, 0xff, 0xf7, + 0xea, 0xe8, 0xef, 0xf0, 0xec, 0xec, 0xf6, 0x00, 0x02, 0x02, 0xfe, 0xfc, + 0xf8, 0xf6, 0xf8, 0xfc, 0x06, 0x10, 0x12, 0x0c, 0x0e, 0x14, 0x12, 0x10, + 0x0b, 0x04, 0x08, 0x0c, 0x04, 0xfa, 0xf0, 0xf2, 0xf7, 0xfc, 0xff, 0x00, + 0x00, 0x07, 0x10, 0x0c, 0x04, 0x08, 0x10, 0x0e, 0x0a, 0x08, 0x08, 0x06, + 0x00, 0xfc, 0xfe, 0x04, 0x08, 0x0e, 0x0c, 0x00, 0xf9, 0xf6, 0xf4, 0xf6, + 0xfa, 0x02, 0x0c, 0x0e, 0x04, 0x00, 0x0a, 0x16, 0x1a, 0x10, 0xff, 0xf4, + 0xf0, 0xf6, 0xf8, 0xf3, 0xf2, 0xf6, 0xf4, 0xf0, 0xf6, 0xfd, 0xfa, 0xf6, + 0xf4, 0xf0, 0xfa, 0x0c, 0x1a, 0x1c, 0x16, 0x0e, 0x0e, 0x10, 0x11, 0x13, + 0x16, 0x21, 0x28, 0x1c, 0x04, 0xfd, 0xff, 0x05, 0x07, 0x06, 0x00, 0xf5, + 0xef, 0xf6, 0xfc, 0xfe, 0x00, 0x08, 0x08, 0xfe, 0xfe, 0x00, 0xfc, 0xf6, + 0xf2, 0xec, 0xf5, 0xfe, 0x00, 0x02, 0x07, 0x09, 0x08, 0x00, 0xf7, 0xf4, + 0xfa, 0x02, 0x02, 0xf6, 0xf0, 0xf3, 0xfb, 0x04, 0x0d, 0x0e, 0x0a, 0x08, + 0x09, 0x0a, 0x08, 0x0a, 0x16, 0x1c, 0x18, 0x10, 0x12, 0x0e, 0x08, 0x0a, + 0x11, 0x18, 0x20, 0x1e, 0x0c, 0x00, 0xfb, 0xf7, 0xed, 0xea, 0xee, 0xee, + 0xf2, 0xfc, 0xfe, 0xf9, 0xfa, 0x00, 0xff, 0xfc, 0xfa, 0xf8, 0xf2, 0xf2, + 0xf7, 0xf5, 0xf4, 0xf9, 0xfd, 0xfe, 0x00, 0x04, 0x08, 0x00, 0xf4, 0xf0, + 0xfa, 0x0e, 0x21, 0x25, 0x20, 0x18, 0x15, 0x14, 0x1c, 0x28, 0x28, 0x25, + 0x21, 0x19, 0x0a, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf8, 0xef, 0xe6, 0xef, + 0xfb, 0xf7, 0xf5, 0xf4, 0xf1, 0xf4, 0xfa, 0xfe, 0xfa, 0xf4, 0xf0, 0xf0, + 0xf6, 0x00, 0x06, 0x0a, 0x0a, 0x0a, 0x02, 0xfc, 0xfd, 0xff, 0xfe, 0x02, + 0x06, 0x00, 0xfb, 0x01, 0x05, 0x17, 0x26, 0x29, 0x26, 0x14, 0x04, 0x03, + 0x06, 0x04, 0x03, 0x08, 0x0a, 0x07, 0x02, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x03, 0x08, 0x0a, 0x06, 0xff, 0xfa, 0xf2, 0xed, 0xf4, 0xf6, 0xf8, 0x01, + 0x06, 0x04, 0x05, 0x03, 0xfb, 0xfd, 0x01, 0x01, 0xff, 0xf7, 0xf9, 0x00, + 0xfe, 0xfa, 0x00, 0x0c, 0x12, 0x0c, 0x04, 0xfe, 0xf8, 0xf2, 0xf3, 0x00, + 0x0c, 0x10, 0x14, 0x0e, 0x0a, 0x14, 0x17, 0x1b, 0x1c, 0x14, 0x06, 0x08, + 0x0a, 0x04, 0x01, 0x01, 0x05, 0x09, 0x01, 0xfb, 0xf7, 0xf4, 0xf9, 0xfe, + 0xf4, 0xee, 0xf6, 0x00, 0x03, 0x03, 0xfe, 0xfa, 0xfb, 0xfa, 0x00, 0x12, + 0x1c, 0x1f, 0x1c, 0x0c, 0x00, 0xf9, 0xf5, 0xf0, 0xec, 0xea, 0xf0, 0xf4, + 0xf0, 0xf2, 0xff, 0x0b, 0x12, 0x13, 0x0d, 0x0c, 0x06, 0x06, 0x0a, 0x0c, + 0x04, 0x06, 0x14, 0x15, 0x12, 0x11, 0x0d, 0x0b, 0x0a, 0x03, 0x02, 0x0c, + 0x14, 0x10, 0x00, 0xfb, 0x00, 0xfe, 0xfa, 0xfc, 0x02, 0x06, 0x06, 0x03, + 0x01, 0xfd, 0xf7, 0xf2, 0xf0, 0xf2, 0xec, 0xec, 0xf2, 0xf5, 0xfb, 0xfa, + 0xf8, 0xff, 0x05, 0xff, 0xfa, 0xfd, 0xfc, 0xf7, 0xf4, 0x00, 0x15, 0x1c, + 0x17, 0x10, 0x11, 0x14, 0x19, 0x19, 0x17, 0x15, 0x13, 0x0d, 0x0b, 0x0b, + 0x06, 0x08, 0x10, 0x15, 0x15, 0x13, 0x10, 0x0e, 0x0a, 0xff, 0xef, 0xe6, + 0xe8, 0xe9, 0xea, 0xf0, 0xf7, 0xf3, 0xeb, 0xe7, 0xed, 0xfb, 0x04, 0x02, + 0x04, 0x04, 0x00, 0xfd, 0xfd, 0xf8, 0xf0, 0xf3, 0xf6, 0xf8, 0xfe, 0x04, + 0x09, 0x16, 0x1d, 0x1a, 0x11, 0x13, 0x16, 0x0f, 0x07, 0x0d, 0x12, 0x13, + 0x16, 0x1b, 0x1f, 0x1b, 0x17, 0x0e, 0x02, 0xfa, 0xfc, 0x02, 0x02, 0xfe, + 0xf6, 0xf3, 0xf5, 0xfd, 0xff, 0xf9, 0xf7, 0xfa, 0xf8, 0xf4, 0xf8, 0xfe, + 0xfb, 0xf1, 0xef, 0xf7, 0xf9, 0xfb, 0xfd, 0xfc, 0xfa, 0xfa, 0xf8, 0xfa, + 0x00, 0x04, 0x02, 0x04, 0x04, 0x00, 0xfc, 0x08, 0x1c, 0x29, 0x29, 0x25, + 0x21, 0x21, 0x21, 0x19, 0x0c, 0x05, 0x00, 0xf2, 0xec, 0xf8, 0x03, 0x03, + 0x01, 0x04, 0x06, 0x00, 0xfe, 0x02, 0x00, 0xfc, 0xf7, 0xf5, 0xf3, 0xef, + 0xf1, 0xf4, 0xfc, 0x04, 0xfe, 0xf4, 0xf4, 0x00, 0x0a, 0x0a, 0x07, 0x04, + 0xfe, 0xfd, 0x01, 0x01, 0xff, 0xfc, 0xf6, 0xf6, 0xff, 0x0b, 0x14, 0x14, + 0x12, 0x09, 0x03, 0x04, 0x04, 0x00, 0x00, 0x02, 0x0b, 0x12, 0x10, 0x12, + 0x12, 0x11, 0x12, 0x0f, 0x03, 0xfd, 0xfe, 0x01, 0x04, 0x08, 0x02, 0xfa, + 0xfc, 0x00, 0x02, 0xff, 0xfc, 0xf2, 0xee, 0xf0, 0xfa, 0x02, 0x02, 0xfc, + 0xf8, 0xf9, 0x02, 0x0c, 0x0c, 0x0d, 0x0c, 0x03, 0xfc, 0xf4, 0xf2, 0xf0, + 0xea, 0xec, 0xf7, 0xfd, 0x00, 0x01, 0x09, 0x13, 0x15, 0x12, 0x0c, 0x12, + 0x19, 0x19, 0x17, 0x12, 0x05, 0xf9, 0xf6, 0xfd, 0x0b, 0x14, 0x14, 0x10, + 0x0e, 0x0c, 0x0f, 0x0d, 0x07, 0x00, 0xfa, 0xfa, 0xfd, 0x00, 0x00, 0xfe, + 0xfc, 0x02, 0x00, 0xfc, 0xf4, 0xf4, 0xf8, 0xf8, 0xf8, 0xf2, 0xec, 0xee, + 0xf3, 0xf7, 0xfd, 0xf9, 0xee, 0xec, 0xf4, 0x00, 0x10, 0x1a, 0x14, 0x07, + 0x05, 0x09, 0x0e, 0x12, 0x15, 0x13, 0x10, 0x0e, 0x11, 0x14, 0x15, 0x13, + 0x11, 0x11, 0x10, 0x0a, 0x06, 0x0c, 0x0c, 0x0c, 0x0e, 0x0a, 0x06, 0x0a, + 0x0e, 0x0b, 0x01, 0xf0, 0xda, 0xd2, 0xd8, 0xe0, 0xed, 0xf6, 0xf2, 0xf0, + 0xf0, 0xf4, 0xfa, 0x00, 0x02, 0x00, 0xf9, 0xf9, 0xfc, 0xfe, 0xfa, 0xf8, + 0xff, 0x09, 0x10, 0x11, 0x16, 0x1b, 0x1c, 0x1c, 0x1c, 0x1a, 0x12, 0x13, + 0x19, 0x16, 0x0f, 0x05, 0x01, 0x03, 0x05, 0x0a, 0x12, 0x12, 0x0c, 0x03, + 0xfd, 0xfc, 0xfd, 0xf8, 0xf7, 0xf3, 0xf3, 0xf8, 0xfc, 0xfc, 0xf1, 0xf1, + 0xfa, 0xfe, 0xfe, 0xfe, 0xf7, 0xf2, 0xf5, 0xf4, 0xf7, 0xfc, 0xfd, 0xfe, + 0xfe, 0xf9, 0xf2, 0xf3, 0xf8, 0x00, 0x07, 0x12, 0x1c, 0x1a, 0x11, 0x10, + 0x11, 0x15, 0x1c, 0x24, 0x20, 0x16, 0x12, 0x15, 0x18, 0x0c, 0xfa, 0xf8, + 0xfb, 0xfb, 0x03, 0x0a, 0x04, 0xfe, 0xfb, 0xf8, 0xfd, 0x02, 0x06, 0x08, + 0x04, 0xf8, 0xeb, 0xe2, 0xe2, 0xe4, 0xea, 0xf4, 0x01, 0x03, 0xfe, 0xff, + 0x02, 0x06, 0x0c, 0x0a, 0xfd, 0xf6, 0xfa, 0x03, 0x07, 0x06, 0x07, 0x0d, + 0x0f, 0x10, 0x15, 0x13, 0x0e, 0x0a, 0x05, 0x06, 0x08, 0x07, 0x09, 0x0a, + 0x04, 0xfa, 0xfd, 0x02, 0xfe, 0xff, 0x06, 0x17, 0x1b, 0x0e, 0x00, 0xfc, + 0xfc, 0x00, 0x08, 0x0c, 0x02, 0xfe, 0x00, 0x00, 0xfe, 0xf9, 0xf7, 0xf8, + 0xfe, 0x03, 0x02, 0xfc, 0xfc, 0xfa, 0xf8, 0xf6, 0x00, 0x02, 0xfe, 0xf8, + 0xf3, 0xf5, 0xf9, 0xf6, 0xef, 0xef, 0xfa, 0x08, 0x0f, 0x0c, 0x07, 0x06, + 0x0a, 0x10, 0x1e, 0x20, 0x16, 0x14, 0x18, 0x17, 0x0f, 0x06, 0x07, 0x0d, + 0x11, 0x0c, 0x0d, 0x0d, 0x08, 0x04, 0x05, 0x0e, 0x0d, 0x0b, 0x04, 0xf6, + 0xed, 0xef, 0xef, 0xe6, 0xe2, 0xeb, 0xf4, 0xf7, 0xfc, 0xfa, 0xf4, 0xf6, + 0xf8, 0xf8, 0xf7, 0xf2, 0xef, 0xf8, 0xfd, 0xfd, 0x01, 0x07, 0x0a, 0x14, + 0x1b, 0x1b, 0x17, 0x12, 0x07, 0x01, 0x08, 0x14, 0x1a, 0x13, 0x09, 0x03, + 0x05, 0x0a, 0x0c, 0x05, 0x04, 0x0a, 0x15, 0x18, 0x0f, 0x05, 0x04, 0x06, + 0x04, 0x08, 0x11, 0x0b, 0xfe, 0xff, 0x01, 0xf7, 0xed, 0xec, 0xea, 0xe8, + 0xec, 0xf3, 0xf7, 0xf1, 0xed, 0xee, 0xf1, 0xf5, 0xfc, 0xf8, 0xf5, 0xfc, + 0x01, 0x00, 0xfc, 0xfb, 0x02, 0x09, 0x10, 0x12, 0x11, 0x14, 0x16, 0x1c, + 0x23, 0x27, 0x28, 0x20, 0x17, 0x14, 0x0f, 0x10, 0x12, 0x0e, 0x10, 0x11, + 0x09, 0x02, 0xff, 0xfa, 0xf7, 0xfc, 0x00, 0xfe, 0xf1, 0xec, 0xf0, 0xee, + 0xe7, 0xdd, 0xd8, 0xda, 0xe5, 0xf6, 0x02, 0x04, 0x02, 0x00, 0xfa, 0xf5, + 0xfa, 0x04, 0x03, 0xff, 0x06, 0x0e, 0x10, 0x15, 0x17, 0x18, 0x1a, 0x1b, + 0x18, 0x11, 0x0a, 0x0b, 0x0e, 0x15, 0x14, 0x09, 0x01, 0x01, 0x02, 0x03, + 0x00, 0x00, 0xfe, 0xff, 0xfa, 0xfa, 0x02, 0x02, 0x00, 0xfd, 0xff, 0x01, + 0x09, 0x12, 0x10, 0x09, 0x07, 0x03, 0xfb, 0xee, 0xef, 0xfd, 0xff, 0xf9, + 0xf9, 0xf6, 0xf5, 0xfb, 0x01, 0x01, 0xf9, 0xf5, 0xfa, 0x04, 0x03, 0xff, + 0x01, 0x00, 0xfe, 0xff, 0x03, 0x0b, 0x0d, 0x09, 0x0a, 0x0b, 0x11, 0x1a, + 0x1d, 0x14, 0x0c, 0x0d, 0x0f, 0x0d, 0x08, 0x06, 0x0e, 0x14, 0x10, 0x0b, + 0x07, 0x05, 0x02, 0x06, 0x03, 0xfd, 0xfa, 0xf9, 0xf8, 0xf8, 0xf7, 0xf2, + 0xe8, 0xe6, 0xeb, 0xf0, 0xf9, 0x04, 0x06, 0xfe, 0x00, 0x00, 0xfa, 0xfc, + 0xfd, 0xfc, 0xfe, 0x07, 0x0e, 0x06, 0x06, 0x13, 0x1c, 0x14, 0x05, 0xfd, + 0xfc, 0xfe, 0x01, 0x0a, 0x11, 0x0b, 0x02, 0x02, 0x0b, 0x0f, 0x0c, 0x08, + 0x01, 0xff, 0x05, 0x07, 0x07, 0x0a, 0x04, 0x02, 0x06, 0x0f, 0x12, 0x13, + 0x18, 0x18, 0x14, 0x0d, 0x00, 0xef, 0xef, 0xf9, 0xf7, 0xee, 0xf0, 0xf4, + 0xf0, 0xee, 0xf0, 0xf1, 0xed, 0xe8, 0xe4, 0xed, 0xff, 0x02, 0xfa, 0xf9, + 0xf6, 0xf6, 0xfa, 0x02, 0x0a, 0x0e, 0x14, 0x18, 0x1d, 0x1f, 0x1f, 0x1d, + 0x1a, 0x1a, 0x18, 0x18, 0x1b, 0x1d, 0x23, 0x26, 0x1c, 0x11, 0x0b, 0x04, + 0xfe, 0x00, 0x06, 0x01, 0xf5, 0xec, 0xea, 0xec, 0xee, 0xe6, 0xda, 0xd3, + 0xdb, 0xe4, 0xed, 0xf1, 0xf3, 0xf1, 0xf1, 0xf6, 0xf6, 0xf9, 0xff, 0x04, + 0x10, 0x19, 0x1b, 0x17, 0x15, 0x19, 0x1d, 0x1d, 0x15, 0x0a, 0x06, 0x02, + 0x05, 0x0d, 0x11, 0x0c, 0x06, 0x08, 0x0e, 0x13, 0x13, 0x0f, 0x09, 0xff, + 0xfb, 0xfb, 0xf8, 0xfb, 0x02, 0x01, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x0f, + 0x0b, 0x07, 0xfb, 0xf1, 0xf0, 0xf5, 0xf5, 0xef, 0xeb, 0xec, 0xf2, 0xf7, + 0xfd, 0xfe, 0xf8, 0xf1, 0xf2, 0xf6, 0xfb, 0x01, 0x05, 0x0a, 0x0b, 0x09, + 0x0b, 0x0d, 0x0d, 0x0d, 0x11, 0x14, 0x17, 0x1e, 0x1a, 0x16, 0x14, 0x12, + 0x12, 0x0d, 0x03, 0x06, 0x11, 0x16, 0x16, 0x10, 0x0a, 0x02, 0xf6, 0xee, + 0xf0, 0xef, 0xf0, 0xf9, 0xfc, 0xfb, 0xf8, 0xf9, 0xf5, 0xec, 0xe3, 0xe2, + 0xea, 0xf3, 0xf3, 0xf7, 0xfc, 0x01, 0x01, 0xfd, 0xf9, 0x04, 0x19, 0x21, + 0x24, 0x1d, 0x1d, 0x23, 0x23, 0x14, 0x01, 0xfc, 0xfc, 0xfe, 0xfe, 0x04, + 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x04, 0x02, 0xfe, 0xfb, 0xfc, + 0xff, 0xfa, 0xf0, 0xfa, 0x0a, 0x11, 0x0f, 0x0f, 0x16, 0x1c, 0x1e, 0x13, + 0x01, 0xfc, 0x06, 0x0b, 0x06, 0x00, 0x00, 0x02, 0xfd, 0xf5, 0xf2, 0xf4, + 0xf3, 0xef, 0xf0, 0xea, 0xea, 0xef, 0xf5, 0xf3, 0xee, 0xf1, 0xf9, 0xfb, + 0xff, 0x02, 0x06, 0x0d, 0x12, 0x09, 0x04, 0x10, 0x1a, 0x22, 0x28, 0x2b, + 0x22, 0x20, 0x26, 0x23, 0x1a, 0x1b, 0x18, 0x0b, 0xff, 0xfa, 0xfa, 0xf8, + 0xf7, 0xf5, 0xf4, 0xfa, 0xfd, 0xfa, 0xf6, 0xf8, 0xf5, 0xed, 0xe4, 0xd8, + 0xd4, 0xdf, 0xea, 0xf8, 0xfc, 0xfb, 0xfe, 0x01, 0x06, 0x0e, 0x17, 0x1b, + 0x17, 0x18, 0x19, 0x10, 0x0d, 0x08, 0xff, 0xf6, 0xf7, 0xff, 0x03, 0x07, + 0x0d, 0x10, 0x13, 0x10, 0x0d, 0x02, 0x03, 0x12, 0x12, 0x0e, 0x0c, 0x0d, + 0x0d, 0x0b, 0x0a, 0x07, 0x09, 0x0e, 0x08, 0x08, 0x08, 0x08, 0x02, 0xf7, + 0xf0, 0xee, 0xec, 0xeb, 0xf2, 0xf3, 0xee, 0xef, 0xf1, 0xe8, 0xe7, 0xe6, + 0xe9, 0xf6, 0xfb, 0xfc, 0x00, 0x09, 0x14, 0x11, 0x07, 0x00, 0x02, 0x05, + 0x07, 0x0b, 0x10, 0x16, 0x19, 0x16, 0x0f, 0x15, 0x25, 0x2e, 0x2f, 0x2d, + 0x28, 0x26, 0x22, 0x19, 0x0f, 0xff, 0xf0, 0xf0, 0xea, 0xe7, 0xec, 0xf4, + 0xf9, 0xf7, 0xf0, 0xe8, 0xe9, 0xf0, 0xef, 0xe7, 0xe1, 0xde, 0xdd, 0xde, + 0xe2, 0xe8, 0xf5, 0x01, 0x08, 0x0c, 0x12, 0x1f, 0x26, 0x26, 0x29, 0x25, + 0x22, 0x26, 0x21, 0x1a, 0x17, 0x14, 0x0d, 0x06, 0xff, 0xfd, 0x03, 0x02, + 0x02, 0x03, 0xfe, 0xf7, 0xf4, 0xf6, 0xf3, 0xf0, 0xef, 0xf2, 0xf9, 0xfe, + 0xfe, 0x01, 0x04, 0x06, 0x04, 0x00, 0x07, 0x17, 0x18, 0x15, 0x1a, 0x17, + 0x0e, 0x07, 0x01, 0x01, 0xfd, 0xf1, 0xeb, 0xeb, 0xef, 0xf6, 0xf7, 0xf6, + 0xf5, 0xf4, 0xf5, 0xfc, 0x0a, 0x13, 0x0f, 0x03, 0xf9, 0xf7, 0xf9, 0xf8, + 0xfc, 0x01, 0x07, 0x09, 0x0d, 0x15, 0x21, 0x29, 0x28, 0x28, 0x25, 0x1b, + 0x15, 0x15, 0x14, 0x0e, 0xfb, 0xec, 0xe6, 0xe6, 0xee, 0xf4, 0xfc, 0x02, + 0x02, 0xfd, 0xf6, 0xf6, 0xfd, 0xff, 0xfa, 0xf4, 0xef, 0xf2, 0xf7, 0xfd, + 0x02, 0x02, 0x08, 0x0a, 0x03, 0x06, 0x12, 0x15, 0x16, 0x15, 0x0a, 0x03, + 0xfe, 0xff, 0x00, 0xfd, 0xf7, 0xf6, 0xf4, 0xf5, 0xfa, 0xff, 0x05, 0x07, + 0x0b, 0x0b, 0x09, 0x11, 0x19, 0x16, 0x0d, 0x09, 0x0a, 0x0a, 0x05, 0x04, + 0x04, 0x09, 0x0f, 0x07, 0xfe, 0x09, 0x13, 0x15, 0x15, 0x12, 0x0b, 0x0a, + 0x06, 0xfe, 0xf1, 0xe6, 0xdc, 0xda, 0xde, 0xe4, 0xec, 0xf4, 0xf9, 0xfa, + 0xf3, 0xf5, 0xfc, 0x03, 0x03, 0xfd, 0xf8, 0xf7, 0xf7, 0xf8, 0xfa, 0xfd, + 0x00, 0x07, 0x11, 0x15, 0x1e, 0x33, 0x40, 0x3c, 0x37, 0x33, 0x2b, 0x29, + 0x29, 0x22, 0x19, 0x09, 0xfc, 0xf5, 0xf7, 0xfd, 0xf9, 0xf0, 0xec, 0xe8, + 0xe6, 0xe6, 0xe2, 0xdd, 0xd9, 0xd8, 0xd6, 0xd6, 0xd9, 0xe1, 0xe7, 0xf2, + 0xf7, 0xfc, 0x05, 0x0c, 0x14, 0x24, 0x2b, 0x29, 0x29, 0x2b, 0x29, 0x24, + 0x20, 0x1c, 0x0e, 0xff, 0xf4, 0xf8, 0x01, 0x05, 0x02, 0x02, 0x04, 0x07, + 0x08, 0x09, 0x09, 0x07, 0x02, 0x01, 0x02, 0xff, 0xfd, 0xfb, 0xf9, 0xfa, + 0xfa, 0xfa, 0xfe, 0x03, 0x0d, 0x18, 0x1b, 0x15, 0x0c, 0x05, 0x01, 0xfe, + 0xf9, 0xeb, 0xdb, 0xd4, 0xda, 0xe5, 0xef, 0xf7, 0xfd, 0x00, 0xfd, 0xff, + 0x07, 0x09, 0x0f, 0x11, 0x0c, 0x0b, 0x0f, 0x0f, 0x0f, 0x11, 0x0e, 0x0a, + 0x0e, 0x13, 0x18, 0x1d, 0x29, 0x2c, 0x26, 0x18, 0x10, 0x0e, 0x08, 0x02, + 0xfe, 0xf0, 0xe5, 0xdf, 0xe0, 0xe7, 0xee, 0xed, 0xed, 0xf1, 0xf7, 0xfb, + 0xfe, 0x00, 0x01, 0xfd, 0xfc, 0xfe, 0x01, 0xff, 0xff, 0xff, 0xfe, 0xfe, + 0x04, 0x08, 0x10, 0x1b, 0x25, 0x22, 0x1e, 0x1d, 0x1b, 0x17, 0x0b, 0x01, + 0xfd, 0xf7, 0xef, 0xeb, 0xf0, 0xf7, 0xfd, 0xff, 0x00, 0x03, 0x06, 0x08, + 0x0a, 0x08, 0x03, 0xfd, 0xfa, 0xfb, 0xf9, 0xf7, 0xfb, 0xf9, 0xf7, 0xf6, + 0xfc, 0x07, 0x13, 0x1f, 0x1c, 0x19, 0x21, 0x25, 0x21, 0x1b, 0x0e, 0x00, + 0x01, 0xfe, 0xf3, 0xf0, 0xf7, 0xfa, 0xfa, 0xf9, 0xfb, 0xf8, 0xf3, 0xed, + 0xe8, 0xe9, 0xe9, 0xec, 0xed, 0xef, 0xf2, 0xf5, 0xf4, 0xf2, 0xef, 0xf5, + 0x0a, 0x1e, 0x2c, 0x36, 0x39, 0x37, 0x3b, 0x3b, 0x36, 0x28, 0x18, 0x10, + 0x0f, 0x06, 0xfc, 0xfc, 0xfb, 0xef, 0xe7, 0xea, 0xee, 0xf3, 0xf5, 0xf6, + 0xf6, 0xef, 0xe9, 0xe3, 0xe6, 0xeb, 0xf4, 0xf4, 0xec, 0xf0, 0xf7, 0xfd, + 0x13, 0x20, 0x1b, 0x1b, 0x1e, 0x18, 0x15, 0x1c, 0x19, 0x04, 0xf2, 0xec, + 0xee, 0xed, 0xec, 0xf4, 0xfa, 0xff, 0x07, 0x0b, 0x0f, 0x11, 0x0e, 0x0f, + 0x18, 0x1b, 0x13, 0x10, 0x14, 0x13, 0x1a, 0x16, 0x07, 0x00, 0xfc, 0xfb, + 0x0a, 0x14, 0x14, 0x0f, 0x05, 0xfc, 0x01, 0x01, 0xf4, 0xe6, 0xe3, 0xe5, + 0xdf, 0xd9, 0xd6, 0xdd, 0xe3, 0xe9, 0xf4, 0xf9, 0xfe, 0x05, 0x05, 0x06, + 0x11, 0x14, 0x0f, 0x14, 0x15, 0x12, 0x12, 0x12, 0x11, 0x0c, 0x08, 0x13, + 0x23, 0x29, 0x2a, 0x2e, 0x2d, 0x2c, 0x27, 0x15, 0x00, 0xf7, 0xf2, 0xf3, + 0xef, 0xea, 0xe9, 0xe9, 0xea, 0xec, 0xf0, 0xf6, 0xf2, 0xf1, 0xf3, 0xf2, + 0xef, 0xf1, 0xf2, 0xee, 0xe7, 0xe6, 0xe8, 0xed, 0xf5, 0xfe, 0x0f, 0x1d, + 0x22, 0x20, 0x21, 0x22, 0x22, 0x24, 0x21, 0x1a, 0x17, 0x13, 0x0d, 0x0c, + 0x09, 0x07, 0x02, 0xfc, 0xfd, 0x02, 0x06, 0x0b, 0x05, 0xfc, 0xf8, 0xf8, + 0xf4, 0xf3, 0xf4, 0xf5, 0xf6, 0xf2, 0xef, 0xe9, 0xe5, 0xed, 0xf7, 0xfd, + 0xff, 0x0a, 0x17, 0x21, 0x26, 0x24, 0x1f, 0x21, 0x1a, 0x0a, 0x02, 0xff, + 0xff, 0x01, 0xfd, 0xf4, 0xf6, 0xfc, 0xfd, 0xfb, 0xf9, 0xfd, 0xfb, 0xf5, + 0xf4, 0xf3, 0xf8, 0xf9, 0xf6, 0xf5, 0xf3, 0xfa, 0x05, 0x15, 0x1f, 0x20, + 0x24, 0x30, 0x31, 0x28, 0x22, 0x15, 0x0d, 0x0b, 0xff, 0xef, 0xeb, 0xe7, + 0xe2, 0xe4, 0xed, 0xf3, 0xf7, 0xf6, 0xf4, 0xf7, 0x00, 0x07, 0x09, 0x03, + 0xff, 0x05, 0x0d, 0x0b, 0x09, 0x08, 0x0a, 0x13, 0x16, 0x13, 0x12, 0x10, + 0x15, 0x15, 0x0d, 0x04, 0xfb, 0xf4, 0xf5, 0xfa, 0xf8, 0xf2, 0xed, 0xe7, + 0xe2, 0xe3, 0xe9, 0xf3, 0xf7, 0xf9, 0xfb, 0x06, 0x11, 0x16, 0x1a, 0x1d, + 0x24, 0x29, 0x1e, 0x10, 0x0d, 0x10, 0x12, 0x13, 0x0f, 0x06, 0xfd, 0x02, + 0x09, 0x13, 0x18, 0x13, 0x05, 0xff, 0xfe, 0xfa, 0xf2, 0xeb, 0xe7, 0xe2, + 0xdf, 0xe7, 0xf6, 0xfc, 0xfe, 0xfe, 0x00, 0x02, 0xfc, 0xf6, 0xf1, 0xf6, + 0xf8, 0xf3, 0xf2, 0xf2, 0xf2, 0xf4, 0xfe, 0x16, 0x24, 0x22, 0x21, 0x21, + 0x28, 0x34, 0x35, 0x2c, 0x21, 0x1b, 0x19, 0x18, 0x13, 0x0c, 0x05, 0xfc, + 0xfd, 0xfd, 0xf5, 0xef, 0xed, 0xf0, 0xee, 0xeb, 0xf0, 0xef, 0xeb, 0xea, + 0xe8, 0xe6, 0xea, 0xed, 0xee, 0xee, 0xfc, 0x01, 0xff, 0xfd, 0xfc, 0xff, + 0x0b, 0x11, 0x10, 0x10, 0x1a, 0x2a, 0x30, 0x28, 0x19, 0x0e, 0x07, 0x0a, + 0x07, 0x04, 0x09, 0x08, 0x05, 0x05, 0x08, 0x0b, 0x0a, 0x07, 0x03, 0xfe, + 0xf8, 0xf6, 0xf7, 0xf2, 0xef, 0xf7, 0x01, 0xfe, 0xfe, 0x00, 0x03, 0x10, + 0x1c, 0x19, 0x10, 0x07, 0x04, 0x01, 0xf7, 0xf2, 0xee, 0xea, 0xe3, 0xe3, + 0xeb, 0xf9, 0x06, 0x08, 0xfe, 0xfc, 0x02, 0x06, 0x08, 0x06, 0x05, 0x05, + 0x07, 0x0b, 0x0e, 0x14, 0x1e, 0x29, 0x25, 0x20, 0x1f, 0x18, 0x14, 0x18, + 0x17, 0x0e, 0x0b, 0x07, 0x03, 0xff, 0xfd, 0xf4, 0xec, 0xe4, 0xda, 0xd6, + 0xd9, 0xde, 0xe0, 0xde, 0xe1, 0xef, 0xfc, 0xfd, 0x03, 0x10, 0x18, 0x1c, + 0x18, 0x17, 0x1c, 0x24, 0x25, 0x1e, 0x1a, 0x16, 0x14, 0x08, 0x03, 0x08, + 0x08, 0x01, 0xff, 0x00, 0xfe, 0xff, 0xff, 0xfb, 0xf3, 0xe9, 0xe6, 0xed, + 0xf7, 0xf8, 0xfb, 0x08, 0x13, 0x14, 0x0e, 0x0d, 0x0d, 0x07, 0xfa, 0xf2, + 0xf2, 0xf5, 0xfb, 0xfc, 0xf9, 0x00, 0x03, 0x04, 0x07, 0x09, 0x0e, 0x18, + 0x1d, 0x1c, 0x1c, 0x18, 0x14, 0x13, 0x10, 0x07, 0x01, 0x04, 0x05, 0x02, + 0x00, 0x00, 0xff, 0xfa, 0xf0, 0xeb, 0xee, 0xef, 0xec, 0xe6, 0xe5, 0xed, + 0xf3, 0xfa, 0xfd, 0x02, 0x03, 0x02, 0x01, 0x03, 0x06, 0x04, 0x09, 0x13, + 0x15, 0x14, 0x1c, 0x2b, 0x30, 0x29, 0x22, 0x1d, 0x12, 0x06, 0xfc, 0xf7, + 0xf9, 0xfb, 0xfb, 0xf9, 0xfc, 0x01, 0x00, 0xf8, 0xf4, 0xf1, 0xf0, 0xf2, + 0xf8, 0xfe, 0x04, 0x05, 0x07, 0x03, 0xff, 0xfc, 0xfd, 0x01, 0x09, 0x08, + 0x05, 0x09, 0x07, 0x02, 0xfc, 0xfa, 0xfc, 0xf6, 0xf1, 0xeb, 0xef, 0xf9, + 0x03, 0x08, 0x0e, 0x16, 0x1a, 0x1a, 0x16, 0x12, 0x10, 0x0d, 0x0f, 0x13, + 0x12, 0x0f, 0x12, 0x15, 0x12, 0x0a, 0x07, 0x09, 0x04, 0xfd, 0xff, 0x02, + 0x06, 0x05, 0xfd, 0xf7, 0xf5, 0xf9, 0xf6, 0xef, 0xe9, 0xe5, 0xe2, 0xe2, + 0xe1, 0xe2, 0xe7, 0xee, 0xf4, 0xf5, 0xf3, 0xfa, 0x03, 0x0f, 0x1b, 0x22, + 0x2c, 0x35, 0x31, 0x27, 0x21, 0x1e, 0x1f, 0x1c, 0x13, 0x0d, 0x0d, 0x13, + 0x11, 0x09, 0x06, 0x07, 0x05, 0xfd, 0xf4, 0xe8, 0xe0, 0xe1, 0xe3, 0xe5, + 0xe8, 0xf3, 0xfa, 0x03, 0x08, 0x02, 0xfd, 0xfd, 0xf9, 0xf6, 0xfd, 0x00, + 0x07, 0x09, 0x06, 0x05, 0x03, 0x04, 0x01, 0xfd, 0xff, 0x09, 0x13, 0x17, + 0x13, 0x0f, 0x12, 0x16, 0x16, 0x1a, 0x14, 0x07, 0xfe, 0x00, 0x05, 0x06, + 0x0c, 0x10, 0x09, 0x05, 0x03, 0xfb, 0xf8, 0xf7, 0xf5, 0xf7, 0xf8, 0xfa, + 0xfa, 0xf5, 0xf4, 0xf4, 0xf3, 0xf1, 0xee, 0xed, 0xf3, 0xfd, 0x0b, 0x10, + 0x12, 0x17, 0x19, 0x19, 0x20, 0x25, 0x24, 0x18, 0x09, 0x05, 0x04, 0xfd, + 0xff, 0x01, 0x01, 0xfa, 0xef, 0xec, 0xed, 0xef, 0xf3, 0xfd, 0x05, 0x05, + 0x05, 0x04, 0x07, 0x0c, 0x0b, 0x05, 0x06, 0x05, 0x02, 0x07, 0x12, 0x11, + 0x10, 0x0d, 0x09, 0x08, 0x04, 0xfa, 0xee, 0xe4, 0xe2, 0xe7, 0xed, 0xf7, + 0xff, 0x07, 0x0e, 0x0f, 0x0f, 0x0c, 0x07, 0x07, 0x10, 0x1c, 0x1d, 0x21, + 0x24, 0x19, 0x0f, 0x09, 0x02, 0xfb, 0xfb, 0xf9, 0xf4, 0xfc, 0x04, 0x00, + 0xf7, 0xf7, 0xf8, 0xf8, 0xf4, 0xf6, 0xef, 0xe8, 0xe9, 0xed, 0xf4, 0xf8, + 0xfa, 0xfb, 0xfb, 0xfd, 0x01, 0x0b, 0x14, 0x19, 0x1b, 0x1b, 0x20, 0x24, + 0x22, 0x1d, 0x1b, 0x19, 0x12, 0x0b, 0x0a, 0x08, 0x08, 0x0a, 0x05, 0xfd, + 0xfe, 0x04, 0x04, 0x01, 0x00, 0xfe, 0xf1, 0xe7, 0xe8, 0xe6, 0xe7, 0xf2, + 0xf6, 0xf3, 0xee, 0xee, 0xf2, 0xf6, 0xf8, 0xfc, 0xff, 0x07, 0x13, 0x0f, + 0x08, 0x0b, 0x12, 0x0c, 0x03, 0x06, 0x0a, 0x0c, 0x12, 0x1c, 0x1f, 0x1e, + 0x20, 0x1f, 0x1a, 0x17, 0x17, 0x10, 0xff, 0xf2, 0xf1, 0xf3, 0xfb, 0x01, + 0x00, 0xfd, 0xff, 0xfd, 0xfd, 0xfc, 0xfa, 0xfb, 0xfe, 0x01, 0xff, 0xfc, + 0xfa, 0xfb, 0xf2, 0xe6, 0xe1, 0xe8, 0xe9, 0xee, 0xf8, 0x00, 0x0c, 0x15, + 0x16, 0x12, 0x15, 0x1a, 0x1b, 0x19, 0x10, 0x10, 0x17, 0x1a, 0x1b, 0x16, + 0x0c, 0x05, 0x00, 0xfc, 0xff, 0x02, 0x02, 0x01, 0x05, 0x06, 0x02, 0xfc, + 0xf8, 0xf9, 0xf8, 0xf5, 0xff, 0x02, 0xfe, 0x00, 0xff, 0xfd, 0xff, 0x04, + 0x05, 0x09, 0x0b, 0x0a, 0x08, 0xfd, 0xee, 0xea, 0xee, 0xed, 0xee, 0xf6, + 0xfb, 0xfd, 0xff, 0x04, 0x0d, 0x0e, 0x0a, 0x13, 0x1f, 0x28, 0x29, 0x23, + 0x1e, 0x14, 0x08, 0xff, 0x00, 0xfe, 0xff, 0x05, 0x08, 0x0e, 0x0f, 0x0d, + 0x05, 0xfe, 0xfa, 0xf2, 0xe9, 0xdd, 0xd6, 0xe1, 0xec, 0xee, 0xf1, 0xf6, + 0xf5, 0xf5, 0xfb, 0x09, 0x15, 0x15, 0x17, 0x20, 0x25, 0x20, 0x18, 0x14, + 0x17, 0x13, 0x0b, 0x09, 0x0a, 0x09, 0x01, 0xfc, 0xfd, 0xfe, 0xfb, 0xf9, + 0xfa, 0xff, 0x01, 0x03, 0x01, 0xf6, 0xef, 0xf6, 0xfb, 0x00, 0x01, 0xfd, + 0xfa, 0xfb, 0xfe, 0xfc, 0xf9, 0xfa, 0x08, 0x12, 0x13, 0x0d, 0x06, 0x04, + 0xff, 0xfb, 0xff, 0x03, 0x04, 0x06, 0x07, 0x07, 0x0e, 0x18, 0x1d, 0x1e, + 0x1d, 0x1e, 0x20, 0x1c, 0x0d, 0xfe, 0xf9, 0xf6, 0xed, 0xe6, 0xe4, 0xec, + 0xf9, 0xff, 0xfe, 0xfd, 0xfa, 0xfa, 0xfe, 0x00, 0x05, 0x03, 0xff, 0xfa, + 0xf2, 0xf1, 0xf6, 0xf6, 0xf4, 0xf7, 0x00, 0x04, 0x13, 0x1e, 0x1d, 0x1f, + 0x1f, 0x1d, 0x14, 0x06, 0xf5, 0xf6, 0x0b, 0x15, 0x17, 0x17, 0x17, 0x11, + 0x05, 0xfd, 0x01, 0x03, 0x00, 0x01, 0x04, 0x07, 0x09, 0x07, 0xfe, 0xef, + 0xea, 0xed, 0xf6, 0xf3, 0xf2, 0xf7, 0xf7, 0xf7, 0xf7, 0xf3, 0xee, 0xf7, + 0x07, 0x0f, 0x12, 0x10, 0x05, 0x01, 0xfe, 0xf9, 0xf9, 0xff, 0x04, 0x05, + 0x05, 0x09, 0x0f, 0x14, 0x19, 0x1f, 0x27, 0x2a, 0x23, 0x16, 0x09, 0x07, + 0x0c, 0x0b, 0x00, 0xf2, 0xec, 0xf7, 0x02, 0x09, 0x0e, 0x10, 0x0b, 0x07, + 0x02, 0xfb, 0xf5, 0xeb, 0xdf, 0xda, 0xd5, 0xd7, 0xe1, 0xed, 0xf0, 0xf3, + 0xfe, 0x03, 0x04, 0x07, 0x11, 0x1e, 0x28, 0x28, 0x20, 0x0d, 0x00, 0x09, + 0x19, 0x1d, 0x17, 0x13, 0x13, 0x13, 0x0b, 0x09, 0x0e, 0x0e, 0x06, 0x00, + 0xfc, 0xfa, 0xf9, 0xf4, 0xed, 0xef, 0xf6, 0xff, 0x04, 0xff, 0xfa, 0xfc, + 0xfd, 0xfa, 0xf5, 0xf3, 0xf8, 0x06, 0x13, 0x18, 0x10, 0x02, 0xfc, 0xfa, + 0xf9, 0xf8, 0xf6, 0xf7, 0xfc, 0xfc, 0xf9, 0x00, 0x0e, 0x13, 0x13, 0x1b, + 0x27, 0x2a, 0x1f, 0x10, 0x05, 0x02, 0x01, 0xfc, 0xf3, 0xee, 0xf5, 0xff, + 0x06, 0x07, 0x09, 0x0c, 0x0e, 0x0d, 0x08, 0xfb, 0xf0, 0xea, 0xec, 0xf1, + 0xf3, 0xf3, 0xef, 0xf4, 0xfa, 0x00, 0x10, 0x1a, 0x19, 0x17, 0x18, 0x1d, + 0x1c, 0x12, 0x01, 0xf2, 0xea, 0xf1, 0x02, 0x0f, 0x10, 0x11, 0x0e, 0x06, + 0xfb, 0xf8, 0xfd, 0x06, 0x09, 0x06, 0x06, 0x05, 0x01, 0xfd, 0xf9, 0xfd, + 0x02, 0xf9, 0xf5, 0xff, 0x00, 0xff, 0x04, 0x05, 0xfd, 0xf8, 0xfb, 0x00, + 0x0b, 0x0d, 0x07, 0xfd, 0xff, 0x04, 0x07, 0x05, 0x05, 0x06, 0x02, 0xff, + 0x00, 0x06, 0x11, 0x1d, 0x20, 0x28, 0x28, 0x19, 0x0a, 0x03, 0x02, 0x01, + 0xf9, 0xed, 0xe7, 0xeb, 0xef, 0xf5, 0x03, 0x0a, 0x05, 0x01, 0x03, 0x06, + 0x06, 0xfe, 0xf0, 0xe6, 0xe1, 0xe2, 0xe5, 0xee, 0xf9, 0x01, 0x04, 0x09, + 0x0f, 0x13, 0x1f, 0x26, 0x25, 0x22, 0x18, 0x06, 0x00, 0x05, 0x07, 0x09, + 0x13, 0x14, 0x13, 0x13, 0x15, 0x12, 0x12, 0x0e, 0x03, 0xff, 0xfe, 0xfe, + 0xf9, 0xee, 0xea, 0xe8, 0xea, 0xf4, 0xf6, 0xf8, 0xfb, 0xf8, 0xf2, 0xf0, + 0xf1, 0xf4, 0xfa, 0x00, 0x03, 0x07, 0x0f, 0x10, 0x0b, 0x06, 0x03, 0x03, + 0x03, 0x02, 0x02, 0x05, 0x06, 0x08, 0x0d, 0x11, 0x0f, 0x16, 0x23, 0x27, + 0x1b, 0x13, 0x0e, 0x09, 0x06, 0x05, 0x02, 0xfd, 0xf8, 0xf7, 0xf3, 0xf8, + 0x06, 0x0d, 0x09, 0x09, 0x08, 0xff, 0xf8, 0xf4, 0xe8, 0xe1, 0xe0, 0xdf, + 0xde, 0xe5, 0xf0, 0xfb, 0x05, 0x0c, 0x0e, 0x12, 0x17, 0x1e, 0x1d, 0x19, + 0x0d, 0x01, 0xfb, 0xfa, 0xfa, 0x02, 0x15, 0x1d, 0x18, 0x12, 0x0f, 0x0f, + 0x14, 0x15, 0x0e, 0x08, 0x04, 0xff, 0xfd, 0xfc, 0xfc, 0xfe, 0x02, 0xfd, + 0xf6, 0xfa, 0x03, 0x02, 0xff, 0xfd, 0xf6, 0xf1, 0xf6, 0xfa, 0xfa, 0xfd, + 0x01, 0xfe, 0xfa, 0xfc, 0xfe, 0x06, 0x0c, 0x06, 0xf8, 0xf5, 0xf9, 0x00, + 0x06, 0x0f, 0x13, 0x1d, 0x27, 0x25, 0x1b, 0x13, 0x0e, 0x07, 0x00, 0xf9, + 0xf7, 0xfa, 0xff, 0xff, 0xfd, 0x02, 0x0a, 0x0a, 0x07, 0x06, 0x05, 0x01, + 0xfd, 0xf9, 0xec, 0xe6, 0xee, 0xf6, 0xf5, 0xf4, 0xf7, 0x01, 0x0a, 0x0d, + 0x13, 0x1a, 0x1e, 0x1b, 0x14, 0x0e, 0x02, 0xfb, 0xfc, 0xf9, 0xf6, 0xf7, + 0x05, 0x0f, 0x13, 0x10, 0x0e, 0x0e, 0x10, 0x0a, 0x00, 0x00, 0x01, 0xfb, + 0xf6, 0xf3, 0xef, 0xf8, 0x05, 0x05, 0xff, 0xfb, 0xfc, 0xfd, 0xff, 0x02, + 0x00, 0x00, 0x04, 0x04, 0x05, 0x05, 0x07, 0x0b, 0x0b, 0x09, 0x07, 0x07, + 0x0d, 0x0e, 0x05, 0xff, 0x02, 0x03, 0x04, 0x05, 0x0d, 0x1b, 0x1b, 0x14, + 0x0f, 0x08, 0x03, 0x04, 0x05, 0xfd, 0xf2, 0xf0, 0xf2, 0xf4, 0xfb, 0xfe, + 0x03, 0x09, 0x06, 0x02, 0x00, 0xff, 0xfb, 0xf4, 0xe9, 0xe2, 0xe6, 0xee, + 0xf6, 0xfa, 0x02, 0x0c, 0x12, 0x17, 0x1a, 0x1d, 0x1f, 0x1e, 0x17, 0x10, + 0x09, 0x01, 0x03, 0x09, 0x0c, 0x09, 0x0a, 0x0e, 0x0f, 0x0f, 0x12, 0x10, + 0x12, 0x0e, 0xff, 0xfb, 0xfe, 0xf7, 0xf2, 0xed, 0xef, 0xf1, 0xf2, 0xf5, + 0xf9, 0xf9, 0xfb, 0xfc, 0xf8, 0xf7, 0xf4, 0xf7, 0xfd, 0xfd, 0xfd, 0xfd, + 0xff, 0x02, 0x0c, 0x15, 0x12, 0x0c, 0x0a, 0x07, 0x04, 0x07, 0x0d, 0x10, + 0x12, 0x13, 0x1d, 0x25, 0x21, 0x1c, 0x16, 0x11, 0x09, 0x06, 0x03, 0xfe, + 0xf9, 0xfa, 0xf9, 0xf5, 0xf7, 0xf8, 0xf8, 0xff, 0x01, 0xfd, 0xfa, 0xf8, + 0xf5, 0xf3, 0xec, 0xea, 0xea, 0xeb, 0xed, 0xf2, 0xfe, 0x0a, 0x12, 0x18, + 0x1a, 0x17, 0x18, 0x15, 0x0d, 0x07, 0x02, 0xfe, 0xfc, 0xfe, 0x02, 0x06, + 0x0c, 0x14, 0x16, 0x17, 0x17, 0x15, 0x15, 0x15, 0x0b, 0x03, 0x02, 0xff, + 0xfa, 0xfd, 0x03, 0x00, 0xfa, 0xf6, 0xf5, 0xf4, 0xfb, 0xff, 0xfa, 0xf7, + 0xf7, 0xfb, 0xff, 0xfc, 0xfa, 0xfa, 0xfa, 0xfd, 0x00, 0x02, 0x06, 0x08, + 0x0a, 0x08, 0x03, 0x03, 0x03, 0x02, 0x07, 0x0d, 0x11, 0x13, 0x14, 0x16, + 0x16, 0x15, 0x14, 0x0b, 0xff, 0xf8, 0xf5, 0xf9, 0x03, 0x04, 0x01, 0x03, + 0x05, 0x0b, 0x0b, 0x05, 0x00, 0xfe, 0xfb, 0xf4, 0xea, 0xeb, 0xf2, 0xf4, + 0xf6, 0xfa, 0x00, 0x04, 0x07, 0x11, 0x17, 0x15, 0x12, 0x0e, 0x06, 0x07, + 0x05, 0x00, 0xfe, 0xfb, 0xfd, 0xff, 0x00, 0x0d, 0x17, 0x18, 0x12, 0x0d, + 0x0b, 0x08, 0x00, 0xfb, 0xfd, 0xfa, 0xf5, 0xf2, 0xf5, 0xfb, 0xf9, 0xfa, + 0xff, 0x03, 0x05, 0x01, 0xff, 0x03, 0x07, 0x06, 0x04, 0x01, 0x05, 0x09, + 0x08, 0x0d, 0x0f, 0x0a, 0x02, 0x00, 0x07, 0x09, 0x05, 0x03, 0x03, 0x04, + 0x0e, 0x10, 0x0f, 0x0d, 0x0e, 0x0e, 0x07, 0x02, 0x03, 0x00, 0xf9, 0xfa, + 0xf8, 0xf9, 0xf9, 0xf7, 0xf9, 0xfa, 0xf7, 0xf8, 0xfb, 0x00, 0x06, 0x06, + 0x01, 0xfc, 0xf3, 0xed, 0xed, 0xf4, 0x00, 0x0a, 0x13, 0x17, 0x19, 0x1e, + 0x24, 0x20, 0x1a, 0x12, 0x0c, 0x05, 0xfd, 0xfd, 0xfe, 0xfd, 0x01, 0x04, + 0x00, 0x04, 0x0d, 0x10, 0x12, 0x13, 0x11, 0x07, 0xfd, 0xff, 0x03, 0xfd, + 0xf6, 0xf5, 0xf2, 0xef, 0xed, 0xf2, 0xfe, 0x07, 0x03, 0xf7, 0xf1, 0xf5, + 0xf7, 0xfa, 0xfe, 0x01, 0x03, 0x00, 0xfe, 0x05, 0x09, 0x0a, 0x0b, 0x0d, + 0x0f, 0x0e, 0x0f, 0x0f, 0x11, 0x17, 0x17, 0x13, 0x17, 0x1c, 0x1e, 0x18, + 0x13, 0x0d, 0x02, 0xf9, 0xf4, 0xf7, 0xfb, 0xfe, 0xf8, 0xf5, 0xf9, 0xfe, + 0xfa, 0xfa, 0xfd, 0xfe, 0xf8, 0xf3, 0xf1, 0xf1, 0xf0, 0xec, 0xf0, 0xf9, + 0xfc, 0x02, 0x09, 0x0c, 0x0a, 0x0a, 0x10, 0x15, 0x18, 0x1a, 0x15, 0x0a, + 0x02, 0xff, 0xfb, 0xfc, 0x02, 0x0b, 0x14, 0x1a, 0x1c, 0x1a, 0x1a, 0x1b, + 0x17, 0x10, 0x08, 0xfe, 0xf7, 0xf2, 0xf0, 0xf3, 0xf1, 0xef, 0xef, 0xf0, + 0xf4, 0xfd, 0xfe, 0xfc, 0xfe, 0xfc, 0xf9, 0xfd, 0x05, 0x09, 0x06, 0xfe, + 0xfd, 0xff, 0x00, 0x01, 0x08, 0x12, 0x16, 0x0d, 0x01, 0xf9, 0xfe, 0x09, + 0x0d, 0x11, 0x14, 0x0f, 0x0a, 0x0b, 0x0f, 0x09, 0xff, 0x00, 0x02, 0xff, + 0x00, 0x06, 0x06, 0x07, 0x04, 0xfe, 0xff, 0x09, 0x10, 0x09, 0xfc, 0xf7, + 0xf7, 0xf1, 0xe9, 0xe8, 0xf6, 0xff, 0xff, 0x02, 0x08, 0x0c, 0x12, 0x15, + 0x14, 0x12, 0x0a, 0x01, 0xfe, 0xfe, 0xfb, 0xf9, 0xfa, 0x00, 0x00, 0xfe, + 0x06, 0x0f, 0x0f, 0x09, 0x07, 0x0c, 0x14, 0x18, 0x13, 0x03, 0xfc, 0xf9, + 0xf4, 0xee, 0xef, 0xf8, 0x04, 0x09, 0x08, 0x04, 0x02, 0x04, 0x07, 0x08, + 0x06, 0x04, 0xfe, 0xf9, 0xf9, 0xfa, 0xfd, 0x01, 0x03, 0x00, 0xff, 0x07, + 0x11, 0x13, 0x0b, 0x04, 0x09, 0x0f, 0x13, 0x17, 0x14, 0x10, 0x0a, 0x09, + 0x04, 0xfe, 0xfc, 0x02, 0x08, 0x00, 0xf2, 0xf0, 0xef, 0xf0, 0xf7, 0xfc, + 0x00, 0x02, 0xff, 0xf9, 0xf9, 0xfb, 0xf7, 0xf5, 0xf5, 0xf6, 0xfe, 0x06, + 0x11, 0x16, 0x16, 0x15, 0x1a, 0x20, 0x23, 0x1d, 0x12, 0x05, 0xfe, 0xfb, + 0xf6, 0xf6, 0xfb, 0x03, 0x04, 0x02, 0x06, 0x10, 0x12, 0x12, 0x16, 0x13, + 0x0b, 0x05, 0xfb, 0xf3, 0xf6, 0xf1, 0xee, 0xee, 0xef, 0xf2, 0xf8, 0xfc, + 0xff, 0xf6, 0xee, 0xf5, 0x04, 0x0a, 0x0b, 0x0e, 0x06, 0xfe, 0xfc, 0x00, + 0x00, 0x06, 0x0e, 0x14, 0x19, 0x17, 0x13, 0x12, 0x0e, 0x13, 0x19, 0x14, + 0x0d, 0x0b, 0x03, 0x06, 0x0a, 0x06, 0x02, 0xfc, 0xf6, 0xfa, 0xfe, 0x02, + 0xff, 0xfd, 0xfb, 0xfd, 0xfe, 0x00, 0x02, 0x04, 0xfb, 0xf4, 0xf6, 0xf5, + 0xf2, 0xf6, 0xfb, 0xff, 0xfd, 0xf7, 0xf6, 0xfe, 0x07, 0x14, 0x17, 0x16, + 0x15, 0x0c, 0x04, 0x06, 0x03, 0xfc, 0xfc, 0x01, 0x03, 0x07, 0x0e, 0x16, + 0x19, 0x1a, 0x19, 0x1c, 0x22, 0x1f, 0x16, 0x06, 0xf7, 0xf2, 0xf4, 0xee, + 0xea, 0xee, 0xf7, 0xfc, 0xfa, 0xfb, 0xfd, 0xfa, 0xff, 0x03, 0x02, 0xfb, + 0xf9, 0xf9, 0xfa, 0xf9, 0xf7, 0xfa, 0x00, 0x02, 0x02, 0x05, 0x0a, 0x0a, + 0x08, 0x02, 0x09, 0x15, 0x1d, 0x1b, 0x15, 0x0d, 0x09, 0x0d, 0x0c, 0x08, + 0x05, 0x07, 0x0b, 0x0a, 0x05, 0x00, 0x01, 0x05, 0x06, 0x04, 0xff, 0xf8, + 0xf6, 0xf6, 0xf3, 0xf2, 0xf3, 0xf0, 0xee, 0xf1, 0xf8, 0xfd, 0x02, 0x07, + 0x06, 0x0b, 0x17, 0x1e, 0x19, 0x15, 0x0f, 0x06, 0x01, 0x02, 0xfe, 0xfa, + 0xff, 0x04, 0x02, 0xfc, 0xf9, 0xff, 0x07, 0x10, 0x16, 0x16, 0x15, 0x0e, + 0x07, 0x03, 0xfe, 0xf9, 0xf5, 0xf1, 0xf1, 0xf8, 0xfd, 0x04, 0x09, 0x09, + 0x00, 0x04, 0x0c, 0x10, 0x0b, 0x04, 0xfb, 0xf4, 0xf5, 0xf8, 0xf6, 0xfb, + 0x04, 0x0a, 0x08, 0x08, 0x0d, 0x0c, 0x0d, 0x12, 0x11, 0x09, 0x05, 0x03, + 0x08, 0x0b, 0x09, 0x07, 0x04, 0x03, 0x00, 0xfc, 0xf9, 0xfe, 0x00, 0xf8, + 0xf5, 0x00, 0x07, 0x05, 0x04, 0x01, 0xfe, 0xff, 0xfe, 0xfa, 0xf6, 0xf8, + 0x01, 0x05, 0x03, 0x00, 0x04, 0x07, 0x11, 0x18, 0x17, 0x12, 0x0c, 0x05, + 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xfa, 0xfe, 0x04, 0x0a, 0x0d, 0x0e, + 0x16, 0x1d, 0x1a, 0x15, 0x11, 0x0a, 0x04, 0x00, 0xfa, 0xf2, 0xf1, 0xf2, + 0xf6, 0xf2, 0xee, 0xf2, 0xf6, 0xfb, 0xfa, 0xfc, 0x02, 0x04, 0x04, 0x02, + 0xff, 0xff, 0xfe, 0xf9, 0xfd, 0x02, 0x08, 0x0f, 0x11, 0x17, 0x16, 0x16, + 0x1a, 0x20, 0x1b, 0x13, 0x0a, 0x03, 0x00, 0x02, 0x03, 0x02, 0x04, 0x07, + 0x02, 0xff, 0xfe, 0x04, 0x07, 0x01, 0xfa, 0xfb, 0xf7, 0xf3, 0xf5, 0xfa, + 0xfd, 0xfa, 0xf6, 0xf2, 0xf0, 0xef, 0xf5, 0xf7, 0xfb, 0xff, 0xff, 0x04, + 0x10, 0x19, 0x1c, 0x1d, 0x17, 0x0c, 0x03, 0x04, 0x02, 0x01, 0x07, 0x08, + 0x06, 0x06, 0x0a, 0x0f, 0x12, 0x13, 0x17, 0x18, 0x11, 0x08, 0x03, 0xff, + 0xfe, 0xfa, 0xf2, 0xed, 0xed, 0xf1, 0xf5, 0xfa, 0x04, 0x06, 0x03, 0x02, + 0x01, 0x01, 0x03, 0x08, 0x04, 0xfa, 0xfa, 0xfa, 0xf8, 0xf9, 0x00, 0x00, + 0x00, 0x03, 0x06, 0x07, 0x06, 0x08, 0x0f, 0x13, 0x11, 0x0d, 0x0c, 0x0e, + 0x0e, 0x0a, 0x07, 0x06, 0x08, 0x04, 0x01, 0x09, 0x10, 0x0e, 0x0a, 0x08, + 0x08, 0x04, 0x00, 0xfa, 0xf2, 0xf0, 0xf4, 0xf6, 0xf1, 0xf4, 0xf9, 0xf7, + 0xfb, 0x04, 0x05, 0x02, 0x02, 0x03, 0x06, 0x0b, 0x0c, 0x0f, 0x11, 0x06, + 0xff, 0x00, 0xfc, 0xfc, 0xfb, 0xf8, 0xfd, 0x06, 0x08, 0x07, 0x0d, 0x16, + 0x1e, 0x21, 0x1c, 0x15, 0x08, 0x03, 0x04, 0xfe, 0xf8, 0xfa, 0xfa, 0xf7, + 0xfb, 0x02, 0x06, 0x06, 0x03, 0xfc, 0xf9, 0xfa, 0xfa, 0xfc, 0xfc, 0xf6, + 0xf6, 0xf7, 0xf5, 0xf7, 0xfd, 0x06, 0x11, 0x16, 0x11, 0x0e, 0x0f, 0x13, + 0x16, 0x18, 0x13, 0x0a, 0x05, 0x03, 0x04, 0x05, 0x07, 0x0a, 0x03, 0xf8, + 0xf8, 0xfe, 0x02, 0x01, 0xfc, 0xfb, 0x00, 0x00, 0xff, 0x01, 0xff, 0xfc, + 0xfd, 0xfb, 0xf4, 0xf2, 0xf5, 0xff, 0x08, 0x0e, 0x0c, 0x0a, 0x10, 0x12, + 0x15, 0x13, 0x0f, 0x07, 0xff, 0xf8, 0xf8, 0xfd, 0x04, 0x09, 0x04, 0x01, + 0x09, 0x0a, 0x08, 0x06, 0x05, 0x09, 0x11, 0x12, 0x0f, 0x0a, 0x03, 0x01, + 0xff, 0xf6, 0xee, 0xec, 0xed, 0xf0, 0xf9, 0x00, 0x01, 0x03, 0x05, 0x05, + 0x07, 0x0b, 0x07, 0x00, 0xfe, 0xfd, 0xfd, 0xfc, 0x00, 0x01, 0x01, 0x0a, + 0x15, 0x14, 0x0b, 0x06, 0x07, 0x0c, 0x0c, 0x0a, 0x07, 0x04, 0x02, 0x01, + 0x01, 0x01, 0x06, 0x0a, 0x07, 0x06, 0x06, 0x07, 0x08, 0x09, 0x07, 0x04, + 0x05, 0x02, 0xf8, 0xf2, 0xf3, 0xf5, 0xf8, 0xfc, 0xf6, 0xec, 0xee, 0xfa, + 0xff, 0x00, 0xfd, 0xfe, 0x02, 0x09, 0x14, 0x18, 0x19, 0x13, 0x08, 0xfe, + 0xfb, 0xfe, 0x05, 0x09, 0x0a, 0x0e, 0x0f, 0x0f, 0x11, 0x13, 0x17, 0x18, + 0x18, 0x0e, 0xfd, 0xf7, 0xf9, 0xfd, 0x00, 0x01, 0xfb, 0xf4, 0xf8, 0xfd, + 0xfe, 0xfc, 0xfa, 0xfa, 0xfa, 0xfa, 0xfc, 0x01, 0x05, 0x01, 0xfb, 0xf8, + 0xf4, 0xf1, 0xf4, 0xfa, 0x02, 0x0a, 0x11, 0x12, 0x0c, 0x10, 0x19, 0x21, + 0x1d, 0x14, 0x0a, 0x07, 0x06, 0x08, 0x0a, 0x0d, 0x0a, 0x0b, 0x09, 0x05, + 0x00, 0x01, 0x02, 0x02, 0x02, 0xfd, 0xf8, 0xfa, 0xf8, 0xf3, 0xf0, 0xf3, + 0xf8, 0xfb, 0xf9, 0xf8, 0x00, 0x06, 0x0a, 0x08, 0x07, 0x0a, 0x0d, 0x12, + 0x10, 0x09, 0x04, 0x04, 0x02, 0xfb, 0xf9, 0xfd, 0x01, 0x01, 0x05, 0x05, + 0x04, 0x02, 0x02, 0x08, 0x12, 0x1c, 0x21, 0x19, 0x0a, 0x00, 0x01, 0xfe, + 0xfb, 0xfa, 0xf6, 0xf7, 0xfc, 0x05, 0x08, 0x07, 0x09, 0x0a, 0x03, 0xfa, + 0xf5, 0xf3, 0xf6, 0xfc, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x02, 0x05, 0x09, + 0x0b, 0x06, 0xff, 0x01, 0x0f, 0x17, 0x12, 0x0b, 0x06, 0x04, 0xfe, 0xfc, + 0x01, 0x07, 0x07, 0x07, 0x05, 0x03, 0x03, 0x08, 0x10, 0x14, 0x13, 0x07, + 0xfc, 0xf7, 0xf7, 0xf8, 0xf8, 0xfb, 0xfd, 0xf8, 0xf2, 0xf6, 0x00, 0x01, + 0x01, 0x01, 0xfe, 0xfe, 0x03, 0x0b, 0x0d, 0x0e, 0x0b, 0x08, 0xfb, 0xfa, + 0x01, 0x06, 0x08, 0x0b, 0x11, 0x0f, 0x0b, 0x0b, 0x10, 0x14, 0x16, 0x12, + 0x0b, 0x03, 0xfa, 0xf9, 0xfd, 0xff, 0xfe, 0xf7, 0xf1, 0xf0, 0xf2, 0xf6, + 0xfb, 0xfd, 0x02, 0x09, 0x07, 0x00, 0x02, 0x01, 0x02, 0xff, 0xfd, 0xf5, + 0xf5, 0xf9, 0x01, 0x0a, 0x13, 0x17, 0x18, 0x13, 0x0e, 0x0e, 0x0f, 0x0b, + 0x08, 0x04, 0x03, 0x04, 0x06, 0x0d, 0x0f, 0x0c, 0x0c, 0x09, 0x00, 0xf7, + 0xf7, 0xfd, 0x07, 0x0d, 0x08, 0xfe, 0xf7, 0xf5, 0xf2, 0xee, 0xed, 0xf4, + 0xf8, 0xf3, 0xf2, 0xfd, 0x07, 0x09, 0x0d, 0x11, 0x0e, 0x0c, 0x0a, 0x0d, + 0x0f, 0x0e, 0x0d, 0x09, 0x01, 0xfa, 0xfb, 0x01, 0x09, 0x0c, 0x0a, 0x06, + 0x03, 0x05, 0x07, 0x0d, 0x11, 0x14, 0x12, 0x06, 0xfb, 0xfb, 0x02, 0x03, + 0x02, 0xfa, 0xf9, 0xff, 0xff, 0x01, 0x05, 0x09, 0x08, 0x05, 0xfa, 0xef, + 0xee, 0xf5, 0xfe, 0xff, 0xff, 0xf9, 0xf4, 0xf6, 0xfd, 0x00, 0x03, 0x0a, + 0x0e, 0x0e, 0x0f, 0x16, 0x18, 0x14, 0x14, 0x0e, 0x02, 0xfd, 0xfd, 0x02, + 0x07, 0x0f, 0x1a, 0x1a, 0x0a, 0x02, 0x04, 0x08, 0x0c, 0x09, 0xff, 0xf7, + 0xf2, 0xf5, 0xf8, 0xfa, 0xfd, 0xff, 0xfa, 0xf4, 0xf1, 0xf5, 0xf9, 0xfe, + 0x06, 0x04, 0x03, 0x03, 0x00, 0x05, 0x0c, 0x09, 0x03, 0x00, 0xfb, 0xf7, + 0xfa, 0x07, 0x13, 0x15, 0x12, 0x11, 0x10, 0x13, 0x15, 0x12, 0x11, 0x11, + 0x0c, 0x02, 0xfd, 0x00, 0xfe, 0xfd, 0xfe, 0xf8, 0xf3, 0xf5, 0xf7, 0xfb, + 0x00, 0x04, 0x05, 0x00, 0xf6, 0xf8, 0xfc, 0xff, 0x04, 0x03, 0xfd, 0xf8, + 0xf9, 0x02, 0x0b, 0x0d, 0x0f, 0x10, 0x13, 0x11, 0x0c, 0x0b, 0x04, 0x03, + 0x05, 0x01, 0xfe, 0x02, 0x02, 0x03, 0x08, 0x08, 0x08, 0x05, 0xfe, 0x00, + 0x08, 0x11, 0x14, 0x0c, 0x05, 0x01, 0xf9, 0xf2, 0xf0, 0xee, 0xef, 0xf6, + 0xff, 0x04, 0x06, 0x05, 0x03, 0x08, 0x0d, 0x04, 0xff, 0xfc, 0xfd, 0x08, + 0x0f, 0x10, 0x0f, 0x08, 0xfe, 0xfa, 0xff, 0x03, 0x07, 0x05, 0x08, 0x0a, + 0x08, 0x0b, 0x0d, 0x09, 0x0a, 0x0b, 0x02, 0xfa, 0xfb, 0xfd, 0xfa, 0x02, + 0x08, 0x02, 0xfd, 0xfc, 0x00, 0x0a, 0x0f, 0x0e, 0x0b, 0x01, 0xf4, 0xf3, + 0xf7, 0xfc, 0x01, 0xfd, 0xf7, 0xf8, 0xf8, 0xfb, 0xff, 0x04, 0x0c, 0x0d, + 0x0c, 0x0e, 0x0e, 0x0d, 0x0f, 0x13, 0x0d, 0x05, 0x02, 0xfd, 0xff, 0x0e, + 0x1a, 0x17, 0x12, 0x0b, 0x02, 0x02, 0x09, 0x0e, 0x07, 0xfa, 0xf5, 0xf3, + 0xef, 0xf1, 0xf8, 0xf5, 0xf3, 0xf4, 0xf2, 0xf0, 0xf9, 0x03, 0x09, 0x0e, + 0x0e, 0x08, 0x03, 0x03, 0x07, 0x0b, 0x09, 0x04, 0x02, 0xfc, 0xfb, 0x07, + 0x12, 0x13, 0x12, 0x12, 0x11, 0x10, 0x0e, 0x0b, 0x08, 0x07, 0x09, 0x09, + 0x07, 0x05, 0x04, 0xff, 0xfd, 0xfe, 0xf6, 0xf0, 0xf3, 0xf7, 0xfc, 0x02, + 0x07, 0x04, 0x00, 0xf8, 0xef, 0xf0, 0xf6, 0xfd, 0xfe, 0xfa, 0x01, 0x08, + 0x03, 0x03, 0x0a, 0x10, 0x16, 0x18, 0x16, 0x10, 0x0b, 0x07, 0x06, 0x09, + 0x06, 0x00, 0xfb, 0xfc, 0x01, 0x08, 0x0c, 0x0e, 0x0f, 0x07, 0xff, 0x05, + 0x0b, 0x0a, 0x09, 0x07, 0x04, 0xfd, 0xf5, 0xef, 0xf0, 0xf5, 0xfe, 0x02, + 0xff, 0xfc, 0xfe, 0x05, 0x0c, 0x0e, 0x05, 0xf8, 0xef, 0xf1, 0xf7, 0x04, + 0x0d, 0x0e, 0x08, 0xff, 0xf8, 0xfd, 0x03, 0x0b, 0x12, 0x14, 0x14, 0x14, + 0x0f, 0x0d, 0x0d, 0x09, 0x06, 0x01, 0xfd, 0xfa, 0xfb, 0x04, 0x0f, 0x0f, + 0x04, 0xfa, 0xf9, 0xfc, 0x03, 0x0b, 0x0a, 0x03, 0xfc, 0xf6, 0xf3, 0xf9, + 0x00, 0x01, 0xff, 0xfc, 0xfc, 0xf6, 0xf4, 0xfc, 0x06, 0x08, 0x0c, 0x0d, + 0x0a, 0x06, 0x06, 0x05, 0x07, 0x07, 0x01, 0xfb, 0xfc, 0x07, 0x10, 0x15, + 0x17, 0x17, 0x16, 0x11, 0x0c, 0x0e, 0x09, 0x02, 0xff, 0xfc, 0xf8, 0xf4, + 0xf1, 0xf0, 0xef, 0xf3, 0xf6, 0xf5, 0xf7, 0xfd, 0x03, 0x07, 0x0e, 0x0c, + 0x04, 0xff, 0xfe, 0xfe, 0x03, 0x07, 0x09, 0x07, 0x0a, 0x0b, 0x06, 0x06, + 0x0b, 0x0f, 0x15, 0x16, 0x11, 0x0a, 0x02, 0xfc, 0xfb, 0xfc, 0x02, 0x06, + 0x03, 0x02, 0x01, 0x00, 0xfe, 0xfd, 0xfd, 0xfc, 0xfc, 0xfe, 0x06, 0x0a, + 0x09, 0x02, 0xfa, 0xf2, 0xf3, 0xf6, 0xf4, 0xfd, 0x09, 0x0a, 0x05, 0x04, + 0x05, 0x07, 0x0b, 0x10, 0x14, 0x0f, 0x08, 0x07, 0x09, 0x0b, 0x0c, 0x09, + 0x03, 0x01, 0xfb, 0xfb, 0xfc, 0x09, 0x10, 0x10, 0x0c, 0x07, 0x04, 0x04, + 0x01, 0x00, 0xfe, 0xfb, 0xf8, 0xf2, 0xf2, 0xf9, 0xfb, 0xfc, 0x01, 0x01, + 0x04, 0x09, 0x10, 0x11, 0x10, 0x04, 0xf6, 0xf0, 0xf1, 0xf6, 0xfd, 0x05, + 0x0c, 0x0b, 0x04, 0xfd, 0xfd, 0x06, 0x0b, 0x12, 0x16, 0x18, 0x13, 0x0f, + 0x0c, 0x07, 0x02, 0x05, 0x05, 0x00, 0x02, 0x09, 0x0b, 0x09, 0x09, 0x04, + 0xff, 0xfd, 0xf9, 0xf8, 0xfa, 0xfa, 0xf9, 0xf8, 0xf4, 0xf0, 0xf3, 0xfb, + 0xff, 0x01, 0xff, 0xfb, 0xfb, 0x02, 0x07, 0x06, 0x07, 0x10, 0x12, 0x0b, + 0x04, 0x02, 0x07, 0x09, 0x07, 0x03, 0x03, 0x0a, 0x07, 0x09, 0x0f, 0x17, + 0x1a, 0x19, 0x14, 0x0e, 0x07, 0x02, 0x02, 0x06, 0x04, 0xfb, 0xf8, 0xf5, + 0xf4, 0xf0, 0xec, 0xf0, 0xf7, 0xf9, 0xfc, 0xff, 0x07, 0x08, 0x03, 0xfc, + 0xf6, 0xf1, 0xf2, 0xf8, 0xfd, 0x06, 0x13, 0x18, 0x10, 0x0f, 0x10, 0x11, + 0x13, 0x19, 0x1a, 0x13, 0x09, 0x01, 0xff, 0xfa, 0xfb, 0x03, 0x04, 0x02, + 0x02, 0x04, 0x04, 0x04, 0x05, 0x03, 0xfe, 0xff, 0xff, 0x00, 0x01, 0x04, + 0x05, 0x00, 0xfb, 0xf5, 0xf3, 0xf9, 0x07, 0x0b, 0x08, 0x05, 0x05, 0x05, + 0x02, 0xfd, 0x00, 0x06, 0x05, 0x02, 0xff, 0x03, 0x07, 0x06, 0x07, 0x04, + 0x02, 0xfd, 0xfc, 0x02, 0x0b, 0x13, 0x18, 0x16, 0x0e, 0x06, 0x00, 0xfc, + 0xfe, 0x02, 0x02, 0xf9, 0xf7, 0xff, 0x00, 0xfa, 0xfe, 0x04, 0x07, 0x05, + 0x05, 0x0b, 0x0c, 0x09, 0x04, 0xfc, 0xf8, 0xf7, 0xf4, 0xf5, 0xfb, 0x03, + 0x0c, 0x09, 0x02, 0x04, 0x05, 0x05, 0x0a, 0x0e, 0x0e, 0x0a, 0x04, 0x00, + 0xfc, 0xfa, 0xfc, 0x02, 0x06, 0x0d, 0x0f, 0x11, 0x13, 0x11, 0x0c, 0x07, + 0x00, 0xfb, 0xf6, 0xf5, 0xf4, 0xfa, 0xff, 0xfb, 0xf5, 0xf5, 0xf7, 0xfc, + 0x00, 0x03, 0x04, 0x04, 0x05, 0x05, 0x02, 0x02, 0x09, 0x0e, 0x0c, 0x08, + 0x07, 0x06, 0x05, 0x03, 0x09, 0x0d, 0x09, 0x05, 0x04, 0x0a, 0x0d, 0x0f, + 0x10, 0x09, 0x03, 0x00, 0xfd, 0xfb, 0xfc, 0x01, 0xff, 0xf9, 0xf7, 0xf5, + 0xf3, 0xf2, 0xfa, 0x01, 0x01, 0x00, 0x05, 0x07, 0x04, 0x00, 0xfc, 0xf7, + 0xf1, 0xf3, 0xf5, 0xfe, 0x0b, 0x16, 0x1c, 0x18, 0x17, 0x15, 0x0e, 0x0f, + 0x14, 0x14, 0x0f, 0x09, 0x06, 0x01, 0xfb, 0xfa, 0xfb, 0xff, 0x00, 0x03, + 0x04, 0x05, 0x06, 0x04, 0xff, 0xfb, 0xf8, 0xf6, 0xf5, 0xf8, 0xf7, 0xf7, + 0xfb, 0xf9, 0xfa, 0x01, 0x07, 0x09, 0x0c, 0x10, 0x0d, 0x08, 0x05, 0x02, + 0xfc, 0xf7, 0xfe, 0x04, 0x03, 0x05, 0x09, 0x08, 0x06, 0x08, 0x06, 0x06, + 0x02, 0x03, 0x05, 0x0a, 0x11, 0x17, 0x16, 0x10, 0x0c, 0x08, 0xff, 0xf9, + 0xfc, 0x00, 0x00, 0x04, 0x04, 0xff, 0xf9, 0xfa, 0xfd, 0xfe, 0x00, 0x00, + 0xff, 0x01, 0x02, 0xfd, 0xf7, 0xf6, 0xf4, 0xf3, 0xf5, 0xfa, 0x01, 0x0c, + 0x12, 0x0f, 0x0e, 0x0f, 0x0b, 0x07, 0x09, 0x0b, 0x08, 0x01, 0xfb, 0xf9, + 0xfa, 0x02, 0x0d, 0x15, 0x16, 0x14, 0x16, 0x11, 0x0f, 0x0c, 0x0b, 0x06, + 0x00, 0xf9, 0xf8, 0xf9, 0xfb, 0xfc, 0xf8, 0xf2, 0xf6, 0xfc, 0xfd, 0xfb, + 0xfd, 0x01, 0x00, 0xfe, 0xfb, 0xf9, 0xf8, 0xfb, 0x01, 0x00, 0x00, 0x03, + 0x07, 0x0b, 0x13, 0x15, 0x11, 0x0f, 0x09, 0x07, 0x0a, 0x0c, 0x0c, 0x0b, + 0x08, 0x02, 0x05, 0x06, 0x01, 0xff, 0x01, 0x05, 0x02, 0x01, 0xfd, 0xf9, + 0xf7, 0xfb, 0x01, 0x04, 0x07, 0x0a, 0x07, 0x06, 0xff, 0xf6, 0xf2, 0xf2, + 0xf2, 0xfb, 0x05, 0x09, 0x0c, 0x11, 0x0f, 0x0d, 0x0f, 0x0e, 0x0a, 0x03, + 0x03, 0x07, 0x06, 0x02, 0xfd, 0xf7, 0xf5, 0xfb, 0x04, 0x08, 0x09, 0x0a, + 0x0b, 0x09, 0x05, 0x01, 0x00, 0xfb, 0xf8, 0xf7, 0xf3, 0xf0, 0xf6, 0x01, + 0x07, 0x0c, 0x12, 0x10, 0x0f, 0x0c, 0x0b, 0x0b, 0x0c, 0x0c, 0x02, 0xf7, + 0xf5, 0xff, 0x06, 0x06, 0x03, 0x01, 0xff, 0x03, 0x07, 0x03, 0xff, 0xfe, + 0xfe, 0x01, 0x04, 0x08, 0x08, 0x09, 0x07, 0xff, 0xfd, 0xfc, 0xfd, 0x00, + 0x0a, 0x12, 0x0f, 0x0a, 0x04, 0xfe, 0xf9, 0xfb, 0x02, 0x00, 0xfc, 0xfc, + 0x02, 0x04, 0x01, 0xfb, 0xf8, 0xf8, 0xfb, 0xff, 0x02, 0x04, 0x0a, 0x10, + 0x12, 0x13, 0x15, 0x15, 0x0f, 0x0a, 0x03, 0xfd, 0xfa, 0xf9, 0xf7, 0xfc, + 0x04, 0x0e, 0x0f, 0x0d, 0x0c, 0x0b, 0x0b, 0x0c, 0x07, 0xff, 0xf7, 0xf5, + 0xfa, 0xfe, 0xfa, 0xf2, 0xf2, 0xf8, 0xfb, 0x00, 0x05, 0x06, 0x03, 0x00, + 0xff, 0xff, 0xff, 0xfc, 0xf7, 0xf6, 0xf1, 0xf7, 0x03, 0x09, 0x10, 0x1a, + 0x1e, 0x1c, 0x16, 0x0d, 0x08, 0x0b, 0x10, 0x13, 0x11, 0x0a, 0x03, 0x06, + 0x0c, 0x08, 0xff, 0xfa, 0xf9, 0xfa, 0xff, 0x01, 0x00, 0xf7, 0xf2, 0xf2, + 0xf1, 0xf9, 0x00, 0x01, 0xff, 0xfe, 0xf7, 0xf5, 0xf7, 0xf6, 0xfb, 0x05, + 0x0a, 0x0a, 0x0a, 0x09, 0x0a, 0x11, 0x12, 0x0c, 0x09, 0x05, 0x03, 0x07, + 0x09, 0x07, 0x04, 0x01, 0xfe, 0xff, 0x03, 0x0c, 0x0d, 0x0b, 0x0c, 0x0e, + 0x0e, 0x0f, 0x0d, 0x01, 0xf9, 0xf6, 0xf2, 0xf1, 0xf1, 0xf2, 0xf9, 0x09, + 0x10, 0x0a, 0x09, 0x06, 0x07, 0x06, 0x06, 0x03, 0xfa, 0xf2, 0xf1, 0xf6, + 0xf9, 0xfe, 0x00, 0x02, 0x05, 0x0a, 0x0c, 0x08, 0x03, 0xfe, 0xfe, 0xff, + 0x01, 0x07, 0x08, 0x04, 0xff, 0x00, 0x02, 0x04, 0x0a, 0x10, 0x18, 0x1c, + 0x19, 0x11, 0x09, 0x06, 0x04, 0x01, 0xff, 0x01, 0xfd, 0xfd, 0x04, 0x06, + 0xfe, 0xf4, 0xf2, 0xed, 0xf2, 0xfa, 0xfc, 0xfd, 0xfc, 0xfb, 0xfe, 0x0a, + 0x10, 0x0e, 0x0a, 0x03, 0xfb, 0xf8, 0xfc, 0xfe, 0xfb, 0x01, 0x0d, 0x0e, + 0x0c, 0x0f, 0x0f, 0x0e, 0x0d, 0x09, 0x06, 0x03, 0xfc, 0xfa, 0x02, 0x05, + 0x02, 0x03, 0x00, 0xfb, 0xfe, 0x05, 0x0b, 0x0b, 0x09, 0x06, 0x06, 0x0c, + 0x0d, 0x05, 0xf6, 0xee, 0xec, 0xeb, 0xf2, 0xf9, 0x01, 0x10, 0x19, 0x17, + 0x11, 0x08, 0x01, 0xfe, 0x03, 0x07, 0x09, 0x07, 0x02, 0x01, 0x05, 0x09, + 0x03, 0xfe, 0xff, 0x04, 0x07, 0x08, 0x07, 0xff, 0xf6, 0xf6, 0xf8, 0xf5, + 0xf8, 0xfc, 0xfa, 0xfb, 0x02, 0x07, 0x04, 0x02, 0x09, 0x0e, 0x0f, 0x0f, + 0x0e, 0x0e, 0x0d, 0x0b, 0x0f, 0x14, 0x11, 0x09, 0x05, 0x05, 0x03, 0xff, + 0xf9, 0xf3, 0xf3, 0xf8, 0xfd, 0xfd, 0xfe, 0x01, 0x00, 0x04, 0x0b, 0x0d, + 0x09, 0x01, 0xf5, 0xef, 0xf4, 0xf9, 0xfa, 0xfe, 0x03, 0x06, 0x0b, 0x0d, + 0x0c, 0x0c, 0x0a, 0x04, 0x03, 0x06, 0x00, 0xf6, 0xf7, 0xfd, 0xfd, 0xfc, + 0x01, 0x09, 0x0c, 0x10, 0x13, 0x11, 0x09, 0x05, 0x01, 0x01, 0x06, 0x0d, + 0x0a, 0x04, 0xfc, 0xf9, 0xff, 0xff, 0xfd, 0x00, 0x0e, 0x15, 0x17, 0x12, + 0x08, 0x00, 0xfe, 0xfd, 0xfc, 0xf7, 0xf4, 0xf6, 0xfc, 0x02, 0x03, 0x01, + 0xf9, 0xf8, 0xf9, 0xf8, 0xfa, 0xfd, 0xfd, 0xfe, 0xfc, 0xff, 0x0a, 0x0d, + 0x08, 0x03, 0x04, 0x06, 0x0a, 0x09, 0x05, 0x08, 0x14, 0x16, 0x12, 0x0f, + 0x12, 0x15, 0x12, 0x0f, 0x0e, 0x0b, 0x04, 0x00, 0xfa, 0xf4, 0xf6, 0xf7, + 0xf5, 0xf9, 0xf6, 0xf7, 0xfc, 0xff, 0x00, 0x02, 0x04, 0x07, 0x0c, 0x07, + 0xf7, 0xe9, 0xea, 0xf0, 0xf2, 0xf0, 0xfb, 0x0f, 0x18, 0x17, 0x15, 0x10, + 0x08, 0x01, 0xfd, 0xfb, 0x02, 0x05, 0x0a, 0x0d, 0x0d, 0x0f, 0x12, 0x0e, + 0x0b, 0x0c, 0x0c, 0x0e, 0x12, 0x0d, 0x05, 0xff, 0xff, 0x01, 0xff, 0xf6, + 0xf1, 0xf3, 0xf9, 0xfc, 0xf8, 0xf8, 0xfe, 0x07, 0x07, 0x05, 0x06, 0x05, + 0x06, 0x03, 0x03, 0x08, 0x07, 0x03, 0x00, 0x02, 0x00, 0x02, 0x03, 0x00, + 0xfa, 0xf8, 0xfb, 0xfe, 0xfd, 0xfd, 0x01, 0x04, 0x06, 0x09, 0x0b, 0x07, + 0x02, 0x03, 0x03, 0x01, 0x03, 0x09, 0x10, 0x12, 0x12, 0x13, 0x13, 0x11, + 0x0f, 0x0e, 0x0b, 0x0d, 0x09, 0xfe, 0xf2, 0xf0, 0xf0, 0xed, 0xee, 0xf3, + 0xf9, 0x00, 0x04, 0x04, 0x04, 0x03, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, + 0xfd, 0xfd, 0x01, 0x02, 0x01, 0x03, 0x0c, 0x16, 0x17, 0x16, 0x13, 0x08, + 0x00, 0xfb, 0xfc, 0xfc, 0xf8, 0xf7, 0xff, 0x09, 0x0a, 0x0d, 0x10, 0x08, + 0x02, 0x01, 0xfe, 0xfe, 0x02, 0x03, 0x01, 0x00, 0x0b, 0x0c, 0x03, 0xfe, + 0xfa, 0xfa, 0xf8, 0xfa, 0xfc, 0xff, 0x05, 0x0c, 0x0e, 0x0c, 0x09, 0x06, + 0x0a, 0x0c, 0x09, 0x06, 0x03, 0xff, 0xfc, 0xfc, 0xfe, 0xfc, 0xfc, 0xf9, + 0xf5, 0xf7, 0xfc, 0xfe, 0xfd, 0xfe, 0x02, 0x06, 0x0b, 0x0b, 0x07, 0x01, + 0xfc, 0xfb, 0xfc, 0xfb, 0xfd, 0x0b, 0x18, 0x20, 0x1c, 0x15, 0x11, 0x0d, + 0x09, 0x04, 0x00, 0xfe, 0xfe, 0x00, 0xfe, 0x01, 0x05, 0x04, 0xfe, 0xfd, + 0x00, 0x05, 0x09, 0x0b, 0x09, 0x04, 0xfe, 0xfd, 0xfc, 0xf2, 0xeb, 0xec, + 0xf5, 0xfa, 0xfa, 0xfc, 0x05, 0x0b, 0x0d, 0x09, 0x02, 0xfc, 0xfd, 0x00, + 0xff, 0x05, 0x0c, 0x0a, 0x06, 0x09, 0x0e, 0x0f, 0x12, 0x10, 0x06, 0x01, + 0x01, 0x05, 0x06, 0x04, 0x02, 0x03, 0x0a, 0x0f, 0x09, 0x03, 0x00, 0xfc, + 0xfa, 0xf5, 0xf5, 0xf8, 0x00, 0x07, 0x0d, 0x10, 0x0d, 0x09, 0x09, 0x07, + 0x06, 0x07, 0x05, 0xfc, 0xf6, 0xf6, 0xf4, 0xf5, 0xf5, 0xf1, 0xed, 0xf3, + 0xfe, 0x01, 0xfc, 0xfe, 0xff, 0xff, 0x03, 0x06, 0x02, 0x02, 0x08, 0x0b, + 0x0c, 0x12, 0x13, 0x10, 0x14, 0x1d, 0x21, 0x1b, 0x18, 0x16, 0x11, 0x0a, + 0x04, 0x00, 0xf5, 0xed, 0xec, 0xf0, 0xf8, 0xfe, 0xfc, 0xfb, 0xfb, 0xfb, + 0xfd, 0xfd, 0xfa, 0xfa, 0xfa, 0xf9, 0x00, 0x04, 0x00, 0xfc, 0xf7, 0xf5, + 0xf8, 0xfe, 0x02, 0x05, 0x0a, 0x0d, 0x07, 0x05, 0x04, 0x03, 0x02, 0x08, + 0x0f, 0x0c, 0x0a, 0x11, 0x13, 0x11, 0x12, 0x0f, 0x06, 0xfe, 0xfd, 0x01, + 0x07, 0x08, 0x06, 0x02, 0x03, 0x09, 0x0a, 0x05, 0x02, 0xfc, 0xf3, 0xed, + 0xec, 0xf0, 0xf1, 0xf7, 0x03, 0x0d, 0x12, 0x0e, 0x0b, 0x09, 0x04, 0x02, + 0xfe, 0xf9, 0xf8, 0xf6, 0xf8, 0x02, 0x0b, 0x09, 0x00, 0xfa, 0xfd, 0x02, + 0x04, 0x03, 0x04, 0x05, 0x0c, 0x0d, 0x07, 0x05, 0xff, 0xfa, 0xfb, 0x01, + 0x0b, 0x0c, 0x0c, 0x14, 0x1a, 0x17, 0x0d, 0x07, 0x03, 0xfd, 0xfe, 0x00, + 0x01, 0x01, 0xfd, 0xf8, 0xf8, 0xfd, 0xfe, 0xfc, 0xfc, 0xfd, 0x02, 0x02, + 0x01, 0x02, 0x00, 0xfe, 0xff, 0x05, 0x05, 0x01, 0xfe, 0xfd, 0xfd, 0xfe, + 0xff, 0x01, 0x00, 0x02, 0x06, 0x06, 0x06, 0x07, 0x08, 0x08, 0x0b, 0x0c, + 0x0b, 0x0b, 0x0e, 0x0d, 0x0b, 0x07, 0x01, 0xfb, 0xf5, 0xf7, 0xff, 0x04, + 0x04, 0xff, 0x01, 0x05, 0x09, 0x07, 0x01, 0xf8, 0xf2, 0xee, 0xf6, 0x02, + 0x07, 0x09, 0x0a, 0x13, 0x1a, 0x19, 0x17, 0x13, 0x0e, 0x09, 0x07, 0xff, + 0xf9, 0xf6, 0xf0, 0xef, 0xf5, 0xfd, 0xfb, 0xf6, 0xf6, 0xfd, 0xfe, 0xf8, + 0xf5, 0xf5, 0xf5, 0xfa, 0x05, 0x0b, 0x0b, 0x0a, 0x06, 0x05, 0x0a, 0x0a, + 0x09, 0x0b, 0x14, 0x1d, 0x15, 0x0d, 0x0d, 0x0c, 0x05, 0x03, 0x03, 0x02, + 0x03, 0x01, 0x02, 0x03, 0x01, 0xff, 0xfd, 0xfb, 0xfa, 0xfb, 0x01, 0x05, + 0x06, 0x02, 0xfe, 0x02, 0x05, 0x01, 0xfc, 0xf8, 0xf6, 0xf8, 0xf7, 0xf3, + 0xf3, 0xf6, 0xfc, 0xff, 0xff, 0x01, 0x04, 0x04, 0x09, 0x0a, 0x09, 0x0c, + 0x0e, 0x0d, 0x08, 0x09, 0x11, 0x12, 0x0c, 0x09, 0x07, 0x0d, 0x0f, 0x0c, + 0x06, 0x06, 0x0c, 0x10, 0x08, 0xfe, 0xf7, 0xf0, 0xec, 0xf1, 0xf7, 0xfd, + 0x01, 0x09, 0x12, 0x15, 0x10, 0x0b, 0x03, 0xfb, 0xf0, 0xee, 0xf7, 0x00, + 0xff, 0xf8, 0xf7, 0xfc, 0xfc, 0xf7, 0xf5, 0xf7, 0xff, 0x02, 0xfd, 0xfb, + 0x01, 0x07, 0x08, 0x0c, 0x0d, 0x0d, 0x10, 0x14, 0x15, 0x10, 0x0c, 0x0c, + 0x0f, 0x12, 0x10, 0x0b, 0x09, 0x0d, 0x0e, 0x06, 0xff, 0x02, 0x05, 0x03, + 0xfb, 0xf9, 0xfc, 0xfc, 0xf7, 0xf2, 0xf2, 0xf5, 0xf8, 0xfe, 0xfc, 0xfc, + 0xfd, 0xfb, 0xff, 0x01, 0xfd, 0xfb, 0xfa, 0xf7, 0xf6, 0xf9, 0x00, 0x07, + 0x0a, 0x0b, 0x0e, 0x0f, 0x11, 0x13, 0x0c, 0x09, 0x0f, 0x17, 0x1a, 0x13, + 0x0d, 0x06, 0x03, 0x04, 0x01, 0xfc, 0x00, 0x06, 0x07, 0x01, 0xfe, 0xff, + 0xfc, 0xf8, 0xf7, 0xf5, 0xf6, 0xfa, 0xfb, 0xf8, 0xf8, 0xfd, 0x00, 0x02, + 0x08, 0x12, 0x1a, 0x15, 0x0e, 0x06, 0xfd, 0xf9, 0xfd, 0x05, 0x05, 0x01, + 0x02, 0x04, 0x03, 0xfd, 0xf8, 0xf9, 0xfe, 0xfc, 0xf8, 0xf5, 0xff, 0x07, + 0x09, 0x09, 0x0e, 0x0f, 0x10, 0x11, 0x0c, 0x09, 0x07, 0x05, 0x02, 0x01, + 0x04, 0x04, 0x03, 0x04, 0x03, 0xff, 0xfd, 0xff, 0x02, 0x01, 0x00, 0xfd, + 0xfb, 0xfb, 0xfd, 0xfa, 0x00, 0x0a, 0x0b, 0x0a, 0x0f, 0x10, 0x0e, 0x00, + 0xfa, 0x02, 0x09, 0x08, 0x01, 0xfc, 0xf8, 0xf3, 0xf4, 0xf6, 0xf8, 0xfd, + 0x06, 0x0b, 0x09, 0x05, 0x01, 0xfe, 0xfe, 0x05, 0x08, 0x0b, 0x0f, 0x0e, + 0x07, 0x04, 0x01, 0xff, 0x01, 0x01, 0xff, 0x04, 0x08, 0x07, 0x01, 0x00, + 0x01, 0x03, 0x00, 0xfe, 0xfe, 0x03, 0x07, 0x06, 0x03, 0x05, 0x07, 0x0f, + 0x17, 0x18, 0x0c, 0x03, 0xfe, 0xfc, 0xfd, 0x00, 0x05, 0x07, 0x01, 0xf7, + 0xf2, 0xf3, 0xf5, 0xf1, 0xed, 0xee, 0xf1, 0xf3, 0xf7, 0xf8, 0xf5, 0xfc, + 0x0b, 0x10, 0x0f, 0x12, 0x13, 0x0f, 0x07, 0x06, 0x07, 0x0b, 0x11, 0x15, + 0x15, 0x15, 0x16, 0x17, 0x0f, 0x06, 0x03, 0x09, 0x0f, 0x0c, 0x02, 0xfc, + 0xf8, 0xf9, 0xf9, 0xf8, 0xfc, 0x04, 0x07, 0x01, 0xfc, 0xf3, 0xed, 0xf1, + 0xf8, 0xf9, 0xf7, 0xf7, 0xfa, 0xf5, 0xf0, 0xf3, 0xf9, 0xfd, 0x02, 0x08, + 0x0a, 0x0c, 0x0d, 0x07, 0x08, 0x0e, 0x14, 0x19, 0x1b, 0x16, 0x12, 0x13, + 0x14, 0x0b, 0x03, 0x01, 0x02, 0x03, 0x04, 0x06, 0x03, 0xfd, 0xff, 0x01, + 0xfd, 0xff, 0x03, 0x08, 0x02, 0xf6, 0xf5, 0xfc, 0x02, 0x03, 0x06, 0x06, + 0x02, 0xfe, 0xf8, 0xf3, 0xf7, 0xfc, 0x01, 0x02, 0x01, 0xfd, 0xf5, 0xf5, + 0xf6, 0xf7, 0xf9, 0xfc, 0x01, 0x02, 0x02, 0x09, 0x0c, 0x0c, 0x0f, 0x13, + 0x15, 0x1c, 0x22, 0x1c, 0x0f, 0x07, 0x04, 0x03, 0x02, 0x01, 0x05, 0x0b, + 0x09, 0x02, 0xfd, 0xfb, 0xf8, 0xf7, 0xfa, 0xfe, 0xfc, 0xf8, 0xf7, 0xf8, + 0xf5, 0xfa, 0x01, 0x05, 0x04, 0x00, 0x00, 0xfe, 0xfa, 0xf9, 0x00, 0x05, + 0x08, 0x07, 0x04, 0xff, 0xff, 0x00, 0x00, 0x01, 0x01, 0x02, 0x06, 0x0a, + 0x0a, 0x0a, 0x0b, 0x0d, 0x0f, 0x10, 0x14, 0x19, 0x17, 0x0e, 0x03, 0xfd, + 0xfa, 0xfd, 0xfc, 0xf6, 0xf5, 0xf6, 0xf6, 0xf4, 0xf1, 0xf4, 0xfc, 0xfe, + 0x00, 0x05, 0x03, 0xfb, 0xf5, 0xfa, 0x07, 0x13, 0x17, 0x14, 0x12, 0x0b, + 0x08, 0x0d, 0x12, 0x0e, 0x0a, 0x09, 0x0a, 0x0c, 0x07, 0xfe, 0xf8, 0xf8, + 0xf7, 0xf4, 0xf4, 0xf9, 0xfe, 0xf9, 0xf4, 0xf1, 0xf5, 0xfd, 0x07, 0x0b, + 0x0e, 0x0f, 0x0a, 0x00, 0xfc, 0xff, 0x02, 0x04, 0x05, 0x08, 0x08, 0x06, + 0x07, 0x0a, 0x08, 0x03, 0x03, 0x09, 0x0c, 0x0b, 0x07, 0x06, 0x0a, 0x0a, + 0x07, 0x0a, 0x06, 0x01, 0xfe, 0xfb, 0xfb, 0x00, 0x04, 0x04, 0x01, 0x00, + 0x01, 0xfe, 0xf7, 0xf0, 0xef, 0xf5, 0xfb, 0xfe, 0xff, 0xfa, 0xf4, 0xf8, + 0xff, 0x01, 0x05, 0x0b, 0x12, 0x11, 0x14, 0x13, 0x08, 0x00, 0xfe, 0xfc, + 0x00, 0x08, 0x0a, 0x04, 0x00, 0x00, 0x03, 0x09, 0x0e, 0x0e, 0x0c, 0x0e, + 0x0e, 0x09, 0x03, 0x01, 0x05, 0x10, 0x10, 0x09, 0x05, 0x02, 0xff, 0xfa, + 0xf7, 0xfa, 0xf8, 0xf7, 0xf7, 0xf7, 0xfa, 0xf9, 0xf4, 0xee, 0xed, 0xed, + 0xf5, 0xfc, 0xfe, 0xfc, 0xf8, 0xf9, 0xff, 0x08, 0x12, 0x17, 0x1c, 0x1e, + 0x15, 0x0f, 0x0d, 0x10, 0x13, 0x11, 0x0b, 0x09, 0x05, 0x03, 0x04, 0x09, + 0x0f, 0x12, 0x0b, 0x05, 0x03, 0x05, 0x05, 0x02, 0xfe, 0xf8, 0xf8, 0xfe, + 0x01, 0xff, 0xf6, 0xe8, 0xe5, 0xec, 0xf2, 0xf8, 0x00, 0x04, 0x02, 0xf8, + 0xf4, 0xf4, 0xf1, 0xf4, 0xfb, 0x04, 0x0b, 0x0e, 0x09, 0x04, 0x09, 0x0f, + 0x18, 0x1f, 0x21, 0x1f, 0x1e, 0x1c, 0x1c, 0x16, 0x08, 0x00, 0x02, 0x05, + 0x02, 0xff, 0xf8, 0xf5, 0xf3, 0xed, 0xee, 0xf5, 0xfb, 0xfc, 0xf9, 0xf8, + 0xfc, 0xfc, 0xfa, 0x01, 0x08, 0x06, 0x05, 0x02, 0xfd, 0xfe, 0x03, 0x06, + 0x08, 0x0b, 0x07, 0x05, 0x06, 0x06, 0x04, 0xff, 0xfe, 0x04, 0x07, 0x03, + 0x01, 0xfd, 0xf6, 0xf4, 0xfa, 0x06, 0x15, 0x1e, 0x1e, 0x19, 0x11, 0x0a, + 0x05, 0x00, 0xfe, 0xff, 0xfe, 0xfe, 0xfd, 0xfb, 0xf8, 0xf8, 0xfb, 0xfd, + 0xfe, 0x00, 0x02, 0x05, 0x06, 0x00, 0xfe, 0xfe, 0xfe, 0xff, 0x02, 0x0a, + 0x0b, 0xfd, 0xf6, 0xfa, 0x00, 0x06, 0x11, 0x19, 0x14, 0x0a, 0x03, 0xff, + 0x00, 0x03, 0x03, 0x06, 0x09, 0x03, 0x00, 0xfe, 0x00, 0x03, 0x00, 0xfe, + 0x00, 0x06, 0x07, 0x07, 0x06, 0x06, 0x01, 0xf7, 0xf3, 0xfb, 0xfe, 0xfe, + 0xfb, 0xf4, 0xf3, 0xf8, 0xfc, 0x00, 0x0b, 0x11, 0x0b, 0x08, 0x08, 0x07, + 0x0b, 0x11, 0x19, 0x1c, 0x15, 0x07, 0xff, 0x02, 0x02, 0x04, 0x08, 0x13, + 0x13, 0x08, 0x05, 0x03, 0xfd, 0xf9, 0xf6, 0xf0, 0xee, 0xf2, 0xf5, 0xf4, + 0xee, 0xea, 0xe9, 0xed, 0xf8, 0x03, 0x10, 0x15, 0x12, 0x0c, 0x04, 0xfc, + 0xfb, 0x00, 0x03, 0x03, 0x05, 0x0d, 0x0e, 0x08, 0x0a, 0x10, 0x12, 0x16, + 0x18, 0x19, 0x16, 0x12, 0x10, 0x0f, 0x10, 0x0c, 0x09, 0x09, 0x06, 0xfc, + 0xf1, 0xee, 0xf3, 0xf5, 0xf3, 0xf2, 0xf7, 0xf6, 0xee, 0xe9, 0xef, 0xf4, + 0xf3, 0xf4, 0xfa, 0xfe, 0xfd, 0xff, 0x01, 0xfe, 0x04, 0x0b, 0x0f, 0x14, + 0x1c, 0x1c, 0x15, 0x11, 0x10, 0x0b, 0x06, 0x0a, 0x11, 0x11, 0x07, 0xf9, + 0xf4, 0xf9, 0xfd, 0x00, 0x09, 0x15, 0x10, 0x07, 0x07, 0x0a, 0x04, 0x02, + 0x05, 0x00, 0xfa, 0xf6, 0xf9, 0xf9, 0xf7, 0xf9, 0xf7, 0xfa, 0xff, 0x00, + 0x00, 0x00, 0xff, 0xfa, 0xf6, 0xf0, 0xf1, 0xf6, 0xfc, 0xfc, 0xfb, 0xf8, + 0xf8, 0x00, 0x08, 0x12, 0x1c, 0x25, 0x23, 0x1b, 0x16, 0x11, 0x0b, 0x0d, + 0x10, 0x0c, 0x06, 0x07, 0x09, 0x04, 0xff, 0x01, 0x02, 0xff, 0xfc, 0xf4, + 0xf5, 0xfc, 0x00, 0xff, 0xff, 0xfa, 0xf7, 0xfa, 0xfe, 0xfb, 0xf4, 0xf4, + 0xf5, 0xf3, 0xf9, 0x01, 0x0a, 0x0b, 0x06, 0x03, 0x00, 0x01, 0x04, 0x06, + 0x07, 0x0c, 0x0f, 0x0f, 0x0d, 0x04, 0x02, 0x0a, 0x14, 0x18, 0x19, 0x15, + 0x12, 0x0d, 0x0b, 0x09, 0x06, 0xff, 0xfa, 0xf7, 0xef, 0xe8, 0xe8, 0xee, + 0xf2, 0xf2, 0xf5, 0xfa, 0x00, 0x00, 0x05, 0x0a, 0x08, 0x03, 0x01, 0xfc, + 0xf8, 0xfd, 0x04, 0x0b, 0x0c, 0x04, 0x02, 0x0b, 0x14, 0x19, 0x18, 0x18, + 0x10, 0x0b, 0x09, 0x07, 0x06, 0x07, 0x09, 0x05, 0xf9, 0xf5, 0xf4, 0xf2, + 0xf9, 0x01, 0x01, 0xff, 0xff, 0xf7, 0xf5, 0xfa, 0xfc, 0xfb, 0xfa, 0xf6, + 0xf5, 0xfb, 0x04, 0x0d, 0x08, 0x01, 0x02, 0x09, 0x09, 0x08, 0x0b, 0x12, + 0x15, 0x13, 0x10, 0x0f, 0x0d, 0x0c, 0x0d, 0x09, 0x02, 0x00, 0xff, 0xf9, + 0xfb, 0x01, 0x08, 0x0d, 0x09, 0x03, 0x00, 0xfd, 0xfe, 0x02, 0x00, 0xf9, + 0xf5, 0xf3, 0xf8, 0xf8, 0xf6, 0xfb, 0x04, 0x06, 0x02, 0x02, 0x04, 0x04, + 0x07, 0x05, 0x00, 0x00, 0xfe, 0xf9, 0xf5, 0xf5, 0xfa, 0xfc, 0xfc, 0x00, + 0x07, 0x0a, 0x10, 0x1a, 0x1f, 0x1e, 0x1b, 0x18, 0x14, 0x10, 0x0d, 0x0a, + 0x0c, 0x0d, 0x0d, 0x04, 0xfa, 0xfd, 0x06, 0x02, 0xfb, 0xfa, 0xf5, 0xed, + 0xee, 0xed, 0xf0, 0xf0, 0xef, 0xed, 0xeb, 0xf0, 0xf4, 0xfd, 0x02, 0x03, + 0x00, 0x01, 0x03, 0x08, 0x0d, 0x0b, 0x0d, 0x0e, 0x0e, 0x0d, 0x0c, 0x10, + 0x12, 0x13, 0x15, 0x13, 0x0d, 0x0e, 0x0e, 0x0c, 0x0f, 0x10, 0x0f, 0x0d, + 0x08, 0x04, 0x08, 0x0c, 0x06, 0xf7, 0xec, 0xec, 0xeb, 0xec, 0xed, 0xeb, + 0xef, 0xf3, 0xf9, 0xfe, 0xfe, 0xff, 0xfc, 0xf8, 0xf8, 0xf8, 0xfa, 0xfa, + 0xfd, 0x04, 0x0a, 0x08, 0x0c, 0x17, 0x19, 0x16, 0x18, 0x1c, 0x1c, 0x19, + 0x16, 0x14, 0x12, 0x12, 0x09, 0x01, 0x00, 0x00, 0xfa, 0xf5, 0xf8, 0xfd, + 0xfa, 0xf9, 0xfb, 0xfe, 0xfc, 0xf8, 0xf6, 0xf3, 0xf3, 0xf4, 0xf5, 0xf9, + 0x00, 0x08, 0x0a, 0x07, 0x09, 0x07, 0x02, 0x03, 0x08, 0x0c, 0x0b, 0x04, + 0x02, 0x06, 0x08, 0x09, 0x07, 0x02, 0x00, 0x00, 0x06, 0x0c, 0x0d, 0x06, + 0x01, 0x00, 0x07, 0x0a, 0x07, 0x03, 0x01, 0x01, 0x09, 0x0d, 0x05, 0xfe, + 0xfd, 0xfe, 0xfb, 0xfe, 0xff, 0xfa, 0xfc, 0x02, 0x04, 0x05, 0x08, 0x06, + 0xff, 0x00, 0x00, 0xfb, 0xf8, 0xf6, 0xf8, 0xf5, 0xf6, 0xfc, 0xfe, 0x02, + 0x09, 0x12, 0x1d, 0x1e, 0x16, 0x0d, 0x07, 0x0d, 0x0f, 0x0c, 0x06, 0x08, + 0x0e, 0x0c, 0x07, 0x05, 0x07, 0x00, 0xfb, 0xf8, 0xf5, 0xf9, 0xfa, 0xf5, + 0xf1, 0xed, 0xf1, 0xf1, 0xf1, 0xf2, 0xf4, 0xf9, 0x03, 0x04, 0x02, 0x01, + 0x01, 0x09, 0x10, 0x0f, 0x08, 0x05, 0x0d, 0x15, 0x13, 0x12, 0x15, 0x15, + 0x16, 0x12, 0x13, 0x13, 0x10, 0x0a, 0x07, 0x06, 0x0a, 0x08, 0xfd, 0xf4, + 0xf6, 0xfa, 0x00, 0x01, 0xfa, 0xf0, 0xed, 0xf2, 0xf4, 0xef, 0xe8, 0xe9, + 0xf0, 0xf8, 0xfb, 0xfd, 0xfc, 0xfe, 0x04, 0x05, 0x03, 0x05, 0x08, 0x08, + 0x07, 0x08, 0x0c, 0x10, 0x11, 0x18, 0x1e, 0x21, 0x23, 0x21, 0x1a, 0x18, + 0x13, 0x12, 0x14, 0x0a, 0xff, 0xfb, 0xfb, 0xf8, 0xef, 0xee, 0xf2, 0xf6, + 0xfc, 0x00, 0xfb, 0xf2, 0xec, 0xea, 0xe8, 0xe9, 0xf0, 0xf7, 0xfc, 0x04, + 0x0d, 0x13, 0x10, 0x09, 0x03, 0xff, 0xfe, 0x03, 0x08, 0x05, 0x04, 0x05, + 0x0a, 0x15, 0x16, 0x0e, 0x08, 0x07, 0x08, 0x07, 0x0a, 0x0e, 0x10, 0x0c, + 0x06, 0x02, 0x00, 0x00, 0x01, 0x04, 0x07, 0x09, 0x08, 0x0b, 0x0c, 0x0a, + 0x07, 0x01, 0xf8, 0xee, 0xef, 0xf7, 0xff, 0x03, 0xfd, 0xf7, 0xf0, 0xf0, + 0xf6, 0xfe, 0xfc, 0xf8, 0xf8, 0xf6, 0xf3, 0xf3, 0xf9, 0xff, 0x05, 0x09, + 0x0f, 0x11, 0x13, 0x18, 0x1d, 0x20, 0x21, 0x1c, 0x16, 0x12, 0x0f, 0x0f, + 0x0d, 0x09, 0x01, 0xfd, 0xfe, 0x01, 0x02, 0x02, 0xff, 0xf9, 0xf4, 0xec, + 0xea, 0xed, 0xee, 0xf1, 0xf4, 0xf6, 0xf7, 0xf9, 0xfb, 0x02, 0x05, 0x09, + 0x09, 0x03, 0xfd, 0xfc, 0xff, 0x06, 0x0e, 0x14, 0x19, 0x1b, 0x1d, 0x20, + 0x1c, 0x14, 0x0a, 0x09, 0x09, 0x02, 0xfd, 0xfb, 0xfa, 0xf8, 0xfb, 0x00, + 0x06, 0x06, 0x02, 0x00, 0xfd, 0xfa, 0xf7, 0xf1, 0xf2, 0xf1, 0xf0, 0xf3, + 0xf7, 0xfc, 0x00, 0x04, 0x06, 0x04, 0x06, 0x0a, 0x0d, 0x11, 0x0f, 0x0a, + 0x00, 0xfc, 0x02, 0x0d, 0x19, 0x20, 0x20, 0x17, 0x0e, 0x0c, 0x0f, 0x16, + 0x18, 0x10, 0x08, 0xff, 0xf5, 0xef, 0xe9, 0xec, 0xed, 0xe9, 0xe8, 0xeb, + 0xf2, 0xfa, 0x00, 0x02, 0xfa, 0xf2, 0xf3, 0xfa, 0x01, 0x09, 0x11, 0x14, + 0x11, 0x08, 0x07, 0x0a, 0x0f, 0x12, 0x0c, 0x00, 0xfd, 0xff, 0x07, 0x0f, + 0x13, 0x19, 0x14, 0x0b, 0x04, 0xff, 0x01, 0x09, 0x0c, 0x0a, 0x05, 0xff, + 0xf8, 0xf5, 0xf6, 0xf7, 0xf9, 0xff, 0x06, 0x0d, 0x13, 0x17, 0x16, 0x0c, + 0xfb, 0xe8, 0xe0, 0xe5, 0xec, 0xea, 0xed, 0xf7, 0xfa, 0x00, 0x03, 0x04, + 0x07, 0x09, 0x03, 0xf9, 0xf2, 0xf3, 0xf8, 0x02, 0x0a, 0x0c, 0x0f, 0x1a, + 0x22, 0x20, 0x21, 0x22, 0x25, 0x25, 0x23, 0x21, 0x19, 0x0f, 0x04, 0xfa, + 0xf4, 0xf6, 0xf9, 0xff, 0xfe, 0xf8, 0xf2, 0xf3, 0xf0, 0xeb, 0xe8, 0xe8, + 0xe9, 0xee, 0xee, 0xed, 0xee, 0xf2, 0xf2, 0xf2, 0xf3, 0xf5, 0xfb, 0x05, + 0x07, 0x07, 0x08, 0x0d, 0x12, 0x19, 0x27, 0x2f, 0x2c, 0x29, 0x24, 0x1b, + 0x13, 0x13, 0x11, 0x0b, 0x08, 0xfa, 0xef, 0xf4, 0xfb, 0xfc, 0x02, 0x0a, + 0x08, 0x02, 0xfd, 0xf9, 0xf7, 0xf5, 0xf4, 0xed, 0xe5, 0xe5, 0xec, 0xf5, + 0xfb, 0xfe, 0xfd, 0xfb, 0xfe, 0x08, 0x16, 0x19, 0x10, 0x06, 0xfd, 0xf1, + 0xef, 0xfa, 0x04, 0x0b, 0x0c, 0x10, 0x14, 0x1b, 0x20, 0x23, 0x25, 0x20, + 0x17, 0x0d, 0xfd, 0xf0, 0xeb, 0xee, 0xf1, 0xf1, 0xf3, 0xf5, 0xfa, 0x00, + 0x04, 0x07, 0x03, 0xfd, 0x00, 0x02, 0x03, 0x05, 0x08, 0x06, 0x06, 0x04, + 0x00, 0x02, 0x0a, 0x0b, 0x02, 0xfe, 0xff, 0xfc, 0xfa, 0x02, 0x09, 0x10, + 0x12, 0x0e, 0x06, 0xfd, 0xfb, 0xf9, 0xf8, 0xf9, 0xfa, 0xfb, 0xfe, 0xfd, + 0xfb, 0xff, 0x01, 0x05, 0x14, 0x21, 0x1e, 0x19, 0x1c, 0x18, 0x0b, 0x00, + 0xfa, 0xf7, 0xed, 0xe3, 0xe9, 0xf5, 0xfc, 0x02, 0x07, 0x07, 0x07, 0x07, + 0x04, 0xf9, 0xee, 0xec, 0xf0, 0xf3, 0xfb, 0x07, 0x0c, 0x12, 0x1f, 0x22, + 0x1e, 0x1c, 0x1c, 0x21, 0x29, 0x2b, 0x20, 0x11, 0x01, 0xf3, 0xe6, 0xe1, + 0xe6, 0xe9, 0xe8, 0xe9, 0xf2, 0xf9, 0xfc, 0xff, 0x01, 0xff, 0xfb, 0xf5, + 0xef, 0xf0, 0xf0, 0xf2, 0xf5, 0xfa, 0xfd, 0x03, 0x07, 0x0a, 0x0e, 0x11, + 0x10, 0x10, 0x14, 0x21, 0x2d, 0x2b, 0x25, 0x25, 0x27, 0x1e, 0x12, 0x0e, + 0x0a, 0xff, 0xf9, 0xfb, 0xfc, 0xf6, 0xed, 0xee, 0xf2, 0xf9, 0x01, 0xfe, + 0xf9, 0xf3, 0xec, 0xe4, 0xe4, 0xe9, 0xe8, 0xe3, 0xe6, 0xed, 0xf7, 0xfd, + 0x02, 0x08, 0x15, 0x21, 0x22, 0x1b, 0x14, 0x10, 0x0d, 0x04, 0x00, 0x02, + 0xfe, 0xfe, 0x0b, 0x19, 0x21, 0x25, 0x28, 0x27, 0x25, 0x1d, 0x15, 0x09, + 0xff, 0xf2, 0xe7, 0xe5, 0xe8, 0xea, 0xec, 0xf2, 0xfd, 0x00, 0xff, 0xfd, + 0xf9, 0xfd, 0x08, 0x0c, 0x06, 0xff, 0xf9, 0xf9, 0xf7, 0xf3, 0xf0, 0xed, + 0xef, 0xf4, 0xfc, 0x00, 0x04, 0x0a, 0x0b, 0x0d, 0x15, 0x1a, 0x16, 0x11, + 0x0d, 0x09, 0x0a, 0x0c, 0x0b, 0x04, 0x02, 0x04, 0x08, 0x09, 0x0b, 0x07, + 0x04, 0x0f, 0x18, 0x17, 0x14, 0x15, 0x16, 0x14, 0x0d, 0x00, 0xf6, 0xec, + 0xe4, 0xe8, 0xf3, 0xf6, 0xf1, 0xef, 0xee, 0xf4, 0xff, 0xfe, 0xf7, 0xed, + 0xe4, 0xe1, 0xe3, 0xe5, 0xf0, 0xf8, 0xff, 0x0a, 0x14, 0x1d, 0x25, 0x2c, + 0x38, 0x40, 0x39, 0x2e, 0x26, 0x1c, 0x12, 0x0d, 0x04, 0xf4, 0xe3, 0xdd, + 0xe5, 0xf2, 0x01, 0x07, 0x01, 0xfe, 0x00, 0x01, 0xfd, 0xf7, 0xf1, 0xeb, + 0xe7, 0xe9, 0xee, 0xf2, 0xf8, 0xff, 0x07, 0x0c, 0x08, 0x07, 0x08, 0x0b, + 0x16, 0x1e, 0x22, 0x21, 0x1b, 0x19, 0x19, 0x13, 0x0c, 0xfb, 0xf0, 0xef, + 0xf7, 0xfa, 0xfe, 0xfd, 0xfd, 0xfd, 0xfe, 0x01, 0x05, 0x01, 0xfc, 0xf9, + 0xfa, 0xfa, 0xf5, 0xf4, 0xf3, 0xf2, 0xf8, 0x00, 0x07, 0x09, 0x0a, 0x0f, + 0x15, 0x15, 0x17, 0x14, 0x11, 0x11, 0x10, 0x0a, 0xfb, 0xf0, 0xf4, 0x00, + 0x08, 0x12, 0x1a, 0x1b, 0x19, 0x17, 0x19, 0x17, 0x09, 0xfb, 0xef, 0xe7, + 0xe3, 0xe5, 0xe5, 0xe4, 0xe3, 0xe8, 0xee, 0xf4, 0xfb, 0x04, 0x0e, 0x19, + 0x1c, 0x16, 0x0f, 0x10, 0x12, 0x0e, 0x06, 0xfa, 0xec, 0xe9, 0xf3, 0xfe, + 0x09, 0x0f, 0x10, 0x0d, 0x08, 0x0b, 0x12, 0x14, 0x10, 0x0d, 0x08, 0x05, + 0x07, 0x07, 0x06, 0x06, 0x05, 0x05, 0x04, 0x01, 0x01, 0x07, 0x0f, 0x0e, + 0x08, 0x01, 0x05, 0x0c, 0x0a, 0x04, 0xfc, 0xef, 0xe2, 0xde, 0xe1, 0xe9, + 0xf5, 0xff, 0xff, 0xfd, 0xfb, 0xfc, 0xfd, 0xfd, 0xf8, 0xf5, 0xf4, 0xf8, + 0xf9, 0xf7, 0xf8, 0xff, 0x0a, 0x17, 0x1e, 0x23, 0x30, 0x3c, 0x41, 0x39, + 0x2e, 0x29, 0x28, 0x1d, 0x11, 0x0a, 0x02, 0xf4, 0xe9, 0xe7, 0xe9, 0xeb, + 0xee, 0xf0, 0xed, 0xf0, 0xf4, 0xf3, 0xee, 0xe7, 0xe2, 0xdf, 0xe4, 0xe8, + 0xe8, 0xe6, 0xec, 0xf4, 0xfb, 0x02, 0x04, 0x0c, 0x1b, 0x23, 0x20, 0x23, + 0x2b, 0x2f, 0x30, 0x2d, 0x27, 0x18, 0x09, 0xfd, 0xfa, 0x00, 0x08, 0x0a, + 0x07, 0x04, 0x03, 0x01, 0x00, 0x00, 0xfc, 0xf6, 0xf5, 0xf6, 0xf9, 0xfb, + 0xf7, 0xf6, 0xf7, 0xf0, 0xf1, 0xfc, 0x02, 0x0a, 0x13, 0x10, 0x04, 0xfe, + 0xfe, 0xfd, 0xfd, 0x02, 0xfe, 0xf4, 0xee, 0xec, 0xf0, 0xfa, 0x06, 0x0e, + 0x16, 0x1d, 0x20, 0x1d, 0x1e, 0x1b, 0x12, 0x09, 0x00, 0xf6, 0xf5, 0xfa, + 0xf9, 0xf8, 0xfa, 0xfb, 0xfe, 0xfc, 0xfd, 0x08, 0x12, 0x13, 0x14, 0x13, + 0x12, 0x13, 0x11, 0x08, 0xfe, 0xf6, 0xf5, 0xf6, 0xf4, 0xfa, 0xfc, 0xfe, + 0x02, 0x06, 0xfe, 0xf7, 0xfc, 0xff, 0xfd, 0xfe, 0xff, 0x02, 0x01, 0xff, + 0xf6, 0xf3, 0xfa, 0x07, 0x0f, 0x0d, 0x0e, 0x15, 0x15, 0x13, 0x14, 0x18, + 0x1e, 0x1c, 0x0f, 0x02, 0xf9, 0xf6, 0xf5, 0xf5, 0xf2, 0xf2, 0xfd, 0x03, + 0x06, 0x06, 0x06, 0x01, 0xf8, 0xed, 0xe6, 0xeb, 0xef, 0xfa, 0x01, 0x00, + 0xfe, 0x01, 0x05, 0x09, 0x12, 0x1e, 0x2f, 0x32, 0x2a, 0x21, 0x1d, 0x20, + 0x1b, 0x0f, 0xfb, 0xf0, 0xf1, 0xf1, 0xee, 0xef, 0xf4, 0xf4, 0xf3, 0xe9, + 0xe6, 0xec, 0xf0, 0xf6, 0xfa, 0xf8, 0xf6, 0xf5, 0xf6, 0xf3, 0xf5, 0xf8, + 0x03, 0x05, 0x03, 0x08, 0x13, 0x19, 0x1e, 0x23, 0x1e, 0x1d, 0x27, 0x2e, + 0x2b, 0x24, 0x1c, 0x13, 0x08, 0x02, 0xfb, 0xf9, 0xfb, 0x00, 0x03, 0xfd, + 0xf8, 0xf4, 0xee, 0xe5, 0xe6, 0xeb, 0xf2, 0xef, 0xea, 0xec, 0xed, 0xf0, + 0xf0, 0xf1, 0xf7, 0x05, 0x0d, 0x0a, 0x11, 0x14, 0x16, 0x17, 0x14, 0x0c, + 0x02, 0xfb, 0xf5, 0xfa, 0x04, 0x09, 0x07, 0x07, 0x0b, 0x10, 0x14, 0x1f, + 0x25, 0x1f, 0x11, 0x0d, 0x0d, 0x0d, 0x07, 0xfd, 0xfb, 0xfd, 0xfe, 0xfc, + 0xf8, 0xfa, 0x01, 0x02, 0xfa, 0xf7, 0xfa, 0xfb, 0xfb, 0x01, 0x08, 0x01, + 0xfa, 0xf5, 0xed, 0xea, 0xf3, 0xff, 0x06, 0x03, 0xfc, 0xfa, 0xfc, 0x00, + 0xfd, 0xfb, 0x01, 0x06, 0x0a, 0x0e, 0x0e, 0x0f, 0x0d, 0x06, 0x03, 0x06, + 0x05, 0x0c, 0x13, 0x16, 0x1a, 0x1a, 0x18, 0x17, 0x15, 0x16, 0x16, 0x16, + 0x12, 0x05, 0xfa, 0xfa, 0xfd, 0xfa, 0xed, 0xea, 0xf2, 0xf8, 0xf7, 0xf3, + 0xf0, 0xed, 0xea, 0xe3, 0xe0, 0xe2, 0xe1, 0xe7, 0xec, 0xf5, 0x03, 0x09, + 0x0e, 0x15, 0x1b, 0x1d, 0x21, 0x27, 0x2b, 0x2f, 0x2d, 0x2a, 0x24, 0x16, + 0x04, 0xfd, 0x02, 0x04, 0x06, 0x04, 0xfd, 0xfb, 0xfd, 0xf7, 0xf0, 0xed, + 0xeb, 0xe9, 0xeb, 0xf0, 0xfa, 0xfe, 0xfb, 0xfa, 0xf6, 0xf9, 0x03, 0x08, + 0x0b, 0x10, 0x0b, 0x08, 0x0a, 0x09, 0x0d, 0x16, 0x16, 0x12, 0x14, 0x10, + 0x0b, 0x08, 0x02, 0x00, 0x06, 0x05, 0x00, 0xfb, 0xfa, 0xf4, 0xf6, 0xf8, + 0xf3, 0xf4, 0xf8, 0xfb, 0x00, 0x02, 0x01, 0x02, 0xfd, 0xff, 0x00, 0xfe, + 0x02, 0x0f, 0x14, 0x12, 0x0e, 0x11, 0x17, 0x16, 0x0c, 0x0a, 0x05, 0x00, + 0xfb, 0xfc, 0xff, 0x02, 0x08, 0x07, 0x02, 0x02, 0x02, 0x05, 0x09, 0x05, + 0x01, 0x04, 0x06, 0x00, 0xfa, 0xf1, 0xf4, 0xfb, 0xff, 0x02, 0x05, 0x08, + 0x07, 0x02, 0xfe, 0xfa, 0xf7, 0xfe, 0x04, 0x02, 0xff, 0x01, 0x02, 0x00, + 0xfe, 0x00, 0x05, 0x09, 0x0c, 0x0b, 0x0a, 0x0b, 0x08, 0x00, 0xf6, 0xf5, + 0x00, 0x0a, 0x0f, 0x10, 0x13, 0x11, 0x0c, 0x06, 0x04, 0x05, 0x0b, 0x0c, + 0x07, 0x03, 0xff, 0xfe, 0x06, 0x0e, 0x08, 0x02, 0x02, 0x04, 0xfe, 0xfb, + 0x03, 0x08, 0x06, 0xfe, 0xf4, 0xee, 0xf2, 0xf6, 0xf1, 0xed, 0xed, 0xef, + 0xf1, 0xf1, 0xf3, 0xf4, 0xf6, 0xfb, 0xfd, 0x00, 0x04, 0x10, 0x18, 0x1c, + 0x23, 0x25, 0x22, 0x21, 0x20, 0x21, 0x27, 0x2d, 0x28, 0x17, 0x06, 0x08, + 0x0e, 0x0a, 0x04, 0x04, 0xfe, 0xef, 0xe2, 0xe0, 0xe2, 0xe2, 0xe3, 0xe3, + 0xe3, 0xe0, 0xe0, 0xe6, 0xee, 0xf6, 0xfa, 0xfe, 0x0c, 0x13, 0x0d, 0x0b, + 0x14, 0x18, 0x12, 0x07, 0xfe, 0x09, 0x1a, 0x1f, 0x1b, 0x18, 0x17, 0x12, + 0x0a, 0x09, 0x0c, 0x0e, 0x0b, 0x07, 0x00, 0xfa, 0xf2, 0xf2, 0xf6, 0xfd, + 0x02, 0x01, 0x05, 0x06, 0x04, 0x01, 0x05, 0x0f, 0x11, 0xfe, 0xf2, 0xfa, + 0x00, 0x02, 0x00, 0xfd, 0xfc, 0xfa, 0xfd, 0xfa, 0xf9, 0xfe, 0x04, 0x07, + 0x07, 0x02, 0xff, 0x03, 0x04, 0x02, 0xff, 0x00, 0xff, 0xfc, 0xfe, 0x06, + 0x09, 0x0c, 0x0a, 0x03, 0xff, 0x03, 0x0f, 0x18, 0x18, 0x13, 0x0d, 0x07, + 0x05, 0x00, 0xfd, 0xfd, 0x02, 0x0b, 0x0a, 0x02, 0xfe, 0x00, 0x00, 0x02, + 0x04, 0x05, 0x05, 0x01, 0xf7, 0xf3, 0xf8, 0xff, 0xfb, 0xf3, 0xf5, 0xfa, + 0xff, 0x06, 0x0b, 0x0a, 0x02, 0x03, 0x0a, 0x0f, 0x0f, 0x0c, 0x0b, 0x09, + 0x04, 0xfc, 0xf3, 0xf5, 0xff, 0x06, 0x0b, 0x0d, 0x0e, 0x0d, 0x0c, 0x0e, + 0x0f, 0x10, 0x0d, 0x05, 0xf9, 0xf2, 0xf4, 0xf7, 0xf5, 0xf4, 0xf4, 0xf7, + 0xf9, 0xfd, 0x00, 0x01, 0x08, 0x0e, 0x0d, 0x05, 0x02, 0x07, 0x0e, 0x0d, + 0x0b, 0x07, 0x07, 0x0d, 0x14, 0x17, 0x17, 0x14, 0x10, 0x0f, 0x0e, 0x0a, + 0x08, 0x0b, 0x07, 0xf9, 0xea, 0xe2, 0xe1, 0xe1, 0xe1, 0xe6, 0xed, 0xef, + 0xf0, 0xef, 0xf0, 0xf8, 0x03, 0x08, 0x10, 0x19, 0x1b, 0x17, 0x17, 0x15, + 0x0f, 0x0f, 0x14, 0x17, 0x1a, 0x1d, 0x21, 0x22, 0x1e, 0x0f, 0x06, 0x01, + 0x01, 0xff, 0xfc, 0xf8, 0xef, 0xe7, 0xe8, 0xe9, 0xe9, 0xf0, 0xf6, 0xf6, + 0xfc, 0x02, 0x03, 0x06, 0x0c, 0x0d, 0x0e, 0x13, 0x11, 0x0b, 0x00, 0xf5, + 0xf2, 0xf6, 0xf6, 0xf1, 0xf5, 0xfd, 0x03, 0x09, 0x0d, 0x0f, 0x12, 0x0f, + 0x0b, 0x0c, 0x0b, 0x09, 0x03, 0xfc, 0xff, 0x05, 0x07, 0x0c, 0x13, 0x10, + 0x0f, 0x0e, 0x0d, 0x12, 0x11, 0x0b, 0x0b, 0x0f, 0x08, 0xf9, 0xf1, 0xea, + 0xe8, 0xf1, 0xfb, 0x00, 0x04, 0x04, 0x03, 0xfe, 0xfb, 0xfe, 0xff, 0xfc, + 0xfe, 0x03, 0x00, 0xfd, 0xfa, 0xf7, 0xf8, 0xf9, 0xf7, 0xfc, 0x02, 0x07, + 0x10, 0x14, 0x11, 0x0b, 0x0d, 0x11, 0x17, 0x1b, 0x15, 0x0b, 0x01, 0xf9, + 0xfc, 0x07, 0x0c, 0x0a, 0x0f, 0x13, 0x12, 0x10, 0x0c, 0x08, 0x01, 0xfc, + 0xff, 0x01, 0xfd, 0xf6, 0xec, 0xe5, 0xe8, 0xeb, 0xec, 0xec, 0xf4, 0xf9, + 0xff, 0x06, 0x0b, 0x0d, 0x10, 0x0e, 0x11, 0x15, 0x0f, 0x05, 0xf9, 0xf5, + 0xfd, 0x05, 0x04, 0x05, 0x12, 0x1a, 0x17, 0x16, 0x17, 0x19, 0x18, 0x12, + 0x0b, 0x05, 0xfc, 0xf0, 0xea, 0xe9, 0xed, 0xf0, 0xf8, 0xff, 0x02, 0xff, + 0x01, 0x02, 0xfd, 0xfc, 0xfd, 0x02, 0x07, 0x08, 0x03, 0xfc, 0xfb, 0x02, + 0x0f, 0x13, 0x14, 0x1e, 0x28, 0x20, 0x12, 0x0c, 0x08, 0x01, 0xff, 0xfe, + 0xfe, 0xfe, 0xfa, 0xf1, 0xe8, 0xe3, 0xe1, 0xe5, 0xeb, 0xf7, 0xfd, 0x05, + 0x0b, 0x0e, 0x11, 0x13, 0x17, 0x1e, 0x1b, 0x11, 0x07, 0x01, 0x02, 0x02, + 0x02, 0x00, 0xff, 0x01, 0x08, 0x0b, 0x0a, 0x09, 0x08, 0x04, 0x01, 0x01, + 0x04, 0x04, 0xfb, 0xf2, 0xed, 0xf0, 0xf6, 0x01, 0x0d, 0x0f, 0x14, 0x16, + 0x0f, 0x0c, 0x0f, 0x15, 0x1b, 0x15, 0x08, 0xfb, 0xf0, 0xe7, 0xe7, 0xea, + 0xea, 0xea, 0xf4, 0xfe, 0x06, 0x09, 0x09, 0x0c, 0x09, 0x04, 0xff, 0x01, + 0x03, 0x02, 0x06, 0x04, 0x04, 0x08, 0x07, 0x0e, 0x17, 0x1f, 0x23, 0x16, + 0x05, 0x03, 0x03, 0x03, 0x07, 0x08, 0xff, 0xf4, 0xf2, 0xf0, 0xf5, 0xfc, + 0x02, 0x07, 0x0d, 0x0e, 0x0e, 0x0d, 0x06, 0x05, 0x04, 0x01, 0x05, 0x07, + 0xfe, 0xfa, 0xfb, 0xf4, 0xeb, 0xe1, 0xdb, 0xe3, 0xee, 0xfa, 0x05, 0x0a, + 0x0d, 0x11, 0x1b, 0x1f, 0x1d, 0x15, 0x10, 0x0b, 0x04, 0x00, 0x07, 0x0d, + 0x08, 0x0a, 0x11, 0x18, 0x1c, 0x15, 0x07, 0x07, 0x06, 0x05, 0x06, 0xfd, + 0xf3, 0xf3, 0xee, 0xe3, 0xe3, 0xed, 0xf2, 0xff, 0x0a, 0x09, 0x02, 0x03, + 0x05, 0x04, 0x05, 0x05, 0x02, 0xfd, 0xf8, 0xf8, 0xf9, 0x02, 0x06, 0xfe, + 0xfe, 0x0c, 0x17, 0x21, 0x23, 0x17, 0x0f, 0x0f, 0x08, 0x01, 0x01, 0x02, + 0x00, 0xff, 0xfd, 0xf3, 0xf3, 0xf7, 0xfe, 0x08, 0x0a, 0x06, 0x06, 0x03, + 0xff, 0x01, 0x0c, 0x10, 0x08, 0xfd, 0xfa, 0xfd, 0x03, 0x09, 0x04, 0x00, + 0x01, 0x03, 0x03, 0x05, 0x09, 0x07, 0x05, 0x04, 0x05, 0x05, 0x09, 0x09, + 0x02, 0xfb, 0xee, 0xe3, 0xe4, 0xe8, 0xf4, 0x01, 0x0e, 0x18, 0x18, 0x12, + 0x14, 0x1e, 0x1f, 0x12, 0x07, 0x02, 0x02, 0x02, 0x01, 0xf8, 0xf7, 0xfe, + 0x00, 0xfd, 0x00, 0x06, 0x08, 0x05, 0x02, 0xfc, 0xf6, 0xf6, 0xf9, 0xf6, + 0xf6, 0xf9, 0xff, 0x06, 0x0a, 0x0f, 0x1e, 0x2a, 0x27, 0x1b, 0x0e, 0x09, + 0x0c, 0x0d, 0x04, 0xf9, 0xf8, 0xf9, 0xf4, 0xf1, 0xec, 0xe7, 0xeb, 0xf3, + 0xf4, 0xfa, 0x03, 0x10, 0x15, 0x10, 0x08, 0x03, 0x09, 0x0e, 0x07, 0x03, + 0x09, 0x0c, 0x05, 0xfd, 0xfc, 0x03, 0x05, 0x03, 0xfe, 0xfa, 0x01, 0x06, + 0x0a, 0x0a, 0x09, 0x07, 0x0a, 0x09, 0x03, 0xfe, 0xfd, 0x01, 0x08, 0x0a, + 0x0a, 0x0c, 0x16, 0x19, 0x0f, 0x04, 0x05, 0x0a, 0x08, 0xfe, 0xf7, 0xf8, + 0xf5, 0xea, 0xdb, 0xd7, 0xe4, 0xf2, 0xf6, 0xf9, 0x01, 0x0a, 0x0f, 0x14, + 0x15, 0x0a, 0x02, 0x02, 0x07, 0x07, 0x07, 0x08, 0x0c, 0x10, 0x13, 0x11, + 0x14, 0x1c, 0x1b, 0x14, 0x0a, 0x07, 0x04, 0xfe, 0xf8, 0xf4, 0xf7, 0xf7, + 0xf7, 0xf4, 0xf5, 0xfc, 0x06, 0x0a, 0x0b, 0x07, 0x07, 0x06, 0x06, 0x08, + 0x04, 0x02, 0x02, 0x05, 0xff, 0xf6, 0xf7, 0xf5, 0xf1, 0xf3, 0xfa, 0xfb, + 0xfc, 0x00, 0x05, 0x09, 0x0d, 0x0e, 0x0b, 0x0a, 0x0f, 0x14, 0x12, 0x0f, + 0x07, 0xfe, 0xff, 0x01, 0x03, 0x03, 0x07, 0x0b, 0x0b, 0x0b, 0x09, 0x06, + 0x05, 0x05, 0x05, 0x01, 0x00, 0x03, 0x03, 0xfc, 0xfb, 0xfd, 0xff, 0x01, + 0x01, 0x01, 0x04, 0x03, 0x02, 0x03, 0x00, 0xff, 0xfe, 0xf7, 0xf2, 0xf4, + 0xf6, 0xf5, 0xf7, 0xfd, 0x05, 0x0c, 0x17, 0x1b, 0x19, 0x1b, 0x19, 0x10, + 0x08, 0x06, 0x04, 0x03, 0x03, 0x02, 0xf8, 0xf5, 0xfc, 0xfe, 0xfa, 0xfb, + 0xfc, 0x02, 0x06, 0x05, 0x03, 0x01, 0x04, 0x02, 0xfd, 0xfc, 0xff, 0x04, + 0x09, 0x0a, 0x09, 0x0e, 0x14, 0x18, 0x0f, 0x04, 0xff, 0x01, 0x01, 0x00, + 0x03, 0x0a, 0x0a, 0x07, 0xfe, 0xf5, 0xec, 0xf0, 0xf5, 0xf3, 0xf3, 0xfe, + 0x07, 0x0e, 0x13, 0x10, 0x0a, 0x09, 0x0a, 0x06, 0x04, 0x0a, 0x0b, 0x0a, + 0x09, 0xff, 0xf4, 0xf1, 0xf7, 0xfc, 0xfe, 0x00, 0x05, 0x04, 0x00, 0x02, + 0x09, 0x0a, 0x07, 0x00, 0xff, 0x04, 0x09, 0x0a, 0x0e, 0x12, 0x19, 0x1a, + 0x17, 0x14, 0x0e, 0x0d, 0x0c, 0x08, 0x02, 0xf5, 0xef, 0xed, 0xed, 0xef, + 0xed, 0xe9, 0xea, 0xef, 0xf8, 0xfe, 0x05, 0x0e, 0x11, 0x06, 0x06, 0x0d, + 0x0e, 0x0e, 0x0c, 0x05, 0x01, 0xff, 0xfe, 0xff, 0x01, 0x07, 0x09, 0x08, + 0x05, 0x03, 0x01, 0x02, 0x04, 0x05, 0x04, 0x08, 0x0b, 0x0c, 0x0f, 0x11, + 0x0c, 0x07, 0x08, 0x09, 0x0f, 0x11, 0x0e, 0x0c, 0x02, 0xfa, 0xfc, 0x02, + 0x02, 0xfd, 0xf7, 0xf4, 0xef, 0xef, 0xf2, 0xf1, 0xea, 0xe8, 0xef, 0xfa, + 0x02, 0x09, 0x0b, 0x08, 0x06, 0x09, 0x0f, 0x14, 0x0e, 0x09, 0x11, 0x11, + 0x04, 0xff, 0x02, 0x07, 0x13, 0x16, 0x14, 0x12, 0x0e, 0x0a, 0x0d, 0x0f, + 0x0b, 0x03, 0xfd, 0xfb, 0xf7, 0xf9, 0xff, 0x01, 0xfe, 0xff, 0x03, 0x00, + 0x00, 0x04, 0x04, 0x04, 0x03, 0xff, 0xf9, 0xf6, 0xf2, 0xf4, 0xfa, 0xf7, + 0xee, 0xf0, 0x00, 0x0d, 0x11, 0x14, 0x17, 0x0c, 0xff, 0x00, 0x0a, 0x13, + 0x17, 0x15, 0x0c, 0x03, 0x01, 0xff, 0xff, 0xfd, 0xfb, 0x01, 0x06, 0x05, + 0x08, 0x09, 0x02, 0xfb, 0xff, 0xff, 0xff, 0x04, 0x10, 0x14, 0x14, 0x10, + 0x09, 0x03, 0x00, 0xfd, 0xfd, 0x04, 0x04, 0xf8, 0xf6, 0xfc, 0x06, 0x06, + 0x06, 0x00, 0xf8, 0xf4, 0xf2, 0xf5, 0xf7, 0xfa, 0xfb, 0x00, 0x0d, 0x10, + 0x13, 0x18, 0x15, 0x10, 0x11, 0x12, 0x0e, 0x09, 0x03, 0x00, 0xfa, 0xf3, + 0xef, 0xf2, 0xf5, 0xfa, 0x03, 0x08, 0x04, 0x00, 0x06, 0x0f, 0x0f, 0x0b, + 0x08, 0x06, 0xff, 0xf8, 0xfe, 0x01, 0x04, 0x0d, 0x13, 0x19, 0x16, 0x0f, + 0x0b, 0x02, 0xf8, 0xf6, 0xfc, 0x01, 0x01, 0x00, 0x01, 0x01, 0xfd, 0xf3, + 0xf4, 0xfa, 0x00, 0x0a, 0x0f, 0x0d, 0x06, 0x03, 0x02, 0x01, 0x08, 0x07, + 0x06, 0x07, 0x00, 0xfa, 0xfd, 0xfd, 0xfb, 0xf8, 0xf3, 0xf6, 0xf8, 0xfd, + 0x04, 0x01, 0xfe, 0x04, 0x0a, 0x11, 0x1b, 0x21, 0x21, 0x19, 0x0f, 0x0b, + 0x09, 0x0c, 0x0d, 0x10, 0x11, 0x09, 0x07, 0x0a, 0x0d, 0x0c, 0x08, 0x02, + 0xfb, 0xef, 0xe1, 0xdb, 0xe0, 0xe6, 0xe5, 0xe9, 0xf4, 0xfa, 0xfb, 0x05, + 0x0a, 0x09, 0x0d, 0x10, 0x0f, 0x11, 0x11, 0x0b, 0xfe, 0xf7, 0xf5, 0xf6, + 0x00, 0x0b, 0x16, 0x1d, 0x1c, 0x12, 0x0c, 0x07, 0x02, 0x04, 0x0c, 0x12, + 0x10, 0x06, 0x02, 0x06, 0x05, 0x03, 0x05, 0x0e, 0x10, 0x08, 0x02, 0x02, + 0xfe, 0xf3, 0xef, 0xec, 0xf0, 0xfd, 0x03, 0x00, 0xfe, 0xfe, 0xf7, 0xf4, + 0xf8, 0xfa, 0xfa, 0xfc, 0xfd, 0xff, 0x02, 0x05, 0x0c, 0x10, 0x13, 0x13, + 0x0e, 0x08, 0x02, 0xfe, 0xf9, 0xfc, 0x03, 0x05, 0x05, 0x00, 0x04, 0x11, + 0x13, 0x10, 0x12, 0x17, 0x1f, 0x24, 0x1b, 0x0d, 0x03, 0xfb, 0xf6, 0xf6, + 0xf9, 0xff, 0x04, 0xff, 0xfc, 0xfe, 0xff, 0x04, 0x05, 0x02, 0xff, 0xfa, + 0xee, 0xe2, 0xde, 0xda, 0xe5, 0xf9, 0x03, 0x08, 0x0f, 0x14, 0x18, 0x16, + 0x0d, 0x05, 0x06, 0x0f, 0x18, 0x13, 0x0b, 0x08, 0x05, 0xfe, 0xfc, 0xff, + 0x08, 0x14, 0x13, 0x0c, 0x0a, 0x07, 0x01, 0xfd, 0xfd, 0xfe, 0x02, 0x0a, + 0x07, 0x00, 0x01, 0x06, 0x06, 0x05, 0x04, 0x01, 0xf9, 0xf4, 0xf7, 0xf5, + 0xf2, 0xf9, 0x01, 0x08, 0x0f, 0x0e, 0x10, 0x0b, 0x03, 0xfc, 0xf7, 0xf8, + 0x02, 0x06, 0x02, 0xfd, 0x06, 0x13, 0x17, 0x19, 0x1c, 0x18, 0x11, 0x03, + 0xf3, 0xe9, 0xe4, 0xe4, 0xe8, 0xf0, 0xf8, 0xfb, 0xfb, 0xfd, 0x05, 0x09, + 0x0b, 0x11, 0x1a, 0x22, 0x21, 0x18, 0x0c, 0x05, 0xfb, 0xf3, 0xf8, 0x0e, + 0x1a, 0x19, 0x18, 0x18, 0x11, 0x08, 0x00, 0xfd, 0xfb, 0xfb, 0xfc, 0xf2, + 0xe6, 0xe9, 0xee, 0xef, 0xf8, 0x00, 0x04, 0x05, 0x07, 0x08, 0x08, 0x03, + 0xff, 0x01, 0x01, 0x01, 0xfe, 0x06, 0x09, 0x06, 0x02, 0xfe, 0x01, 0x08, + 0x09, 0x05, 0x01, 0xfe, 0xff, 0x01, 0x09, 0x12, 0x15, 0x16, 0x16, 0x10, + 0x0e, 0x0c, 0x0b, 0x07, 0x07, 0x07, 0x08, 0x00, 0xf5, 0xf2, 0xf9, 0x04, + 0x0c, 0x13, 0x18, 0x12, 0x0a, 0x01, 0xfa, 0xf0, 0xe3, 0xdf, 0xe7, 0xee, + 0xf4, 0xf8, 0xfa, 0x02, 0x08, 0x10, 0x13, 0x10, 0x0e, 0x07, 0xfa, 0xef, + 0xec, 0xe5, 0xe8, 0xf3, 0x01, 0x10, 0x16, 0x15, 0x19, 0x1a, 0x18, 0x14, + 0x19, 0x20, 0x1d, 0x17, 0x16, 0x0f, 0x0b, 0x07, 0x02, 0x03, 0x0e, 0x13, + 0x0f, 0x0b, 0x07, 0x00, 0xfa, 0xf5, 0xf2, 0xec, 0xe9, 0xe4, 0xe0, 0xe8, + 0xee, 0xf1, 0xf8, 0xfa, 0xfa, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0x00, 0x0c, + 0x17, 0x18, 0x0f, 0x10, 0x18, 0x15, 0x0f, 0x0e, 0x0b, 0x08, 0x0c, 0x0f, + 0x0c, 0x03, 0xff, 0x01, 0x0b, 0x1e, 0x24, 0x22, 0x1d, 0x12, 0x02, 0xfb, + 0xfa, 0xf5, 0xee, 0xef, 0xf5, 0xf6, 0xf6, 0xf2, 0xed, 0xf4, 0x02, 0x0b, + 0x0e, 0x0c, 0x0a, 0x05, 0xfd, 0xf5, 0xf1, 0xe7, 0xe8, 0xf0, 0xfc, 0x0a, + 0x12, 0x15, 0x19, 0x1b, 0x1d, 0x17, 0x0b, 0x03, 0xff, 0xf3, 0xf0, 0xf2, + 0xf6, 0xf9, 0xff, 0x0a, 0x13, 0x0f, 0x0b, 0x0a, 0x09, 0x0a, 0x12, 0x16, + 0x0f, 0x05, 0x04, 0x00, 0x03, 0x0d, 0x0e, 0x09, 0x05, 0x07, 0x08, 0x03, + 0xfd, 0xf6, 0xf3, 0xf3, 0xfc, 0xfe, 0x00, 0xff, 0xf6, 0xf6, 0xfb, 0xfc, + 0xfe, 0x01, 0x00, 0xfd, 0xfc, 0x00, 0xfd, 0xf4, 0xf9, 0x07, 0x16, 0x22, + 0x20, 0x18, 0x12, 0x0d, 0x0a, 0x04, 0xff, 0xf8, 0xf2, 0xf6, 0xfd, 0xfd, + 0xfb, 0xfc, 0x05, 0x15, 0x1b, 0x17, 0x15, 0x0e, 0x03, 0xfc, 0xfc, 0xfa, + 0xf2, 0xf1, 0xfa, 0xfe, 0x06, 0x11, 0x0d, 0x05, 0x09, 0x16, 0x19, 0x14, + 0x08, 0x02, 0xfc, 0xfa, 0xfa, 0xf9, 0xf8, 0xf2, 0xf7, 0x03, 0x07, 0x03, + 0x06, 0x0e, 0x12, 0x0c, 0x04, 0xf9, 0xeb, 0xe1, 0xe0, 0xe2, 0xf1, 0xff, + 0x03, 0x06, 0x09, 0x0a, 0x07, 0x01, 0xfb, 0x00, 0x0b, 0x1a, 0x21, 0x20, + 0x18, 0x14, 0x18, 0x1f, 0x1c, 0x19, 0x14, 0x0d, 0x0b, 0x0b, 0x07, 0xff, + 0xf4, 0xf1, 0xf8, 0xfc, 0x04, 0x0c, 0x06, 0xfa, 0xf0, 0xf1, 0xf4, 0xef, + 0xeb, 0xe9, 0xe3, 0xe4, 0xec, 0xf2, 0xf2, 0xfb, 0x0f, 0x1b, 0x16, 0x0c, + 0x09, 0x09, 0x08, 0x08, 0x09, 0x05, 0xfa, 0xfb, 0x02, 0x05, 0x0c, 0x17, + 0x1d, 0x20, 0x26, 0x27, 0x20, 0x16, 0x0a, 0x00, 0xfb, 0xfb, 0xfd, 0xfc, + 0xfd, 0xff, 0x09, 0x0e, 0x07, 0xfd, 0xf5, 0x01, 0x0f, 0x0b, 0x03, 0xf6, + 0xe9, 0xe7, 0xeb, 0xf0, 0xf9, 0xfe, 0xfa, 0xf7, 0xf8, 0xfb, 0xfe, 0x00, + 0x02, 0x06, 0x05, 0x01, 0x03, 0x03, 0xfb, 0xf8, 0x03, 0x0c, 0x09, 0x0d, + 0x12, 0x12, 0x11, 0x0d, 0x0b, 0xff, 0xfe, 0x11, 0x1d, 0x1b, 0x1d, 0x23, + 0x21, 0x1a, 0x14, 0x10, 0x0b, 0x03, 0xfb, 0xf9, 0xf4, 0xf0, 0xf0, 0xef, + 0xf2, 0xf8, 0xff, 0x00, 0xfe, 0xf9, 0xee, 0xec, 0xee, 0xf1, 0xf3, 0xef, + 0xe7, 0xe9, 0xf3, 0xfe, 0x04, 0x0c, 0x1b, 0x22, 0x20, 0x19, 0x13, 0x0e, + 0x0b, 0x0d, 0x0a, 0x07, 0x0a, 0x05, 0x03, 0x08, 0x12, 0x12, 0x0e, 0x11, + 0x16, 0x19, 0x15, 0x10, 0x08, 0xf7, 0xe5, 0xe6, 0xee, 0xf3, 0xf9, 0x01, + 0x05, 0x03, 0x01, 0xf9, 0xf1, 0xf1, 0xfe, 0x09, 0x07, 0x02, 0x00, 0x01, + 0x02, 0x07, 0x0f, 0x10, 0x09, 0x02, 0x00, 0x03, 0x04, 0x07, 0x09, 0x03, + 0xfb, 0xfb, 0xfd, 0x03, 0x08, 0x08, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, + 0xff, 0xff, 0xf6, 0xef, 0xf5, 0x02, 0x12, 0x1b, 0x1c, 0x18, 0x16, 0x14, + 0x11, 0x0f, 0x0e, 0x0d, 0x04, 0xfc, 0xf8, 0xfa, 0xfd, 0x02, 0x07, 0x0b, + 0x0e, 0x0c, 0x09, 0x07, 0x00, 0xf3, 0xef, 0xf2, 0xed, 0xee, 0xef, 0xf1, + 0xf4, 0xfe, 0x05, 0x05, 0x03, 0x0a, 0x0f, 0x10, 0x0a, 0x08, 0x03, 0xfb, + 0xf4, 0xf8, 0x00, 0x02, 0x00, 0x05, 0x0a, 0x06, 0x07, 0x07, 0x08, 0x0c, + 0x13, 0x17, 0x0f, 0x09, 0x06, 0x00, 0x04, 0x0a, 0x0d, 0x10, 0x11, 0x0f, + 0x0c, 0x0b, 0x03, 0xfc, 0xfc, 0xfe, 0xfc, 0xfc, 0xff, 0x03, 0x09, 0x0c, + 0x0a, 0x05, 0x00, 0xf8, 0xf0, 0xec, 0xf1, 0xf6, 0xf1, 0xef, 0xf3, 0xf8, + 0xfc, 0xff, 0x03, 0x04, 0xfe, 0xfa, 0xfe, 0x01, 0x02, 0x07, 0x07, 0x02, + 0xfe, 0xff, 0x05, 0x0f, 0x1f, 0x2c, 0x2c, 0x25, 0x22, 0x21, 0x1b, 0x15, + 0x11, 0x0f, 0x07, 0xff, 0xfd, 0x02, 0x05, 0x05, 0x04, 0x01, 0xfe, 0xfc, + 0xfe, 0x01, 0xfb, 0xf4, 0xe7, 0xe0, 0xd9, 0xdc, 0xe6, 0xe9, 0xed, 0xf2, + 0xf8, 0xf8, 0xfc, 0xff, 0xfe, 0x04, 0x0d, 0x0d, 0x0d, 0x0e, 0x11, 0x15, + 0x18, 0x1c, 0x19, 0x12, 0x12, 0x15, 0x16, 0x14, 0x12, 0x10, 0x0f, 0x0b, + 0x05, 0x03, 0x08, 0x08, 0x06, 0x05, 0x06, 0x06, 0x05, 0x01, 0xfc, 0xfa, + 0xf9, 0xf3, 0xec, 0xea, 0xf1, 0xfa, 0xfd, 0xfe, 0x04, 0x05, 0x02, 0x00, + 0x00, 0xfd, 0xf8, 0xf2, 0xf5, 0xf8, 0xf6, 0xf9, 0x00, 0x07, 0x0b, 0x10, + 0x14, 0x12, 0x10, 0x0a, 0x05, 0x04, 0x04, 0x06, 0x03, 0x02, 0x05, 0x08, + 0x07, 0x0e, 0x15, 0x16, 0x1c, 0x1b, 0x16, 0x17, 0x15, 0x0c, 0x04, 0xfd, + 0xf7, 0xf6, 0xf7, 0xfb, 0xfb, 0xfc, 0xfd, 0xfa, 0xf8, 0xf3, 0xf2, 0xfa, + 0x00, 0xff, 0xf6, 0xf1, 0xf7, 0xfe, 0x00, 0x01, 0x01, 0xfd, 0x00, 0x03, + 0x08, 0x08, 0x03, 0x02, 0x06, 0x06, 0x03, 0x0c, 0x13, 0x15, 0x12, 0x16, + 0x13, 0x0b, 0x08, 0x03, 0x03, 0x06, 0x03, 0x02, 0xff, 0x00, 0x04, 0x07, + 0x05, 0x05, 0x04, 0x01, 0x00, 0xff, 0x01, 0x07, 0x06, 0x00, 0xfd, 0xfa, + 0xf8, 0xfa, 0xfe, 0x05, 0x0b, 0x11, 0x15, 0x14, 0x11, 0x09, 0x04, 0x03, + 0xfc, 0xf3, 0xec, 0xee, 0xfa, 0xfe, 0xfe, 0x03, 0x03, 0x03, 0x04, 0x05, + 0x05, 0x07, 0x05, 0xfe, 0xf9, 0xf5, 0xf1, 0xf8, 0xfa, 0xfa, 0xfb, 0x05, + 0x0b, 0x0c, 0x0d, 0x0e, 0x14, 0x1a, 0x1d, 0x1a, 0x12, 0x0e, 0x14, 0x16, + 0x14, 0x11, 0x10, 0x0e, 0x0e, 0x09, 0x05, 0x01, 0xfb, 0xf7, 0xf6, 0xf4, + 0xef, 0xf4, 0xf8, 0xf4, 0xf6, 0xfb, 0xfb, 0xf5, 0xee, 0xe9, 0xef, 0xfa, + 0xfb, 0xf2, 0xf3, 0xfd, 0x06, 0x08, 0x0b, 0x11, 0x0f, 0x0d, 0x0e, 0x08, + 0x06, 0x08, 0x0c, 0x0b, 0x08, 0x05, 0x06, 0x0d, 0x14, 0x14, 0x13, 0x1a, + 0x1d, 0x17, 0x0e, 0x07, 0x09, 0x09, 0x05, 0xfe, 0xf7, 0xf9, 0x02, 0x01, + 0xfc, 0xfb, 0x00, 0x07, 0x07, 0x04, 0x02, 0x02, 0x00, 0xff, 0xf6, 0xe6, + 0xdf, 0xe4, 0xe6, 0xe5, 0xeb, 0xf7, 0xfc, 0xff, 0xfc, 0xfa, 0x03, 0x0d, + 0x14, 0x0c, 0x06, 0x0a, 0x10, 0x0e, 0x10, 0x13, 0x13, 0x14, 0x17, 0x16, + 0x14, 0x17, 0x18, 0x15, 0x12, 0x0d, 0x0a, 0x0c, 0x0f, 0x0d, 0x08, 0x0a, + 0x0c, 0x05, 0xfc, 0xf4, 0xf9, 0xfa, 0xf4, 0xed, 0xe7, 0xea, 0xf1, 0xf2, + 0xf4, 0xf6, 0xf8, 0xf6, 0xf2, 0xf0, 0xf0, 0xf3, 0xf4, 0xf9, 0xfc, 0xf9, + 0xfc, 0x0c, 0x15, 0x17, 0x1d, 0x25, 0x24, 0x22, 0x1d, 0x10, 0x08, 0x08, + 0x0a, 0x04, 0x02, 0x06, 0x08, 0x0c, 0x11, 0x11, 0x0d, 0x0d, 0x0c, 0x0a, + 0x08, 0x08, 0x04, 0xfe, 0xfc, 0xf0, 0xeb, 0xee, 0xef, 0xf2, 0xf5, 0xf6, + 0xf7, 0xfc, 0xfc, 0xfc, 0x01, 0x07, 0x0a, 0x07, 0x06, 0x04, 0x00, 0xfd, + 0xff, 0x00, 0xff, 0x01, 0x06, 0x0a, 0x0a, 0x08, 0x06, 0x06, 0x0a, 0x08, + 0x06, 0x03, 0x01, 0x01, 0x02, 0x07, 0x06, 0x04, 0x01, 0x02, 0x05, 0x0b, + 0x12, 0x10, 0x0b, 0x09, 0x06, 0x06, 0x0d, 0x12, 0x0d, 0x05, 0x00, 0x03, + 0x04, 0x05, 0x00, 0xfc, 0xfd, 0xf8, 0xf6, 0xf8, 0xfa, 0xfc, 0x07, 0x13, + 0x0d, 0x05, 0x01, 0xfa, 0xf2, 0xee, 0xec, 0xec, 0xf2, 0xfb, 0xfc, 0x00, + 0x0f, 0x18, 0x13, 0x11, 0x13, 0x13, 0x15, 0x17, 0x0f, 0x02, 0xfc, 0xf7, + 0xf1, 0xf1, 0xf2, 0xf8, 0x01, 0x09, 0x09, 0x05, 0x05, 0x0d, 0x13, 0x15, + 0x10, 0x09, 0x0d, 0x0e, 0x08, 0x08, 0x0b, 0x0e, 0x0c, 0x07, 0x04, 0x06, + 0x09, 0x04, 0xfc, 0xfe, 0x00, 0xfd, 0xff, 0x00, 0xf7, 0xf0, 0xf1, 0xf3, + 0xef, 0xed, 0xf2, 0xf8, 0xfd, 0x02, 0x01, 0xfd, 0x03, 0x07, 0x06, 0x03, + 0x04, 0x01, 0xfe, 0xfc, 0xfe, 0x03, 0x08, 0x0b, 0x0b, 0x0d, 0x13, 0x18, + 0x1b, 0x17, 0x17, 0x16, 0x1c, 0x24, 0x24, 0x1c, 0x10, 0x08, 0x00, 0x00, + 0xfe, 0xf9, 0xf9, 0xf7, 0xf2, 0xf0, 0xf4, 0xfa, 0xfe, 0x00, 0x02, 0x01, + 0xff, 0xfc, 0xf4, 0xeb, 0xe4, 0xdd, 0xdd, 0xe1, 0xea, 0xf0, 0xfc, 0x0a, + 0x0d, 0x0d, 0x11, 0x11, 0x15, 0x1c, 0x19, 0x10, 0x0c, 0x0a, 0x07, 0x09, + 0x10, 0x14, 0x15, 0x17, 0x19, 0x17, 0x12, 0x0e, 0x0f, 0x10, 0x0c, 0x04, + 0xfa, 0xfb, 0xfc, 0xfc, 0xfe, 0x01, 0xfd, 0xfb, 0xfc, 0xf7, 0xf8, 0xfe, + 0xfe, 0xf8, 0xf6, 0xf6, 0xf8, 0xfe, 0x00, 0xf7, 0xeb, 0xe8, 0xeb, 0xf3, + 0xf9, 0xfe, 0x02, 0x03, 0x08, 0x0d, 0x0e, 0x10, 0x17, 0x1a, 0x1c, 0x18, + 0x10, 0x0e, 0x08, 0xfe, 0xff, 0x01, 0x03, 0x08, 0x08, 0x07, 0x0e, 0x15, + 0x16, 0x18, 0x13, 0x12, 0x16, 0x18, 0x15, 0x07, 0xff, 0xfc, 0xf8, 0xf3, + 0xe9, 0xe5, 0xe4, 0xe0, 0xe8, 0xee, 0xef, 0xfd, 0x04, 0x01, 0x04, 0x03, + 0xff, 0xfc, 0xf7, 0xf1, 0xf6, 0xfd, 0x09, 0x0f, 0x0d, 0x18, 0x23, 0x21, + 0x19, 0x15, 0x10, 0x10, 0x11, 0x0b, 0xfb, 0xf4, 0xf6, 0xf8, 0xfe, 0x01, + 0x00, 0x04, 0x07, 0x07, 0x09, 0x0c, 0x12, 0x10, 0x0a, 0x03, 0xfd, 0xfa, + 0xfe, 0xfd, 0xf8, 0xfe, 0x02, 0x06, 0x04, 0xfd, 0xfa, 0xff, 0x04, 0x02, + 0xfe, 0x00, 0x07, 0x0d, 0x16, 0x12, 0x04, 0xfb, 0xf2, 0xe9, 0xec, 0xf5, + 0xfc, 0xfd, 0xfc, 0xfe, 0x04, 0x0f, 0x1a, 0x1a, 0x12, 0x11, 0x0c, 0x09, + 0x05, 0xfc, 0xfa, 0xfe, 0xff, 0xfb, 0xf5, 0xf6, 0xfb, 0x01, 0x0b, 0x0f, + 0x10, 0x13, 0x15, 0x15, 0x17, 0x14, 0x0f, 0x09, 0x05, 0x05, 0x04, 0x06, + 0x09, 0x04, 0x00, 0x01, 0x03, 0x05, 0x01, 0xfb, 0xff, 0xff, 0xfa, 0xf0, + 0xe3, 0xdc, 0xe3, 0xf0, 0xf8, 0xfb, 0xff, 0x02, 0x09, 0x10, 0x15, 0x18, + 0x15, 0x0d, 0x04, 0x02, 0xfb, 0xf6, 0xf6, 0xf6, 0xf8, 0xff, 0x05, 0x0d, + 0x0d, 0x0d, 0x0f, 0x14, 0x1b, 0x1d, 0x18, 0x14, 0x14, 0x12, 0x15, 0x14, + 0x0c, 0x07, 0x05, 0xff, 0xfd, 0xfc, 0xf7, 0xed, 0xee, 0xf4, 0xf8, 0xfe, + 0x02, 0x05, 0x07, 0x0a, 0x05, 0xfc, 0xf0, 0xe8, 0xeb, 0xf0, 0xf7, 0xf3, + 0xe8, 0xe8, 0xf2, 0xff, 0x0c, 0x10, 0x0f, 0x10, 0x0d, 0x09, 0x08, 0x08, + 0x02, 0x04, 0x0a, 0x0b, 0x0f, 0x14, 0x19, 0x21, 0x28, 0x2b, 0x25, 0x1d, + 0x11, 0x0a, 0x0d, 0x0c, 0x03, 0xf7, 0xf1, 0xef, 0xf4, 0xf7, 0xfd, 0xf4, + 0xee, 0xf1, 0xf3, 0xf9, 0xff, 0x00, 0xff, 0xfb, 0xf8, 0xee, 0xe5, 0xdf, + 0xe3, 0xee, 0xfc, 0x02, 0x06, 0x08, 0x06, 0x0f, 0x1b, 0x23, 0x23, 0x1c, + 0x13, 0x0e, 0x12, 0x12, 0x0f, 0x0a, 0x04, 0xfe, 0xfc, 0xfd, 0x00, 0x04, + 0x05, 0x02, 0x06, 0x0c, 0x11, 0x10, 0x14, 0x15, 0x13, 0x0e, 0x08, 0x04, + 0xfe, 0x02, 0x04, 0xff, 0xf4, 0xe5, 0xdb, 0xdc, 0xe8, 0xf0, 0xf8, 0xfa, + 0x02, 0x06, 0x05, 0x00, 0xf9, 0xf9, 0xf2, 0xf7, 0x00, 0x04, 0x04, 0x0a, + 0x17, 0x1f, 0x29, 0x2c, 0x23, 0x15, 0x08, 0x03, 0x02, 0xfd, 0xf3, 0xf0, + 0xf3, 0xf9, 0xf9, 0xfe, 0x05, 0x09, 0x12, 0x19, 0x18, 0x14, 0x12, 0x14, + 0x0f, 0x07, 0x00, 0xf7, 0xed, 0xed, 0xf6, 0xfc, 0x00, 0x00, 0xfc, 0xf5, + 0xf2, 0xfb, 0x09, 0x0d, 0x0b, 0x08, 0x04, 0x02, 0x00, 0xfd, 0xfa, 0xff, + 0x05, 0x03, 0xfd, 0xf7, 0xfb, 0x04, 0x09, 0x0c, 0x0d, 0x0d, 0x09, 0x0c, + 0x10, 0x11, 0x0b, 0x06, 0x00, 0xf9, 0xf5, 0xf7, 0x01, 0x07, 0x05, 0xfe, + 0xf7, 0xf9, 0x01, 0x06, 0x0e, 0x11, 0x11, 0x10, 0x06, 0xfd, 0x05, 0x14, + 0x12, 0x09, 0x02, 0xfc, 0xf7, 0x01, 0x11, 0x15, 0x15, 0x0f, 0x0a, 0xff, + 0xf9, 0xf9, 0xf6, 0xee, 0xe6, 0xe3, 0xe6, 0xed, 0xf6, 0xfa, 0x01, 0x08, + 0x10, 0x16, 0x13, 0x11, 0x11, 0x0d, 0x04, 0xf8, 0xec, 0xe3, 0xeb, 0xf6, + 0xff, 0x03, 0x0a, 0x13, 0x19, 0x1d, 0x1c, 0x1d, 0x21, 0x21, 0x1d, 0x1a, + 0x14, 0x0d, 0x07, 0x04, 0x06, 0x09, 0x08, 0x00, 0xf1, 0xe7, 0xe8, 0xec, + 0xef, 0xf1, 0xf6, 0xf8, 0xf8, 0xfe, 0x06, 0x03, 0xfc, 0xfc, 0x01, 0x01, + 0xfd, 0xfe, 0x00, 0x01, 0x08, 0x08, 0x00, 0xfb, 0xfb, 0xff, 0x07, 0x0c, + 0x0c, 0x05, 0xfa, 0xf5, 0xfc, 0x00, 0xff, 0x03, 0x0a, 0x11, 0x16, 0x21, + 0x2b, 0x2d, 0x2c, 0x26, 0x1c, 0x11, 0x04, 0xfe, 0xfa, 0xfe, 0x02, 0xfe, + 0xf8, 0xea, 0xe3, 0xea, 0xf9, 0x01, 0xff, 0xfe, 0xf9, 0xfc, 0x02, 0x00, + 0xfb, 0xf2, 0xdf, 0xd6, 0xdd, 0xed, 0x00, 0x06, 0x0a, 0x0d, 0x13, 0x18, + 0x16, 0x19, 0x1e, 0x1d, 0x16, 0x10, 0x0d, 0x01, 0xf9, 0x05, 0x0e, 0x09, + 0x01, 0xfe, 0x00, 0x09, 0x16, 0x13, 0x09, 0x07, 0x09, 0x09, 0x09, 0x10, + 0x16, 0x08, 0x00, 0xff, 0x04, 0x00, 0xf7, 0xf1, 0xec, 0xef, 0xf2, 0xf0, + 0xec, 0xea, 0xea, 0xf5, 0xfe, 0x04, 0x00, 0xf6, 0xf8, 0x02, 0x0b, 0x09, + 0x04, 0x06, 0x0b, 0x18, 0x1f, 0x23, 0x26, 0x27, 0x24, 0x18, 0x11, 0x0b, + 0xfa, 0xe8, 0xe5, 0xea, 0xf0, 0xf4, 0xf6, 0xf4, 0xfd, 0x0e, 0x18, 0x18, + 0x16, 0x14, 0x11, 0x0f, 0x0f, 0x06, 0xfb, 0xf5, 0xf7, 0xf7, 0xf2, 0xf2, + 0xf6, 0xf8, 0x00, 0x06, 0x08, 0x07, 0x04, 0x05, 0x08, 0x0b, 0x10, 0x0d, + 0x01, 0xeb, 0xee, 0x03, 0x0d, 0x0d, 0x03, 0xfe, 0x00, 0x05, 0x06, 0x04, + 0x04, 0x04, 0x02, 0x02, 0xff, 0x02, 0x02, 0x05, 0x08, 0x05, 0x02, 0x01, + 0xff, 0x08, 0x15, 0x1a, 0x15, 0x0b, 0x02, 0xf9, 0xff, 0x0b, 0x13, 0x0b, + 0xfa, 0xf0, 0xfc, 0x07, 0x04, 0xfa, 0xf3, 0xf7, 0xff, 0x01, 0x04, 0x0d, + 0x17, 0x16, 0x12, 0x09, 0x04, 0xff, 0xf6, 0xf5, 0xf7, 0xfb, 0xfe, 0xfd, + 0xfb, 0xfe, 0x07, 0x0e, 0x11, 0x0e, 0x09, 0x09, 0x0a, 0x08, 0x03, 0xf2, + 0xde, 0xda, 0xe5, 0xec, 0xef, 0xf6, 0x04, 0x15, 0x20, 0x21, 0x25, 0x24, + 0x1f, 0x1d, 0x1d, 0x18, 0x16, 0x12, 0x0d, 0x09, 0x0a, 0x0a, 0x02, 0xf8, + 0xf1, 0xf6, 0xf7, 0xf7, 0xf0, 0xed, 0xef, 0xf5, 0xf7, 0xfd, 0x03, 0xf6, + 0xf1, 0xfa, 0x04, 0x09, 0x0b, 0x08, 0x02, 0x04, 0x08, 0x08, 0x07, 0x05, + 0xff, 0xfa, 0xfa, 0xfc, 0xfe, 0x00, 0xfe, 0xfe, 0xfe, 0x05, 0x04, 0x04, + 0x0f, 0x1c, 0x24, 0x23, 0x1e, 0x22, 0x2b, 0x29, 0x1f, 0x18, 0x0b, 0xf3, + 0xe6, 0xed, 0xf3, 0xf1, 0xed, 0xe7, 0xe8, 0xf3, 0xf8, 0xfa, 0x00, 0x00, + 0xfb, 0xfd, 0xfe, 0xfd, 0xfa, 0xfa, 0xf8, 0xf3, 0xf8, 0xfc, 0xfc, 0x00, + 0x10, 0x1b, 0x1b, 0x17, 0x1d, 0x1b, 0x12, 0x10, 0x11, 0x0f, 0xff, 0xed, + 0xeb, 0xfb, 0x03, 0x06, 0x05, 0x06, 0x0b, 0x11, 0x0f, 0x0d, 0x09, 0x05, + 0x04, 0x02, 0x00, 0x00, 0x04, 0x0b, 0x0c, 0x07, 0x01, 0xfd, 0xfe, 0xfc, + 0xfb, 0xfc, 0xf9, 0xfa, 0xf8, 0xf2, 0xf0, 0xf8, 0xfe, 0xfb, 0xf1, 0xe9, + 0xf3, 0x02, 0x0b, 0x0a, 0x07, 0x0b, 0x0f, 0x10, 0x15, 0x1a, 0x18, 0x18, + 0x1d, 0x14, 0x07, 0x02, 0x06, 0xfc, 0xef, 0xf0, 0xf9, 0xfd, 0x00, 0x05, + 0x0f, 0x19, 0x17, 0x11, 0x10, 0x10, 0x0f, 0x0e, 0x08, 0xf7, 0xe6, 0xe3, + 0xe6, 0xea, 0xea, 0xe8, 0xec, 0xf5, 0xff, 0x08, 0x0a, 0x0e, 0x0f, 0x0a, + 0x08, 0x08, 0x0a, 0x11, 0x12, 0x0a, 0x09, 0x11, 0x12, 0x0e, 0x0d, 0x0c, + 0x09, 0x07, 0x02, 0xfc, 0xfa, 0xfc, 0xfa, 0xf8, 0xf1, 0xe5, 0xe0, 0xeb, + 0xfb, 0x03, 0x07, 0x15, 0x1b, 0x13, 0x13, 0x15, 0x13, 0x10, 0x0b, 0x03, + 0xfe, 0xff, 0xfe, 0x04, 0x08, 0x01, 0xfd, 0xfe, 0xff, 0xfb, 0xfe, 0x03, + 0x06, 0x06, 0x04, 0x06, 0x08, 0x0f, 0x15, 0x13, 0x03, 0xf9, 0xf3, 0xeb, + 0xf1, 0xfa, 0x03, 0x04, 0xfe, 0xfc, 0x06, 0x0b, 0x09, 0x06, 0x06, 0x03, + 0xfc, 0xf9, 0xf9, 0xfb, 0xf4, 0xef, 0xef, 0xfa, 0xff, 0x00, 0x0e, 0x1f, + 0x25, 0x25, 0x25, 0x29, 0x21, 0x17, 0x17, 0x0e, 0x00, 0xf9, 0xf6, 0xf3, + 0xfa, 0x01, 0xff, 0xfd, 0xfb, 0xfa, 0xf7, 0xf5, 0xf1, 0xee, 0xf0, 0xf3, + 0xf3, 0xf7, 0xfe, 0x06, 0x04, 0x04, 0x0c, 0x13, 0x13, 0x19, 0x17, 0x0e, + 0x08, 0x06, 0x06, 0x02, 0xfa, 0xf8, 0xf8, 0xec, 0xe1, 0xe5, 0xeb, 0xf4, + 0x00, 0x0d, 0x15, 0x17, 0x17, 0x1b, 0x1f, 0x1f, 0x1d, 0x19, 0x14, 0x12, + 0x12, 0x13, 0x19, 0x14, 0xfb, 0xeb, 0xeb, 0xec, 0xf0, 0xf6, 0xf8, 0xf8, + 0xfe, 0xff, 0xfa, 0xfc, 0x00, 0x05, 0xfe, 0xf2, 0xed, 0xeb, 0xe7, 0xf0, + 0xfe, 0x03, 0x01, 0xfe, 0x00, 0x06, 0x14, 0x1b, 0x1f, 0x19, 0x0a, 0x00, + 0x02, 0x0a, 0x10, 0x0a, 0x02, 0x03, 0x0e, 0x16, 0x18, 0x1f, 0x1f, 0x1b, + 0x13, 0x0a, 0x04, 0xfe, 0xfc, 0xfd, 0xf0, 0xe7, 0xe7, 0xe5, 0xe5, 0xed, + 0xff, 0x09, 0x0b, 0x05, 0xfc, 0xfa, 0xfc, 0xfc, 0xfc, 0xf8, 0xf6, 0xf8, + 0xff, 0x09, 0x0c, 0x0a, 0x07, 0x08, 0x0a, 0x10, 0x14, 0x13, 0x11, 0x11, + 0x11, 0x0f, 0x0c, 0x08, 0x06, 0xfe, 0xf6, 0xf8, 0xf9, 0xec, 0xe5, 0xf7, + 0x09, 0x11, 0x0d, 0x0a, 0x0c, 0x12, 0x18, 0x14, 0x06, 0x01, 0xfe, 0xff, + 0x03, 0x09, 0x00, 0xec, 0xe7, 0xe9, 0xed, 0xf2, 0xf7, 0xfc, 0xfe, 0x01, + 0x0a, 0x15, 0x19, 0x12, 0x06, 0x00, 0xfe, 0x00, 0xfe, 0xfd, 0x04, 0x14, + 0x1b, 0x13, 0x06, 0x04, 0x01, 0x03, 0x00, 0xf9, 0xee, 0xe8, 0xe9, 0xec, + 0xfa, 0xff, 0xfa, 0xf8, 0x00, 0x0c, 0x1e, 0x31, 0x33, 0x26, 0x1a, 0x17, + 0x13, 0x0b, 0x04, 0xfd, 0xf2, 0xea, 0xec, 0xeb, 0xe7, 0xe9, 0xf7, 0x00, + 0x02, 0x04, 0x02, 0xfd, 0x00, 0x04, 0x08, 0x03, 0x01, 0x05, 0x02, 0x0c, + 0x1d, 0x1e, 0x0d, 0xff, 0xfb, 0xff, 0x03, 0x09, 0x06, 0x01, 0x01, 0x02, + 0x04, 0x00, 0xfc, 0xf3, 0xeb, 0xeb, 0xea, 0xea, 0xea, 0xf0, 0x02, 0x10, + 0x14, 0x11, 0x0d, 0x0e, 0x18, 0x1f, 0x1f, 0x1e, 0x15, 0x0b, 0x0c, 0x17, + 0x17, 0x09, 0x00, 0xfc, 0xf9, 0x00, 0x0d, 0x0b, 0x03, 0xfe, 0xfb, 0xf8, + 0xf7, 0xfc, 0xf4, 0xe5, 0xe5, 0xe9, 0xec, 0xee, 0xf1, 0xfb, 0x07, 0x0c, + 0x16, 0x18, 0x0e, 0x06, 0x06, 0x03, 0xfb, 0xf4, 0xee, 0xf0, 0xf7, 0x04, + 0x08, 0x02, 0x04, 0x0b, 0x17, 0x23, 0x2d, 0x30, 0x27, 0x1e, 0x1a, 0x17, + 0x14, 0x0c, 0x01, 0xf8, 0xf4, 0xf2, 0xfa, 0xf8, 0xec, 0xea, 0xf0, 0xf4, + 0xf4, 0xf2, 0xf0, 0xf6, 0xf9, 0xff, 0xfe, 0xfa, 0xfb, 0xff, 0x0b, 0x13, + 0x0e, 0x06, 0xfe, 0xfa, 0xfc, 0x03, 0x08, 0x04, 0x00, 0x00, 0x04, 0x0c, + 0x14, 0x0e, 0x00, 0xf9, 0xf7, 0xfa, 0xfe, 0x00, 0x09, 0x19, 0x20, 0x26, + 0x26, 0x1b, 0x14, 0x11, 0x0a, 0xfe, 0xf7, 0xf8, 0xf1, 0xf6, 0x00, 0x00, + 0xf6, 0xee, 0xec, 0xee, 0xf8, 0x08, 0x17, 0x10, 0x04, 0x02, 0x04, 0x04, + 0x00, 0xf6, 0xec, 0xe8, 0xea, 0xfa, 0xfd, 0xfc, 0x04, 0x0c, 0x11, 0x11, + 0x12, 0x0e, 0x08, 0x05, 0x00, 0xfb, 0xfc, 0xfe, 0x00, 0x08, 0x0f, 0x0f, + 0x0f, 0x0d, 0x0c, 0x0e, 0x14, 0x1c, 0x1c, 0x13, 0x10, 0x0e, 0x0a, 0x08, + 0x00, 0xf2, 0xeb, 0xeb, 0xef, 0xee, 0xef, 0xee, 0xec, 0xef, 0xf2, 0xf4, + 0xf4, 0xf4, 0xf8, 0xfe, 0x00, 0x08, 0x16, 0x10, 0x14, 0x20, 0x1e, 0x15, + 0x0e, 0x0a, 0x09, 0x0b, 0x15, 0x1e, 0x13, 0x03, 0x00, 0xfc, 0xf7, 0xf0, + 0xee, 0xe4, 0xdc, 0xe1, 0xe8, 0xf3, 0xfd, 0x04, 0x0a, 0x12, 0x1b, 0x28, + 0x28, 0x20, 0x16, 0x0a, 0x00, 0xff, 0xfb, 0xf7, 0xff, 0x01, 0x00, 0x00, + 0xfc, 0xf7, 0xf9, 0x03, 0x0d, 0x10, 0x0e, 0x0b, 0x08, 0x0a, 0x06, 0x00, + 0xfc, 0xf8, 0xf4, 0xf6, 0xff, 0x05, 0x01, 0xff, 0x01, 0x01, 0x00, 0x00, + 0xfc, 0xf8, 0xf3, 0xee, 0xf0, 0xf8, 0xf8, 0x00, 0x0c, 0x0c, 0x0a, 0x0c, + 0x14, 0x11, 0x0e, 0x16, 0x1b, 0x18, 0x12, 0x10, 0x10, 0x0c, 0x0a, 0x0c, + 0x08, 0x00, 0xfc, 0xfc, 0xfe, 0xfc, 0xf5, 0xf6, 0xfc, 0x00, 0x04, 0x09, + 0x01, 0xfa, 0xf8, 0xf4, 0xf6, 0xfa, 0xff, 0x00, 0x03, 0x02, 0x00, 0xfe, + 0xfe, 0xfc, 0xfe, 0x05, 0x12, 0x14, 0x0e, 0x08, 0x04, 0xf8, 0xf3, 0xf6, + 0xee, 0xe6, 0xec, 0xf6, 0x04, 0x0e, 0x10, 0x16, 0x1f, 0x24, 0x28, 0x28, + 0x22, 0x12, 0x06, 0x00, 0x00, 0x02, 0x06, 0x0a, 0x08, 0x00, 0xfe, 0xfc, + 0xf4, 0xf2, 0xf8, 0xfc, 0xfc, 0xfc, 0xff, 0x03, 0x00, 0xf6, 0xf8, 0xfa, + 0xee, 0xef, 0xfa, 0x00, 0x00, 0x00, 0x01, 0x00, 0xfe, 0x00, 0xfe, 0xfa, + 0xf4, 0xf0, 0xf0, 0xfa, 0x07, 0x10, 0x1a, 0x24, 0x1f, 0x1c, 0x1e, 0x1c, + 0x19, 0x1b, 0x24, 0x26, 0x24, 0x22, 0x16, 0x07, 0xf9, 0xf3, 0xf6, 0xf2, + 0xe7, 0xde, 0xe6, 0xeb, 0xea, 0xe8, 0xea, 0xee, 0xf0, 0xfc, 0x04, 0x06, + 0x04, 0x00, 0x00, 0xff, 0x00, 0x02, 0x08, 0x0a, 0x04, 0x02, 0x08, 0x0c, + 0x06, 0x0a, 0x12, 0x13, 0x14, 0x18, 0x10, 0xfe, 0xf4, 0xf6, 0xfc, 0xf9, + 0xf7, 0xfe, 0x04, 0x09, 0x08, 0x08, 0x14, 0x17, 0x14, 0x0e, 0x0b, 0x06, + 0x00, 0xfe, 0xfe, 0xf8, 0xfe, 0x06, 0x04, 0x00, 0xfe, 0xfc, 0xfc, 0xfe, + 0xfa, 0xf8, 0xfc, 0xfe, 0x00, 0x02, 0x01, 0xfd, 0xfb, 0x03, 0x03, 0xfe, + 0x06, 0x0d, 0x0d, 0x05, 0x03, 0x07, 0x09, 0x07, 0x07, 0x05, 0x05, 0xfb, + 0xed, 0xe9, 0xeb, 0xf5, 0x05, 0x15, 0x11, 0x07, 0x09, 0x0d, 0x0f, 0x0d, + 0x0f, 0x16, 0x1a, 0x1e, 0x1c, 0x19, 0x10, 0x02, 0xfb, 0xfb, 0xf1, 0xe7, + 0xe9, 0xef, 0xef, 0xeb, 0xf6, 0xfe, 0xfd, 0xff, 0x05, 0x09, 0x11, 0x15, + 0x0b, 0x00, 0xfb, 0x02, 0x0b, 0x13, 0x11, 0x0b, 0x05, 0x03, 0xfb, 0xfb, + 0x05, 0x07, 0x01, 0xfb, 0xfc, 0xf8, 0xef, 0xed, 0xf3, 0xf5, 0xf9, 0xfb, + 0xff, 0x07, 0x08, 0x09, 0x17, 0x21, 0x1a, 0x11, 0x0d, 0x0b, 0x05, 0x01, + 0x00, 0x00, 0x05, 0x0f, 0x11, 0x15, 0x17, 0x0d, 0x07, 0x00, 0xf9, 0xfb, + 0x03, 0x07, 0x06, 0x0b, 0x0f, 0x00, 0xee, 0xef, 0xf2, 0xef, 0x00, 0x00, + 0xc8, 0xcb, 0x0f, 0x20, 0xc0, 0xff, 0x50, 0xd8, 0xbb, 0x2f, 0x40, 0xe0, + 0xdf, 0xf1, 0x0f, 0x04, 0xf7, 0x0a, 0x0b, 0x00, 0xa7, 0x37, 0x28, 0xfb, + 0x13, 0xf4, 0xc2, 0xff, 0x5a, 0x18, 0xe8, 0xf7, 0x55, 0x4e, 0x42, 0x20, + 0x07, 0x3f, 0x00, 0xe2, 0xd7, 0x3f, 0x10, 0xf9, 0x03, 0xf0, 0x0f, 0x00, + 0xdb, 0xff, 0xf0, 0xdf, 0xe8, 0xe6, 0xf0, 0xd7, 0xf2, 0xcc, 0xbd, 0xe2, + 0xc0, 0x89, 0x80, 0xab, 0xa8, 0x9a, 0x97, 0xea, 0xc0, 0xa0, 0xbf, 0x00, + 0xb0, 0xbf, 0x00, 0xca, 0xed, 0xed, 0xf3, 0xf8, 0xef, 0x13, 0x04, 0xe7, + 0x37, 0x02, 0x1f, 0x37, 0x2f, 0x4f, 0x42, 0x3f, 0x58, 0x2d, 0x71, 0x20, + 0x3f, 0x7b, 0x50, 0x3f, 0x50, 0x39, 0x30, 0x2d, 0x4e, 0x20, 0x16, 0x22, + 0x23, 0x14, 0xff, 0x1e, 0x08, 0xca, 0xff, 0x28, 0xe0, 0xe3, 0x1f, 0xc0, + 0xbf, 0x2e, 0xd8, 0xf7, 0xc0, 0xbf, 0x13, 0x08, 0xdb, 0xfe, 0xf1, 0xe8, + 0xdf, 0xe0, 0xe7, 0xd0, 0xcf, 0x0c, 0x0b, 0xf2, 0xe4, 0xbf, 0xe7, 0x10, + 0xc8, 0xc5, 0xe8, 0xe7, 0xcc, 0xc9, 0xb6, 0xcf, 0x03, 0xea, 0xfb, 0x06, + 0xe0, 0xd5, 0xff, 0x00, 0xf1, 0xfb, 0x23, 0x04, 0xdf, 0x2f, 0x1c, 0xf4, + 0x17, 0x38, 0x05, 0x13, 0x21, 0x2f, 0x00, 0x1f, 0x48, 0xf0, 0x37, 0x48, + 0xf2, 0x2f, 0x38, 0x1c, 0x1f, 0x27, 0x37, 0x40, 0xff, 0x52, 0x20, 0x27, + 0x55, 0x64, 0x52, 0x20, 0x3b, 0x55, 0x69, 0x68, 0x17, 0x6f, 0x50, 0x2b, + 0x5b, 0x40, 0x14, 0x12, 0x27, 0x30, 0x02, 0x34, 0xf4, 0x07, 0x16, 0x00, + 0xff, 0xfb, 0x1a, 0xf4, 0xcf, 0x0a, 0x00, 0xe2, 0xe0, 0xbf, 0x0b, 0x00, + 0xde, 0xd9, 0xe1, 0xd8, 0xb6, 0xcf, 0xd5, 0xde, 0xd0, 0xdb, 0xc0, 0xaf, + 0xc8, 0xbd, 0xe5, 0xcc, 0x80, 0xbf, 0xe0, 0xc8, 0xaf, 0xb6, 0xe5, 0xd0, + 0xaf, 0xf7, 0xe4, 0xc8, 0xef, 0xe8, 0xfa, 0xd0, 0x0f, 0xf8, 0xe0, 0xfb, + 0x10, 0xec, 0xfb, 0x11, 0xfd, 0x08, 0x0b, 0x0c, 0xff, 0x0a, 0x15, 0x12, + 0x07, 0x26, 0x09, 0x1a, 0x19, 0x3b, 0x34, 0x1a, 0x34, 0x03, 0x30, 0xf3, + 0x7b, 0x48, 0x00, 0x2f, 0x30, 0x27, 0x37, 0x34, 0x01, 0x2b, 0x50, 0x2c, + 0xf0, 0x37, 0x14, 0x09, 0x0d, 0x2f, 0x08, 0x0f, 0x14, 0xfc, 0x0f, 0x04, + 0xb9, 0xff, 0x20, 0xd4, 0x17, 0xf0, 0xd4, 0xd7, 0x12, 0xf0, 0xd8, 0xdf, + 0xf0, 0xa8, 0xdf, 0xf8, 0xd0, 0xc7, 0xfb, 0xe0, 0xbf, 0xd4, 0xcb, 0xd9, + 0x02, 0xe5, 0xd5, 0xe2, 0xca, 0xcf, 0xeb, 0x04, 0xef, 0xe8, 0xd0, 0xcf, + 0x0c, 0xe2, 0xe7, 0x0f, 0xd0, 0xef, 0xf0, 0xe4, 0xe7, 0x00, 0xbb, 0xff, + 0x08, 0xd5, 0x0d, 0x13, 0xf0, 0xdf, 0x1f, 0x1a, 0x00, 0xdf, 0xf4, 0xfb, + 0x2f, 0x08, 0xdd, 0x0f, 0x05, 0x00, 0xdf, 0x1e, 0xf0, 0x0d, 0x00, 0x02, + 0xfb, 0x2b, 0x00, 0x0b, 0xf6, 0x2d, 0x2c, 0x08, 0xfd, 0x09, 0x1c, 0x0d, + 0x1f, 0x34, 0x1a, 0xea, 0x27, 0x28, 0x00, 0xe5, 0x1f, 0x4c, 0x1c, 0x06, + 0x06, 0x07, 0x10, 0x1b, 0x06, 0xf9, 0x15, 0x02, 0x0c, 0x0f, 0x00, 0xff, + 0x00, 0xcb, 0xff, 0x1c, 0x0a, 0xf8, 0xef, 0x13, 0x14, 0xec, 0xcb, 0xff, + 0xeb, 0x1f, 0x08, 0xdb, 0xff, 0x08, 0xf0, 0xe3, 0x0b, 0xe0, 0xcf, 0x0f, + 0x20, 0xec, 0xcb, 0xfd, 0xfc, 0xf6, 0xff, 0xc8, 0xcf, 0x17, 0xf0, 0xc8, + 0xdf, 0x07, 0xe4, 0xcf, 0xf7, 0xfa, 0xe0, 0xe7, 0xe3, 0xeb, 0xea, 0xe1, + 0xfe, 0xe0, 0xc1, 0xd3, 0x0c, 0xd4, 0xbf, 0xe3, 0xe3, 0xfd, 0xf0, 0xc7, + 0xff, 0xdd, 0xfd, 0xd2, 0xea, 0xc7, 0x17, 0xf4, 0xe1, 0xd3, 0x07, 0x00, + 0xda, 0xff, 0x12, 0xd8, 0xe3, 0xf7, 0x00, 0xef, 0x1c, 0x0c, 0xe0, 0xef, + 0x18, 0x00, 0xf7, 0x17, 0x02, 0xfe, 0x0a, 0xfa, 0x17, 0x14, 0x07, 0x13, + 0x17, 0x10, 0x0f, 0x14, 0x1f, 0x30, 0x16, 0x05, 0x25, 0x2e, 0x25, 0xf8, + 0x1f, 0x28, 0x10, 0x03, 0x2b, 0x2e, 0x18, 0x04, 0x07, 0x19, 0x1d, 0x37, + 0xf0, 0xe7, 0x3f, 0x20, 0xed, 0x12, 0x26, 0xf0, 0xdb, 0x15, 0xf8, 0xfb, + 0x0a, 0xf9, 0x00, 0xf3, 0xe0, 0xff, 0x09, 0xf0, 0xf5, 0xfb, 0xf4, 0xea, + 0xe3, 0x0d, 0x04, 0xee, 0x09, 0xcc, 0xf7, 0x1a, 0xf0, 0xe7, 0xef, 0xfe, + 0xfc, 0xf7, 0x0a, 0xd3, 0xef, 0x06, 0xf4, 0xf0, 0xd5, 0xfb, 0x00, 0xe6, + 0xff, 0xe4, 0xef, 0xf3, 0x00, 0xff, 0xf0, 0xff, 0x02, 0x0a, 0xd4, 0xef, + 0xff, 0x10, 0xdb, 0x13, 0xea, 0xfc, 0xe7, 0xf4, 0x07, 0x00, 0xfc, 0xe8, + 0xef, 0x13, 0x14, 0xe6, 0xf7, 0x27, 0x00, 0xdb, 0x15, 0x10, 0xea, 0x1f, + 0x18, 0xf2, 0xfb, 0x0f, 0x28, 0xf4, 0x0b, 0x22, 0xf8, 0xff, 0x00, 0xfe, + 0x07, 0x18, 0xf2, 0xf7, 0x1b, 0x0d, 0x1b, 0x00, 0xff, 0x2c, 0x06, 0xf2, + 0x0f, 0x22, 0x20, 0xf0, 0x0f, 0x30, 0x08, 0xea, 0x07, 0x1f, 0x22, 0x0c, + 0xe7, 0x17, 0x31, 0xf4, 0x0f, 0x30, 0x04, 0xfe, 0x2d, 0x10, 0xec, 0x13, + 0x14, 0x09, 0x22, 0x08, 0x17, 0x06, 0x03, 0x15, 0x00, 0xf2, 0x1b, 0x10, + 0x11, 0x07, 0x18, 0x02, 0x10, 0x07, 0x19, 0x12, 0xe3, 0x0a, 0x1f, 0x00, + 0xf7, 0x1f, 0x18, 0xfe, 0xfa, 0x13, 0x0c, 0x03, 0x16, 0x06, 0x04, 0x07, + 0x0a, 0x16, 0xe8, 0xff, 0x00, 0xe9, 0xff, 0x00, 0x0b, 0x0e, 0xf0, 0xff, + 0x08, 0xf8, 0xe0, 0xef, 0x0a, 0xfc, 0x06, 0xe9, 0x0b, 0xfa, 0xf0, 0xef, + 0xfe, 0xf8, 0xec, 0xdf, 0xf9, 0xfd, 0xfc, 0xfa, 0xf1, 0xf1, 0xf5, 0xf9, + 0xe0, 0xfb, 0x06, 0xfb, 0xe9, 0xfe, 0xff, 0x00, 0xf5, 0xff, 0x00, 0xf8, + 0xf5, 0x00, 0xe3, 0x0b, 0x18, 0x10, 0x00, 0x07, 0x04, 0x17, 0x00, 0xfb, + 0x09, 0xff, 0x20, 0xf0, 0x17, 0x18, 0xff, 0x1f, 0x20, 0xef, 0x13, 0xfa, + 0x0f, 0x10, 0x1b, 0x32, 0xfd, 0x1f, 0x22, 0x03, 0x09, 0x1b, 0x18, 0x19, + 0x1d, 0x25, 0x0c, 0x01, 0x1f, 0x28, 0x18, 0x05, 0x1e, 0x12, 0x00, 0x0c, + 0x0b, 0x1b, 0x12, 0x10, 0xf7, 0x2a, 0x12, 0xf5, 0x0d, 0x18, 0xec, 0xf7, + 0x0a, 0xff, 0x0e, 0x0c, 0xfd, 0xfe, 0xf0, 0xfb, 0x0a, 0xf1, 0xf7, 0x10, + 0xf0, 0xe7, 0x06, 0xfe, 0xf0, 0xee, 0xff, 0x03, 0xf2, 0xef, 0xff, 0xf0, + 0xdf, 0xff, 0x00, 0xee, 0xef, 0xe0, 0xe7, 0xef, 0xf3, 0xf9, 0xe4, 0xee, + 0xf3, 0xf8, 0xe6, 0xf0, 0xe5, 0xe4, 0xd3, 0xe5, 0x03, 0xfd, 0xec, 0xd7, + 0xef, 0xf8, 0xe9, 0xe6, 0xe9, 0xe6, 0xf3, 0x05, 0xfc, 0xea, 0xf1, 0xf3, + 0xf8, 0xfd, 0xf0, 0xeb, 0xf2, 0x12, 0x00, 0xee, 0xff, 0x08, 0x01, 0xf8, + 0xfb, 0x11, 0x09, 0x04, 0xef, 0x0f, 0x00, 0x03, 0x00, 0x12, 0x0a, 0x08, + 0x0a, 0xf9, 0xfb, 0xff, 0x01, 0x09, 0x12, 0x0e, 0x09, 0x14, 0x07, 0xfc, + 0x07, 0xfa, 0x05, 0x0e, 0x0d, 0xf9, 0x0d, 0x0c, 0xe7, 0xfb, 0x10, 0x02, + 0x03, 0x02, 0xf8, 0x0c, 0xf6, 0xfd, 0xfc, 0x00, 0xf5, 0x03, 0x10, 0xf6, + 0xdf, 0xff, 0x16, 0xf8, 0xef, 0x0b, 0xf8, 0xe2, 0xff, 0xf4, 0xf3, 0xf1, + 0xf5, 0xe6, 0xf3, 0x05, 0xf8, 0xf5, 0xe8, 0xf1, 0xf7, 0xf8, 0xe0, 0xe7, + 0xf8, 0xe7, 0xf3, 0xea, 0xeb, 0x00, 0xf2, 0xdc, 0xdf, 0xf5, 0xe9, 0xf0, + 0xe9, 0xf6, 0x02, 0xe0, 0xef, 0x0a, 0xe5, 0xf8, 0xe3, 0xf5, 0x00, 0xf8, + 0xf0, 0xe0, 0xef, 0x03, 0xec, 0xe5, 0xf3, 0xfe, 0xfc, 0xed, 0x01, 0xf4, + 0xe8, 0xf3, 0x01, 0xfc, 0x04, 0xe1, 0xfd, 0xfa, 0xf2, 0xe7, 0xf5, 0x07, + 0x08, 0xf8, 0xe8, 0xf6, 0xfb, 0x05, 0x01, 0x09, 0xf8, 0xf3, 0xfd, 0x00, + 0xed, 0xfb, 0x06, 0xf4, 0xf8, 0x02, 0xf8, 0xe8, 0xed, 0x0e, 0xfa, 0xf7, + 0x05, 0x07, 0xf0, 0xf3, 0x06, 0xf9, 0xf7, 0x01, 0xfc, 0xfc, 0xfc, 0xfc, + 0x02, 0xf2, 0xf5, 0xfd, 0x02, 0x0f, 0x04, 0xfb, 0xff, 0x0c, 0x02, 0x02, + 0x00, 0xf7, 0x0f, 0x08, 0x07, 0x03, 0x05, 0x0d, 0x00, 0xff, 0x13, 0x00, + 0x0f, 0x04, 0xfb, 0x08, 0xfe, 0x0a, 0x09, 0xfc, 0xfa, 0x03, 0x08, 0xff, + 0x09, 0x03, 0xf0, 0x03, 0x04, 0xfb, 0xf9, 0xee, 0x07, 0x09, 0xf8, 0xfa, + 0xf2, 0xf3, 0xec, 0xee, 0xf7, 0xff, 0x0c, 0xf4, 0xf2, 0xf7, 0x0c, 0xf2, + 0xf2, 0xf2, 0xf4, 0x02, 0x01, 0xf9, 0xf2, 0xf7, 0xf7, 0xf5, 0xf0, 0xfd, + 0x00, 0xf0, 0xf3, 0xf7, 0xf8, 0xf0, 0x03, 0xf4, 0xf9, 0x03, 0xf1, 0xff, + 0xf2, 0xde, 0xff, 0x04, 0xf5, 0xe8, 0xfd, 0x04, 0xfb, 0xfa, 0x03, 0xfb, + 0xf0, 0xf5, 0xfe, 0xfa, 0x05, 0xf8, 0xff, 0x12, 0x00, 0xf3, 0x05, 0x00, + 0xf7, 0x0a, 0x0a, 0xf8, 0x03, 0xfe, 0x0e, 0x0c, 0x02, 0xf6, 0x07, 0x10, + 0xf8, 0x0b, 0x06, 0xf8, 0xf7, 0x03, 0x0a, 0x09, 0x0b, 0x0b, 0x04, 0x02, + 0xf9, 0xf7, 0x0d, 0x06, 0x03, 0x00, 0xff, 0x06, 0x0f, 0x08, 0x07, 0x00, + 0xf9, 0x0b, 0x13, 0x00, 0x03, 0x0a, 0x00, 0x02, 0x05, 0x05, 0x0d, 0x0f, + 0x0f, 0x0c, 0x07, 0x00, 0x02, 0x03, 0x11, 0x16, 0x0c, 0xf6, 0x07, 0x18, + 0x06, 0x04, 0x08, 0x05, 0x15, 0x0e, 0x06, 0xf7, 0x0e, 0x06, 0x02, 0x03, + 0x07, 0x0a, 0x05, 0x00, 0x07, 0x00, 0x02, 0xfa, 0x06, 0x0e, 0x10, 0xfd, + 0xfd, 0x00, 0xf5, 0x03, 0xfa, 0xfc, 0x04, 0x03, 0xfb, 0x00, 0xfc, 0xfc, + 0x03, 0x04, 0x05, 0x01, 0xf6, 0xff, 0x02, 0xf8, 0xf1, 0xfb, 0x15, 0x0e, + 0xf8, 0xf9, 0x10, 0x02, 0xff, 0x06, 0xf0, 0xfd, 0x12, 0xfa, 0x07, 0xfc, + 0xfb, 0x11, 0x14, 0x00, 0xf9, 0x0d, 0x0b, 0x06, 0x00, 0xf5, 0x01, 0x0a, + 0x08, 0x07, 0x08, 0xfb, 0x0b, 0x0b, 0xf9, 0xff, 0x10, 0x0c, 0x14, 0x05, + 0xf7, 0xff, 0x12, 0x0c, 0x09, 0x12, 0x0c, 0xfc, 0x03, 0x00, 0x0f, 0x14, + 0x16, 0x12, 0xf8, 0xfd, 0x13, 0x1c, 0x0c, 0x11, 0x00, 0x02, 0x12, 0x0d, + 0x0f, 0x18, 0x03, 0x09, 0x12, 0x14, 0x08, 0xff, 0x02, 0x0f, 0x11, 0x07, + 0x05, 0x05, 0xfd, 0x17, 0x0c, 0x00, 0x03, 0x0e, 0x00, 0x07, 0x10, 0x07, + 0x00, 0x03, 0x09, 0x05, 0xf0, 0xf5, 0x0f, 0x18, 0x04, 0x04, 0xff, 0x02, + 0x06, 0x00, 0x01, 0x01, 0x03, 0xfc, 0xff, 0x03, 0x03, 0xf6, 0xf9, 0x01, + 0x0a, 0x04, 0x04, 0xf8, 0xfb, 0xfd, 0xf9, 0xfe, 0x00, 0x07, 0x00, 0xfa, + 0x05, 0x09, 0xf8, 0xfb, 0xfa, 0xf7, 0xf9, 0x04, 0x02, 0x02, 0xf7, 0x09, + 0x06, 0xf0, 0xea, 0xff, 0x00, 0xff, 0x10, 0x00, 0xec, 0xf3, 0xfe, 0x07, + 0x03, 0xf6, 0xff, 0xfe, 0xf4, 0xf8, 0xf7, 0x07, 0x05, 0xfc, 0xf2, 0x0b, + 0x0a, 0xf0, 0xf7, 0x09, 0x01, 0x01, 0xf5, 0xff, 0x05, 0x00, 0xf7, 0xfb, + 0xf8, 0x02, 0x00, 0xf4, 0x06, 0x09, 0xfd, 0x02, 0x00, 0x00, 0xf8, 0xfa, + 0xfe, 0xfc, 0xfd, 0x00, 0x01, 0x03, 0x04, 0x08, 0xf6, 0xf5, 0x0e, 0x00, + 0xf6, 0x09, 0x08, 0xf3, 0xff, 0x07, 0x09, 0x06, 0xfd, 0x07, 0x07, 0x05, + 0xff, 0xfd, 0x09, 0x0c, 0x0a, 0x07, 0x0a, 0x02, 0xfa, 0xff, 0x02, 0x0d, + 0x10, 0x08, 0xfb, 0xfd, 0x04, 0x07, 0x08, 0xfa, 0xfe, 0x05, 0xfc, 0xf9, + 0xfb, 0x03, 0x04, 0xf7, 0xf6, 0xf2, 0xf7, 0x04, 0x04, 0xfa, 0xf2, 0xf5, + 0xff, 0xfa, 0xea, 0xef, 0xfc, 0xf4, 0xee, 0x02, 0xf4, 0xef, 0xf1, 0xee, + 0xf9, 0xfe, 0xf7, 0xf1, 0xed, 0xf7, 0xfd, 0xfb, 0xf8, 0xf6, 0xf6, 0xef, + 0xf0, 0xf7, 0x05, 0xfd, 0xf6, 0xef, 0xf7, 0xf7, 0xfa, 0xed, 0xf5, 0xfe, + 0x00, 0xf5, 0xf6, 0xf4, 0xf5, 0xfc, 0xf9, 0xfa, 0xee, 0xf8, 0xf2, 0xf5, + 0xfb, 0x02, 0x04, 0xf4, 0xfb, 0xf0, 0xed, 0xfb, 0x03, 0x02, 0xfc, 0xf0, + 0xfb, 0x07, 0x00, 0xf0, 0xf7, 0x03, 0x02, 0x02, 0x00, 0xff, 0xfe, 0xf8, + 0xfa, 0x03, 0xfe, 0x05, 0x08, 0xfc, 0x05, 0x00, 0xf7, 0xf5, 0xf9, 0x08, + 0x00, 0x00, 0x02, 0x04, 0xf8, 0xf3, 0xf5, 0x09, 0x0a, 0x00, 0xfa, 0xfb, + 0xf8, 0xef, 0xf8, 0xff, 0x02, 0xfd, 0xfd, 0xfc, 0xed, 0xef, 0x01, 0x01, + 0x00, 0xec, 0xeb, 0x07, 0x0c, 0xf2, 0xff, 0x00, 0xf7, 0xfd, 0xfc, 0xf4, + 0xfe, 0x0a, 0xf4, 0xe6, 0x07, 0x0a, 0xf0, 0xf7, 0x04, 0x04, 0x04, 0xf8, + 0xff, 0x00, 0xf9, 0xf3, 0xfa, 0x03, 0x00, 0x03, 0x00, 0xf4, 0xee, 0xf2, + 0x0f, 0x08, 0xf8, 0xea, 0xef, 0x07, 0x04, 0xfd, 0xf6, 0xe6, 0xfd, 0x08, + 0xf1, 0xf5, 0x03, 0xfa, 0xf2, 0xfa, 0xf2, 0xff, 0xfc, 0xfa, 0xf8, 0xf1, + 0xfe, 0xf8, 0xf7, 0x08, 0xf4, 0xf5, 0xfb, 0xf9, 0xf2, 0xfa, 0xf5, 0xf9, + 0xf7, 0xf0, 0xff, 0x09, 0xf4, 0xf1, 0xfe, 0xf8, 0xef, 0x03, 0x00, 0xf8, + 0xff, 0x00, 0xf8, 0xf0, 0xfd, 0x0a, 0xfe, 0xfd, 0xf6, 0xf4, 0x07, 0x02, + 0xf5, 0xfb, 0xfc, 0x06, 0x03, 0xfe, 0x07, 0x0a, 0x00, 0xf2, 0x05, 0x06, + 0xff, 0x0b, 0x0a, 0xfc, 0xff, 0x0d, 0x09, 0x05, 0xfe, 0x0d, 0xf9, 0x06, + 0x04, 0xfe, 0x0d, 0x0c, 0x00, 0xf6, 0x03, 0x06, 0x07, 0x04, 0x05, 0x0d, + 0x08, 0xfa, 0xff, 0xf9, 0xfb, 0x0b, 0x04, 0xff, 0x02, 0x06, 0xfd, 0xff, + 0xfa, 0xff, 0x0a, 0x00, 0xff, 0xff, 0x06, 0x01, 0xfa, 0xf6, 0x0a, 0x00, + 0xf9, 0xff, 0xfe, 0xf2, 0xff, 0x0e, 0xf8, 0xf9, 0xf6, 0xf9, 0x05, 0x01, + 0xf1, 0xf6, 0xff, 0x02, 0xfc, 0xf2, 0xfd, 0xf4, 0xec, 0xfb, 0x09, 0xf6, + 0xf4, 0xfb, 0xfc, 0x00, 0xf4, 0xf5, 0x08, 0xf6, 0xf3, 0x03, 0x02, 0xf6, + 0xf0, 0xf3, 0xfe, 0x08, 0xfb, 0xf8, 0xef, 0xfd, 0x04, 0xf1, 0xff, 0x0b, + 0x00, 0xf2, 0xff, 0x02, 0x05, 0x06, 0x00, 0xf2, 0x07, 0x0e, 0xf8, 0x0b, + 0x0c, 0xf6, 0x05, 0x10, 0x08, 0xfc, 0xf5, 0x0d, 0x12, 0x04, 0xf9, 0x0b, + 0x12, 0x02, 0x08, 0x02, 0x07, 0x11, 0x04, 0x0d, 0x0a, 0x02, 0xfe, 0xfd, + 0xfe, 0x0b, 0x08, 0x03, 0x0f, 0x09, 0xfa, 0xf3, 0x07, 0x03, 0x02, 0x02, + 0xff, 0x09, 0x0a, 0x05, 0x03, 0xff, 0xfd, 0xfc, 0x02, 0xfd, 0x01, 0x08, + 0x00, 0xfa, 0x01, 0x04, 0x00, 0xf7, 0x0c, 0x08, 0xfd, 0x0c, 0x04, 0x01, + 0xf1, 0x07, 0x0a, 0xfc, 0x06, 0x03, 0x07, 0x05, 0x00, 0xf8, 0xfb, 0x04, + 0x00, 0x02, 0xfe, 0x00, 0x05, 0xfc, 0xfa, 0x02, 0x04, 0xf9, 0xff, 0x0a, + 0x02, 0xf0, 0xfc, 0x03, 0x07, 0xfc, 0xfc, 0xf3, 0xff, 0x09, 0xff, 0x05, + 0xf8, 0xfb, 0x09, 0x04, 0xf4, 0xed, 0xff, 0x0b, 0x08, 0x00, 0xf3, 0x05, + 0x08, 0xff, 0x00, 0xee, 0xfa, 0x0e, 0x02, 0xfa, 0x07, 0x06, 0xf4, 0xf5, + 0xf8, 0xff, 0x0b, 0x0a, 0xf4, 0xfd, 0x0b, 0x05, 0xf7, 0x02, 0xfc, 0xfa, + 0xf9, 0xfa, 0x09, 0x0b, 0x09, 0xf8, 0xef, 0x0d, 0x08, 0xf1, 0x0b, 0x10, + 0xfc, 0xf5, 0x07, 0x0e, 0xfa, 0xfb, 0x0e, 0x00, 0x02, 0x04, 0x07, 0x06, + 0x00, 0xff, 0x13, 0x00, 0xf9, 0x05, 0x06, 0x05, 0x05, 0x05, 0x02, 0x00, + 0x03, 0x09, 0x00, 0xf1, 0x05, 0x06, 0x06, 0x0d, 0xfa, 0xfb, 0x02, 0xfd, + 0xf4, 0xff, 0x0a, 0x00, 0xf8, 0xf8, 0xf8, 0xfd, 0x0a, 0xf9, 0xf1, 0xfc, + 0xfa, 0xf9, 0xfe, 0xf9, 0xfa, 0xfc, 0xfb, 0xf6, 0xef, 0xff, 0x00, 0xfd, + 0xf9, 0xfa, 0xfe, 0xf7, 0xf1, 0xf5, 0xf9, 0xfb, 0xff, 0xf8, 0xfa, 0x03, + 0x00, 0xed, 0xf7, 0xf5, 0xff, 0x04, 0xf4, 0xff, 0xff, 0xfb, 0xf5, 0xf9, + 0xf0, 0xf7, 0xfb, 0xf9, 0x0b, 0x04, 0xf3, 0xfa, 0xfc, 0xfb, 0xf0, 0xfd, + 0x0c, 0x01, 0xfa, 0xf0, 0xff, 0x04, 0xfd, 0xfa, 0xf8, 0xfb, 0xfe, 0x0a, + 0x0a, 0x04, 0xf4, 0xfa, 0xff, 0xff, 0x03, 0x02, 0xf7, 0x0d, 0x0c, 0xec, + 0xfd, 0x18, 0xf8, 0xf5, 0x11, 0x06, 0xf4, 0x03, 0x04, 0x02, 0x0a, 0x02, + 0xfd, 0xfd, 0xf6, 0xf7, 0x01, 0x09, 0x0a, 0x05, 0xfa, 0xf6, 0x05, 0x02, + 0x06, 0xf6, 0xfd, 0x04, 0x00, 0xf6, 0x02, 0x04, 0x01, 0xfe, 0xff, 0xfb, + 0xf9, 0xf9, 0xf8, 0xfa, 0xff, 0x06, 0xfe, 0xff, 0x01, 0xfc, 0xf8, 0xf5, + 0xfe, 0x00, 0x06, 0x00, 0xf3, 0xff, 0x01, 0xf5, 0x07, 0x04, 0xf4, 0xff, + 0x00, 0x00, 0xfb, 0xfd, 0x00, 0xff, 0xf2, 0xf9, 0x0c, 0x05, 0x03, 0x08, + 0xf6, 0xfd, 0x02, 0xfc, 0xfe, 0x06, 0x00, 0xf1, 0x09, 0x0c, 0xfc, 0xfa, + 0xf9, 0x03, 0x03, 0x01, 0xf8, 0xf5, 0x0a, 0x0b, 0xf6, 0xf5, 0x06, 0x05, + 0xf3, 0xff, 0x09, 0xfa, 0xff, 0x01, 0xfb, 0x09, 0x08, 0xfe, 0xfa, 0xf5, + 0xff, 0x04, 0xfe, 0xff, 0x06, 0xfa, 0xf9, 0x05, 0x02, 0xfe, 0xf8, 0xfa, + 0x07, 0x06, 0xfa, 0xf4, 0xfd, 0x03, 0xff, 0xf4, 0xf9, 0x0a, 0x04, 0xee, + 0xfd, 0x06, 0x00, 0xfa, 0xfa, 0xed, 0xff, 0x10, 0x04, 0xf4, 0xed, 0xff, + 0x0b, 0x02, 0xf8, 0xf7, 0x01, 0x06, 0x00, 0xfb, 0x09, 0x05, 0x02, 0x05, + 0xfa, 0x00, 0xfe, 0x06, 0x05, 0x0b, 0x08, 0x00, 0xf9, 0x0a, 0x0e, 0x00, + 0x02, 0x0c, 0x00, 0xf7, 0x13, 0x0a, 0x04, 0x06, 0x05, 0xfb, 0xff, 0x06, + 0x10, 0x04, 0xf8, 0xf4, 0xff, 0x0e, 0x04, 0x00, 0xfd, 0xf7, 0x07, 0x06, + 0xf6, 0xfa, 0x0b, 0xfc, 0xff, 0x05, 0xf6, 0xf9, 0x05, 0x05, 0x02, 0xf3, + 0xff, 0x02, 0xf3, 0x07, 0x04, 0xfb, 0xfd, 0x05, 0xfd, 0xf6, 0xf4, 0xfa, + 0xff, 0x08, 0xfc, 0xfb, 0x06, 0x05, 0xf8, 0xff, 0xf8, 0xf2, 0xff, 0x04, + 0xfe, 0x03, 0x03, 0x00, 0xf7, 0xfe, 0xfa, 0xf9, 0x05, 0x04, 0xf7, 0x05, + 0x05, 0xf6, 0xfa, 0x0b, 0x10, 0xfc, 0xff, 0x04, 0x02, 0x06, 0xfa, 0xfb, + 0x0b, 0x02, 0x00, 0xf5, 0x03, 0x10, 0x08, 0x05, 0xfc, 0xff, 0x12, 0x04, + 0x00, 0xf6, 0x05, 0x14, 0x08, 0x06, 0x04, 0xfb, 0x02, 0x03, 0x00, 0xfe, + 0x17, 0x10, 0xfc, 0x09, 0x04, 0xff, 0x03, 0x01, 0xf9, 0xff, 0x03, 0x01, + 0x07, 0x04, 0x07, 0x08, 0xf9, 0xf5, 0xfb, 0x04, 0x00, 0x09, 0x05, 0xf0, + 0x0f, 0x10, 0xf8, 0xf8, 0xf6, 0xff, 0x02, 0x01, 0x00, 0xfb, 0x05, 0x06, + 0xf6, 0xf1, 0xfc, 0xff, 0x07, 0x06, 0xff, 0xfb, 0xfc, 0xfd, 0x02, 0xf8, + 0xf5, 0x06, 0x04, 0xf1, 0xff, 0x0a, 0xf2, 0xee, 0x0b, 0x08, 0xfd, 0xfe, + 0xf6, 0x05, 0x07, 0xfa, 0xfd, 0xfe, 0xf7, 0xff, 0xf4, 0xf5, 0x03, 0x0b, + 0x00, 0xf3, 0x0e, 0x08, 0xf9, 0x01, 0xfe, 0x06, 0xfa, 0xf5, 0xfe, 0x02, + 0x00, 0xf7, 0xff, 0x03, 0x0b, 0x03, 0x02, 0x01, 0x02, 0xfc, 0xf9, 0x09, + 0x05, 0xf8, 0xfe, 0x04, 0xfd, 0xfe, 0xff, 0x07, 0x0e, 0xf8, 0xfb, 0x0c, + 0x03, 0x01, 0xf5, 0xff, 0x0a, 0xf8, 0xf7, 0x04, 0x00, 0xfb, 0x05, 0x01, + 0xf9, 0xfb, 0xfe, 0xf9, 0xfc, 0xfe, 0x04, 0x00, 0xf5, 0xfb, 0x00, 0xfb, + 0x07, 0x00, 0xf0, 0xed, 0x09, 0x02, 0xfb, 0x0d, 0x00, 0xf7, 0x04, 0xfc, + 0xf6, 0xf5, 0x02, 0x00, 0xfe, 0xfd, 0xf9, 0xf5, 0x05, 0x07, 0xf8, 0xf7, + 0x04, 0x02, 0x02, 0xfc, 0xf7, 0x00, 0x01, 0xfc, 0xf5, 0xfd, 0x06, 0x00, + 0xf6, 0xf7, 0x0a, 0x05, 0xf8, 0xfd, 0x0a, 0x06, 0xfd, 0x06, 0x08, 0xf4, + 0xfc, 0x01, 0x0a, 0x00, 0xf7, 0x06, 0x00, 0xfa, 0xfc, 0x00, 0xfc, 0xfe, + 0x05, 0xfe, 0x02, 0x00, 0xff, 0x0a, 0xf5, 0xff, 0x01, 0xf8, 0xf8, 0xf8, + 0x02, 0xff, 0x05, 0xfd, 0x01, 0xf3, 0x05, 0x00, 0xf6, 0xff, 0x00, 0x05, + 0x02, 0xfd, 0x00, 0xf3, 0xfb, 0x09, 0x02, 0xf2, 0xef, 0x05, 0x00, 0xfb, + 0x02, 0xfb, 0xfc, 0xfd, 0xf5, 0xf3, 0xfd, 0x02, 0x02, 0x00, 0xf0, 0xeb, + 0x0e, 0x04, 0xf6, 0xfe, 0xf4, 0xf5, 0x00, 0xf8, 0xfb, 0x05, 0x00, 0xea, + 0xf7, 0xff, 0xfc, 0xf0, 0xef, 0x09, 0x0a, 0xf0, 0xf7, 0x05, 0xfa, 0xfd, + 0x00, 0xf3, 0xfa, 0xf5, 0xfa, 0xfe, 0xfc, 0x04, 0x08, 0xfa, 0xfb, 0x03, + 0xfa, 0xfa, 0xf5, 0x05, 0x02, 0xff, 0xf4, 0xff, 0x08, 0xff, 0x01, 0x03, + 0xf9, 0xfc, 0xfe, 0xfe, 0x06, 0xfa, 0xf3, 0xf9, 0x08, 0x04, 0xfe, 0xfb, + 0xfc, 0xf7, 0x05, 0xfc, 0xf2, 0x03, 0x00, 0xfe, 0xfe, 0xf4, 0xf0, 0xf9, + 0x04, 0xee, 0xff, 0x12, 0xf8, 0xe7, 0x0a, 0x02, 0xf2, 0x07, 0x06, 0xf2, + 0xf7, 0x04, 0x04, 0x00, 0xf0, 0xff, 0x08, 0x00, 0xf8, 0xef, 0xff, 0x05, + 0x01, 0x0b, 0x04, 0xfc, 0xf0, 0xef, 0xff, 0x0b, 0x06, 0xfc, 0xf5, 0x03, + 0x06, 0x00, 0xf1, 0xfe, 0x06, 0x01, 0xfc, 0xf7, 0xff, 0xff, 0x00, 0x03, + 0x04, 0xf8, 0xf6, 0xff, 0x00, 0xfa, 0xfd, 0xfa, 0x06, 0x00, 0xff, 0x03, + 0x00, 0xf5, 0x06, 0x00, 0xfb, 0x04, 0xf8, 0xff, 0x01, 0xfd, 0x04, 0xf6, + 0xff, 0x06, 0xfd, 0x01, 0xfb, 0xf7, 0xfb, 0x00, 0xf8, 0xf2, 0xff, 0x0a, + 0x02, 0xf3, 0xf5, 0x0d, 0x0b, 0xf9, 0xff, 0x03, 0xfd, 0xff, 0x06, 0x02, + 0xf6, 0xff, 0x04, 0xf8, 0x0e, 0x08, 0xfc, 0xfa, 0x06, 0xfe, 0x05, 0x06, + 0x00, 0xf9, 0xfa, 0x02, 0x06, 0xfe, 0x02, 0x0b, 0x00, 0xee, 0x0e, 0x0f, + 0xfd, 0xfd, 0xf8, 0x05, 0x05, 0xf8, 0x0c, 0x00, 0xf6, 0x00, 0x0d, 0x01, + 0x00, 0x02, 0x00, 0xfe, 0xf7, 0xfe, 0x09, 0x00, 0xfb, 0x0a, 0x09, 0xf3, + 0xf4, 0x0c, 0x0b, 0xfc, 0x04, 0x00, 0xfb, 0xfd, 0x01, 0x01, 0xfa, 0xfc, + 0x03, 0x05, 0x00, 0xfd, 0xfd, 0x00, 0x00, 0xf4, 0x00, 0x07, 0x00, 0xfd, + 0x03, 0xfd, 0xfa, 0xfb, 0xf8, 0xfc, 0x05, 0x05, 0xfd, 0xf9, 0x05, 0x00, + 0xf9, 0xff, 0xfb, 0x00, 0x05, 0xfd, 0xf7, 0x01, 0x00, 0x00, 0xfd, 0xfc, + 0x01, 0x00, 0xfa, 0xfb, 0x00, 0xfc, 0x04, 0x04, 0x05, 0x03, 0xfd, 0xf8, + 0x00, 0x05, 0xfd, 0x00, 0x03, 0x01, 0x02, 0xfe, 0xfe, 0x00, 0xf6, 0xfd, + 0x07, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0xfe, 0x00, 0x02, 0x00, 0xfe, + 0x02, 0xfe, 0x00, 0x0d, 0x04, 0x00, 0xf9, 0xfb, 0x01, 0x08, 0x07, 0x04, + 0x00, 0xf7, 0xfd, 0x04, 0x04, 0x00, 0x02, 0xfa, 0x00, 0x06, 0x02, 0xfe, + 0xfa, 0x03, 0x05, 0xfe, 0xfc, 0x05, 0x00, 0xfb, 0x03, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x01, 0xfd, 0x00, 0x05, 0x00, 0xff, 0x01, 0x03, 0x05, 0x00, + 0x00, 0xfe, 0xfd, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, 0xfe, + 0x02, 0x07, 0x00, 0xf9, 0xfe, 0x01, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, + 0xfd, 0x00, 0x06, 0x05, 0xfe, 0xfd, 0xfe, 0x01, 0x02, 0x01, 0x02, 0x02, + 0xfb, 0xfa, 0xfe, 0x01, 0x01, 0x04, 0xfd, 0xfe, 0x03, 0x01, 0xfc, 0xfe, + 0x01, 0x01, 0x00, 0xf9, 0x01, 0x01, 0xfe, 0xfd, 0x00, 0xfd, 0x00, 0x06, + 0x00, 0xf8, 0x02, 0x00, 0xfc, 0x03, 0x00, 0xfe, 0xfd, 0xff, 0xff, 0x01, + 0x00, 0x02, 0xfd, 0xfa, 0xfe, 0x03, 0x05, 0x00, 0xfd, 0x00, 0x00, 0xfd, + 0xfc, 0x01, 0x04, 0x00, 0xfe, 0x03, 0x00, 0xfe, 0x04, 0x01, 0xfe, 0xfe, + 0xff, 0x00, 0x04, 0x00, 0xff, 0xfd, 0x01, 0x02, 0xfe, 0xff, 0xfd, 0x03, + 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0x01, 0xfe, 0xfd, 0xfe, 0x01, 0xff, + 0x00, 0x02, 0xfe, 0xfd, 0x03, 0x00, 0xff, 0xfd, 0xfd, 0x02, 0x00, 0xfe, + 0xfd, 0x00, 0x02, 0xfd, 0x00, 0x01, 0xfd, 0xfe, 0x04, 0x00, 0xff, 0x00, + 0x00, 0x00, 0xff, 0xfe, 0xff, 0xfe, 0xfd, 0x01, 0x02, 0x00, 0xff, 0xff, + 0x00, 0x00, 0xff, 0xff, 0xfd, 0xff, 0x01, 0xff, 0x01, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, + 0x01, 0x01, 0xff, 0xff, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, + 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x01, 0x00, 0xff, 0x01, 0x01, 0xff, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xf4, 0xf6, 0x03, 0x30, 0x32, 0x07, 0xca, + 0xba, 0xfd, 0x20, 0x54, 0x20, 0x01, 0xc9, 0x1b, 0x01, 0xf4, 0x36, 0x20, + 0x54, 0x3b, 0xf2, 0xc9, 0xa3, 0x03, 0x48, 0x49, 0xfd, 0xc1, 0xb3, 0x09, + 0x27, 0x42, 0x0c, 0x03, 0xa3, 0xf4, 0x27, 0x5b, 0xf6, 0xf6, 0xe4, 0x0c, + 0x07, 0x46, 0x44, 0x0e, 0xdc, 0x1c, 0xdb, 0xf9, 0x22, 0xd5, 0xce, 0xcc, + 0xfb, 0xf6, 0x1b, 0xe4, 0xcc, 0xf7, 0xe7, 0xf0, 0xee, 0xd9, 0xcc, 0xd2, + 0xf0, 0x1c, 0xdc, 0xf9, 0xed, 0x09, 0xdb, 0x1b, 0xe4, 0xb1, 0xbe, 0x19, + 0xed, 0xca, 0xff, 0xbe, 0xa1, 0x9f, 0x8f, 0x80, 0xd3, 0x13, 0x0c, 0xcc, + 0xd9, 0xdb, 0xf9, 0x05, 0xf7, 0xd2, 0xce, 0xc3, 0xba, 0xeb, 0xc1, 0xfd, + 0x07, 0xcc, 0xd5, 0xc1, 0x10, 0xd7, 0x17, 0x19, 0x05, 0xd2, 0x03, 0x2e, + 0xe0, 0xf6, 0x13, 0x15, 0x09, 0x22, 0xe5, 0x29, 0x1e, 0x10, 0xf4, 0x1c, + 0x03, 0x22, 0xf6, 0x1c, 0xf2, 0x2e, 0x32, 0x29, 0x07, 0x0a, 0x01, 0x22, + 0x10, 0x1e, 0x15, 0x1b, 0x34, 0x4d, 0x52, 0x49, 0x2d, 0x5b, 0x1b, 0x48, + 0x05, 0x48, 0x37, 0x4f, 0x36, 0x1c, 0x30, 0x30, 0x30, 0x5b, 0x20, 0x2e, + 0x03, 0x42, 0xff, 0x37, 0x42, 0x39, 0x49, 0x27, 0x13, 0x0a, 0x44, 0x34, + 0x58, 0x0a, 0x20, 0x4d, 0x1e, 0x3b, 0x00, 0x10, 0x49, 0x42, 0x03, 0xfb, + 0x0e, 0x3d, 0x20, 0x19, 0x1b, 0xdc, 0x1c, 0x29, 0x1c, 0xf4, 0x22, 0x05, + 0xdc, 0x0c, 0x2e, 0x24, 0x03, 0xe9, 0xc1, 0x01, 0xc9, 0x22, 0x1b, 0xe5, + 0xb3, 0xd7, 0x07, 0xf0, 0xc9, 0xde, 0xcc, 0x03, 0xf4, 0x00, 0xd5, 0x05, + 0xcc, 0xd0, 0xe7, 0xc1, 0xd0, 0xd9, 0xe9, 0xc5, 0xce, 0xd0, 0xb3, 0xca, + 0xc9, 0xca, 0xc0, 0xe9, 0xce, 0x9f, 0x9a, 0xd0, 0xbe, 0xbc, 0xc3, 0xbc, + 0x98, 0xb3, 0xca, 0xd2, 0xaf, 0xcc, 0xa8, 0xcc, 0xc7, 0xc7, 0xbc, 0xc5, + 0xd0, 0xb1, 0xb1, 0xd2, 0xe0, 0xeb, 0xee, 0xbc, 0xca, 0xa5, 0xd5, 0xf6, + 0x09, 0xe4, 0xd0, 0xd9, 0x00, 0xe0, 0xd5, 0xe0, 0xee, 0xf7, 0xd9, 0xf7, + 0xe4, 0xe0, 0xfb, 0xbe, 0xc0, 0x05, 0x17, 0xe7, 0xcc, 0xde, 0xdc, 0xce, + 0xf7, 0x0e, 0x00, 0xed, 0x01, 0xed, 0xf0, 0x0a, 0x07, 0xfb, 0x09, 0xfb, + 0x0a, 0x05, 0x20, 0x1c, 0x07, 0xf4, 0x09, 0x0c, 0x39, 0x27, 0xf2, 0xfb, + 0x1b, 0x3f, 0x2b, 0x42, 0x24, 0x29, 0x17, 0x4b, 0x32, 0x1b, 0x27, 0x51, + 0x48, 0x3b, 0x36, 0x39, 0x2e, 0x27, 0x15, 0x29, 0x3f, 0x5a, 0x2b, 0x22, + 0x25, 0x1e, 0x32, 0x42, 0x2d, 0x05, 0x20, 0x13, 0x22, 0x32, 0x13, 0x03, + 0x15, 0x15, 0x2b, 0x1b, 0x13, 0x1c, 0x27, 0x1b, 0x42, 0x34, 0x27, 0x2e, + 0x2e, 0xed, 0x1c, 0x3b, 0x30, 0x29, 0x3b, 0x32, 0x24, 0x22, 0x2b, 0x07, + 0x1e, 0x39, 0x30, 0x2d, 0x46, 0x40, 0x29, 0x24, 0x32, 0x2d, 0x19, 0x19, + 0x20, 0x1b, 0x17, 0x0c, 0xfb, 0x05, 0x10, 0x00, 0xff, 0x0a, 0xde, 0xfd, + 0x05, 0x0c, 0xee, 0x0c, 0x0c, 0xeb, 0x15, 0x2e, 0x03, 0xdc, 0xe9, 0x0a, + 0x00, 0x24, 0x24, 0xf9, 0x05, 0xff, 0xe2, 0xff, 0x27, 0x22, 0xeb, 0xf9, + 0x2d, 0x0c, 0xf7, 0xeb, 0xe5, 0xfb, 0x13, 0xf0, 0xde, 0xed, 0xe2, 0xca, + 0xce, 0xe7, 0x01, 0x19, 0xfb, 0xc5, 0xaf, 0xe0, 0xee, 0xcc, 0xd0, 0xeb, + 0xfd, 0xf7, 0xdc, 0xc3, 0xac, 0xd0, 0xf2, 0xde, 0xd2, 0xe7, 0xbe, 0xa1, + 0xc0, 0xdb, 0xd9, 0xde, 0xe0, 0xb3, 0x9c, 0xc5, 0xdc, 0xdb, 0xc9, 0xcc, + 0xb8, 0xcc, 0xe9, 0xee, 0xc9, 0xb3, 0xb7, 0xba, 0xc0, 0xdc, 0xf7, 0xd9, + 0xc9, 0xcc, 0xc3, 0xb3, 0xdb, 0xeb, 0xe5, 0xdb, 0xd3, 0xc9, 0xc5, 0xee, + 0xf6, 0xe9, 0xe2, 0xcc, 0xba, 0xd9, 0x03, 0xe5, 0xbc, 0xb8, 0xd3, 0x09, + 0x01, 0xca, 0xb1, 0xd5, 0xf2, 0xd0, 0xce, 0xdc, 0xd9, 0xf2, 0x03, 0xd9, + 0xc5, 0x00, 0x0e, 0x05, 0xf4, 0x07, 0x05, 0xfb, 0x0a, 0x05, 0xf0, 0x03, + 0x24, 0x24, 0x09, 0xed, 0xee, 0x05, 0x1b, 0x10, 0x17, 0x1e, 0x10, 0xfd, + 0x19, 0x13, 0xff, 0x22, 0x20, 0x01, 0x17, 0x2e, 0x1b, 0x05, 0x05, 0xf4, + 0xf6, 0x00, 0x17, 0x17, 0x07, 0x0a, 0x03, 0x0e, 0x22, 0x34, 0x29, 0x01, + 0x15, 0x37, 0x46, 0x44, 0x37, 0x25, 0x2e, 0x3b, 0x22, 0x17, 0x1c, 0x0e, + 0x22, 0x3b, 0xf9, 0x00, 0x3d, 0x46, 0x0a, 0xf0, 0x15, 0x1e, 0x30, 0x4d, + 0x24, 0x0a, 0x27, 0x34, 0x13, 0x17, 0x42, 0x37, 0x29, 0x29, 0x25, 0x1e, + 0x20, 0x29, 0x19, 0x00, 0x01, 0x10, 0x39, 0x3f, 0x19, 0xfd, 0x39, 0x4d, + 0x27, 0x10, 0x17, 0x24, 0x01, 0xfd, 0x03, 0x12, 0x24, 0x20, 0x17, 0x1b, + 0x0c, 0xeb, 0xf4, 0x17, 0x24, 0x0c, 0x13, 0x27, 0xf7, 0xeb, 0x17, 0x2e, + 0x0a, 0x0c, 0x29, 0x0a, 0x01, 0x17, 0x34, 0x27, 0x13, 0xf7, 0xee, 0x15, + 0x24, 0x0e, 0x13, 0x07, 0xeb, 0xee, 0xff, 0xff, 0x12, 0xfd, 0x00, 0xf9, + 0xd3, 0xde, 0x00, 0x1b, 0x13, 0xe0, 0xd2, 0xdc, 0xe4, 0x09, 0x0c, 0xcc, + 0xc5, 0x01, 0x1b, 0x12, 0xe0, 0xc5, 0xc5, 0xe0, 0xeb, 0xf6, 0x03, 0xed, + 0xe5, 0x19, 0xf4, 0xc9, 0xee, 0x2e, 0x03, 0xe2, 0xd5, 0xd0, 0xe2, 0xff, + 0xfd, 0xe0, 0xe5, 0xe9, 0xed, 0xf9, 0xe2, 0xba, 0xaf, 0xcc, 0xf4, 0x05, + 0xfd, 0xcc, 0xb1, 0xd3, 0x03, 0x01, 0xce, 0xb8, 0xe9, 0xe0, 0xf0, 0xf6, + 0xb3, 0xb5, 0xe7, 0xff, 0x07, 0xe5, 0xd5, 0xd0, 0xf2, 0x17, 0xf2, 0xe4, + 0xf2, 0xfd, 0xdb, 0xd7, 0xde, 0xc5, 0xbe, 0xf2, 0x01, 0xe2, 0xe7, 0x1b, + 0xe2, 0xcc, 0xfb, 0xff, 0xba, 0xca, 0xff, 0x17, 0x03, 0xce, 0xc5, 0xf0, + 0x19, 0x09, 0xeb, 0xcc, 0xcc, 0xfb, 0x1b, 0x12, 0xd9, 0xd3, 0x19, 0x17, + 0xe0, 0xc3, 0xd7, 0x09, 0x1b, 0x05, 0xce, 0xd2, 0xf2, 0x13, 0x24, 0x07, + 0xcc, 0xd3, 0x05, 0xfd, 0xd7, 0x2e, 0x17, 0xdc, 0xee, 0x1b, 0xf0, 0x05, + 0x0a, 0xe7, 0x00, 0x05, 0xe7, 0xfd, 0x07, 0x1c, 0xfd, 0xd9, 0xd5, 0xf7, + 0x1b, 0x29, 0x1c, 0xe7, 0xd2, 0xe9, 0x29, 0x36, 0x0e, 0xf0, 0x0c, 0xff, + 0xe9, 0xe0, 0xe7, 0x01, 0x24, 0x27, 0xf4, 0xce, 0xe4, 0x05, 0x1e, 0x2b, + 0x03, 0xd5, 0xe5, 0x1e, 0x36, 0x19, 0xee, 0xde, 0xe2, 0x1b, 0x2d, 0x12, + 0x00, 0xde, 0xd9, 0x10, 0x24, 0x01, 0x00, 0x1e, 0x0e, 0x01, 0xfb, 0xd3, + 0xf2, 0x27, 0x34, 0x1b, 0xff, 0x05, 0xe9, 0xf9, 0x15, 0xf6, 0xf6, 0x34, + 0x29, 0xe5, 0xd0, 0x03, 0x12, 0x12, 0x39, 0x0c, 0xdb, 0xff, 0x40, 0x3d, + 0x0e, 0xe5, 0xe4, 0x0a, 0x3d, 0x2d, 0x0e, 0xf0, 0xd9, 0xfb, 0x20, 0x30, + 0x39, 0x13, 0xfb, 0xed, 0x12, 0x2b, 0x10, 0xfb, 0x1b, 0x39, 0x03, 0xfd, + 0x0e, 0x01, 0x1c, 0x0c, 0xd7, 0xf4, 0x1c, 0x25, 0x22, 0x10, 0xe4, 0x01, + 0x39, 0x42, 0x12, 0xed, 0xf2, 0x03, 0x10, 0x2d, 0x15, 0x0a, 0x15, 0xf6, + 0x15, 0x3f, 0xfd, 0xd9, 0x01, 0x2b, 0x1e, 0x07, 0x29, 0x19, 0x09, 0x51, + 0x20, 0xf7, 0xf0, 0x20, 0x3f, 0x30, 0x1b, 0x07, 0xfd, 0x07, 0x24, 0xf0, + 0xe4, 0x0e, 0x24, 0x2e, 0x01, 0xdb, 0x0a, 0x2e, 0x3d, 0x2d, 0xfb, 0xe7, + 0xf4, 0x27, 0x3d, 0x0c, 0xdb, 0x13, 0x22, 0x12, 0x40, 0x25, 0xee, 0xf7, + 0x3b, 0x13, 0xeb, 0x37, 0x46, 0x19, 0x09, 0x05, 0xee, 0xf0, 0x25, 0x36, + 0xf7, 0xd5, 0xee, 0x0c, 0x12, 0x22, 0x24, 0xf0, 0xd5, 0xee, 0x24, 0x22, + 0xe9, 0xd0, 0xfb, 0xff, 0xff, 0x2b, 0x15, 0xe0, 0xce, 0x07, 0x15, 0xd3, + 0x01, 0x2d, 0x0e, 0xf4, 0xed, 0xdc, 0xde, 0x10, 0x25, 0x17, 0xf4, 0xe9, + 0xd9, 0xdc, 0x00, 0x01, 0xd9, 0xc7, 0x05, 0x0e, 0xce, 0xb3, 0xcc, 0xed, + 0x03, 0x12, 0xe9, 0xba, 0xcc, 0x07, 0x15, 0xe4, 0xb7, 0xcc, 0xf9, 0x0e, + 0xf6, 0xc7, 0xaf, 0xc0, 0xf9, 0x03, 0xd0, 0xb7, 0x03, 0xfd, 0xc7, 0xae, + 0xd3, 0x00, 0x09, 0xfd, 0xcc, 0xb8, 0xce, 0x0a, 0x13, 0xe7, 0xca, 0xcc, + 0xc5, 0xd2, 0x01, 0x03, 0xcc, 0xae, 0xc0, 0xe4, 0xf2, 0xee, 0xf0, 0xd5, + 0xba, 0xdc, 0x0e, 0xee, 0xb1, 0xd7, 0x19, 0xfb, 0xcc, 0xc7, 0xd2, 0xd0, + 0xf4, 0x0e, 0xde, 0xae, 0xd9, 0xff, 0x07, 0xf6, 0xce, 0xde, 0x13, 0x17, + 0xee, 0xd2, 0xed, 0xf7, 0xd7, 0x0a, 0x0a, 0xd5, 0xdb, 0xf9, 0xf2, 0xd2, + 0xb7, 0xd9, 0xfb, 0x0c, 0x10, 0xf2, 0xd5, 0xc5, 0xff, 0x22, 0x0e, 0xdc, + 0xc0, 0xe0, 0x20, 0x1b, 0xee, 0xcc, 0xde, 0x01, 0x1e, 0xfb, 0xc9, 0xe5, + 0x1e, 0x17, 0xd9, 0xc3, 0xf7, 0x29, 0x22, 0xff, 0xd9, 0xd0, 0xeb, 0x17, + 0x25, 0x12, 0xdc, 0xce, 0xd3, 0x00, 0x07, 0x03, 0x19, 0x1c, 0xe2, 0xdb, + 0x05, 0x25, 0xf6, 0xd2, 0x03, 0x2d, 0x00, 0xee, 0x12, 0x12, 0x13, 0x17, + 0x03, 0xd9, 0xf9, 0x32, 0x1b, 0xe2, 0xd5, 0x09, 0x37, 0x2b, 0xff, 0xe4, + 0xe9, 0xfd, 0xf9, 0x27, 0x1e, 0xe4, 0xfb, 0x3f, 0x1e, 0xe9, 0xdb, 0xf6, + 0x25, 0x32, 0x27, 0xfb, 0xe4, 0xee, 0x20, 0x39, 0x36, 0x15, 0x0e, 0xee, + 0xe5, 0x13, 0x40, 0x1e, 0xf6, 0x15, 0x32, 0xfd, 0xee, 0x22, 0x42, 0x07, + 0xd9, 0xf2, 0x27, 0x40, 0x3d, 0x0c, 0xeb, 0xf2, 0x15, 0x46, 0x3b, 0x19, + 0xee, 0xf2, 0x24, 0x49, 0x15, 0xeb, 0x20, 0x40, 0x05, 0xe4, 0x07, 0x29, + 0x39, 0x3b, 0x0c, 0xe7, 0x07, 0x3d, 0x3f, 0x1b, 0x1b, 0x20, 0xe4, 0x17, + 0x46, 0x46, 0x19, 0x01, 0xf9, 0xf9, 0x05, 0x1e, 0x3f, 0x24, 0xe9, 0x07, + 0x17, 0x13, 0x39, 0x2e, 0x19, 0x1b, 0xfb, 0xee, 0x22, 0x3f, 0x42, 0x17, + 0xf4, 0xfb, 0x2d, 0x4b, 0x19, 0xee, 0xf9, 0x2b, 0x12, 0xf2, 0x2e, 0x49, + 0x24, 0xf7, 0xeb, 0xfd, 0x2b, 0x00, 0xe2, 0x1c, 0x3d, 0x17, 0xdc, 0xde, + 0xf9, 0x1e, 0x32, 0x12, 0xd9, 0xd7, 0x05, 0x2b, 0x2d, 0x07, 0xd9, 0x03, + 0x29, 0xe9, 0xd9, 0x20, 0x39, 0x1c, 0xf2, 0xe2, 0xf2, 0x27, 0x25, 0xf2, + 0xd0, 0xde, 0x0e, 0x20, 0x1c, 0x17, 0xee, 0xd7, 0xf0, 0x34, 0x1c, 0xe2, + 0xe5, 0xfb, 0xcc, 0xe2, 0x00, 0x09, 0x15, 0x07, 0xd0, 0xc7, 0x01, 0x20, + 0x05, 0xeb, 0x25, 0x09, 0xca, 0xe2, 0x01, 0x20, 0x29, 0xf7, 0xd5, 0xe4, + 0x25, 0xfd, 0xce, 0x13, 0xf4, 0xb3, 0xe5, 0x05, 0x09, 0x1b, 0xeb, 0xc1, + 0xf6, 0x09, 0xce, 0x0a, 0x20, 0xee, 0xc0, 0xd9, 0x0e, 0x15, 0x0a, 0x00, + 0xe2, 0xd0, 0xca, 0xf4, 0xf4, 0xfd, 0x22, 0xee, 0xc5, 0xd0, 0xfd, 0x1c, + 0xee, 0xc1, 0xeb, 0x17, 0xd9, 0xb3, 0xdc, 0x0c, 0xfd, 0xf0, 0xf9, 0xc1, + 0xce, 0x00, 0x17, 0xeb, 0xb8, 0xce, 0xf2, 0xfb, 0x13, 0x01, 0xd7, 0xde, + 0xe5, 0xbe, 0xf4, 0x17, 0x0e, 0xe5, 0xdb, 0xce, 0xbe, 0xeb, 0x0e, 0x13, + 0xee, 0xc9, 0xcc, 0xc9, 0xf2, 0x17, 0x07, 0xd5, 0xba, 0xcc, 0x01, 0x07, + 0xe7, 0xce, 0xae, 0xd0, 0xfb, 0x0c, 0xee, 0xb5, 0xd7, 0x15, 0xf2, 0xb3, + 0xd0, 0x0e, 0x19, 0xff, 0xd5, 0xcc, 0xc7, 0xfd, 0x1e, 0xf2, 0xbc, 0xc3, + 0xe0, 0x07, 0x12, 0xdc, 0xbe, 0x01, 0x13, 0xdc, 0xf6, 0x12, 0xc9, 0xc5, + 0xff, 0x1e, 0xf7, 0xde, 0x0e, 0x09, 0xde, 0xee, 0xf9, 0xd7, 0xe0, 0x0c, + 0x20, 0xf4, 0xc5, 0xde, 0x15, 0x24, 0xf2, 0xcc, 0xd3, 0xe9, 0x00, 0x09, + 0xe0, 0xe7, 0x20, 0x15, 0xed, 0xc9, 0xd3, 0x03, 0x1b, 0x1e, 0xf7, 0xc9, + 0xd0, 0x03, 0x17, 0xf4, 0x30, 0x20, 0xe7, 0xd2, 0xe9, 0x15, 0x34, 0x19, + 0xeb, 0xe2, 0xed, 0xf9, 0xfb, 0x1c, 0x12, 0xe4, 0xd0, 0x01, 0x22, 0x2b, + 0x19, 0xf4, 0xdc, 0xee, 0x29, 0x36, 0x00, 0xd9, 0xd5, 0xff, 0x25, 0x2b, + 0x19, 0xff, 0x09, 0xe7, 0xf7, 0x3b, 0x1e, 0xe4, 0x05, 0x36, 0xe9, 0xe5, + 0x25, 0x37, 0xee, 0xd7, 0xf4, 0x0a, 0xf6, 0x0e, 0x2b, 0x12, 0xf9, 0x0e, + 0x25, 0xf7, 0x13, 0x27, 0xed, 0x0c, 0x17, 0x01, 0x27, 0x4d, 0x1b, 0x03, + 0xff, 0x13, 0x15, 0x34, 0x0e, 0xee, 0x19, 0x30, 0xf9, 0xe5, 0x15, 0x40, + 0x19, 0xe0, 0xe2, 0x12, 0x32, 0x37, 0x27, 0xf2, 0xfd, 0x05, 0x25, 0x3d, + 0xff, 0x01, 0x3d, 0x25, 0xf0, 0xf6, 0x3b, 0x25, 0xf0, 0x2d, 0x19, 0xe0, + 0x10, 0x3b, 0x2e, 0x12, 0x15, 0xff, 0x0c, 0x4d, 0x20, 0xf0, 0x15, 0x44, + 0x15, 0xfd, 0x39, 0x1b, 0xf2, 0x2e, 0x4b, 0x2d, 0x00, 0x01, 0x40, 0x34, + 0xf0, 0xf9, 0x07, 0x05, 0x22, 0x3d, 0x2d, 0xf4, 0xf9, 0x30, 0x3b, 0x01, + 0xe2, 0x10, 0x3b, 0x15, 0xfb, 0x44, 0x25, 0xed, 0x05, 0x19, 0x03, 0x2b, + 0x19, 0xe0, 0xfb, 0x19, 0x2d, 0x2e, 0x03, 0xde, 0x03, 0x36, 0x20, 0xe9, + 0xde, 0x09, 0x2e, 0x03, 0xe5, 0x34, 0x22, 0xe7, 0xfd, 0x0e, 0xcc, 0xfd, + 0x36, 0x10, 0xd7, 0xfd, 0xf2, 0x22, 0x2b, 0xff, 0xd7, 0xde, 0x15, 0x34, + 0x09, 0xd9, 0xd5, 0x07, 0x36, 0xf9, 0xcc, 0xdb, 0xf4, 0x07, 0x15, 0xd7, + 0xbc, 0xe5, 0x07, 0x07, 0xf4, 0xf0, 0xd3, 0xc1, 0xf6, 0x10, 0xe2, 0xb5, + 0xf4, 0x09, 0xeb, 0xdb, 0xfd, 0x1b, 0x0c, 0xed, 0xde, 0xc3, 0xd5, 0x03, + 0x12, 0x17, 0xed, 0xd2, 0xbe, 0xe0, 0x19, 0xff, 0xca, 0xc1, 0xf9, 0x1b, + 0xde, 0xaf, 0xe5, 0xf7, 0xb1, 0xf9, 0x07, 0xca, 0xdb, 0x15, 0xeb, 0xc9, + 0xf2, 0x20, 0xe7, 0xbc, 0xc9, 0xeb, 0xf0, 0x00, 0xe4, 0xbe, 0xfb, 0x17, + 0xf7, 0xce, 0xba, 0xd7, 0x0c, 0xfd, 0xe5, 0x09, 0xe9, 0xc5, 0xe2, 0xfd, + 0xd3, 0xc7, 0x0e, 0x01, 0xba, 0xd5, 0x15, 0x12, 0xe5, 0xba, 0xca, 0xf9, + 0x19, 0x13, 0xee, 0xd3, 0xe4, 0xf6, 0xce, 0xf2, 0x20, 0x05, 0xe9, 0xfb, + 0xd3, 0xee, 0x0a, 0xf4, 0xcc, 0xd3, 0x07, 0x24, 0xf9, 0xd7, 0x1c, 0x05, + 0xc1, 0xe0, 0x13, 0x27, 0x0a, 0xee, 0xe9, 0xd7, 0xe5, 0xf6, 0x09, 0x24, + 0xfd, 0xcc, 0xf4, 0x25, 0x09, 0xf4, 0x01, 0xeb, 0xe9, 0xf7, 0x07, 0x15, + 0x1c, 0xe5, 0xd3, 0xf4, 0x10, 0x20, 0x2d, 0x07, 0xe0, 0x01, 0x34, 0x07, + 0x03, 0x15, 0x10, 0xe9, 0xf4, 0x12, 0x05, 0xeb, 0x0c, 0xf6, 0xdb, 0x15, + 0x2b, 0x0a, 0xe4, 0xe5, 0x05, 0x30, 0x1b, 0xf4, 0xd9, 0xe4, 0x00, 0x09, + 0x27, 0x17, 0xde, 0xe4, 0x0e, 0x05, 0xf7, 0x25, 0x0a, 0xde, 0xdb, 0x09, + 0x2b, 0x2d, 0x03, 0xd5, 0xe2, 0x15, 0x2d, 0x1b, 0x09, 0x03, 0xe4, 0x05, + 0x27, 0xf0, 0xe2, 0x1b, 0x15, 0xe5, 0xdb, 0x0e, 0x24, 0xf7, 0xeb, 0x2e, + 0x15, 0xd9, 0xde, 0x0e, 0x2e, 0x20, 0xfd, 0xf0, 0xdb, 0xf4, 0x01, 0x17, + 0x17, 0xce, 0xd9, 0x0c, 0x1c, 0xe0, 0xf4, 0x15, 0x03, 0x0e, 0xd5, 0xee, + 0x2b, 0x2b, 0x07, 0xe4, 0xdc, 0xe9, 0x15, 0x29, 0x07, 0xd3, 0xd5, 0x09, + 0x30, 0x19, 0x00, 0xf0, 0xd7, 0x00, 0x20, 0x03, 0xe7, 0x27, 0x09, 0xe0, + 0x07, 0x20, 0xe5, 0x07, 0x2e, 0xfb, 0xdb, 0xe0, 0x19, 0x29, 0xff, 0xd7, + 0xf0, 0x24, 0xf0, 0xd5, 0x20, 0x19, 0xe4, 0xe0, 0x25, 0x10, 0xd7, 0xe2, + 0x1c, 0x36, 0x1e, 0xf6, 0xe2, 0xe9, 0xf4, 0xed, 0x25, 0x15, 0xdc, 0xed, + 0x32, 0x19, 0xd7, 0xdb, 0x1c, 0x29, 0xee, 0xd0, 0x00, 0x2b, 0x00, 0xd0, + 0x0c, 0x24, 0x00, 0xe0, 0xf6, 0x1e, 0x24, 0xf4, 0xd0, 0xf7, 0x2b, 0x34, + 0x20, 0xeb, 0xdb, 0xe5, 0x24, 0x30, 0x13, 0xde, 0x20, 0x3d, 0x00, 0xf2, + 0x13, 0xf6, 0xe9, 0x2d, 0x1b, 0xd7, 0xed, 0x2d, 0x24, 0xd5, 0xf7, 0x19, + 0x01, 0x34, 0xff, 0xd3, 0xfb, 0x34, 0x24, 0xe7, 0xdc, 0x25, 0x19, 0xd5, + 0x20, 0x2b, 0xe4, 0xe7, 0x2b, 0x3d, 0x17, 0xee, 0xde, 0x07, 0x34, 0xf7, + 0xf9, 0x30, 0x19, 0xd5, 0xed, 0x30, 0x3b, 0x0c, 0xe9, 0x13, 0x09, 0xf2, + 0x09, 0x36, 0x19, 0xe5, 0xdb, 0xf4, 0x2b, 0x32, 0x10, 0xe4, 0xdc, 0xe7, + 0x1c, 0x2b, 0x25, 0xf0, 0xdb, 0xde, 0x03, 0x07, 0xf6, 0x05, 0x15, 0xe2, + 0x12, 0x3b, 0xed, 0x00, 0x24, 0xdb, 0xd2, 0x05, 0x36, 0x2d, 0x01, 0xd9, + 0xd3, 0xf4, 0x24, 0x17, 0x00, 0x0c, 0xf6, 0xd7, 0x22, 0x27, 0xf0, 0xd2, + 0xff, 0x30, 0x2b, 0x00, 0xe7, 0xde, 0xe5, 0x05, 0x25, 0x20, 0xff, 0xde, + 0xd3, 0xd0, 0xf4, 0xfb, 0xf9, 0x19, 0x09, 0xe7, 0xdb, 0x05, 0x27, 0xff, + 0xd2, 0xd2, 0x09, 0x0a, 0xf2, 0x24, 0xed, 0xce, 0xc9, 0xf2, 0x19, 0x1e, + 0xfd, 0xc5, 0xc7, 0xf0, 0x0c, 0xfb, 0x12, 0x19, 0xed, 0xde, 0xf6, 0x00, + 0xd7, 0xf7, 0x24, 0xf7, 0xbe, 0xdb, 0x13, 0x20, 0x03, 0xee, 0xe4, 0xd3, + 0x05, 0x25, 0x0a, 0xdc, 0xd3, 0x01, 0x1c, 0xe9, 0xf9, 0x25, 0xe5, 0xd0, + 0x0a, 0x39, 0x0e, 0xe7, 0xe5, 0xd7, 0xe9, 0x07, 0x13, 0xf7, 0xfb, 0x01, + 0xc5, 0xe0, 0x10, 0x20, 0xe5, 0xbc, 0xe7, 0x19, 0x07, 0xc5, 0xde, 0x05, + 0x01, 0xed, 0xed, 0x13, 0xf7, 0xdc, 0x0e, 0x25, 0x0e, 0x03, 0xeb, 0x0a, + 0x30, 0xee, 0xde, 0x0e, 0x32, 0xf4, 0xe5, 0xe9, 0xf4, 0xf7, 0xf6, 0x17, + 0xdc, 0xc9, 0xf9, 0x1e, 0x0a, 0xc9, 0xc5, 0xf7, 0x1c, 0xf6, 0xbe, 0xfb, + 0x13, 0xf0, 0xfd, 0xf9, 0xc5, 0xfb, 0x20, 0xfb, 0xd0, 0xf0, 0x2e, 0xf6, + 0xc5, 0xf9, 0x17, 0xf6, 0xcc, 0xf7, 0x2e, 0xf9, 0xd2, 0xf2, 0x2b, 0x07, + 0xe0, 0xdc, 0xe4, 0x13, 0x12, 0xdc, 0xc0, 0xf0, 0x19, 0xfd, 0xf6, 0xfd, + 0xd5, 0xe7, 0x0e, 0x12, 0xd9, 0xd0, 0x10, 0xfb, 0xd0, 0x03, 0x17, 0xe2, + 0xf6, 0x22, 0xf7, 0xd5, 0xed, 0x24, 0x17, 0xe4, 0xfd, 0x1b, 0xdc, 0xd2, + 0x00, 0x24, 0x0a, 0xd9, 0xdb, 0x05, 0x22, 0x03, 0xe7, 0x05, 0xf0, 0xd3, + 0x10, 0x2d, 0x15, 0xeb, 0xee, 0xf2, 0xd5, 0xff, 0x1b, 0x24, 0x00, 0xe2, + 0xdc, 0xde, 0x0e, 0x2b, 0x1b, 0xe7, 0xce, 0xe7, 0x0e, 0x1e, 0x07, 0xf9, + 0x17, 0xf2, 0xe5, 0x1c, 0x2b, 0x00, 0xe5, 0x17, 0x22, 0xde, 0x0e, 0x3d, + 0x12, 0xeb, 0xe4, 0xf7, 0x15, 0xeb, 0x09, 0x32, 0x24, 0x0c, 0xe7, 0x07, + 0x3f, 0x12, 0xe2, 0x1e, 0x27, 0xe5, 0x0c, 0x32, 0x00, 0xdc, 0x10, 0x3b, + 0x1e, 0xff, 0x19, 0x12, 0xe4, 0x25, 0x46, 0x12, 0xe9, 0xe9, 0x01, 0x24, + 0x1c, 0xed, 0xf9, 0x36, 0x10, 0x24, 0x37, 0xfb, 0x0c, 0x42, 0x15, 0xe7, + 0xf7, 0x2b, 0x32, 0x0e, 0x1c, 0xf4, 0xdc, 0x0e, 0x42, 0x2d, 0xf2, 0xd5, + 0xf6, 0x2e, 0x36, 0x1b, 0xf4, 0xe2, 0xde, 0x0c, 0x1e, 0x17, 0x07, 0x1b, + 0xfd, 0xe0, 0x19, 0x34, 0x0c, 0x0a, 0x20, 0xe2, 0xeb, 0x24, 0x2e, 0xee, + 0xf4, 0x2b, 0xf6, 0xf0, 0x22, 0x2b, 0xfd, 0xd3, 0xdc, 0x0a, 0x1e, 0x15, + 0x10, 0xd7, 0xdc, 0x10, 0x32, 0x15, 0xe5, 0xed, 0xed, 0xfd, 0x25, 0xe5, + 0xd3, 0x09, 0x2e, 0xfd, 0xc7, 0xd2, 0x03, 0x24, 0x12, 0xf9, 0xe9, 0xc1, + 0xf4, 0x1e, 0x27, 0x0a, 0xd3, 0xdc, 0xeb, 0x0c, 0x27, 0x07, 0xe0, 0xee, + 0x25, 0x0c, 0xca, 0xf2, 0x1e, 0x00, 0xf9, 0x15, 0xfd, 0xe0, 0xd3, 0x0c, + 0x2b, 0xe2, 0xd5, 0x24, 0x20, 0xe2, 0xed, 0xe7, 0xfb, 0x2d, 0xf9, 0xca, + 0xe0, 0x13, 0xe9, 0xc9, 0x07, 0xfd, 0xed, 0x00, 0xf4, 0x05, 0x27, 0xf2, + 0xc1, 0xde, 0x1b, 0x2b, 0x1c, 0xf4, 0xd9, 0xde, 0x20, 0x32, 0x12, 0xe7, + 0xd7, 0xe2, 0x12, 0x29, 0x12, 0xd0, 0xf7, 0x0a, 0xd7, 0xd3, 0xff, 0x1c, + 0x17, 0xf2, 0xc3, 0xe9, 0x22, 0x27, 0x05, 0xd9, 0xd5, 0xee, 0x10, 0x22, + 0x1c, 0xe5, 0xc9, 0xe9, 0x24, 0x22, 0xf0, 0xc5, 0xe7, 0x05, 0xee, 0xe7, + 0x22, 0x15, 0xf2, 0x01, 0xfb, 0xde, 0xf9, 0x29, 0xf9, 0xd5, 0x17, 0xf9, + 0xce, 0x15, 0x20, 0xe2, 0xc7, 0xde, 0x12, 0x1c, 0xf4, 0x01, 0x0c, 0xc0, + 0xee, 0x15, 0xf6, 0xed, 0xf9, 0xf0, 0xf7, 0x25, 0xdc, 0xf0, 0x27, 0x12, + 0xd0, 0xdc, 0x1e, 0x10, 0xcc, 0x00, 0x2b, 0xe7, 0xc9, 0xfd, 0x03, 0x0a, + 0xff, 0xd7, 0xf6, 0x00, 0x2d, 0xff, 0xe2, 0xfb, 0x09, 0x2b, 0x10, 0xe9, + 0xed, 0xf0, 0xe5, 0x01, 0x0c, 0xd9, 0xf7, 0x17, 0x17, 0xe5, 0x03, 0x2b, + 0xdb, 0xd7, 0xf7, 0x15, 0x1c, 0x15, 0xe5, 0xce, 0x05, 0x32, 0x0a, 0xf4, + 0x20, 0xe9, 0xeb, 0x1c, 0xf6, 0xdc, 0x30, 0x2b, 0xf4, 0xd5, 0xdb, 0xff, + 0x20, 0x25, 0x01, 0xd0, 0xee, 0x0c, 0x00, 0x19, 0x03, 0xd7, 0xf9, 0x2d, + 0x1b, 0xd7, 0xe9, 0x2b, 0xff, 0xd2, 0x20, 0x1b, 0x01, 0x30, 0x07, 0xe4, + 0x01, 0x09, 0xff, 0x39, 0x09, 0xde, 0xd7, 0x05, 0x1e, 0x0c, 0x24, 0xde, + 0xcc, 0xe7, 0x1e, 0x24, 0x10, 0xdc, 0xd0, 0x01, 0x2d, 0x05, 0xce, 0xf4, + 0x2e, 0x22, 0xee, 0xd7, 0x05, 0x2e, 0x17, 0xf2, 0xd5, 0xde, 0x0a, 0x17, + 0x25, 0x0e, 0xf4, 0xe0, 0xf0, 0x32, 0x2d, 0xf7, 0xd7, 0xfd, 0x19, 0x0a, + 0x01, 0x00, 0xe2, 0xf7, 0x2b, 0x03, 0xd3, 0xf6, 0x34, 0x19, 0xe0, 0xd5, + 0x01, 0xff, 0xdc, 0x17, 0x1c, 0xf4, 0xca, 0xf9, 0x29, 0x12, 0xe5, 0xff, + 0x27, 0x03, 0xd0, 0xe7, 0x03, 0x05, 0x15, 0xfb, 0xe9, 0x07, 0x0e, 0xd3, + 0x00, 0x27, 0xf4, 0xe2, 0x2e, 0x0e, 0xd0, 0xfb, 0x27, 0xed, 0xc5, 0x00, + 0x27, 0x03, 0xf0, 0x24, 0xee, 0xc9, 0x00, 0x2e, 0x00, 0xcc, 0xfd, 0x2e, + 0xf6, 0xd0, 0xed, 0x19, 0x2d, 0xfd, 0xcc, 0xf2, 0x17, 0xfd, 0xfd, 0x29, + 0x01, 0xd0, 0xed, 0x25, 0x1c, 0xdb, 0xe5, 0xe9, 0xde, 0x1b, 0x0a, 0xe0, + 0xfd, 0x19, 0xe9, 0xe0, 0xe4, 0xfb, 0x22, 0x15, 0xf6, 0xd3, 0x07, 0x03, + 0xdc, 0x1b, 0x24, 0xf9, 0xd3, 0xff, 0x25, 0xe0, 0xf2, 0x32, 0x00, 0xd3, + 0xed, 0x27, 0xfb, 0xc7, 0xf6, 0x2b, 0x0a, 0xcc, 0xfd, 0x3b, 0xfd, 0xd0, + 0xde, 0x03, 0xfd, 0xee, 0x05, 0x29, 0xee, 0xc3, 0xe7, 0x13, 0x22, 0x0c, + 0xf9, 0x17, 0xe0, 0xd9, 0x17, 0x24, 0xdb, 0xe5, 0x32, 0x0c, 0xca, 0xde, + 0x15, 0x1c, 0xed, 0x20, 0x0a, 0xcc, 0x07, 0x36, 0xf7, 0xd0, 0xd7, 0x00, + 0x1c, 0x20, 0xfb, 0xdb, 0xe5, 0xfb, 0x0e, 0x00, 0x15, 0x20, 0x07, 0xfb, + 0xd7, 0xe2, 0x0e, 0x2e, 0x00, 0xd7, 0x15, 0x0e, 0xcc, 0x12, 0x24, 0xde, + 0xd3, 0x12, 0x32, 0x0a, 0xdb, 0xf0, 0x1c, 0xf0, 0xd7, 0xfb, 0x1c, 0x27, + 0xf0, 0xd0, 0x07, 0x2e, 0xf7, 0xe9, 0x20, 0xde, 0xdb, 0x1c, 0x27, 0xe5, + 0xc5, 0xfb, 0x27, 0x1c, 0x00, 0xe9, 0xf4, 0x12, 0xdb, 0xd7, 0x15, 0x20, + 0x19, 0x07, 0xed, 0xcc, 0xf4, 0x2b, 0x27, 0x00, 0xf4, 0xde, 0xe2, 0x24, + 0x2e, 0x00, 0xd3, 0xe2, 0x07, 0x00, 0xff, 0x1c, 0xf0, 0x00, 0xf7, 0xd3, + 0x2b, 0x32, 0x0a, 0xf0, 0xde, 0xd0, 0xf0, 0x0e, 0x24, 0x19, 0xdb, 0xc9, + 0xff, 0x27, 0x19, 0x00, 0xff, 0xd7, 0xe2, 0x0e, 0x2b, 0x27, 0xf7, 0xf4, + 0x03, 0xe5, 0x15, 0x27, 0xf4, 0xd0, 0xe5, 0x20, 0x00, 0xd3, 0x2b, 0x24, + 0xe5, 0xd0, 0x00, 0x2b, 0xe2, 0xc5, 0x0e, 0x2b, 0x03, 0xe2, 0x12, 0xfb, + 0xc5, 0xf0, 0x03, 0x0a, 0x1c, 0xf7, 0xe5, 0x1c, 0xed, 0xe9, 0x07, 0x36, + 0x07, 0xdb, 0x00, 0x0e, 0xcc, 0xfb, 0x32, 0x12, 0xe2, 0x03, 0x19, 0xdb, + 0xd7, 0x0e, 0x24, 0x19, 0xf4, 0xe5, 0x19, 0x0a, 0xd0, 0xfb, 0x15, 0xd0, + 0xf0, 0x20, 0x27, 0xf4, 0xcc, 0xe5, 0x24, 0x00, 0xed, 0x32, 0xed, 0xc5, + 0xe5, 0x07, 0x07, 0xf4, 0x07, 0x20, 0xfb, 0xe5, 0x03, 0x20, 0xe9, 0x0a, + 0x0e, 0xd0, 0xf0, 0x2b, 0x27, 0xe5, 0xd7, 0x0e, 0xff, 0x15, 0x2e, 0xfb, + 0xfb, 0xe9, 0xe2, 0xed, 0x27, 0x0e, 0xd0, 0xfb, 0x27, 0xf4, 0xd3, 0x19, + 0x27, 0xf0, 0xc9, 0xf4, 0x24, 0xff, 0xf0, 0x3d, 0x00, 0xdb, 0xd3, 0xf7, + 0x15, 0x19, 0x00, 0xf4, 0x03, 0xde, 0xfb, 0x32, 0x24, 0xf7, 0xdb, 0xf0, + 0x03, 0xe2, 0x03, 0x1c, 0x20, 0xe2, 0xc9, 0xf0, 0x24, 0x20, 0x03, 0x00, + 0xe9, 0xc9, 0xe9, 0x19, 0x24, 0x00, 0xcc, 0xd7, 0x07, 0x24, 0x00, 0xe9, + 0x32, 0x19, 0xe2, 0x00, 0x07, 0xe9, 0x1c, 0x12, 0xde, 0xe9, 0xfb, 0xe5, + 0x1c, 0x1c, 0x24, 0xf0, 0xdb, 0x00, 0x20, 0xd7, 0xf7, 0x20, 0xd3, 0xe5, + 0x27, 0x07, 0xc5, 0xe9, 0x20, 0x20, 0xfb, 0xc9, 0xe2, 0x12, 0x1c, 0x20, + 0x00, 0xd7, 0xe9, 0x2e, 0x15, 0xd3, 0xde, 0x19, 0x20, 0xed, 0xd3, 0x00, + 0x24, 0x27, 0x03, 0xe2, 0xd3, 0xde, 0x15, 0x20, 0x03, 0xf7, 0xe9, 0xfb, + 0xf0, 0xfb, 0x15, 0x03, 0x2b, 0xf4, 0xd3, 0x00, 0x32, 0x0a, 0xe5, 0xd0, + 0xe9, 0x0e, 0x07, 0x1c, 0x00, 0xc9, 0xd7, 0x03, 0x1c, 0x24, 0x15, 0xff, + 0xe5, 0xd3, 0xf7, 0x20, 0x24, 0x00, 0xd3, 0xdb, 0x03, 0x27, 0x27, 0x0e, + 0xf4, 0xe5, 0xd0, 0xf4, 0x20, 0x2b, 0x19, 0xed, 0xe2, 0xd3, 0x0a, 0x2b, + 0x1c, 0xf7, 0xe2, 0xfb, 0xe9, 0xe2, 0x20, 0x20, 0xf7, 0xc9, 0xd3, 0xff, + 0x12, 0x20, 0x20, 0xe9, 0xcc, 0xde, 0x07, 0x19, 0x24, 0x07, 0xe2, 0xf7, + 0x2b, 0xe5, 0xdb, 0x2b, 0x32, 0x00, 0xe5, 0xde, 0x0e, 0x2e, 0xe5, 0xcc, + 0x07, 0x32, 0x07, 0xcc, 0xed, 0x2e, 0x0e, 0xc9, 0xf0, 0x2b, 0x00, 0xd3, + 0x24, 0x27, 0xe5, 0xcc, 0xd3, 0x00, 0x15, 0x1c, 0x12, 0x00, 0xf7, 0xdb, + 0xd7, 0x19, 0x24, 0x0a, 0x0a, 0xe5, 0xcc, 0xf7, 0x24, 0x2b, 0x03, 0xe5, + 0x0e, 0xe2, 0xde, 0x24, 0x27, 0xe9, 0xc5, 0xf0, 0x20, 0x2b, 0x0e, 0xf0, + 0xff, 0xc9, 0xe2, 0x12, 0x27, 0x19, 0x00, 0x00, 0xd0, 0xe2, 0x12, 0x32, + 0x19, 0xed, 0xdb, 0xd3, 0xff, 0x24, 0x2b, 0x00, 0xcc, 0xff, 0x24, 0xf0, + 0xcc, 0x19, 0x27, 0xe2, 0xc9, 0xff, 0x0e, 0x19, 0x0a, 0x00, 0xe9, 0xe9, + 0xff, 0xf7, 0x2b, 0x2b, 0x03, 0xde, 0xe2, 0x03, 0xfb, 0x0e, 0x39, 0xed, + 0xd0, 0xed, 0x1c, 0xf7, 0x00, 0x3d, 0x00, 0xd7, 0xed, 0x00, 0xde, 0x1c, + 0x27, 0xed, 0xc1, 0xfb, 0x27, 0x1c, 0xf7, 0xde, 0xe2, 0x27, 0x19, 0xd7, + 0x03, 0x2b, 0xe5, 0xc9, 0xde, 0x07, 0x15, 0xff, 0x0a, 0x19, 0xc5, 0xe5, + 0x20, 0x2b, 0xf0, 0xcc, 0x00, 0x20, 0xf4, 0xdb, 0x36, 0x15, 0xde, 0xed, + 0x1c, 0x27, 0xf0, 0xd7, 0xf4, 0x0e, 0xf0, 0x1c, 0x15, 0xf4, 0xfb, 0xf7, + 0xff, 0x0e, 0xdb, 0xcc, 0x12, 0x27, 0x0a, 0xed, 0x03, 0xe2, 0xcc, 0x03, + 0x0e, 0x03, 0x0e, 0xf7, 0xf4, 0xf0, 0xd7, 0x0a, 0x27, 0x27, 0xff, 0xe5, + 0xf7, 0xe9, 0x0e, 0x32, 0x00, 0xd0, 0xde, 0x1c, 0x19, 0xf7, 0x0a, 0xf0, + 0xcc, 0xff, 0x24, 0x2e, 0x19, 0xf0, 0xf4, 0xde, 0xd7, 0x12, 0x2b, 0x27, + 0xf7, 0xe2, 0xe9, 0xe9, 0x00, 0x2b, 0x03, 0xd3, 0xc9, 0xf4, 0x19, 0x0e, + 0xed, 0xe9, 0xfb, 0x27, 0xde, 0xd3, 0x24, 0x24, 0xf0, 0xcc, 0xed, 0x24, + 0x1c, 0xfb, 0x0a, 0x24, 0xde, 0xe5, 0x00, 0x1c, 0xf7, 0xdb, 0x12, 0x0e, + 0xf4, 0xd0, 0x0e, 0x36, 0x0e, 0xed, 0xe2, 0xdb, 0x0e, 0x19, 0xd3, 0xe2, + 0x2b, 0x12, 0xd0, 0xf0, 0x2e, 0xe5, 0xc9, 0x0a, 0x20, 0xe9, 0x07, 0x36, + 0xed, 0xd0, 0xe2, 0x0e, 0x07, 0x12, 0x27, 0xe9, 0xdb, 0x0e, 0x20, 0xd3, + 0xfb, 0x2b, 0x0a, 0xdb, 0xe9, 0x19, 0x03, 0xf4, 0x0a, 0xdb, 0x00, 0x32, + 0x03, 0xd7, 0xd3, 0xfb, 0x03, 0xe5, 0x12, 0x27, 0xff, 0xed, 0xf7, 0xf0, + 0xfb, 0x32, 0x00, 0xc5, 0xff, 0x32, 0x19, 0xe2, 0xcc, 0xed, 0x0e, 0x20, + 0x27, 0xf0, 0xed, 0x0e, 0xed, 0xdb, 0x27, 0x32, 0x1c, 0xf7, 0xf4, 0xe5, + 0xd3, 0xff, 0x20, 0x27, 0x07, 0xe5, 0xdb, 0xdb, 0x0e, 0x1c, 0x0a, 0xd7, + 0xe9, 0x07, 0x15, 0x0a, 0xff, 0xc9, 0xd7, 0x07, 0x1c, 0xf0, 0xe5, 0x00, + 0x15, 0x20, 0xf0, 0xd3, 0x07, 0x3d, 0x0a, 0xe5, 0xd7, 0xe9, 0x24, 0x2b, + 0x00, 0xcc, 0x00, 0x3d, 0x15, 0xe5, 0xfb, 0x0e, 0xdb, 0xf7, 0x32, 0x20, + 0xed, 0xdb, 0x0e, 0x24, 0xd3, 0xd7, 0x07, 0x2b, 0xff, 0xc5, 0x00, 0x2b, + 0xe9, 0xde, 0x32, 0x00, 0xc1, 0xd0, 0xf7, 0x0a, 0x19, 0x19, 0xde, 0xe2, + 0x32, 0x15, 0xde, 0x12, 0x12, 0xcc, 0xf7, 0x27, 0xfb, 0xd7, 0x2b, 0x27, + 0xe9, 0xd3, 0x00, 0x2e, 0xed, 0xed, 0x39, 0x07, 0xd7, 0x00, 0x39, 0xff, + 0xd7, 0xed, 0x24, 0xf7, 0xcc, 0x20, 0x0e, 0xd0, 0xfb, 0x32, 0x07, 0xd3, + 0xf0, 0x0e, 0xc9, 0xf0, 0x24, 0x20, 0xed, 0xe5, 0x1c, 0xcc, 0xf0, 0x2b, + 0x0a, 0xf7, 0xff, 0xf4, 0xde, 0x0a, 0x32, 0x20, 0xf0, 0xdb, 0xdb, 0x07, + 0x32, 0x15, 0xdb, 0xd0, 0x0a, 0x27, 0x00, 0x2b, 0x07, 0xe9, 0xe2, 0xf4, + 0xf0, 0xff, 0x1c, 0x0a, 0xe5, 0xf4, 0xe5, 0x00, 0x2b, 0xff, 0xc5, 0xf4, + 0x24, 0x03, 0x00, 0x15, 0x0e, 0xe9, 0xd7, 0x00, 0x39, 0x15, 0xde, 0xde, + 0x03, 0xf4, 0x03, 0x36, 0xf7, 0xd0, 0xf4, 0x20, 0xe5, 0xf0, 0x36, 0xfb, + 0xc9, 0xe5, 0x24, 0x2b, 0x07, 0xf7, 0x00, 0xd7, 0xe9, 0x1c, 0x27, 0xfb, + 0xf4, 0xe2, 0xde, 0x12, 0x27, 0xff, 0xfb, 0x24, 0xe2, 0xd0, 0x03, 0x36, + 0x0e, 0xd7, 0xd7, 0x00, 0x1c, 0x03, 0x00, 0xff, 0xd7, 0x0a, 0x20, 0xd0, + 0xe5, 0x27, 0x20, 0xe9, 0xd0, 0x00, 0x07, 0xf4, 0x00, 0x19, 0xfb, 0xd7, + 0x12, 0x2b, 0xf4, 0xc9, 0xe9, 0x20, 0x27, 0x15, 0x00, 0xe9, 0xe5, 0x27, + 0x19, 0xd0, 0x03, 0x19, 0xde, 0xf0, 0x24, 0xed, 0xdb, 0x12, 0x24, 0xf0, + 0xc9, 0x07, 0x00, 0x1c, 0x19, 0xd0, 0xe5, 0x24, 0x24, 0xe2, 0xc9, 0xed, + 0x1c, 0x27, 0x19, 0xfb, 0xe2, 0xd3, 0xf7, 0x19, 0x19, 0xe5, 0xde, 0x27, + 0x19, 0xd3, 0xe5, 0xff, 0x00, 0x2e, 0x0e, 0xd7, 0xd7, 0x19, 0x32, 0x0e, + 0x00, 0xe9, 0xe9, 0xff, 0x0e, 0x0e, 0x03, 0xde, 0xd0, 0x12, 0x2b, 0x15, + 0xe2, 0xd3, 0x12, 0x2b, 0xdb, 0xcc, 0x07, 0x2b, 0x1c, 0xe2, 0xcc, 0xf4, + 0x15, 0x2b, 0x1c, 0xe9, 0xf7, 0xe9, 0xdb, 0x15, 0x0a, 0x03, 0x00, 0xf0, + 0x36, 0xff, 0xc9, 0xff, 0x32, 0x07, 0xd3, 0xf0, 0x15, 0x1c, 0x0e, 0xd0, + 0xdb, 0x03, 0x00, 0xf7, 0x32, 0x0e, 0xd0, 0xd0, 0x03, 0x24, 0x0e, 0x03, + 0x19, 0x00, 0xfb, 0xff, 0xe5, 0xdb, 0x03, 0x0e, 0xdb, 0x03, 0x15, 0xde, + 0xfb, 0x07, 0xf4, 0x0e, 0x00, 0xff, 0x00, 0x07, 0x1c, 0xc9, 0xdb, 0x15, + 0x2b, 0x19, 0x00, 0xff, 0xde, 0xf4, 0x19, 0xf4, 0x00, 0x0e, 0x12, 0xff, + 0xed, 0xc5, 0xe2, 0x00, 0x0e, 0x15, 0x12, 0xe5, 0xd0, 0x0e, 0x0a, 0xff, + 0x36, 0x0a, 0xe9, 0xe9, 0x00, 0xed, 0xf7, 0x00, 0x07, 0x1c, 0xf0, 0xe5, + 0x00, 0x19, 0xfb, 0xff, 0xf4, 0xde, 0x2b, 0x2b, 0x00, 0xd7, 0xf7, 0x12, + 0x07, 0x0e, 0xf4, 0xed, 0xf4, 0x2e, 0x07, 0xe9, 0xd0, 0x03, 0x32, 0x03, + 0xcc, 0xd0, 0xfb, 0x15, 0x0e, 0x00, 0xd7, 0x00, 0x2e, 0x00, 0xc9, 0xdb, + 0x07, 0x07, 0xfb, 0x27, 0x12, 0xed, 0xf7, 0x2b, 0xe5, 0xd0, 0x1c, 0x2e, + 0xf0, 0xed, 0x19, 0xd3, 0xff, 0x39, 0x1c, 0xe9, 0xf0, 0x19, 0xf7, 0xd0, + 0x03, 0xfb, 0x00, 0x36, 0x0a, 0xd7, 0xd7, 0x07, 0x0e, 0xf4, 0x0e, 0xe2, + 0xd3, 0x0e, 0x2e, 0x15, 0xdb, 0xd0, 0xe9, 0xff, 0x0e, 0x24, 0xe2, 0xe9, + 0x36, 0x00, 0xc9, 0xf7, 0x20, 0x24, 0x12, 0x00, 0xdb, 0xdb, 0x07, 0x2e, + 0x1c, 0xe2, 0xdb, 0x24, 0x2e, 0xed, 0xdb, 0xd3, 0xf4, 0x15, 0x1c, 0xe9, + 0xd3, 0x12, 0x24, 0x0e, 0xd7, 0xde, 0x00, 0x19, 0x15, 0xf7, 0xd3, 0xe9, + 0x2e, 0x07, 0xc9, 0xf4, 0x2b, 0xff, 0x07, 0x15, 0xc9, 0xde, 0x15, 0x27, + 0x0a, 0x00, 0x19, 0xde, 0xd3, 0xf0, 0x27, 0x19, 0xed, 0xf4, 0x07, 0x20, + 0xd7, 0xdb, 0x27, 0x15, 0xd0, 0xfb, 0x32, 0x07, 0xf7, 0xff, 0xe2, 0xcc, + 0xf0, 0x12, 0x20, 0x19, 0xf0, 0xd0, 0xd3, 0x0a, 0x24, 0x15, 0xff, 0x00, + 0xd3, 0xde, 0x1c, 0x27, 0x00, 0xf4, 0xff, 0xde, 0x0a, 0x3d, 0x0a, 0xdb, + 0xe5, 0x12, 0xf4, 0xf0, 0x40, 0x0a, 0xdb, 0xfb, 0xfb, 0xd0, 0x19, 0x2e, + 0x1c, 0xe9, 0xd3, 0xd7, 0x0e, 0x2e, 0x1c, 0xe9, 0xd7, 0xde, 0xff, 0x20, + 0x1c, 0xdb, 0xd7, 0x00, 0x0e, 0xf0, 0xff, 0x2b, 0x12, 0xde, 0xc9, 0xf7, + 0x27, 0x19, 0x00, 0x0e, 0x03, 0xd0, 0xe9, 0x20, 0x27, 0xed, 0xf7, 0x20, + 0xfb, 0xdb, 0x03, 0x2e, 0xde, 0xc5, 0xf4, 0x19, 0x15, 0xff, 0x15, 0xff, + 0xd3, 0x07, 0x00, 0xff, 0x19, 0xe2, 0x00, 0x27, 0xde, 0xd0, 0x0a, 0x27, + 0xe9, 0xed, 0x32, 0xf4, 0xcc, 0x00, 0x32, 0x15, 0xde, 0xff, 0x27, 0xd3, + 0xd7, 0x0a, 0x15, 0xff, 0x03, 0xf0, 0x19, 0x20, 0xe2, 0xed, 0x19, 0xf4, + 0xd0, 0x00, 0x32, 0x12, 0xf7, 0xed, 0xd0, 0xf4, 0x19, 0x2e, 0x12, 0xe5, + 0xd7, 0xdb, 0x15, 0x1c, 0xf0, 0x03, 0x24, 0xd7, 0xc9, 0xf7, 0x1c, 0xff, + 0x19, 0x19, 0xd7, 0xe5, 0x2b, 0x20, 0xe5, 0xd0, 0xff, 0x1c, 0xd7, 0x03, + 0x2e, 0xff, 0xd7, 0x03, 0x0a, 0xd3, 0x00, 0x36, 0x0a, 0xe9, 0xe2, 0xdb, + 0xff, 0x03, 0xff, 0x0e, 0x19, 0x00, 0xd7, 0xd7, 0x07, 0x19, 0x2b, 0x00, + 0xdb, 0xff, 0x1c, 0x03, 0x00, 0xdb, 0xdb, 0x24, 0x27, 0xde, 0xcc, 0x0a, + 0x2b, 0xf0, 0xff, 0x15, 0xd3, 0x07, 0x1c, 0xd7, 0xd7, 0x12, 0x27, 0xed, + 0xe5, 0x36, 0xf4, 0xd0, 0x19, 0x1c, 0xc9, 0xed, 0x2e, 0x27, 0xf0, 0xdb, + 0xde, 0xfb, 0x20, 0x27, 0xed, 0xc9, 0xf0, 0x19, 0x0a, 0x19, 0x12, 0xe9, + 0xde, 0x0e, 0x36, 0xfb, 0xdb, 0x00, 0x24, 0xde, 0xe2, 0x24, 0x0a, 0xcc, + 0xf0, 0x2e, 0x00, 0xc1, 0xf4, 0x2b, 0x0a, 0xd3, 0xf7, 0x00, 0xd7, 0x1c, + 0x27, 0xfb, 0xe9, 0x24, 0xf7, 0xc5, 0xf4, 0x24, 0x24, 0x0a, 0x00, 0xe5, + 0xde, 0x07, 0x24, 0xf7, 0xde, 0x15, 0x1c, 0xe5, 0xc5, 0xf4, 0x19, 0x19, + 0x20, 0xfb, 0xd3, 0xf0, 0x2e, 0x0a, 0xd0, 0x00, 0x24, 0xe2, 0x0a, 0x07, + 0xd7, 0xfb, 0xff, 0xe5, 0xf0, 0x07, 0x24, 0x19, 0xde, 0xd7, 0x0a, 0x00, + 0xf4, 0x0e, 0x27, 0xf0, 0xcc, 0x00, 0x2b, 0x03, 0xf4, 0x32, 0x0a, 0xdb, + 0xed, 0x03, 0x00, 0x12, 0xff, 0xd0, 0x00, 0x32, 0x0e, 0xd7, 0xe9, 0x27, + 0xf7, 0xc1, 0x00, 0x1c, 0x00, 0x0a, 0x03, 0xc9, 0xe2, 0x19, 0x2b, 0x15, + 0xed, 0xe9, 0xdb, 0xf7, 0x27, 0x1c, 0xf0, 0xe5, 0x03, 0xff, 0x00, 0xf4, + 0xed, 0x39, 0x12, 0xd7, 0xde, 0x0e, 0x24, 0xff, 0xe5, 0x07, 0x15, 0x00, + 0xd3, 0xfb, 0x2e, 0x15, 0xd7, 0xe5, 0x2b, 0x24, 0xd7, 0xde, 0x1c, 0x19, + 0xd3, 0x00, 0x2b, 0xed, 0xd0, 0x15, 0x19, 0xff, 0xf0, 0xdb, 0xfb, 0x27, + 0x0e, 0xe2, 0x03, 0x32, 0xff, 0xde, 0xe5, 0x0a, 0x00, 0x0e, 0x00, 0xc9, + 0x07, 0x2b, 0x07, 0xd0, 0xe2, 0x19, 0x0e, 0xf4, 0x03, 0x00, 0xf4, 0xe2, + 0x15, 0x15, 0xed, 0xe9, 0x24, 0x2e, 0xf0, 0xd3, 0x00, 0x39, 0x00, 0xd3, + 0x0a, 0x27, 0xf4, 0xd7, 0xf0, 0xf4, 0xff, 0x12, 0xfb, 0xf4, 0xd7, 0x0e, + 0x27, 0xff, 0xd0, 0xed, 0x2b, 0x2b, 0x00, 0xe2, 0xed, 0xed, 0xf7, 0x24, + 0x27, 0xe9, 0xe5, 0x24, 0xf4, 0xcc, 0x03, 0x2e, 0x20, 0xed, 0x03, 0x0e, + 0xde, 0xdb, 0xe9, 0x19, 0x1c, 0xe9, 0xf7, 0x36, 0xf0, 0xde, 0x20, 0xff, + 0xd0, 0x0e, 0x32, 0x00, 0xd3, 0xd7, 0x00, 0x03, 0xf4, 0x32, 0xfb, 0xd7, + 0x19, 0x0a, 0xc1, 0xe9, 0x20, 0x27, 0x00, 0xed, 0x07, 0xf0, 0xf0, 0x03, + 0x19, 0xdb, 0xed, 0x32, 0x20, 0xf0, 0xe9, 0x12, 0xe5, 0xed, 0x2b, 0xff, + 0xdb, 0x00, 0x1c, 0xed, 0xcc, 0x0a, 0x20, 0xe2, 0xf0, 0x3d, 0x03, 0xd3, + 0xd0, 0xf4, 0x19, 0x1c, 0x07, 0xe9, 0xed, 0x19, 0x0e, 0xd7, 0xde, 0x19, + 0x24, 0x0a, 0xe9, 0xe2, 0x15, 0xfb, 0xfb, 0x27, 0x00, 0xd7, 0xd7, 0x0e, + 0x2b, 0xf0, 0xc9, 0x03, 0x32, 0x07, 0xd3, 0x07, 0x24, 0xdb, 0xe9, 0x00, + 0xff, 0xfb, 0xf4, 0xed, 0x0a, 0x2b, 0x0e, 0xf0, 0xd7, 0xed, 0x19, 0x0a, + 0x00, 0x0e, 0xff, 0xf0, 0x03, 0x27, 0xe2, 0xe5, 0x0e, 0x32, 0xe9, 0xd0, + 0x12, 0x2b, 0xdb, 0xe2, 0x12, 0xfb, 0x03, 0x19, 0xd7, 0xc9, 0xe9, 0x0e, + 0x12, 0x03, 0x07, 0xf0, 0x0a, 0x07, 0xde, 0xdb, 0x00, 0x27, 0x15, 0xd7, + 0xdb, 0x07, 0x03, 0xe5, 0x19, 0x20, 0xdb, 0xf7, 0x3d, 0x07, 0xd7, 0xd3, + 0x00, 0x20, 0xfb, 0x19, 0x20, 0x00, 0xe9, 0xd0, 0xf0, 0x24, 0x00, 0x03, + 0x36, 0xff, 0xdb, 0x07, 0x19, 0xde, 0xff, 0xf0, 0xed, 0x24, 0xfb, 0xc5, + 0x0a, 0x24, 0xe5, 0xf7, 0x39, 0xf4, 0xcc, 0xe9, 0x1c, 0xfb, 0xd3, 0x0e, + 0x24, 0x19, 0x00, 0xff, 0xde, 0xd7, 0x0a, 0x1c, 0x00, 0x0a, 0x12, 0xde, + 0x24, 0x15, 0xd3, 0xf4, 0x2b, 0x12, 0xe5, 0xed, 0xf4, 0xde, 0x00, 0x27, + 0x12, 0xf7, 0xdb, 0x07, 0x24, 0xd7, 0xc9, 0xff, 0x15, 0xfb, 0xf4, 0x19, + 0x0a, 0xd0, 0x0e, 0x20, 0xde, 0xf4, 0x27, 0x0e, 0xdb, 0x12, 0x07, 0xd7, + 0x00, 0x36, 0x15, 0xde, 0xde, 0xf7, 0x00, 0x2b, 0x0e, 0xe9, 0xf4, 0x0e, + 0xf7, 0x07, 0x19, 0xd0, 0xd3, 0x0e, 0x2e, 0x07, 0xdb, 0xe2, 0xff, 0x24, + 0x15, 0xe9, 0xd7, 0x00, 0x12, 0x19, 0xf7, 0xd3, 0xfb, 0x24, 0x20, 0xed, + 0xc9, 0xe5, 0x1c, 0x1c, 0x00, 0xf7, 0xf4, 0xed, 0x32, 0x0e, 0xd3, 0xde, + 0x1c, 0x32, 0xff, 0xde, 0xf7, 0x07, 0x15, 0xfb, 0xe9, 0x2e, 0x00, 0xcc, + 0xf4, 0x27, 0xfb, 0xd0, 0x24, 0x1c, 0xd3, 0xed, 0x36, 0xfb, 0xcc, 0x0e, + 0x32, 0xe5, 0xd3, 0x19, 0x27, 0xd0, 0xd3, 0x0a, 0x0a, 0xe2, 0x32, 0x24, + 0xe9, 0xd0, 0xe9, 0x24, 0x0e, 0xdb, 0x00, 0x32, 0x0e, 0xde, 0xd7, 0xff, + 0x12, 0x0e, 0x20, 0x00, 0xfb, 0xf4, 0xdb, 0x15, 0x36, 0x0a, 0xde, 0xfb, + 0x00, 0xe5, 0xe5, 0x15, 0x15, 0xd0, 0xf4, 0x32, 0x12, 0xed, 0x00, 0xdb, + 0xd7, 0x07, 0x2b, 0x15, 0xdb, 0xde, 0x19, 0x0e, 0xc5, 0xed, 0x27, 0x20, + 0xf7, 0xe5, 0x20, 0x00, 0xcc, 0xf0, 0x32, 0x1c, 0xed, 0xfb, 0xf4, 0xe2, + 0x00, 0xff, 0xed, 0x0a, 0x2e, 0x07, 0xe9, 0xf7, 0xde, 0xed, 0x15, 0x12, + 0x00, 0xe5, 0xe2, 0x2b, 0x19, 0xf4, 0xd3, 0xed, 0x27, 0x2b, 0x00, 0xd3, + 0xde, 0x12, 0x12, 0xfb, 0xff, 0xde, 0x2b, 0x27, 0xe2, 0xd7, 0xf7, 0x00, + 0xf4, 0x0a, 0xff, 0xe9, 0xf7, 0x24, 0x07, 0xf4, 0xc9, 0x00, 0x27, 0xff, + 0x00, 0x00, 0xc9, 0xe9, 0x20, 0x20, 0x03, 0x00, 0x27, 0x00, 0xde, 0xf0, + 0x12, 0xf7, 0xf4, 0x20, 0x07, 0xd0, 0xd3, 0x0a, 0x24, 0xf0, 0xf7, 0x12, + 0xc5, 0x03, 0x32, 0x03, 0xd0, 0xcc, 0x00, 0x20, 0x24, 0x12, 0xd7, 0xe2, + 0x0e, 0x03, 0xe2, 0x1c, 0x1c, 0xed, 0xf7, 0x20, 0xde, 0xd3, 0x19, 0x20, + 0xe2, 0x00, 0x24, 0xe2, 0xe9, 0xf7, 0xff, 0x24, 0xe5, 0xed, 0x39, 0x1c, + 0xed, 0xd7, 0xe9, 0x1c, 0xff, 0xed, 0x2b, 0xe9, 0xc9, 0x15, 0x2b, 0xf7, + 0xe9, 0x24, 0xf7, 0xf4, 0x0e, 0xe2, 0x00, 0x00, 0xf7, 0xf7, 0xf4, 0xfb, + 0x24, 0x24, 0xe5, 0xd0, 0xe9, 0x1c, 0x2b, 0x03, 0xd7, 0x00, 0x00, 0xd0, + 0xe9, 0x1c, 0x1c, 0x00, 0xf4, 0x00, 0xf7, 0xed, 0xff, 0x27, 0x03, 0xd3, + 0x0e, 0x32, 0xf7, 0xde, 0xfb, 0xed, 0xf7, 0x27, 0x15, 0xde, 0x07, 0x1c, + 0xd0, 0xd7, 0x0a, 0x2e, 0x15, 0xf7, 0xe2, 0xd7, 0xfb, 0x1c, 0x15, 0xe9, + 0xe9, 0x0e, 0xed, 0xe9, 0x2b, 0x12, 0xd7, 0x00, 0x3d, 0x00, 0xdb, 0xff, + 0xff, 0xdb, 0x00, 0x2b, 0xfb, 0xc9, 0x00, 0x24, 0x00, 0x0a, 0x12, 0xd0, + 0xde, 0x19, 0x2e, 0x00, 0xcc, 0xe9, 0x27, 0x19, 0xd3, 0xf4, 0x39, 0x19, + 0xed, 0xd3, 0xe9, 0x27, 0x2e, 0x03, 0xf0, 0xdb, 0xd7, 0x03, 0x24, 0x12, + 0xde, 0xde, 0xf0, 0x20, 0x07, 0xed, 0x20, 0xf0, 0xd7, 0x00, 0x2e, 0xfb, + 0xd3, 0x19, 0x12, 0xc5, 0xed, 0x2b, 0x19, 0xe5, 0xf4, 0x24, 0xfb, 0xfb, + 0x0e, 0x07, 0xf4, 0x0a, 0xe9, 0xe2, 0x12, 0x24, 0xfb, 0xfb, 0x15, 0xe2, + 0x00, 0x20, 0xed, 0xd7, 0x07, 0x00, 0xf7, 0x0e, 0xf7, 0xf4, 0x00, 0xed, + 0xf0, 0x1c, 0x19, 0xd7, 0xde, 0x12, 0x00, 0x19, 0x1c, 0xe2, 0xe2, 0x12, + 0x2e, 0xe5, 0xdb, 0xff, 0xed, 0xff, 0x27, 0xf0, 0xf0, 0x39, 0xf7, 0xcc, + 0xd7, 0x0a, 0x20, 0x1c, 0x00, 0xd0, 0xd3, 0x0a, 0x27, 0x0a, 0xff, 0x1c, + 0xdb, 0xe5, 0x2e, 0x27, 0xde, 0xe5, 0x0e, 0xe9, 0xfb, 0x2e, 0x1c, 0xf0, + 0xe2, 0xd7, 0xff, 0x27, 0x1c, 0xfb, 0x03, 0xf4, 0xc9, 0x00, 0x2e, 0x03, + 0xd7, 0x12, 0x00, 0xbe, 0xf7, 0x20, 0x07, 0x00, 0x07, 0xd0, 0x1c, 0x2b, + 0xe5, 0xcc, 0xff, 0x20, 0xe9, 0x12, 0x32, 0xf0, 0xd7, 0x15, 0x20, 0xd3, + 0xff, 0x32, 0xe5, 0xe9, 0x2b, 0x03, 0xc9, 0xe5, 0x0a, 0x1c, 0x0e, 0xdb, + 0xe2, 0x24, 0x0e, 0xd0, 0xdb, 0x15, 0x2b, 0x20, 0x03, 0xed, 0xd7, 0xde, + 0x0a, 0x20, 0xed, 0xd3, 0x27, 0x20, 0xe5, 0xf4, 0x24, 0xed, 0xd0, 0x12, + 0x20, 0xe5, 0xde, 0x19, 0x1c, 0xd7, 0xe2, 0x12, 0x32, 0x1c, 0xfb, 0xf4, + 0xd7, 0xe2, 0x12, 0x2e, 0x1c, 0xe2, 0xe9, 0x1c, 0xfb, 0xc1, 0x00, 0x2b, + 0x03, 0xcc, 0xfb, 0x15, 0x03, 0x15, 0xf7, 0xe5, 0xde, 0x00, 0x24, 0x20, + 0xf7, 0xc9, 0xdb, 0x0a, 0x15, 0x15, 0x15, 0x07, 0xed, 0xdb, 0xf7, 0xff, + 0x07, 0x32, 0x19, 0xf0, 0xe9, 0xe9, 0xe5, 0x19, 0x12, 0xd0, 0x03, 0x32, + 0x0a, 0xde, 0xe2, 0x0e, 0xff, 0x0a, 0x24, 0xd7, 0xd0, 0x07, 0x27, 0xf4, + 0xf7, 0x07, 0xe2, 0x19, 0x36, 0xf7, 0xdb, 0xde, 0xf4, 0x00, 0x12, 0x12, + 0x0e, 0x03, 0xd0, 0xd7, 0x0a, 0x19, 0xfb, 0x24, 0x0e, 0xcc, 0xdb, 0x12, + 0x24, 0xf4, 0x00, 0x00, 0xd7, 0x0e, 0x32, 0xfb, 0xc5, 0xe5, 0x15, 0x15, + 0x15, 0x19, 0xed, 0xd7, 0xe2, 0x07, 0x00, 0x24, 0x24, 0xe9, 0xf0, 0xff, + 0xf0, 0xfb, 0xff, 0x24, 0x0e, 0xfb, 0xf4, 0xdb, 0x1c, 0x00, 0xc9, 0x07, + 0x32, 0x00, 0xd3, 0xf7, 0x07, 0xe9, 0xf0, 0x07, 0x0e, 0x1c, 0xed, 0xde, + 0x0a, 0x27, 0xe2, 0xf0, 0x0a, 0xe2, 0xff, 0x24, 0x1c, 0xd7, 0xe2, 0x20, + 0x0e, 0xf4, 0x0e, 0x12, 0xf7, 0xcc, 0x00, 0x24, 0xd3, 0xe9, 0x2e, 0x15, + 0xdb, 0xcc, 0xff, 0x2b, 0x24, 0xff, 0xc9, 0xed, 0x20, 0xfb, 0xed, 0x32, + 0x07, 0xd3, 0xe5, 0x27, 0x15, 0xcc, 0x00, 0x32, 0xf0, 0xdb, 0x27, 0x15, + 0xd0, 0x03, 0x24, 0xd0, 0xd3, 0x0e, 0x24, 0xd7, 0xe2, 0x27, 0x03, 0xde, + 0x27, 0x20, 0xd7, 0xdb, 0x1c, 0x2e, 0xf0, 0xde, 0x00, 0x0a, 0x0e, 0xf4, + 0xe9, 0xed, 0x00, 0x2b, 0x27, 0xf0, 0xd3, 0xed, 0x15, 0xfb, 0x20, 0x0e, + 0xd7, 0xd3, 0x03, 0x20, 0xf4, 0x07, 0xff, 0xd3, 0x07, 0x15, 0xde, 0x07, + 0x24, 0xdb, 0xc9, 0x00, 0x1c, 0xf7, 0x12, 0x20, 0xcc, 0xd0, 0x00, 0x1c, + 0x15, 0x0e, 0x03, 0xf0, 0xf4, 0x36, 0xfb, 0xf0, 0x12, 0xfb, 0xf7, 0x00, + 0xff, 0x0a, 0x00, 0x03, 0xde, 0xf7, 0x0e, 0x07, 0x19, 0xde, 0xd3, 0x03, + 0x07, 0xe2, 0x19, 0x12, 0xd3, 0xe5, 0x2b, 0x15, 0xd3, 0xde, 0x27, 0x0a, + 0xd3, 0x12, 0x1c, 0xcc, 0xd3, 0x0a, 0x19, 0xff, 0x20, 0x15, 0xd7, 0xde, + 0x1c, 0x2b, 0xe2, 0x03, 0x32, 0xe5, 0xd0, 0xed, 0x27, 0x15, 0xdb, 0xfb, + 0x20, 0xe2, 0x00, 0x36, 0xf0, 0xdb, 0xe9, 0xf0, 0x0a, 0x19, 0x2b, 0xf0, + 0xd3, 0xde, 0x00, 0x12, 0x00, 0x19, 0x0e, 0xed, 0xd0, 0xf0, 0x24, 0x27, + 0x15, 0xed, 0xdb, 0xf0, 0x2b, 0x00, 0xc1, 0x00, 0x27, 0xf7, 0xf4, 0x3d, + 0x00, 0xd7, 0xf0, 0x1c, 0x12, 0xdb, 0xe9, 0x2b, 0x03, 0xd7, 0xde, 0x19, + 0xff, 0x03, 0x20, 0xf0, 0x00, 0xf4, 0x0e, 0x0a, 0xc9, 0xed, 0x27, 0x24, + 0xed, 0xde, 0x00, 0xe9, 0xe5, 0x24, 0x20, 0xe2, 0xdb, 0x2b, 0x20, 0xde, + 0xe5, 0x24, 0x0e, 0xf7, 0xf7, 0xf7, 0xff, 0x1c, 0xf4, 0xe9, 0xff, 0xed, + 0xf7, 0x24, 0x19, 0xde, 0xd0, 0x00, 0x2e, 0xff, 0xe2, 0xf7, 0x12, 0xf4, + 0xdb, 0x20, 0x03, 0xe5, 0xf4, 0x24, 0x12, 0xde, 0xe2, 0xfb, 0x20, 0x1c, + 0xf7, 0xed, 0x07, 0xf7, 0xed, 0x2e, 0x0e, 0xf7, 0x0e, 0x03, 0xde, 0xf0, + 0x2e, 0x1c, 0xde, 0xd3, 0xf4, 0x0a, 0xf0, 0x12, 0x15, 0xd7, 0xdb, 0x00, + 0x20, 0x19, 0xde, 0xcc, 0xf0, 0x12, 0xf7, 0x03, 0x32, 0x03, 0xf7, 0xf7, + 0xdb, 0xfb, 0x32, 0x20, 0xf0, 0xd3, 0xe2, 0x0a, 0x20, 0x07, 0x00, 0x19, + 0xed, 0xcc, 0xf4, 0x27, 0x1c, 0xe9, 0xe2, 0x19, 0x1c, 0xf4, 0xff, 0x07, + 0x00, 0xcc, 0xde, 0x15, 0x2b, 0x1c, 0xf0, 0xe9, 0xe2, 0xde, 0x12, 0x2e, + 0x0a, 0xd3, 0xe2, 0xf4, 0xed, 0x0a, 0x24, 0xff, 0xcc, 0x00, 0x36, 0xfb, + 0xc9, 0xed, 0x27, 0x0e, 0xe5, 0x0a, 0x15, 0x00, 0xc9, 0xf0, 0x24, 0xfb, + 0xe5, 0x24, 0x2e, 0xf7, 0xdb, 0xed, 0x0a, 0x00, 0x00, 0xfb, 0xfb, 0x07, + 0x19, 0x07, 0xe9, 0xcc, 0x00, 0x27, 0xf0, 0x03, 0x0e, 0xc1, 0xe2, 0x0e, + 0x24, 0x15, 0xf0, 0x00, 0xf0, 0x07, 0x00, 0xe2, 0xf0, 0x07, 0x27, 0xe5, + 0xe5, 0x27, 0x03, 0xd7, 0xde, 0x19, 0xff, 0xfb, 0x32, 0x0e, 0xde, 0xd0, + 0xed, 0x20, 0x24, 0x12, 0xf4, 0xdb, 0xf0, 0x19, 0x19, 0xff, 0xde, 0x0e, + 0x24, 0xdb, 0xde, 0x20, 0xf7, 0xc9, 0x20, 0x20, 0xd7, 0xd7, 0x24, 0x0e, + 0xc9, 0xf7, 0x32, 0xf7, 0xe5, 0x0e, 0x03, 0xf4, 0xf7, 0xf4, 0x00, 0x03, + 0xff, 0xf4, 0x12, 0x24, 0xff, 0xe5, 0xde, 0x03, 0x2e, 0x12, 0xe2, 0xcc, + 0xff, 0x24, 0xf4, 0x00, 0x19, 0xd7, 0xe9, 0x36, 0x27, 0xed, 0xe2, 0x03, + 0xed, 0xe2, 0x24, 0xfb, 0xde, 0x0e, 0x0e, 0xf0, 0xd7, 0x19, 0x32, 0x00, + 0xd0, 0xdb, 0x12, 0x32, 0x0a, 0xdb, 0xed, 0xf7, 0xfb, 0x32, 0x20, 0xed, + 0xd0, 0xde, 0x12, 0x27, 0x19, 0x03, 0xf4, 0xfb, 0xde, 0xe2, 0x00, 0x1c, + 0x24, 0xf4, 0xcc, 0xde, 0x0a, 0x12, 0xf7, 0x1c, 0x00, 0xc5, 0x00, 0x39, + 0x0a, 0xe9, 0xf4, 0xe2, 0xf0, 0x19, 0x20, 0xed, 0xf0, 0x03, 0xde, 0x00, + 0x2e, 0x27, 0x00, 0xf0, 0xe5, 0xe2, 0xff, 0x1c, 0x20, 0xe5, 0xd7, 0xf0, + 0x12, 0x2e, 0x0e, 0xf0, 0xe9, 0xdb, 0xfb, 0x2b, 0x15, 0xd3, 0xcc, 0x03, + 0x19, 0xdb, 0x07, 0x36, 0xfb, 0xcc, 0xf0, 0x2b, 0x07, 0xe5, 0xff, 0x19, + 0x00, 0xd3, 0x07, 0x2b, 0xf0, 0xc9, 0x00, 0x2e, 0x00, 0xde, 0x1c, 0x0a, + 0xc9, 0x03, 0x32, 0x00, 0xdb, 0x19, 0xff, 0xc9, 0x07, 0x2b, 0xe9, 0xd7, + 0x19, 0xff, 0xde, 0x19, 0x03, 0x00, 0x07, 0xf4, 0xd7, 0x12, 0x2b, 0xf4, + 0xe9, 0x20, 0xe9, 0xd7, 0x27, 0x19, 0xd3, 0xed, 0x27, 0x03, 0xf0, 0x15, + 0xe2, 0xe2, 0x03, 0x07, 0xff, 0x19, 0x00, 0xd0, 0x0a, 0x27, 0xe2, 0xed, + 0x2b, 0x0a, 0xd3, 0xed, 0x27, 0x00, 0xc9, 0xff, 0x2b, 0x03, 0xd7, 0x24, + 0x20, 0xd7, 0xd0, 0xf4, 0x20, 0x15, 0x03, 0x03, 0xe2, 0xde, 0x03, 0x32, + 0x12, 0xd7, 0xd7, 0x0a, 0x24, 0xf0, 0xe5, 0x12, 0x1c, 0xd0, 0xfb, 0x2e, + 0x27, 0xf4, 0xdb, 0xe2, 0xf0, 0xf4, 0x19, 0x2b, 0x12, 0xde, 0xdb, 0xf4, + 0x07, 0x15, 0x12, 0xf4, 0xde, 0xde, 0x15, 0x2b, 0x0e, 0xe5, 0xdb, 0xf0, + 0x0e, 0x32, 0x0e, 0xdb, 0xdb, 0x03, 0x0e, 0x0a, 0x2e, 0x00, 0xe9, 0xf4, + 0xdb, 0xf4, 0x15, 0x27, 0x00, 0xf0, 0x00, 0xf7, 0xdb, 0x03, 0x2b, 0xed, + 0xc9, 0x03, 0x2e, 0x19, 0xf0, 0xf0, 0xdb, 0xe2, 0x19, 0x27, 0x12, 0xd7, + 0xd3, 0xed, 0x12, 0x19, 0x0a, 0x19, 0x00, 0xd3, 0xed, 0x20, 0xfb, 0xed, + 0x1c, 0x0a, 0xde, 0xfb, 0x2e, 0x00, 0x0a, 0xf0, 0xcc, 0xff, 0x20, 0x24, + 0xf7, 0xfb, 0xe2, 0xd7, 0x19, 0x2e, 0x03, 0xd7, 0x00, 0xf4, 0xc9, 0x15, + 0x27, 0x03, 0xc9, 0xff, 0x2e, 0xfb, 0xde, 0xff, 0x00, 0xf4, 0x07, 0x00, + 0x03, 0x00, 0xf7, 0x0a, 0x24, 0xe5, 0xdb, 0x20, 0x2b, 0xf7, 0xf7, 0xf0, + 0xd3, 0x12, 0x32, 0x0e, 0xd3, 0xe9, 0x20, 0x0e, 0xe5, 0xed, 0xe9, 0xfb, + 0x19, 0x1c, 0xe9, 0xe9, 0x20, 0xed, 0xde, 0x0e, 0xed, 0xf7, 0x36, 0x19, + 0xde, 0xd7, 0x00, 0x03, 0xed, 0x27, 0x12, 0xd3, 0xe5, 0x15, 0xf0, 0xe5, + 0x12, 0x24, 0x0a, 0xf0, 0xfb, 0x07, 0xfb, 0xe2, 0xf7, 0x19, 0x15, 0x0a, + 0xf4, 0xff, 0x20, 0xf7, 0xe2, 0xe9, 0x07, 0x1c, 0x0e, 0x00, 0xe9, 0xd0, + 0xe5, 0x12, 0x27, 0x0a, 0xd0, 0xd3, 0x00, 0x0e, 0xff, 0x03, 0xe2, 0xff, + 0x27, 0x24, 0xf4, 0xd3, 0xff, 0x0a, 0xff, 0x19, 0xfb, 0xed, 0x15, 0x1c, + 0xf0, 0xde, 0xf7, 0x2b, 0x19, 0xd7, 0xd3, 0x03, 0x07, 0xe2, 0x24, 0x19, + 0xd7, 0xdb, 0x20, 0x2e, 0xf7, 0xd0, 0xf0, 0x20, 0x1c, 0xe2, 0xd7, 0x03, + 0xff, 0x12, 0x19, 0xd3, 0xd7, 0x12, 0x27, 0x03, 0xde, 0xfb, 0xf7, 0x07, + 0x24, 0x03, 0xde, 0xe2, 0x19, 0x19, 0x07, 0xe9, 0xe9, 0x19, 0x15, 0xff, + 0xd7, 0xdb, 0x15, 0x2e, 0x03, 0xdb, 0xdb, 0xfb, 0x0e, 0x00, 0x00, 0xff, + 0xe9, 0xf7, 0x15, 0x07, 0xed, 0xf7, 0x00, 0xff, 0x00, 0x0e, 0xf7, 0xe9, + 0x2b, 0x03, 0xd0, 0xf7, 0x0a, 0x19, 0x0a, 0x00, 0xf7, 0xdb, 0xf0, 0x32, + 0x12, 0xe2, 0x00, 0x0a, 0xd3, 0xed, 0x24, 0x15, 0xe2, 0xf4, 0x2e, 0x07, + 0xf0, 0xe5, 0xde, 0x07, 0x27, 0xf4, 0xe2, 0x1c, 0xfb, 0xc9, 0x00, 0x2e, + 0x00, 0xe9, 0x07, 0x0a, 0xe2, 0xd7, 0x03, 0x1c, 0x15, 0xf4, 0xe5, 0x0e, + 0x15, 0xfb, 0xed, 0xed, 0x12, 0xed, 0x1c, 0x32, 0xf7, 0xdb, 0xde, 0xf0, + 0x0a, 0x27, 0x12, 0x03, 0xfb, 0xd7, 0xe5, 0x07, 0x20, 0x1c, 0xf4, 0xf4, + 0xe5, 0xf0, 0x24, 0x00, 0xfb, 0xf7, 0xf7, 0xf0, 0x1c, 0x20, 0xd3, 0xd0, + 0x0a, 0x07, 0xe2, 0x2e, 0x24, 0xf7, 0xd7, 0xe9, 0xff, 0xf7, 0x12, 0x24, + 0x00, 0xcc, 0xe2, 0x20, 0x2b, 0x00, 0xd7, 0xf4, 0x0e, 0xed, 0x0e, 0x24, + 0xe9, 0xcc, 0xff, 0x2b, 0x15, 0x00, 0x00, 0x03, 0xd3, 0xdb, 0x03, 0x24, + 0x24, 0xff, 0xd7, 0x00, 0x00, 0xe5, 0x2e, 0x12, 0xd3, 0xde, 0x12, 0x1c, + 0xf7, 0x07, 0xf0, 0xd3, 0x00, 0x24, 0x15, 0xe2, 0xf7, 0x19, 0xe2, 0xd7, + 0x12, 0x27, 0x0e, 0xfb, 0xd7, 0xe5, 0x0e, 0x00, 0x0a, 0x19, 0xe9, 0xcc, + 0x00, 0x27, 0x0e, 0xe9, 0xe9, 0xed, 0x07, 0x27, 0x0e, 0xdb, 0xf4, 0x15, + 0xed, 0xf7, 0x19, 0xff, 0xff, 0x27, 0xf4, 0xdb, 0xff, 0x32, 0x20, 0xff, + 0xf4, 0xed, 0xde, 0xff, 0x2e, 0xff, 0xc5, 0xfb, 0x27, 0x00, 0xcc, 0x0e, + 0x1c, 0xd0, 0xe2, 0x1c, 0x07, 0xdb, 0x0a, 0x2b, 0x00, 0xf4, 0xed, 0xed, + 0x15, 0x0e, 0xf0, 0xf4, 0xed, 0xff, 0x15, 0x15, 0xff, 0x12, 0x00, 0xe9, + 0x00, 0x07, 0xf7, 0xe9, 0x1c, 0x24, 0xe5, 0xe9, 0x15, 0x07, 0xe5, 0x0e, + 0x07, 0xcc, 0x03, 0x39, 0x07, 0xd7, 0xe9, 0x0e, 0xf4, 0xfb, 0x2b, 0xed, + 0xc1, 0xe2, 0x07, 0x15, 0x19, 0x00, 0xff, 0xe5, 0xe5, 0x00, 0x00, 0x00, + 0xed, 0x03, 0x0a, 0xd3, 0x07, 0x2b, 0x00, 0xf4, 0xed, 0x00, 0x00, 0x03, + 0x27, 0x07, 0xde, 0xe2, 0x00, 0x27, 0x27, 0xf7, 0xd7, 0xd7, 0x0e, 0x2e, + 0x03, 0xf4, 0xf7, 0xe2, 0x0a, 0x20, 0xfb, 0xed, 0x19, 0xf7, 0xc1, 0xff, + 0x19, 0xfb, 0xff, 0x03, 0xd0, 0x03, 0x27, 0xe2, 0xf4, 0x20, 0xd3, 0xe2, + 0x24, 0x2b, 0xfb, 0xd3, 0x1c, 0x07, 0xc9, 0x19, 0x36, 0x07, 0xd7, 0x00, + 0x15, 0xe9, 0x27, 0x0a, 0xcc, 0xf0, 0x2b, 0x07, 0xe2, 0x19, 0x00, 0xf0, + 0xfb, 0xd0, 0x00, 0x2e, 0x19, 0xdb, 0xd3, 0xe9, 0xf4, 0x07, 0x20, 0x07, + 0xed, 0xf7, 0xe2, 0xf7, 0x27, 0x03, 0xdb, 0x03, 0x15, 0xf7, 0xf4, 0x0a, + 0x00, 0xe9, 0xff, 0xff, 0x0a, 0x07, 0x07, 0xe9, 0xed, 0x1c, 0x0a, 0xed, + 0x03, 0x1c, 0xe2, 0xdb, 0x20, 0x19, 0xd7, 0xf7, 0x36, 0x0a, 0xdb, 0xf0, + 0x12, 0xe9, 0xfb, 0x1c, 0x0e, 0xf7, 0xed, 0x00, 0xe9, 0xf4, 0x03, 0x00, + 0x20, 0xff, 0xcc, 0xe5, 0x12, 0x20, 0x03, 0xfb, 0xe2, 0xe9, 0x15, 0x12, + 0xfb, 0xd3, 0xf4, 0x24, 0x0e, 0x00, 0x07, 0xfb, 0xdb, 0xf0, 0x07, 0x19, + 0x27, 0xf4, 0xdb, 0x03, 0x0e, 0xe5, 0x0a, 0x20, 0xe2, 0xdb, 0x19, 0x1c, + 0xd7, 0xf4, 0x19, 0xe2, 0xe9, 0x12, 0x20, 0x00, 0xf0, 0xf7, 0xdb, 0xed, + 0x20, 0x27, 0x00, 0xcc, 0xdb, 0x0e, 0x24, 0x00, 0xe9, 0xf7, 0x0a, 0xff, + 0x0e, 0x27, 0xf4, 0xd3, 0xe9, 0x0a, 0x07, 0x12, 0x0a, 0x03, 0x00, 0xe9, + 0xd3, 0x00, 0x20, 0x1c, 0x00, 0xe5, 0xd7, 0xf0, 0x20, 0x2b, 0xff, 0xe2, + 0xed, 0xdb, 0x15, 0x2b, 0xf7, 0xcc, 0xff, 0x07, 0x07, 0x03, 0x0e, 0xf7, + 0xdb, 0x15, 0x00, 0xd0, 0x0a, 0x32, 0x03, 0xf4, 0xf4, 0xe9, 0x0e, 0x2b, + 0xf0, 0xc9, 0xe2, 0x15, 0x27, 0x15, 0xfb, 0xed, 0xe2, 0xe9, 0x12, 0x1c, + 0xe5, 0xed, 0x12, 0xfb, 0xe9, 0x07, 0x0e, 0x0e, 0xff, 0xf7, 0xff, 0xdb, + 0x0a, 0x15, 0xe2, 0xed, 0x07, 0x15, 0x19, 0x0a, 0xe2, 0xf0, 0xf0, 0xed, + 0x27, 0x24, 0xed, 0xe2, 0x12, 0xf7, 0xff, 0x1c, 0x00, 0xd0, 0xf0, 0x2b, + 0x03, 0xdb, 0x07, 0x2b, 0xf0, 0xd0, 0xfb, 0x0e, 0x03, 0x12, 0xfb, 0xe5, + 0xf7, 0xff, 0x2b, 0x2b, 0xf7, 0xe2, 0xe9, 0xf7, 0xed, 0xff, 0x0e, 0x24, + 0xf7, 0xd7, 0xf4, 0x0e, 0x15, 0x0e, 0xf4, 0xd3, 0xe2, 0x12, 0x19, 0x0e, + 0x12, 0xe5, 0xcc, 0xf7, 0x20, 0xff, 0x03, 0x1c, 0xdb, 0xe2, 0x27, 0x32, + 0x00, 0xe9, 0x15, 0xe9, 0xc9, 0x00, 0x27, 0x12, 0xf0, 0x00, 0xf7, 0xd7, + 0x15, 0x2b, 0x00, 0xd7, 0xe2, 0xf7, 0x15, 0x27, 0xf4, 0xe9, 0x0a, 0xe2, + 0xf4, 0x19, 0x12, 0xed, 0xd7, 0xff, 0x0a, 0xf4, 0x12, 0x2b, 0xfb, 0xe2, + 0xd0, 0xf4, 0x24, 0x0e, 0xf4, 0xf4, 0xe5, 0x0e, 0x2e, 0x00, 0xd0, 0xf4, + 0x2b, 0x00, 0xed, 0x19, 0x00, 0xd7, 0x19, 0x24, 0xe5, 0xf4, 0x19, 0x19, + 0xe9, 0xcc, 0xe5, 0x0a, 0x15, 0x20, 0x00, 0xdb, 0xe9, 0x0a, 0x20, 0x12, + 0xe5, 0xd0, 0xf0, 0x15, 0x2b, 0x12, 0xdb, 0xf0, 0x15, 0xe5, 0xe9, 0x15, + 0x12, 0xe2, 0xf0, 0x24, 0xf0, 0xd7, 0x07, 0x27, 0x0a, 0xcc, 0xe2, 0x24, + 0x1c, 0xe9, 0x07, 0x00, 0xd3, 0x24, 0x36, 0x00, 0xe2, 0xf7, 0x0e, 0xe9, + 0xe9, 0x07, 0x24, 0x12, 0xf7, 0xed, 0x00, 0xfb, 0x00, 0x2b, 0xed, 0xe2, + 0x20, 0x03, 0xd3, 0xf7, 0x00, 0xf7, 0x12, 0x0e, 0xe2, 0xde, 0x03, 0x2b, + 0x00, 0xde, 0xf0, 0x00, 0xf0, 0x12, 0xff, 0xde, 0x0a, 0x0e, 0xff, 0xe2, + 0xfb, 0x1c, 0x1c, 0xff, 0xed, 0xf0, 0x12, 0x19, 0x19, 0x00, 0xdb, 0xe9, + 0x27, 0x0a, 0xd0, 0x0a, 0x27, 0xe9, 0xe2, 0x2e, 0x19, 0xe2, 0xf4, 0x00, + 0xdb, 0x07, 0x15, 0xe2, 0xde, 0x00, 0x03, 0x07, 0x03, 0xf7, 0xe5, 0xf0, + 0x20, 0x03, 0xdb, 0x0e, 0x2e, 0xf7, 0xe5, 0xff, 0xe5, 0x00, 0x12, 0x07, + 0xf4, 0xf7, 0x2e, 0x19, 0xed, 0xf4, 0xfb, 0xf7, 0x03, 0x1c, 0x0e, 0xed, + 0xcc, 0xe9, 0x1c, 0x27, 0x15, 0xe2, 0xde, 0xfb, 0x15, 0x00, 0xe2, 0x00, + 0x03, 0x00, 0x0e, 0xfb, 0xd3, 0x07, 0x0e, 0xf4, 0xf4, 0xe2, 0x00, 0x2b, + 0x1c, 0xf7, 0xd3, 0xdb, 0x15, 0x32, 0x15, 0xde, 0xd0, 0xf7, 0x24, 0xf4, + 0xf4, 0x27, 0x12, 0xf4, 0x00, 0xff, 0xd0, 0x00, 0x2e, 0x1c, 0xe5, 0xd3, + 0xf7, 0x2e, 0x15, 0xe5, 0xde, 0xed, 0xf0, 0x15, 0x2b, 0x0a, 0xe2, 0xd7, + 0xff, 0x20, 0xf4, 0xde, 0x12, 0x07, 0xd0, 0xf0, 0x24, 0x07, 0xe2, 0x15, + 0x2b, 0xe5, 0xdb, 0x03, 0x0e, 0xff, 0xed, 0x0e, 0x03, 0xfb, 0x19, 0x0a, + 0xe2, 0xd3, 0x07, 0x12, 0xf7, 0x0a, 0x0a, 0x00, 0xfb, 0xfb, 0x00, 0x00, + 0xe2, 0xed, 0x0e, 0x1c, 0xde, 0xd7, 0x19, 0x0e, 0xf4, 0x0e, 0x0a, 0xf7, + 0xd0, 0xf0, 0x15, 0xf7, 0x00, 0x27, 0x12, 0xe2, 0xe2, 0x00, 0x0a, 0xf7, + 0x12, 0x20, 0xed, 0xd7, 0xf4, 0x15, 0x12, 0x00, 0xf4, 0x03, 0xe9, 0xe2, + 0x00, 0x1c, 0x15, 0xe9, 0xf0, 0x12, 0xf4, 0xfb, 0x27, 0x07, 0xd7, 0xe2, + 0xf7, 0xff, 0x27, 0x12, 0xff, 0xf4, 0xd3, 0xff, 0x07, 0x24, 0x12, 0xd7, + 0xe2, 0x07, 0xff, 0x07, 0x27, 0x00, 0xe9, 0xd0, 0xe9, 0x1c, 0x20, 0x12, + 0xf4, 0xd3, 0xe5, 0x1c, 0x2b, 0x07, 0xe5, 0xed, 0xf4, 0xf0, 0x15, 0x15, + 0xf0, 0x03, 0xfb, 0xfb, 0x00, 0x12, 0xed, 0x03, 0x24, 0xe2, 0xd0, 0x00, + 0x2e, 0x0e, 0xe2, 0xd7, 0xe5, 0x0a, 0x24, 0x0e, 0xe5, 0xd7, 0x03, 0x20, + 0xf0, 0x00, 0x19, 0xd0, 0x00, 0x36, 0x00, 0xd0, 0xe2, 0x07, 0x20, 0x12, + 0xe5, 0xff, 0xfb, 0x07, 0x19, 0xe9, 0xe2, 0x0a, 0x15, 0xed, 0xf4, 0xfb, + 0x00, 0xff, 0x19, 0x15, 0xdb, 0xd7, 0x15, 0x39, 0x12, 0xe9, 0xe9, 0xf7, + 0xed, 0x20, 0x27, 0xed, 0xd7, 0xf0, 0xfb, 0xf7, 0xff, 0x20, 0x07, 0xed, + 0xff, 0xe5, 0xff, 0x2b, 0x03, 0xd7, 0xf0, 0x00, 0xe9, 0x15, 0x2e, 0x07, + 0xde, 0xde, 0x03, 0x0a, 0x03, 0x24, 0x00, 0xd7, 0xed, 0x0a, 0x20, 0x19, + 0xdb, 0xde, 0x07, 0x00, 0xf4, 0x0e, 0xff, 0xf0, 0x15, 0x19, 0xe5, 0xe2, + 0x12, 0x19, 0xff, 0xfb, 0xde, 0xf0, 0x15, 0x1c, 0xe9, 0xe2, 0x24, 0x00, + 0xc9, 0x03, 0x20, 0xf7, 0xf0, 0x0a, 0xf0, 0xf0, 0x07, 0x07, 0xed, 0x00, + 0x19, 0xfb, 0xdb, 0x00, 0x0e, 0x00, 0x15, 0x0e, 0xdb, 0xe9, 0x0e, 0x12, + 0x0e, 0xf7, 0xd3, 0x0a, 0x36, 0x0e, 0xe5, 0xf7, 0x03, 0xde, 0x03, 0x32, + 0xf7, 0xd0, 0xed, 0x0e, 0xf7, 0xfb, 0x0a, 0xf4, 0x0a, 0x15, 0xed, 0xd3, + 0xed, 0x00, 0x0e, 0x27, 0x00, 0xcc, 0xf7, 0x32, 0x03, 0xd0, 0xf0, 0x20, + 0x1c, 0x07, 0x03, 0xde, 0xd3, 0x00, 0x24, 0x20, 0xf4, 0xd7, 0x07, 0x36, + 0x00, 0xd3, 0xfb, 0x15, 0x03, 0xff, 0x19, 0x00, 0xd7, 0xf4, 0x12, 0xed, + 0xe5, 0x24, 0x27, 0xf4, 0xed, 0xff, 0xd7, 0xed, 0x20, 0x24, 0xff, 0xdb, + 0xf0, 0xed, 0x03, 0x2b, 0x00, 0xde, 0xe5, 0x00, 0x24, 0x15, 0xff, 0xed, + 0xe5, 0x00, 0x0e, 0x15, 0xff, 0xe2, 0x07, 0x07, 0xe2, 0xf7, 0x27, 0x27, + 0x00, 0xf7, 0xde, 0xde, 0x15, 0x32, 0x00, 0xe5, 0x0e, 0xde, 0xde, 0x19, + 0x19, 0xe2, 0xc9, 0x07, 0x20, 0x03, 0xf7, 0x03, 0xe5, 0xd3, 0x0e, 0x20, + 0x0a, 0xe2, 0xed, 0x0e, 0x07, 0xf7, 0x03, 0x15, 0x0a, 0xff, 0xfb, 0xed, + 0xe2, 0x0a, 0x27, 0x12, 0xde, 0xf7, 0x20, 0xff, 0xdb, 0xe2, 0x19, 0x27, + 0x03, 0xe5, 0xf0, 0x00, 0x03, 0x03, 0xf7, 0xff, 0x07, 0xe5, 0xd3, 0x15, + 0x1c, 0xd7, 0xf0, 0x32, 0xff, 0xe2, 0x12, 0x07, 0xe2, 0x00, 0xff, 0xf4, + 0x2e, 0x1c, 0xe2, 0xd7, 0x0a, 0x19, 0xed, 0xf4, 0xff, 0xf4, 0x2b, 0x0e, + 0xd7, 0xed, 0x20, 0x00, 0xdb, 0x0e, 0x12, 0xe9, 0x00, 0x00, 0xf4, 0xff, + 0x15, 0xff, 0x0e, 0x0e, 0xe9, 0xe2, 0xe2, 0x00, 0x1c, 0x19, 0xf7, 0xe2, + 0x15, 0x19, 0xd7, 0xe9, 0x19, 0xf4, 0xde, 0x24, 0x20, 0xe9, 0xde, 0x07, + 0x0e, 0xfb, 0x03, 0xff, 0xe5, 0x12, 0xff, 0xd3, 0x0e, 0x36, 0x20, 0xfb, + 0xed, 0xf0, 0xe5, 0xf4, 0x24, 0x15, 0xde, 0xed, 0x07, 0xf4, 0x1c, 0x24, + 0xe9, 0xd0, 0xde, 0x0e, 0x24, 0x07, 0xe9, 0xf0, 0xf7, 0xf0, 0x15, 0x2b, + 0xff, 0xd7, 0xf4, 0x00, 0xde, 0x03, 0x2e, 0x20, 0xf4, 0xd3, 0xdb, 0x07, + 0x27, 0x24, 0xe9, 0xc9, 0xf4, 0x2b, 0x24, 0x00, 0xfb, 0xf4, 0xe5, 0xfb, + 0x12, 0x24, 0xe9, 0xe2, 0x0a, 0x00, 0xd7, 0x07, 0x2b, 0x03, 0xe5, 0xd0, + 0xf4, 0x0a, 0x1c, 0x00, 0xf0, 0x12, 0x00, 0xed, 0x0a, 0x12, 0xd0, 0xde, + 0x1c, 0x24, 0xff, 0xff, 0x2e, 0xf7, 0xd7, 0xf4, 0x0e, 0xf4, 0x00, 0x27, + 0xf7, 0xd3, 0x00, 0x12, 0x00, 0xff, 0xed, 0xe2, 0x1c, 0x1c, 0xfb, 0xfb, + 0xe2, 0xed, 0x20, 0x32, 0xff, 0xdb, 0xe9, 0xed, 0x00, 0x15, 0xfb, 0xfb, + 0x20, 0x03, 0xd0, 0xe5, 0x07, 0x07, 0x15, 0x12, 0xe9, 0xdb, 0x19, 0x24, + 0xfb, 0xf4, 0xfb, 0xed, 0xed, 0x0a, 0x1c, 0x00, 0xe5, 0xfb, 0x07, 0x0e, + 0x00, 0xfb, 0x03, 0xff, 0xdb, 0xe2, 0x00, 0x0a, 0x0a, 0x24, 0x0a, 0xde, + 0xde, 0x0a, 0x20, 0x03, 0x00, 0xed, 0xe5, 0x03, 0x24, 0x07, 0xdb, 0xf0, + 0xf7, 0x0a, 0x03, 0xfb, 0x00, 0x0a, 0x15, 0xe9, 0xd7, 0x03, 0x12, 0x00, + 0x0e, 0xf7, 0xcc, 0xff, 0x24, 0x00, 0xe9, 0x12, 0x0a, 0xed, 0xff, 0xed, + 0xff, 0x2b, 0x12, 0xd3, 0xe9, 0x0a, 0xf0, 0x03, 0x03, 0xfb, 0xf7, 0x0e, + 0x12, 0x07, 0x07, 0xed, 0xed, 0x03, 0x0a, 0xf4, 0x00, 0x12, 0xe2, 0xd0, + 0x0e, 0x12, 0xff, 0x0e, 0x0a, 0xf0, 0xf4, 0xfb, 0xfb, 0x00, 0xff, 0x15, + 0x03, 0xe2, 0xf0, 0x1c, 0x07, 0xe5, 0xe9, 0x1c, 0x20, 0xe5, 0xe5, 0x0a, + 0x00, 0x00, 0x24, 0xf4, 0xcc, 0xe2, 0x0a, 0x15, 0x15, 0x15, 0xe2, 0xde, + 0x15, 0x12, 0xf0, 0xfb, 0x1c, 0x00, 0xf7, 0xf0, 0xff, 0x07, 0x19, 0x00, + 0xcc, 0xf4, 0x20, 0x00, 0xf7, 0xfb, 0xfb, 0x0e, 0xf0, 0xf7, 0x20, 0x1c, + 0xde, 0xd0, 0xe5, 0x0e, 0x12, 0x0e, 0x12, 0xed, 0xde, 0x07, 0x1c, 0xed, + 0xe5, 0x0e, 0x20, 0xed, 0xdb, 0x0e, 0x00, 0xfb, 0x2e, 0x03, 0xd7, 0xf7, + 0x1c, 0x0a, 0xe2, 0xf4, 0x27, 0x03, 0xe9, 0x03, 0x0e, 0xff, 0xd7, 0xe2, + 0x07, 0xfb, 0x07, 0x20, 0xe9, 0xf7, 0x19, 0xf4, 0xed, 0x03, 0xff, 0x00, + 0xfb, 0xe9, 0x12, 0x12, 0xf0, 0xf7, 0x15, 0x00, 0xdb, 0x00, 0x0e, 0x00, + 0xf7, 0x15, 0x0a, 0xf7, 0xf7, 0xed, 0x00, 0x19, 0x00, 0xfb, 0xdb, 0xf7, + 0x20, 0x07, 0xfb, 0x19, 0xe5, 0xd3, 0x00, 0x12, 0x12, 0x0a, 0x03, 0xde, + 0xde, 0x00, 0x1c, 0x20, 0x00, 0xe9, 0xe2, 0x03, 0x0a, 0xf4, 0xff, 0xfb, + 0x12, 0x07, 0xe5, 0xe9, 0x07, 0x0a, 0x0a, 0x00, 0xd7, 0xfb, 0x20, 0x24, + 0xf0, 0xd3, 0xf7, 0x1c, 0x0e, 0x00, 0x00, 0xf7, 0xe2, 0x00, 0x1c, 0x00, + 0xe2, 0x0e, 0x0a, 0xff, 0x03, 0xd3, 0xfb, 0x2e, 0xff, 0xe2, 0x0a, 0x00, + 0xd0, 0x00, 0x20, 0x03, 0xff, 0x07, 0xf0, 0xcc, 0x0a, 0x32, 0x00, 0xd7, + 0xff, 0x03, 0xf0, 0xf0, 0x1c, 0x15, 0xe5, 0xed, 0xf4, 0xf7, 0x12, 0x03, + 0xf4, 0x07, 0xff, 0xf4, 0x0e, 0xf7, 0x00, 0x03, 0xe5, 0xed, 0x12, 0x27, + 0x12, 0xf0, 0xde, 0xf7, 0x15, 0x00, 0xf0, 0x0e, 0x15, 0xf4, 0xe9, 0x00, + 0xfb, 0xed, 0xf7, 0x1c, 0x24, 0xe9, 0xcc, 0xed, 0x27, 0x12, 0xdb, 0xfb, + 0x19, 0x12, 0x0e, 0xf0, 0xdb, 0xdb, 0x00, 0x27, 0x12, 0xde, 0xe2, 0x1c, + 0x27, 0xf4, 0xe5, 0xed, 0xff, 0x00, 0x20, 0x1c, 0xde, 0xd7, 0x15, 0x36, + 0x00, 0xd7, 0xfb, 0x20, 0x00, 0xed, 0xf7, 0xed, 0x03, 0x32, 0x0e, 0xf4, + 0xe2, 0xd0, 0x00, 0x24, 0x1c, 0xe9, 0xde, 0xf7, 0x00, 0x24, 0x00, 0xd3, + 0xed, 0x12, 0x0e, 0xde, 0xff, 0x0a, 0x03, 0xff, 0xe5, 0xf4, 0x03, 0x24, + 0x12, 0xe2, 0xd7, 0xe9, 0x0e, 0x24, 0x27, 0xfb, 0xe2, 0x0e, 0x00, 0xde, + 0x00, 0x1c, 0xff, 0xf7, 0x1c, 0xe5, 0xe5, 0x20, 0x20, 0xe9, 0xe5, 0xf7, + 0xe5, 0x00, 0x15, 0xff, 0xf0, 0x15, 0x15, 0xf0, 0xde, 0x00, 0x19, 0xf0, + 0xe5, 0x07, 0x03, 0xe2, 0x0a, 0x20, 0xf4, 0xdb, 0xf0, 0x0e, 0x0e, 0x00, + 0x0a, 0xf7, 0xd0, 0x03, 0x32, 0x07, 0xdb, 0xff, 0x19, 0x03, 0xdb, 0xed, + 0x1c, 0x24, 0x00, 0xfb, 0xf0, 0xd3, 0x03, 0x2b, 0x03, 0xe5, 0xe2, 0xed, + 0x0e, 0x24, 0x0e, 0xe9, 0xed, 0x07, 0x07, 0xff, 0xed, 0xe5, 0xf7, 0x19, + 0x19, 0xe5, 0xed, 0x1c, 0x00, 0xc5, 0xe2, 0x15, 0x12, 0x03, 0x03, 0xf0, + 0xf4, 0x1c, 0x19, 0xe2, 0xed, 0x12, 0x00, 0xfb, 0x03, 0x12, 0x12, 0xed, + 0xdb, 0x0e, 0x2e, 0xf4, 0xd7, 0xff, 0xfb, 0xdb, 0x0e, 0x2b, 0x12, 0xe5, + 0xe5, 0x03, 0xff, 0xdb, 0x19, 0x0e, 0xe9, 0xf7, 0x00, 0x03, 0x15, 0x00, + 0xd7, 0xe2, 0x0a, 0x03, 0x00, 0x12, 0xf7, 0xe2, 0x00, 0x15, 0xff, 0x0e, + 0x1c, 0xff, 0xd7, 0xe2, 0x0e, 0x24, 0x12, 0xf7, 0xf4, 0xfb, 0x00, 0x07, + 0x00, 0xe2, 0xed, 0x03, 0x07, 0x0a, 0x00, 0xff, 0xff, 0xe9, 0xe9, 0x03, + 0x07, 0xf7, 0x0e, 0x03, 0xd7, 0xf4, 0x24, 0x0a, 0xe5, 0x07, 0xfb, 0xed, + 0xed, 0x07, 0x1c, 0x00, 0xfb, 0xde, 0xfb, 0x20, 0x15, 0xfb, 0xde, 0xed, + 0x0e, 0x20, 0x0e, 0xf4, 0xd7, 0xe9, 0x12, 0x19, 0x0a, 0xff, 0xe5, 0xe9, + 0x1c, 0x19, 0xde, 0xe2, 0x12, 0x12, 0xe9, 0xed, 0xf7, 0x0e, 0x15, 0xf7, + 0xed, 0xed, 0xf0, 0x12, 0x27, 0x00, 0xd7, 0xe9, 0x07, 0x2b, 0x03, 0xe5, + 0xf4, 0x00, 0xf4, 0x19, 0x1c, 0xe9, 0xd7, 0x00, 0x32, 0x1c, 0xf0, 0xde, + 0xf0, 0x0a, 0x0e, 0xed, 0xde, 0x0a, 0x2b, 0x03, 0xde, 0xd3, 0x00, 0x2b, + 0x12, 0xf4, 0xe9, 0xf4, 0x07, 0x07, 0x07, 0x00, 0xd0, 0xf4, 0x1c, 0x0e, + 0xf0, 0xe9, 0xf4, 0xf4, 0x20, 0x20, 0xfb, 0xf0, 0xed, 0xff, 0x0a, 0x00, + 0xf4, 0x00, 0x00, 0xff, 0x0a, 0xf7, 0xe9, 0xff, 0x24, 0x1c, 0xde, 0xde, + 0x15, 0x1c, 0x00, 0xed, 0xf4, 0xff, 0x0a, 0x0e, 0xed, 0xfb, 0xff, 0xf0, + 0xf0, 0x15, 0x12, 0xe2, 0x00, 0x1c, 0xed, 0xde, 0x07, 0xf7, 0xe9, 0x00, + 0x12, 0x00, 0x0a, 0x0a, 0xf7, 0xe9, 0x0a, 0x24, 0xf4, 0xd7, 0x03, 0x20, + 0xf7, 0x00, 0x15, 0xd7, 0xf0, 0x27, 0xf4, 0xd7, 0x19, 0x12, 0xde, 0xf0, + 0x15, 0x24, 0x03, 0xf0, 0xe5, 0xf0, 0x00, 0x00, 0x20, 0x03, 0xd7, 0xf0, + 0x20, 0x1c, 0xff, 0xe9, 0xf4, 0x03, 0xff, 0xe2, 0xff, 0x24, 0x07, 0xe5, + 0xe5, 0x0e, 0x27, 0x00, 0xd7, 0xdb, 0x15, 0x12, 0x00, 0x03, 0xf0, 0xff, + 0xfb, 0x0a, 0x00, 0xff, 0xe2, 0xfb, 0x20, 0xf7, 0xed, 0x00, 0x0e, 0x19, + 0xf7, 0xe9, 0xfb, 0x00, 0x0e, 0x12, 0xe5, 0xd7, 0x19, 0x2b, 0x00, 0xf0, + 0xf0, 0xe5, 0xf7, 0x12, 0x2b, 0x07, 0xde, 0xd7, 0xfb, 0x2e, 0x15, 0xdb, + 0xcc, 0x00, 0x27, 0x03, 0xe2, 0xde, 0x00, 0x1c, 0x03, 0xe2, 0xf7, 0x0e, + 0x00, 0xff, 0xf4, 0xff, 0xf4, 0x20, 0x24, 0xfb, 0xdb, 0xe2, 0x0a, 0x27, + 0x20, 0xe9, 0xd3, 0xf7, 0x32, 0x12, 0xdb, 0xed, 0x07, 0xf7, 0x0a, 0x0e, + 0x03, 0xfb, 0xe2, 0x03, 0x03, 0x0a, 0x03, 0xf0, 0x03, 0x00, 0xe5, 0xe5, + 0x0a, 0x24, 0xff, 0xf4, 0xe2, 0xe9, 0x00, 0x20, 0x12, 0xde, 0xe9, 0x0a, + 0x03, 0x03, 0x1c, 0xf0, 0xcc, 0xf7, 0x27, 0x2b, 0x0e, 0xf0, 0xde, 0xf7, + 0x07, 0x0a, 0xff, 0x0a, 0x00, 0xe2, 0x00, 0x0e, 0x0a, 0x03, 0xf7, 0xd7, + 0xe9, 0x0e, 0x07, 0xfb, 0x12, 0xfb, 0xd3, 0x0a, 0x24, 0x00, 0x00, 0xfb, + 0xd0, 0xde, 0x15, 0x27, 0x12, 0xed, 0xe9, 0xdb, 0x0e, 0x32, 0x0a, 0xdb, + 0xe5, 0x00, 0x00, 0x0a, 0x20, 0x03, 0xde, 0xed, 0x07, 0xf4, 0x0a, 0x15, + 0xf7, 0xd7, 0xff, 0x19, 0x0e, 0x0e, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0xf7, + 0x0e, 0xfb, 0xd7, 0xfb, 0x19, 0x1c, 0x0a, 0xf4, 0xd7, 0xe2, 0xff, 0x20, + 0x27, 0x00, 0xd7, 0xde, 0x19, 0x27, 0xe2, 0xd7, 0x07, 0xff, 0xff, 0x1c, + 0x0e, 0xf7, 0xed, 0x00, 0x00, 0xf0, 0x00, 0x0a, 0x07, 0x00, 0xd3, 0xe9, + 0x27, 0x20, 0x0a, 0x00, 0xe9, 0xd3, 0xf0, 0x20, 0x24, 0xe9, 0xd3, 0x07, + 0x07, 0x00, 0x07, 0xf0, 0xdb, 0xf4, 0x19, 0xff, 0x00, 0xf4, 0xf7, 0x15, + 0x19, 0xf4, 0xd0, 0x0e, 0x2b, 0x07, 0xe5, 0xd3, 0x03, 0x2e, 0x19, 0xfb, + 0xfb, 0x00, 0xe5, 0xf0, 0x19, 0x12, 0xe5, 0xff, 0x15, 0xe2, 0xe5, 0x15, + 0x0a, 0x00, 0xed, 0xdb, 0x00, 0x15, 0x12, 0xed, 0xe9, 0x12, 0xff, 0xcc, + 0x00, 0x27, 0x0a, 0xe2, 0xe2, 0x0a, 0x15, 0x0e, 0x19, 0xf7, 0xdb, 0xed, + 0x1c, 0x07, 0xe9, 0x00, 0xf7, 0xf7, 0x20, 0x0e, 0xdb, 0xe2, 0x12, 0xfb, + 0xed, 0x27, 0x12, 0xe5, 0xe5, 0x00, 0x03, 0x0e, 0x00, 0x00, 0xff, 0xdb, + 0xf7, 0x1c, 0x20, 0xe2, 0xed, 0x2b, 0x00, 0xd0, 0x03, 0x20, 0xe9, 0xe9, + 0xf7, 0xf4, 0x07, 0x20, 0x0e, 0xe5, 0xd3, 0x00, 0x12, 0x0a, 0x0e, 0xe2, + 0xdb, 0x15, 0x24, 0xe9, 0xf7, 0x24, 0xf4, 0xcc, 0xf4, 0x0e, 0x24, 0x0e, + 0xf0, 0xf7, 0xfb, 0x00, 0xf7, 0x15, 0x00, 0xf4, 0xff, 0x00, 0x00, 0xe9, + 0x0e, 0x20, 0xe9, 0xdb, 0xfb, 0x19, 0x1c, 0xf7, 0xd7, 0xe9, 0x07, 0x2b, + 0x19, 0xdb, 0xd3, 0x00, 0x19, 0x00, 0xf4, 0xf4, 0x0a, 0x0a, 0xf7, 0x07, + 0x12, 0xe9, 0xde, 0xf7, 0x07, 0x1c, 0x03, 0xed, 0xde, 0x07, 0x15, 0xf0, + 0xf0, 0x24, 0x1c, 0xdb, 0xde, 0x07, 0x15, 0x03, 0x0a, 0xf7, 0xc5, 0xfb, + 0x20, 0x20, 0x03, 0xd3, 0xd7, 0x00, 0x2b, 0x20, 0xf0, 0xd3, 0xf4, 0x03, + 0xf7, 0x15, 0x19, 0xf7, 0xed, 0xff, 0x0e, 0xf7, 0xe9, 0x12, 0x12, 0xf4, + 0xe9, 0xfb, 0x0e, 0x20, 0x0e, 0xe2, 0xd3, 0xfb, 0x20, 0x20, 0x00, 0xe9, + 0xdb, 0xf4, 0x20, 0x24, 0xff, 0xd7, 0xe9, 0x0e, 0x00, 0xff, 0x19, 0xff, + 0xde, 0xff, 0x1c, 0x00, 0xe5, 0x03, 0x03, 0xe9, 0x0e, 0xff, 0xe9, 0x19, + 0x20, 0xe5, 0xdb, 0x00, 0x15, 0x00, 0xde, 0x00, 0x00, 0xf7, 0x0e, 0x12, + 0xfb, 0x00, 0x00, 0xe9, 0x00, 0x0a, 0x12, 0xff, 0xe5, 0xe9, 0x00, 0x1c, + 0x15, 0xe5, 0xcc, 0x03, 0x2b, 0x03, 0xde, 0xed, 0x19, 0x1c, 0x00, 0xf7, + 0xed, 0xe9, 0x0e, 0x0e, 0xf7, 0xe5, 0xf4, 0x0e, 0x20, 0x07, 0xe9, 0xe5, + 0x00, 0x1c, 0x00, 0xd7, 0xe2, 0xfb, 0x03, 0x15, 0x27, 0xfb, 0xcc, 0xf4, + 0x1c, 0x0a, 0xdb, 0xf0, 0x12, 0x20, 0x0e, 0xe5, 0xe9, 0x03, 0x19, 0x00, + 0x00, 0xf4, 0xf0, 0xff, 0x15, 0x07, 0xf0, 0x03, 0x20, 0x07, 0xe2, 0xd7, + 0xed, 0x0e, 0x00, 0xed, 0x03, 0x0e, 0x07, 0xff, 0xf7, 0xe5, 0xde, 0x07, + 0x19, 0xed, 0x00, 0x24, 0xfb, 0xe5, 0x00, 0x0e, 0x00, 0xfb, 0x00, 0xf7, + 0xf0, 0xfb, 0x19, 0x19, 0xff, 0xf7, 0xf0, 0x00, 0x12, 0x00, 0xcc, 0xf7, + 0x2b, 0x0e, 0xf4, 0x0a, 0x12, 0xf4, 0xf4, 0x00, 0xf4, 0xe9, 0x03, 0x20, + 0xff, 0xd3, 0xe9, 0x0a, 0x12, 0x03, 0xf4, 0xde, 0xfb, 0x19, 0x0a, 0xde, + 0xf0, 0x19, 0x03, 0x03, 0x19, 0xf4, 0xd3, 0xed, 0x0e, 0x27, 0x00, 0xdb, + 0x03, 0x27, 0xff, 0xde, 0x00, 0x0e, 0xff, 0xfb, 0x00, 0x00, 0x03, 0x00, + 0xf4, 0xf7, 0xff, 0x07, 0x12, 0x0a, 0xd3, 0xd7, 0x19, 0x24, 0xe5, 0xde, + 0x1c, 0x0e, 0xf0, 0xe9, 0xf7, 0xf4, 0x0a, 0x15, 0x03, 0xf0, 0xe2, 0x03, + 0x15, 0x0a, 0xde, 0xf0, 0x1c, 0x15, 0xf4, 0xd7, 0x07, 0x12, 0x00, 0x00, + 0xf4, 0x1c, 0xff, 0xe2, 0x12, 0x12, 0xe2, 0xe2, 0x27, 0x1c, 0xe2, 0xde, + 0x0a, 0x20, 0x15, 0xf0, 0xdb, 0xdb, 0x0e, 0x19, 0xfb, 0x03, 0xf4, 0xe5, + 0x0a, 0x2b, 0x00, 0xd3, 0xe9, 0x19, 0x24, 0xf7, 0xf4, 0xf7, 0xde, 0x1c, + 0x19, 0xf7, 0xf4, 0x12, 0x00, 0xf4, 0xde, 0xe5, 0x0a, 0x24, 0x19, 0xf4, + 0xe9, 0xe9, 0xfb, 0x24, 0x12, 0xed, 0xe5, 0xfb, 0x0e, 0x15, 0x12, 0xfb, + 0xf4, 0xe5, 0xe5, 0x0a, 0x20, 0x0e, 0xe2, 0xd3, 0xfb, 0x12, 0x1c, 0x0e, + 0xde, 0xde, 0xfb, 0x07, 0x00, 0x00, 0x00, 0xff, 0xf4, 0x07, 0x20, 0x00, + 0xe9, 0x0e, 0xf7, 0xd3, 0x03, 0x2e, 0x0e, 0xde, 0xf4, 0x12, 0xfb, 0x00, + 0x0a, 0xed, 0xf4, 0x0e, 0xed, 0xf4, 0x0e, 0x12, 0x03, 0xe9, 0xf0, 0x00, + 0x00, 0x03, 0x00, 0xe5, 0xdb, 0x12, 0x2b, 0x00, 0xe2, 0x00, 0x0e, 0xd3, + 0xe5, 0x19, 0x20, 0xfb, 0xde, 0xf0, 0x15, 0x20, 0x0a, 0xf0, 0xd3, 0xf0, + 0x0a, 0x19, 0x12, 0xf7, 0xfb, 0x00, 0x00, 0xed, 0x03, 0x0e, 0x0e, 0xf7, + 0xde, 0xf7, 0x00, 0x12, 0x07, 0xff, 0xfb, 0xf4, 0x00, 0x03, 0xf7, 0xf0, + 0x00, 0x0a, 0x00, 0x00, 0xf7, 0x0e, 0x0e, 0xe9, 0xd0, 0xf4, 0x19, 0x19, + 0x0e, 0xfb, 0xe5, 0xe2, 0x0e, 0x24, 0xf7, 0xe9, 0x03, 0x03, 0xff, 0xf7, + 0xf0, 0x00, 0x15, 0x15, 0x00, 0xed, 0xe2, 0xfb, 0x00, 0x0a, 0x15, 0x0e, + 0xff, 0xe2, 0xf7, 0x1c, 0x07, 0xde, 0xe5, 0x00, 0x12, 0x19, 0xff, 0xed, + 0x03, 0x00, 0xe9, 0xed, 0xf7, 0x24, 0x12, 0xff, 0xe5, 0xde, 0xf4, 0x1c, + 0x20, 0xed, 0xd7, 0x0a, 0x20, 0xf0, 0xe5, 0x0a, 0x0a, 0xf0, 0x03, 0x00, + 0xff, 0xff, 0x00, 0xff, 0xe5, 0x03, 0x12, 0x12, 0x0e, 0xe5, 0xe2, 0xfb, + 0xff, 0xff, 0x0e, 0x19, 0xff, 0xff, 0xf7, 0xe5, 0x00, 0x07, 0x0e, 0x00, + 0xe9, 0x00, 0x15, 0xff, 0xf4, 0xe5, 0xf4, 0x24, 0x15, 0xed, 0xf7, 0xe5, + 0xed, 0x03, 0x15, 0x07, 0xfb, 0x07, 0xfb, 0xff, 0x00, 0xf0, 0xf4, 0x07, + 0x15, 0x00, 0x00, 0xf4, 0xf7, 0xff, 0xe9, 0x03, 0x0e, 0x03, 0x00, 0x0a, + 0x0a, 0x00, 0xed, 0xe2, 0xfb, 0x27, 0x1c, 0xe5, 0xd0, 0xff, 0x1c, 0x00, + 0x00, 0xfb, 0xed, 0xf4, 0x0a, 0x0e, 0xfb, 0xe5, 0xf7, 0x03, 0xff, 0xe5, + 0x12, 0x27, 0xf7, 0xc9, 0xf0, 0x24, 0x00, 0xf7, 0x15, 0x15, 0xf4, 0xe2, + 0x03, 0x00, 0x00, 0x15, 0x00, 0xe9, 0xed, 0x12, 0x19, 0x00, 0xde, 0xed, + 0x27, 0x19, 0xf4, 0xed, 0xe2, 0x0a, 0x0e, 0xed, 0xf4, 0x0a, 0x15, 0xf7, + 0xe5, 0xe9, 0xff, 0x0e, 0x03, 0x15, 0xf7, 0xd3, 0x00, 0x1c, 0xf7, 0xf0, + 0x12, 0xff, 0xde, 0x07, 0x27, 0x00, 0xe9, 0xf4, 0x27, 0x0e, 0xd3, 0xe2, + 0x0e, 0x1c, 0xed, 0xe5, 0x0e, 0x00, 0xfb, 0x15, 0x00, 0xf0, 0xf7, 0x07, + 0x12, 0xf7, 0xfb, 0xf4, 0x00, 0x0a, 0x12, 0x0a, 0xe5, 0xe5, 0xff, 0xff, + 0x03, 0x03, 0x0a, 0x00, 0xff, 0xf4, 0xff, 0x0a, 0xfb, 0xfb, 0xfb, 0xe9, + 0x00, 0x15, 0x07, 0x07, 0xe9, 0xed, 0x12, 0x00, 0xf0, 0x00, 0x00, 0x00, + 0x0a, 0xf4, 0xfb, 0x0a, 0xf7, 0xed, 0x12, 0x07, 0xe5, 0xf4, 0x1c, 0x15, + 0xe5, 0xf7, 0x20, 0x00, 0xed, 0xff, 0xe9, 0xf0, 0x0e, 0x07, 0xfb, 0xf4, + 0x15, 0x03, 0x00, 0xf4, 0xe2, 0x03, 0x0e, 0x00, 0x07, 0xf7, 0xf4, 0xf4, + 0x00, 0x19, 0x15, 0xe9, 0xdb, 0x07, 0x19, 0x07, 0xd7, 0xf0, 0x27, 0x19, + 0xe9, 0xe5, 0xf4, 0x07, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x1c, 0x07, 0xdb, + 0xe2, 0x00, 0x0e, 0x20, 0xfb, 0xdb, 0x00, 0x00, 0xfb, 0x00, 0x07, 0xff, + 0xe9, 0xfb, 0x12, 0xfb, 0x00, 0x00, 0xf0, 0xff, 0x0a, 0x24, 0xfb, 0xe2, + 0xe2, 0xfb, 0x12, 0xff, 0x07, 0x1c, 0xfb, 0xdb, 0xff, 0x1c, 0xf0, 0xf0, + 0x12, 0x03, 0xed, 0xf0, 0xfb, 0x20, 0x07, 0xe5, 0xed, 0x07, 0x1c, 0xf7, + 0xf7, 0x19, 0xff, 0xd3, 0x03, 0x24, 0xf0, 0xe5, 0x0a, 0x12, 0xde, 0xde, + 0x15, 0x0e, 0xe5, 0x00, 0x0e, 0xf7, 0xf4, 0x00, 0x03, 0x00, 0xed, 0x07, + 0x0a, 0xff, 0x00, 0x00, 0xe5, 0xed, 0x0a, 0x1c, 0x0e, 0xf0, 0xf0, 0x0e, + 0x00, 0xf0, 0x00, 0x00, 0x03, 0x07, 0xf4, 0xe2, 0x07, 0x20, 0xf4, 0xdb, + 0x19, 0x0a, 0xde, 0xf7, 0x07, 0xfb, 0x00, 0x07, 0xed, 0xe2, 0x07, 0x12, + 0xf7, 0xfb, 0x00, 0xf7, 0x07, 0x03, 0xfb, 0xf0, 0x00, 0x1c, 0x00, 0xf0, + 0xf4, 0xf7, 0xf7, 0x15, 0x19, 0xde, 0xf7, 0x15, 0x00, 0xff, 0xf7, 0x00, + 0x07, 0xed, 0x03, 0x24, 0xff, 0xde, 0xfb, 0x15, 0x0a, 0xe9, 0xf4, 0x07, + 0xed, 0x0e, 0x1c, 0xdb, 0xdb, 0x20, 0x19, 0xd7, 0xde, 0x07, 0x07, 0xfb, + 0xf7, 0xf7, 0xff, 0x12, 0x15, 0x00, 0x00, 0xf0, 0xde, 0x0a, 0x20, 0xde, + 0xdb, 0x27, 0x24, 0xed, 0xf0, 0x1c, 0xf4, 0xcc, 0x07, 0x2b, 0x0e, 0xe5, + 0xff, 0x12, 0xf0, 0xff, 0x12, 0x00, 0xff, 0xe9, 0xdb, 0x12, 0x19, 0xe9, + 0xed, 0x24, 0x03, 0xe9, 0xf4, 0x03, 0x00, 0xe5, 0xf4, 0x0a, 0xed, 0xf7, + 0x24, 0x15, 0xf0, 0xe5, 0xe5, 0x12, 0x15, 0xed, 0xfb, 0x12, 0x07, 0xf0, + 0x07, 0x0e, 0xed, 0xe9, 0x07, 0x0e, 0xed, 0x00, 0x03, 0xf0, 0x0e, 0x19, + 0xff, 0xe9, 0xe9, 0xfb, 0x12, 0x0e, 0xe2, 0xd3, 0x07, 0x27, 0x19, 0xf4, + 0xe5, 0xf7, 0x00, 0x00, 0xff, 0xf4, 0x00, 0x0e, 0x00, 0xfb, 0xfb, 0x07, + 0x00, 0xe2, 0xf4, 0x03, 0x00, 0x0e, 0x07, 0xed, 0xed, 0x15, 0x12, 0x00, + 0x07, 0xe2, 0xde, 0xfb, 0x12, 0x0e, 0x00, 0x0e, 0x03, 0xeb, 0xe7, 0x0e, + 0x1c, 0xf9, 0xee, 0xf2, 0xfd, 0x1c, 0x20, 0xf6, 0xd9, 0xe7, 0x15, 0x1c, + 0xf6, 0xee, 0x00, 0xfd, 0xe4, 0x03, 0x1c, 0x03, 0xfd, 0x00, 0xe7, 0xe7, + 0xfd, 0x0e, 0x20, 0x0a, 0xe4, 0xd9, 0x19, 0x24, 0xf2, 0x00, 0x12, 0xee, + 0xd9, 0x1c, 0x2e, 0x00, 0xe0, 0xfd, 0x19, 0xf2, 0xf9, 0x15, 0x03, 0xe0, + 0xf6, 0x12, 0x07, 0xf9, 0xf2, 0xf6, 0x19, 0x03, 0xca, 0xf2, 0x24, 0x20, + 0xeb, 0xd2, 0x00, 0x0e, 0x07, 0x00, 0xee, 0xf6, 0x07, 0x12, 0x03, 0xfd, + 0xe7, 0xfd, 0x15, 0x03, 0xf6, 0xf6, 0x00, 0x07, 0x0e, 0x00, 0x00, 0xf9, + 0xf6, 0x00, 0x00, 0x03, 0xfd, 0xf9, 0x00, 0x0a, 0x03, 0xeb, 0x00, 0x24, + 0xeb, 0xe0, 0xf2, 0x00, 0x00, 0x15, 0x24, 0xe7, 0xd2, 0xeb, 0x1c, 0x19, + 0x00, 0xf2, 0xe0, 0x00, 0x0e, 0x12, 0x07, 0xeb, 0x00, 0x00, 0xf6, 0x03, + 0x0a, 0xeb, 0xee, 0x12, 0x03, 0xfd, 0x0e, 0x15, 0x00, 0xe7, 0xe4, 0xf9, + 0x12, 0x29, 0x07, 0xf2, 0x00, 0x03, 0x00, 0xee, 0xf9, 0x03, 0x00, 0x07, + 0x03, 0x0a, 0xf9, 0xfd, 0xfd, 0xf9, 0xf6, 0x0e, 0x19, 0xe7, 0xdc, 0xee, + 0x03, 0x29, 0x12, 0xe4, 0xe7, 0x07, 0x0a, 0xf2, 0xf2, 0x03, 0x00, 0xe7, + 0x15, 0x22, 0x00, 0x00, 0x00, 0xe0, 0xdc, 0x0e, 0x2d, 0x0a, 0xdc, 0xf2, + 0x07, 0x00, 0x07, 0x0e, 0x00, 0xeb, 0xee, 0x00, 0x1b, 0x00, 0xf6, 0x03, + 0xf9, 0xfd, 0x1b, 0x12, 0xe0, 0xe0, 0xfd, 0x00, 0x00, 0x0a, 0x00, 0x07, + 0x0a, 0xee, 0xe0, 0xf6, 0xfd, 0x0e, 0x12, 0x00, 0x00, 0xf9, 0x00, 0x0a, + 0xdc, 0xee, 0x1b, 0x1b, 0xf6, 0xd7, 0x0a, 0x25, 0xeb, 0xee, 0x30, 0x00, + 0xdc, 0x00, 0x03, 0xf2, 0x0a, 0x17, 0xf6, 0xeb, 0x07, 0x13, 0x00, 0x00, + 0xf2, 0xdb, 0xf9, 0x17, 0x0e, 0x0a, 0x0a, 0xe0, 0xdb, 0xf6, 0x1e, 0x17, + 0xf6, 0x00, 0x00, 0xdc, 0xee, 0x17, 0x29, 0x00, 0xdb, 0xee, 0x07, 0xf9, + 0x0a, 0x25, 0x00, 0xd7, 0xe4, 0x1b, 0x22, 0xf9, 0x00, 0x03, 0xe4, 0xe7, + 0x03, 0x25, 0x22, 0xf9, 0xe0, 0xe4, 0x00, 0x1b, 0x0e, 0x03, 0xf2, 0xdb, + 0x00, 0x1e, 0x10, 0xe7, 0xee, 0x03, 0x07, 0xeb, 0x00, 0x1b, 0xf9, 0xd7, + 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0xe4, 0xf6, 0x0a, 0x0e, 0x00, 0xf9, + 0x0a, 0xfd, 0x0c, 0x0c, 0xeb, 0xe2, 0x10, 0x0a, 0xeb, 0x0c, 0x0a, 0xeb, + 0xf9, 0x17, 0x13, 0xf9, 0xf6, 0x00, 0xf6, 0xf6, 0x07, 0x0a, 0x0a, 0x00, + 0xf9, 0xe2, 0xf6, 0x13, 0x0a, 0xe7, 0xf9, 0x0c, 0xeb, 0x00, 0x2b, 0xf9, + 0xd3, 0x00, 0x13, 0x00, 0xf6, 0x07, 0x00, 0x03, 0xfd, 0xfd, 0x07, 0x13, + 0x03, 0xee, 0xf6, 0x10, 0xf9, 0xee, 0x1b, 0x1e, 0xeb, 0xde, 0x0a, 0x17, + 0xeb, 0xe2, 0xfd, 0x1e, 0x10, 0x00, 0xf6, 0xf9, 0xfd, 0x00, 0x07, 0xfd, + 0xee, 0xf9, 0x00, 0xf6, 0x03, 0x00, 0x00, 0x0c, 0x00, 0xe2, 0xf9, 0x13, + 0x00, 0xe9, 0xfd, 0xfd, 0x10, 0x17, 0xfd, 0x00, 0xeb, 0xe5, 0x07, 0x10, + 0x09, 0x07, 0x03, 0x07, 0xf6, 0xee, 0x0c, 0x07, 0xe5, 0x07, 0x1b, 0xe9, + 0xf2, 0x13, 0x0c, 0xed, 0xed, 0x07, 0x00, 0x09, 0x00, 0xf9, 0xfd, 0xf9, + 0xf9, 0xfd, 0x07, 0x13, 0xfd, 0xed, 0xf9, 0xf2, 0xfd, 0x09, 0x0c, 0x09, + 0x00, 0xfd, 0x00, 0xee, 0xe2, 0x10, 0x10, 0xed, 0xf9, 0x09, 0x0c, 0x0c, + 0x07, 0xe9, 0xf2, 0x00, 0x10, 0x1b, 0xf6, 0xf2, 0x00, 0x00, 0xf6, 0x00, + 0x1b, 0x07, 0xf9, 0xed, 0xed, 0xf9, 0x17, 0x13, 0xf2, 0xf9, 0x17, 0x00, + 0xdc, 0xe9, 0xee, 0x00, 0x10, 0x03, 0x00, 0x07, 0x00, 0xee, 0xfd, 0xed, + 0x00, 0x24, 0x13, 0xf6, 0xe9, 0xfd, 0x00, 0x07, 0x0c, 0x07, 0xee, 0x00, + 0x17, 0xed, 0xe9, 0x17, 0x20, 0xf0, 0xf9, 0x17, 0x00, 0xf2, 0xf2, 0xfd, + 0xf9, 0x00, 0x03, 0x20, 0x13, 0xf2, 0xdc, 0xe5, 0x0c, 0x13, 0x00, 0x00, + 0x00, 0xf0, 0xe2, 0x00, 0x24, 0x00, 0xd2, 0xfd, 0x0c, 0xed, 0x03, 0x09, + 0x00, 0x00, 0xfd, 0xf6, 0x0c, 0x1c, 0x00, 0xe5, 0xdc, 0xf6, 0x10, 0x15, + 0x1c, 0x03, 0xe5, 0xd5, 0x00, 0x25, 0x20, 0x07, 0xed, 0xf9, 0x03, 0xf9, + 0x0c, 0x10, 0xf9, 0xf2, 0xfd, 0xfd, 0x00, 0x15, 0x00, 0xd5, 0xe9, 0x10, + 0x15, 0xf6, 0x00, 0x09, 0xd9, 0xd5, 0x03, 0x19, 0x13, 0x03, 0x00, 0xf0, + 0xe5, 0x00, 0x1c, 0x1c, 0xf9, 0xed, 0xed, 0x05, 0x00, 0xf2, 0x00, 0x09, + 0x10, 0xfd, 0xf9, 0xf2, 0x03, 0x03, 0x00, 0x00, 0xf9, 0x05, 0x10, 0x05, + 0xe5, 0xf9, 0x0c, 0x00, 0xf9, 0x00, 0x13, 0xe4, 0xe5, 0x15, 0x09, 0xe0, + 0xf4, 0x19, 0x0c, 0xf4, 0xfd, 0x00, 0xed, 0xf6, 0x09, 0x15, 0x00, 0xf9, + 0x00, 0xf9, 0xf9, 0xfd, 0x0c, 0x15, 0x00, 0xe9, 0xf6, 0x09, 0xe9, 0x00, + 0x19, 0x10, 0xed, 0xe9, 0x0c, 0x15, 0x05, 0xe7, 0xe7, 0x05, 0x0c, 0x03, + 0x00, 0x09, 0xe4, 0xe0, 0x10, 0x09, 0xf0, 0x09, 0x15, 0xf0, 0xe4, 0x00, + 0x10, 0x00, 0x05, 0xfd, 0xed, 0x00, 0x15, 0x03, 0xe7, 0xf9, 0x00, 0xf9, + 0x15, 0x15, 0xf4, 0xf4, 0x0c, 0xf6, 0xe0, 0x09, 0x22, 0x0c, 0xf4, 0xfd, + 0x03, 0xf0, 0xfd, 0x09, 0xf6, 0xf9, 0x15, 0x0c, 0xf9, 0xf9, 0xf6, 0xf6, + 0x00, 0x19, 0x05, 0xed, 0xe7, 0xed, 0x00, 0x1c, 0x10, 0xf0, 0xf9, 0x05, + 0x00, 0xf4, 0xf4, 0xf9, 0x00, 0x0c, 0x00, 0xfd, 0x00, 0x09, 0x15, 0x00, + 0xdb, 0xed, 0x12, 0x10, 0x05, 0xf6, 0xf6, 0x10, 0x03, 0xe7, 0x00, 0x22, + 0xfd, 0xde, 0x00, 0x15, 0xf0, 0xeb, 0x19, 0x1e, 0xf9, 0xeb, 0xf6, 0x09, + 0x00, 0xeb, 0xfd, 0x05, 0x03, 0x09, 0x15, 0xf4, 0xde, 0xf9, 0x03, 0xf9, + 0x00, 0x12, 0x03, 0xfd, 0x00, 0xfd, 0xfd, 0xf9, 0x05, 0x00, 0xed, 0xfd, + 0x00, 0x00, 0x19, 0x09, 0xe4, 0x05, 0x19, 0x00, 0xeb, 0xed, 0x03, 0x15, + 0x00, 0xfd, 0x00, 0x05, 0x00, 0xf4, 0x00, 0x12, 0xf9, 0xed, 0x0e, 0x03, + 0xeb, 0xf4, 0x0c, 0x03, 0xf0, 0xfd, 0xfd, 0x03, 0x03, 0xf6, 0xf0, 0xed, + 0x00, 0x05, 0x15, 0x12, 0xe7, 0xe2, 0x0c, 0x0c, 0xf0, 0x05, 0x24, 0x00, + 0xed, 0xfd, 0xeb, 0xf4, 0x15, 0x20, 0x00, 0xeb, 0xf4, 0x00, 0x00, 0x09, + 0x0c, 0xed, 0xed, 0x09, 0x05, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x00, 0xe4, 0xf4, 0x09, 0x00, 0x00, 0x1b, 0xf4, 0xd5, 0xf4, + 0x1b, 0x09, 0xf7, 0x00, 0x12, 0xf9, 0xf4, 0x0c, 0x09, 0xf7, 0xeb, 0x09, + 0x0e, 0xf4, 0x00, 0x00, 0xf9, 0xee, 0xfd, 0x0e, 0x09, 0x00, 0x09, 0xf0, + 0xdc, 0x00, 0x0e, 0x0c, 0x0e, 0x00, 0xeb, 0xf9, 0x00, 0xf0, 0x05, 0x1b, + 0x00, 0xe7, 0x00, 0x20, 0xf7, 0xe5, 0xee, 0x00, 0x03, 0x03, 0x0e, 0x03, + 0xee, 0xe7, 0x03, 0x09, 0x15, 0x00, 0xe2, 0xf4, 0x0c, 0xf4, 0xf0, 0x1c, + 0x17, 0xf4, 0xee, 0x09, 0x05, 0xf0, 0xfd, 0xf7, 0xf9, 0x0c, 0x13, 0x09, + 0x00, 0xeb, 0xf7, 0xfd, 0x00, 0x13, 0x0a, 0xfd, 0xe2, 0xee, 0x0a, 0x13, + 0x00, 0xee, 0xfd, 0x0a, 0x00, 0xf0, 0x00, 0x05, 0xf4, 0x00, 0x05, 0x05, + 0x0a, 0xfd, 0xf4, 0x00, 0x00, 0xf0, 0x00, 0x20, 0x12, 0xf0, 0xee, 0x09, + 0x00, 0xf4, 0x12, 0x00, 0xf4, 0x03, 0xf9, 0xf0, 0x13, 0x13, 0xe9, 0xeb, + 0x12, 0x0e, 0xf4, 0xf9, 0xf9, 0xf0, 0x09, 0x09, 0x00, 0x09, 0x00, 0xeb, + 0xeb, 0xf9, 0x03, 0x00, 0x12, 0x1b, 0xf9, 0xeb, 0xf7, 0x0a, 0x0e, 0xf9, + 0xf0, 0x00, 0x05, 0xfd, 0x05, 0x00, 0xf4, 0x00, 0x03, 0x09, 0x0e, 0xeb, + 0xe9, 0x00, 0x00, 0x00, 0x13, 0x05, 0xee, 0xf9, 0x0a, 0xf4, 0xee, 0x17, + 0x12, 0xe9, 0xf4, 0x05, 0x00, 0x00, 0x00, 0xee, 0xf7, 0x0e, 0x03, 0xfd, + 0x12, 0xf2, 0xe4, 0x00, 0x0e, 0x00, 0x0a, 0xfd, 0xee, 0x05, 0xf9, 0xfd, + 0x17, 0x12, 0xf7, 0xe9, 0x05, 0x00, 0xeb, 0x17, 0x13, 0xee, 0xeb, 0x05, + 0x01, 0x01, 0x01, 0xf2, 0xf2, 0x00, 0x01, 0x00, 0xf7, 0x05, 0x01, 0xeb, + 0x00, 0x00, 0x00, 0x0a, 0x13, 0xf2, 0xe0, 0x0a, 0x19, 0xf2, 0xf7, 0x05, + 0xf7, 0xf7, 0x17, 0x09, 0xf9, 0xf4, 0xfd, 0x01, 0x00, 0x01, 0xf9, 0xf7, + 0x05, 0x00, 0xf2, 0x00, 0x01, 0x05, 0x09, 0xfd, 0xf2, 0xfd, 0xf9, 0x00, + 0x0a, 0x10, 0xfd, 0xe9, 0xfd, 0x09, 0x00, 0xf9, 0x00, 0x01, 0x01, 0x00, + 0xee, 0xf9, 0x05, 0x05, 0x00, 0x01, 0x09, 0xed, 0xe4, 0x09, 0x0e, 0xf9, + 0x00, 0x09, 0xf7, 0xe5, 0x09, 0x19, 0xfd, 0xf9, 0x09, 0xe9, 0xee, 0x19, + 0x15, 0xfd, 0xf4, 0x00, 0xf7, 0xf7, 0x19, 0x10, 0xf4, 0xf9, 0x00, 0xee, + 0x05, 0x19, 0x01, 0xe7, 0xed, 0x0a, 0x00, 0xfd, 0x10, 0x01, 0xe7, 0xed, + 0x00, 0x09, 0x0a, 0xf7, 0x00, 0x00, 0xe4, 0xf4, 0x09, 0x1b, 0x10, 0xf2, + 0xde, 0xfd, 0x13, 0x00, 0xfb, 0x00, 0x0a, 0x00, 0xed, 0x0e, 0x1b, 0xf7, + 0xf2, 0x01, 0x00, 0xf2, 0x10, 0x13, 0xed, 0xf4, 0x0a, 0x00, 0x00, 0x0e, + 0x00, 0xee, 0xf7, 0x00, 0x00, 0x01, 0x09, 0x05, 0xf7, 0x00, 0xf7, 0xed, + 0x15, 0x0a, 0xe9, 0xf4, 0x05, 0x09, 0x00, 0xee, 0xf7, 0x00, 0x00, 0x00, + 0x05, 0x00, 0xf7, 0xf7, 0x00, 0x20, 0x13, 0xed, 0xe7, 0xf7, 0x00, 0x05, + 0x15, 0x0e, 0xf2, 0xe7, 0xfd, 0x00, 0x13, 0x15, 0xf6, 0xe2, 0xf7, 0x07, + 0x01, 0x00, 0x13, 0x01, 0xed, 0xe9, 0x07, 0x1b, 0x0a, 0xf7, 0xe9, 0xf7, + 0xfb, 0x13, 0x20, 0xee, 0xdc, 0xee, 0x05, 0x0a, 0x00, 0x00, 0x00, 0xf6, + 0xf7, 0x05, 0x00, 0x00, 0x15, 0xfd, 0xe9, 0xf7, 0x00, 0x07, 0x1b, 0xfd, + 0xe7, 0xf6, 0x0c, 0x17, 0x01, 0xf6, 0xfb, 0x01, 0xf6, 0xfd, 0x17, 0x0c, + 0xe5, 0xeb, 0x15, 0x12, 0xf0, 0xf2, 0xf7, 0x01, 0x10, 0x0a, 0x00, 0xf6, + 0xed, 0xed, 0x00, 0x01, 0x07, 0x05, 0x00, 0xf7, 0xed, 0xf2, 0x0c, 0x1c, + 0x05, 0xeb, 0xf0, 0xfd, 0x07, 0x1b, 0xf7, 0xdc, 0xfd, 0x12, 0x0c, 0x01, + 0xfd, 0xf6, 0x00, 0xfb, 0x00, 0x12, 0x12, 0x00, 0xed, 0xed, 0xfd, 0x01, + 0x0c, 0x12, 0x07, 0xfb, 0xe2, 0xed, 0x0c, 0x22, 0x01, 0xe2, 0xf6, 0x00, + 0xfb, 0x0a, 0x0c, 0xf6, 0xe7, 0xf0, 0xfd, 0x12, 0x0a, 0xf2, 0xf0, 0x00, + 0x0a, 0x00, 0xf7, 0x07, 0x12, 0xf0, 0xdc, 0x00, 0x15, 0x07, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x0a, 0x00, 0xed, 0xf7, 0x10, 0x07, 0xfd, 0x05, 0x00, + 0xf7, 0xfd, 0x01, 0xf6, 0xf6, 0x12, 0x10, 0xe7, 0xeb, 0x12, 0x01, 0xed, + 0xfd, 0x00, 0xf7, 0x05, 0x07, 0xeb, 0xf0, 0x0a, 0x15, 0x01, 0xf7, 0xfd, + 0x00, 0xf0, 0x00, 0x15, 0x00, 0xf6, 0xfd, 0x0a, 0x07, 0xfd, 0xf6, 0x0c, + 0x0a, 0xe4, 0x00, 0x17, 0x0c, 0xf6, 0xf0, 0x07, 0x05, 0xfd, 0x00, 0x00, + 0xfb, 0xfb, 0xfb, 0xfb, 0x0c, 0x01, 0xf2, 0x07, 0x05, 0xf2, 0x00, 0x00, + 0x00, 0xfd, 0xf2, 0x07, 0x01, 0xf7, 0x00, 0x00, 0x05, 0x01, 0xf6, 0xeb, + 0x01, 0x07, 0x00, 0x00, 0x05, 0xf2, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0xfb, 0xf6, 0x00, 0x10, 0x00, 0xf0, 0x07, 0x0c, 0x00, 0x01, 0xf6, 0xeb, + 0x01, 0x12, 0x00, 0xee, 0x00, 0x0c, 0x00, 0xfb, 0x00, 0xf6, 0x00, 0x19, + 0x01, 0xeb, 0xf0, 0xfd, 0x12, 0x0e, 0xeb, 0xee, 0x0c, 0x00, 0xf7, 0x00, + 0xf7, 0xfd, 0x0c, 0x13, 0xfb, 0xe4, 0xfd, 0x0c, 0x07, 0xfb, 0xfb, 0xfd, + 0x00, 0x07, 0xfb, 0xfd, 0x0a, 0x07, 0xfb, 0xfd, 0xfd, 0xf7, 0x00, 0x0a, + 0x05, 0x00, 0xfb, 0x00, 0x05, 0xf6, 0x05, 0x05, 0xe9, 0x00, 0x0e, 0xf4, + 0x00, 0x12, 0xee, 0xeb, 0x0c, 0x13, 0xf6, 0xee, 0x00, 0x00, 0xf7, 0x05, + 0x09, 0xfd, 0x05, 0x05, 0xf4, 0xf7, 0xf6, 0xfb, 0x12, 0x0e, 0xee, 0xeb, + 0x07, 0x0c, 0x00, 0x05, 0xf4, 0xf4, 0x05, 0x05, 0x00, 0x05, 0x0c, 0xf0, + 0xee, 0x00, 0x0c, 0x0c, 0xfd, 0xfb, 0xf0, 0x00, 0x09, 0x00, 0x00, 0x07, + 0x05, 0xfb, 0xf4, 0xf7, 0x05, 0x0c, 0xfd, 0xf0, 0x00, 0x07, 0x07, 0x05, + 0xf6, 0xe7, 0xf6, 0x12, 0x1b, 0x01, 0xee, 0xf4, 0x00, 0xf6, 0xfd, 0x00, + 0x0e, 0x0c, 0xfb, 0xed, 0xf4, 0x12, 0x01, 0xf4, 0x07, 0x09, 0x00, 0x00, + 0x00, 0xee, 0xf0, 0x00, 0x05, 0x15, 0x0c, 0xf0, 0xf9, 0x01, 0xfb, 0xf9, + 0x07, 0x13, 0x00, 0xf6, 0xf4, 0xf4, 0x05, 0x0e, 0x00, 0xe9, 0x09, 0x1b, + 0xfb, 0xed, 0x00, 0x09, 0xf0, 0x00, 0x19, 0x05, 0xe9, 0xfd, 0x15, 0xf9, + 0xe2, 0x05, 0x15, 0x01, 0x00, 0x01, 0xf4, 0xe9, 0xfb, 0x19, 0x0c, 0xf6, + 0xfb, 0xfd, 0xee, 0xfb, 0x15, 0x0c, 0xee, 0xf0, 0x0e, 0x10, 0xfd, 0xf0, + 0xf9, 0x00, 0x07, 0x0c, 0xfb, 0xfd, 0x09, 0x00, 0xf2, 0xed, 0x00, 0x0e, + 0x01, 0x05, 0x01, 0xee, 0xe7, 0x0e, 0x15, 0xe9, 0xee, 0x15, 0x09, 0xed, + 0x00, 0x05, 0xe2, 0xfb, 0x10, 0x09, 0xfd, 0x07, 0xf9, 0xe2, 0x05, 0x17, + 0xfd, 0xf2, 0x01, 0x09, 0x05, 0xfd, 0xed, 0xf9, 0x10, 0x0e, 0x00, 0xfd, + 0xf2, 0xf4, 0x05, 0x13, 0xf9, 0xee, 0x07, 0x0e, 0x00, 0xf4, 0xf2, 0xf6, + 0x09, 0x0e, 0x00, 0xfb, 0xfd, 0xfd, 0x00, 0x01, 0x00, 0x00, 0x09, 0xfb, + 0xee, 0x01, 0x03, 0xf9, 0x00, 0x10, 0x01, 0xe7, 0xf6, 0x10, 0x07, 0xeb, + 0x00, 0x01, 0xf9, 0x00, 0x0e, 0x00, 0xf2, 0x00, 0xfb, 0x00, 0x0a, 0x07, + 0xf2, 0xf4, 0x03, 0x00, 0x03, 0x09, 0xf4, 0xfd, 0x01, 0x00, 0x01, 0x03, + 0x00, 0xfd, 0x09, 0x01, 0xee, 0xfb, 0x10, 0x01, 0xf2, 0x00, 0x00, 0x00, + 0x10, 0x01, 0xf2, 0xfd, 0x00, 0xf2, 0xfb, 0x0a, 0x01, 0xf4, 0xfb, 0x00, + 0xfb, 0x00, 0x00, 0xf4, 0x00, 0x12, 0x01, 0xeb, 0xf0, 0x01, 0x03, 0x01, + 0x09, 0x01, 0xf9, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0xf2, + 0xf4, 0x12, 0x01, 0xe9, 0xfd, 0x19, 0x00, 0xf9, 0x07, 0xf9, 0xed, 0xfd, + 0x03, 0x07, 0x0a, 0x01, 0xf2, 0xe5, 0xf6, 0x0a, 0x0a, 0x00, 0x01, 0xf9, + 0xeb, 0xf9, 0x07, 0x07, 0xf9, 0xed, 0x00, 0x17, 0x00, 0xf2, 0xf9, 0x00, + 0xfd, 0x00, 0x0e, 0x07, 0x00, 0x00, 0xf2, 0xf2, 0x00, 0x0a, 0x03, 0x0a, + 0x01, 0xf2, 0xf0, 0x01, 0x07, 0x00, 0x00, 0x00, 0xf7, 0x03, 0x17, 0xf7, + 0xe7, 0xfb, 0x03, 0x00, 0x00, 0x0a, 0x0c, 0xf2, 0xe7, 0x00, 0x0c, 0xfd, + 0xf7, 0x01, 0x10, 0x00, 0xe7, 0xf7, 0x07, 0x09, 0x03, 0xfd, 0xfd, 0x00, + 0xf7, 0x03, 0x07, 0xeb, 0xf7, 0x0a, 0x0a, 0x03, 0x01, 0xf7, 0xe4, 0xfb, + 0x15, 0x10, 0xf9, 0x00, 0x07, 0xf0, 0xf2, 0x10, 0x03, 0xfb, 0x03, 0xfb, + 0x00, 0x03, 0x00, 0xf0, 0x00, 0x10, 0xf9, 0xfd, 0x0a, 0x00, 0xfd, 0xfb, + 0xf4, 0xfb, 0x09, 0x0a, 0x00, 0xfd, 0x00, 0xee, 0xf4, 0x15, 0x03, 0xf2, + 0x09, 0x03, 0xf0, 0x03, 0x01, 0xeb, 0x01, 0x12, 0x00, 0xeb, 0xf4, 0x09, + 0x10, 0x01, 0x00, 0x00, 0xf2, 0x00, 0x10, 0xfd, 0xf7, 0x00, 0xf7, 0xfb, + 0x0a, 0x09, 0xf9, 0xfd, 0x0a, 0x00, 0xee, 0xfb, 0x09, 0x00, 0xf7, 0x00, + 0x07, 0xfb, 0xf4, 0x03, 0x0a, 0x00, 0xe7, 0x00, 0x12, 0xfb, 0x00, 0x12, + 0xf7, 0xed, 0x03, 0x0c, 0xfd, 0xf9, 0x00, 0x00, 0xfb, 0x00, 0x09, 0x07, + 0x00, 0x03, 0x00, 0xf7, 0xf9, 0x00, 0x09, 0x09, 0xfb, 0xf7, 0xfd, 0xf9, + 0x00, 0x13, 0x0a, 0xee, 0xe9, 0xfd, 0x05, 0x00, 0x00, 0x09, 0xf7, 0xed, + 0x00, 0x03, 0x00, 0x00, 0xfb, 0xfd, 0x09, 0x03, 0xfb, 0x01, 0x03, 0xf9, + 0xf7, 0x00, 0x0a, 0x00, 0x00, 0x01, 0xf2, 0xee, 0x0c, 0x17, 0x00, 0xf6, + 0x03, 0xfb, 0xed, 0x09, 0x0a, 0x01, 0xf7, 0xf9, 0x0a, 0x05, 0xed, 0xf7, + 0x0e, 0x00, 0xf2, 0x00, 0x05, 0xfd, 0xfd, 0x00, 0xf9, 0xf9, 0x0a, 0x09, + 0xf9, 0xfd, 0xfd, 0xf7, 0x00, 0x00, 0x01, 0x05, 0x00, 0xfd, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0xf9, 0x00, 0x00, 0x00, + 0x01, 0x10, 0x00, 0xed, 0xf6, 0x0a, 0x03, 0x00, 0xff, 0x00, 0x00, 0xf4, + 0xff, 0x09, 0xff, 0xf6, 0x01, 0x00, 0xfb, 0x00, 0x00, 0x01, 0xfb, 0xf6, + 0xfb, 0x00, 0x05, 0x09, 0xfb, 0x00, 0x00, 0xed, 0x01, 0x1c, 0x03, 0xee, + 0x00, 0x05, 0xf6, 0xf9, 0x10, 0x05, 0xf4, 0x01, 0x05, 0xf9, 0xf9, 0x00, + 0x03, 0xff, 0xfb, 0x07, 0x03, 0xf6, 0xfb, 0x01, 0x00, 0x00, 0x01, 0x05, + 0xf2, 0xf2, 0x0e, 0x05, 0xf2, 0xfb, 0x03, 0x00, 0x01, 0x0e, 0x00, 0xee, + 0xf6, 0x03, 0x00, 0x00, 0x13, 0x00, 0xeb, 0xf6, 0x05, 0x03, 0x03, 0x05, + 0x00, 0xf6, 0xf6, 0x05, 0x0c, 0x00, 0xfb, 0x03, 0x00, 0xeb, 0xfb, 0x0e, + 0x0a, 0xf7, 0xf6, 0xfb, 0x07, 0x0c, 0xff, 0x00, 0xf9, 0xf7, 0x00, 0x07, + 0x00, 0xf7, 0xf7, 0x00, 0x00, 0xff, 0x01, 0x03, 0x00, 0xf6, 0xfb, 0x05, + 0x00, 0x00, 0x0c, 0x00, 0xed, 0xfb, 0x0c, 0x05, 0x00, 0xff, 0xf9, 0x01, + 0x00, 0x00, 0x07, 0x01, 0xf7, 0xf4, 0x07, 0x00, 0xf6, 0x0c, 0xff, 0xeb, + 0x05, 0x12, 0x00, 0xf6, 0x00, 0x00, 0xff, 0x00, 0xff, 0xf9, 0x00, 0x00, + 0xf6, 0x00, 0x09, 0x00, 0x00, 0x00, 0xf0, 0xf4, 0x07, 0x17, 0x03, 0xe7, + 0xf9, 0x0e, 0x00, 0x00, 0x0c, 0xfb, 0xf2, 0x01, 0x03, 0xfb, 0x00, 0x05, + 0x00, 0xf7, 0xff, 0x05, 0x03, 0x00, 0xf9, 0xf7, 0x00, 0xf9, 0xff, 0x09, + 0x0c, 0x00, 0xf0, 0xfb, 0xff, 0x00, 0x12, 0x0e, 0xf2, 0xf7, 0x03, 0xf6, + 0xfb, 0x09, 0x00, 0xf4, 0x03, 0x01, 0xf6, 0x00, 0x09, 0xff, 0xf7, 0x00, + 0x00, 0x00, 0x09, 0x00, 0xf0, 0x00, 0x05, 0x00, 0x00, 0x05, 0x00, 0xff, + 0x05, 0xff, 0xeb, 0x00, 0x13, 0x01, 0xf4, 0xfd, 0x05, 0x05, 0x00, 0xf2, + 0xf4, 0x03, 0x0a, 0x00, 0xf9, 0xff, 0xfd, 0x03, 0x0c, 0x00, 0xeb, 0xff, + 0x15, 0x07, 0xf4, 0xf4, 0xf9, 0xf9, 0x01, 0x13, 0x01, 0xf4, 0x00, 0x03, + 0x00, 0xf4, 0xf9, 0x07, 0x12, 0xff, 0xf4, 0xf6, 0xfd, 0x01, 0x0c, 0x09, + 0xfd, 0xf4, 0x00, 0x00, 0x00, 0x03, 0x09, 0xff, 0xee, 0x00, 0x13, 0x00, + 0xf0, 0xfd, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0xfd, + 0x0a, 0x0c, 0x00, 0xf2, 0xed, 0xff, 0x09, 0x01, 0xf6, 0x00, 0x00, 0xfd, + 0x00, 0x01, 0x00, 0x00, 0x07, 0x00, 0xfb, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x07, 0x01, 0x00, 0x00, 0x03, 0xfb, 0xf4, 0xff, 0x07, 0x07, + 0xfb, 0xf7, 0xfb, 0x03, 0x00, 0xfb, 0x03, 0x00, 0xfd, 0x00, 0x01, 0xfd, + 0xf7, 0x01, 0x07, 0xfb, 0xf2, 0xff, 0x09, 0x01, 0xff, 0x00, 0x00, 0x05, + 0x00, 0x00, 0xff, 0x03, 0x00, 0xff, 0x01, 0xfb, 0x00, 0x0c, 0x03, 0xfb, + 0xfd, 0xf6, 0xf9, 0x09, 0x0a, 0x00, 0xff, 0xfd, 0xf9, 0xf6, 0x01, 0x09, + 0x00, 0xfd, 0x00, 0xf6, 0xfd, 0x0e, 0x03, 0xf6, 0xff, 0x05, 0x03, 0xff, + 0xf7, 0x01, 0x01, 0xf7, 0xfd, 0x0a, 0x09, 0xfb, 0x00, 0xff, 0xff, 0xfd, + 0x05, 0x0a, 0xfb, 0xf7, 0x01, 0x0a, 0xf7, 0xf7, 0x00, 0x00, 0x00, 0x05, + 0xff, 0xf6, 0x00, 0x05, 0xfb, 0xff, 0x0c, 0x01, 0xf6, 0xf9, 0x00, 0x00, + 0x0c, 0x07, 0xf0, 0xf4, 0x03, 0x0a, 0x00, 0xff, 0x00, 0xff, 0xfd, 0xff, + 0x09, 0x0a, 0xfd, 0xf6, 0xfd, 0x00, 0xfd, 0x00, 0x12, 0x00, 0xed, 0xfb, + 0x05, 0x00, 0x00, 0x0a, 0x00, 0xf4, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfd, 0x00, 0x09, 0x07, 0xfb, 0xf6, 0x00, 0x01, 0xfd, 0x00, 0x0c, + 0xfb, 0xf2, 0xff, 0x03, 0xfd, 0x05, 0x0a, 0x00, 0xf0, 0xf0, 0x07, 0x10, + 0x00, 0xf4, 0x00, 0x00, 0xfb, 0x00, 0x09, 0x09, 0x03, 0xfb, 0xf4, 0xf7, + 0x03, 0x0e, 0x09, 0xfb, 0xee, 0xfb, 0x09, 0x05, 0x00, 0x01, 0xff, 0xf9, + 0xfb, 0x00, 0x07, 0xff, 0xfd, 0x0a, 0xff, 0xee, 0xfb, 0x0e, 0x05, 0xee, + 0xf7, 0x09, 0x09, 0xf9, 0xff, 0x09, 0xfb, 0xf2, 0x00, 0x0a, 0xfd, 0x00, + 0x0a, 0xff, 0xf0, 0xff, 0x0a, 0x03, 0x01, 0xff, 0xf2, 0x00, 0x0e, 0x00, + 0xee, 0x00, 0x0c, 0x00, 0xfd, 0x05, 0x01, 0xf2, 0xfd, 0x0c, 0x03, 0xfb, + 0xff, 0x07, 0x01, 0xf4, 0xf6, 0x00, 0x0a, 0x00, 0x00, 0xfd, 0xf7, 0x00, + 0x05, 0x09, 0x00, 0xf0, 0xf7, 0x05, 0x0e, 0x01, 0xfb, 0xf4, 0xff, 0x09, + 0x07, 0x00, 0x00, 0xf6, 0xf4, 0x05, 0x07, 0xf6, 0x00, 0x0e, 0x00, 0xf0, + 0xfb, 0x05, 0x07, 0x07, 0x00, 0xf2, 0xf4, 0x01, 0x0c, 0x05, 0x00, 0xf4, + 0xf2, 0x09, 0x0a, 0xfd, 0xf7, 0x03, 0x03, 0xf9, 0xee, 0x00, 0x10, 0x05, + 0xf9, 0xfb, 0xfd, 0x01, 0x07, 0x05, 0xff, 0xf9, 0x05, 0x00, 0xf7, 0x00, + 0x09, 0x05, 0xfd, 0xff, 0xfd, 0xfb, 0xff, 0x09, 0x07, 0xfd, 0xfb, 0xfd, + 0x00, 0xff, 0x00, 0x03, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x03, 0x00, 0x00, + 0xff, 0xf7, 0x01, 0x0e, 0xff, 0xf4, 0xff, 0x03, 0x00, 0x00, 0x0e, 0x05, + 0xed, 0xf4, 0x03, 0x00, 0x01, 0x12, 0x05, 0xf7, 0xee, 0xf7, 0x05, 0x0a, + 0x03, 0xff, 0x00, 0xfd, 0xf4, 0xff, 0x0c, 0x03, 0xfb, 0xf6, 0xff, 0x09, + 0x07, 0xff, 0xf7, 0x00, 0xf7, 0xfd, 0x0a, 0x0e, 0xf7, 0xee, 0x00, 0x00, + 0xf9, 0x00, 0x12, 0x07, 0xf2, 0xee, 0x00, 0x0c, 0x00, 0xfd, 0x00, 0x00, + 0x00, 0xfb, 0xfd, 0x01, 0xf9, 0xff, 0x03, 0x00, 0x00, 0x0a, 0x05, 0xf7, + 0xee, 0xfd, 0x0a, 0x09, 0x00, 0xf9, 0xf9, 0x00, 0x03, 0x01, 0x01, 0x00, + 0x00, 0x07, 0xff, 0xf9, 0x00, 0x01, 0xfd, 0xfb, 0x01, 0x01, 0x01, 0x01, + 0xff, 0xf0, 0xf7, 0x03, 0x0a, 0x05, 0xfd, 0xfd, 0x00, 0xf4, 0xf2, 0x03, + 0x0c, 0xff, 0xf4, 0x00, 0x07, 0xfd, 0xfd, 0x03, 0x03, 0xff, 0xfb, 0x0a, + 0x07, 0xf9, 0xf7, 0x00, 0x00, 0x00, 0x05, 0x03, 0x00, 0xfd, 0xf9, 0xf7, + 0xff, 0x0c, 0x0c, 0x00, 0xf9, 0xfd, 0xfb, 0x00, 0x07, 0xff, 0xf6, 0x00, + 0x09, 0x00, 0xf6, 0xff, 0x0a, 0x03, 0xf4, 0xf6, 0x05, 0x03, 0xf9, 0xf9, + 0xff, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xfd, 0x01, 0x00, 0xfb, 0x00, + 0x0a, 0x00, 0xf6, 0x00, 0x0c, 0xff, 0xf0, 0x00, 0x01, 0x05, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xff, 0x01, 0x07, 0x00, 0xf7, 0x00, + 0x00, 0x00, 0xfb, 0x01, 0x09, 0x03, 0xf6, 0xf0, 0x03, 0x0c, 0xf7, 0xf7, + 0x0c, 0xff, 0xee, 0x00, 0x05, 0xf7, 0x00, 0x0e, 0x00, 0xf2, 0xf9, 0x0e, + 0x03, 0xf4, 0xf9, 0x00, 0x00, 0x05, 0x03, 0xf9, 0xf7, 0x00, 0x05, 0x09, + 0xff, 0xf9, 0x01, 0x03, 0x00, 0xf7, 0xf9, 0x01, 0x05, 0x03, 0xfb, 0xf7, + 0x00, 0x05, 0x01, 0x00, 0xf9, 0xff, 0x05, 0x07, 0xf9, 0xf6, 0x00, 0x01, + 0xf9, 0x00, 0x09, 0xfd, 0xfb, 0x05, 0xfb, 0xf4, 0x01, 0x0c, 0x00, 0xf2, + 0x01, 0x09, 0xfd, 0xf9, 0xff, 0xff, 0x00, 0x01, 0xfd, 0x00, 0x01, 0xf9, + 0xfb, 0x00, 0x05, 0x07, 0x01, 0xff, 0xf2, 0xf9, 0x07, 0x10, 0x01, 0xf4, + 0xf7, 0x01, 0x09, 0xfb, 0x00, 0x0c, 0xff, 0xf2, 0xfb, 0x0a, 0x07, 0xf9, + 0xfd, 0xff, 0xf4, 0xff, 0x0c, 0x0a, 0xf6, 0xee, 0x00, 0x07, 0x03, 0x00, + 0x00, 0x00, 0xfd, 0xf7, 0xff, 0x09, 0x01, 0xfd, 0x03, 0x00, 0xf9, 0xfd, + 0x03, 0x01, 0x01, 0x01, 0xfd, 0xf9, 0xff, 0x01, 0x00, 0xfb, 0x00, 0x07, + 0x00, 0xf9, 0x00, 0x01, 0xff, 0xfb, 0x09, 0x09, 0xf7, 0xf7, 0x01, 0x00, + 0x00, 0xfd, 0x01, 0x01, 0x00, 0x01, 0xfb, 0xf6, 0xfb, 0x09, 0x0c, 0x00, + 0xfb, 0xfb, 0x00, 0x00, 0xfb, 0x00, 0x01, 0x09, 0x00, 0xfb, 0xfd, 0xfd, + 0x00, 0x01, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, 0xf7, 0x00, 0x09, 0x00, + 0xfb, 0xfd, 0x03, 0x01, 0xfd, 0xfb, 0x01, 0x05, 0x00, 0xfb, 0x00, 0x07, + 0xfb, 0xf4, 0xff, 0x01, 0x01, 0x07, 0x07, 0xf9, 0xf0, 0xfb, 0x07, 0x07, + 0x00, 0x00, 0x03, 0x00, 0xf0, 0xfd, 0x09, 0x01, 0xfb, 0xff, 0x00, 0xfb, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf7, 0xfb, 0xff, + 0x00, 0xff, 0x07, 0x07, 0xff, 0xf9, 0xf6, 0xfd, 0x03, 0x07, 0x07, 0xff, + 0xf4, 0xfd, 0x00, 0x00, 0x00, 0x01, 0x01, 0xfb, 0xf9, 0x00, 0x07, 0x03, + 0xff, 0x00, 0x00, 0xfb, 0xfb, 0x03, 0x01, 0xf9, 0xfb, 0x03, 0x05, 0xff, + 0x00, 0x00, 0xf9, 0xfd, 0x00, 0x00, 0x00, 0x07, 0xfd, 0xf6, 0x00, 0x01, + 0x00, 0xfb, 0x00, 0x03, 0x00, 0xfb, 0xf6, 0x00, 0x0a, 0x00, 0xfb, 0x01, + 0x01, 0xf6, 0xfb, 0x07, 0xfd, 0x00, 0x05, 0x00, 0xfb, 0xfd, 0xfd, 0x05, + 0x05, 0x01, 0xfd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x03, + 0x00, 0x00, 0x01, 0xff, 0xf6, 0xff, 0x0a, 0x0a, 0x00, 0xf7, 0xf7, 0xfb, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf9, 0xfb, 0x00, 0x0a, 0x05, + 0xfd, 0xf6, 0xfd, 0x05, 0x00, 0xf7, 0xf9, 0x00, 0x05, 0x05, 0x00, 0xff, + 0x00, 0xf9, 0xfd, 0x05, 0x01, 0xfd, 0x01, 0x00, 0xf7, 0xf9, 0x00, 0x01, + 0x00, 0x00, 0x03, 0xfd, 0xf9, 0xfd, 0x00, 0x03, 0x05, 0x00, 0xf9, 0xf9, + 0x00, 0xfd, 0xff, 0x00, 0x05, 0x05, 0x00, 0xfd, 0xf7, 0x03, 0x07, 0xfd, + 0xf6, 0x00, 0x05, 0xff, 0x00, 0x00, 0xf9, 0xfd, 0x00, 0xff, 0x00, 0x03, + 0x00, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x05, 0x05, 0xfb, 0xf4, 0x00, 0x05, + 0xfd, 0xfd, 0x01, 0x03, 0xfd, 0xfd, 0x03, 0x05, 0x00, 0xfb, 0xfd, 0x00, + 0xfb, 0x03, 0x0e, 0x00, 0xf4, 0xf4, 0x00, 0x09, 0x01, 0x00, 0x00, 0xfd, + 0xfd, 0x00, 0x00, 0xfb, 0x00, 0x07, 0x00, 0xf6, 0xfb, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xfd, 0xfd, 0x05, 0xfd, 0xf9, 0x03, 0x00, 0xf6, 0xfd, + 0x07, 0x05, 0xf6, 0xf7, 0x05, 0x09, 0x00, 0xf9, 0xf7, 0x01, 0x09, 0x00, + 0xf9, 0xf9, 0x03, 0x09, 0x00, 0xfd, 0xff, 0xfd, 0x00, 0x03, 0xfd, 0xff, + 0x07, 0x00, 0xf7, 0xfb, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf9, 0xfd, 0x07, + 0x0c, 0x00, 0xf6, 0xfd, 0x00, 0xff, 0x00, 0x09, 0x00, 0xf4, 0xf6, 0x05, + 0x0c, 0x01, 0xf6, 0xf7, 0x01, 0x09, 0xfd, 0xf9, 0x03, 0x01, 0xfb, 0xfd, + 0xfd, 0x00, 0x03, 0x05, 0xfb, 0xf4, 0xf9, 0x07, 0x0a, 0x00, 0xfb, 0x00, + 0xf6, 0xfd, 0x0c, 0x09, 0xf6, 0xf4, 0x07, 0x05, 0xf7, 0x03, 0x07, 0xfd, + 0xfd, 0x00, 0x00, 0xfd, 0x01, 0x03, 0x00, 0xff, 0x00, 0xff, 0x00, 0x01, + 0x00, 0xff, 0x00, 0x00, 0xff, 0xfb, 0x00, 0x09, 0x00, 0xf9, 0x00, 0x00, + 0xfd, 0xfb, 0x00, 0x05, 0x00, 0x00, 0xff, 0xf6, 0xff, 0x07, 0x07, 0xff, + 0xfd, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, + 0x05, 0xff, 0xf6, 0xff, 0x07, 0x05, 0x03, 0xff, 0xf7, 0xff, 0x00, 0xff, + 0x00, 0x09, 0x05, 0xf6, 0xf7, 0x00, 0x03, 0x00, 0x00, 0xff, 0xf7, 0xff, + 0x03, 0x01, 0x00, 0xfb, 0xfb, 0x00, 0x00, 0x00, 0x05, 0x03, 0xfd, 0xf7, + 0xff, 0x00, 0x05, 0x03, 0x00, 0xff, 0xf7, 0xff, 0x03, 0x03, 0x00, 0xff, + 0xfd, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xff, 0xfd, 0xff, 0x01, 0x03, 0x00, 0xfd, 0xf9, 0x01, 0x03, 0xfb, 0xf9, + 0x00, 0x03, 0x00, 0x00, 0x00, 0xff, 0xfb, 0xfd, 0x03, 0x07, 0x00, 0xfb, + 0xfd, 0xf9, 0xfd, 0x07, 0x09, 0x00, 0xf7, 0xff, 0x03, 0x00, 0xfd, 0x01, + 0x05, 0xff, 0xfb, 0xff, 0x00, 0x03, 0x05, 0x00, 0xf9, 0xf9, 0x01, 0x0a, + 0xff, 0xf2, 0xff, 0x0a, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xfd, + 0x05, 0x05, 0x00, 0xfb, 0xf9, 0xfd, 0x03, 0x05, 0x00, 0xfd, 0xff, 0x00, + 0x00, 0x00, 0xff, 0x01, 0x01, 0xfd, 0xf6, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x01, 0x00, 0xff, 0xfd, 0x00, 0x00, 0x00, 0x00, 0xfb, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xfd, 0x00, 0x00, 0xff, 0xfb, + 0x00, 0x01, 0x05, 0x05, 0xf7, 0xf6, 0x00, 0x01, 0xfd, 0x01, 0x07, 0x00, + 0xf6, 0xf9, 0x01, 0x05, 0x01, 0xff, 0xff, 0xfd, 0xfd, 0x00, 0x07, 0x01, + 0xf7, 0xf7, 0x00, 0x07, 0x01, 0xfd, 0x00, 0x01, 0xf9, 0xfb, 0x00, 0x09, + 0x09, 0xff, 0xf6, 0xf6, 0x01, 0x0a, 0x01, 0xff, 0xff, 0xfd, 0x00, 0x00, + 0xfd, 0x00, 0x07, 0x00, 0xfb, 0xfd, 0xff, 0x03, 0x07, 0x00, 0xfd, 0xfd, + 0x01, 0x07, 0x00, 0xfd, 0xfd, 0xff, 0x00, 0x00, 0x00, 0x05, 0x00, 0xf9, + 0xf9, 0xff, 0x01, 0x01, 0x01, 0x00, 0xfd, 0x00, 0x00, 0xfd, 0xfb, 0x03, + 0x03, 0xff, 0xfb, 0x00, 0x07, 0x00, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x03, + 0x00, 0xf7, 0xfb, 0x03, 0x03, 0xfb, 0xf9, 0x00, 0x0a, 0x00, 0xf6, 0xf6, + 0x01, 0x09, 0x00, 0xff, 0x00, 0xff, 0xf7, 0xfd, 0x03, 0x01, 0xff, 0x03, + 0x05, 0xfb, 0xf4, 0x00, 0x0a, 0x05, 0xfd, 0xf9, 0xff, 0x01, 0x00, 0x00, + 0xff, 0xfb, 0x00, 0x01, 0xff, 0x00, 0x03, 0x00, 0xfb, 0xf9, 0xfd, 0x07, + 0x09, 0xff, 0xf9, 0xff, 0xff, 0xfd, 0xff, 0x05, 0x05, 0xfd, 0xfb, 0x01, + 0x03, 0xfd, 0x00, 0x03, 0x01, 0xf9, 0xfd, 0x07, 0x00, 0xf7, 0x01, 0x09, + 0xff, 0xf7, 0xff, 0x05, 0x00, 0xfd, 0x00, 0xff, 0x00, 0x03, 0x01, 0xf7, + 0xfd, 0x03, 0xff, 0xfd, 0x00, 0x00, 0x03, 0x00, 0xfd, 0xfd, 0xff, 0x00, + 0x03, 0x01, 0xfd, 0xfd, 0x00, 0xff, 0xff, 0x00, 0x03, 0x03, 0x00, 0xfd, + 0xff, 0xff, 0xff, 0x03, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xfd, 0x00, 0x01, 0x00, 0x01, 0x05, 0xfd, 0xf7, 0xfd, 0x00, 0x05, 0x07, + 0xfd, 0xf7, 0xfd, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xfd, 0xf9, + 0x03, 0x09, 0x00, 0xf7, 0xfd, 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x01, + 0x01, 0xff, 0xf9, 0xfd, 0x01, 0x01, 0xfd, 0xfd, 0x01, 0x03, 0x00, 0xf9, + 0xff, 0x01, 0x00, 0x00, 0x03, 0x03, 0x00, 0xf9, 0xfd, 0x03, 0x03, 0xff, + 0x00, 0x00, 0xff, 0xfd, 0x00, 0x01, 0x01, 0xff, 0x00, 0xff, 0xf9, 0x00, + 0x05, 0x00, 0xfb, 0xff, 0x00, 0x00, 0x01, 0x00, 0xff, 0x00, 0x01, 0x00, + 0x00, 0x00, 0xff, 0x01, 0x03, 0x00, 0xfb, 0xff, 0x03, 0x01, 0xfb, 0xfd, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0xff, 0xfd, 0x01, + 0x00, 0xff, 0xfd, 0xfb, 0x03, 0x07, 0x00, 0xf9, 0xff, 0x00, 0x00, 0x01, + 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x01, 0x01, 0xfd, 0xfb, + 0x00, 0x01, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, + 0xfd, 0xfd, 0x01, 0x01, 0x00, 0x00, 0xff, 0xfd, 0x01, 0x00, 0xfd, 0x00, + 0x01, 0xff, 0xfb, 0x01, 0x03, 0xff, 0x01, 0x01, 0xfb, 0xfd, 0x01, 0x01, + 0xff, 0x00, 0x01, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xff, 0x00, 0x01, 0xff, + 0xff, 0x03, 0x00, 0xfd, 0xff, 0x00, 0x01, 0xff, 0xfd, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xfd, 0xff, 0x03, 0x03, 0xfd, + 0xfb, 0x01, 0x05, 0xfb, 0xf9, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf9, 0xff, + 0x03, 0x05, 0x00, 0xfb, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x01, 0x00, + 0x00, 0xff, 0x01, 0x00, 0xff, 0xfd, 0xff, 0x01, 0x01, 0x00, 0xff, 0xfd, + 0xfb, 0x00, 0x05, 0x05, 0x00, 0xff, 0xfb, 0xf9, 0x00, 0x07, 0x01, 0xfb, + 0xfd, 0x05, 0x00, 0xfb, 0xfb, 0x00, 0x01, 0x01, 0x00, 0x00, 0xff, 0x00, + 0x00, 0xff, 0xfb, 0xff, 0x05, 0x03, 0xfd, 0xf9, 0xfd, 0x00, 0x00, 0x03, + 0x01, 0xfb, 0xfd, 0x00, 0x00, 0xfd, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, 0xff, 0x00, 0xff, 0xfd, 0x01, + 0x03, 0x00, 0xff, 0x00, 0xff, 0xfd, 0x00, 0x03, 0x05, 0x00, 0xfb, 0xfd, + 0x01, 0x03, 0x00, 0xfd, 0xf9, 0x00, 0x03, 0x03, 0x00, 0xfb, 0xfd, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x01, 0x01, 0xff, 0xfd, + 0xfd, 0x00, 0x00, 0x01, 0x00, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, + 0xfd, 0xff, 0x00, 0x01, 0xff, 0xfd, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, + 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, + 0xfd, 0x00, 0x01, 0x03, 0x00, 0xfd, 0xfb, 0xff, 0x00, 0x01, 0x01, 0x00, + 0xff, 0xfd, 0xff, 0x00, 0x00, 0x01, 0x03, 0x00, 0xfd, 0xfb, 0xff, 0x01, + 0x03, 0x00, 0xfb, 0x00, 0x03, 0x01, 0x00, 0xff, 0xfb, 0xfd, 0x05, 0x05, + 0xff, 0xff, 0x00, 0xff, 0xfb, 0x00, 0x03, 0x01, 0x00, 0x00, 0xfb, 0xfd, + 0x01, 0x03, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0xff, 0x03, 0x00, 0xfd, 0x00, 0x00, 0xfd, 0x00, 0x05, 0x00, 0xfd, 0xfd, + 0x00, 0x01, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfd, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xff, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x03, 0xff, 0xfb, 0x00, 0x05, 0x00, 0xfd, + 0x00, 0x00, 0xff, 0x01, 0x03, 0xff, 0xfd, 0x00, 0x01, 0xff, 0xff, 0x01, + 0x01, 0xfd, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, + 0x01, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xfd, 0x01, + 0x01, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0xff, + 0xff, 0x01, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x03, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xfd, 0x00, 0x03, 0x00, 0xfd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xfd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfd, 0x01, 0x03, 0x00, + 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xfd, 0x00, 0x03, 0x00, + 0xff, 0x00, 0x00, 0xfd, 0xfd, 0x03, 0x01, 0x00, 0x00, 0x00, 0xfd, 0xfd, + 0x00, 0x03, 0x00, 0xfd, 0x00, 0x01, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, 0x03, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x03, 0x00, 0xff, 0xff, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x01, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xff, + 0xff, 0x01, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, + 0xff, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, + 0x00, 0x01, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, + 0x01, 0xff, 0xfd, 0xff, 0x00, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x01, 0x00, 0xfd, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xfd, 0x00, 0x03, 0x01, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x01, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x00, 0x00, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x01, 0x00, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0xfd, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x01, 0x00, 0xff, 0x00, 0x01, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, + 0x00, 0x01, 0x00, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x00, + 0x01, 0x01, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x01, 0x00, 0xff, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0xfc, 0xf9, 0xf8, 0xf8, + 0xf7, 0xf5, 0xf2, 0xf1, 0xef, 0xed, 0xec, 0xea, 0xe8, 0xe4, 0xe1, 0xe0, + 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe3, 0xe5, 0xe5, + 0xe3, 0xe2, 0xe3, 0xe8, 0xea, 0xec, 0xee, 0xec, 0xed, 0xf4, 0xf7, 0xf7, + 0xf7, 0xf8, 0xfa, 0xf8, 0xfa, 0xff, 0x02, 0x02, 0x05, 0x04, 0x02, 0x0c, + 0x0e, 0x02, 0xfb, 0x04, 0x10, 0x1f, 0x22, 0x20, 0x1e, 0x14, 0x14, 0x14, + 0x0e, 0x0e, 0x14, 0x0f, 0x0d, 0x12, 0x11, 0x11, 0x14, 0x12, 0x10, 0x0a, + 0x00, 0xfa, 0xf4, 0xee, 0xef, 0xed, 0xe2, 0xdb, 0xd7, 0xd5, 0xd7, 0xd4, + 0xcb, 0xbf, 0xb3, 0xa8, 0xa2, 0xa0, 0x9a, 0x99, 0x99, 0x9d, 0x9f, 0xa3, + 0xaa, 0xae, 0xb1, 0xb1, 0xb6, 0xb8, 0xb8, 0xbd, 0xbe, 0xb9, 0xbf, 0xc8, + 0xcc, 0xcf, 0xd3, 0xd7, 0xd4, 0xcf, 0xde, 0xed, 0xe3, 0xe9, 0xf8, 0xf3, + 0xeb, 0xf4, 0x04, 0x0d, 0x15, 0x16, 0x0c, 0x03, 0x0c, 0x24, 0x34, 0x44, + 0x4f, 0x45, 0x37, 0x37, 0x3c, 0x45, 0x54, 0x5c, 0x5b, 0x52, 0x4a, 0x4c, + 0x57, 0x5d, 0x5d, 0x5d, 0x61, 0x61, 0x5b, 0x5e, 0x6b, 0x74, 0x72, 0x70, + 0x6d, 0x67, 0x66, 0x6e, 0x78, 0x76, 0x70, 0x68, 0x5f, 0x5b, 0x55, 0x55, + 0x5f, 0x65, 0x61, 0x59, 0x56, 0x56, 0x51, 0x4a, 0x4c, 0x58, 0x5b, 0x55, + 0x4c, 0x3c, 0x40, 0x4e, 0x47, 0x3a, 0x3b, 0x3d, 0x36, 0x2f, 0x2e, 0x32, + 0x34, 0x31, 0x2d, 0x23, 0x1c, 0x29, 0x37, 0x2f, 0x21, 0x25, 0x2e, 0x2d, + 0x20, 0x16, 0x22, 0x37, 0x41, 0x37, 0x22, 0x1e, 0x2c, 0x38, 0x3a, 0x3a, + 0x3b, 0x38, 0x34, 0x30, 0x34, 0x3f, 0x40, 0x3b, 0x3a, 0x3b, 0x40, 0x4b, + 0x51, 0x4a, 0x44, 0x48, 0x4e, 0x4e, 0x4b, 0x4b, 0x51, 0x56, 0x56, 0x53, + 0x4c, 0x46, 0x46, 0x4c, 0x54, 0x54, 0x4b, 0x42, 0x44, 0x4a, 0x4c, 0x48, + 0x44, 0x46, 0x49, 0x4b, 0x4a, 0x4a, 0x4b, 0x45, 0x3c, 0x35, 0x38, 0x40, + 0x44, 0x3f, 0x36, 0x31, 0x2f, 0x2e, 0x2f, 0x31, 0x38, 0x3d, 0x37, 0x28, + 0x1a, 0x1d, 0x2a, 0x34, 0x33, 0x2c, 0x2a, 0x2a, 0x2a, 0x28, 0x26, 0x2c, + 0x38, 0x38, 0x2a, 0x24, 0x2b, 0x31, 0x32, 0x33, 0x31, 0x2a, 0x26, 0x2a, + 0x2d, 0x30, 0x3c, 0x44, 0x3b, 0x2a, 0x28, 0x30, 0x35, 0x3d, 0x43, 0x3b, + 0x32, 0x33, 0x33, 0x2f, 0x2b, 0x31, 0x38, 0x37, 0x30, 0x29, 0x24, 0x20, + 0x1f, 0x1c, 0x11, 0x06, 0x00, 0xfb, 0xfa, 0xfb, 0xfa, 0xf8, 0xee, 0xe3, + 0xdf, 0xde, 0xde, 0xdb, 0xd7, 0xd3, 0xc9, 0xc3, 0xc5, 0xc7, 0xc6, 0xcc, + 0xd4, 0xd3, 0xd0, 0xd2, 0xd9, 0xe4, 0xed, 0xef, 0xea, 0xe4, 0xe0, 0xe2, + 0xeb, 0xf4, 0xf1, 0xef, 0xf1, 0xeb, 0xe7, 0xea, 0xf1, 0xf9, 0xfa, 0xf5, + 0xef, 0xea, 0xee, 0xf7, 0xfb, 0xff, 0x0b, 0x0b, 0xfd, 0xf9, 0x02, 0x11, + 0x17, 0x0f, 0x09, 0x0c, 0x15, 0x1b, 0x18, 0x14, 0x1a, 0x24, 0x20, 0x0f, + 0x07, 0x13, 0x25, 0x25, 0x16, 0x13, 0x1e, 0x21, 0x1c, 0x19, 0x1d, 0x2a, + 0x33, 0x27, 0x15, 0x17, 0x25, 0x29, 0x1c, 0x0d, 0x0e, 0x19, 0x20, 0x1a, + 0x0e, 0x06, 0x08, 0x0d, 0x07, 0xff, 0x00, 0x05, 0x09, 0x05, 0xfd, 0xfa, + 0xfa, 0xf5, 0xf2, 0xf6, 0xf8, 0xf4, 0xec, 0xdf, 0xd7, 0xd8, 0xde, 0xe3, + 0xe2, 0xda, 0xd4, 0xd4, 0xd7, 0xdb, 0xdb, 0xd2, 0xcd, 0xd1, 0xd7, 0xd9, + 0xdb, 0xde, 0xe4, 0xe7, 0xdf, 0xda, 0xe3, 0xf1, 0xfc, 0xff, 0xfe, 0xfd, + 0xf9, 0xf6, 0xf7, 0xfc, 0x0b, 0x20, 0x1a, 0x08, 0x0e, 0x18, 0x1c, 0x1e, + 0x28, 0x32, 0x37, 0x37, 0x39, 0x3a, 0x3a, 0x48, 0x4d, 0x3a, 0x2d, 0x35, + 0x3e, 0x49, 0x50, 0x48, 0x39, 0x33, 0x33, 0x38, 0x3d, 0x45, 0x4b, 0x48, + 0x40, 0x3d, 0x41, 0x41, 0x46, 0x4e, 0x50, 0x4e, 0x42, 0x33, 0x2e, 0x31, + 0x31, 0x36, 0x3d, 0x37, 0x2b, 0x23, 0x26, 0x2e, 0x33, 0x2f, 0x23, 0x18, + 0x1a, 0x25, 0x29, 0x26, 0x28, 0x22, 0x1b, 0x1d, 0x1e, 0x20, 0x24, 0x2c, + 0x31, 0x27, 0x1d, 0x1e, 0x1c, 0x1a, 0x28, 0x32, 0x29, 0x1f, 0x22, 0x28, + 0x2c, 0x35, 0x3a, 0x33, 0x2b, 0x28, 0x2b, 0x38, 0x48, 0x45, 0x38, 0x30, + 0x2e, 0x32, 0x3d, 0x47, 0x49, 0x42, 0x38, 0x2f, 0x26, 0x24, 0x2b, 0x33, + 0x37, 0x30, 0x1e, 0x10, 0x0b, 0x0d, 0x11, 0x15, 0x14, 0x05, 0xf0, 0xe2, + 0xe4, 0xed, 0xf0, 0xea, 0xe0, 0xdc, 0xd6, 0xc9, 0xc4, 0xce, 0xd8, 0xd7, + 0xd3, 0xcc, 0xc4, 0xca, 0xd9, 0xe5, 0xe8, 0xea, 0xf0, 0xe8, 0xdd, 0xde, + 0xe7, 0xf2, 0xfb, 0xf6, 0xe6, 0xe3, 0xee, 0xf2, 0xed, 0xed, 0xef, 0xf4, + 0xf4, 0xf0, 0xee, 0xf2, 0xfb, 0x01, 0x01, 0xfc, 0xf8, 0xfb, 0x06, 0x0d, + 0x0b, 0x05, 0x06, 0x0e, 0x13, 0x14, 0x14, 0x12, 0x11, 0x0d, 0x0a, 0x0f, + 0x19, 0x1b, 0x16, 0x0e, 0x08, 0x0c, 0x19, 0x23, 0x22, 0x1b, 0x1a, 0x1f, + 0x21, 0x1a, 0x16, 0x1a, 0x25, 0x2c, 0x1f, 0x0e, 0x0d, 0x10, 0x0c, 0x0e, + 0x14, 0x10, 0x04, 0xfc, 0xfe, 0x07, 0x0d, 0x0b, 0x03, 0xfa, 0xfb, 0x02, + 0x03, 0xff, 0xfe, 0xfc, 0xf5, 0xeb, 0xe6, 0xe9, 0xef, 0xf2, 0xec, 0xe2, + 0xdd, 0xdc, 0xdb, 0xd8, 0xd8, 0xe0, 0xe9, 0xe5, 0xd5, 0xc9, 0xcd, 0xdc, + 0xe8, 0xe9, 0xe3, 0xda, 0xd8, 0xe1, 0xed, 0xf8, 0xfd, 0xf5, 0xec, 0xea, + 0xf0, 0xfa, 0x01, 0x06, 0x06, 0x02, 0xff, 0xff, 0x01, 0x0a, 0x1a, 0x23, + 0x26, 0x25, 0x1f, 0x16, 0x18, 0x28, 0x37, 0x40, 0x41, 0x35, 0x25, 0x21, + 0x2e, 0x3d, 0x41, 0x3a, 0x2f, 0x28, 0x29, 0x2d, 0x2f, 0x2f, 0x30, 0x35, + 0x38, 0x37, 0x33, 0x30, 0x32, 0x36, 0x37, 0x31, 0x28, 0x24, 0x20, 0x21, + 0x25, 0x26, 0x25, 0x21, 0x18, 0x0f, 0x11, 0x1a, 0x1a, 0x11, 0x0b, 0x0b, + 0x10, 0x16, 0x13, 0x08, 0x03, 0x06, 0x0b, 0x11, 0x18, 0x17, 0x10, 0x08, + 0x04, 0x06, 0x07, 0x0a, 0x10, 0x12, 0x13, 0x13, 0x09, 0xff, 0x02, 0x0d, + 0x1e, 0x27, 0x1c, 0x0d, 0x0b, 0x14, 0x1e, 0x20, 0x1e, 0x24, 0x2a, 0x26, + 0x20, 0x20, 0x2a, 0x37, 0x33, 0x21, 0x17, 0x1b, 0x25, 0x28, 0x20, 0x1a, + 0x23, 0x2c, 0x23, 0x12, 0x09, 0x12, 0x20, 0x1e, 0x07, 0xf3, 0xf4, 0xfd, + 0xfc, 0xee, 0xe5, 0xec, 0xf4, 0xec, 0xd8, 0xcb, 0xce, 0xda, 0xda, 0xcf, + 0xc8, 0xcf, 0xd6, 0xd5, 0xd2, 0xd5, 0xe0, 0xe6, 0xe8, 0xe6, 0xe4, 0xef, + 0xfa, 0xf6, 0xe6, 0xe0, 0xec, 0xfa, 0xfc, 0xf5, 0xed, 0xe8, 0xe9, 0xf0, + 0xf6, 0xf6, 0xf4, 0xf1, 0xf0, 0xf1, 0xf6, 0xfb, 0xf7, 0xf6, 0x03, 0x0b, + 0x05, 0xfd, 0xfc, 0x03, 0x0f, 0x17, 0x13, 0x0a, 0x03, 0x01, 0x07, 0x10, + 0x13, 0x13, 0x0e, 0x05, 0x00, 0x0b, 0x1d, 0x22, 0x19, 0x13, 0x18, 0x22, + 0x28, 0x2a, 0x27, 0x22, 0x23, 0x26, 0x22, 0x1b, 0x1b, 0x1e, 0x1a, 0x15, + 0x18, 0x14, 0x0a, 0x05, 0x08, 0x11, 0x17, 0x16, 0x0e, 0x07, 0x07, 0x11, + 0x18, 0x11, 0x07, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xf1, 0xe9, + 0xea, 0xef, 0xf1, 0xeb, 0xe4, 0xe2, 0xe3, 0xe5, 0xdf, 0xd5, 0xd4, 0xe0, + 0xeb, 0xed, 0xe7, 0xe2, 0xdc, 0xe2, 0xf1, 0xf9, 0xf5, 0xed, 0xed, 0xef, + 0xf0, 0xf5, 0xfa, 0xfb, 0xfb, 0xfe, 0x02, 0x06, 0x08, 0x0b, 0x0d, 0x0f, + 0x11, 0x18, 0x1e, 0x1b, 0x19, 0x1d, 0x26, 0x2e, 0x2d, 0x2a, 0x28, 0x26, + 0x2d, 0x34, 0x2a, 0x1d, 0x1a, 0x1f, 0x25, 0x28, 0x2d, 0x2d, 0x25, 0x21, + 0x2e, 0x39, 0x3a, 0x36, 0x29, 0x1e, 0x22, 0x2a, 0x28, 0x28, 0x2d, 0x30, + 0x2a, 0x1b, 0x12, 0x16, 0x1d, 0x21, 0x20, 0x19, 0x12, 0x0e, 0x08, 0x03, + 0x06, 0x14, 0x21, 0x1a, 0x03, 0xf6, 0x02, 0x13, 0x15, 0x0a, 0x03, 0x09, + 0x11, 0x0a, 0xff, 0xfe, 0x09, 0x16, 0x12, 0x04, 0xff, 0x08, 0x11, 0x11, + 0x0f, 0x0d, 0x11, 0x16, 0x14, 0x12, 0x16, 0x20, 0x2c, 0x2c, 0x22, 0x21, + 0x27, 0x2b, 0x2b, 0x28, 0x28, 0x2c, 0x29, 0x23, 0x21, 0x20, 0x22, 0x2a, + 0x2c, 0x2a, 0x28, 0x23, 0x21, 0x20, 0x1a, 0x11, 0x09, 0x08, 0x0e, 0x0d, + 0x01, 0xf5, 0xeb, 0xe3, 0xe6, 0xec, 0xea, 0xe0, 0xd6, 0xd3, 0xd2, 0xcc, + 0xca, 0xd0, 0xd3, 0xcf, 0xca, 0xc8, 0xcc, 0xd4, 0xd7, 0xd5, 0xda, 0xe4, + 0xea, 0xe6, 0xdf, 0xde, 0xe7, 0xf0, 0xf0, 0xe6, 0xdd, 0xdf, 0xe7, 0xef, + 0xf2, 0xef, 0xec, 0xea, 0xea, 0xec, 0xf6, 0x01, 0x02, 0xf9, 0xf4, 0xff, + 0x0f, 0x14, 0x0b, 0x06, 0x0d, 0x17, 0x17, 0x10, 0x0e, 0x12, 0x1b, 0x1d, + 0x11, 0x06, 0x0b, 0x15, 0x17, 0x17, 0x1d, 0x23, 0x20, 0x18, 0x15, 0x1b, + 0x28, 0x34, 0x2f, 0x1e, 0x14, 0x1a, 0x24, 0x20, 0x18, 0x15, 0x12, 0x0f, + 0x0d, 0x09, 0x04, 0x05, 0x08, 0x09, 0x07, 0x03, 0xfe, 0xf9, 0xfa, 0x00, + 0x01, 0xff, 0xfc, 0xf6, 0xf0, 0xee, 0xef, 0xf0, 0xef, 0xea, 0xe4, 0xe2, + 0xe3, 0xe5, 0xe3, 0xdb, 0xd4, 0xd3, 0xd8, 0xdb, 0xd7, 0xd0, 0xcd, 0xd2, + 0xd8, 0xd9, 0xd6, 0xd4, 0xd7, 0xdc, 0xde, 0xe0, 0xe1, 0xde, 0xdd, 0xe0, + 0xe4, 0xe6, 0xe4, 0xe3, 0xe7, 0xee, 0xf5, 0xf8, 0xf5, 0xf2, 0xf4, 0xf6, + 0xfa, 0x03, 0x0b, 0x0d, 0x0b, 0x09, 0x0a, 0x11, 0x17, 0x1a, 0x1b, 0x1a, + 0x1a, 0x18, 0x10, 0x08, 0x09, 0x14, 0x22, 0x27, 0x1f, 0x17, 0x15, 0x1a, + 0x21, 0x22, 0x23, 0x28, 0x26, 0x1e, 0x18, 0x18, 0x1f, 0x24, 0x1f, 0x18, + 0x15, 0x18, 0x1a, 0x14, 0x0e, 0x0f, 0x13, 0x12, 0x0c, 0x07, 0x06, 0x07, + 0x09, 0x05, 0xff, 0x00, 0x05, 0x04, 0xfd, 0xfc, 0x00, 0x04, 0x03, 0xfc, + 0xf7, 0xf9, 0xff, 0x02, 0x01, 0x00, 0x01, 0x00, 0xfd, 0xfc, 0xfd, 0x00, + 0x00, 0xff, 0x04, 0x09, 0x09, 0x07, 0x05, 0x06, 0x0d, 0x16, 0x1c, 0x1c, + 0x16, 0x10, 0x0c, 0x0c, 0x10, 0x14, 0x16, 0x15, 0x14, 0x14, 0x15, 0x14, + 0x13, 0x13, 0x14, 0x18, 0x1a, 0x16, 0x11, 0x0f, 0x0c, 0x09, 0x04, 0xfb, + 0xf5, 0xef, 0xe9, 0xe8, 0xeb, 0xea, 0xe2, 0xd8, 0xd0, 0xd1, 0xd7, 0xdc, + 0xdc, 0xd4, 0xcb, 0xcb, 0xcd, 0xce, 0xcf, 0xd2, 0xd7, 0xd9, 0xd9, 0xdb, + 0xe2, 0xea, 0xec, 0xe9, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xee, 0xf4, 0xf8, + 0xf4, 0xed, 0xeb, 0xf2, 0xfc, 0x05, 0x09, 0x04, 0xff, 0xff, 0x02, 0x06, + 0x0b, 0x12, 0x14, 0x10, 0x0b, 0x09, 0x0b, 0x0d, 0x0d, 0x0d, 0x0e, 0x0b, + 0x06, 0x02, 0x00, 0x01, 0x05, 0x08, 0x06, 0x04, 0x05, 0x07, 0x0a, 0x0f, + 0x11, 0x0d, 0x09, 0x06, 0x04, 0x05, 0x07, 0x07, 0x03, 0xfe, 0xfd, 0xff, + 0xff, 0xfc, 0xfa, 0xfc, 0xff, 0xff, 0xfc, 0xf8, 0xf4, 0xf5, 0xf8, 0xf8, + 0xf8, 0xf7, 0xf6, 0xf6, 0xf4, 0xef, 0xed, 0xef, 0xee, 0xec, 0xeb, 0xec, + 0xed, 0xeb, 0xe7, 0xe3, 0xe4, 0xe8, 0xeb, 0xe6, 0xe0, 0xde, 0xde, 0xe0, + 0xe2, 0xe0, 0xdf, 0xe0, 0xe4, 0xe6, 0xe1, 0xde, 0xe2, 0xe6, 0xe6, 0xe4, + 0xe3, 0xe7, 0xea, 0xe8, 0xe3, 0xe4, 0xee, 0xf6, 0xf2, 0xea, 0xea, 0xf2, + 0xfa, 0xfd, 0xfb, 0xfc, 0x01, 0x06, 0x04, 0x00, 0x00, 0x04, 0x07, 0x02, + 0xfe, 0x00, 0x04, 0x03, 0xfe, 0xfd, 0x00, 0x07, 0x0d, 0x0b, 0x05, 0x04, + 0x0a, 0x0e, 0x0d, 0x0b, 0x0a, 0x0a, 0x0a, 0x0c, 0x10, 0x11, 0x0d, 0x09, + 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, + 0x06, 0x08, 0x0d, 0x0d, 0x05, 0xff, 0xff, 0x00, 0x01, 0x01, 0x00, 0xff, + 0xfe, 0xff, 0x01, 0xfd, 0xf9, 0xfb, 0xfd, 0xfb, 0xfb, 0xfc, 0xf9, 0xf5, + 0xf3, 0xf4, 0xf9, 0xfe, 0xff, 0xfe, 0xfe, 0x01, 0x05, 0x05, 0x02, 0x00, + 0x00, 0x03, 0x06, 0x05, 0x06, 0x08, 0x05, 0x02, 0x04, 0x07, 0x08, 0x0a, + 0x0d, 0x0b, 0x09, 0x0b, 0x10, 0x11, 0x0c, 0x09, 0x09, 0x08, 0x03, 0xfd, + 0xf6, 0xf2, 0xef, 0xe9, 0xe1, 0xda, 0xd6, 0xd8, 0xd9, 0xd9, 0xda, 0xdb, + 0xd6, 0xcf, 0xca, 0xca, 0xce, 0xd1, 0xd1, 0xce, 0xcc, 0xcf, 0xd5, 0xd7, + 0xd7, 0xdd, 0xe4, 0xe6, 0xe6, 0xe5, 0xe5, 0xe6, 0xe9, 0xec, 0xee, 0xf1, + 0xf2, 0xf2, 0xf1, 0xf3, 0xf9, 0xfe, 0x01, 0x00, 0xff, 0x03, 0x08, 0x0a, + 0x09, 0x09, 0x0c, 0x11, 0x14, 0x10, 0x0f, 0x11, 0x13, 0x11, 0x0f, 0x0d, + 0x0b, 0x08, 0x08, 0x08, 0x0c, 0x11, 0x12, 0x0f, 0x0b, 0x0c, 0x12, 0x18, + 0x1a, 0x15, 0x10, 0x0d, 0x0b, 0x09, 0x09, 0x0b, 0x0f, 0x11, 0x0d, 0x09, + 0x09, 0x09, 0x0b, 0x0b, 0x09, 0x0b, 0x0d, 0x0a, 0x07, 0x07, 0x0b, 0x0d, + 0x0b, 0x07, 0x04, 0x02, 0x04, 0x06, 0x04, 0x01, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x01, 0xff, 0xfb, 0xf8, 0xf9, 0xfc, 0xfe, 0xfd, 0xf9, 0xf6, 0xf6, + 0xf7, 0xf7, 0xf7, 0xfa, 0xfb, 0xf9, 0xf7, 0xf7, 0xf7, 0xf4, 0xf5, 0xf9, + 0xfd, 0xfd, 0xf9, 0xf6, 0xf6, 0xf7, 0xfb, 0xff, 0xfd, 0xfa, 0xf9, 0xfc, + 0x00, 0x01, 0x02, 0x01, 0xff, 0x01, 0x07, 0x0c, 0x0e, 0x0d, 0x0a, 0x07, + 0x07, 0x0b, 0x0b, 0x09, 0x09, 0x0e, 0x12, 0x11, 0x0d, 0x09, 0x0b, 0x10, + 0x16, 0x19, 0x17, 0x11, 0x0c, 0x0e, 0x14, 0x17, 0x19, 0x16, 0x10, 0x0f, + 0x13, 0x17, 0x17, 0x12, 0x10, 0x11, 0x12, 0x12, 0x12, 0x12, 0x13, 0x14, + 0x12, 0x10, 0x0e, 0x0f, 0x10, 0x0f, 0x0e, 0x0f, 0x0e, 0x09, 0x04, 0x05, + 0x0b, 0x10, 0x10, 0x0b, 0x08, 0x08, 0x0b, 0x0b, 0x09, 0x08, 0x06, 0x02, + 0x00, 0x00, 0x02, 0x05, 0x06, 0x05, 0x03, 0x02, 0x03, 0x05, 0x07, 0x09, + 0x09, 0x08, 0x08, 0x07, 0x06, 0x07, 0x09, 0x09, 0x09, 0x09, 0x09, 0x07, + 0x07, 0x09, 0x0a, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07, 0x03, 0xfe, 0xfa, + 0xf5, 0xee, 0xe6, 0xe1, 0xe0, 0xdc, 0xd8, 0xd4, 0xd1, 0xcf, 0xcd, 0xcd, + 0xcd, 0xcc, 0xca, 0xc8, 0xc6, 0xc4, 0xc4, 0xc5, 0xc6, 0xc6, 0xc7, 0xcb, + 0xd0, 0xd3, 0xd7, 0xdc, 0xe2, 0xe8, 0xea, 0xea, 0xea, 0xed, 0xf1, 0xf4, + 0xf4, 0xf3, 0xf3, 0xf5, 0xf9, 0xfd, 0xff, 0xff, 0xff, 0x00, 0x02, 0x05, + 0x07, 0x08, 0x08, 0x07, 0x07, 0x0a, 0x0e, 0x0f, 0x0d, 0x0b, 0x09, 0x09, + 0x0a, 0x09, 0x07, 0x07, 0x0a, 0x0b, 0x08, 0x07, 0x05, 0x04, 0x06, 0x09, + 0x08, 0x05, 0x06, 0x08, 0x07, 0x07, 0x08, 0x08, 0x07, 0x07, 0x08, 0x08, + 0x08, 0x08, 0x07, 0x04, 0x02, 0x04, 0x07, 0x07, 0x06, 0x06, 0x07, 0x08, + 0x08, 0x06, 0x03, 0x03, 0x05, 0x06, 0x04, 0x00, 0xff, 0xff, 0xff, 0x01, + 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01, 0xff, 0xff, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05, 0x04, + 0x04, 0x02, 0x01, 0x01, 0x04, 0x07, 0x07, 0x05, 0x02, 0xff, 0x00, 0x02, + 0x04, 0x04, 0x03, 0x01, 0x01, 0x01, 0x02, 0x04, 0x06, 0x05, 0x04, 0x05, + 0x07, 0x08, 0x09, 0x08, 0x09, 0x0c, 0x0d, 0x0b, 0x09, 0x0c, 0x12, 0x15, + 0x15, 0x13, 0x12, 0x13, 0x17, 0x17, 0x16, 0x18, 0x1a, 0x19, 0x19, 0x19, + 0x1a, 0x1b, 0x1b, 0x1a, 0x18, 0x16, 0x17, 0x17, 0x15, 0x15, 0x15, 0x16, + 0x14, 0x11, 0x0e, 0x0d, 0x0f, 0x10, 0x0f, 0x0c, 0x09, 0x08, 0x08, 0x09, + 0x08, 0x08, 0x07, 0x06, 0x06, 0x06, 0x06, 0x05, 0x02, 0x00, 0xff, 0xfe, + 0xfe, 0xff, 0xff, 0xfd, 0xfb, 0xfa, 0xfa, 0xfb, 0xfd, 0xfd, 0xfc, 0xfb, + 0xfa, 0xf9, 0xf7, 0xf7, 0xf9, 0xfc, 0xfe, 0xfc, 0xf8, 0xf7, 0xf7, 0xfa, + 0xfd, 0xfc, 0xf8, 0xf7, 0xfb, 0xfe, 0xfe, 0xfe, 0xfe, 0xfc, 0xf8, 0xf4, + 0xf0, 0xed, 0xec, 0xe8, 0xe2, 0xdb, 0xd7, 0xd6, 0xd3, 0xce, 0xcd, 0xd0, + 0xd3, 0xd2, 0xce, 0xca, 0xc8, 0xcb, 0xcb, 0xc6, 0xc2, 0xc3, 0xc9, 0xcc, + 0xcd, 0xcd, 0xce, 0xd2, 0xd8, 0xdd, 0xe0, 0xe3, 0xe6, 0xe8, 0xea, 0xec, + 0xf0, 0xf4, 0xf4, 0xf3, 0xf4, 0xf6, 0xf8, 0xfb, 0xfb, 0xfb, 0xfe, 0x01, + 0x03, 0x03, 0x03, 0x06, 0x09, 0x09, 0x08, 0x07, 0x06, 0x07, 0x09, 0x0a, + 0x0a, 0x09, 0x08, 0x07, 0x07, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, + 0x09, 0x07, 0x06, 0x07, 0x09, 0x0b, 0x0b, 0x08, 0x08, 0x08, 0x09, 0x0a, + 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, + 0x0b, 0x0d, 0x0d, 0x0b, 0x0a, 0x0b, 0x0b, 0x09, 0x09, 0x09, 0x0a, 0x0a, + 0x09, 0x09, 0x08, 0x08, 0x09, 0x0a, 0x09, 0x09, 0x08, 0x07, 0x06, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x0c, + 0x0f, 0x0f, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x11, 0x14, 0x15, 0x15, + 0x13, 0x12, 0x14, 0x15, 0x16, 0x16, 0x17, 0x19, 0x1a, 0x19, 0x17, 0x18, + 0x1a, 0x1b, 0x1a, 0x17, 0x15, 0x18, 0x19, 0x16, 0x11, 0x11, 0x12, 0x13, + 0x12, 0x12, 0x12, 0x14, 0x15, 0x14, 0x11, 0x11, 0x13, 0x15, 0x14, 0x11, + 0x11, 0x13, 0x15, 0x14, 0x13, 0x13, 0x14, 0x14, 0x12, 0x11, 0x10, 0x11, + 0x14, 0x12, 0x0f, 0x0f, 0x11, 0x10, 0x0c, 0x0a, 0x0c, 0x10, 0x10, 0x0c, + 0x09, 0x08, 0x09, 0x0a, 0x09, 0x07, 0x07, 0x08, 0x08, 0x06, 0x04, 0x04, + 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, + 0x00, 0x01, 0x03, 0x05, 0x05, 0x04, 0x00, 0x00, 0x0f, 0x11, 0x11, 0x0f, + 0x0d, 0x0b, 0x0c, 0x0d, 0x0d, 0x0c, 0x0b, 0x0b, 0x0b, 0x09, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x08, 0x07, 0x07, 0x07, 0x07, 0x05, 0x05, 0x05, 0x04, + 0x05, 0x05, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, + 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x05, 0x07, 0x08, 0x07, 0x06, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x07, 0x05, 0x05, 0x07, 0x07, + 0x09, 0x09, 0x09, 0x08, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x07, 0x06, + 0x07, 0x07, 0x08, 0x08, 0x07, 0x05, 0x07, 0x07, 0x07, 0x05, 0x05, 0x05, + 0x05, 0x03, 0x03, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01, 0x00, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x02, 0x01, 0xf5, 0xe5, 0xdd, 0xd9, 0xd7, 0xd5, 0xd3, 0xd1, 0xcf, + 0xcb, 0xc9, 0xc9, 0xc9, 0xc6, 0xc3, 0xc1, 0xc0, 0xc0, 0xbd, 0xbb, 0xb9, + 0xb9, 0xb8, 0xb8, 0xc3, 0xd3, 0xd7, 0xd9, 0xdc, 0xde, 0xe1, 0xe1, 0xe2, + 0xe5, 0xe7, 0xe8, 0xeb, 0xed, 0xef, 0xef, 0xf2, 0xf5, 0xf7, 0xf8, 0xf9, + 0xfb, 0xfd, 0xff, 0x01, 0x01, 0x01, 0x03, 0x03, 0x05, 0x07, 0x08, 0x08, + 0x07, 0x07, 0x07, 0x05, 0x05, 0x03, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x03, 0x03, 0x03, 0x03, 0x04, 0x05, 0x05, 0x05, 0x06, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x0b, 0x0d, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, 0x0d, 0x0d, + 0x0d, 0x0f, 0x0f, 0x11, 0x11, 0x12, 0x11, 0x12, 0x13, 0x11, 0x11, 0x11, + 0x11, 0x0f, 0x0d, 0x0d, 0x0d, 0x0d, 0x0f, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, + 0x0d, 0x0d, 0x0d, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x09, 0x0b, 0x0b, 0x09, + 0x0b, 0x0b, 0x0b, 0x0a, 0x09, 0x09, 0x07, 0x07, 0x07, 0x08, 0x09, 0x08, + 0x07, 0x07, 0x07, 0x07, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x03, 0x04, + 0x03, 0x05, 0x05, 0x04, 0x03, 0x03, 0x05, 0x06, 0x06, 0x06, 0x05, 0x05, + 0x05, 0x05, 0x07, 0x08, 0x09, 0x07, 0x07, 0x08, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x09, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, + 0x03, 0x02, 0x02, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x01, 0x00, + 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, + 0x01, 0x01, 0x01, 0x01, 0x01, 0xef, 0xe0, 0xdd, 0xd9, 0xd7, 0xd5, 0xd1, + 0xcf, 0xcf, 0xcd, 0xcb, 0xc7, 0xc6, 0xc5, 0xc3, 0xc1, 0xc0, 0xbd, 0xbc, + 0xbb, 0xb9, 0xb8, 0xb7, 0xb9, 0xcb, 0xd6, 0xd7, 0xd8, 0xdb, 0xde, 0xe1, + 0xe3, 0xe4, 0xe5, 0xe8, 0xeb, 0xed, 0xef, 0xf1, 0xf3, 0xf3, 0xf5, 0xf7, + 0xf9, 0xfb, 0xfb, 0xfd, 0xff, 0x01, 0x01, 0x02, 0x03, 0x05, 0x05, 0x05, + 0x07, 0x06, 0x07, 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0b, 0x0b, 0x0b, 0x09, 0x09, 0x09, 0x09, 0x0b, 0x0b, 0x0a, 0x09, + 0x0b, 0x0d, 0x0d, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x0b, 0x0a, + 0x0b, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, + 0x0b, 0x0b, 0x0b, 0x0d, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x11, 0x0f, 0x0d, 0x0d, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0e, 0x0d, 0x0b, 0x0b, 0x0b, 0x0d, 0x0c, + 0x0b, 0x0b, 0x0b, 0x0b, 0x09, 0x09, 0x08, 0x09, 0x09, 0x09, 0x09, 0x08, + 0x08, 0x09, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x05, 0x05, 0x04, 0x04, 0x03, 0x03, + 0x04, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x04, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, + 0x00, 0x00, 0x00, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x01, 0x01, 0x01, + 0x00, 0x01, 0x01, 0x01, 0x01, 0xfc, 0xe9, 0xdf, 0xdb, 0xd8, 0xd5, 0xd3, + 0xd1, 0xcf, 0xcd, 0xc9, 0xc9, 0xc8, 0xc7, 0xc5, 0xc2, 0xbf, 0xbd, 0xbd, + 0xbc, 0xbb, 0xb9, 0xb7, 0xb7, 0xbb, 0xd1, 0xd5, 0xd9, 0xdb, 0xdb, 0xdf, + 0xe2, 0xe5, 0xe7, 0xe8, 0xe9, 0xeb, 0xef, 0xef, 0xf3, 0xf5, 0xf7, 0xf8, + 0xfa, 0xfb, 0xfd, 0xff, 0x01, 0x01, 0x03, 0x05, 0x05, 0x05, 0x07, 0x08, + 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0e, 0x0d, + 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, 0x0e, 0x0d, + 0x0d, 0x0d, 0x0d, 0x0b, 0x0c, 0x0d, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x11, 0x0f, 0x11, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0d, 0x0f, 0x0f, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0b, 0x0b, 0x0c, + 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x0b, 0x0b, 0x09, 0x09, 0x0b, 0x09, 0x09, + 0x09, 0x09, 0x0b, 0x09, 0x09, 0x08, 0x07, 0x08, 0x09, 0x09, 0x08, 0x06, + 0x07, 0x07, 0x07, 0x07, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, + 0x05, 0x03, 0x03, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x01, 0x01, 0x00, 0xff, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xfd, 0xe8, 0xdd, 0xdb, 0xd9, 0xd5, + 0xd3, 0xd1, 0xcf, 0xcb, 0xc9, 0xc9, 0xc7, 0xc6, 0xc5, 0xc3, 0xc1, 0xc0, + 0xbd, 0xbd, 0xbd, 0xbc, 0xbb, 0xb9, 0xbb, 0xd3, 0xd9, 0xda, 0xdd, 0xdf, + 0xe1, 0xe4, 0xe5, 0xe8, 0xeb, 0xeb, 0xed, 0xef, 0xf1, 0xf3, 0xf5, 0xf7, + 0xf9, 0xfb, 0xfb, 0xfd, 0xff, 0x01, 0x01, 0x03, 0x05, 0x05, 0x05, 0x07, + 0x09, 0x09, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, + 0x0b, 0x0b, 0x0b, 0x0c, 0x0d, 0x0d, 0x0c, 0x0b, 0x0b, 0x0c, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0b, 0x0c, + 0x0d, 0x0d, 0x0b, 0x0b, 0x0b, 0x0c, 0x0d, 0x0f, 0x0e, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x11, 0x11, 0x11, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, 0x0d, 0x0d, 0x0b, 0x0b, + 0x0b, 0x0c, 0x0b, 0x0b, 0x0b, 0x0d, 0x0b, 0x0b, 0x0b, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x07, 0x07, 0x07, 0x07, 0x06, 0x05, 0x06, 0x05, 0x04, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x03, 0x05, 0x04, 0x04, 0x03, 0x03, 0x03, 0x05, 0x05, 0x03, 0x03, 0x03, + 0x04, 0x05, 0x03, 0x03, 0x02, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, + 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0xff, + 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xfe, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x01, + 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0xf7, 0xdf, 0xe1, 0xdd, + 0xd9, 0xd7, 0xd3, 0xd1, 0xcf, 0xcd, 0xcb, 0xc9, 0xc9, 0xc7, 0xc7, 0xc5, + 0xc3, 0xc1, 0xbd, 0xbf, 0xbd, 0xbd, 0xbb, 0xb9, 0xc3, 0xd9, 0xd9, 0xdb, + 0xdf, 0xdf, 0xe1, 0xe5, 0xe7, 0xe9, 0xe9, 0xed, 0xef, 0xf1, 0xf3, 0xf5, + 0xf5, 0xf8, 0xfb, 0xfb, 0xfd, 0xff, 0x01, 0x01, 0x03, 0x05, 0x05, 0x06, + 0x07, 0x09, 0x09, 0x09, 0x0b, 0x0b, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0d, 0x0c, 0x0b, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, + 0x0d, 0x0b, 0x0c, 0x0c, 0x0b, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, + 0x0d, 0x0d, 0x0d, 0x0d, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0d, 0x0f, 0x0f, + 0x0d, 0x0e, 0x0d, 0x0d, 0x0c, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, + 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0d, 0x0e, 0x0f, 0x0e, 0x0d, 0x0d, + 0x0f, 0x0d, 0x0d, 0x0d, 0x0f, 0x0e, 0x0d, 0x0e, 0x0f, 0x0e, 0x0d, 0x0d, + 0x0b, 0x0b, 0x0c, 0x0b, 0x0d, 0x0b, 0x0d, 0x0d, 0x0b, 0x0b, 0x0b, 0x0a, + 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0b, 0x09, 0x08, 0x08, 0x07, 0x07, + 0x09, 0x09, 0x07, 0x07, 0x07, 0x08, 0x07, 0x05, 0x07, 0x07, 0x06, 0x07, + 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x06, 0x05, 0x05, 0x05, 0x07, 0x05, + 0x05, 0x05, 0x04, 0x05, 0x05, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, + 0x03, 0x03, 0x03, 0x02, 0x01, 0x02, 0x01, 0x01, 0x03, 0x02, 0x01, 0x01, + 0x01, 0x01, 0x03, 0x02, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x03, + 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0x01, 0xff, 0xff, 0xff, + 0x00, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0xf5, 0xde, + 0xe0, 0xdd, 0xd9, 0xd7, 0xd5, 0xd3, 0xd1, 0xcf, 0xcd, 0xcc, 0xca, 0xc9, + 0xc8, 0xc6, 0xc5, 0xc3, 0xc1, 0xc0, 0xc0, 0xbd, 0xbd, 0xbb, 0xc5, 0xdb, + 0xda, 0xdd, 0xdf, 0xe1, 0xe3, 0xe6, 0xe8, 0xe9, 0xeb, 0xed, 0xef, 0xf2, + 0xf3, 0xf5, 0xf7, 0xf8, 0xfb, 0xfd, 0xfe, 0x00, 0x01, 0x03, 0x05, 0x05, + 0x07, 0x07, 0x09, 0x0a, 0x0b, 0x0b, 0x0b, 0x0d, 0x0d, 0x0b, 0x0b, 0x0c, + 0x0d, 0x0d, 0x0c, 0x0d, 0x0b, 0x0b, 0x0b, 0x0d, 0x0c, 0x0d, 0x0c, 0x0d, + 0x0b, 0x0c, 0x0b, 0x0b, 0x0c, 0x0d, 0x0b, 0x0c, 0x0d, 0x0c, 0x0d, 0x0d, + 0x0c, 0x0b, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, + 0x0f, 0x0d, 0x0d, 0x0d, 0x0d, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, + 0x0d, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0d, 0x0f, 0x0d, 0x0d, + 0x0d, 0x0d, 0x0f, 0x0d, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0f, 0x0e, 0x0d, + 0x0d, 0x0d, 0x0b, 0x0b, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0c, 0x0b, 0x0c, + 0x0b, 0x0b, 0x09, 0x0b, 0x0b, 0x0b, 0x09, 0x0b, 0x0b, 0x09, 0x09, 0x09, + 0x07, 0x08, 0x09, 0x09, 0x08, 0x09, 0x07, 0x06, 0x05, 0x05, 0x05, 0x06, + 0x05, 0x05, 0x05, 0x05, 0x07, 0x07, 0x07, 0x06, 0x05, 0x05, 0x05, 0x06, + 0x07, 0x05, 0x07, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x03, 0x05, 0x04, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, + 0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0xfe, 0xe0, 0xe3, 0xdf, 0xdb, 0xd9, 0xd7, 0xd5, 0xd3, 0xd1, 0xd1, 0xcd, + 0xcb, 0xca, 0xca, 0xc7, 0xc6, 0xc4, 0xc3, 0xc1, 0xc1, 0xc0, 0xbe, 0xbd, + 0xc0, 0xdd, 0xdb, 0xdd, 0xe0, 0xe1, 0xe3, 0xe7, 0xe9, 0xea, 0xed, 0xef, + 0xf1, 0xf3, 0xf3, 0xf5, 0xf7, 0xf9, 0xfb, 0xfd, 0xff, 0x00, 0x01, 0x03, + 0x05, 0x05, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0d, 0x0d, 0x0b, 0x0d, 0x0b, 0x0c, 0x0c, 0x0d, 0x0b, 0x0d, + 0x0d, 0x0d, 0x0b, 0x0c, 0x0d, 0x0d, 0x0c, 0x0b, 0x0c, 0x0d, 0x0d, 0x0c, + 0x0b, 0x0c, 0x0c, 0x0b, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, + 0x0c, 0x0d, 0x0e, 0x0c, 0x0d, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0d, + 0x0d, 0x00, 0x00, 0x00, 0x03, 0x03, 0x02, 0xf2, 0xe9, 0xeb, 0xe1, 0xd7, + 0xd2, 0xc9, 0xba, 0xb3, 0xb4, 0xb4, 0xb7, 0xb7, 0xbe, 0xbb, 0xb9, 0xc8, + 0xd4, 0xcc, 0xec, 0xe0, 0xe6, 0xe5, 0xfe, 0x03, 0x03, 0x32, 0xe1, 0x14, + 0x55, 0x31, 0x1b, 0x32, 0x23, 0x20, 0x3a, 0x26, 0x27, 0x29, 0x33, 0x20, + 0x35, 0x18, 0x2e, 0x3b, 0x17, 0x07, 0x12, 0x0a, 0x15, 0x0e, 0x05, 0x06, + 0x13, 0x13, 0xd7, 0x1a, 0xfd, 0xfd, 0xd0, 0x21, 0xf5, 0xd1, 0xef, 0x07, + 0x0a, 0xc3, 0x0b, 0x28, 0xe3, 0xe8, 0x1b, 0x2f, 0xf1, 0x07, 0x1c, 0x17, + 0x12, 0x1a, 0x3e, 0x2d, 0x01, 0x25, 0x35, 0x20, 0x0d, 0x1e, 0x33, 0x0a, + 0x1d, 0x00, 0x46, 0x0f, 0xf6, 0x3b, 0xf5, 0x1c, 0x08, 0x06, 0x07, 0xf6, + 0x3a, 0xdf, 0x0f, 0x1a, 0xdb, 0x39, 0xfc, 0x0c, 0x21, 0x02, 0x13, 0x00, + 0x27, 0xfc, 0x12, 0x39, 0xe5, 0x1a, 0x22, 0x0b, 0x16, 0x10, 0x0a, 0x1b, + 0x01, 0xf6, 0x1f, 0x0d, 0xf4, 0x14, 0x1e, 0xe4, 0xf5, 0x1a, 0x02, 0xea, + 0xfb, 0x19, 0xfd, 0xdc, 0xf5, 0x1d, 0x01, 0xd8, 0xfc, 0x15, 0xf0, 0xf5, + 0x0e, 0x09, 0xd7, 0x09, 0x0b, 0x0e, 0xea, 0x05, 0x26, 0xf2, 0x05, 0xed, + 0x1b, 0xf2, 0xf7, 0xfc, 0xf6, 0xfd, 0x02, 0x00, 0xfd, 0xfc, 0xfd, 0xe7, + 0xe9, 0xf3, 0xef, 0xf7, 0xd7, 0xf7, 0x03, 0xd7, 0xd8, 0xf9, 0xec, 0xd9, + 0xd6, 0xde, 0xe9, 0xd2, 0xd7, 0xe8, 0xf9, 0xd0, 0xe4, 0x15, 0xbe, 0x0c, + 0x0d, 0x01, 0x08, 0xce, 0x42, 0xf1, 0x25, 0x10, 0x0b, 0x50, 0xec, 0x39, + 0x1d, 0xfc, 0x4b, 0xff, 0x0b, 0x1b, 0x0d, 0x24, 0xff, 0x2a, 0x09, 0x13, + 0x13, 0xe9, 0x16, 0x08, 0xed, 0x0d, 0x09, 0xe1, 0x05, 0x0d, 0xf7, 0x07, + 0x0c, 0x17, 0x15, 0xf7, 0x04, 0x27, 0x16, 0xfd, 0x19, 0x2e, 0xed, 0x17, + 0x26, 0x21, 0xfc, 0x1e, 0x28, 0x00, 0xfb, 0x0e, 0x26, 0x08, 0xf4, 0x17, + 0x26, 0xea, 0xf6, 0x0d, 0x13, 0xf6, 0xf8, 0x0d, 0xf0, 0xf0, 0x02, 0x07, + 0xf1, 0xe1, 0x00, 0x14, 0xe7, 0xf4, 0x03, 0xfd, 0xf3, 0xfc, 0xfe, 0x01, + 0x0d, 0x10, 0xf6, 0x05, 0x0e, 0x01, 0x02, 0xeb, 0x00, 0xff, 0xe5, 0xfa, + 0x10, 0x00, 0xf0, 0xfd, 0x02, 0xdd, 0xfb, 0xd1, 0x03, 0xf0, 0xd7, 0x00, + 0xd4, 0xff, 0xcf, 0xf2, 0xed, 0xb6, 0x02, 0xc3, 0xd9, 0xe1, 0xbf, 0x17, + 0xc6, 0xce, 0xf3, 0xdc, 0x02, 0xea, 0x08, 0xe3, 0xfd, 0x21, 0xdc, 0x06, + 0x1a, 0x12, 0x22, 0x0e, 0x0f, 0x3a, 0x0e, 0x15, 0x1a, 0x29, 0xf6, 0x24, + 0x11, 0x11, 0x18, 0x1c, 0x1b, 0x05, 0x09, 0xfe, 0x17, 0xf5, 0xec, 0x0f, + 0x09, 0xdf, 0xf1, 0x0a, 0x03, 0xe8, 0x1f, 0x05, 0xfb, 0x02, 0x00, 0x29, + 0xec, 0xfc, 0x24, 0x14, 0xf5, 0xfd, 0x2b, 0x25, 0xf7, 0x1a, 0x1a, 0x0f, + 0x0a, 0x12, 0x1e, 0x19, 0x0a, 0x19, 0x12, 0x07, 0x0b, 0x1a, 0x18, 0xf2, + 0x10, 0x06, 0x0d, 0x06, 0x00, 0xf7, 0xfb, 0x05, 0xf7, 0xf9, 0x00, 0x04, + 0x02, 0xe2, 0xf8, 0x1f, 0xe0, 0x0b, 0x05, 0x0c, 0xff, 0xf7, 0x1c, 0xf7, + 0x02, 0xf2, 0xeb, 0x0b, 0xe0, 0xfb, 0x0d, 0xeb, 0x0b, 0xec, 0xfd, 0xec, + 0xe0, 0xf9, 0xe6, 0xeb, 0xe1, 0xf7, 0xee, 0xe3, 0xe3, 0xfd, 0xe1, 0xf1, + 0xd9, 0xd1, 0xf1, 0xeb, 0xeb, 0xe6, 0xdd, 0xce, 0xf9, 0xd0, 0xd0, 0xef, + 0xee, 0xbe, 0xce, 0xdd, 0xc0, 0xd9, 0xe6, 0xd9, 0xe2, 0xd2, 0xf0, 0xec, + 0xe6, 0xe2, 0xf9, 0x06, 0xc0, 0xf7, 0x19, 0xee, 0x04, 0x26, 0x04, 0x10, + 0x2a, 0x3e, 0x00, 0x17, 0x1a, 0x17, 0x28, 0xfd, 0x0a, 0x3b, 0x45, 0x03, + 0x43, 0x2d, 0x34, 0x1c, 0x32, 0x34, 0x1d, 0x1a, 0x27, 0x36, 0x13, 0x19, + 0x4d, 0x2a, 0xf6, 0x2e, 0x16, 0x05, 0xe5, 0x32, 0x0a, 0x00, 0xf4, 0x08, + 0x1b, 0xe2, 0x10, 0x15, 0xee, 0x01, 0x13, 0x1f, 0xf1, 0x0a, 0x22, 0xdf, + 0x29, 0x09, 0x1c, 0x20, 0xfa, 0x3d, 0x07, 0x14, 0x11, 0x16, 0x2e, 0x01, + 0x2e, 0x11, 0x1c, 0x31, 0x17, 0x2f, 0xf8, 0x14, 0x19, 0xed, 0x05, 0xfa, + 0x2f, 0x02, 0xf0, 0x1a, 0xdf, 0x20, 0xf5, 0xe7, 0x18, 0xef, 0xff, 0xf3, + 0x05, 0xe8, 0x06, 0x24, 0xdc, 0xe3, 0x0a, 0x01, 0xe1, 0xf9, 0xf7, 0xeb, + 0x01, 0xcf, 0xfc, 0x0e, 0xd2, 0x1b, 0x03, 0xe6, 0xf9, 0x06, 0x1e, 0xd5, + 0x19, 0x1b, 0x00, 0x14, 0x00, 0x1f, 0x27, 0x05, 0x0d, 0x12, 0x07, 0x09, + 0x24, 0x09, 0xf9, 0x22, 0x1c, 0x02, 0xfb, 0x1b, 0x17, 0x10, 0xf3, 0x05, + 0xfc, 0xf8, 0xf4, 0x10, 0xfe, 0xe9, 0x22, 0x06, 0xf8, 0x0d, 0x09, 0x13, + 0xf3, 0xef, 0x19, 0xfb, 0x09, 0xf2, 0x1f, 0x1c, 0xdd, 0x08, 0xf7, 0xed, + 0x03, 0xe9, 0xfc, 0xe3, 0xf3, 0xf6, 0xe1, 0xfe, 0xdb, 0x04, 0xda, 0xe6, + 0x19, 0xe5, 0x06, 0xde, 0xfe, 0x05, 0xde, 0x1e, 0xe9, 0x23, 0x09, 0x01, + 0x26, 0xd2, 0x38, 0x0e, 0xfc, 0x12, 0x08, 0x31, 0xff, 0x23, 0x16, 0x17, + 0x19, 0xec, 0x04, 0x03, 0xf4, 0x03, 0x10, 0xed, 0xf1, 0x1e, 0xeb, 0xec, + 0x06, 0x01, 0x07, 0xe0, 0xec, 0x06, 0x03, 0xef, 0xf3, 0x16, 0xe7, 0xed, + 0x1b, 0xf3, 0xe0, 0x0d, 0x03, 0xe3, 0xdf, 0xfc, 0x01, 0xf9, 0xea, 0xff, + 0x13, 0xe5, 0xf7, 0x13, 0x03, 0xf9, 0x1a, 0x16, 0xf0, 0x0d, 0x2c, 0x18, + 0x00, 0x0f, 0x1c, 0x26, 0xf1, 0x07, 0x2f, 0xff, 0x0c, 0x17, 0x10, 0x02, + 0x03, 0x2b, 0x00, 0xfb, 0x13, 0x00, 0x05, 0xdd, 0x08, 0x12, 0xe5, 0x01, + 0x09, 0x05, 0xff, 0x00, 0x06, 0xf1, 0x05, 0xee, 0xf8, 0xff, 0xf2, 0x13, + 0xf8, 0xfb, 0xf4, 0xfb, 0x00, 0xd2, 0x09, 0xe4, 0xe8, 0xf5, 0xdd, 0x11, + 0xda, 0xe1, 0xfa, 0xdc, 0x01, 0xe7, 0xfc, 0xe4, 0xf8, 0x0e, 0xe1, 0xf5, + 0x04, 0x07, 0x08, 0x00, 0x08, 0x1b, 0xfe, 0x0e, 0x0c, 0x16, 0xf3, 0x29, + 0x10, 0x0e, 0x15, 0x21, 0x30, 0xf4, 0x10, 0x0f, 0x0f, 0xfe, 0xf2, 0x18, + 0x0f, 0xeb, 0x02, 0x0e, 0x04, 0xf1, 0x1a, 0x03, 0xe5, 0x00, 0x0b, 0x0d, + 0xe6, 0xfe, 0x14, 0x03, 0xec, 0xfb, 0x1e, 0xfe, 0xea, 0x0f, 0xfe, 0xe5, + 0x00, 0x04, 0xfc, 0xf6, 0xfe, 0x13, 0xf6, 0xea, 0x17, 0x14, 0x07, 0xf5, + 0x17, 0x18, 0x03, 0x1b, 0x03, 0x13, 0x18, 0x0c, 0x11, 0x0a, 0x09, 0x16, + 0x11, 0xfd, 0x15, 0x11, 0x00, 0x0a, 0x07, 0x0e, 0x01, 0x0b, 0x0a, 0xef, + 0xfc, 0xf6, 0x06, 0xf1, 0xf3, 0x0e, 0xfd, 0xf5, 0xfe, 0xf6, 0x06, 0xe8, + 0xef, 0xfe, 0xec, 0xf9, 0xf4, 0x09, 0xee, 0xf3, 0x03, 0xee, 0xf3, 0xee, + 0xe8, 0xf0, 0xf1, 0xf6, 0xeb, 0xef, 0xe7, 0xf4, 0xfa, 0xe2, 0x02, 0xfe, + 0xe8, 0x06, 0xf5, 0x0b, 0xee, 0xfe, 0x04, 0xfe, 0xf8, 0xfc, 0x11, 0xf7, + 0xea, 0xf9, 0x08, 0xe5, 0xf0, 0x05, 0x03, 0xf9, 0xfd, 0x0e, 0x0a, 0xee, + 0x11, 0x0b, 0xfc, 0xf3, 0x18, 0x09, 0xf8, 0x0a, 0x09, 0x24, 0x0b, 0x19, + 0x1f, 0x11, 0x0c, 0x12, 0x20, 0x1f, 0x05, 0x1a, 0x24, 0x11, 0x1a, 0x26, + 0x27, 0x20, 0x12, 0x1c, 0x10, 0x0d, 0x19, 0x12, 0x24, 0x06, 0x06, 0x1c, + 0xf9, 0x13, 0x00, 0xfe, 0xff, 0x01, 0xff, 0xee, 0x02, 0xf8, 0xf1, 0xf8, + 0xf1, 0x02, 0xf3, 0xe9, 0x04, 0xfd, 0xf3, 0xf5, 0x07, 0xfc, 0xfb, 0x07, + 0x11, 0x0f, 0x08, 0x09, 0x18, 0x09, 0xff, 0x06, 0x06, 0x0c, 0x10, 0x03, + 0x0f, 0x12, 0xff, 0x0a, 0xf8, 0xfd, 0xf8, 0xfe, 0x00, 0xe4, 0x02, 0xf1, + 0xe9, 0x0b, 0xd6, 0xf8, 0xf5, 0xdc, 0xfb, 0xe6, 0xfa, 0xeb, 0xed, 0xef, + 0xe3, 0x14, 0xe6, 0xf3, 0x16, 0xee, 0xff, 0x03, 0x05, 0xff, 0x05, 0x11, + 0xfd, 0x1a, 0x0b, 0x17, 0x22, 0x0e, 0x13, 0x15, 0x10, 0x07, 0x18, 0x21, + 0x10, 0x11, 0x16, 0x0e, 0x11, 0x0c, 0x07, 0x0e, 0x12, 0xf8, 0x0e, 0x06, + 0xff, 0x03, 0x06, 0x0e, 0x01, 0x0f, 0x01, 0x14, 0x13, 0x02, 0x11, 0x11, + 0x04, 0x05, 0x0a, 0x0f, 0x0b, 0x1c, 0x12, 0x1a, 0x08, 0x04, 0x23, 0x07, + 0x10, 0x0f, 0x19, 0x08, 0x06, 0x17, 0x04, 0x07, 0x00, 0x01, 0x08, 0xf6, + 0xfb, 0x05, 0xf2, 0xf0, 0xf8, 0xfc, 0xec, 0xf9, 0xf2, 0xf5, 0xf7, 0xf5, + 0x0c, 0xf3, 0xf0, 0x07, 0x01, 0xfc, 0xf6, 0x1a, 0x0c, 0xf9, 0x0a, 0xee, + 0x09, 0x00, 0xf5, 0x07, 0xfc, 0x02, 0x01, 0x03, 0xf4, 0xf0, 0x0b, 0xec, + 0xef, 0xef, 0xe7, 0xfd, 0xe8, 0xed, 0xef, 0xef, 0xea, 0xe3, 0xee, 0xeb, + 0xf5, 0xf8, 0xe1, 0xea, 0xfd, 0xed, 0xf1, 0xf8, 0x01, 0xf3, 0xfb, 0x02, + 0xfc, 0x00, 0x03, 0xfe, 0x09, 0x04, 0xfe, 0x18, 0x07, 0x0e, 0x14, 0x11, + 0x02, 0x0c, 0x0c, 0x0f, 0x11, 0x16, 0x17, 0x10, 0x11, 0x0a, 0x1a, 0x0d, + 0x08, 0x18, 0x13, 0xff, 0x0a, 0x0e, 0x0c, 0x0b, 0x08, 0x0d, 0x0d, 0x08, + 0x0b, 0x15, 0x09, 0x09, 0x15, 0x0c, 0xf4, 0x09, 0x07, 0x11, 0x0a, 0x0b, + 0x0e, 0x0d, 0x08, 0x06, 0x13, 0x04, 0x08, 0x0e, 0x0b, 0x0b, 0x06, 0x0e, + 0x05, 0xfb, 0x09, 0xf7, 0x0a, 0xf8, 0xfe, 0xff, 0xeb, 0x0a, 0xf6, 0xf9, + 0xf2, 0xf5, 0xfc, 0xf6, 0xf9, 0xf7, 0xfa, 0x07, 0xec, 0xfd, 0xfb, 0xfd, + 0x0e, 0xff, 0x00, 0xfd, 0x07, 0xf6, 0xfb, 0x05, 0xf6, 0x05, 0x04, 0xf7, + 0xfa, 0x00, 0x04, 0xfc, 0xf7, 0xf8, 0xf5, 0xfd, 0xea, 0xf4, 0xfd, 0xf1, + 0xe9, 0xf0, 0xf4, 0xe9, 0xf2, 0xf8, 0xf5, 0xf3, 0xeb, 0xf9, 0xfd, 0xec, + 0x01, 0xff, 0x01, 0xf7, 0x00, 0x10, 0xfc, 0x09, 0x09, 0x02, 0x08, 0x02, + 0x0f, 0x0f, 0x03, 0x16, 0x0d, 0x08, 0xfd, 0x10, 0x0e, 0x06, 0x13, 0x0f, + 0x0f, 0x0f, 0x05, 0x0e, 0x0f, 0x0a, 0x0d, 0x0d, 0x08, 0x01, 0x14, 0x07, + 0x04, 0x0d, 0x06, 0x09, 0x09, 0x07, 0x0c, 0x10, 0x11, 0x02, 0x05, 0x05, + 0xfe, 0x0b, 0xfd, 0x06, 0x07, 0x04, 0x03, 0x03, 0x03, 0x00, 0x01, 0x03, + 0x01, 0x01, 0x01, 0x0b, 0x04, 0xfb, 0x00, 0x01, 0x02, 0x01, 0xfe, 0xfb, + 0xfb, 0x00, 0xff, 0xfd, 0xfb, 0xf6, 0x08, 0xf1, 0xf5, 0x09, 0x02, 0x00, + 0xfa, 0x08, 0x01, 0xfc, 0x0d, 0x0b, 0x09, 0x04, 0x07, 0x0f, 0xfe, 0xfc, + 0x09, 0x09, 0xfa, 0x02, 0x06, 0xff, 0xfa, 0xfb, 0x03, 0x00, 0xf0, 0xfd, + 0xfb, 0xf1, 0xf8, 0xf7, 0xfe, 0xec, 0xf1, 0xfb, 0xf2, 0xf5, 0xfa, 0xfe, + 0x00, 0xf5, 0x03, 0x06, 0x02, 0x03, 0x05, 0x11, 0xfe, 0x08, 0x13, 0x05, + 0x0e, 0x0f, 0x0a, 0x0b, 0x09, 0x0b, 0x0c, 0x12, 0x05, 0x06, 0x0e, 0x01, + 0x03, 0x09, 0x07, 0x0c, 0x06, 0x07, 0x07, 0x0d, 0x04, 0x00, 0x12, 0x04, + 0x03, 0x08, 0x09, 0x07, 0x04, 0x05, 0x0c, 0x0b, 0x04, 0x07, 0x09, 0x08, + 0x0e, 0x0f, 0x0c, 0x09, 0x09, 0x0c, 0x06, 0x02, 0x09, 0x07, 0x07, 0x00, + 0x02, 0x03, 0x00, 0x01, 0xf5, 0x01, 0xff, 0xfa, 0x01, 0xfa, 0xf5, 0xfe, + 0xfd, 0xf8, 0xf6, 0xf7, 0xfe, 0xf3, 0xf3, 0xf5, 0xfd, 0xf9, 0xf2, 0xfa, + 0xfe, 0xf1, 0xff, 0xff, 0xfc, 0xfb, 0xfd, 0x02, 0x01, 0x03, 0x01, 0x0b, + 0x03, 0x05, 0x05, 0x07, 0x05, 0x00, 0x08, 0x02, 0x05, 0x08, 0x00, 0x03, + 0x04, 0x03, 0x00, 0xfe, 0x04, 0xf9, 0x02, 0x00, 0xf8, 0x00, 0xfe, 0xf8, + 0xf7, 0xf9, 0xfe, 0xfb, 0x00, 0xf5, 0x03, 0x06, 0xf9, 0x0a, 0x05, 0x03, + 0x0a, 0x09, 0x0a, 0x05, 0x11, 0x0f, 0x0a, 0x0d, 0x08, 0x13, 0x0c, 0x08, + 0x0c, 0x12, 0x0a, 0x01, 0x0e, 0x06, 0x05, 0x05, 0x05, 0x0c, 0x03, 0x06, + 0x08, 0x05, 0x07, 0xff, 0x07, 0x04, 0x02, 0x05, 0x00, 0x03, 0x03, 0x08, + 0x07, 0x00, 0x08, 0x01, 0x05, 0x08, 0x05, 0x06, 0x07, 0x09, 0xff, 0x03, + 0x05, 0x03, 0x08, 0x00, 0xff, 0x09, 0xfd, 0xfd, 0xff, 0x01, 0xf7, 0x03, + 0x01, 0xf7, 0x01, 0xfe, 0x01, 0xfc, 0xfe, 0xf8, 0x00, 0xfa, 0xf4, 0xff, + 0xfd, 0xfa, 0xfb, 0xfb, 0xf9, 0xfa, 0x01, 0xfd, 0xfe, 0x00, 0xfe, 0x04, + 0x00, 0x00, 0x05, 0x0b, 0x05, 0x01, 0x0e, 0x07, 0x08, 0x08, 0x06, 0x08, + 0x08, 0x08, 0x02, 0x06, 0x09, 0x02, 0x06, 0xff, 0x00, 0x05, 0xff, 0xfb, + 0x01, 0x00, 0xfb, 0xfe, 0x00, 0xfa, 0xfe, 0xfe, 0xfc, 0xfa, 0xff, 0x00, + 0x00, 0x00, 0xff, 0x09, 0x07, 0xfd, 0x07, 0x06, 0x07, 0x06, 0x05, 0x0a, + 0x04, 0x05, 0x0a, 0x06, 0x09, 0x04, 0x06, 0x05, 0x04, 0x06, 0xff, 0x06, + 0xff, 0x05, 0x02, 0x02, 0x02, 0x05, 0xff, 0xff, 0x04, 0x02, 0xfd, 0x03, + 0x00, 0xfe, 0x00, 0xfe, 0x04, 0x00, 0xfe, 0x00, 0x03, 0xfc, 0xfe, 0x06, + 0xff, 0xfd, 0x02, 0x02, 0xfd, 0x03, 0x00, 0x00, 0x02, 0x00, 0x01, 0x02, + 0xfc, 0x00, 0x02, 0x03, 0x00, 0x02, 0x03, 0x00, 0x02, 0x03, 0x02, 0x01, + 0x00, 0x01, 0x00, 0xfd, 0x00, 0x01, 0x00, 0xfb, 0xff, 0x04, 0xfb, 0xff, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x01, 0x04, + 0x04, 0xff, 0x02, 0x05, 0x02, 0x01, 0x03, 0x04, 0x04, 0x01, 0x07, 0x04, + 0x02, 0x02, 0x04, 0x04, 0xff, 0x02, 0x03, 0x00, 0xff, 0x02, 0x03, 0x00, + 0xfe, 0x04, 0x00, 0xff, 0x00, 0x02, 0x01, 0x00, 0x02, 0x02, 0x02, 0x00, + 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x02, 0x05, 0x04, 0x02, 0x03, 0x04, + 0x03, 0x03, 0x03, 0x04, 0x03, 0x01, 0x01, 0x04, 0x02, 0x00, 0x03, 0x02, + 0x00, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, + 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xf9, 0xf3, 0xed, 0xe9, 0xe5, 0xe3, 0xe1, 0xdf, + 0xdd, 0xdb, 0xd9, 0xd7, 0xd5, 0xd3, 0xd1, 0xcf, 0xcd, 0xcb, 0xc9, 0xc8, + 0xc7, 0xc5, 0xc3, 0xc2, 0xc1, 0xbf, 0xbd, 0xbc, 0xbb, 0xb9, 0xb7, 0xb6, + 0xb5, 0xb3, 0xb2, 0xb1, 0xb0, 0xaf, 0xaf, 0xae, 0xad, 0xad, 0xad, 0xad, + 0xaf, 0xb3, 0xb9, 0xc1, 0xc9, 0xd0, 0xd7, 0xdd, 0xe2, 0xe6, 0xe9, 0xec, + 0xef, 0xf2, 0xf5, 0xf7, 0xf9, 0xfc, 0xfd, 0xff, 0x01, 0x03, 0x05, 0x07, + 0x09, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11, 0x13, 0x15, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1b, 0x1c, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x22, 0x23, 0x24, + 0x25, 0x27, 0x29, 0x2a, 0x2b, 0x2b, 0x2d, 0x2f, 0x31, 0x30, 0x2f, 0x30, + 0x33, 0x36, 0x37, 0x37, 0x36, 0x35, 0x33, 0x33, 0x33, 0x35, 0x38, 0x3b, + 0x3e, 0x41, 0x44, 0x44, 0x44, 0x46, 0x49, 0x49, 0x47, 0x46, 0x46, 0x47, + 0x48, 0x48, 0x47, 0x46, 0x46, 0x46, 0x48, 0x49, 0x48, 0x47, 0x46, 0x46, + 0x46, 0x47, 0x48, 0x47, 0x47, 0x47, 0x48, 0x49, 0x48, 0x47, 0x47, 0x47, + 0x48, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, + 0x48, 0x48, 0x47, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x46, + 0x47, 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, 0x40, 0x40, + 0x3f, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3a, + 0x3a, 0x3a, 0x3a, 0x39, 0x38, 0x38, 0x37, 0x36, 0x35, 0x35, 0x35, 0x35, + 0x35, 0x35, 0x35, 0x35, 0x35, 0x34, 0x33, 0x31, 0x2f, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2e, 0x2f, 0x2f, 0x2e, 0x2d, 0x2d, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, + 0x27, 0x25, 0x26, 0x28, 0x2b, 0x2c, 0x2a, 0x27, 0x26, 0x26, 0x27, 0x28, + 0x27, 0x25, 0x22, 0x1f, 0x1f, 0x21, 0x22, 0x23, 0x24, 0x25, 0x25, 0x25, + 0x25, 0x26, 0x26, 0x25, 0x22, 0x20, 0x1e, 0x1e, 0x20, 0x21, 0x22, 0x22, + 0x23, 0x26, 0x29, 0x29, 0x28, 0x27, 0x25, 0x23, 0x21, 0x21, 0x21, 0x22, + 0x23, 0x25, 0x27, 0x29, 0x2a, 0x2b, 0x2c, 0x2c, 0x2b, 0x2a, 0x28, 0x26, + 0x25, 0x25, 0x26, 0x27, 0x28, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x2a, + 0x2a, 0x29, 0x28, 0x27, 0x27, 0x29, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x2f, + 0x2f, 0x2f, 0x30, 0x30, 0x2f, 0x2d, 0x2c, 0x2c, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x31, 0x31, 0x31, 0x30, 0x2f, 0x2d, 0x2d, 0x2c, 0x2b, 0x2a, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2e, 0x2d, 0x2c, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x26, 0x26, 0x28, 0x2a, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2a, 0x29, 0x27, 0x25, 0x25, 0x27, 0x28, 0x29, 0x29, 0x27, + 0x25, 0x23, 0x23, 0x24, 0x25, 0x24, 0x24, 0x24, 0x23, 0x22, 0x21, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x21, 0x20, 0x1f, 0x1d, 0x1c, 0x1b, 0x1b, 0x1b, + 0x1d, 0x1f, 0x21, 0x21, 0x20, 0x1d, 0x1a, 0x18, 0x18, 0x19, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1e, 0x1b, 0x19, 0x17, 0x17, 0x19, 0x1b, 0x1d, 0x1e, 0x1f, + 0x1f, 0x1e, 0x1c, 0x1a, 0x19, 0x19, 0x1b, 0x1d, 0x1e, 0x1f, 0x1e, 0x1d, + 0x1c, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1d, 0x1c, 0x1b, 0x1b, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1b, 0x1b, 0x1d, 0x1e, + 0x20, 0x21, 0x22, 0x22, 0x20, 0x1e, 0x1c, 0x1b, 0x1b, 0x1b, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x1e, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1e, 0x1d, + 0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1b, 0x1a, 0x19, + 0x18, 0x15, 0x12, 0x0e, 0x0a, 0x06, 0x02, 0xfe, 0xfb, 0xf8, 0xf4, 0xf1, + 0xee, 0xe9, 0xe4, 0xdf, 0xd9, 0xd5, 0xd1, 0xcd, 0xcb, 0xc9, 0xc8, 0xc7, + 0xc5, 0xc4, 0xc3, 0xc1, 0xbf, 0xbc, 0xba, 0xb8, 0xb6, 0xb4, 0xb3, 0xb3, + 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb2, 0xb1, 0xb1, 0xb0, 0xb0, 0xb0, 0xb0, + 0xb1, 0xb3, 0xb5, 0xb9, 0xbd, 0xc1, 0xc5, 0xc9, 0xce, 0xd1, 0xd4, 0xd7, + 0xd9, 0xdc, 0xdf, 0xe1, 0xe5, 0xe8, 0xeb, 0xef, 0xf3, 0xf7, 0xfb, 0xfe, + 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x05, 0x07, 0x09, + 0x0b, 0x0d, 0x0e, 0x0f, 0x10, 0x10, 0x0f, 0x0e, 0x0d, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x15, 0x14, 0x13, 0x11, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x15, 0x15, 0x17, 0x18, 0x19, 0x1a, 0x19, 0x18, + 0x17, 0x16, 0x16, 0x16, 0x16, 0x17, 0x18, 0x18, 0x19, 0x1b, 0x1c, 0x1d, + 0x1d, 0x1c, 0x1b, 0x19, 0x19, 0x19, 0x1a, 0x19, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1b, 0x1a, 0x19, 0x19, 0x19, 0x19, 0x19, + 0x19, 0x19, 0x19, 0x19, 0x18, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, + 0x17, 0x17, 0x17, 0x17, 0x18, 0x19, 0x19, 0x19, 0x19, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x18, 0x17, 0x16, 0x15, 0x15, 0x15, + 0x15, 0x14, 0x13, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x12, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x10, 0x0f, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, + 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x0f, 0x0e, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0d, 0x0e, 0x0f, 0x0f, 0x0d, 0x0b, 0x0b, 0x0a, 0x09, + 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, + 0x05, 0x05, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x05, 0x05, + 0x05, 0x05, 0x06, 0x07, 0x08, 0x07, 0x06, 0x05, 0x03, 0x03, 0x05, 0x07, + 0x09, 0x0b, 0x0c, 0x0c, 0x0b, 0x09, 0x07, 0x07, 0x07, 0x07, 0x09, 0x0b, + 0x0d, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x11, 0x13, 0x14, 0x13, 0x12, + 0x11, 0x0f, 0x0d, 0x0c, 0x0d, 0x11, 0x14, 0x17, 0x19, 0x19, 0x17, 0x15, + 0x14, 0x15, 0x17, 0x18, 0x19, 0x1a, 0x19, 0x19, 0x19, 0x19, 0x19, 0x1b, + 0x1d, 0x1f, 0x21, 0x23, 0x24, 0x22, 0x20, 0x1e, 0x1d, 0x1e, 0x20, 0x22, + 0x25, 0x27, 0x26, 0x24, 0x22, 0x20, 0x1f, 0x1f, 0x21, 0x23, 0x25, 0x26, + 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x21, + 0x20, 0x20, 0x20, 0x20, 0x21, 0x22, 0x23, 0x23, 0x22, 0x21, 0x20, 0x1f, + 0x1f, 0x20, 0x21, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, + 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1b, 0x19, 0x19, 0x19, 0x19, 0x19, 0x1a, + 0x1b, 0x1c, 0x1b, 0x1a, 0x18, 0x16, 0x15, 0x15, 0x15, 0x15, 0x15, 0x16, + 0x17, 0x17, 0x17, 0x16, 0x15, 0x13, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x07, + 0x10, 0x16, 0x18, 0x16, 0x0f, 0x04, 0xfd, 0xf9, 0xfa, 0xfe, 0x02, 0x07, + 0x0a, 0x0a, 0x08, 0x05, 0x03, 0x02, 0x01, 0x01, 0xfd, 0xfa, 0xf8, 0xf5, + 0xf3, 0xf1, 0xee, 0xed, 0xec, 0xef, 0xf5, 0x00, 0x0b, 0x18, 0x1f, 0x21, + 0x1e, 0x19, 0x15, 0x12, 0x12, 0x15, 0x15, 0x12, 0x0d, 0x05, 0xfd, 0xf5, + 0xf2, 0xf9, 0xec, 0xe0, 0xda, 0xdb, 0xdd, 0xe0, 0xeb, 0xfd, 0x0e, 0x11, + 0x07, 0x02, 0x0d, 0x22, 0x2d, 0x21, 0x0d, 0xff, 0x01, 0x0a, 0x07, 0xf9, + 0xf0, 0xf0, 0xf9, 0xff, 0x01, 0x04, 0x0d, 0x17, 0x19, 0x10, 0x07, 0x07, + 0x0c, 0x09, 0xf5, 0xdc, 0xdb, 0xd8, 0xe4, 0xf0, 0xec, 0xe6, 0xea, 0xfa, + 0x0f, 0x1e, 0x29, 0x31, 0x33, 0x2d, 0x26, 0x19, 0x19, 0x25, 0x28, 0x1b, + 0x00, 0xe6, 0xe0, 0xeb, 0xf3, 0xf0, 0xe5, 0xdd, 0xdc, 0xde, 0xdf, 0xe5, + 0xf3, 0x02, 0x0a, 0x07, 0x00, 0x03, 0x15, 0x26, 0x2a, 0x1c, 0x0b, 0x01, + 0x02, 0x06, 0x00, 0xf8, 0xf5, 0xfa, 0x00, 0x03, 0x04, 0x06, 0x0c, 0x14, + 0x11, 0x08, 0x04, 0x05, 0x06, 0xfe, 0xea, 0xdb, 0xd9, 0xdd, 0xea, 0xee, + 0xeb, 0xed, 0xf8, 0x0b, 0x1d, 0x27, 0x2c, 0x30, 0x2e, 0x27, 0x1b, 0x16, + 0x1b, 0x24, 0x23, 0x0d, 0xf4, 0xe4, 0xe3, 0xec, 0xef, 0xe9, 0xe2, 0xde, + 0xde, 0xe1, 0xe4, 0xeb, 0xf7, 0x03, 0x06, 0x01, 0xff, 0x0a, 0x1c, 0x2a, + 0x26, 0x17, 0x08, 0x03, 0x02, 0x00, 0xfc, 0xf9, 0xfb, 0x01, 0x07, 0x05, + 0x04, 0x07, 0x0d, 0x0f, 0x0a, 0x05, 0x02, 0x03, 0x01, 0xf6, 0xe4, 0xdb, + 0xd9, 0xe2, 0xeb, 0xed, 0xee, 0xf6, 0x07, 0x19, 0x26, 0x2b, 0x2d, 0x2c, + 0x26, 0x1d, 0x15, 0x16, 0x1f, 0x22, 0x18, 0x03, 0xed, 0xe3, 0xe6, 0xec, + 0xeb, 0xe5, 0xe0, 0xe0, 0xe1, 0xe4, 0xe8, 0xf0, 0xfa, 0x01, 0x00, 0x00, + 0x05, 0x11, 0x25, 0x2d, 0x24, 0x13, 0x07, 0x01, 0x00, 0xfe, 0xfc, 0xfc, + 0x02, 0x09, 0x0a, 0x07, 0x05, 0x07, 0x0a, 0x09, 0x05, 0x00, 0xff, 0xff, + 0xfc, 0xef, 0xe1, 0xdc, 0xe0, 0xea, 0xef, 0xf2, 0xf8, 0x06, 0x1a, 0x29, + 0x30, 0x30, 0x2c, 0x29, 0x24, 0x1c, 0x1a, 0x1e, 0x24, 0x22, 0x11, 0xfa, + 0xe9, 0xe3, 0xe5, 0xe7, 0xe3, 0xdd, 0xda, 0xdb, 0xde, 0xe1, 0xe6, 0xef, + 0xf7, 0xfb, 0xfc, 0xfc, 0x07, 0x17, 0x26, 0x26, 0x1a, 0x0c, 0x00, 0xfc, + 0xfc, 0xfd, 0xfe, 0x04, 0x0b, 0x0e, 0x0c, 0x08, 0x06, 0x07, 0x0a, 0x07, + 0x02, 0xfd, 0xfc, 0xfc, 0xf6, 0xea, 0xe1, 0xe0, 0xe5, 0xed, 0xf2, 0xf8, + 0x03, 0x16, 0x26, 0x30, 0x31, 0x2d, 0x27, 0x22, 0x1d, 0x1a, 0x1c, 0x20, + 0x21, 0x17, 0x04, 0xf0, 0xe5, 0xe3, 0xe5, 0xe2, 0xde, 0xdc, 0xdb, 0xde, + 0xe0, 0xe5, 0xea, 0xf2, 0xf7, 0xfa, 0xfb, 0x02, 0x12, 0x21, 0x27, 0x23, + 0x14, 0x06, 0xfe, 0xfb, 0xfc, 0xff, 0x04, 0x0a, 0x0e, 0x0d, 0x09, 0x05, + 0x05, 0x08, 0x07, 0x04, 0xfe, 0xfc, 0xfb, 0xf9, 0xf1, 0xe8, 0xe3, 0xe3, + 0xe9, 0xef, 0xf6, 0xff, 0x11, 0x21, 0x2e, 0x32, 0x2e, 0x28, 0x21, 0x1d, + 0x1a, 0x1a, 0x1d, 0x20, 0x1a, 0x0d, 0xf9, 0xe9, 0xe1, 0xe0, 0xe2, 0xdf, + 0xdd, 0xdb, 0xdc, 0xdf, 0xe3, 0xe8, 0xed, 0xf3, 0xf8, 0xfb, 0xfe, 0x0b, + 0x1a, 0x26, 0x28, 0x1d, 0x0c, 0x00, 0xfb, 0xfb, 0x00, 0x04, 0x0a, 0x0e, + 0x0e, 0x0b, 0x07, 0x04, 0x05, 0x07, 0x04, 0x00, 0xfb, 0xf9, 0xf8, 0xf5, + 0xed, 0xe7, 0xe4, 0xe6, 0xec, 0xf3, 0xfc, 0x0b, 0x1d, 0x2b, 0x32, 0x30, + 0x28, 0x22, 0x1d, 0x1a, 0x1a, 0x1b, 0x1d, 0x1a, 0x12, 0x02, 0xef, 0xe3, + 0xdf, 0xe0, 0xe0, 0xde, 0xdb, 0xdc, 0xde, 0xe2, 0xe6, 0xeb, 0xef, 0xf3, + 0xf7, 0xfc, 0x06, 0x14, 0x22, 0x29, 0x22, 0x14, 0x03, 0xfb, 0xf9, 0xfc, + 0x01, 0x07, 0x0c, 0x0e, 0x0b, 0x07, 0x01, 0x01, 0x02, 0x01, 0xff, 0xf9, + 0xf4, 0xf3, 0xf2, 0xee, 0xe8, 0xe5, 0xe5, 0xea, 0xf1, 0xfb, 0x08, 0x1a, + 0x29, 0x32, 0x33, 0x2b, 0x23, 0x1c, 0x18, 0x19, 0x1c, 0x1d, 0x1e, 0x16, + 0x0a, 0xfa, 0xed, 0xe5, 0xe2, 0xe2, 0xe1, 0xdf, 0xdd, 0xde, 0xe2, 0xe6, + 0xea, 0xef, 0xf3, 0xf7, 0xfc, 0x04, 0x10, 0x1e, 0x27, 0x27, 0x1b, 0x0b, + 0xfe, 0xf9, 0xfa, 0xff, 0x07, 0x0c, 0x0f, 0x0e, 0x09, 0x04, 0x01, 0x01, + 0x01, 0x00, 0xfb, 0xf7, 0xf4, 0xf3, 0xf1, 0xed, 0xe9, 0xe7, 0xe8, 0xee, + 0xf9, 0x04, 0x15, 0x25, 0x31, 0x34, 0x2e, 0x24, 0x1d, 0x18, 0x17, 0x1a, + 0x1c, 0x1c, 0x18, 0x0d, 0xfe, 0xf0, 0xe7, 0xe3, 0xe1, 0xe0, 0xdf, 0xde, + 0xdf, 0xe0, 0xe4, 0xe8, 0xec, 0xf0, 0xf3, 0xf9, 0xff, 0x0c, 0x19, 0x26, + 0x28, 0x20, 0x12, 0x04, 0xfd, 0xfc, 0xfe, 0x04, 0x0b, 0x0f, 0x0f, 0x0b, + 0x05, 0x01, 0x01, 0x01, 0x00, 0xff, 0xfa, 0xf6, 0xf4, 0xf3, 0xef, 0xeb, + 0xe8, 0xe8, 0xeb, 0xf3, 0xff, 0x0f, 0x21, 0x2f, 0x33, 0x30, 0x29, 0x1e, + 0x19, 0x17, 0x19, 0x1b, 0x1c, 0x18, 0x10, 0x03, 0xf5, 0xe9, 0xe3, 0xe1, + 0xe0, 0xde, 0xdd, 0xde, 0xe0, 0xe1, 0xe6, 0xea, 0xed, 0xf0, 0xf5, 0xfb, + 0x07, 0x15, 0x21, 0x28, 0x26, 0x19, 0x0a, 0xff, 0xfc, 0xfe, 0x04, 0x0b, + 0x0f, 0x10, 0x0d, 0x07, 0x03, 0x00, 0x00, 0x01, 0xff, 0xfb, 0xf7, 0xf4, + 0xf2, 0xf1, 0xed, 0xeb, 0xe9, 0xea, 0xef, 0xfb, 0x09, 0x1a, 0x2b, 0x34, + 0x33, 0x2b, 0x21, 0x19, 0x16, 0x17, 0x1b, 0x1c, 0x1a, 0x11, 0x05, 0xf6, + 0xea, 0xe4, 0xe0, 0xdf, 0xde, 0xdd, 0xdd, 0xdf, 0xe2, 0xe5, 0xe8, 0xeb, + 0xed, 0xf1, 0xf8, 0x02, 0x10, 0x1d, 0x27, 0x28, 0x20, 0x11, 0x04, 0xfd, + 0xfd, 0x02, 0x0a, 0x0f, 0x11, 0x0e, 0x09, 0x04, 0xff, 0xfe, 0x00, 0x00, + 0xfd, 0xf9, 0xf5, 0xf4, 0xf3, 0xf0, 0xed, 0xea, 0xea, 0xee, 0xf7, 0x04, + 0x14, 0x26, 0x33, 0x35, 0x30, 0x25, 0x1a, 0x16, 0x16, 0x18, 0x1a, 0x19, + 0x12, 0x08, 0xfb, 0xee, 0xe5, 0xe0, 0xe0, 0xdf, 0xdd, 0xdd, 0xde, 0xe0, + 0xe3, 0xe7, 0xe9, 0xec, 0xee, 0xf4, 0xfd, 0x0b, 0x19, 0x26, 0x2b, 0x25, + 0x19, 0x09, 0x01, 0xfe, 0x02, 0x08, 0x0e, 0x11, 0x0f, 0x0b, 0x06, 0x00, + 0xff, 0xff, 0x00, 0xfe, 0xfc, 0xf8, 0xf5, 0xf3, 0xf2, 0xef, 0xec, 0xe9, + 0xec, 0xf3, 0xff, 0x0f, 0x21, 0x2e, 0x35, 0x32, 0x28, 0x1d, 0x17, 0x15, + 0x16, 0x19, 0x18, 0x15, 0x0c, 0xff, 0xf1, 0xe7, 0xe0, 0xdf, 0xdf, 0xdd, + 0xdd, 0xdd, 0xde, 0xe2, 0xe6, 0xe8, 0xe9, 0xec, 0xf1, 0xfa, 0x05, 0x15, + 0x21, 0x2a, 0x29, 0x20, 0x10, 0x05, 0x00, 0x02, 0x08, 0x0f, 0x11, 0x10, + 0x0c, 0x07, 0x01, 0xff, 0xfe, 0xff, 0xfe, 0xfc, 0xf9, 0xf5, 0xf5, 0xf3, + 0xf1, 0xed, 0xea, 0xea, 0xef, 0xfb, 0x09, 0x1b, 0x2b, 0x33, 0x33, 0x2c, + 0x21, 0x18, 0x15, 0x16, 0x18, 0x19, 0x14, 0x0d, 0x01, 0xf4, 0xe8, 0xe1, + 0xde, 0xdd, 0xde, 0xdd, 0xdd, 0xdf, 0xe2, 0xe4, 0xe7, 0xe9, 0xea, 0xee, + 0xf6, 0x01, 0x10, 0x1e, 0x28, 0x2a, 0x24, 0x16, 0x09, 0x02, 0x01, 0x05, + 0x0d, 0x11, 0x11, 0x0e, 0x08, 0x02, 0xfe, 0xfe, 0xfe, 0x00, 0xff, 0xfc, + 0xf8, 0xf5, 0xf5, 0xf3, 0xf0, 0xeb, 0xea, 0xed, 0xf7, 0x04, 0x16, 0x26, + 0x32, 0x35, 0x2f, 0x25, 0x1b, 0x15, 0x15, 0x17, 0x19, 0x16, 0x0e, 0x04, + 0xf7, 0xeb, 0xe2, 0xde, 0xdc, 0xdd, 0xdd, 0xdd, 0xdd, 0xdf, 0xe4, 0xe6, + 0xe7, 0xe9, 0xeb, 0xf0, 0xfb, 0x0a, 0x18, 0x25, 0x2b, 0x27, 0x1c, 0x10, + 0x06, 0x02, 0x05, 0x0d, 0x12, 0x12, 0x0f, 0x09, 0x04, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xfd, 0xfa, 0xf5, 0xf5, 0xf4, 0xf2, 0xee, 0xec, 0xec, 0xf1, + 0x00, 0x10, 0x21, 0x2f, 0x35, 0x31, 0x28, 0x1e, 0x17, 0x13, 0x16, 0x18, + 0x17, 0x0f, 0x06, 0xfa, 0xee, 0xe4, 0xdf, 0xdd, 0xdd, 0xde, 0xdd, 0xdd, + 0xdf, 0xe1, 0xe4, 0xe7, 0xe7, 0xe9, 0xec, 0xf7, 0x04, 0x14, 0x22, 0x29, + 0x2b, 0x22, 0x16, 0x09, 0x05, 0x05, 0x0b, 0x11, 0x14, 0x11, 0x0c, 0x05, + 0x01, 0xfe, 0xfe, 0xfe, 0x00, 0xff, 0xfc, 0xf8, 0xf6, 0xf4, 0xf4, 0xf1, + 0xed, 0xec, 0xf1, 0xfd, 0x0a, 0x1c, 0x2c, 0x33, 0x34, 0x2b, 0x20, 0x17, + 0x14, 0x15, 0x17, 0x18, 0x12, 0x08, 0xfb, 0xef, 0xe6, 0xdf, 0xdd, 0xdd, + 0xdc, 0xdd, 0xdd, 0xde, 0xe1, 0xe2, 0xe5, 0xe5, 0xe6, 0xe8, 0xf1, 0xff, + 0x0d, 0x1d, 0x28, 0x2a, 0x25, 0x1b, 0x10, 0x09, 0x07, 0x0b, 0x11, 0x15, + 0x12, 0x0d, 0x07, 0x01, 0xfd, 0xfc, 0xfe, 0x00, 0x00, 0xfe, 0xfa, 0xf6, + 0xf6, 0xf4, 0xf3, 0xef, 0xec, 0xee, 0xf8, 0x07, 0x16, 0x27, 0x32, 0x34, + 0x2e, 0x25, 0x19, 0x14, 0x13, 0x15, 0x18, 0x13, 0x0a, 0xfe, 0xf2, 0xe8, + 0xe1, 0xdd, 0xdc, 0xdd, 0xdc, 0xdd, 0xdf, 0xe0, 0xe1, 0xe3, 0xe5, 0xe4, + 0xe6, 0xec, 0xf9, 0x08, 0x17, 0x25, 0x2a, 0x28, 0x20, 0x15, 0x0c, 0x09, + 0x0b, 0x11, 0x16, 0x16, 0x10, 0x09, 0x02, 0xfe, 0xfc, 0xfd, 0xfe, 0xff, + 0xff, 0xfc, 0xf9, 0xf7, 0xf5, 0xf5, 0xf1, 0xee, 0xee, 0xf4, 0x00, 0x11, + 0x23, 0x30, 0x34, 0x30, 0x28, 0x1d, 0x14, 0x11, 0x14, 0x16, 0x16, 0x0d, + 0x02, 0xf5, 0xea, 0xe3, 0xdd, 0xdc, 0xdb, 0xdd, 0xdd, 0xdf, 0xdf, 0xe0, + 0xe1, 0xe4, 0xe3, 0xe3, 0xe8, 0xf3, 0x02, 0x13, 0x22, 0x2a, 0x2a, 0x25, + 0x1a, 0x0f, 0x0a, 0x0c, 0x10, 0x16, 0x17, 0x13, 0x0c, 0x05, 0xfe, 0xfd, + 0xfc, 0xfe, 0x00, 0x01, 0xfe, 0xfb, 0xf7, 0xf7, 0xf5, 0xf2, 0xef, 0xee, + 0xf2, 0xfd, 0x0c, 0x1e, 0x2d, 0x33, 0x32, 0x2a, 0x1f, 0x17, 0x12, 0x13, + 0x15, 0x15, 0x10, 0x05, 0xf8, 0xec, 0xe3, 0xdd, 0xdc, 0xdb, 0xda, 0xdd, + 0xdc, 0xde, 0xdf, 0xe1, 0xe1, 0xe2, 0xe3, 0xe6, 0xed, 0xfd, 0x0e, 0x1d, + 0x29, 0x2c, 0x27, 0x1d, 0x12, 0x0d, 0x0c, 0x10, 0x16, 0x18, 0x16, 0x0f, + 0x08, 0x01, 0xfd, 0xfc, 0xff, 0xff, 0xff, 0xfe, 0xfd, 0xfa, 0xf8, 0xf6, + 0xf4, 0xf1, 0xee, 0xf0, 0xf9, 0x08, 0x18, 0x2a, 0x34, 0x34, 0x2c, 0x22, + 0x18, 0x14, 0x11, 0x14, 0x14, 0x11, 0x08, 0xfb, 0xef, 0xe5, 0xdf, 0xdc, + 0xda, 0xda, 0xdc, 0xdc, 0xde, 0xde, 0xe0, 0xdf, 0xe0, 0xe0, 0xe2, 0xe8, + 0xf4, 0x06, 0x17, 0x26, 0x2c, 0x2a, 0x23, 0x18, 0x11, 0x0d, 0x0f, 0x16, + 0x1a, 0x18, 0x12, 0x0a, 0x02, 0xfe, 0xfd, 0xfc, 0xfe, 0xff, 0xff, 0xfe, + 0xfb, 0xf8, 0xf9, 0xf6, 0xf2, 0xf2, 0xef, 0xf4, 0x01, 0x13, 0x25, 0x31, + 0x34, 0x2f, 0x25, 0x1b, 0x12, 0x0f, 0x11, 0x14, 0x13, 0x0b, 0xff, 0xf3, + 0xe7, 0xe0, 0xdd, 0xdc, 0xda, 0xdb, 0xdd, 0xdd, 0xde, 0xde, 0xdf, 0xde, + 0xdf, 0xe0, 0xe4, 0xee, 0xfe, 0x11, 0x22, 0x2b, 0x2c, 0x26, 0x1e, 0x14, + 0x11, 0x10, 0x15, 0x1b, 0x1c, 0x17, 0x0e, 0x05, 0xff, 0xfd, 0xfd, 0xfc, + 0xff, 0xff, 0xfe, 0xfc, 0xf9, 0xf9, 0xf7, 0xf6, 0xf2, 0xf0, 0xf3, 0xfd, + 0x0d, 0x1f, 0x2d, 0x35, 0x31, 0x28, 0x1e, 0x15, 0x0f, 0x10, 0x12, 0x12, + 0x0b, 0x03, 0xf6, 0xeb, 0xe3, 0xdd, 0xda, 0xdb, 0xdb, 0xdb, 0xdb, 0xdc, + 0xdc, 0xdd, 0xdf, 0xdf, 0xde, 0xe0, 0xe8, 0xf9, 0x0a, 0x1d, 0x2a, 0x2e, + 0x2a, 0x21, 0x19, 0x12, 0x12, 0x15, 0x1a, 0x1d, 0x19, 0x11, 0x08, 0x01, + 0xfe, 0xfd, 0xfd, 0xff, 0x00, 0xff, 0xfd, 0xfb, 0xf9, 0xf9, 0xf6, 0xf3, + 0xf1, 0xf2, 0xfb, 0x0a, 0x19, 0x2a, 0x33, 0x33, 0x2b, 0x20, 0x16, 0x0f, + 0x0e, 0x10, 0x11, 0x0d, 0x07, 0xfb, 0xed, 0xe5, 0xdf, 0xdc, 0xdb, 0xdd, + 0xdd, 0xdc, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdd, 0xdd, 0xe5, 0xf3, 0x03, + 0x15, 0x25, 0x2d, 0x2c, 0x25, 0x1c, 0x15, 0x12, 0x15, 0x19, 0x1c, 0x1c, + 0x15, 0x0c, 0x03, 0xff, 0xfe, 0xfd, 0x00, 0x01, 0x00, 0xff, 0xfc, 0xfa, + 0xfa, 0xf8, 0xf6, 0xf1, 0xf1, 0xf8, 0x04, 0x14, 0x26, 0x31, 0x35, 0x2e, + 0x23, 0x17, 0x0f, 0x0d, 0x10, 0x10, 0x0e, 0x08, 0xfe, 0xf2, 0xe8, 0xe1, + 0xdc, 0xdc, 0xdc, 0xdd, 0xdd, 0xdc, 0xdd, 0xdc, 0xdc, 0xdb, 0xda, 0xdb, + 0xe1, 0xed, 0xff, 0x0f, 0x20, 0x2b, 0x2d, 0x28, 0x1f, 0x17, 0x13, 0x15, + 0x1a, 0x1d, 0x1e, 0x18, 0x10, 0x07, 0xff, 0xfe, 0xfe, 0x00, 0x01, 0x01, + 0xff, 0xfd, 0xfa, 0xfa, 0xf9, 0xf6, 0xf3, 0xf2, 0xf6, 0xfe, 0x0e, 0x20, + 0x2e, 0x33, 0x30, 0x27, 0x1a, 0x11, 0x0c, 0x0d, 0x0f, 0x0f, 0x0a, 0x01, + 0xf3, 0xe9, 0xe2, 0xdd, 0xdc, 0xdc, 0xdd, 0xdc, 0xdc, 0xdc, 0xdb, 0xdb, + 0xdb, 0xd9, 0xda, 0xdd, 0xe6, 0xf8, 0x09, 0x1c, 0x29, 0x2d, 0x2b, 0x22, + 0x19, 0x14, 0x15, 0x18, 0x1e, 0x20, 0x1b, 0x13, 0x0b, 0x03, 0xfe, 0xfe, + 0xfe, 0x01, 0x01, 0x01, 0xfe, 0xfb, 0xfb, 0xfb, 0xf7, 0xf4, 0xf2, 0xf4, + 0xfe, 0x0b, 0x1b, 0x2b, 0x34, 0x32, 0x2a, 0x1e, 0x12, 0x0c, 0x0b, 0x0c, + 0x0f, 0x0b, 0x05, 0xf7, 0xed, 0xe4, 0xdf, 0xdc, 0xde, 0xde, 0xdd, 0xdd, + 0xdc, 0xdb, 0xdb, 0xdb, 0xda, 0xd9, 0xda, 0xe2, 0xf0, 0x02, 0x15, 0x25, + 0x2d, 0x2c, 0x25, 0x1b, 0x15, 0x14, 0x17, 0x1c, 0x21, 0x1e, 0x17, 0x0f, + 0x06, 0x01, 0xfe, 0x00, 0x01, 0x02, 0x02, 0xff, 0xfc, 0xfb, 0xfa, 0xf8, + 0xf4, 0xf3, 0xf3, 0xfa, 0x05, 0x16, 0x28, 0x32, 0x33, 0x2e, 0x23, 0x16, + 0x0d, 0x0a, 0x0b, 0x0d, 0x0b, 0x04, 0xfc, 0xf1, 0xe6, 0xdf, 0xde, 0xde, + 0xdd, 0xdc, 0xdc, 0xdb, 0xda, 0xd9, 0xda, 0xd9, 0xd9, 0xd9, 0xde, 0xe9, + 0xfc, 0x0f, 0x1f, 0x2b, 0x2d, 0x28, 0x1f, 0x18, 0x14, 0x17, 0x1c, 0x21, + 0x20, 0x1b, 0x12, 0x0a, 0x03, 0x01, 0x00, 0x02, 0x02, 0x02, 0x01, 0xfc, + 0xfc, 0xfc, 0xf9, 0xf6, 0xf4, 0xf3, 0xf7, 0x02, 0x12, 0x22, 0x2f, 0x34, + 0x30, 0x25, 0x19, 0x10, 0x09, 0x09, 0x0b, 0x0b, 0x07, 0xff, 0xf3, 0xe9, + 0xe1, 0xde, 0xde, 0xdd, 0xdd, 0xdd, 0xdc, 0xda, 0xda, 0xda, 0xd9, 0xd9, + 0xd9, 0xdb, 0xe4, 0xf6, 0x08, 0x1a, 0x27, 0x2d, 0x29, 0x21, 0x19, 0x15, + 0x15, 0x19, 0x21, 0x23, 0x1d, 0x15, 0x0e, 0x07, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x01, 0xff, 0xfc, 0xfb, 0xf9, 0xf8, 0xf5, 0xf4, 0xf6, 0xff, 0x0d, + 0x1e, 0x2c, 0x34, 0x33, 0x2a, 0x1c, 0x11, 0x09, 0x06, 0x0a, 0x0b, 0x08, + 0x01, 0xf6, 0xea, 0xe3, 0xe0, 0xde, 0xdd, 0xdd, 0xdd, 0xdb, 0xda, 0xd9, + 0xd9, 0xd8, 0xd8, 0xd8, 0xd8, 0xe0, 0xf0, 0x01, 0x14, 0x23, 0x2b, 0x29, + 0x22, 0x1c, 0x15, 0x14, 0x18, 0x1e, 0x22, 0x20, 0x1b, 0x11, 0x0a, 0x05, + 0x04, 0x03, 0x03, 0x04, 0x03, 0xff, 0xfd, 0xfb, 0xfa, 0xf8, 0xf7, 0xf5, + 0xf5, 0xfd, 0x09, 0x18, 0x29, 0x34, 0x33, 0x2b, 0x20, 0x13, 0x0a, 0x06, + 0x06, 0x09, 0x07, 0x03, 0xf9, 0xee, 0xe5, 0xe3, 0xdf, 0xde, 0xdf, 0xdf, + 0xdc, 0xda, 0xd9, 0xd8, 0xd8, 0xd7, 0xd7, 0xd8, 0xde, 0xea, 0xfd, 0x0e, + 0x1f, 0x29, 0x2a, 0x25, 0x1d, 0x17, 0x14, 0x16, 0x1d, 0x21, 0x23, 0x1e, + 0x16, 0x0e, 0x08, 0x05, 0x05, 0x05, 0x04, 0x03, 0x01, 0xfd, 0xfc, 0xfa, + 0xf8, 0xf7, 0xf5, 0xf5, 0xfb, 0x04, 0x14, 0x24, 0x32, 0x35, 0x2f, 0x23, + 0x17, 0x0a, 0x05, 0x05, 0x08, 0x08, 0x04, 0xfd, 0xf2, 0xe8, 0xe2, 0xe0, + 0xe0, 0xdf, 0xdf, 0xdb, 0xda, 0xd9, 0xd8, 0xd7, 0xd8, 0xd8, 0xd8, 0xdb, + 0xe5, 0xf6, 0x08, 0x1b, 0x27, 0x2a, 0x27, 0x1f, 0x17, 0x14, 0x15, 0x1a, + 0x1f, 0x22, 0x20, 0x19, 0x11, 0x0c, 0x08, 0x07, 0x07, 0x07, 0x05, 0x02, + 0xfe, 0xfd, 0xf9, 0xf8, 0xf8, 0xf5, 0xf5, 0xfa, 0x01, 0x0f, 0x20, 0x2e, + 0x34, 0x30, 0x27, 0x19, 0x0d, 0x05, 0x03, 0x05, 0x07, 0x05, 0xff, 0xf3, + 0xe9, 0xe4, 0xe2, 0xe0, 0xe1, 0xe0, 0xdd, 0xdb, 0xd9, 0xd7, 0xd5, 0xd7, + 0xd7, 0xd7, 0xda, 0xe2, 0xf1, 0x02, 0x14, 0x23, 0x29, 0x26, 0x20, 0x18, + 0x13, 0x13, 0x18, 0x1d, 0x22, 0x22, 0x1d, 0x14, 0x0f, 0x0b, 0x08, 0x08, + 0x09, 0x07, 0x04, 0x00, 0xfe, 0xfa, 0xf8, 0xf6, 0xf5, 0xf6, 0xf9, 0xff, + 0x0c, 0x1b, 0x2b, 0x34, 0x34, 0x2a, 0x1d, 0x0f, 0x06, 0x02, 0x03, 0x06, + 0x05, 0x02, 0xf8, 0xee, 0xe6, 0xe1, 0xe0, 0xe1, 0xe0, 0xde, 0xdb, 0xda, + 0xd6, 0xd5, 0xd5, 0xd5, 0xd7, 0xd8, 0xde, 0xeb, 0xfe, 0x10, 0x20, 0x28, + 0x28, 0x21, 0x1a, 0x14, 0x12, 0x14, 0x1b, 0x21, 0x24, 0x20, 0x1a, 0x13, + 0x0e, 0x0b, 0x0a, 0x0a, 0x09, 0x06, 0x03, 0xff, 0xfa, 0xf8, 0xf7, 0xf6, + 0xf6, 0xf7, 0xfc, 0x06, 0x16, 0x27, 0x33, 0x34, 0x2d, 0x21, 0x12, 0x06, + 0x00, 0x00, 0x03, 0x06, 0x01, 0xfa, 0xf1, 0xe8, 0xe4, 0xe2, 0xe2, 0xe1, + 0xde, 0xdc, 0xd9, 0xd7, 0xd5, 0xd7, 0xd4, 0xd4, 0xd7, 0xdd, 0xe7, 0xf7, + 0x0a, 0x1a, 0x26, 0x27, 0x22, 0x1b, 0x14, 0x11, 0x12, 0x17, 0x1f, 0x23, + 0x22, 0x1d, 0x17, 0x11, 0x0e, 0x0d, 0x0c, 0x0b, 0x08, 0x03, 0xff, 0xfc, + 0xf9, 0xf6, 0xf5, 0xf5, 0xf6, 0xfa, 0x02, 0x12, 0x23, 0x31, 0x36, 0x32, + 0x24, 0x16, 0x08, 0x00, 0x00, 0x02, 0x04, 0x03, 0xfe, 0xf5, 0xeb, 0xe4, + 0xe3, 0xe3, 0xe2, 0xe0, 0xde, 0xda, 0xd8, 0xd7, 0xd5, 0xd5, 0xd5, 0xd7, + 0xda, 0xe2, 0xf1, 0x04, 0x16, 0x23, 0x29, 0x24, 0x1d, 0x14, 0x0f, 0x0f, + 0x14, 0x1b, 0x21, 0x22, 0x1f, 0x19, 0x13, 0x0f, 0x0f, 0x0e, 0x0c, 0x0a, + 0x06, 0x02, 0xfd, 0xfa, 0xf6, 0xf5, 0xf6, 0xf6, 0xfa, 0x00, 0x0c, 0x1f, + 0x2d, 0x36, 0x34, 0x29, 0x19, 0x0c, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, + 0xf8, 0xef, 0xe6, 0xe3, 0xe3, 0xe2, 0xe0, 0xdf, 0xdc, 0xd7, 0xd7, 0xd5, + 0xd4, 0xd4, 0xd7, 0xd8, 0xdf, 0xec, 0x00, 0x11, 0x21, 0x2a, 0x26, 0x1e, + 0x15, 0x0e, 0x0b, 0x0f, 0x18, 0x20, 0x23, 0x22, 0x1c, 0x16, 0x12, 0x10, + 0x10, 0x0f, 0x0c, 0x08, 0x03, 0x00, 0xfd, 0xf8, 0xf6, 0xf5, 0xf6, 0xf7, + 0xfe, 0x08, 0x1a, 0x2a, 0x35, 0x36, 0x2d, 0x1e, 0x0f, 0x03, 0xff, 0x00, + 0x00, 0x02, 0x00, 0xfb, 0xf1, 0xe9, 0xe5, 0xe4, 0xe3, 0xe2, 0xe0, 0xdd, + 0xd9, 0xd7, 0xd5, 0xd4, 0xd4, 0xd6, 0xd7, 0xdc, 0xe8, 0xfa, 0x0b, 0x1c, + 0x27, 0x27, 0x20, 0x16, 0x0d, 0x09, 0x0b, 0x14, 0x1c, 0x21, 0x22, 0x1e, + 0x18, 0x15, 0x13, 0x12, 0x10, 0x0f, 0x0b, 0x05, 0x00, 0xfd, 0xfa, 0xf6, + 0xf5, 0xf5, 0xf6, 0xfb, 0x04, 0x14, 0x25, 0x33, 0x37, 0x30, 0x24, 0x15, + 0x06, 0xff, 0xfd, 0x00, 0x01, 0x00, 0xfc, 0xf4, 0xeb, 0xe7, 0xe4, 0xe3, + 0xe3, 0xe2, 0xde, 0xda, 0xd6, 0xd5, 0xd3, 0xd3, 0xd3, 0xd6, 0xda, 0xe3, + 0xf3, 0x04, 0x17, 0x24, 0x28, 0x22, 0x1a, 0x10, 0x09, 0x0a, 0x10, 0x19, + 0x21, 0x23, 0x21, 0x1c, 0x17, 0x15, 0x15, 0x13, 0x12, 0x0f, 0x07, 0x01, + 0xfd, 0xfa, 0xf6, 0xf5, 0xf4, 0xf5, 0xf9, 0x01, 0x10, 0x22, 0x31, 0x37, + 0x34, 0x28, 0x18, 0x09, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfe, 0xf7, 0xef, + 0xe9, 0xe7, 0xe5, 0xe4, 0xe4, 0xe1, 0xdc, 0xd8, 0xd5, 0xd2, 0xd2, 0xd3, + 0xd4, 0xd7, 0xdf, 0xed, 0x00, 0x12, 0x21, 0x28, 0x25, 0x1c, 0x10, 0x08, + 0x06, 0x0b, 0x14, 0x1c, 0x22, 0x21, 0x1d, 0x18, 0x15, 0x14, 0x15, 0x14, + 0x10, 0x0a, 0x03, 0x00, 0xfb, 0xf8, 0xf6, 0xf5, 0xf4, 0xf7, 0x00, 0x0b, + 0x1b, 0x2c, 0x36, 0x35, 0x2b, 0x1b, 0x0b, 0x00, 0xfc, 0xfd, 0x00, 0x00, + 0x00, 0xfb, 0xf4, 0xef, 0xea, 0xe8, 0xe7, 0xe6, 0xe3, 0xe0, 0xdc, 0xd7, + 0xd4, 0xd3, 0xd3, 0xd3, 0xd7, 0xde, 0xe9, 0xfa, 0x0b, 0x1c, 0x26, 0x26, + 0x1e, 0x12, 0x09, 0x04, 0x07, 0x0f, 0x18, 0x20, 0x21, 0x1e, 0x1b, 0x17, + 0x15, 0x15, 0x15, 0x12, 0x0d, 0x06, 0x00, 0xfd, 0xfa, 0xf7, 0xf5, 0xf4, + 0xf5, 0xfc, 0x05, 0x15, 0x27, 0x33, 0x36, 0x2f, 0x21, 0x0f, 0x00, 0xfc, + 0xfb, 0xfe, 0x00, 0x00, 0xfe, 0xf8, 0xf0, 0xeb, 0xe9, 0xe8, 0xe7, 0xe4, + 0xe2, 0xde, 0xd9, 0xd7, 0xd4, 0xd4, 0xd5, 0xd7, 0xdc, 0xe5, 0xf5, 0x05, + 0x17, 0x23, 0x27, 0x22, 0x15, 0x0a, 0x03, 0x04, 0x0b, 0x14, 0x1d, 0x21, + 0x20, 0x1c, 0x19, 0x17, 0x17, 0x16, 0x14, 0x0f, 0x0a, 0x02, 0xfd, 0xfa, + 0xf7, 0xf5, 0xf4, 0xf5, 0xfa, 0x01, 0x10, 0x21, 0x30, 0x35, 0x32, 0x24, + 0x15, 0x04, 0xfd, 0xfa, 0xfb, 0x00, 0x00, 0xff, 0xf9, 0xf3, 0xef, 0xeb, + 0xea, 0xe9, 0xe6, 0xe3, 0xe0, 0xda, 0xd8, 0xd5, 0xd5, 0xd4, 0xd7, 0xdb, + 0xe2, 0xef, 0x00, 0x12, 0x20, 0x26, 0x22, 0x19, 0x0c, 0x04, 0x02, 0x06, + 0x10, 0x19, 0x1f, 0x1f, 0x1d, 0x1a, 0x17, 0x17, 0x17, 0x15, 0x11, 0x0b, + 0x03, 0xff, 0xfa, 0xf7, 0xf5, 0xf5, 0xf5, 0xf9, 0x00, 0x0c, 0x1c, 0x2d, + 0x34, 0x34, 0x2a, 0x19, 0x09, 0xfe, 0xf8, 0xf9, 0xfd, 0x00, 0x01, 0xfb, + 0xf6, 0xf0, 0xed, 0xec, 0xea, 0xe8, 0xe5, 0xe1, 0xdd, 0xd9, 0xd8, 0xd6, + 0xd6, 0xd5, 0xd8, 0xde, 0xea, 0xfc, 0x0c, 0x1b, 0x24, 0x24, 0x1b, 0x10, + 0x05, 0x00, 0x03, 0x0b, 0x15, 0x1d, 0x20, 0x1e, 0x1b, 0x19, 0x17, 0x17, + 0x15, 0x14, 0x0e, 0x07, 0xff, 0xfb, 0xf9, 0xf6, 0xf5, 0xf5, 0xf6, 0xfc, + 0x07, 0x17, 0x27, 0x32, 0x35, 0x2d, 0x1e, 0x0d, 0x01, 0xf8, 0xf6, 0xfb, + 0x00, 0x01, 0xfe, 0xf8, 0xf2, 0xf0, 0xee, 0xed, 0xeb, 0xe9, 0xe4, 0xdf, + 0xdb, 0xd9, 0xd7, 0xd5, 0xd7, 0xd8, 0xdd, 0xe6, 0xf6, 0x06, 0x16, 0x23, + 0x25, 0x1e, 0x12, 0x06, 0x00, 0x00, 0x07, 0x11, 0x19, 0x1f, 0x1f, 0x1c, + 0x1a, 0x19, 0x17, 0x16, 0x14, 0x10, 0x09, 0x02, 0xff, 0xfa, 0xf5, 0xf5, + 0xf5, 0xf6, 0xfa, 0x01, 0x11, 0x20, 0x2e, 0x34, 0x30, 0x23, 0x13, 0x03, + 0xf9, 0xf6, 0xf8, 0xfd, 0x01, 0xff, 0xfc, 0xf4, 0xf1, 0xf0, 0xee, 0xed, + 0xea, 0xe6, 0xe2, 0xde, 0xda, 0xd8, 0xd7, 0xd8, 0xd9, 0xdd, 0xe3, 0xf0, + 0x00, 0x11, 0x1f, 0x24, 0x20, 0x14, 0x09, 0x00, 0x00, 0x02, 0x0c, 0x16, + 0x1b, 0x1e, 0x1c, 0x1a, 0x1a, 0x19, 0x17, 0x14, 0x10, 0x0b, 0x04, 0xfe, + 0xfb, 0xf8, 0xf4, 0xf5, 0xf5, 0xf9, 0xff, 0x0d, 0x1b, 0x2a, 0x34, 0x32, + 0x27, 0x17, 0x07, 0xfc, 0xf5, 0xf7, 0xfb, 0x00, 0x02, 0xfe, 0xf8, 0xf3, + 0xf1, 0xf0, 0xee, 0xec, 0xe9, 0xe4, 0xdf, 0xdb, 0xd8, 0xd8, 0xd9, 0xda, + 0xdc, 0xe1, 0xec, 0xfd, 0x0b, 0x1b, 0x23, 0x22, 0x18, 0x0c, 0x00, 0xfe, + 0xff, 0x08, 0x11, 0x1a, 0x1e, 0x1c, 0x1b, 0x19, 0x19, 0x18, 0x17, 0x13, + 0x0c, 0x05, 0xff, 0xfc, 0xf8, 0xf5, 0xf4, 0xf5, 0xf9, 0xff, 0x0a, 0x17, + 0x27, 0x31, 0x33, 0x2b, 0x1c, 0x0b, 0xfe, 0xf6, 0xf5, 0xf8, 0xfe, 0x01, + 0xff, 0xf9, 0xf5, 0xf1, 0xf1, 0xf0, 0xee, 0xeb, 0xe6, 0xe1, 0xdf, 0xdb, + 0xda, 0xda, 0xdb, 0xdc, 0xe0, 0xea, 0xf8, 0x08, 0x16, 0x21, 0x22, 0x18, + 0x0e, 0x02, 0xfe, 0xff, 0x04, 0x0c, 0x16, 0x1d, 0x1e, 0x1c, 0x1a, 0x18, + 0x18, 0x16, 0x14, 0x0f, 0x09, 0x01, 0xfc, 0xf9, 0xf6, 0xf5, 0xf5, 0xf8, + 0xfe, 0x05, 0x11, 0x21, 0x2e, 0x34, 0x2e, 0x21, 0x10, 0x02, 0xf7, 0xf5, + 0xf7, 0xfc, 0x00, 0xff, 0xfa, 0xf7, 0xf4, 0xf1, 0xf1, 0xf0, 0xee, 0xe8, + 0xe3, 0xe0, 0xdc, 0xdc, 0xdb, 0xdb, 0xde, 0xe1, 0xe9, 0xf5, 0x03, 0x13, + 0x1e, 0x21, 0x1c, 0x11, 0x04, 0xfe, 0xfc, 0xff, 0x08, 0x12, 0x1a, 0x1b, + 0x1b, 0x1a, 0x19, 0x18, 0x18, 0x15, 0x10, 0x0a, 0x03, 0xfe, 0xf9, 0xf7, + 0xf6, 0xf6, 0xf6, 0xfc, 0x02, 0x0e, 0x1d, 0x2b, 0x31, 0x31, 0x27, 0x15, + 0x04, 0xf9, 0xf5, 0xf6, 0xfa, 0xfe, 0x00, 0xfe, 0xf9, 0xf4, 0xf1, 0xf1, + 0xf1, 0xef, 0xea, 0xe6, 0xe2, 0xde, 0xdc, 0xdd, 0xdd, 0xde, 0xe1, 0xe7, + 0xf1, 0x00, 0x0e, 0x1a, 0x21, 0x1d, 0x13, 0x05, 0xfd, 0xfa, 0xfc, 0x03, + 0x0f, 0x18, 0x1b, 0x1d, 0x1b, 0x19, 0x18, 0x18, 0x16, 0x12, 0x0d, 0x06, + 0xfe, 0xfa, 0xf8, 0xf6, 0xf6, 0xf6, 0xf9, 0xff, 0x09, 0x18, 0x26, 0x30, + 0x33, 0x2a, 0x1a, 0x08, 0xfc, 0xf3, 0xf3, 0xf8, 0xfe, 0x00, 0xff, 0xfb, + 0xf6, 0xf3, 0xf2, 0xf1, 0xef, 0xec, 0xe9, 0xe3, 0xe0, 0xdf, 0xde, 0xdf, + 0xe0, 0xe2, 0xe6, 0xee, 0xfc, 0x09, 0x17, 0x1e, 0x1f, 0x16, 0x09, 0x00, + 0xf9, 0xf9, 0xff, 0x0c, 0x15, 0x1a, 0x1d, 0x1d, 0x1a, 0x18, 0x18, 0x16, + 0x12, 0x0e, 0x07, 0x00, 0xfb, 0xf8, 0xf6, 0xf6, 0xf8, 0xf9, 0xfe, 0x06, + 0x15, 0x23, 0x2d, 0x32, 0x2d, 0x1f, 0x0d, 0xff, 0xf6, 0xf2, 0xf6, 0xfd, + 0x00, 0x00, 0xfd, 0xf9, 0xf4, 0xf3, 0xf2, 0xef, 0xec, 0xea, 0xe5, 0xe1, + 0xdf, 0xde, 0xdf, 0xe1, 0xe3, 0xe5, 0xec, 0xf8, 0x06, 0x13, 0x1d, 0x20, + 0x19, 0x0d, 0x01, 0xfa, 0xf7, 0xfd, 0x05, 0x11, 0x19, 0x1c, 0x1c, 0x1a, + 0x19, 0x19, 0x17, 0x13, 0x0f, 0x0a, 0x02, 0xfd, 0xf8, 0xf7, 0xf6, 0xf7, + 0xf9, 0xfc, 0x03, 0x10, 0x1d, 0x2a, 0x32, 0x2e, 0x23, 0x12, 0x03, 0xf7, + 0xf2, 0xf3, 0xfa, 0xff, 0x01, 0xfe, 0xfa, 0xf5, 0xf3, 0xf2, 0xf1, 0xed, + 0xec, 0xe8, 0xe4, 0xe1, 0xdf, 0xdf, 0xe1, 0xe5, 0xe6, 0xeb, 0xf4, 0x00, + 0x0e, 0x1b, 0x1f, 0x1c, 0x10, 0x02, 0xfa, 0xf6, 0xf8, 0x01, 0x0d, 0x17, + 0x1c, 0x1c, 0x1a, 0x19, 0x18, 0x18, 0x13, 0x11, 0x0b, 0x04, 0xfd, 0xfa, + 0xf7, 0xf5, 0xf6, 0xf9, 0xfb, 0xff, 0x0b, 0x19, 0x26, 0x30, 0x31, 0x27, + 0x17, 0x08, 0xfb, 0xf3, 0xf4, 0xf8, 0xfe, 0x01, 0x00, 0xfb, 0xf8, 0xf4, + 0xf2, 0xf1, 0xef, 0xee, 0xea, 0xe7, 0xe3, 0xe2, 0xe1, 0xe2, 0xe4, 0xe6, + 0xea, 0xf2, 0xfe, 0x09, 0x16, 0x1e, 0x1c, 0x13, 0x06, 0xfb, 0xf5, 0xf5, + 0xfd, 0x08, 0x13, 0x1c, 0x1c, 0x1c, 0x1a, 0x19, 0x17, 0x15, 0x11, 0x0c, + 0x05, 0xfe, 0xfa, 0xf8, 0xf6, 0xf6, 0xf9, 0xf9, 0xfe, 0x07, 0x14, 0x22, + 0x2f, 0x32, 0x2b, 0x1e, 0x0d, 0xfe, 0xf5, 0xf2, 0xf6, 0xfc, 0x01, 0x02, + 0xff, 0xf9, 0xf5, 0xf2, 0xf1, 0xf0, 0xee, 0xeb, 0xe8, 0xe5, 0xe3, 0xe3, + 0xe4, 0xe5, 0xe8, 0xea, 0xf0, 0xfb, 0x05, 0x12, 0x1c, 0x1c, 0x15, 0x08, + 0xfd, 0xf6, 0xf4, 0xf9, 0x02, 0x10, 0x1a, 0x1d, 0x1d, 0x1b, 0x19, 0x18, + 0x16, 0x13, 0x0e, 0x06, 0x00, 0xfc, 0xf7, 0xf5, 0xf6, 0xf7, 0xf9, 0xfd, + 0x03, 0x0f, 0x1e, 0x2b, 0x31, 0x2e, 0x22, 0x13, 0x03, 0xf7, 0xf2, 0xf4, + 0xf9, 0xff, 0x01, 0xff, 0xfb, 0xf8, 0xf4, 0xf2, 0xf1, 0xef, 0xec, 0xe9, + 0xe6, 0xe5, 0xe3, 0xe5, 0xe6, 0xe7, 0xeb, 0xf0, 0xf7, 0x00, 0x0d, 0x18, + 0x1c, 0x18, 0x0e, 0x00, 0xf7, 0xf2, 0xf4, 0xfd, 0x0b, 0x18, 0x1c, 0x1d, + 0x1c, 0x1b, 0x18, 0x17, 0x13, 0x10, 0x09, 0x02, 0xfd, 0xf9, 0xf5, 0xf5, + 0xf7, 0xf9, 0xfb, 0x00, 0x09, 0x18, 0x28, 0x31, 0x32, 0x28, 0x18, 0x06, + 0xf9, 0xf2, 0xf3, 0xf7, 0xfe, 0x01, 0x00, 0xfd, 0xfa, 0xf5, 0xf3, 0xf1, + 0xef, 0xee, 0xeb, 0xe9, 0xe6, 0xe5, 0xe5, 0xe6, 0xe8, 0xe9, 0xed, 0xf5, + 0x00, 0x0a, 0x15, 0x1b, 0x19, 0x0f, 0x03, 0xf7, 0xf1, 0xf3, 0xfa, 0x06, + 0x12, 0x1b, 0x1e, 0x1d, 0x1b, 0x18, 0x16, 0x16, 0x11, 0x0a, 0x03, 0xfd, + 0xf9, 0xf5, 0xf5, 0xf6, 0xf8, 0xfa, 0xfe, 0x06, 0x13, 0x22, 0x2e, 0x32, + 0x2a, 0x1e, 0x0a, 0xfe, 0xf3, 0xf2, 0xf6, 0xfd, 0x01, 0x01, 0xff, 0xfc, + 0xf6, 0xf4, 0xf2, 0xef, 0xee, 0xec, 0xe9, 0xe7, 0xe6, 0xe6, 0xe7, 0xe9, + 0xea, 0xed, 0xf2, 0xfc, 0x05, 0x12, 0x1a, 0x1a, 0x13, 0x07, 0xfa, 0xf2, + 0xf0, 0xf7, 0x00, 0x0f, 0x19, 0x1d, 0x1e, 0x1c, 0x1a, 0x17, 0x14, 0x11, + 0x0b, 0x06, 0xff, 0xf9, 0xf6, 0xf5, 0xf6, 0xf6, 0xfa, 0xfd, 0x03, 0x0f, + 0x1d, 0x29, 0x30, 0x2e, 0x23, 0x12, 0x01, 0xf5, 0xf1, 0xf4, 0xfb, 0x01, + 0x02, 0x01, 0xfc, 0xf8, 0xf5, 0xf2, 0xf0, 0xef, 0xec, 0xea, 0xe7, 0xe6, + 0xe7, 0xe8, 0xe8, 0xea, 0xec, 0xf1, 0xf7, 0x03, 0x0e, 0x18, 0x1c, 0x16, + 0x0a, 0xfe, 0xf4, 0xf0, 0xf3, 0xfc, 0x09, 0x16, 0x1b, 0x20, 0x1c, 0x1b, + 0x17, 0x15, 0x12, 0x0e, 0x07, 0x01, 0xfb, 0xf7, 0xf5, 0xf6, 0xf6, 0xf9, + 0xfc, 0x01, 0x0a, 0x18, 0x25, 0x2f, 0x31, 0x28, 0x17, 0x06, 0xf9, 0xf2, + 0xf3, 0xf8, 0xff, 0x02, 0x02, 0xfe, 0xfa, 0xf5, 0xf3, 0xf1, 0xf0, 0xee, + 0xec, 0xe8, 0xe7, 0xe7, 0xe8, 0xea, 0xec, 0xec, 0xef, 0xf5, 0x00, 0x0a, + 0x15, 0x1b, 0x18, 0x0d, 0x01, 0xf6, 0xf0, 0xf1, 0xf9, 0x06, 0x12, 0x1b, + 0x1e, 0x1e, 0x1b, 0x1a, 0x16, 0x11, 0x0d, 0x09, 0x02, 0xfd, 0xf9, 0xf5, + 0xf5, 0xf6, 0xf9, 0xfb, 0xff, 0x07, 0x13, 0x21, 0x2e, 0x31, 0x2b, 0x1e, + 0x0d, 0xfd, 0xf2, 0xf2, 0xf6, 0xfd, 0x02, 0x03, 0x00, 0xfb, 0xf6, 0xf3, + 0xf2, 0xf0, 0xee, 0xec, 0xea, 0xe8, 0xe7, 0xe8, 0xeb, 0xed, 0xed, 0xef, + 0xf4, 0xfd, 0x08, 0x12, 0x19, 0x1a, 0x11, 0x05, 0xfa, 0xf1, 0xef, 0xf6, + 0x00, 0x0e, 0x19, 0x1e, 0x1f, 0x1c, 0x1a, 0x17, 0x12, 0x0f, 0x09, 0x04, + 0xfd, 0xfa, 0xf6, 0xf5, 0xf6, 0xf9, 0xfb, 0xff, 0x04, 0x10, 0x1d, 0x29, + 0x30, 0x2e, 0x22, 0x12, 0x02, 0xf4, 0xf0, 0xf4, 0xfa, 0x00, 0x04, 0x02, + 0xfd, 0xf8, 0xf5, 0xf3, 0xf2, 0xf0, 0xed, 0xea, 0xe8, 0xe8, 0xe9, 0xea, + 0xec, 0xed, 0xee, 0xf2, 0xfb, 0x02, 0x0e, 0x18, 0x1b, 0x15, 0x0a, 0xfe, + 0xf3, 0xf0, 0xf3, 0xfb, 0x09, 0x15, 0x1c, 0x1e, 0x1c, 0x1a, 0x17, 0x14, + 0x0f, 0x0b, 0x05, 0xfe, 0xfa, 0xf6, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0x02, + 0x0c, 0x17, 0x25, 0x2e, 0x2f, 0x26, 0x18, 0x05, 0xf9, 0xf2, 0xf3, 0xf7, + 0xff, 0x02, 0x03, 0xfe, 0xf9, 0xf5, 0xf3, 0xf2, 0xf2, 0xef, 0xeb, 0xea, + 0xe9, 0xe9, 0xeb, 0xed, 0xee, 0xf0, 0xf2, 0xf7, 0x00, 0x0b, 0x15, 0x1a, + 0x17, 0x0d, 0x01, 0xf4, 0xf0, 0xf1, 0xfb, 0x05, 0x13, 0x1a, 0x1d, 0x1d, + 0x1b, 0x19, 0x15, 0x11, 0x0c, 0x06, 0x00, 0xfd, 0xf7, 0xf4, 0xf4, 0xf6, + 0xf9, 0xfb, 0xff, 0x07, 0x12, 0x21, 0x2c, 0x30, 0x29, 0x1d, 0x0b, 0xfc, + 0xf3, 0xf2, 0xf5, 0xfc, 0x02, 0x03, 0x00, 0xfc, 0xf7, 0xf3, 0xf2, 0xf2, + 0xf0, 0xed, 0xea, 0xe9, 0xe9, 0xea, 0xee, 0xef, 0xf0, 0xf2, 0xf6, 0xfd, + 0x06, 0x12, 0x19, 0x1a, 0x12, 0x06, 0xf9, 0xf2, 0xf0, 0xf6, 0x00, 0x0d, + 0x18, 0x1d, 0x1d, 0x1c, 0x19, 0x15, 0x11, 0x0e, 0x08, 0x02, 0xfd, 0xf8, + 0xf5, 0xf4, 0xf5, 0xf7, 0xfa, 0xff, 0x04, 0x0e, 0x1b, 0x28, 0x2f, 0x2d, + 0x23, 0x10, 0x02, 0xf5, 0xf1, 0xf5, 0xf9, 0x01, 0x04, 0x01, 0xfd, 0xf7, + 0xf3, 0xf2, 0xf2, 0xf0, 0xed, 0xeb, 0xea, 0xe9, 0xeb, 0xed, 0xf0, 0xf1, + 0xf2, 0xf4, 0xfb, 0x03, 0x0f, 0x18, 0x19, 0x15, 0x09, 0xfc, 0xf3, 0xef, + 0xf2, 0xfc, 0x09, 0x15, 0x1c, 0x1d, 0x1c, 0x19, 0x16, 0x13, 0x0f, 0x0a, + 0x03, 0xfd, 0xf9, 0xf5, 0xf4, 0xf4, 0xf6, 0xf9, 0xfd, 0x01, 0x0a, 0x17, + 0x24, 0x2e, 0x2e, 0x26, 0x17, 0x05, 0xf9, 0xf3, 0xf2, 0xf8, 0xff, 0x03, + 0x02, 0xfe, 0xf9, 0xf5, 0xf3, 0xf3, 0xf2, 0xef, 0xed, 0xeb, 0xea, 0xea, + 0xed, 0xf0, 0xf1, 0xf2, 0xf4, 0xf9, 0x00, 0x0a, 0x14, 0x1a, 0x18, 0x0e, + 0x01, 0xf5, 0xf0, 0xf1, 0xf9, 0x05, 0x12, 0x1a, 0x1d, 0x1c, 0x1a, 0x17, + 0x14, 0x10, 0x0c, 0x05, 0xff, 0xfb, 0xf7, 0xf5, 0xf5, 0xf5, 0xf6, 0xfb, + 0xff, 0x06, 0x12, 0x20, 0x2a, 0x2f, 0x2a, 0x1c, 0x0c, 0xff, 0xf5, 0xf3, + 0xf6, 0xfc, 0x02, 0x03, 0x00, 0xfb, 0xf6, 0xf2, 0xf2, 0xf2, 0xf1, 0xee, + 0xec, 0xeb, 0xea, 0xee, 0xef, 0xf2, 0xf4, 0xf4, 0xf6, 0xfe, 0x06, 0x12, + 0x19, 0x1a, 0x11, 0x05, 0xf8, 0xf0, 0xef, 0xf5, 0x01, 0x0e, 0x17, 0x1d, + 0x1e, 0x1a, 0x17, 0x15, 0x11, 0x0e, 0x07, 0x01, 0xfc, 0xf8, 0xf4, 0xf4, + 0xf4, 0xf6, 0xf8, 0xfd, 0x02, 0x0d, 0x1b, 0x27, 0x2f, 0x2d, 0x22, 0x12, + 0x04, 0xf7, 0xf3, 0xf4, 0xf9, 0xff, 0x03, 0x02, 0xfd, 0xf6, 0xf3, 0xf2, + 0xf1, 0xf1, 0xf0, 0xee, 0xed, 0xec, 0xed, 0xef, 0xf1, 0xf4, 0xf4, 0xf6, + 0xfc, 0x02, 0x0d, 0x16, 0x1a, 0x14, 0x08, 0xfc, 0xf3, 0xf0, 0xf2, 0xfc, + 0x0a, 0x15, 0x1b, 0x1e, 0x1b, 0x18, 0x15, 0x12, 0x0e, 0x09, 0x03, 0xfc, + 0xf7, 0xf4, 0xf4, 0xf4, 0xf6, 0xf6, 0xfb, 0xff, 0x09, 0x16, 0x23, 0x2d, + 0x2f, 0x27, 0x17, 0x08, 0xfb, 0xf5, 0xf4, 0xf8, 0xfe, 0x01, 0x02, 0xfd, + 0xf8, 0xf4, 0xf2, 0xf1, 0xf1, 0xf1, 0xf0, 0xed, 0xee, 0xee, 0xef, 0xf1, + 0xf3, 0xf4, 0xf5, 0xfa, 0x01, 0x0a, 0x13, 0x1a, 0x17, 0x0d, 0x02, 0xf5, + 0xf0, 0xf1, 0xf9, 0x05, 0x12, 0x19, 0x1d, 0x1b, 0x19, 0x15, 0x13, 0x10, + 0x0b, 0x05, 0xff, 0xf9, 0xf7, 0xf4, 0xf3, 0xf4, 0xf6, 0xf8, 0xfd, 0x04, + 0x0f, 0x1e, 0x2a, 0x2f, 0x2a, 0x1d, 0x0c, 0xff, 0xf5, 0xf4, 0xf8, 0xfb, + 0x01, 0x02, 0xff, 0xfa, 0xf4, 0xf2, 0xf1, 0xf1, 0xf1, 0xef, 0xed, 0xed, + 0xed, 0xef, 0xf2, 0xf4, 0xf4, 0xf4, 0xf8, 0xfe, 0x06, 0x11, 0x19, 0x1a, + 0x12, 0x07, 0xfa, 0xf2, 0xf0, 0xf7, 0x00, 0x0d, 0x18, 0x1c, 0x1d, 0x1a, + 0x18, 0x13, 0x11, 0x0e, 0x07, 0x01, 0xfc, 0xf7, 0xf4, 0xf4, 0xf4, 0xf5, + 0xf7, 0xfb, 0x00, 0x0b, 0x18, 0x26, 0x2e, 0x2c, 0x22, 0x12, 0x03, 0xf8, + 0xf5, 0xf6, 0xfa, 0x00, 0x01, 0x00, 0xfb, 0xf7, 0xf3, 0xf2, 0xf2, 0xf1, + 0xef, 0xee, 0xee, 0xed, 0xf0, 0xf1, 0xf3, 0xf5, 0xf5, 0xf7, 0xfa, 0x03, + 0x0d, 0x16, 0x1b, 0x15, 0x0c, 0xff, 0xf4, 0xf0, 0xf3, 0xfc, 0x09, 0x16, + 0x1c, 0x1d, 0x1b, 0x18, 0x15, 0x12, 0x0f, 0x09, 0x04, 0xfc, 0xf8, 0xf3, + 0xf3, 0xf2, 0xf3, 0xf5, 0xf7, 0xfd, 0x04, 0x12, 0x22, 0x2c, 0x2e, 0x28, + 0x1a, 0x09, 0xfd, 0xf6, 0xf5, 0xfa, 0xff, 0x02, 0x00, 0xfe, 0xf8, 0xf3, + 0xf2, 0xf0, 0xf1, 0xef, 0xee, 0xee, 0xed, 0xee, 0xf0, 0xf3, 0xf4, 0xf5, + 0xf6, 0xf9, 0x01, 0x09, 0x14, 0x19, 0x18, 0x0f, 0x04, 0xf8, 0xf1, 0xf2, + 0xf9, 0x04, 0x11, 0x19, 0x1c, 0x1b, 0x19, 0x15, 0x12, 0x0f, 0x0b, 0x05, + 0xfe, 0xfa, 0xf6, 0xf2, 0xf3, 0xf3, 0xf4, 0xf6, 0xfa, 0x00, 0x0d, 0x1b, + 0x28, 0x2f, 0x2b, 0x1e, 0x0f, 0x01, 0xf8, 0xf6, 0xf8, 0xfe, 0x02, 0x03, + 0xff, 0xfb, 0xf5, 0xf1, 0xf1, 0xf0, 0xf0, 0xee, 0xef, 0xee, 0xee, 0xf1, + 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xfe, 0x06, 0x11, 0x19, 0x1a, 0x13, 0x08, + 0xfb, 0xf2, 0xf0, 0xf7, 0x00, 0x0c, 0x17, 0x1b, 0x1d, 0x1a, 0x17, 0x14, + 0x11, 0x0d, 0x07, 0x01, 0xfc, 0xf7, 0xf3, 0xf3, 0xf2, 0xf2, 0xf4, 0xf7, + 0xfe, 0x07, 0x15, 0x24, 0x2d, 0x2d, 0x24, 0x14, 0x06, 0xfa, 0xf6, 0xf8, + 0xfd, 0x01, 0x02, 0x00, 0xfb, 0xf6, 0xf2, 0xf1, 0xf1, 0xf0, 0xef, 0xee, + 0xee, 0xef, 0xf1, 0xf2, 0xf4, 0xf5, 0xf5, 0xf7, 0xfb, 0x03, 0x0e, 0x17, + 0x1b, 0x16, 0x0c, 0xff, 0xf5, 0xf0, 0xf4, 0xfb, 0x09, 0x14, 0x19, 0x1c, + 0x1b, 0x18, 0x14, 0x12, 0x0e, 0x0a, 0x05, 0xfd, 0xf9, 0xf4, 0xf2, 0xf2, + 0xf1, 0xf2, 0xf5, 0xfa, 0x01, 0x0f, 0x1d, 0x29, 0x2e, 0x28, 0x1b, 0x0b, + 0xff, 0xf8, 0xf7, 0xfc, 0x00, 0x03, 0x02, 0xfd, 0xf7, 0xf3, 0xf2, 0xf0, + 0xf0, 0xf0, 0xee, 0xee, 0xee, 0xf0, 0xf3, 0xf4, 0xf5, 0xf6, 0xf6, 0xfa, + 0x02, 0x0a, 0x15, 0x1b, 0x19, 0x10, 0x05, 0xf8, 0xf2, 0xf2, 0xf8, 0x03, + 0x0f, 0x17, 0x1c, 0x1c, 0x19, 0x15, 0x13, 0x0f, 0x0b, 0x06, 0x00, 0xfb, + 0xf6, 0xf3, 0xf1, 0xf0, 0xf1, 0xf2, 0xf6, 0xff, 0x09, 0x18, 0x26, 0x2d, + 0x2b, 0x20, 0x10, 0x04, 0xf9, 0xf7, 0xfb, 0xff, 0x03, 0x03, 0x00, 0xfa, + 0xf4, 0xf3, 0xf1, 0xf0, 0xf0, 0xee, 0xee, 0xee, 0xef, 0xf0, 0xf3, 0xf4, + 0xf5, 0xf5, 0xf7, 0xfe, 0x06, 0x11, 0x19, 0x1b, 0x15, 0x09, 0xfc, 0xf3, + 0xf0, 0xf6, 0xff, 0x0b, 0x16, 0x1a, 0x1b, 0x19, 0x17, 0x14, 0x11, 0x0e, + 0x09, 0x02, 0xfc, 0xf7, 0xf4, 0xf1, 0xf0, 0xf0, 0xf1, 0xf3, 0xfb, 0x03, + 0x11, 0x20, 0x2a, 0x2c, 0x24, 0x17, 0x08, 0xfc, 0xf8, 0xfa, 0xff, 0x02, + 0x04, 0x02, 0xfc, 0xf7, 0xf4, 0xf1, 0xf1, 0xf0, 0xef, 0xee, 0xed, 0xef, + 0xf0, 0xf1, 0xf3, 0xf5, 0xf5, 0xf7, 0xfb, 0x03, 0x0e, 0x18, 0x1c, 0x18, + 0x0c, 0x01, 0xf6, 0xf0, 0xf3, 0xfb, 0x07, 0x13, 0x19, 0x1c, 0x19, 0x18, + 0x15, 0x13, 0x0f, 0x0b, 0x06, 0xff, 0xfa, 0xf6, 0xf2, 0xf2, 0xf0, 0xf0, + 0xf1, 0xf5, 0xff, 0x0c, 0x1b, 0x28, 0x2c, 0x27, 0x1b, 0x0c, 0x00, 0xf9, + 0xf9, 0xfd, 0x01, 0x04, 0x03, 0xfe, 0xf9, 0xf4, 0xf3, 0xf1, 0xf0, 0xf0, + 0xee, 0xee, 0xef, 0xef, 0xf3, 0xf4, 0xf5, 0xf5, 0xf6, 0xf9, 0x01, 0x0a, + 0x15, 0x1c, 0x1b, 0x13, 0x06, 0xf9, 0xf2, 0xf2, 0xf7, 0x02, 0x0e, 0x17, + 0x1c, 0x1a, 0x19, 0x16, 0x13, 0x10, 0x0d, 0x07, 0x02, 0xfc, 0xf7, 0xf3, + 0xf2, 0xf0, 0xf0, 0xf0, 0xf5, 0xfc, 0x05, 0x14, 0x23, 0x2a, 0x29, 0x20, + 0x11, 0x04, 0xfb, 0xfa, 0xfc, 0x01, 0x04, 0x05, 0x01, 0xfb, 0xf6, 0xf2, + 0xf0, 0xf2, 0xf0, 0xed, 0xed, 0xed, 0xef, 0xf0, 0xf3, 0xf4, 0xf5, 0xf5, + 0xf7, 0xfd, 0x06, 0x12, 0x1b, 0x1d, 0x16, 0x0b, 0xfd, 0xf5, 0xf1, 0xf6, + 0xfe, 0x0b, 0x14, 0x19, 0x1a, 0x18, 0x16, 0x14, 0x11, 0x0f, 0x0a, 0x04, + 0xfe, 0xfa, 0xf6, 0xf3, 0xf2, 0xf0, 0xef, 0xf2, 0xf8, 0x01, 0x0f, 0x1d, + 0x27, 0x29, 0x24, 0x17, 0x08, 0xfe, 0xf9, 0xfa, 0xff, 0x03, 0x05, 0x04, + 0xfd, 0xf7, 0xf3, 0xf1, 0xf0, 0xf0, 0xef, 0xee, 0xed, 0xec, 0xee, 0xf1, + 0xf3, 0xf4, 0xf4, 0xf7, 0xfc, 0x03, 0x0f, 0x1a, 0x1d, 0x19, 0x0f, 0x03, + 0xf8, 0xf3, 0xf4, 0xfa, 0x07, 0x12, 0x17, 0x19, 0x19, 0x17, 0x14, 0x13, + 0x10, 0x0c, 0x06, 0x01, 0xfd, 0xf8, 0xf4, 0xf3, 0xf1, 0xf0, 0xf0, 0xf4, + 0xfd, 0x09, 0x18, 0x24, 0x29, 0x26, 0x1a, 0x0d, 0x01, 0xfa, 0xfa, 0xfe, + 0x03, 0x05, 0x06, 0x00, 0xfa, 0xf6, 0xf3, 0xf2, 0xf1, 0xef, 0xef, 0xec, + 0xec, 0xed, 0xef, 0xf2, 0xf3, 0xf4, 0xf5, 0xf9, 0x01, 0x0c, 0x16, 0x1d, + 0x1d, 0x14, 0x09, 0xfb, 0xf4, 0xf4, 0xf7, 0x01, 0x0d, 0x15, 0x18, 0x18, + 0x16, 0x14, 0x13, 0x11, 0x0d, 0x08, 0x04, 0xff, 0xfa, 0xf7, 0xf4, 0xf2, + 0xef, 0xf0, 0xf1, 0xf8, 0x03, 0x11, 0x1f, 0x27, 0x26, 0x1d, 0x10, 0x04, + 0xfc, 0xfa, 0xfd, 0x02, 0x06, 0x06, 0x03, 0xfd, 0xf7, 0xf3, 0xf2, 0xf0, + 0xef, 0xee, 0xec, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf3, 0xf5, 0xf7, 0xfe, + 0x07, 0x14, 0x1c, 0x1f, 0x1a, 0x0e, 0x00, 0xf8, 0xf2, 0xf5, 0xff, 0x0a, + 0x13, 0x16, 0x18, 0x16, 0x14, 0x13, 0x12, 0x0f, 0x0c, 0x07, 0x00, 0xfd, + 0xf9, 0xf4, 0xf2, 0xf0, 0xee, 0xef, 0xf4, 0xfe, 0x0c, 0x1a, 0x25, 0x26, + 0x21, 0x14, 0x08, 0xfe, 0xf9, 0xfc, 0x01, 0x04, 0x06, 0x06, 0x01, 0xf9, + 0xf6, 0xf2, 0xf1, 0xf0, 0xef, 0xed, 0xeb, 0xec, 0xed, 0xee, 0xf0, 0xf2, + 0xf3, 0xf5, 0xfc, 0x03, 0x10, 0x1a, 0x20, 0x1d, 0x13, 0x06, 0xf9, 0xf5, + 0xf6, 0xfc, 0x07, 0x10, 0x16, 0x17, 0x16, 0x14, 0x12, 0x11, 0x10, 0x0e, + 0x09, 0x03, 0xff, 0xfa, 0xf8, 0xf4, 0xf2, 0xef, 0xee, 0xf2, 0xfb, 0x06, + 0x14, 0x20, 0x25, 0x21, 0x17, 0x0c, 0x00, 0xfb, 0xfa, 0x00, 0x04, 0x06, + 0x06, 0x03, 0xfc, 0xf8, 0xf3, 0xf2, 0xf0, 0xee, 0xed, 0xeb, 0xeb, 0xec, + 0xed, 0xef, 0xf0, 0xf1, 0xf3, 0xfa, 0x01, 0x0c, 0x17, 0x20, 0x20, 0x18, + 0x0c, 0xff, 0xf6, 0xf4, 0xf9, 0x03, 0x0c, 0x14, 0x16, 0x16, 0x14, 0x12, + 0x11, 0x10, 0x0e, 0x0b, 0x04, 0x00, 0xfd, 0xf9, 0xf6, 0xf4, 0xf0, 0xee, + 0xef, 0xf7, 0x01, 0x0f, 0x1c, 0x24, 0x23, 0x1a, 0x0f, 0x03, 0xfb, 0xf9, + 0xfe, 0x03, 0x08, 0x08, 0x06, 0x00, 0xfb, 0xf5, 0xf1, 0xf1, 0xf0, 0xee, + 0xec, 0xeb, 0xeb, 0xec, 0xee, 0xf0, 0xf0, 0xf2, 0xf6, 0xff, 0x08, 0x14, + 0x1f, 0x21, 0x1c, 0x11, 0x04, 0xf9, 0xf5, 0xf6, 0xfe, 0x09, 0x13, 0x16, + 0x16, 0x14, 0x12, 0x11, 0x10, 0x0f, 0x0c, 0x07, 0x01, 0xfe, 0xfa, 0xf7, + 0xf3, 0xf1, 0xef, 0xef, 0xf2, 0xfc, 0x08, 0x16, 0x21, 0x24, 0x1e, 0x13, + 0x07, 0xfd, 0xfa, 0xfd, 0x02, 0x07, 0x09, 0x06, 0x01, 0xfd, 0xf8, 0xf3, + 0xf1, 0xef, 0xee, 0xec, 0xea, 0xea, 0xea, 0xed, 0xef, 0xf0, 0xf1, 0xf5, + 0xfc, 0x04, 0x11, 0x1c, 0x21, 0x1f, 0x15, 0x09, 0xfc, 0xf5, 0xf6, 0xfb, + 0x07, 0x11, 0x15, 0x16, 0x15, 0x14, 0x11, 0x10, 0x0f, 0x0d, 0x09, 0x03, + 0x00, 0xfb, 0xf8, 0xf5, 0xf3, 0xf0, 0xee, 0xf1, 0xf9, 0x05, 0x11, 0x1c, + 0x22, 0x1f, 0x17, 0x0a, 0xff, 0xf9, 0xfb, 0x01, 0x06, 0x0a, 0x09, 0x04, + 0xff, 0xfc, 0xf6, 0xf2, 0xef, 0xed, 0xeb, 0xe9, 0xe8, 0xe8, 0xeb, 0xed, + 0xef, 0xf0, 0xf3, 0xf9, 0x00, 0x0d, 0x19, 0x20, 0x21, 0x1a, 0x0e, 0x01, + 0xf8, 0xf5, 0xf8, 0x02, 0x0e, 0x14, 0x17, 0x16, 0x15, 0x12, 0x10, 0x0f, + 0x0f, 0x0b, 0x06, 0x00, 0xfb, 0xf8, 0xf7, 0xf3, 0xf1, 0xef, 0xef, 0xf5, + 0xff, 0x0d, 0x1a, 0x21, 0x21, 0x19, 0x0d, 0x02, 0xfb, 0xfa, 0xfe, 0x06, + 0x0a, 0x0a, 0x06, 0x02, 0xfd, 0xf8, 0xf3, 0xf0, 0xed, 0xeb, 0xe9, 0xe7, + 0xe7, 0xe9, 0xeb, 0xed, 0xee, 0xf2, 0xf7, 0xff, 0x0a, 0x16, 0x1f, 0x23, + 0x1e, 0x13, 0x05, 0xfb, 0xf5, 0xf6, 0xff, 0x0b, 0x12, 0x16, 0x17, 0x15, + 0x13, 0x11, 0x10, 0x0f, 0x0c, 0x08, 0x03, 0xff, 0xfa, 0xf7, 0xf5, 0xf2, + 0xf1, 0xef, 0xf3, 0xfb, 0x07, 0x14, 0x1e, 0x21, 0x1b, 0x10, 0x05, 0xfd, + 0xf9, 0xfd, 0x05, 0x0a, 0x0b, 0x09, 0x03, 0xff, 0xfa, 0xf6, 0xf2, 0xef, + 0xec, 0xe9, 0xe7, 0xe6, 0xe7, 0xea, 0xec, 0xef, 0xf1, 0xf4, 0xfc, 0x04, + 0x12, 0x1d, 0x23, 0x20, 0x17, 0x0b, 0xfe, 0xf7, 0xf6, 0xfc, 0x07, 0x11, + 0x15, 0x17, 0x15, 0x13, 0x11, 0x10, 0x0e, 0x0c, 0x09, 0x04, 0x00, 0xfc, + 0xf9, 0xf6, 0xf4, 0xf3, 0xf0, 0xf1, 0xf7, 0x02, 0x0f, 0x1b, 0x22, 0x1e, + 0x16, 0x09, 0xff, 0xf9, 0xfa, 0x01, 0x08, 0x0b, 0x0b, 0x05, 0x00, 0xfa, + 0xf7, 0xf3, 0xee, 0xec, 0xea, 0xe7, 0xe6, 0xe7, 0xe9, 0xec, 0xef, 0xf1, + 0xf3, 0xf9, 0x00, 0x0e, 0x1b, 0x22, 0x23, 0x1b, 0x0e, 0x02, 0xfa, 0xf7, + 0xf9, 0x03, 0x0d, 0x14, 0x17, 0x16, 0x13, 0x11, 0x10, 0x0f, 0x0d, 0x0a, + 0x05, 0x01, 0xfd, 0xf9, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0, 0xf5, 0xfe, 0x0b, + 0x17, 0x20, 0x1f, 0x19, 0x0d, 0x01, 0xfa, 0xf9, 0xff, 0x06, 0x0b, 0x0c, + 0x07, 0x00, 0xfb, 0xf7, 0xf3, 0xf0, 0xec, 0xe9, 0xe7, 0xe6, 0xe7, 0xe8, + 0xeb, 0xed, 0xf0, 0xf2, 0xf6, 0x00, 0x0a, 0x16, 0x21, 0x24, 0x1e, 0x11, + 0x07, 0xfd, 0xf7, 0xf7, 0x00, 0x0b, 0x13, 0x17, 0x17, 0x15, 0x12, 0x10, + 0x0f, 0x0e, 0x0b, 0x07, 0x02, 0x00, 0xfc, 0xf8, 0xf5, 0xf3, 0xf1, 0xf1, + 0xf4, 0xfa, 0x06, 0x13, 0x1f, 0x21, 0x1c, 0x11, 0x04, 0xfc, 0xfa, 0xfd, + 0x04, 0x09, 0x0c, 0x0a, 0x03, 0xfc, 0xf7, 0xf3, 0xf0, 0xee, 0xea, 0xe8, + 0xe6, 0xe6, 0xe8, 0xea, 0xed, 0xef, 0xf1, 0xf4, 0xfc, 0x05, 0x12, 0x1e, + 0x24, 0x21, 0x17, 0x0a, 0xfe, 0xf9, 0xf8, 0xfe, 0x08, 0x10, 0x17, 0x17, + 0x15, 0x13, 0x11, 0x0f, 0x0d, 0x0c, 0x08, 0x03, 0x00, 0xfd, 0xf9, 0xf6, + 0xf5, 0xf2, 0xf1, 0xf3, 0xf8, 0x02, 0x0e, 0x1b, 0x21, 0x1e, 0x15, 0x09, + 0xfe, 0xfa, 0xfa, 0x01, 0x08, 0x0c, 0x0c, 0x05, 0xfe, 0xf7, 0xf3, 0xf0, + 0xee, 0xeb, 0xe8, 0xe6, 0xe6, 0xe6, 0xe9, 0xeb, 0xee, 0xf1, 0xf3, 0xf9, + 0x00, 0x0d, 0x1b, 0x24, 0x23, 0x1b, 0x0e, 0x02, 0xfb, 0xf8, 0xfb, 0x04, + 0x0e, 0x15, 0x19, 0x16, 0x13, 0x11, 0x0f, 0x0d, 0x0c, 0x08, 0x04, 0x01, + 0xfe, 0xfa, 0xf7, 0xf5, 0xf3, 0xf1, 0xf2, 0xf6, 0xfe, 0x0a, 0x18, 0x20, + 0x1f, 0x18, 0x0e, 0x01, 0xfb, 0xfa, 0xff, 0x07, 0x0c, 0x0e, 0x08, 0x02, + 0xfa, 0xf3, 0xf0, 0xee, 0xea, 0xe8, 0xe6, 0xe5, 0xe5, 0xe8, 0xeb, 0xee, + 0xf0, 0xf3, 0xf8, 0xff, 0x09, 0x17, 0x21, 0x24, 0x1f, 0x13, 0x06, 0xfc, + 0xf9, 0xfa, 0x02, 0x0b, 0x12, 0x17, 0x17, 0x15, 0x12, 0x0f, 0x0d, 0x0c, + 0x0a, 0x06, 0x02, 0xff, 0xfc, 0xf9, 0xf6, 0xf4, 0xf2, 0xf2, 0xf4, 0xfb, + 0x06, 0x12, 0x1e, 0x21, 0x1e, 0x12, 0x06, 0xfd, 0xfa, 0xfd, 0x05, 0x0b, + 0x0d, 0x09, 0x03, 0xfc, 0xf5, 0xef, 0xec, 0xea, 0xe7, 0xe4, 0xe4, 0xe5, + 0xe5, 0xea, 0xed, 0xef, 0xf2, 0xf6, 0xfd, 0x04, 0x12, 0x1d, 0x23, 0x21, + 0x18, 0x0a, 0xff, 0xf9, 0xf9, 0xfe, 0x0a, 0x11, 0x16, 0x18, 0x16, 0x12, + 0x11, 0x0e, 0x0c, 0x0b, 0x07, 0x03, 0xff, 0xfc, 0xfa, 0xf8, 0xf5, 0xf2, + 0xf2, 0xf3, 0xf8, 0x03, 0x0f, 0x1a, 0x20, 0x20, 0x17, 0x0c, 0x01, 0xfb, + 0xfc, 0x02, 0x09, 0x0c, 0x0b, 0x05, 0xfe, 0xf6, 0xf0, 0xec, 0xea, 0xe7, + 0xe4, 0xe4, 0xe3, 0xe5, 0xe9, 0xec, 0xef, 0xf2, 0xf5, 0xfa, 0x01, 0x0d, + 0x1a, 0x21, 0x22, 0x1c, 0x10, 0x02, 0xfc, 0xf8, 0xfd, 0x06, 0x0f, 0x16, + 0x18, 0x17, 0x13, 0x10, 0x0d, 0x0b, 0x09, 0x08, 0x04, 0x00, 0xfd, 0xfb, + 0xf9, 0xf7, 0xf4, 0xf2, 0xf2, 0xf6, 0xff, 0x0b, 0x16, 0x1f, 0x20, 0x1a, + 0x0f, 0x03, 0xfe, 0xfc, 0x00, 0x09, 0x0d, 0x0d, 0x08, 0x00, 0xf8, 0xf0, + 0xeb, 0xe9, 0xe7, 0xe6, 0xe4, 0xe2, 0xe4, 0xe7, 0xeb, 0xed, 0xf1, 0xf4, + 0xf8, 0x00, 0x0a, 0x16, 0x21, 0x24, 0x20, 0x14, 0x07, 0xff, 0xf9, 0xfa, + 0x02, 0x0d, 0x15, 0x19, 0x18, 0x14, 0x11, 0x0d, 0x0b, 0x09, 0x09, 0x06, + 0x02, 0xff, 0xfc, 0xf9, 0xf8, 0xf5, 0xf4, 0xf3, 0xf4, 0xfb, 0x07, 0x12, + 0x1d, 0x20, 0x1d, 0x12, 0x06, 0xff, 0xfc, 0x00, 0x06, 0x0c, 0x0d, 0x0a, + 0x03, 0xf9, 0xf1, 0xec, 0xe8, 0xe6, 0xe5, 0xe2, 0xe1, 0xe2, 0xe4, 0xe9, + 0xee, 0xf1, 0xf2, 0xf6, 0xfd, 0x05, 0x13, 0x1d, 0x24, 0x22, 0x19, 0x0b, + 0x00, 0xfb, 0xfb, 0x01, 0x0c, 0x14, 0x18, 0x18, 0x15, 0x11, 0x0d, 0x0b, + 0x0a, 0x08, 0x06, 0x04, 0x00, 0xfe, 0xfc, 0xf9, 0xf7, 0xf6, 0xf3, 0xf4, + 0xf9, 0x03, 0x0f, 0x1a, 0x20, 0x1f, 0x17, 0x0a, 0x01, 0xfc, 0xff, 0x05, + 0x0b, 0x0e, 0x0d, 0x05, 0xfc, 0xf3, 0xeb, 0xe7, 0xe5, 0xe4, 0xe2, 0xe1, + 0xe1, 0xe3, 0xe7, 0xeb, 0xef, 0xf2, 0xf5, 0xfa, 0x01, 0x0f, 0x1a, 0x23, + 0x23, 0x1c, 0x10, 0x05, 0xfc, 0xf9, 0xff, 0x09, 0x12, 0x18, 0x1a, 0x15, + 0x12, 0x0e, 0x0b, 0x09, 0x08, 0x07, 0x05, 0x02, 0xff, 0xfd, 0xfa, 0xf8, + 0xf6, 0xf3, 0xf3, 0xf6, 0xff, 0x0a, 0x17, 0x1e, 0x21, 0x1b, 0x10, 0x04, + 0xfd, 0xfe, 0x04, 0x0a, 0x0f, 0x0e, 0x08, 0x00, 0xf6, 0xec, 0xe6, 0xe4, + 0xe2, 0xe2, 0xe0, 0xe0, 0xe2, 0xe5, 0xe9, 0xee, 0xf1, 0xf4, 0xf8, 0x00, + 0x0a, 0x17, 0x22, 0x26, 0x20, 0x15, 0x09, 0xff, 0xfa, 0xfe, 0x06, 0x0f, + 0x17, 0x1a, 0x18, 0x13, 0x0f, 0x0b, 0x09, 0x07, 0x06, 0x05, 0x02, 0xff, + 0xfe, 0xfc, 0xf9, 0xf7, 0xf4, 0xf3, 0xf4, 0xfb, 0x06, 0x13, 0x1f, 0x21, + 0x1e, 0x14, 0x07, 0xff, 0xff, 0x01, 0x09, 0x0e, 0x10, 0x0b, 0x03, 0xf9, + 0xef, 0xe7, 0xe3, 0xe1, 0xe0, 0xde, 0xdf, 0xe1, 0xe4, 0xe8, 0xec, 0xf0, + 0xf3, 0xf6, 0xfd, 0x05, 0x12, 0x1e, 0x25, 0x23, 0x1b, 0x0f, 0x03, 0xfc, + 0xfc, 0x04, 0x0c, 0x16, 0x1a, 0x1a, 0x15, 0x10, 0x0b, 0x08, 0x08, 0x07, + 0x06, 0x02, 0x00, 0xfe, 0xfd, 0xfa, 0xf8, 0xf6, 0xf3, 0xf4, 0xf9, 0x03, + 0x0e, 0x1c, 0x21, 0x21, 0x19, 0x0c, 0x02, 0xfe, 0x01, 0x07, 0x0e, 0x11, + 0x0e, 0x05, 0xfb, 0xf0, 0xe9, 0xe4, 0xe1, 0xde, 0xdc, 0xdd, 0xdf, 0xe2, + 0xe5, 0xeb, 0xee, 0xf3, 0xf5, 0xfb, 0x01, 0x0f, 0x1c, 0x24, 0x25, 0x1f, + 0x13, 0x07, 0xff, 0xfc, 0x00, 0x0a, 0x14, 0x1a, 0x1a, 0x17, 0x11, 0x0b, + 0x08, 0x08, 0x07, 0x07, 0x04, 0x02, 0xff, 0xfe, 0xfc, 0xf9, 0xf8, 0xf5, + 0xf4, 0xf6, 0xfe, 0x0a, 0x17, 0x1f, 0x21, 0x1b, 0x11, 0x07, 0x00, 0x00, + 0x05, 0x0d, 0x11, 0x10, 0x08, 0xff, 0xf3, 0xea, 0xe3, 0xde, 0xdd, 0xdb, + 0xdc, 0xdd, 0xe0, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf9, 0x00, 0x0a, 0x18, + 0x22, 0x26, 0x23, 0x18, 0x0b, 0x01, 0xfd, 0xff, 0x08, 0x11, 0x18, 0x1a, + 0x18, 0x12, 0x0c, 0x09, 0x07, 0x07, 0x05, 0x04, 0x02, 0xff, 0xff, 0xfd, + 0xfb, 0xf9, 0xf6, 0xf4, 0xf5, 0xfc, 0x06, 0x13, 0x1e, 0x21, 0x1e, 0x14, + 0x0a, 0x03, 0x00, 0x04, 0x0b, 0x10, 0x11, 0x0b, 0x03, 0xf8, 0xec, 0xe3, + 0xde, 0xdc, 0xda, 0xda, 0xda, 0xdd, 0xe1, 0xe6, 0xeb, 0xf0, 0xf3, 0xf6, + 0xfd, 0x05, 0x13, 0x1f, 0x26, 0x26, 0x1c, 0x10, 0x04, 0xfe, 0xff, 0x05, + 0x0f, 0x17, 0x1a, 0x19, 0x13, 0x0f, 0x09, 0x07, 0x06, 0x05, 0x05, 0x03, + 0xff, 0xfe, 0xfd, 0xfc, 0xf9, 0xf8, 0xf5, 0xf6, 0xf9, 0x03, 0x0e, 0x1b, + 0x21, 0x21, 0x1a, 0x0f, 0x06, 0x01, 0x03, 0x0b, 0x10, 0x11, 0x0e, 0x04, + 0xf9, 0xee, 0xe5, 0xdf, 0xdb, 0xda, 0xd9, 0xda, 0xdb, 0xdf, 0xe4, 0xea, + 0xee, 0xf3, 0xf6, 0xfb, 0x02, 0x0f, 0x1a, 0x25, 0x26, 0x20, 0x15, 0x09, + 0x00, 0xfe, 0x03, 0x0b, 0x16, 0x1a, 0x1b, 0x16, 0x0f, 0x0a, 0x07, 0x06, + 0x05, 0x05, 0x03, 0x01, 0x00, 0xfe, 0xfc, 0xfb, 0xfa, 0xf6, 0xf5, 0xf8, + 0x00, 0x0a, 0x18, 0x20, 0x23, 0x1d, 0x12, 0x08, 0x03, 0x03, 0x08, 0x0f, + 0x12, 0x11, 0x09, 0xfc, 0xef, 0xe6, 0xe0, 0xdd, 0xda, 0xd7, 0xd8, 0xd9, + 0xdd, 0xe1, 0xe7, 0xeb, 0xf0, 0xf4, 0xf9, 0xff, 0x09, 0x17, 0x22, 0x29, + 0x23, 0x19, 0x0d, 0x04, 0x01, 0x04, 0x0a, 0x12, 0x19, 0x1a, 0x17, 0x10, + 0x0b, 0x07, 0x06, 0x06, 0x05, 0x04, 0x02, 0x02, 0x00, 0xfe, 0xfc, 0xfa, + 0xf8, 0xf6, 0xf7, 0xfc, 0x05, 0x12, 0x1e, 0x23, 0x1e, 0x15, 0x0d, 0x04, + 0x04, 0x07, 0x0e, 0x12, 0x12, 0x0c, 0x01, 0xf4, 0xe8, 0xe0, 0xdc, 0xda, + 0xd8, 0xd6, 0xd7, 0xdb, 0xdf, 0xe3, 0xea, 0xee, 0xf2, 0xf6, 0xfc, 0x03, + 0x12, 0x1f, 0x27, 0x27, 0x1f, 0x12, 0x08, 0x00, 0x03, 0x09, 0x11, 0x18, + 0x1b, 0x19, 0x13, 0x0b, 0x07, 0x05, 0x06, 0x06, 0x04, 0x02, 0x01, 0x00, + 0xff, 0xfe, 0xfc, 0xf9, 0xf7, 0xf7, 0xf9, 0x03, 0x0e, 0x19, 0x21, 0x22, + 0x1b, 0x10, 0x08, 0x04, 0x06, 0x0c, 0x11, 0x14, 0x10, 0x04, 0xf7, 0xea, + 0xe1, 0xdc, 0xd9, 0xd7, 0xd5, 0xd6, 0xd8, 0xdd, 0xe2, 0xe8, 0xec, 0xf0, + 0xf3, 0xf9, 0x00, 0x0c, 0x1b, 0x25, 0x28, 0x23, 0x19, 0x0c, 0x04, 0x02, + 0x07, 0x0e, 0x17, 0x1b, 0x1a, 0x15, 0x0e, 0x08, 0x04, 0x04, 0x05, 0x04, + 0x03, 0x01, 0x00, 0x00, 0x00, 0xfe, 0xfb, 0xf8, 0xf7, 0xf9, 0xff, 0x09, + 0x15, 0x1f, 0x24, 0x1e, 0x15, 0x0b, 0x04, 0x06, 0x0b, 0x10, 0x13, 0x10, + 0x08, 0xfc, 0xee, 0xe3, 0xdc, 0xd9, 0xd7, 0xd6, 0xd4, 0xd7, 0xda, 0xdf, + 0xe4, 0xea, 0xed, 0xf1, 0xf5, 0xfd, 0x08, 0x15, 0x23, 0x2a, 0x28, 0x1f, + 0x12, 0x08, 0x03, 0x06, 0x0d, 0x15, 0x19, 0x1a, 0x16, 0x0f, 0x08, 0x04, + 0x03, 0x04, 0x04, 0x02, 0x03, 0x01, 0x00, 0xff, 0x00, 0xfc, 0xf9, 0xf6, + 0xf7, 0xfd, 0x05, 0x12, 0x1c, 0x22, 0x21, 0x18, 0x0e, 0x07, 0x06, 0x09, + 0x0e, 0x12, 0x11, 0x0c, 0x01, 0xf4, 0xe6, 0xdd, 0xd8, 0xd7, 0xd6, 0xd5, + 0xd6, 0xd8, 0xdc, 0xe3, 0xe8, 0xec, 0xee, 0xf3, 0xf9, 0x04, 0x10, 0x1e, + 0x27, 0x2a, 0x24, 0x19, 0x0c, 0x05, 0x06, 0x0c, 0x14, 0x1a, 0x1a, 0x17, + 0x11, 0x0a, 0x04, 0x02, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00, 0x01, 0x00, + 0xfe, 0xfa, 0xf7, 0xf6, 0xf9, 0x03, 0x0e, 0x19, 0x21, 0x22, 0x1c, 0x13, + 0x0a, 0x06, 0x08, 0x0e, 0x12, 0x12, 0x0d, 0x04, 0xf7, 0xea, 0xdf, 0xd9, + 0xd6, 0xd4, 0xd5, 0xd5, 0xd7, 0xdb, 0xe1, 0xe5, 0xea, 0xed, 0xf1, 0xf5, + 0xff, 0x0c, 0x1a, 0x25, 0x2a, 0x27, 0x1e, 0x11, 0x08, 0x06, 0x0a, 0x10, + 0x18, 0x1a, 0x19, 0x13, 0x0b, 0x05, 0x02, 0x02, 0x02, 0x04, 0x04, 0x02, + 0x01, 0x00, 0x02, 0x00, 0xfc, 0xf7, 0xf5, 0xf7, 0xff, 0x09, 0x15, 0x1f, + 0x24, 0x21, 0x17, 0x0e, 0x09, 0x08, 0x0d, 0x11, 0x13, 0x0f, 0x06, 0xfb, + 0xed, 0xe1, 0xda, 0xd6, 0xd4, 0xd4, 0xd4, 0xd5, 0xd8, 0xde, 0xe4, 0xe8, + 0xeb, 0xee, 0xf2, 0xf9, 0x06, 0x15, 0x22, 0x2a, 0x2a, 0x22, 0x17, 0x0e, + 0x08, 0x09, 0x10, 0x17, 0x1b, 0x1a, 0x15, 0x0c, 0x06, 0x03, 0x02, 0x02, + 0x02, 0x03, 0x03, 0x02, 0x00, 0x01, 0x01, 0xff, 0xfb, 0xf7, 0xf6, 0xfb, + 0x06, 0x12, 0x1d, 0x24, 0x22, 0x1a, 0x11, 0x0a, 0x08, 0x0a, 0x11, 0x13, + 0x11, 0x09, 0xfe, 0xf1, 0xe4, 0xdb, 0xd7, 0xd4, 0xd4, 0xd4, 0xd5, 0xd7, + 0xdb, 0xe0, 0xe5, 0xea, 0xec, 0xf0, 0xf4, 0x02, 0x0e, 0x1d, 0x28, 0x2a, + 0x27, 0x1c, 0x12, 0x09, 0x0a, 0x0e, 0x15, 0x1a, 0x1c, 0x17, 0x0f, 0x07, + 0x03, 0x01, 0x01, 0x02, 0x03, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0xfc, + 0xf8, 0xf6, 0xfb, 0x04, 0x0e, 0x1a, 0x23, 0x24, 0x1f, 0x15, 0x0c, 0x08, + 0x0b, 0x10, 0x12, 0x14, 0x0c, 0x01, 0xf3, 0xe7, 0xdd, 0xd8, 0xd5, 0xd5, + 0xd4, 0xd5, 0xd7, 0xd9, 0xdf, 0xe3, 0xe7, 0xe9, 0xeb, 0xef, 0xfa, 0x09, + 0x17, 0x24, 0x2a, 0x28, 0x20, 0x16, 0x0e, 0x0c, 0x0e, 0x15, 0x1b, 0x1d, + 0x18, 0x11, 0x08, 0x03, 0xff, 0xfe, 0x01, 0x03, 0x04, 0x03, 0x03, 0x00, + 0x02, 0x00, 0xfe, 0xf9, 0xf6, 0xf7, 0x00, 0x0b, 0x17, 0x21, 0x26, 0x22, + 0x1a, 0x11, 0x0a, 0x0a, 0x0e, 0x11, 0x14, 0x0e, 0x04, 0xf7, 0xea, 0xdf, + 0xd9, 0xd5, 0xd4, 0xd4, 0xd4, 0xd7, 0xd9, 0xdc, 0xe1, 0xe4, 0xe8, 0xe9, + 0xec, 0xf4, 0x03, 0x12, 0x20, 0x29, 0x2a, 0x24, 0x1b, 0x12, 0x0d, 0x0e, + 0x13, 0x1a, 0x1d, 0x1c, 0x14, 0x0b, 0x03, 0xff, 0xfe, 0x00, 0x00, 0x03, + 0x04, 0x03, 0x02, 0x01, 0x01, 0x00, 0xfb, 0xf8, 0xf7, 0xfc, 0x06, 0x14, + 0x20, 0x26, 0x24, 0x1d, 0x14, 0x0c, 0x09, 0x0b, 0x10, 0x13, 0x12, 0x08, + 0xfb, 0xed, 0xe2, 0xdb, 0xd6, 0xd4, 0xd3, 0xd4, 0xd6, 0xd9, 0xdb, 0xde, + 0xe1, 0xe5, 0xe6, 0xe9, 0xef, 0xfc, 0x0b, 0x1c, 0x27, 0x2b, 0x28, 0x21, + 0x16, 0x10, 0x0e, 0x14, 0x19, 0x1e, 0x1d, 0x17, 0x0e, 0x05, 0xff, 0xfe, + 0xfe, 0x00, 0x02, 0x05, 0x04, 0x03, 0x01, 0x02, 0x00, 0xfc, 0xf8, 0xf7, + 0xfa, 0x04, 0x10, 0x1c, 0x25, 0x26, 0x20, 0x17, 0x0e, 0x0a, 0x0b, 0x0f, + 0x13, 0x12, 0x0c, 0xff, 0xf1, 0xe5, 0xdb, 0xd6, 0xd5, 0xd3, 0xd2, 0xd5, + 0xd6, 0xda, 0xdc, 0xe0, 0xe2, 0xe4, 0xe7, 0xec, 0xf5, 0x06, 0x16, 0x23, + 0x2b, 0x2b, 0x24, 0x1a, 0x12, 0x10, 0x12, 0x18, 0x1e, 0x1e, 0x1a, 0x12, + 0x08, 0x02, 0xff, 0xfe, 0x00, 0x01, 0x03, 0x04, 0x04, 0x03, 0x02, 0x01, + 0xfe, 0xfa, 0xf6, 0xf8, 0xff, 0x0b, 0x19, 0x25, 0x2a, 0x25, 0x1a, 0x12, + 0x0b, 0x0c, 0x0e, 0x12, 0x12, 0x0e, 0x03, 0xf6, 0xe8, 0xde, 0xd9, 0xd5, + 0xd3, 0xd2, 0xd5, 0xd6, 0xd9, 0xdb, 0xdf, 0xe0, 0xe2, 0xe4, 0xe7, 0xef, + 0xfd, 0x0e, 0x1e, 0x2a, 0x2c, 0x27, 0x1f, 0x17, 0x12, 0x12, 0x17, 0x1e, + 0x21, 0x1d, 0x15, 0x0b, 0x03, 0xff, 0xfe, 0xfe, 0x00, 0x02, 0x03, 0x04, + 0x02, 0x01, 0x02, 0xff, 0xfb, 0xf9, 0xf6, 0xfb, 0x06, 0x15, 0x21, 0x29, + 0x28, 0x20, 0x15, 0x0e, 0x09, 0x0a, 0x0f, 0x12, 0x10, 0x06, 0xfa, 0xec, + 0xe0, 0xda, 0xd6, 0xd4, 0xd3, 0xd4, 0xd6, 0xd8, 0xda, 0xdd, 0xdf, 0xe0, + 0xe2, 0xe4, 0xe9, 0xf6, 0x06, 0x18, 0x27, 0x2c, 0x2a, 0x23, 0x1c, 0x15, + 0x14, 0x17, 0x1d, 0x21, 0x21, 0x1a, 0x0f, 0x05, 0xff, 0xfe, 0xfe, 0xfe, + 0x02, 0x02, 0x03, 0x03, 0x01, 0x02, 0x00, 0xfe, 0xf9, 0xf7, 0xfa, 0x03, + 0x10, 0x1e, 0x27, 0x2a, 0x23, 0x19, 0x11, 0x0b, 0x0a, 0x0e, 0x10, 0x10, + 0x08, 0xfe, 0xf0, 0xe4, 0xdd, 0xd7, 0xd4, 0xd5, 0xd5, 0xd5, 0xd6, 0xd9, + 0xda, 0xdd, 0xe0, 0xe0, 0xe1, 0xe4, 0xef, 0x00, 0x11, 0x22, 0x2c, 0x2c, + 0x28, 0x1f, 0x19, 0x15, 0x17, 0x1d, 0x21, 0x21, 0x1c, 0x12, 0x08, 0x01, + 0xfe, 0xfe, 0xfe, 0x01, 0x03, 0x03, 0x03, 0x02, 0x01, 0x02, 0xfe, 0xfa, + 0xf8, 0xf8, 0x01, 0x0d, 0x1a, 0x26, 0x2b, 0x28, 0x1d, 0x14, 0x0c, 0x09, + 0x0c, 0x0f, 0x0f, 0x0b, 0x02, 0xf5, 0xe7, 0xdf, 0xda, 0xd6, 0xd5, 0xd6, + 0xd6, 0xd7, 0xd8, 0xda, 0xdb, 0xdc, 0xdd, 0xdf, 0xe1, 0xea, 0xfa, 0x0a, + 0x1b, 0x29, 0x2d, 0x2a, 0x23, 0x1b, 0x16, 0x17, 0x1b, 0x20, 0x21, 0x1f, + 0x16, 0x0c, 0x03, 0xff, 0xfe, 0xfe, 0x01, 0x03, 0x04, 0x04, 0x02, 0x01, + 0x02, 0x00, 0xfd, 0xf8, 0xf7, 0xfd, 0x07, 0x16, 0x24, 0x2b, 0x2b, 0x21, + 0x16, 0x0e, 0x09, 0x0b, 0x0e, 0x0f, 0x0d, 0x04, 0xf9, 0xed, 0xe2, 0xdc, + 0xd7, 0xd6, 0xd6, 0xd7, 0xd7, 0xd8, 0xda, 0xdb, 0xdb, 0xdc, 0xdc, 0xde, + 0xe5, 0xf3, 0x05, 0x15, 0x24, 0x2c, 0x2c, 0x26, 0x1e, 0x18, 0x16, 0x1a, + 0x20, 0x22, 0x21, 0x1a, 0x10, 0x07, 0xff, 0xfe, 0xfe, 0x01, 0x03, 0x04, + 0x04, 0x02, 0x01, 0x01, 0x00, 0xfd, 0xf8, 0xf7, 0xfb, 0x02, 0x11, 0x20, + 0x29, 0x2b, 0x25, 0x1c, 0x10, 0x0a, 0x09, 0x0c, 0x0e, 0x0d, 0x07, 0xfd, + 0xef, 0xe4, 0xdd, 0xd8, 0xd7, 0xd6, 0xd8, 0xd7, 0xd8, 0xd8, 0xd9, 0xda, + 0xdb, 0xda, 0xdd, 0xe0, 0xeb, 0xfd, 0x0f, 0x20, 0x2b, 0x2c, 0x2a, 0x20, + 0x19, 0x16, 0x1a, 0x1e, 0x23, 0x23, 0x1d, 0x13, 0x0b, 0x03, 0xfe, 0xfe, + 0xff, 0x02, 0x04, 0x05, 0x03, 0x00, 0x01, 0x02, 0xfe, 0xf9, 0xf6, 0xf8, + 0x02, 0x0d, 0x1c, 0x28, 0x2e, 0x2a, 0x20, 0x15, 0x0b, 0x08, 0x0a, 0x0c, + 0x0e, 0x09, 0x01, 0xf3, 0xe8, 0xe0, 0xda, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, + 0xd9, 0xd9, 0xda, 0xdb, 0xda, 0xdb, 0xdd, 0xe6, 0xf5, 0x07, 0x1a, 0x28, + 0x2e, 0x2b, 0x24, 0x1b, 0x16, 0x17, 0x1c, 0x22, 0x25, 0x20, 0x18, 0x0f, + 0x06, 0x00, 0xfe, 0x00, 0x01, 0x04, 0x04, 0x03, 0x00, 0x01, 0x00, 0xfd, + 0xf9, 0xf7, 0xf7, 0xfe, 0x08, 0x18, 0x26, 0x2d, 0x2c, 0x25, 0x1a, 0x0f, + 0x08, 0x08, 0x0a, 0x0c, 0x0a, 0x01, 0xf8, 0xec, 0xe2, 0xdb, 0xda, 0xd9, + 0xd8, 0xd8, 0xd9, 0xd8, 0xd8, 0xd8, 0xda, 0xd9, 0xda, 0xdc, 0xe0, 0xed, + 0x01, 0x14, 0x22, 0x2c, 0x2c, 0x27, 0x1e, 0x19, 0x17, 0x1b, 0x21, 0x25, + 0x22, 0x1c, 0x12, 0x09, 0x03, 0x00, 0x00, 0x02, 0x03, 0x04, 0x04, 0x00, + 0x00, 0x01, 0xfe, 0xfb, 0xf8, 0xf7, 0xfa, 0x05, 0x14, 0x22, 0x2c, 0x2f, + 0x28, 0x1d, 0x13, 0x0b, 0x07, 0x08, 0x0b, 0x0a, 0x04, 0xfc, 0xef, 0xe5, + 0xde, 0xda, 0xda, 0xd9, 0xda, 0xda, 0xd9, 0xd7, 0xd9, 0xd9, 0xd9, 0xda, + 0xda, 0xdd, 0xe7, 0xfa, 0x0c, 0x1e, 0x28, 0x2c, 0x28, 0x20, 0x1a, 0x17, + 0x18, 0x1e, 0x25, 0x25, 0x1e, 0x15, 0x0e, 0x07, 0x03, 0x01, 0x02, 0x03, + 0x04, 0x04, 0x02, 0x00, 0x00, 0xfe, 0xfc, 0xf9, 0xf8, 0xf9, 0x01, 0x0f, + 0x1e, 0x2a, 0x30, 0x2d, 0x23, 0x16, 0x0d, 0x07, 0x06, 0x09, 0x0a, 0x06, + 0xff, 0xf2, 0xe7, 0xe0, 0xdd, 0xdb, 0xd9, 0xda, 0xd9, 0xd8, 0xd8, 0xd8, + 0xd8, 0xd8, 0xd9, 0xd9, 0xda, 0xe3, 0xf3, 0x05, 0x17, 0x25, 0x2b, 0x28, + 0x22, 0x1c, 0x16, 0x17, 0x1c, 0x22, 0x25, 0x21, 0x1b, 0x11, 0x09, 0x05, + 0x04, 0x03, 0x04, 0x05, 0x05, 0x02, 0x00, 0xfe, 0xfe, 0xfc, 0xfb, 0xf7, + 0xf8, 0xff, 0x0a, 0x19, 0x28, 0x30, 0x2f, 0x26, 0x1a, 0x0f, 0x08, 0x05, + 0x06, 0x09, 0x06, 0x01, 0xf6, 0xeb, 0xe2, 0xe0, 0xdc, 0xdb, 0xdc, 0xdc, + 0xda, 0xd8, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xda, 0xe0, 0xec, 0x00, 0x11, + 0x22, 0x29, 0x29, 0x25, 0x1d, 0x18, 0x15, 0x19, 0x20, 0x24, 0x24, 0x1e, + 0x16, 0x0e, 0x08, 0x05, 0x05, 0x05, 0x05, 0x05, 0x03, 0x00, 0xff, 0xfd, + 0xfc, 0xfa, 0xf7, 0xf7, 0xfd, 0x06, 0x15, 0x24, 0x2f, 0x31, 0x2a, 0x1e, + 0x12, 0x08, 0x04, 0x05, 0x07, 0x07, 0x03, 0xfa, 0xef, 0xe5, 0xe0, 0xde, + 0xdd, 0xdd, 0xdd, 0xd9, 0xd8, 0xd7, 0xd8, 0xd7, 0xd8, 0xd8, 0xd8, 0xdc, + 0xe7, 0xf8, 0x0b, 0x1d, 0x28, 0x29, 0x27, 0x1f, 0x18, 0x15, 0x18, 0x1d, + 0x22, 0x23, 0x20, 0x19, 0x11, 0x0b, 0x08, 0x07, 0x07, 0x07, 0x06, 0x04, + 0x00, 0xff, 0xfc, 0xfa, 0xfa, 0xf7, 0xf7, 0xfb, 0x03, 0x10, 0x20, 0x2d, + 0x31, 0x2d, 0x23, 0x16, 0x0b, 0x04, 0x03, 0x05, 0x07, 0x03, 0xfd, 0xf1, + 0xe7, 0xe2, 0xe0, 0xde, 0xdf, 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd5, 0xd7, + 0xd7, 0xd7, 0xdb, 0xe3, 0xf2, 0x04, 0x17, 0x25, 0x29, 0x26, 0x1f, 0x18, + 0x14, 0x14, 0x1b, 0x20, 0x23, 0x23, 0x1d, 0x14, 0x0e, 0x0a, 0x08, 0x08, + 0x09, 0x08, 0x05, 0x02, 0x00, 0xfc, 0xfa, 0xf8, 0xf7, 0xf7, 0xfa, 0x00, + 0x0d, 0x1c, 0x2b, 0x32, 0x31, 0x27, 0x1a, 0x0d, 0x05, 0x02, 0x03, 0x05, + 0x04, 0x00, 0xf6, 0xec, 0xe4, 0xe0, 0xdf, 0xdf, 0xde, 0xdd, 0xda, 0xd9, + 0xd5, 0xd5, 0xd5, 0xd5, 0xd7, 0xd9, 0xdf, 0xed, 0x00, 0x12, 0x21, 0x29, + 0x27, 0x21, 0x1a, 0x15, 0x13, 0x15, 0x1c, 0x22, 0x24, 0x20, 0x1a, 0x13, + 0x0e, 0x0a, 0x0a, 0x0b, 0x0a, 0x07, 0x04, 0x00, 0xfc, 0xfa, 0xf8, 0xf7, + 0xf7, 0xf8, 0xfd, 0x06, 0x17, 0x27, 0x31, 0x32, 0x2b, 0x1f, 0x10, 0x06, + 0x00, 0x00, 0x03, 0x05, 0x00, 0xf8, 0xef, 0xe7, 0xe3, 0xe1, 0xe1, 0xe0, + 0xdd, 0xdb, 0xd8, 0xd6, 0xd4, 0xd6, 0xd5, 0xd5, 0xd8, 0xde, 0xe7, 0xf8, + 0x0b, 0x1c, 0x27, 0x27, 0x22, 0x1b, 0x14, 0x12, 0x13, 0x18, 0x20, 0x23, + 0x22, 0x1d, 0x17, 0x11, 0x0e, 0x0d, 0x0c, 0x0b, 0x09, 0x04, 0x00, 0xfd, + 0xfa, 0xf7, 0xf6, 0xf6, 0xf7, 0xfb, 0x02, 0x13, 0x24, 0x30, 0x35, 0x30, + 0x23, 0x15, 0x08, 0x00, 0x00, 0x02, 0x04, 0x02, 0xfd, 0xf4, 0xea, 0xe3, + 0xe2, 0xe3, 0xe2, 0xe0, 0xde, 0xda, 0xd8, 0xd7, 0xd5, 0xd5, 0xd5, 0xd7, + 0xda, 0xe2, 0xf1, 0x05, 0x17, 0x23, 0x29, 0x24, 0x1c, 0x14, 0x0f, 0x0f, + 0x15, 0x1c, 0x21, 0x22, 0x1f, 0x19, 0x13, 0x0f, 0x0f, 0x0e, 0x0c, 0x0a, + 0x06, 0x02, 0xfe, 0xfb, 0xf7, 0xf6, 0xf6, 0xf6, 0xfa, 0x00, 0x0c, 0x1f, + 0x2d, 0x35, 0x33, 0x28, 0x18, 0x0c, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, + 0xf7, 0xee, 0xe6, 0xe3, 0xe3, 0xe2, 0xe0, 0xdf, 0xdc, 0xd7, 0xd7, 0xd5, + 0xd4, 0xd4, 0xd7, 0xd8, 0xdf, 0xec, 0x00, 0x12, 0x22, 0x2a, 0x26, 0x1e, + 0x15, 0x0e, 0x0b, 0x0f, 0x18, 0x20, 0x23, 0x22, 0x1c, 0x16, 0x12, 0x10, + 0x10, 0x0f, 0x0c, 0x08, 0x03, 0x00, 0xfd, 0xf8, 0xf6, 0xf5, 0xf6, 0xf7, + 0xfe, 0x08, 0x1a, 0x2a, 0x35, 0x35, 0x2c, 0x1d, 0x0f, 0x03, 0xff, 0x00, + 0x00, 0x02, 0x00, 0xfb, 0xf1, 0xe9, 0xe5, 0xe4, 0xe3, 0xe2, 0xe0, 0xdd, + 0xd9, 0xd7, 0xd5, 0xd4, 0xd4, 0xd6, 0xd7, 0xdc, 0xe8, 0xfa, 0x0b, 0x1c, + 0x27, 0x27, 0x20, 0x16, 0x0d, 0x09, 0x0b, 0x14, 0x1c, 0x21, 0x22, 0x1e, + 0x18, 0x15, 0x13, 0x12, 0x10, 0x0f, 0x0b, 0x05, 0x00, 0xfd, 0xfa, 0xf6, + 0xf5, 0xf5, 0xf6, 0xfb, 0x04, 0x14, 0x25, 0x33, 0x37, 0x30, 0x24, 0x15, + 0x06, 0xff, 0xfd, 0x00, 0x01, 0x00, 0xfc, 0xf4, 0xeb, 0xe7, 0xe4, 0xe3, + 0xe3, 0xe2, 0xde, 0xda, 0xd6, 0xd5, 0xd3, 0xd3, 0xd3, 0xd6, 0xda, 0xe3, + 0xf3, 0x04, 0x17, 0x24, 0x28, 0x22, 0x1a, 0x10, 0x09, 0x0a, 0x10, 0x19, + 0x21, 0x23, 0x21, 0x1c, 0x17, 0x15, 0x15, 0x13, 0x12, 0x0f, 0x00, 0x00, + 0x02, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xfd, 0xfe, 0x06, 0x0b, 0x07, 0x05, + 0x07, 0x06, 0xfd, 0xfe, 0x00, 0x03, 0x02, 0x01, 0x0b, 0x03, 0x01, 0xfe, + 0xff, 0x02, 0x07, 0x09, 0x07, 0x03, 0x03, 0x06, 0x0a, 0x05, 0x06, 0x07, + 0x07, 0x10, 0x0f, 0x07, 0x07, 0x06, 0x00, 0xff, 0x00, 0x09, 0x07, 0x06, + 0x06, 0x02, 0x00, 0xfa, 0xf9, 0xf9, 0xfe, 0xfa, 0xfd, 0xfe, 0x02, 0x03, + 0x0b, 0x06, 0x02, 0x01, 0x0a, 0x0e, 0x05, 0x02, 0x03, 0xff, 0xff, 0x00, + 0x00, 0x03, 0x07, 0x06, 0x05, 0x02, 0x00, 0x00, 0x03, 0x07, 0x07, 0x09, + 0x03, 0x00, 0xfb, 0xf7, 0xfa, 0xfb, 0xff, 0x02, 0x0a, 0x10, 0x07, 0x0d, + 0x0f, 0x0e, 0x03, 0x01, 0x00, 0xff, 0xfb, 0x01, 0xfe, 0x01, 0x02, 0x02, + 0x05, 0x07, 0x03, 0x06, 0x06, 0x06, 0x02, 0x01, 0x02, 0xff, 0x02, 0x05, + 0x0e, 0x12, 0x0d, 0x0a, 0x05, 0x03, 0x00, 0x01, 0x00, 0xff, 0xfb, 0xfb, + 0x02, 0x07, 0xf7, 0xfa, 0xfa, 0xf9, 0xfb, 0xfb, 0xff, 0xfb, 0x00, 0x00, + 0x05, 0x01, 0x01, 0x01, 0x06, 0x0b, 0x07, 0x05, 0x07, 0x0f, 0x10, 0x10, + 0x0a, 0x09, 0x07, 0x03, 0x06, 0x07, 0x00, 0xff, 0xfb, 0xf9, 0xf7, 0x00, + 0x03, 0xff, 0x07, 0x0a, 0x07, 0x02, 0x05, 0x05, 0x0a, 0x10, 0x0a, 0x0b, + 0x0b, 0x06, 0x00, 0x01, 0x01, 0x00, 0x00, 0x03, 0x09, 0x03, 0xff, 0xff, + 0xfd, 0xfa, 0xff, 0x01, 0x01, 0xfd, 0xfd, 0xfd, 0xfe, 0xff, 0xff, 0x00, + 0x07, 0x0a, 0x0b, 0x0b, 0x09, 0x06, 0x01, 0xfe, 0xfe, 0x03, 0x02, 0x05, + 0x0a, 0x0b, 0x09, 0x03, 0x09, 0x03, 0x00, 0x06, 0x03, 0x06, 0x07, 0x03, + 0xff, 0xfb, 0x02, 0x09, 0x0d, 0x0f, 0x0d, 0x07, 0x09, 0x0d, 0x07, 0x01, + 0xfe, 0xfa, 0xf7, 0xf6, 0xf7, 0x01, 0xfd, 0xfd, 0x00, 0x02, 0x05, 0x07, + 0x02, 0x05, 0x03, 0x02, 0x02, 0x02, 0x00, 0x02, 0x07, 0x0f, 0x0d, 0x09, + 0x0a, 0x05, 0x00, 0x05, 0x09, 0x0d, 0x05, 0xff, 0x00, 0x05, 0x00, 0xfe, + 0xf5, 0xf5, 0xf1, 0xf7, 0xfd, 0x01, 0x07, 0x07, 0x02, 0xfe, 0x0a, 0x0b, + 0x06, 0x0b, 0x0e, 0x0d, 0x09, 0x0e, 0x0e, 0x05, 0x03, 0x07, 0x06, 0x06, + 0x07, 0x07, 0x06, 0x07, 0x05, 0x01, 0xfd, 0xff, 0xff, 0x00, 0x01, 0x02, + 0x03, 0x01, 0xfe, 0x00, 0xfe, 0xfa, 0xff, 0x00, 0x02, 0x07, 0x07, 0x03, + 0x02, 0x00, 0xff, 0x03, 0x03, 0x02, 0x06, 0x03, 0x01, 0xfe, 0xfd, 0x01, + 0x06, 0xfe, 0x02, 0x05, 0x02, 0xfe, 0x02, 0x0d, 0x12, 0x14, 0x14, 0x0d, + 0x0b, 0x03, 0xfd, 0xfe, 0x00, 0xf7, 0xf5, 0xfa, 0xfb, 0x06, 0x0a, 0x07, + 0x09, 0x05, 0x06, 0x0a, 0x09, 0x0b, 0x05, 0x0a, 0x0d, 0x05, 0x00, 0xff, + 0x02, 0x03, 0x0a, 0x0b, 0x09, 0x03, 0xff, 0xff, 0x03, 0x05, 0xfe, 0xf5, + 0xf7, 0xf6, 0xf3, 0xfb, 0xf9, 0xf7, 0xf7, 0xf9, 0x05, 0x05, 0xff, 0x06, + 0x0d, 0x0a, 0x0e, 0x07, 0x07, 0x0d, 0x12, 0x0f, 0x0d, 0x09, 0x0b, 0x0a, + 0x0b, 0x0e, 0x06, 0x03, 0xfd, 0x01, 0x00, 0x01, 0x03, 0xff, 0xf9, 0xfd, + 0x00, 0xfb, 0xfd, 0xfe, 0xf9, 0xff, 0xff, 0xfd, 0x03, 0x06, 0x09, 0x07, + 0x03, 0x09, 0x0e, 0x0a, 0x0d, 0x07, 0x0b, 0x0b, 0x07, 0x02, 0x00, 0x02, + 0x03, 0x01, 0xff, 0xff, 0xfd, 0xfb, 0x05, 0x06, 0xff, 0x03, 0x01, 0x01, + 0x03, 0x07, 0x09, 0x03, 0x01, 0x00, 0xff, 0x01, 0x03, 0xfa, 0xfe, 0xfe, + 0xfa, 0xfe, 0x02, 0x0a, 0x0f, 0x0a, 0x05, 0x0d, 0x07, 0x06, 0x06, 0x09, + 0x02, 0x07, 0x01, 0x00, 0x00, 0x02, 0x10, 0x12, 0x0b, 0x05, 0x09, 0xfe, + 0xfe, 0x01, 0x05, 0xfb, 0xfe, 0x02, 0xff, 0x09, 0x06, 0xff, 0x01, 0xfe, + 0xfb, 0xff, 0xfe, 0xfd, 0xfe, 0x01, 0x07, 0x09, 0x09, 0x02, 0x06, 0x09, + 0x0e, 0x07, 0x02, 0x06, 0x01, 0x00, 0x09, 0x05, 0xfb, 0xf5, 0xf9, 0xfd, + 0xf7, 0xfb, 0xf7, 0x01, 0x07, 0x09, 0x09, 0x14, 0x0d, 0x0d, 0x06, 0x02, + 0x02, 0xff, 0x06, 0x07, 0x01, 0x02, 0x0a, 0x0a, 0x09, 0x0b, 0x0e, 0x0f, + 0x09, 0x06, 0x03, 0x02, 0x06, 0x09, 0x03, 0x02, 0xf9, 0xfe, 0xff, 0x02, + 0xff, 0xfe, 0x00, 0xf9, 0xfd, 0x05, 0x03, 0x03, 0x07, 0x05, 0x00, 0xfe, + 0xfd, 0xfd, 0x02, 0x01, 0xfd, 0xff, 0xfd, 0x05, 0x09, 0x0e, 0x0f, 0x07, + 0x06, 0x07, 0x09, 0x02, 0x06, 0x06, 0x0d, 0x01, 0x02, 0x02, 0x05, 0x00, + 0x12, 0x09, 0x00, 0xfb, 0x01, 0x02, 0x0e, 0x10, 0x02, 0xfd, 0xfd, 0xff, + 0x02, 0xff, 0xfe, 0xfb, 0x00, 0xfd, 0xf9, 0xff, 0x03, 0x01, 0x0d, 0x09, + 0x10, 0x0d, 0x07, 0x05, 0x0f, 0x14, 0x07, 0x00, 0x03, 0xff, 0xf9, 0xf3, + 0xf9, 0xfe, 0xfd, 0xfb, 0xfd, 0x07, 0x0b, 0xfd, 0x05, 0x05, 0x05, 0x10, + 0x0d, 0x03, 0xfb, 0xfe, 0x02, 0x03, 0x01, 0xfe, 0x03, 0x01, 0x07, 0x06, + 0x0e, 0x13, 0x0d, 0x0e, 0x0d, 0x01, 0x01, 0xff, 0x00, 0xff, 0xfd, 0xfe, + 0xf7, 0xfd, 0x01, 0x06, 0x05, 0x02, 0x06, 0x07, 0x03, 0x00, 0x02, 0x00, + 0x09, 0x0a, 0x00, 0x05, 0x02, 0xfe, 0xfe, 0x06, 0x01, 0x02, 0x00, 0x02, + 0x01, 0x09, 0x0e, 0x0d, 0x07, 0x05, 0xfd, 0x00, 0x06, 0xfe, 0xec, 0xfd, + 0xf9, 0xfe, 0xff, 0xff, 0x0d, 0x0d, 0xfe, 0x02, 0x06, 0x03, 0xfb, 0x0a, + 0x09, 0x00, 0x07, 0x09, 0x07, 0x0a, 0x0a, 0x0a, 0x01, 0x0a, 0x03, 0x06, + 0x06, 0x01, 0x03, 0x0e, 0x0b, 0x07, 0xff, 0x01, 0xfe, 0x03, 0x0a, 0x07, + 0xfb, 0xfa, 0x03, 0x09, 0x05, 0x00, 0x02, 0x00, 0xf7, 0xfe, 0xf9, 0xf7, + 0xf9, 0xfa, 0x07, 0x0a, 0x09, 0x03, 0x01, 0x0b, 0x05, 0x09, 0x0a, 0x01, + 0xfb, 0xfe, 0x02, 0x09, 0x14, 0x10, 0x10, 0x09, 0xfe, 0xf1, 0xf3, 0xf7, + 0xfd, 0xf6, 0x05, 0x09, 0xff, 0xfd, 0x09, 0x0e, 0x0a, 0x0d, 0x05, 0x06, + 0x02, 0xff, 0x0d, 0x0d, 0x0e, 0x0b, 0x17, 0x12, 0x0e, 0x06, 0x00, 0x02, + 0x00, 0xf7, 0xfe, 0x01, 0xfd, 0xff, 0xff, 0x03, 0x02, 0xfb, 0xfd, 0xf9, + 0x05, 0x0a, 0xff, 0xfd, 0x02, 0x00, 0xfa, 0xf6, 0x06, 0x02, 0x01, 0xfd, + 0xfd, 0x05, 0x0a, 0xfb, 0x01, 0x02, 0x10, 0x14, 0x12, 0x10, 0x12, 0x0d, + 0xff, 0xff, 0x01, 0x00, 0xfe, 0x01, 0x01, 0x00, 0x03, 0x00, 0x01, 0x06, + 0x07, 0x09, 0x0a, 0x09, 0x0e, 0x12, 0x00, 0xfa, 0x06, 0x03, 0x00, 0x01, + 0xfb, 0xff, 0x0a, 0x09, 0x02, 0x0f, 0x20, 0x14, 0x13, 0x13, 0x05, 0xfe, + 0xfb, 0xf9, 0xf7, 0xf7, 0xf1, 0xf1, 0xf5, 0xf5, 0x00, 0xfd, 0xfb, 0x06, + 0x0b, 0x05, 0x01, 0x00, 0x00, 0x02, 0x00, 0xf7, 0xf6, 0xf2, 0xf9, 0x01, + 0x02, 0x0d, 0x07, 0xff, 0x03, 0x1a, 0x1a, 0x13, 0x14, 0x0e, 0x0e, 0x14, + 0x12, 0x12, 0x0d, 0x06, 0x07, 0x06, 0xf9, 0xf0, 0xf9, 0x00, 0x03, 0x05, + 0x0d, 0x0b, 0x09, 0x02, 0xfb, 0xfd, 0x00, 0xfe, 0xfd, 0xfb, 0xf9, 0xf9, + 0xff, 0x07, 0x07, 0x07, 0x0e, 0x1b, 0x0e, 0x03, 0x00, 0x0b, 0x01, 0xfa, + 0xfe, 0xf6, 0xfe, 0x01, 0xfb, 0xfa, 0xff, 0xfb, 0xfa, 0xfa, 0x03, 0x02, + 0xf7, 0xf5, 0x05, 0x0e, 0x05, 0xfa, 0xf7, 0x03, 0x0b, 0x09, 0xfa, 0xfa, + 0x01, 0x0d, 0x0e, 0x02, 0x1b, 0x21, 0x20, 0x21, 0x14, 0x10, 0x0d, 0x13, + 0x10, 0x06, 0x10, 0x0e, 0x01, 0xf3, 0xed, 0xf3, 0xea, 0xf2, 0xf3, 0xfd, + 0x0d, 0x05, 0x00, 0x07, 0x07, 0x02, 0xfd, 0xf7, 0xf6, 0xf3, 0x01, 0x00, + 0x05, 0x0a, 0xff, 0x05, 0x1b, 0x16, 0x13, 0x09, 0x02, 0x06, 0xff, 0xfe, + 0x00, 0xfb, 0xf2, 0xfb, 0x03, 0x01, 0x09, 0x01, 0xf9, 0x00, 0xff, 0xfe, + 0xfb, 0x00, 0x03, 0x0b, 0x01, 0x02, 0x0a, 0x06, 0x05, 0x02, 0x0a, 0x0e, + 0x17, 0x0d, 0x05, 0x17, 0x23, 0x18, 0x0f, 0x10, 0x10, 0x0f, 0x12, 0x03, + 0x00, 0x01, 0x03, 0xfa, 0xf5, 0xf6, 0xfe, 0x05, 0x02, 0x00, 0xf9, 0xfa, + 0xf9, 0xf0, 0xf3, 0xfb, 0xf9, 0xf6, 0xf3, 0xf2, 0xf7, 0xf1, 0xf1, 0x02, + 0x0e, 0x1b, 0x13, 0x1f, 0x07, 0x00, 0x01, 0xfd, 0xfd, 0x06, 0x12, 0x13, + 0x0b, 0x07, 0x06, 0x06, 0x06, 0x02, 0x00, 0x01, 0x06, 0x0b, 0x00, 0xf7, + 0xfa, 0xfe, 0xff, 0xfe, 0x01, 0x03, 0x02, 0x03, 0x05, 0x00, 0x05, 0x10, + 0x06, 0x03, 0x0f, 0x34, 0x30, 0x28, 0x1d, 0x13, 0x0e, 0x0a, 0x07, 0x07, + 0x00, 0xfd, 0xfb, 0xf7, 0xec, 0xee, 0xed, 0xf0, 0xee, 0xf9, 0xfd, 0xf1, + 0xe5, 0xe5, 0xee, 0xf1, 0xee, 0xee, 0xf3, 0xf9, 0xfb, 0xfe, 0x03, 0x09, + 0x12, 0x1b, 0x24, 0x21, 0x1a, 0x1a, 0x16, 0x0e, 0x02, 0xfd, 0x01, 0x09, + 0x0d, 0x07, 0x0a, 0x0d, 0x06, 0x05, 0x0b, 0x0a, 0x01, 0xff, 0x05, 0x07, + 0x0f, 0x06, 0x0a, 0xfe, 0xf7, 0xf6, 0xf7, 0x02, 0xfb, 0xfa, 0x06, 0x01, + 0xff, 0x10, 0x23, 0x13, 0x0d, 0x06, 0x13, 0x17, 0x0b, 0xfd, 0xf6, 0xf0, + 0xf5, 0xf6, 0xf2, 0xf2, 0x02, 0xff, 0x06, 0x01, 0x00, 0x00, 0xfa, 0xf1, + 0xec, 0xed, 0xf7, 0xf5, 0x01, 0x06, 0x03, 0x02, 0xfe, 0x07, 0x07, 0x09, + 0x05, 0x1a, 0x18, 0x16, 0x16, 0x0d, 0x0a, 0x0a, 0x32, 0x31, 0x1d, 0x0e, + 0x07, 0x06, 0x09, 0x03, 0xff, 0xfe, 0x03, 0x00, 0xf3, 0xf0, 0xf6, 0xf7, + 0xf1, 0xf3, 0xfb, 0xf7, 0xf3, 0xf5, 0xee, 0xee, 0x00, 0x02, 0xfd, 0xfe, + 0x1c, 0x2c, 0x21, 0x17, 0x13, 0x1b, 0x13, 0x02, 0x05, 0x0e, 0x12, 0x0d, + 0xfb, 0xf5, 0xed, 0xed, 0xe4, 0xe8, 0xec, 0xfd, 0x05, 0xf7, 0xf5, 0xf7, + 0xf9, 0xf3, 0xf2, 0xf1, 0x0d, 0x17, 0x18, 0x1b, 0x14, 0x0b, 0x06, 0x0a, + 0x21, 0x21, 0x0f, 0x01, 0x00, 0x01, 0x00, 0x07, 0x06, 0x01, 0x03, 0x13, + 0x12, 0x0e, 0x02, 0x02, 0x09, 0x07, 0x03, 0x03, 0x0d, 0x17, 0x0f, 0x07, + 0xfe, 0xff, 0xfd, 0xf3, 0xf2, 0xf0, 0xec, 0x00, 0xfd, 0xf3, 0xf3, 0x03, + 0x07, 0x09, 0x00, 0xf3, 0xf5, 0xf9, 0xee, 0xee, 0xf7, 0xf1, 0xfe, 0x01, + 0x14, 0x3b, 0x28, 0x17, 0x12, 0x06, 0xf7, 0xfb, 0x06, 0x06, 0x02, 0xff, + 0xfb, 0x01, 0x06, 0x0b, 0x0d, 0x10, 0x0b, 0x0d, 0x03, 0x03, 0x0e, 0x1a, + 0x16, 0x0b, 0x03, 0xff, 0xfd, 0x13, 0x0a, 0x0b, 0x0b, 0x06, 0x07, 0xff, + 0xfe, 0xfb, 0x12, 0x17, 0x0e, 0xfe, 0xf6, 0xe9, 0xe5, 0xe9, 0xea, 0xe4, + 0xe3, 0xed, 0xee, 0xf1, 0x07, 0x05, 0x05, 0xfe, 0xfe, 0x13, 0x21, 0x25, + 0x21, 0x20, 0x24, 0x12, 0x0e, 0x10, 0x03, 0xfd, 0xf5, 0xf7, 0xfa, 0xf7, + 0xf3, 0xf5, 0xfa, 0xfe, 0x07, 0x00, 0x06, 0x06, 0x0a, 0x05, 0xfd, 0xfa, + 0xfa, 0x16, 0x16, 0x1a, 0x14, 0x14, 0x13, 0x01, 0xfb, 0x03, 0x10, 0x0f, + 0x0f, 0x06, 0x01, 0x00, 0xff, 0xfa, 0xfa, 0xf2, 0xec, 0xec, 0xe9, 0xf3, + 0x09, 0x0a, 0x03, 0x01, 0x09, 0x30, 0x30, 0x1b, 0x1a, 0x10, 0xea, 0xe3, + 0xe4, 0xf7, 0xf9, 0xee, 0xf6, 0x0b, 0x05, 0x02, 0x07, 0x10, 0x07, 0x05, + 0x02, 0xfe, 0x00, 0x09, 0x14, 0x0a, 0xf7, 0xee, 0xf5, 0x0b, 0x0b, 0xff, + 0x00, 0x06, 0x0b, 0x01, 0xf6, 0xfd, 0x0f, 0x1a, 0x0d, 0x0a, 0x06, 0x03, + 0xfd, 0x07, 0x13, 0x13, 0x10, 0x09, 0x05, 0x09, 0x2c, 0x1d, 0x07, 0x09, + 0x03, 0x12, 0x14, 0x09, 0xff, 0xff, 0xfb, 0xf3, 0xee, 0xf0, 0xec, 0xe5, + 0xe5, 0xe1, 0xec, 0xfa, 0xee, 0xdd, 0xd9, 0xe8, 0x12, 0x0a, 0xfe, 0xfe, + 0x10, 0x12, 0x05, 0x0d, 0x0a, 0x1b, 0x2c, 0x25, 0x2d, 0x28, 0x25, 0x24, + 0x1a, 0x17, 0x0b, 0x07, 0x07, 0x06, 0x02, 0x03, 0xfa, 0xe4, 0xe4, 0xe4, + 0xed, 0xea, 0xe5, 0xe9, 0x02, 0x03, 0xf6, 0xf1, 0xf2, 0x13, 0x34, 0x1d, + 0x1c, 0x23, 0x1d, 0x03, 0xfa, 0xfb, 0x01, 0x0b, 0x09, 0x06, 0x0d, 0x05, + 0x00, 0x00, 0xfb, 0xf9, 0xf2, 0xf2, 0xee, 0xf2, 0xfd, 0xfe, 0xfd, 0xff, + 0xfa, 0x09, 0x1c, 0x0b, 0x01, 0x09, 0x07, 0xf7, 0xe8, 0xf1, 0xf5, 0x0f, + 0x1d, 0x1d, 0x1d, 0x0a, 0x02, 0x00, 0x06, 0x12, 0x0e, 0x14, 0x0e, 0x0d, + 0x16, 0x14, 0x05, 0xfa, 0xf5, 0xfd, 0x13, 0x0e, 0x03, 0xfe, 0xfe, 0xf7, + 0xf6, 0xf3, 0xf6, 0xee, 0xea, 0xea, 0xee, 0xfb, 0xfa, 0xf6, 0xee, 0xf6, + 0x14, 0x25, 0x1a, 0x18, 0x1f, 0x1b, 0x23, 0x02, 0xff, 0x1a, 0x28, 0x17, + 0x0f, 0x12, 0x1a, 0x07, 0x02, 0xfe, 0xfd, 0xf2, 0xf0, 0xec, 0xec, 0xf1, + 0xfa, 0xec, 0xdf, 0xdf, 0xdc, 0xe3, 0xe5, 0xed, 0x05, 0xfa, 0xf3, 0xfd, + 0x06, 0x17, 0x3f, 0x2e, 0x2d, 0x3a, 0x32, 0x27, 0x25, 0x23, 0x21, 0x17, + 0x0f, 0x0f, 0x0e, 0x0e, 0x0b, 0x06, 0xf6, 0xe3, 0xe4, 0xe5, 0xe5, 0xee, + 0xf2, 0xf0, 0xec, 0xe8, 0xe3, 0xe5, 0xfe, 0xfa, 0xf9, 0x01, 0x07, 0x07, + 0xf9, 0xf1, 0xf1, 0x00, 0x1b, 0x31, 0x2a, 0x1d, 0x17, 0x17, 0x09, 0x02, + 0x01, 0x01, 0x03, 0x0f, 0x0f, 0x07, 0xfd, 0xfd, 0xff, 0x00, 0x0f, 0x0b, + 0x09, 0x0a, 0x00, 0xfd, 0xfe, 0xf3, 0xe5, 0xec, 0xed, 0xfb, 0x17, 0x0a, + 0x0d, 0x0a, 0xfe, 0xf9, 0x12, 0x21, 0x1c, 0x28, 0x2a, 0x1a, 0x06, 0xf2, + 0xf6, 0xf9, 0x0a, 0x0b, 0x09, 0x0b, 0x03, 0xf5, 0xf5, 0xf3, 0xed, 0xee, + 0xec, 0xee, 0xf0, 0xec, 0xe8, 0xee, 0xed, 0xf1, 0x02, 0x03, 0x05, 0x1c, + 0x1d, 0x0e, 0x06, 0x10, 0x09, 0x0a, 0x37, 0x37, 0x30, 0x2d, 0x29, 0x17, + 0x0e, 0x0a, 0xff, 0x00, 0xfd, 0xfa, 0xfa, 0xf3, 0xf5, 0xf0, 0xe6, 0xe5, + 0xe5, 0xe8, 0xf3, 0xf7, 0xf2, 0xed, 0xea, 0xf2, 0x00, 0x02, 0x0b, 0x0b, + 0x18, 0x20, 0x27, 0x1a, 0x0f, 0x14, 0x0f, 0x18, 0x20, 0x18, 0x1a, 0x14, + 0x0e, 0x0d, 0x09, 0xf1, 0xe4, 0xe9, 0xfd, 0xfe, 0xf9, 0xf3, 0xf2, 0xfa, + 0xf6, 0x01, 0x0a, 0xfb, 0xfd, 0x00, 0x05, 0x09, 0xee, 0xee, 0xf0, 0xf2, + 0xf5, 0x02, 0x17, 0x10, 0x13, 0x0f, 0x09, 0x02, 0x05, 0x17, 0x13, 0x12, + 0x16, 0x1d, 0x12, 0x00, 0xf7, 0x07, 0x18, 0x10, 0x13, 0x1c, 0x16, 0x0e, + 0x03, 0x01, 0xf6, 0xe4, 0xf1, 0xf9, 0x06, 0xfe, 0xf2, 0xf2, 0xf5, 0xf9, + 0xfa, 0x0a, 0x0e, 0x0a, 0x09, 0x03, 0xf5, 0xe4, 0xe1, 0xee, 0x12, 0x05, + 0x09, 0x20, 0x1b, 0x16, 0x0d, 0x00, 0xf7, 0xfa, 0xfa, 0x03, 0x05, 0x06, + 0x02, 0xff, 0xfe, 0xf9, 0xff, 0x14, 0x0d, 0x02, 0x00, 0xfd, 0xfa, 0x02, + 0x10, 0x0d, 0x0b, 0x21, 0x2d, 0x29, 0x18, 0x0a, 0x0d, 0x09, 0x03, 0x09, + 0x0f, 0x02, 0x05, 0x0a, 0xfe, 0xf3, 0xe5, 0xe1, 0xe3, 0xf1, 0xf1, 0xf2, + 0xf2, 0xf2, 0xf0, 0xf6, 0xfa, 0xff, 0x06, 0x01, 0x09, 0x07, 0x05, 0x12, + 0x0d, 0x0a, 0x09, 0x0a, 0x23, 0x21, 0x17, 0x18, 0x0f, 0x01, 0x05, 0x0a, + 0x07, 0x0b, 0x02, 0x03, 0xff, 0xfb, 0xf7, 0xf9, 0xf7, 0x00, 0x03, 0x06, + 0x10, 0x12, 0x0f, 0x0b, 0xf3, 0xee, 0xf0, 0xf0, 0xf3, 0xf3, 0x09, 0x10, + 0x07, 0x07, 0x05, 0x06, 0x12, 0x1b, 0x0e, 0x05, 0x00, 0xff, 0xf5, 0xf2, + 0xfb, 0x0a, 0x17, 0x0e, 0x17, 0x16, 0x06, 0x01, 0x00, 0x05, 0xff, 0xec, + 0xe1, 0x02, 0x12, 0x0a, 0xfb, 0xf6, 0xfa, 0x07, 0x12, 0x18, 0x1f, 0x16, + 0x0f, 0x06, 0xfa, 0xed, 0xf1, 0x00, 0x0a, 0x06, 0x0a, 0x03, 0xff, 0xf7, + 0xec, 0xed, 0xf6, 0x02, 0xff, 0x00, 0xff, 0xfa, 0x00, 0x03, 0x03, 0x0e, + 0x1f, 0x17, 0x17, 0x14, 0x0f, 0x06, 0x07, 0x06, 0x0a, 0x2c, 0x18, 0x0e, + 0x23, 0x1f, 0x10, 0x00, 0xff, 0xfd, 0xfb, 0x02, 0xfb, 0xf9, 0xfe, 0xfb, + 0xf1, 0xd3, 0xd2, 0xe1, 0xf3, 0xf1, 0xe8, 0xe9, 0xe4, 0xf1, 0xf9, 0xfb, + 0x0d, 0x1a, 0x0d, 0x0f, 0x21, 0x24, 0x17, 0x0e, 0x1b, 0x23, 0x18, 0x14, + 0x10, 0x10, 0x18, 0x0b, 0x0f, 0x09, 0x07, 0x0d, 0x16, 0x02, 0xf2, 0xfb, + 0xfb, 0xed, 0xe6, 0xe5, 0xec, 0x01, 0x0e, 0x06, 0x17, 0x1c, 0x1a, 0x02, + 0xf1, 0xf9, 0xfa, 0xf0, 0xe9, 0xec, 0xfe, 0x0b, 0x12, 0x14, 0x0a, 0x0e, + 0x05, 0x01, 0x03, 0x01, 0xff, 0xf9, 0xf5, 0xf3, 0xf5, 0x0e, 0x09, 0x09, + 0x14, 0x18, 0x0e, 0x02, 0xf7, 0xf7, 0xfd, 0x0a, 0x03, 0x07, 0x09, 0x0d, + 0x09, 0xff, 0x00, 0x0e, 0x0d, 0x02, 0x0d, 0x1b, 0x23, 0x1d, 0x07, 0xf6, + 0xf9, 0x0d, 0x03, 0x02, 0x00, 0x06, 0xff, 0xfb, 0xf6, 0xf7, 0xfa, 0xfa, + 0xf7, 0xf6, 0xf7, 0xf9, 0xf3, 0xed, 0xf2, 0xfe, 0x14, 0x17, 0x18, 0x16, + 0x07, 0x01, 0xfd, 0xf3, 0xfe, 0x1d, 0x24, 0x14, 0x12, 0x27, 0x1a, 0x09, + 0x01, 0x02, 0x01, 0x09, 0x01, 0xfe, 0xff, 0x01, 0x06, 0xf7, 0xfe, 0xfb, + 0xf5, 0xf0, 0xe4, 0xe8, 0xe4, 0xe0, 0xe3, 0xea, 0xf6, 0x0e, 0x1c, 0x1a, + 0x13, 0x16, 0x12, 0x09, 0x07, 0x0d, 0x10, 0x23, 0x21, 0x1d, 0x20, 0x18, + 0x24, 0x24, 0x20, 0x16, 0x0a, 0x05, 0xf9, 0xee, 0xf2, 0xea, 0xea, 0xec, + 0xf7, 0x05, 0x01, 0xfa, 0xf1, 0xfb, 0x03, 0xfd, 0xec, 0xe3, 0xe3, 0xf7, + 0xfb, 0xf0, 0xf2, 0xf1, 0xfe, 0x0b, 0x1d, 0x1b, 0x14, 0x14, 0x10, 0x1a, + 0x1a, 0x12, 0x0f, 0x03, 0x01, 0x14, 0x16, 0x0e, 0x05, 0x0a, 0x10, 0x05, + 0xfe, 0xfb, 0xf9, 0xf5, 0xff, 0xfd, 0xf7, 0xf3, 0xf0, 0xff, 0x02, 0xff, + 0x0b, 0x18, 0x0e, 0x1a, 0x18, 0x16, 0x0b, 0x00, 0x01, 0x12, 0x0a, 0x0b, + 0x03, 0x07, 0x10, 0x01, 0xfa, 0xf2, 0xf3, 0xf0, 0xf1, 0xf3, 0xf2, 0xf1, + 0xee, 0xfb, 0xfe, 0x00, 0x01, 0x01, 0x00, 0xff, 0xfd, 0x07, 0x05, 0xfd, + 0xff, 0x1d, 0x36, 0x34, 0x1d, 0x12, 0x14, 0x0f, 0x09, 0x01, 0x00, 0x01, + 0x0b, 0x10, 0x07, 0x06, 0xff, 0x09, 0x02, 0x02, 0xff, 0xf5, 0xec, 0xec, + 0xe5, 0xe1, 0xe0, 0xf2, 0x0e, 0x18, 0x0b, 0x06, 0xff, 0x05, 0x0e, 0x02, + 0xfb, 0xfd, 0x0a, 0x21, 0x21, 0x1d, 0x1b, 0x16, 0x0a, 0x17, 0x18, 0x10, + 0x03, 0xfe, 0x0b, 0x02, 0xf1, 0xe9, 0xe9, 0xed, 0xfd, 0x02, 0xfa, 0xfb, + 0x02, 0x00, 0x09, 0x09, 0xfe, 0xfb, 0xf9, 0xf9, 0xfa, 0xf2, 0xec, 0xec, + 0xf2, 0x05, 0x10, 0x10, 0x14, 0x1d, 0x1a, 0x10, 0x0b, 0x0a, 0x05, 0x07, + 0x14, 0x12, 0x09, 0x0b, 0x0e, 0x0d, 0x16, 0x12, 0x10, 0x0b, 0x07, 0x01, + 0xf7, 0xff, 0x03, 0xe6, 0xe4, 0xf5, 0x03, 0x02, 0xff, 0x05, 0x00, 0xfb, + 0x02, 0x06, 0xf9, 0xf5, 0x05, 0x1a, 0x1b, 0x0d, 0x01, 0xf5, 0xf9, 0xfa, + 0xf3, 0xf3, 0xf6, 0xf9, 0xfe, 0x03, 0x01, 0x06, 0x0a, 0x0d, 0x13, 0x07, + 0x06, 0x0a, 0x09, 0x07, 0xff, 0xfb, 0xfa, 0xfe, 0x0e, 0x1b, 0x0f, 0x10, + 0x18, 0x13, 0xf9, 0xfd, 0x03, 0x0a, 0x0a, 0x14, 0x0f, 0x07, 0x05, 0x09, + 0x14, 0x0f, 0x05, 0xfd, 0xf7, 0xfb, 0xfe, 0xff, 0xec, 0xea, 0xf1, 0xfb, + 0x02, 0x07, 0xff, 0xf6, 0xf3, 0xf9, 0xf7, 0xfb, 0x03, 0x0a, 0x0b, 0x0f, + 0x09, 0x03, 0x01, 0x02, 0x0a, 0x1c, 0x29, 0x1d, 0x1a, 0x1f, 0x1f, 0x13, + 0xfe, 0xe9, 0xed, 0xf1, 0xf7, 0x02, 0xfd, 0xf7, 0xfe, 0x06, 0x09, 0x0d, + 0x0d, 0x06, 0xfb, 0xf3, 0xf3, 0xf5, 0xf1, 0xec, 0xee, 0xfe, 0x0f, 0x18, + 0x0b, 0x07, 0x10, 0x1a, 0x12, 0x07, 0x0a, 0x09, 0x0a, 0x0f, 0x18, 0x14, + 0x07, 0x03, 0x02, 0x09, 0x0f, 0x03, 0xfe, 0xf9, 0xf3, 0x00, 0x00, 0xfd, + 0xf3, 0xf3, 0xfb, 0xfa, 0xf1, 0xf1, 0xf7, 0xfb, 0x02, 0x10, 0x10, 0x03, + 0x0d, 0x0f, 0x09, 0x12, 0x0d, 0x0b, 0x00, 0xf3, 0xff, 0xff, 0x00, 0x02, + 0x00, 0xfd, 0xff, 0x00, 0x01, 0x09, 0x07, 0x07, 0x07, 0x06, 0x0b, 0x0a, + 0x07, 0x09, 0x0a, 0x02, 0x03, 0x0f, 0x0d, 0x12, 0x18, 0x18, 0x06, 0xfa, + 0xfb, 0x06, 0x12, 0x06, 0x01, 0xfe, 0x01, 0x00, 0xff, 0x07, 0x06, 0x05, + 0xf7, 0xfe, 0x02, 0x00, 0xf7, 0xf1, 0xe4, 0xe0, 0xe1, 0xfa, 0xf9, 0xf2, + 0xfe, 0x07, 0x06, 0x01, 0x0d, 0x0f, 0x0f, 0x0d, 0x17, 0x1a, 0x12, 0x07, + 0x09, 0x12, 0x20, 0x25, 0x1b, 0x16, 0x14, 0x0b, 0x05, 0x02, 0xf9, 0xe1, + 0xe6, 0xf9, 0xfd, 0x00, 0xff, 0x02, 0xfb, 0xfd, 0x0f, 0x16, 0x0e, 0xff, + 0xed, 0xe9, 0xf0, 0x02, 0xfe, 0xf7, 0x03, 0x0b, 0x14, 0x18, 0x0d, 0x06, + 0x0b, 0x10, 0x06, 0x01, 0xfe, 0x10, 0x09, 0x03, 0x01, 0x06, 0xfe, 0xf7, + 0x03, 0x09, 0x02, 0x02, 0x0d, 0x05, 0xfb, 0xfb, 0x00, 0x03, 0xfe, 0xff, + 0x01, 0xfb, 0xf2, 0xf5, 0x0a, 0x0e, 0x09, 0x0a, 0x0f, 0x14, 0x13, 0x06, + 0x0a, 0x0b, 0x09, 0xfd, 0xfe, 0xfb, 0xfd, 0xff, 0xfe, 0xf9, 0xf5, 0xfe, + 0x0d, 0x09, 0x0e, 0x10, 0x0d, 0x09, 0x0b, 0x0d, 0x14, 0x0b, 0x01, 0xfa, + 0xf7, 0xfd, 0x00, 0xfe, 0xff, 0x01, 0x09, 0x09, 0x13, 0x0e, 0xfd, 0x03, + 0x09, 0xff, 0xfd, 0xfa, 0xfb, 0xfe, 0x09, 0x14, 0x14, 0x09, 0xff, 0xfa, + 0x05, 0x07, 0x00, 0xf1, 0xe0, 0xe5, 0xf1, 0x02, 0x06, 0x02, 0xfe, 0xfa, + 0x07, 0x0b, 0x07, 0x09, 0x03, 0xfb, 0x02, 0x10, 0x1a, 0x13, 0x16, 0x2a, + 0x2a, 0x21, 0x1d, 0x21, 0x10, 0x03, 0x01, 0xf9, 0xee, 0xea, 0xfd, 0xfb, + 0xfa, 0xfe, 0x02, 0xfd, 0xfd, 0x01, 0xff, 0x01, 0xff, 0xfd, 0xed, 0xec, + 0xed, 0xf5, 0xfd, 0x05, 0xfd, 0xfa, 0xfb, 0xff, 0x0a, 0x14, 0x14, 0x0e, + 0x09, 0x0d, 0x1b, 0x14, 0x10, 0x10, 0x0a, 0x07, 0x0b, 0x0d, 0x02, 0x06, + 0x0a, 0x03, 0xfb, 0xf6, 0xfd, 0xf9, 0x01, 0x13, 0xfd, 0xf1, 0xfa, 0x02, + 0xff, 0xfe, 0xfe, 0xff, 0xfa, 0x07, 0x18, 0x13, 0x07, 0x02, 0x12, 0x13, + 0x16, 0x17, 0x06, 0xff, 0xfe, 0xfa, 0xfa, 0xf7, 0xf6, 0xfa, 0x00, 0x14, + 0x0e, 0x0d, 0x05, 0x00, 0xff, 0x02, 0x03, 0xfe, 0xf5, 0xe9, 0xf1, 0xf9, + 0x0a, 0x0b, 0xfb, 0xfa, 0x0b, 0x18, 0x17, 0x0d, 0x00, 0x02, 0xfe, 0x05, + 0x0f, 0x0e, 0x0d, 0x17, 0x17, 0x17, 0x12, 0x0e, 0x06, 0xf2, 0xf6, 0xfd, + 0xf0, 0xe1, 0xe8, 0xf3, 0xf0, 0xf7, 0x01, 0x00, 0x0a, 0x13, 0x0b, 0x03, + 0x06, 0x05, 0x03, 0x00, 0x09, 0x12, 0x16, 0x1f, 0x25, 0x1d, 0x16, 0x13, + 0x07, 0x09, 0x06, 0x05, 0xf9, 0xf9, 0xfb, 0xf6, 0xf1, 0xf5, 0xff, 0xf6, + 0xfd, 0xff, 0xf5, 0xf7, 0x02, 0x03, 0xfa, 0xfb, 0xf5, 0xff, 0x05, 0x0b, + 0x05, 0xfa, 0xf7, 0x0a, 0x0e, 0x07, 0x06, 0x0a, 0x13, 0x0f, 0x0b, 0x13, + 0x09, 0x03, 0x0a, 0x0e, 0x17, 0x17, 0x0e, 0x07, 0x03, 0x06, 0x05, 0x01, + 0x00, 0x00, 0x01, 0xff, 0x0a, 0x07, 0xff, 0xfd, 0xfe, 0xff, 0xfe, 0xfa, + 0xf3, 0xf1, 0xf3, 0x06, 0x06, 0x0e, 0x0d, 0x10, 0x16, 0x17, 0x0e, 0xfd, + 0xf3, 0xf1, 0xec, 0xed, 0xfa, 0xfd, 0x03, 0x0b, 0x10, 0x12, 0x12, 0x0f, + 0x0a, 0x06, 0x01, 0x00, 0x01, 0xfd, 0xfb, 0x0a, 0x0a, 0x05, 0x09, 0x03, + 0x06, 0x06, 0x02, 0x0b, 0x03, 0x00, 0xfb, 0x02, 0x09, 0x09, 0x07, 0x0b, + 0x09, 0x09, 0x0f, 0x13, 0x09, 0x0d, 0x0b, 0x05, 0xff, 0xf6, 0xf2, 0xf5, + 0xf7, 0xf2, 0xf9, 0xfe, 0x02, 0x0a, 0x07, 0x05, 0x05, 0x05, 0x01, 0xfd, + 0xff, 0xff, 0x0a, 0x07, 0x0b, 0x13, 0x14, 0x13, 0x0f, 0x06, 0x05, 0x05, + 0xf7, 0xf6, 0xf7, 0xfb, 0x03, 0xf7, 0xfb, 0x06, 0x0b, 0x14, 0x09, 0x03, + 0xfb, 0x00, 0xff, 0xfb, 0x02, 0x07, 0x10, 0x07, 0xfd, 0xfa, 0xf5, 0xfd, + 0x00, 0xfe, 0x00, 0xff, 0x06, 0x0e, 0x13, 0x13, 0x1a, 0x0a, 0x0f, 0x0e, + 0x0f, 0x16, 0x0e, 0x0a, 0xff, 0xff, 0xff, 0xfe, 0x03, 0x01, 0x05, 0xfb, + 0xf9, 0xfd, 0x02, 0x0b, 0x07, 0xf5, 0xfb, 0xff, 0xf3, 0xea, 0xea, 0xee, + 0xfa, 0x02, 0x12, 0x0f, 0x1f, 0x29, 0x1c, 0x10, 0x03, 0xfa, 0xf6, 0xf9, + 0x00, 0x01, 0xff, 0xfb, 0x02, 0x02, 0x09, 0x0e, 0x0d, 0x0d, 0x05, 0x00, + 0xfb, 0xf7, 0xfa, 0x00, 0x0d, 0x0b, 0x05, 0x06, 0x12, 0x1d, 0x07, 0x02, + 0x06, 0x06, 0x06, 0x12, 0x0d, 0x06, 0x0d, 0x07, 0x01, 0xff, 0xfd, 0x05, + 0x03, 0x03, 0x02, 0x00, 0xfb, 0xfe, 0xfa, 0xed, 0xe3, 0xec, 0xf6, 0xfe, + 0xfe, 0x02, 0x06, 0x06, 0x0b, 0x0f, 0x0e, 0x07, 0x06, 0x0e, 0x06, 0x05, + 0x09, 0x0d, 0x17, 0x20, 0x17, 0x18, 0x12, 0x0b, 0xfd, 0xf2, 0xf1, 0xf7, + 0xf9, 0xfb, 0xfb, 0xff, 0xff, 0x07, 0x06, 0x00, 0xf9, 0xf6, 0xf9, 0x03, + 0x12, 0x10, 0x0e, 0x18, 0x14, 0x0f, 0x06, 0xfb, 0xfd, 0xfe, 0xfd, 0xff, + 0xfd, 0x03, 0x0b, 0x07, 0x03, 0x07, 0x0a, 0x0e, 0x18, 0x13, 0x0d, 0x02, + 0xfb, 0xfd, 0xf6, 0xf6, 0xff, 0x03, 0xfa, 0xee, 0xf7, 0xfa, 0xf9, 0xfd, + 0x02, 0x0f, 0x12, 0x0a, 0x00, 0x00, 0xfe, 0xfa, 0xfb, 0xfe, 0x00, 0x05, + 0x1d, 0x2e, 0x2c, 0x1c, 0x13, 0x0b, 0xfd, 0xf3, 0xfe, 0xff, 0xff, 0xf7, + 0xf6, 0xf7, 0x00, 0x07, 0x0d, 0x0b, 0x0a, 0x09, 0xfe, 0xf9, 0xf7, 0xf2, + 0xf7, 0xfe, 0x09, 0x13, 0x18, 0x0b, 0x03, 0x02, 0x01, 0x02, 0x03, 0x0a, + 0x1b, 0x1d, 0x1b, 0x07, 0x03, 0x01, 0xfd, 0xf7, 0xf5, 0xf9, 0x00, 0x00, + 0x03, 0xfe, 0xf9, 0xfa, 0xf5, 0xf3, 0xf6, 0xf2, 0x00, 0x07, 0x03, 0x05, + 0x06, 0x02, 0x00, 0x0d, 0x16, 0x0e, 0x0f, 0x09, 0x06, 0x02, 0x02, 0x12, + 0x1b, 0x10, 0x16, 0x16, 0x06, 0x06, 0x06, 0x00, 0xf9, 0xf5, 0xfa, 0x03, + 0x0b, 0x0d, 0x10, 0x02, 0xfa, 0xfa, 0xfd, 0x02, 0xf9, 0xf5, 0x00, 0x06, + 0x05, 0x03, 0xfd, 0xfa, 0xf5, 0x00, 0x05, 0xff, 0xf6, 0xf3, 0xfd, 0x07, + 0x07, 0x0a, 0x09, 0x13, 0x24, 0x29, 0x23, 0x12, 0x07, 0x02, 0xfd, 0x00, + 0x00, 0x06, 0x03, 0xf5, 0xf6, 0xf6, 0xf2, 0xf9, 0xfe, 0x00, 0x00, 0x02, + 0x02, 0xff, 0xf6, 0xed, 0xea, 0xea, 0xfa, 0x0f, 0x1d, 0x27, 0x34, 0x2d, + 0x23, 0x20, 0x1b, 0x12, 0x0e, 0x0a, 0x0b, 0xff, 0xfb, 0xfb, 0xf5, 0xf2, + 0xf5, 0xfa, 0xfe, 0x01, 0x01, 0xfb, 0xfa, 0xf3, 0xfa, 0xfe, 0xf9, 0xf7, + 0x06, 0xfe, 0xff, 0x02, 0xfb, 0xf9, 0xff, 0x07, 0x1a, 0x1f, 0x1c, 0x1b, + 0x17, 0x16, 0x0b, 0x06, 0x07, 0x02, 0xff, 0x05, 0x01, 0x00, 0xfb, 0xf7, + 0xfb, 0xf6, 0xea, 0xee, 0x06, 0x0d, 0x03, 0xf7, 0xfe, 0x03, 0x10, 0x0f, + 0x0a, 0x01, 0xfb, 0x00, 0x0b, 0x0b, 0x00, 0xfd, 0x07, 0x18, 0x18, 0x17, + 0x0d, 0x09, 0x07, 0x01, 0xfd, 0xfa, 0xfb, 0xfe, 0x13, 0x1a, 0x10, 0x0a, + 0x0a, 0x06, 0x00, 0xf5, 0xee, 0xf2, 0xfe, 0xff, 0xfb, 0xff, 0x01, 0x03, + 0xfe, 0xf1, 0xee, 0xf2, 0xf7, 0xfe, 0x00, 0xff, 0xfe, 0xfb, 0x0b, 0x16, + 0x24, 0x2c, 0x25, 0x1a, 0x14, 0x1a, 0x14, 0x05, 0xff, 0xff, 0xff, 0xfa, + 0xfe, 0x09, 0x05, 0xfa, 0xf2, 0xfb, 0xff, 0x01, 0x03, 0xfe, 0xfe, 0xfe, + 0xfb, 0xf2, 0xee, 0xf6, 0x02, 0x0b, 0x13, 0x16, 0x14, 0x16, 0x18, 0x13, + 0x16, 0x0f, 0x0a, 0x09, 0x0a, 0x05, 0xfe, 0xf5, 0xf3, 0xf5, 0xfa, 0x02, + 0x02, 0xfe, 0x00, 0xfe, 0x01, 0xfd, 0xf6, 0xf7, 0x03, 0x07, 0x07, 0xfa, + 0xfe, 0x06, 0x06, 0x02, 0x05, 0x07, 0x0d, 0x09, 0x06, 0x0e, 0x12, 0x0a, + 0x03, 0x05, 0x02, 0x05, 0x0d, 0x09, 0x03, 0x02, 0x02, 0x01, 0xfe, 0xfa, + 0x0b, 0x0f, 0x14, 0x0d, 0x0e, 0x0f, 0x06, 0xfb, 0xf6, 0xf9, 0xf6, 0xf5, + 0xfb, 0xff, 0x03, 0x05, 0x03, 0x0f, 0x0a, 0x02, 0xf7, 0xf9, 0xfb, 0x01, + 0xfe, 0xf6, 0xfa, 0x03, 0x0e, 0x12, 0x14, 0x12, 0x13, 0x14, 0x0b, 0x0f, + 0x0a, 0x02, 0x00, 0x02, 0x05, 0x03, 0xff, 0xff, 0xfe, 0xf3, 0xe6, 0xed, + 0xf2, 0xf2, 0xf9, 0x05, 0x0a, 0x02, 0xfb, 0x09, 0x1c, 0x21, 0x17, 0x14, + 0x14, 0x18, 0x14, 0x0d, 0x0d, 0x0a, 0x03, 0xfb, 0xfe, 0xfb, 0xff, 0x01, + 0xfd, 0xff, 0x05, 0x00, 0x01, 0x00, 0x00, 0xff, 0xfd, 0xf6, 0xf2, 0xf3, + 0x02, 0x03, 0x03, 0x14, 0x24, 0x1a, 0x0e, 0x0a, 0x0b, 0x09, 0x06, 0x05, + 0x02, 0x01, 0xf9, 0xfa, 0xfb, 0xfd, 0xfb, 0xfb, 0x00, 0xff, 0xfd, 0x01, + 0x07, 0x05, 0x01, 0x06, 0x17, 0x10, 0xff, 0xfb, 0x03, 0x07, 0x07, 0x01, + 0x00, 0x02, 0x0a, 0x12, 0x0f, 0x16, 0x13, 0x0b, 0x07, 0x07, 0x0b, 0x07, + 0x05, 0xfb, 0xf2, 0xee, 0xec, 0xf2, 0xfe, 0x07, 0x09, 0x06, 0x06, 0x09, + 0x1a, 0x14, 0x0a, 0x09, 0x0d, 0x0a, 0xfd, 0xf9, 0xfa, 0xf9, 0xfb, 0xfa, + 0xfb, 0xfd, 0x06, 0x0d, 0x05, 0xf9, 0xf9, 0xff, 0x00, 0x05, 0xff, 0x06, + 0x18, 0x0d, 0x03, 0xff, 0x07, 0x0a, 0xff, 0x03, 0x0d, 0x0d, 0x0a, 0x13, + 0x0e, 0x03, 0x02, 0x09, 0x0a, 0x07, 0x06, 0xf9, 0xf7, 0xf9, 0xf9, 0xfd, + 0xfe, 0x05, 0x0d, 0x0d, 0x16, 0x0b, 0x03, 0x06, 0x1b, 0x20, 0x14, 0x0e, + 0x05, 0x02, 0xff, 0xfe, 0xf1, 0xe8, 0xec, 0xee, 0xee, 0xf6, 0x06, 0x02, + 0x00, 0xfe, 0xff, 0xfb, 0xfd, 0x03, 0x05, 0x0a, 0x13, 0x0d, 0x0a, 0x0b, + 0x12, 0x1b, 0x13, 0x0e, 0x0e, 0x09, 0x05, 0xfb, 0x01, 0x03, 0x06, 0x06, + 0x01, 0xfd, 0xfd, 0x00, 0xff, 0xf6, 0xf9, 0xf6, 0xf7, 0xfb, 0xff, 0x14, + 0x1b, 0x12, 0x07, 0xfe, 0x00, 0x02, 0x07, 0x09, 0x03, 0x01, 0x05, 0x03, + 0x0a, 0x0e, 0x09, 0x07, 0x06, 0x01, 0x01, 0x02, 0x05, 0x06, 0x09, 0x09, + 0xff, 0xfa, 0xfd, 0x01, 0x0e, 0x07, 0xf9, 0xf9, 0x02, 0x01, 0x00, 0x00, + 0x02, 0x09, 0x09, 0x02, 0xf7, 0xf2, 0xf9, 0x03, 0x06, 0x0a, 0x02, 0x03, + 0x0a, 0x09, 0x02, 0xfa, 0xfd, 0xfe, 0x00, 0x07, 0x18, 0x18, 0x0e, 0x09, + 0x14, 0x13, 0x0a, 0x09, 0x06, 0x02, 0x03, 0x03, 0x05, 0x01, 0xfe, 0xfe, + 0xf6, 0xee, 0xf9, 0x00, 0x01, 0xf3, 0xf2, 0xf6, 0x00, 0x07, 0x0e, 0x16, + 0x23, 0x20, 0x14, 0x0e, 0x0e, 0x07, 0x01, 0x09, 0x0e, 0x07, 0xff, 0xfd, + 0xf7, 0xf3, 0xf6, 0xf6, 0xf0, 0xf6, 0xf7, 0xfb, 0x00, 0xfb, 0xff, 0xfb, + 0xfa, 0xf3, 0xee, 0xfa, 0x0e, 0x14, 0x13, 0x0e, 0x12, 0x10, 0x1c, 0x2e, + 0x29, 0x17, 0x12, 0x14, 0x06, 0xff, 0x02, 0x00, 0x02, 0x02, 0x02, 0x00, + 0xfe, 0xfa, 0xfb, 0xf7, 0xf9, 0xf9, 0xff, 0x09, 0x09, 0x09, 0x05, 0xff, + 0x00, 0xf3, 0xea, 0xee, 0xf7, 0x00, 0x00, 0x01, 0xff, 0xfe, 0x0d, 0x0f, + 0x12, 0x0d, 0x0b, 0x0a, 0x06, 0x02, 0x05, 0x0a, 0x09, 0x07, 0x07, 0x07, + 0x09, 0x0f, 0x09, 0x01, 0xff, 0x07, 0x05, 0x05, 0x03, 0x0e, 0x07, 0x01, + 0xfe, 0xfb, 0xfe, 0xf9, 0xf2, 0xf6, 0xfe, 0x03, 0xfd, 0x03, 0x0d, 0x06, + 0xff, 0x05, 0x0f, 0x0b, 0x09, 0x13, 0x0e, 0x0d, 0x0f, 0x0d, 0x03, 0x02, + 0xff, 0x03, 0x01, 0xff, 0xf7, 0xfd, 0x0e, 0x0e, 0x05, 0x05, 0x05, 0x03, + 0xfe, 0xfa, 0xff, 0xf2, 0xf1, 0xf6, 0xf6, 0xf3, 0x00, 0x1b, 0x18, 0x16, + 0x12, 0x0f, 0x09, 0x0e, 0x0b, 0x0b, 0x0b, 0x09, 0x05, 0xff, 0xfb, 0xfa, + 0xf5, 0xf5, 0xf6, 0xf6, 0xf7, 0x02, 0x03, 0x03, 0x07, 0x06, 0x06, 0x03, + 0x06, 0x12, 0x0d, 0x0a, 0x09, 0x09, 0x05, 0xff, 0x02, 0x0b, 0x1a, 0x14, + 0x05, 0x06, 0x06, 0x00, 0x09, 0x03, 0x06, 0x05, 0x05, 0x06, 0x07, 0x06, + 0xfe, 0xf7, 0xfa, 0xfb, 0xfe, 0x09, 0x01, 0x01, 0xfb, 0x00, 0xfb, 0xf2, + 0xf6, 0xf7, 0xfd, 0x06, 0xff, 0xfa, 0xf7, 0xfa, 0x05, 0x02, 0x05, 0x05, + 0x07, 0x05, 0x07, 0x0d, 0x0b, 0x0e, 0x18, 0x18, 0x1c, 0x23, 0x24, 0x1c, + 0x0d, 0x07, 0xfe, 0xfb, 0x00, 0x02, 0x00, 0xff, 0xfe, 0xfe, 0x00, 0x01, + 0xfd, 0xfd, 0x02, 0xff, 0xf6, 0xf7, 0x00, 0xff, 0x00, 0xfe, 0xf5, 0xf5, + 0xf6, 0x09, 0x17, 0x0d, 0x05, 0x06, 0x12, 0x13, 0x0b, 0x06, 0x06, 0x05, + 0x00, 0xfe, 0xfb, 0xfe, 0x02, 0x02, 0x05, 0x02, 0xfd, 0xfe, 0x03, 0x02, + 0x02, 0x02, 0x02, 0x01, 0xff, 0x09, 0x14, 0x1b, 0x13, 0x0a, 0x0a, 0x0a, + 0x02, 0xfe, 0x01, 0x06, 0x05, 0x00, 0xff, 0x07, 0x0e, 0x06, 0xff, 0xfb, + 0xf6, 0xfb, 0xfe, 0xfe, 0xfe, 0xff, 0x00, 0x00, 0x02, 0x02, 0x07, 0x00, + 0x03, 0x06, 0x09, 0x0d, 0x0b, 0x0b, 0x0f, 0x18, 0x1a, 0x16, 0x0e, 0x03, + 0xfe, 0xf3, 0xf5, 0xf2, 0xf6, 0x00, 0x05, 0x02, 0xff, 0x09, 0x0e, 0x09, + 0x01, 0xfb, 0x06, 0x0d, 0x0a, 0x03, 0xfe, 0xfb, 0xfb, 0xf5, 0xf3, 0xf5, + 0xfb, 0xff, 0x02, 0x03, 0x0b, 0x0f, 0x14, 0x0f, 0x0b, 0x0d, 0x0a, 0x06, + 0x03, 0x02, 0x05, 0x01, 0x00, 0x01, 0x18, 0x20, 0x1a, 0x14, 0x0f, 0x18, + 0x03, 0xf9, 0xfe, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0xfe, 0xfd, 0x01, + 0xf6, 0xf2, 0xf3, 0xf5, 0xf3, 0xfa, 0x0d, 0x0a, 0x00, 0xfa, 0x00, 0x0d, + 0x0a, 0x07, 0xff, 0xfb, 0xfb, 0xf7, 0xff, 0x02, 0x12, 0x0f, 0x05, 0x01, + 0x07, 0x10, 0x13, 0x0d, 0x05, 0x05, 0x14, 0x14, 0x0e, 0x07, 0x06, 0x02, + 0xfa, 0xf7, 0xfb, 0x06, 0x09, 0x13, 0x0d, 0x0d, 0x0f, 0x05, 0x06, 0x00, + 0x05, 0x09, 0x06, 0x01, 0xfa, 0xf3, 0xf6, 0xf3, 0xf3, 0xf2, 0x00, 0xfe, + 0xfe, 0x00, 0x09, 0x0b, 0x05, 0x01, 0x02, 0x0a, 0x09, 0x06, 0x02, 0xfe, + 0xff, 0xfd, 0xff, 0x01, 0x03, 0x0f, 0x13, 0x14, 0x13, 0x13, 0x1a, 0x03, + 0xfd, 0x00, 0x06, 0x09, 0x00, 0xfb, 0xfe, 0x00, 0xfb, 0xff, 0xff, 0x0d, + 0x13, 0x0b, 0x06, 0x00, 0x03, 0x03, 0x02, 0x00, 0xf7, 0xfa, 0x03, 0x05, + 0xff, 0xf7, 0xf7, 0x00, 0x07, 0x0b, 0x09, 0x01, 0xff, 0x01, 0x0a, 0x10, + 0x09, 0x02, 0x09, 0x1b, 0x1f, 0x1c, 0x13, 0x05, 0x05, 0x03, 0xf9, 0xe6, + 0xf0, 0x02, 0x09, 0x05, 0x02, 0x01, 0xff, 0xff, 0xfd, 0x00, 0xfe, 0xfb, + 0xfa, 0xf9, 0xfa, 0xfd, 0x06, 0x02, 0x01, 0x01, 0x03, 0x06, 0x0b, 0x02, + 0x01, 0x17, 0x12, 0x0b, 0x0d, 0x0d, 0x10, 0x14, 0x0a, 0x00, 0xfa, 0xf7, + 0xfa, 0x00, 0x06, 0x12, 0x0f, 0x0b, 0x0d, 0x14, 0x13, 0x0f, 0xfd, 0xf2, + 0x05, 0x07, 0x03, 0xfe, 0xff, 0x03, 0x01, 0x06, 0x06, 0x06, 0x01, 0x01, + 0x00, 0x00, 0xfb, 0xff, 0xfe, 0x00, 0x02, 0x00, 0xfa, 0xf5, 0xf2, 0xee, + 0xed, 0xf6, 0xf9, 0xfd, 0x0d, 0x17, 0x0d, 0x06, 0x02, 0x0f, 0x0b, 0x09, + 0x09, 0x0b, 0x12, 0x1f, 0x23, 0x17, 0x13, 0x1a, 0x16, 0x07, 0xf6, 0xfa, + 0x00, 0xfe, 0xfd, 0xfe, 0x00, 0x03, 0x01, 0x05, 0x0b, 0x0b, 0x00, 0xf9, + 0xf1, 0xf9, 0xf9, 0xf7, 0xfa, 0xf7, 0x02, 0x0a, 0x07, 0x00, 0x00, 0x06, + 0x05, 0x03, 0x00, 0x09, 0x07, 0x02, 0x01, 0xff, 0x03, 0x03, 0xff, 0xfe, + 0x02, 0x12, 0x0d, 0x09, 0x07, 0x06, 0x14, 0x1c, 0x17, 0x02, 0xfb, 0x00, + 0x05, 0x07, 0xfb, 0xf9, 0xfa, 0xf6, 0xf7, 0x00, 0x0f, 0x0e, 0x07, 0x05, + 0x07, 0xff, 0x01, 0x0a, 0x06, 0x0b, 0x0f, 0x09, 0xfb, 0xf5, 0xfe, 0x07, + 0x02, 0xff, 0x05, 0x0b, 0x09, 0x06, 0xff, 0x00, 0x06, 0x05, 0x00, 0x03, + 0x09, 0x10, 0x0d, 0x07, 0x03, 0xff, 0xfe, 0x03, 0x00, 0xfa, 0x0e, 0x0d, + 0x01, 0xf9, 0xfe, 0x0f, 0x0e, 0x09, 0x0a, 0x0b, 0x01, 0xff, 0xfa, 0x00, + 0x03, 0xf7, 0xf5, 0xfe, 0x01, 0x01, 0xff, 0xf6, 0xf1, 0xf5, 0xfb, 0x05, + 0x0f, 0x14, 0x1b, 0x0f, 0x00, 0xf9, 0xf7, 0x02, 0x09, 0x07, 0x0e, 0x13, + 0x1a, 0x16, 0x1f, 0x20, 0x1c, 0x1b, 0x17, 0x0f, 0x06, 0xf5, 0xf2, 0xf2, + 0xf0, 0xf5, 0xfb, 0xf9, 0xf7, 0xf9, 0x02, 0x01, 0xfa, 0xf1, 0xee, 0xf9, + 0x07, 0x16, 0x10, 0x0b, 0x01, 0x00, 0x01, 0xfa, 0xf2, 0xf9, 0xf7, 0xf7, + 0xfb, 0x03, 0x17, 0x0b, 0x07, 0x12, 0x0f, 0x10, 0x0a, 0x09, 0x0b, 0x0d, + 0x07, 0x05, 0x05, 0x0e, 0x1b, 0x1a, 0x14, 0x12, 0x00, 0xf3, 0xf7, 0xfb, + 0x00, 0x01, 0xff, 0x07, 0x03, 0x02, 0x02, 0xfa, 0xfb, 0xfa, 0xfb, 0xf5, + 0xee, 0xfb, 0x06, 0x16, 0x17, 0x0b, 0x01, 0x01, 0xff, 0x0b, 0x07, 0x09, + 0x06, 0x00, 0xff, 0x00, 0x02, 0x02, 0x00, 0xfb, 0x01, 0xfd, 0xfb, 0xfa, + 0x03, 0x0a, 0x0a, 0x06, 0x0a, 0x14, 0x16, 0x18, 0x09, 0xf9, 0xf1, 0xf1, + 0xfa, 0x07, 0x12, 0x0f, 0x0d, 0x13, 0x12, 0x0f, 0x10, 0x10, 0x0d, 0x02, + 0xff, 0xfa, 0xf7, 0xf2, 0xf7, 0xf7, 0x00, 0xfe, 0xf0, 0xf2, 0xf5, 0x00, + 0x09, 0x02, 0xfb, 0xf7, 0xfe, 0x0b, 0x16, 0x1f, 0x1a, 0x0f, 0x0d, 0x09, + 0x07, 0x13, 0x0e, 0x10, 0x13, 0x0b, 0x07, 0x0b, 0xfe, 0xf6, 0xfa, 0x00, + 0xff, 0xf9, 0xf6, 0xf5, 0xfd, 0xfa, 0xf1, 0xf3, 0xfd, 0xfe, 0xff, 0x06, + 0x03, 0x03, 0x00, 0x05, 0x05, 0x0a, 0x0b, 0x0d, 0x01, 0x02, 0x06, 0x0a, + 0x07, 0x10, 0x09, 0x07, 0x02, 0x00, 0x00, 0x01, 0x0a, 0x1b, 0x14, 0x0b, + 0x0f, 0x14, 0x17, 0x1b, 0x13, 0x09, 0x00, 0xfd, 0xed, 0xf2, 0xf9, 0xf9, + 0xf7, 0xfa, 0xf7, 0xf9, 0xfb, 0xfa, 0xf7, 0x00, 0x03, 0x02, 0x00, 0x01, + 0x05, 0x17, 0x07, 0x03, 0x01, 0xfe, 0x00, 0x03, 0x02, 0x00, 0xfd, 0x0a, + 0x0b, 0x06, 0x07, 0x0d, 0x0a, 0x05, 0x01, 0x01, 0x00, 0x00, 0x02, 0x03, + 0x0b, 0x09, 0x0b, 0x0e, 0x0e, 0x16, 0x0e, 0xff, 0xf2, 0xfe, 0x03, 0x06, + 0x12, 0x20, 0x1a, 0x10, 0x0a, 0x02, 0x01, 0x00, 0xfd, 0xf7, 0xf9, 0xf5, + 0xf2, 0xfd, 0xff, 0xfd, 0x00, 0x06, 0x03, 0xf3, 0xe4, 0xea, 0xfa, 0x00, + 0x05, 0x09, 0x05, 0x07, 0x0f, 0x17, 0x0f, 0x0e, 0x0d, 0x0b, 0x0e, 0x10, + 0x18, 0x16, 0x12, 0x10, 0x0e, 0x0a, 0x07, 0xfa, 0xe9, 0xf5, 0xf3, 0xf6, + 0xf3, 0xf3, 0xfe, 0x0b, 0x07, 0x03, 0x07, 0x12, 0x0b, 0x0b, 0x05, 0x00, + 0x00, 0x00, 0x03, 0x05, 0x03, 0x09, 0x09, 0x00, 0xf6, 0xfb, 0xfe, 0x00, + 0x09, 0x0e, 0x07, 0x00, 0x00, 0x07, 0x0b, 0x14, 0x0b, 0x07, 0x07, 0x07, + 0x01, 0x07, 0x0e, 0x10, 0x0e, 0x12, 0x0a, 0xf9, 0xf5, 0xfb, 0xf7, 0xf0, + 0xf6, 0xfb, 0xf9, 0xf7, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, + 0x0b, 0x0a, 0x0b, 0x10, 0x10, 0x0b, 0x16, 0x0a, 0x05, 0x02, 0x0b, 0x0d, + 0x03, 0xf9, 0xf7, 0xfb, 0xff, 0x00, 0x00, 0x0a, 0x06, 0x05, 0x0f, 0x10, + 0x0b, 0x01, 0xfe, 0x02, 0x0b, 0x07, 0x06, 0xfd, 0xfe, 0x01, 0x01, 0x07, + 0x0f, 0x0d, 0x09, 0x09, 0x06, 0x00, 0xfe, 0x00, 0x02, 0x0a, 0x05, 0xfd, + 0xf6, 0xf2, 0xf6, 0xf9, 0xf1, 0xf1, 0xf0, 0xe8, 0xf6, 0x07, 0x07, 0x0e, + 0x14, 0x0f, 0x0a, 0x13, 0x12, 0x13, 0x0f, 0x10, 0x13, 0x0e, 0x0f, 0x0d, + 0x13, 0x0f, 0x12, 0x13, 0x09, 0x03, 0x00, 0xf7, 0xf3, 0xf3, 0xf7, 0x00, + 0x05, 0x0f, 0x0a, 0x03, 0xfe, 0xf9, 0xf5, 0x02, 0x02, 0x00, 0xfd, 0x0a, + 0x03, 0x03, 0x02, 0x00, 0x00, 0x06, 0xff, 0xf5, 0xf6, 0xfa, 0xff, 0x09, + 0x13, 0x05, 0x00, 0x02, 0x07, 0x18, 0x14, 0x0d, 0x0d, 0x0f, 0x0d, 0x10, + 0x12, 0x18, 0x0b, 0x07, 0x05, 0xfe, 0xf6, 0xe3, 0xdf, 0xf0, 0xf7, 0xff, + 0x00, 0x05, 0x05, 0x01, 0x00, 0x03, 0x09, 0x09, 0x01, 0x03, 0x0b, 0x0e, + 0x0e, 0x13, 0x12, 0x0f, 0x1a, 0x13, 0x06, 0xfe, 0x03, 0x05, 0xfd, 0xf7, + 0xf6, 0xfd, 0x00, 0x05, 0x02, 0x02, 0xfa, 0xf6, 0xf3, 0xfb, 0xfd, 0xff, + 0xff, 0xff, 0x0e, 0x1c, 0x18, 0x1b, 0x10, 0x00, 0x01, 0x03, 0x00, 0x05, + 0x0d, 0x0a, 0x07, 0x03, 0x01, 0x01, 0x00, 0x01, 0x03, 0x02, 0xfa, 0xf5, + 0xec, 0xf2, 0xfa, 0xfb, 0x02, 0x00, 0x00, 0x09, 0x00, 0x02, 0x0e, 0x0d, + 0x0a, 0x0e, 0x10, 0x0a, 0x09, 0x1a, 0x1b, 0x10, 0x07, 0x07, 0x0a, 0x0e, + 0x0b, 0x03, 0x01, 0x03, 0x00, 0xff, 0xfd, 0xf2, 0xf2, 0xf9, 0x00, 0x07, + 0x02, 0x00, 0x05, 0x00, 0x00, 0x06, 0x10, 0x0e, 0x03, 0x02, 0x02, 0xf9, + 0xf2, 0xf5, 0xf9, 0xfe, 0x00, 0xfb, 0xf7, 0x00, 0x01, 0xfa, 0xf9, 0x0a, + 0x13, 0x0a, 0x05, 0x13, 0x20, 0x18, 0x17, 0x16, 0x14, 0x1a, 0x14, 0x0f, + 0x05, 0x00, 0x06, 0x06, 0xfd, 0xfb, 0xfb, 0xee, 0xfa, 0x05, 0x06, 0x01, + 0xff, 0xf5, 0xf2, 0xf6, 0xf9, 0xfd, 0xfe, 0xfe, 0x0d, 0x0d, 0x0a, 0x13, + 0x10, 0x0f, 0x13, 0x0e, 0x07, 0x00, 0xff, 0xfe, 0xfe, 0x03, 0x00, 0xfe, + 0x01, 0x01, 0x00, 0xfe, 0xfd, 0xfd, 0xf5, 0xf7, 0x02, 0x10, 0x13, 0x0b, + 0x13, 0x1a, 0x0f, 0x06, 0x05, 0x10, 0x0a, 0xfb, 0xfe, 0xfd, 0xfb, 0x0d, + 0x0a, 0x0a, 0x07, 0x05, 0x05, 0x02, 0x05, 0x05, 0x01, 0xf9, 0xf5, 0xf9, + 0xfb, 0xff, 0x00, 0xff, 0xf7, 0x05, 0x01, 0xfe, 0x06, 0x13, 0x13, 0x16, + 0x0f, 0x0a, 0x06, 0x02, 0x00, 0x00, 0xff, 0xfe, 0xfe, 0x01, 0xff, 0x06, + 0x00, 0x0b, 0x0f, 0x09, 0x0a, 0x0a, 0x02, 0xf7, 0xfd, 0x06, 0x0d, 0x02, + 0x09, 0x10, 0x0d, 0x07, 0x03, 0x01, 0xf9, 0xf9, 0x00, 0xfb, 0xfb, 0xfe, + 0x00, 0x09, 0x00, 0xf7, 0xf6, 0x00, 0xfd, 0xf5, 0xf3, 0xfd, 0x09, 0x16, + 0x0d, 0x0e, 0x1a, 0x1c, 0x27, 0x29, 0x20, 0x13, 0x12, 0x0a, 0xfe, 0xfa, + 0xfd, 0xfb, 0xfb, 0xfe, 0x00, 0x00, 0xf7, 0xf3, 0xf9, 0xf9, 0xf5, 0xf9, + 0xfa, 0xfd, 0x03, 0x05, 0x0b, 0x0e, 0x14, 0x0e, 0x07, 0x07, 0x0d, 0x0f, + 0x07, 0x07, 0x01, 0xf6, 0xf7, 0x03, 0x02, 0x00, 0xfb, 0xfe, 0xff, 0xfb, + 0xfa, 0xf9, 0xff, 0x01, 0x00, 0x00, 0x07, 0x0d, 0x0d, 0x07, 0x0d, 0x16, + 0x0e, 0x16, 0x1b, 0x16, 0x1d, 0x1c, 0x0b, 0xfa, 0xf7, 0xfb, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0xfe, 0xf3, 0xf1, 0x00, 0xfd, 0xf6, 0xf9, 0xfb, + 0xf3, 0xf6, 0xf5, 0x09, 0x0b, 0x09, 0x17, 0x18, 0x17, 0x10, 0x09, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x07, 0x0f, 0x12, 0x0a, 0x03, 0xff, 0x05, 0x09, + 0x03, 0x00, 0x00, 0x07, 0x0a, 0x07, 0xf9, 0xf9, 0x03, 0x0f, 0x16, 0x06, + 0x01, 0x01, 0x01, 0xfe, 0xf9, 0x00, 0x09, 0x05, 0x00, 0x00, 0xfe, 0xfb, + 0xf6, 0xf3, 0xf3, 0xfe, 0x01, 0xfd, 0x00, 0x07, 0x02, 0x05, 0x0f, 0x10, + 0x1c, 0x23, 0x21, 0x1a, 0x12, 0x09, 0x02, 0xfe, 0xf9, 0xf6, 0xfe, 0x07, + 0x05, 0x00, 0x00, 0x02, 0x07, 0x05, 0xf6, 0xfe, 0xfe, 0xfb, 0xfe, 0x00, + 0xfd, 0xfe, 0x00, 0x02, 0x0f, 0x17, 0x12, 0x0a, 0x0d, 0x0d, 0x14, 0x06, + 0x00, 0xfb, 0x00, 0x01, 0x00, 0xf6, 0xf3, 0xf6, 0xf7, 0xfd, 0xfe, 0xfd, + 0xfd, 0x07, 0x06, 0x02, 0x0a, 0x07, 0x06, 0x0a, 0x0d, 0x20, 0x1c, 0x0a, + 0x0a, 0x0d, 0x0e, 0x12, 0x0e, 0x00, 0xf1, 0xf1, 0xf6, 0x06, 0x09, 0x07, + 0x09, 0x0b, 0x09, 0x07, 0x03, 0xfd, 0xf9, 0xf3, 0xf3, 0xf1, 0xf0, 0xed, + 0xf3, 0x0d, 0x16, 0x1a, 0x10, 0x06, 0x03, 0x06, 0x00, 0xfd, 0xff, 0xfe, + 0x02, 0x05, 0x07, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x0f, + 0x12, 0x1a, 0x1f, 0x1a, 0x0f, 0x0d, 0x10, 0x06, 0xfe, 0xfe, 0xf9, 0xf7, + 0xfb, 0xf7, 0xf9, 0xfb, 0xfb, 0x03, 0x00, 0xf7, 0xf6, 0xf9, 0xf2, 0xec, + 0xf3, 0x00, 0x05, 0x00, 0x01, 0x02, 0x00, 0x01, 0x07, 0x1c, 0x32, 0x25, + 0x21, 0x20, 0x1f, 0x14, 0x0a, 0x02, 0x00, 0x00, 0xfb, 0xf9, 0xf6, 0xf9, + 0xf6, 0x00, 0x0a, 0x07, 0x02, 0xf5, 0xf3, 0xfe, 0xf3, 0xf6, 0xfe, 0x00, + 0x00, 0x05, 0x21, 0x1c, 0x0f, 0x09, 0x07, 0x05, 0x03, 0x02, 0xf9, 0xfb, + 0x00, 0x0d, 0x0b, 0x02, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0xfb, + 0xfe, 0x05, 0x00, 0x00, 0x01, 0x07, 0x1a, 0x1f, 0x12, 0x0f, 0x07, 0x0d, + 0x12, 0x14, 0x0d, 0x05, 0x00, 0xf6, 0xf9, 0xf9, 0x00, 0x05, 0x02, 0x05, + 0x02, 0x00, 0x05, 0x07, 0xff, 0x01, 0x00, 0xfb, 0xf6, 0xf1, 0x00, 0x0d, + 0x0d, 0x07, 0x02, 0x00, 0xfe, 0xfe, 0xfb, 0xf9, 0xfb, 0x00, 0x05, 0x07, + 0x02, 0x0d, 0x07, 0x05, 0x00, 0x00, 0x00, 0x05, 0x14, 0x0d, 0x05, 0x0b, + 0x16, 0x1c, 0x1c, 0x24, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0xfb, 0xfe, 0x00, 0xfa, 0xf3, 0xe6, 0xec, 0xf0, 0xf1, + 0x07, 0x05, 0x00, 0x00, 0xfe, 0x05, 0x06, 0x17, 0x27, 0x1a, 0x0d, 0x0e, + 0x0d, 0x07, 0x05, 0x05, 0x05, 0x0d, 0x03, 0x00, 0x02, 0x02, 0x07, 0x0d, + 0x14, 0x0f, 0x0a, 0x05, 0xf7, 0xf6, 0xf3, 0xf1, 0xf9, 0x02, 0x02, 0x01, + 0x0d, 0x07, 0x07, 0x00, 0x05, 0x05, 0xfe, 0xf6, 0xf9, 0xf9, 0xfb, 0x02, + 0x05, 0x05, 0x05, 0x02, 0x00, 0x00, 0x02, 0x03, 0x00, 0x0d, 0x0f, 0x0a, + 0x07, 0x10, 0x0f, 0x0d, 0x1a, 0x12, 0x06, 0x02, 0x02, 0x00, 0x02, 0x05, + 0x02, 0xfe, 0xfd, 0xfb, 0xf7, 0xff, 0x02, 0x0a, 0x03, 0x00, 0xfe, 0xfb, + 0xfe, 0x05, 0x00, 0xff, 0x07, 0x0d, 0xfb, 0xfb, 0x0d, 0x13, 0x0d, 0x07, + 0x03, 0x02, 0x02, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xff, 0x00, 0x05, 0x00, + 0xfe, 0xfb, 0xfd, 0x00, 0x00, 0x0d, 0x17, 0x1a, 0x14, 0x1a, 0x14, 0x12, + 0x1a, 0x21, 0x1a, 0x00, 0xf6, 0xf7, 0xfa, 0xfe, 0x0a, 0x0d, 0x00, 0xfb, + 0xfe, 0x05, 0x07, 0x00, 0xf6, 0xee, 0xee, 0xf1, 0xf0, 0xfb, 0xfb, 0xfb, + 0x00, 0x01, 0xfe, 0xf9, 0xfb, 0x07, 0x0f, 0x1f, 0x1a, 0x12, 0x0f, 0x0a, + 0x05, 0x02, 0x03, 0x01, 0x01, 0x01, 0x09, 0x0e, 0x0b, 0x10, 0x13, 0x0e, + 0x0b, 0x13, 0x06, 0xf5, 0x03, 0x09, 0x06, 0x03, 0x03, 0x0b, 0x06, 0x06, + 0xfd, 0xf7, 0xfb, 0xf6, 0xf0, 0xf0, 0xfa, 0xf2, 0xf2, 0x0a, 0x13, 0x0e, + 0x03, 0x00, 0xfd, 0xfd, 0xf7, 0xfd, 0x03, 0x03, 0x0d, 0x0b, 0x0d, 0x13, + 0x0b, 0x17, 0x1c, 0x1b, 0x10, 0x06, 0x06, 0x09, 0x09, 0x03, 0x06, 0x0d, + 0x09, 0x06, 0xfa, 0xf2, 0xf5, 0xfb, 0xfd, 0xf7, 0xf1, 0xf2, 0x01, 0x18, + 0x1d, 0x0b, 0xf2, 0xf2, 0xf2, 0x03, 0x09, 0x09, 0x03, 0xff, 0x01, 0x09, + 0x13, 0x0d, 0x06, 0x03, 0x02, 0x06, 0x0b, 0x0d, 0x07, 0x01, 0xfe, 0xfe, + 0xff, 0x03, 0x03, 0x09, 0x10, 0x16, 0x0e, 0x06, 0x01, 0x03, 0x13, 0x10, + 0x20, 0x13, 0xf6, 0xf7, 0x02, 0x01, 0xff, 0xfb, 0xf2, 0xf2, 0xff, 0x02, + 0xf7, 0xfd, 0x02, 0x00, 0x02, 0x03, 0xfd, 0x01, 0x03, 0x00, 0x00, 0xfd, + 0xfd, 0xfd, 0x0b, 0x09, 0x0e, 0x09, 0x01, 0x01, 0x03, 0x09, 0x0b, 0x03, + 0x00, 0x09, 0x25, 0x23, 0x13, 0x09, 0x06, 0x03, 0x09, 0x0b, 0x06, 0x10, + 0x13, 0x05, 0x03, 0x07, 0x06, 0x01, 0x05, 0x05, 0x01, 0x00, 0xfb, 0xf1, + 0xf6, 0xee, 0xec, 0xf6, 0x00, 0xfd, 0xfe, 0x00, 0x00, 0x00, 0xff, 0xf6, + 0xf6, 0xf7, 0xfe, 0x0f, 0x1a, 0x14, 0x0f, 0x07, 0x05, 0x02, 0x0d, 0x0e, + 0x09, 0x0f, 0x0a, 0x12, 0x17, 0x14, 0x0f, 0x09, 0x07, 0x07, 0x07, 0x0a, + 0x07, 0xf9, 0xf9, 0xfb, 0x05, 0x00, 0x00, 0x02, 0x03, 0x02, 0xfe, 0xf9, + 0xf2, 0xf3, 0xf7, 0x00, 0x00, 0x0a, 0x07, 0xfe, 0xfe, 0x02, 0x02, 0x00, + 0x00, 0xfe, 0x00, 0x03, 0x0f, 0x0a, 0x00, 0xff, 0x02, 0x06, 0x0d, 0x0f, + 0x0d, 0x0b, 0x07, 0x0d, 0x07, 0x02, 0x01, 0x12, 0x14, 0x1c, 0x12, 0x0d, + 0x00, 0xf5, 0xf6, 0xf6, 0xf1, 0xf1, 0xfb, 0x09, 0x02, 0x00, 0xfb, 0xf6, + 0xf6, 0xff, 0x0f, 0x07, 0x00, 0x07, 0x07, 0x02, 0x00, 0x00, 0x00, 0x07, + 0x05, 0x05, 0x07, 0x0d, 0x09, 0x05, 0x00, 0x02, 0x09, 0x0a, 0x10, 0x14, + 0x0f, 0x0a, 0x02, 0xff, 0x00, 0xfe, 0x0a, 0x09, 0x0f, 0x18, 0x0d, 0x01, + 0xfb, 0xfb, 0xfd, 0x02, 0xfe, 0xf6, 0xfe, 0xfb, 0xfd, 0xf6, 0xf1, 0xf5, + 0xfe, 0x02, 0x0d, 0x05, 0x01, 0xfe, 0xf9, 0xfb, 0x02, 0x0a, 0x17, 0x0f, + 0x07, 0x05, 0x05, 0x00, 0xfe, 0xf9, 0xf6, 0x07, 0x0f, 0x0d, 0x1c, 0x1a, + 0x14, 0x17, 0x0e, 0x07, 0x05, 0x05, 0x07, 0x0f, 0x0f, 0x0a, 0x02, 0xf6, + 0xfe, 0x0a, 0x0f, 0x06, 0x00, 0xf7, 0xf9, 0xfd, 0xfe, 0xf9, 0xf6, 0xfb, + 0x00, 0xfb, 0x00, 0xfe, 0xf3, 0xf3, 0xf3, 0xf3, 0xfb, 0xff, 0xfe, 0x02, + 0x10, 0x07, 0x00, 0x07, 0x0a, 0x0f, 0x0d, 0x0b, 0x0f, 0x0e, 0x0b, 0x09, + 0x0a, 0x14, 0x12, 0x12, 0x1c, 0x0f, 0x14, 0x1c, 0x18, 0x0f, 0xfb, 0xf3, + 0xfb, 0x01, 0xfe, 0xf5, 0xec, 0xf1, 0xf3, 0xf9, 0xf3, 0xfe, 0x00, 0x00, + 0x00, 0x07, 0x07, 0xfe, 0xfa, 0xfb, 0xfb, 0xfb, 0x02, 0x02, 0x09, 0x0b, + 0x0a, 0x10, 0x07, 0x02, 0x06, 0x0d, 0x12, 0x17, 0x12, 0x0d, 0x06, 0x07, + 0x06, 0x0a, 0x05, 0x02, 0x05, 0x07, 0x0a, 0x0f, 0x07, 0xf9, 0xf1, 0xf9, + 0x00, 0xf9, 0xf3, 0xfa, 0xf9, 0xfe, 0xfe, 0xf6, 0xf3, 0xfe, 0x02, 0x07, + 0x0f, 0x07, 0x02, 0x05, 0x0d, 0x17, 0x1a, 0x14, 0x0d, 0x07, 0x03, 0x00, + 0xfe, 0xfa, 0xf6, 0xfe, 0x07, 0x03, 0x09, 0x10, 0x0f, 0x07, 0x07, 0x07, + 0x06, 0x00, 0x00, 0x02, 0x0b, 0x0b, 0x0a, 0x0a, 0x05, 0xf9, 0xf9, 0x07, + 0x0d, 0x01, 0xf6, 0xf9, 0xfb, 0xfe, 0x00, 0x00, 0x05, 0x02, 0x03, 0x00, + 0x00, 0xfb, 0xf6, 0xf1, 0xf5, 0xfb, 0x00, 0x07, 0x0a, 0x05, 0x07, 0x07, + 0x12, 0x0a, 0x02, 0x02, 0x02, 0x02, 0x12, 0x0f, 0x07, 0x05, 0x0d, 0x0f, + 0x17, 0x1f, 0x1a, 0x17, 0x20, 0x17, 0x14, 0x12, 0x00, 0xfb, 0xfd, 0xfe, + 0xee, 0xe9, 0xf3, 0xf3, 0xf6, 0xf6, 0xfb, 0x00, 0x00, 0x00, 0xfb, 0xf6, + 0xf1, 0xf0, 0xf0, 0xea, 0xf9, 0xfb, 0xfa, 0x02, 0x07, 0x00, 0x06, 0x0b, + 0x0d, 0x0f, 0x1a, 0x23, 0x1d, 0x1a, 0x18, 0x17, 0x1a, 0x14, 0x16, 0x12, + 0x12, 0x07, 0x0a, 0x07, 0x0a, 0x06, 0x03, 0xf2, 0xf9, 0x00, 0x00, 0xf1, + 0xf3, 0xf0, 0xea, 0xf1, 0xee, 0xee, 0xec, 0xf1, 0xf9, 0x0f, 0x0e, 0x09, + 0x0e, 0x06, 0x09, 0x17, 0x1d, 0x18, 0x10, 0x0b, 0x06, 0x00, 0x02, 0x02, + 0x0d, 0x0a, 0x00, 0xfb, 0x07, 0x0a, 0x05, 0x01, 0x02, 0x00, 0x00, 0x05, + 0x07, 0x05, 0x00, 0x05, 0x17, 0x07, 0xf9, 0xf1, 0xf3, 0xfe, 0xfb, 0xf9, + 0xf9, 0xfb, 0x00, 0x00, 0x14, 0x23, 0x14, 0x03, 0x0a, 0x07, 0xfe, 0x02, + 0x02, 0xfb, 0xfd, 0x02, 0x0d, 0x0d, 0x00, 0x01, 0x07, 0x00, 0x00, 0x00, + 0x06, 0x07, 0x01, 0xfd, 0x01, 0x01, 0xff, 0xfa, 0x10, 0x16, 0x0d, 0x0d, + 0x20, 0x20, 0x16, 0x16, 0x14, 0x07, 0x00, 0x00, 0x02, 0xf6, 0xf1, 0xf1, + 0xf9, 0xfe, 0x00, 0x00, 0x00, 0xfb, 0xf3, 0xfb, 0xfb, 0xf9, 0xf1, 0xec, + 0xf6, 0xfe, 0xfb, 0xfd, 0x00, 0x05, 0x00, 0x0a, 0x12, 0x06, 0x02, 0x0b, + 0x18, 0x1d, 0x1b, 0x1d, 0x1b, 0x14, 0x14, 0x20, 0x23, 0x18, 0x0b, 0x06, + 0x06, 0x0e, 0x0a, 0x05, 0x0b, 0x00, 0xf9, 0xf3, 0xea, 0xe3, 0xe8, 0xf1, + 0xee, 0xed, 0xee, 0xf9, 0xfd, 0xf9, 0xfb, 0x0a, 0x03, 0xff, 0xff, 0x00, + 0xfd, 0xfe, 0x0e, 0x12, 0x09, 0x02, 0xff, 0xff, 0x0e, 0x1c, 0x1b, 0x13, + 0x0f, 0x0d, 0x0f, 0x0e, 0x0d, 0x07, 0x07, 0x0f, 0x0f, 0x06, 0x07, 0x10, + 0x0f, 0x07, 0x05, 0x02, 0xf3, 0xf1, 0xfb, 0xf9, 0xea, 0xea, 0xf6, 0xf2, + 0xfe, 0x03, 0x01, 0x01, 0x0d, 0x02, 0x01, 0x02, 0x01, 0x01, 0x0a, 0x0d, + 0x09, 0x0b, 0x07, 0x0e, 0x0f, 0x0d, 0x10, 0x0b, 0x06, 0x02, 0x00, 0xfd, + 0xf7, 0xf7, 0xf6, 0xf6, 0x00, 0x0f, 0x12, 0x10, 0x0b, 0x0d, 0x0f, 0x0d, + 0x0d, 0x0f, 0x0a, 0xff, 0xf6, 0x00, 0xfb, 0xed, 0xf3, 0xf9, 0x03, 0x0f, + 0x0d, 0x0b, 0x06, 0x00, 0xfe, 0x00, 0xfe, 0xff, 0x05, 0x05, 0xfd, 0xfe, + 0xfd, 0xfb, 0xfe, 0xfe, 0x01, 0x07, 0x07, 0x06, 0x0a, 0x10, 0x0b, 0x12, + 0x16, 0x12, 0x0f, 0x0b, 0x0a, 0x07, 0x0d, 0x16, 0x0f, 0x0a, 0x06, 0x06, + 0x10, 0x1b, 0x01, 0x00, 0xf9, 0xed, 0xe6, 0xe8, 0xf1, 0xf6, 0xf9, 0xf5, + 0xf1, 0xf1, 0xf0, 0xf6, 0x0d, 0x02, 0x00, 0x00, 0x02, 0xfe, 0x01, 0x02, + 0x06, 0x09, 0x05, 0x00, 0x0d, 0x0f, 0x0a, 0x13, 0x1d, 0x14, 0x10, 0x0d, + 0x0b, 0x0e, 0x18, 0x18, 0x13, 0x0f, 0x0e, 0x0d, 0x0d, 0x0a, 0x0e, 0x0e, + 0x06, 0xf5, 0xf1, 0xf5, 0xf1, 0xe5, 0xe4, 0xea, 0xfb, 0x02, 0x05, 0x07, + 0x0b, 0x02, 0xfe, 0xfe, 0xfd, 0xfb, 0xfb, 0xfb, 0xf6, 0xfe, 0x02, 0xfd, + 0x05, 0x03, 0x03, 0x09, 0x16, 0x14, 0x12, 0x0e, 0x06, 0x00, 0x00, 0x01, + 0x0e, 0x10, 0x16, 0x1a, 0x10, 0x0e, 0x07, 0x0e, 0x10, 0x17, 0x17, 0x12, + 0x01, 0xfe, 0xf9, 0xf2, 0xf6, 0xf0, 0xf3, 0xf2, 0xf5, 0xf5, 0xf9, 0x00, + 0xf9, 0xf3, 0xf6, 0xf9, 0x03, 0x10, 0x10, 0x07, 0x01, 0x05, 0x01, 0x02, + 0x07, 0x17, 0x20, 0x13, 0x09, 0x02, 0x05, 0x01, 0x05, 0x0a, 0x0f, 0x0b, + 0x0d, 0x0e, 0x0a, 0x03, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x0e, 0x0a, 0xf7, + 0xfd, 0xfb, 0xf6, 0xf3, 0xf2, 0xf5, 0xfb, 0x02, 0xff, 0xfa, 0x00, 0x00, + 0x05, 0x13, 0x0d, 0x0d, 0x0d, 0x0a, 0x07, 0xfb, 0xfa, 0xfe, 0x00, 0x02, + 0x10, 0x10, 0x10, 0x13, 0x0e, 0x0a, 0x05, 0x01, 0x06, 0x06, 0x02, 0x01, + 0xfe, 0x09, 0x16, 0x0b, 0x0a, 0x10, 0x0b, 0x0a, 0x0b, 0x0f, 0x00, 0xf7, + 0x00, 0xfd, 0xf1, 0xe9, 0xfd, 0x01, 0x00, 0xfb, 0xfd, 0x00, 0xfe, 0xfd, + 0x07, 0x05, 0x03, 0x03, 0x01, 0xfb, 0xf7, 0xf3, 0xf6, 0x01, 0xff, 0xfb, + 0x00, 0x05, 0x0f, 0x17, 0x0b, 0x06, 0x01, 0x03, 0x17, 0x1b, 0x1a, 0x21, + 0x24, 0x1d, 0x16, 0x0a, 0x0b, 0x14, 0x17, 0x0e, 0x0b, 0xf7, 0xf3, 0xee, + 0xf0, 0xfe, 0x00, 0xf2, 0xf3, 0x00, 0xfe, 0xf7, 0xf3, 0xed, 0xe9, 0xed, + 0x00, 0xff, 0xfb, 0xfe, 0x0a, 0x00, 0xfd, 0xfb, 0x00, 0x01, 0x10, 0x12, + 0x14, 0x0b, 0x0e, 0x14, 0x0d, 0x13, 0x12, 0x13, 0x14, 0x16, 0x0e, 0x07, + 0x07, 0x07, 0x00, 0xff, 0x13, 0x1c, 0x18, 0x0a, 0xfd, 0xf2, 0xf2, 0xf6, + 0xfb, 0xf6, 0xea, 0xe6, 0xe9, 0xf5, 0xf6, 0xf3, 0xf1, 0xff, 0x0f, 0x0b, + 0x02, 0x07, 0x0e, 0x0a, 0x0b, 0x05, 0x02, 0x09, 0x20, 0x21, 0x17, 0x12, + 0x16, 0x0e, 0x07, 0x01, 0x03, 0x03, 0x05, 0x05, 0x00, 0xfd, 0xf9, 0xfb, + 0xf6, 0xf7, 0x05, 0xff, 0xf9, 0x02, 0x0d, 0x00, 0xfb, 0x00, 0xfb, 0xfe, + 0x0e, 0x0a, 0xfb, 0x00, 0x0d, 0x07, 0x05, 0x06, 0x07, 0x0a, 0x0f, 0x0e, + 0x06, 0x00, 0xfd, 0xf7, 0xf6, 0xf6, 0x02, 0x00, 0x00, 0x07, 0x05, 0x01, + 0xff, 0x01, 0xfd, 0xfe, 0x0e, 0x0a, 0x05, 0x0b, 0x25, 0x20, 0x16, 0x12, + 0x0f, 0x0f, 0x0f, 0x10, 0x0e, 0x0a, 0x00, 0xf6, 0xf7, 0xfe, 0x05, 0x07, + 0x00, 0xf6, 0xed, 0xf0, 0xed, 0xe9, 0xe6, 0xf2, 0x06, 0x09, 0x0a, 0x05, + 0x01, 0xff, 0xf9, 0xf9, 0xf7, 0xfb, 0xfe, 0x02, 0x03, 0x0d, 0x0b, 0x0b, + 0x0b, 0x0a, 0x0b, 0x1f, 0x1c, 0x1c, 0x16, 0x16, 0x1a, 0x17, 0x12, 0x16, + 0x1f, 0x17, 0x0f, 0x0a, 0x05, 0xf5, 0xed, 0xf1, 0xf9, 0xf3, 0xf7, 0xfe, + 0xfb, 0xed, 0xe6, 0xea, 0xea, 0xe6, 0xf2, 0x02, 0xfe, 0xfd, 0x02, 0x09, + 0x03, 0xfd, 0xfe, 0x09, 0x1b, 0x13, 0x0e, 0x0e, 0x10, 0x16, 0x17, 0x1f, + 0x17, 0x10, 0x13, 0x13, 0x07, 0x00, 0xfb, 0xfb, 0xfb, 0xfa, 0xfe, 0xfe, + 0x09, 0x07, 0x03, 0x02, 0xfa, 0xf6, 0xfb, 0x02, 0x0d, 0x02, 0xfe, 0x02, + 0x09, 0xfb, 0xfe, 0x07, 0xff, 0xfd, 0x00, 0x07, 0x03, 0xff, 0xfe, 0x07, + 0x00, 0xfe, 0x01, 0x0a, 0x10, 0x09, 0x05, 0x03, 0x00, 0xfe, 0x01, 0x06, + 0x10, 0x0a, 0x0e, 0x0b, 0x0b, 0x12, 0x0e, 0x07, 0x02, 0x03, 0xff, 0xff, + 0xfb, 0x02, 0x0d, 0x00, 0xfa, 0xfa, 0xfd, 0x02, 0x0d, 0x0a, 0x07, 0x00, + 0xf7, 0xf9, 0xfb, 0x00, 0x0b, 0x09, 0x00, 0x00, 0x03, 0x01, 0xfe, 0xfe, + 0xfb, 0xfe, 0x00, 0x07, 0x0e, 0x05, 0x01, 0xfe, 0xfe, 0x00, 0xfe, 0xfe, + 0x02, 0x0a, 0x1b, 0x1b, 0x0f, 0x13, 0x18, 0x1b, 0x24, 0x20, 0x14, 0x0e, + 0x09, 0x06, 0x00, 0x00, 0xf9, 0xfd, 0xff, 0xfd, 0xf9, 0xf2, 0xee, 0xe9, + 0xdf, 0xe1, 0xe6, 0xf0, 0xfd, 0x0e, 0x07, 0x03, 0x01, 0x00, 0x00, 0xff, + 0x05, 0x09, 0x0d, 0x09, 0x12, 0x13, 0x14, 0x16, 0x17, 0x0f, 0x0f, 0x0f, + 0x12, 0x0d, 0x03, 0x00, 0x05, 0x0b, 0x09, 0x09, 0x07, 0x06, 0x06, 0x03, + 0x00, 0xf5, 0xf6, 0xff, 0x0a, 0x09, 0x09, 0x03, 0x03, 0x03, 0x03, 0xfe, + 0xf7, 0xf0, 0xf3, 0xfa, 0xfb, 0x01, 0xfe, 0xfd, 0x00, 0x00, 0xfa, 0xfb, + 0x00, 0x01, 0x0a, 0x05, 0xfe, 0x01, 0x03, 0x10, 0x24, 0x1f, 0x17, 0x13, + 0x0f, 0x0d, 0x13, 0x0e, 0x0d, 0x07, 0x05, 0x02, 0x02, 0x00, 0xfe, 0x00, + 0xf3, 0xea, 0xf1, 0xf1, 0xfb, 0x01, 0x09, 0x17, 0x0b, 0x0d, 0x09, 0x07, + 0x05, 0x00, 0x02, 0x01, 0xfd, 0xf5, 0xf7, 0xfb, 0x03, 0x05, 0x03, 0x05, + 0x02, 0x0b, 0x0a, 0x01, 0xfe, 0xfd, 0xfa, 0x00, 0x05, 0x03, 0x0a, 0x10, + 0x0b, 0x0b, 0x10, 0x10, 0x18, 0x0e, 0x09, 0x06, 0x0d, 0x09, 0x0d, 0x0e, + 0x03, 0x02, 0x00, 0x00, 0xfe, 0xf9, 0xf3, 0xf1, 0xed, 0xf1, 0xf7, 0xff, + 0xfa, 0x02, 0x02, 0x05, 0xff, 0xfa, 0xfb, 0x03, 0x10, 0x0a, 0x0d, 0x0d, + 0x0a, 0x0a, 0x0f, 0x10, 0x12, 0x0a, 0x06, 0x05, 0x03, 0x09, 0x0e, 0x0b, + 0x05, 0x05, 0x05, 0x07, 0x05, 0x03, 0xff, 0x00, 0x06, 0x05, 0xff, 0xfb, + 0x1b, 0x18, 0x0f, 0x06, 0x00, 0xff, 0xfa, 0xfd, 0xfe, 0xfb, 0xf7, 0xee, + 0xea, 0xfa, 0x02, 0x00, 0xfd, 0xfd, 0xfb, 0xfb, 0xf9, 0xfa, 0xfb, 0x0a, + 0x12, 0x0f, 0x0d, 0x0f, 0x1a, 0x16, 0x12, 0x0a, 0x05, 0x05, 0x05, 0x0e, + 0x1c, 0x1d, 0x1d, 0x17, 0x0b, 0x02, 0xff, 0x00, 0xfa, 0xf2, 0xe8, 0xea, + 0xea, 0xf5, 0x09, 0x0a, 0x06, 0x0a, 0x07, 0x0d, 0x0f, 0x05, 0x02, 0xfd, + 0xff, 0x02, 0x01, 0xfa, 0xfa, 0x00, 0x00, 0x00, 0xfe, 0xf9, 0xf9, 0x02, + 0x00, 0xfb, 0xfe, 0x00, 0x06, 0x13, 0x0f, 0x10, 0x0f, 0x10, 0x0f, 0x10, + 0x16, 0x14, 0x17, 0x14, 0x12, 0x0b, 0x09, 0x07, 0x02, 0xfe, 0xfa, 0xf9, + 0xee, 0xf1, 0xfd, 0xfb, 0xfb, 0xfd, 0xff, 0xfe, 0xfa, 0xfe, 0x03, 0x00, + 0xf9, 0xfb, 0x00, 0x00, 0x09, 0x09, 0x0f, 0x13, 0x06, 0x02, 0x03, 0x03, + 0xff, 0x0f, 0x17, 0x12, 0x0b, 0x0b, 0x0e, 0x09, 0x03, 0x03, 0x05, 0x00, + 0xfd, 0xfa, 0xf5, 0xfd, 0x01, 0x01, 0x06, 0x0b, 0x14, 0x12, 0x16, 0x0f, + 0x05, 0x01, 0xff, 0xfb, 0xfa, 0x03, 0x09, 0x03, 0x00, 0x03, 0xfa, 0xf3, + 0xe9, 0xf5, 0xfa, 0xf6, 0xf7, 0xfa, 0xfd, 0x05, 0x12, 0x0f, 0x0d, 0x12, + 0x16, 0x12, 0x06, 0x00, 0x01, 0x0e, 0x0a, 0x0a, 0x0b, 0x1a, 0x1d, 0x14, + 0x0d, 0x06, 0x01, 0xfb, 0xfb, 0xfd, 0x00, 0xfe, 0xf2, 0xf5, 0xfa, 0xfb, + 0xff, 0x09, 0x07, 0x09, 0x12, 0x10, 0x03, 0xff, 0x03, 0x07, 0x02, 0x01, + 0xf9, 0xf5, 0xfa, 0xf7, 0xf7, 0xf5, 0xfd, 0x00, 0x05, 0x06, 0x02, 0x05, + 0x07, 0x06, 0x02, 0x02, 0x06, 0x07, 0x09, 0x0d, 0x1f, 0x1f, 0x0f, 0x0a, + 0x1d, 0x29, 0x16, 0x07, 0x06, 0x03, 0x06, 0xfd, 0xff, 0xfe, 0xf7, 0xf9, + 0xf5, 0xf3, 0xf0, 0xea, 0xed, 0xf1, 0xf0, 0xf9, 0x0d, 0x0b, 0x09, 0x05, + 0x06, 0x0f, 0x0a, 0x02, 0x03, 0x06, 0x00, 0xfd, 0xfe, 0xff, 0x00, 0x0a, + 0x0d, 0x13, 0x17, 0x17, 0x0e, 0x09, 0x09, 0x09, 0x05, 0x05, 0x01, 0x00, + 0x00, 0x06, 0x02, 0x01, 0x05, 0x0f, 0xff, 0xfe, 0x02, 0x07, 0x05, 0xfe, + 0xff, 0x01, 0x01, 0x0a, 0x0a, 0x05, 0x00, 0xfd, 0xf5, 0xf2, 0xf6, 0xf9, + 0xf9, 0x01, 0xfd, 0xfb, 0x05, 0x0d, 0x06, 0x02, 0x06, 0x1a, 0x13, 0x09, + 0x09, 0x09, 0x07, 0x09, 0x05, 0x02, 0x02, 0x0f, 0x0d, 0x06, 0xfe, 0x05, + 0x05, 0x00, 0xfe, 0x00, 0xff, 0x00, 0xfe, 0xfe, 0xfd, 0x00, 0xfd, 0x02, + 0x0b, 0x24, 0x1d, 0x10, 0x0d, 0x0b, 0x0a, 0x07, 0xfb, 0xfa, 0xf6, 0xf1, + 0xf5, 0xf1, 0xf1, 0xf5, 0xf9, 0xfa, 0x02, 0x06, 0x05, 0xfe, 0xfe, 0xfd, + 0x05, 0x16, 0x14, 0x0e, 0x0d, 0x1d, 0x20, 0x14, 0x12, 0x10, 0x05, 0x07, + 0x0b, 0x12, 0x13, 0x0f, 0x13, 0x06, 0xff, 0xfb, 0xfe, 0xf7, 0xf0, 0xf1, + 0xf0, 0xf0, 0xf2, 0xf0, 0xee, 0xf6, 0x06, 0x06, 0x03, 0x0d, 0x14, 0x06, + 0x05, 0x00, 0x00, 0x09, 0x03, 0x01, 0x06, 0x0a, 0x07, 0x0b, 0x06, 0x07, + 0x0e, 0x0e, 0x09, 0x09, 0x0a, 0x0a, 0x09, 0x05, 0x00, 0x01, 0x09, 0x09, + 0x05, 0x0d, 0x18, 0x0d, 0x06, 0x05, 0x02, 0x00, 0x02, 0xff, 0xf9, 0xfb, + 0xfe, 0xfe, 0xf6, 0xf1, 0xfb, 0x01, 0xfe, 0xfb, 0xfe, 0xfd, 0xfa, 0xfa, + 0x02, 0x03, 0x06, 0x09, 0x0a, 0x0d, 0x1a, 0x14, 0x0f, 0x05, 0xfa, 0x00, + 0x10, 0x0d, 0x06, 0x01, 0x05, 0x10, 0x0d, 0x09, 0x02, 0x05, 0x06, 0x07, + 0x03, 0x01, 0xf7, 0xf2, 0xed, 0xf6, 0x03, 0x05, 0x02, 0x00, 0x0a, 0x1f, + 0x24, 0x17, 0x07, 0x0a, 0x0b, 0x0b, 0x03, 0x00, 0xfa, 0xfd, 0xf9, 0xed, + 0xea, 0xf2, 0xf6, 0xf6, 0xff, 0xff, 0xfb, 0xfd, 0xfa, 0x01, 0x09, 0x0d, + 0x10, 0x0d, 0x0a, 0x16, 0x16, 0x0d, 0x05, 0x0a, 0x12, 0x0e, 0x05, 0x0e, + 0x12, 0x12, 0x12, 0x0f, 0x05, 0x00, 0x00, 0x00, 0xfb, 0xf9, 0xf5, 0xf5, + 0xf7, 0xf7, 0xf6, 0xfd, 0x07, 0x05, 0x03, 0x0a, 0x0e, 0x0a, 0xfe, 0xf7, + 0xfd, 0x00, 0x00, 0xff, 0xfe, 0xfb, 0xff, 0x07, 0x01, 0x07, 0x13, 0x17, + 0x0f, 0x0d, 0x10, 0x0f, 0x09, 0x05, 0x01, 0x01, 0x07, 0x09, 0x06, 0x10, + 0x14, 0x0f, 0x05, 0xfb, 0xff, 0x05, 0x03, 0xfe, 0xfb, 0xfd, 0xfb, 0xfe, + 0xfb, 0xf2, 0xf5, 0xf2, 0xf6, 0xf6, 0xf7, 0xfe, 0xfe, 0xfa, 0xff, 0x13, + 0x18, 0x14, 0x10, 0x1c, 0x23, 0x18, 0x0b, 0x02, 0x02, 0x07, 0x06, 0x01, + 0xfd, 0xfe, 0x01, 0x09, 0x07, 0xff, 0xff, 0x0a, 0x06, 0x03, 0x07, 0x0a, + 0x03, 0x02, 0xfd, 0xf3, 0xf7, 0xfd, 0x01, 0x0b, 0x12, 0x06, 0x0a, 0x07, + 0x0b, 0x16, 0x0d, 0xff, 0xfa, 0xfb, 0xff, 0x01, 0xfd, 0xf0, 0xf0, 0xfb, + 0xfd, 0xf6, 0xfe, 0x03, 0xff, 0xfb, 0xfb, 0xfe, 0x03, 0x0f, 0x13, 0x14, + 0x20, 0x1d, 0x0f, 0x07, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0f, 0x10, + 0x0f, 0x09, 0xff, 0x00, 0xfe, 0xfa, 0xfe, 0x00, 0xff, 0xfa, 0xf6, 0xf9, + 0xfe, 0x05, 0x0d, 0x0f, 0x16, 0x13, 0x0b, 0x02, 0xf6, 0xf5, 0x00, 0x00, + 0xfd, 0xf9, 0xf7, 0xfa, 0xfa, 0xfb, 0xfd, 0xff, 0xff, 0x05, 0x0a, 0x10, + 0x0d, 0x07, 0x02, 0x00, 0x0d, 0x12, 0x0f, 0x0a, 0x16, 0x1a, 0x17, 0x10, + 0x09, 0x05, 0x06, 0x0a, 0x09, 0x05, 0xff, 0x01, 0xfe, 0xfa, 0xf5, 0xf7, + 0xff, 0xfa, 0xf5, 0xf6, 0xf5, 0xf7, 0xf9, 0xf3, 0xf3, 0x03, 0x0f, 0x0e, + 0x14, 0x1c, 0x0e, 0x07, 0x06, 0x0b, 0x12, 0x0d, 0x0b, 0x02, 0x00, 0x00, + 0xff, 0x05, 0x0a, 0x09, 0x09, 0x06, 0x06, 0x05, 0x02, 0x01, 0xfe, 0xf9, + 0xfa, 0xf7, 0xfe, 0x03, 0x07, 0x16, 0x0e, 0x0d, 0x0b, 0x05, 0x03, 0x06, + 0x02, 0xfb, 0xf6, 0xf3, 0xf6, 0x00, 0xfe, 0xfb, 0x02, 0xff, 0x00, 0xfe, + 0xff, 0x07, 0x06, 0x06, 0x09, 0x0d, 0x0b, 0x0b, 0x07, 0x17, 0x10, 0x07, + 0x06, 0x00, 0x00, 0x07, 0x0a, 0x07, 0x07, 0x0d, 0x10, 0x10, 0x16, 0x10, + 0x09, 0xf7, 0xf6, 0xf9, 0xf7, 0xf9, 0xfd, 0xf9, 0xf2, 0xff, 0x02, 0xfd, + 0x00, 0x16, 0x0d, 0x0e, 0x0f, 0x09, 0xff, 0xfd, 0x00, 0xff, 0xfd, 0xfd, + 0xf3, 0xf0, 0xf5, 0xf9, 0x01, 0x03, 0x06, 0x07, 0x07, 0x10, 0x0f, 0x0d, + 0x07, 0x06, 0x0b, 0x0a, 0x0b, 0x1a, 0x1d, 0x17, 0x16, 0x0b, 0x01, 0x06, + 0x05, 0xff, 0xff, 0x00, 0xfe, 0x03, 0x01, 0x01, 0xff, 0xfa, 0xf9, 0xfd, + 0xfd, 0xfa, 0xf7, 0xf6, 0xf6, 0xf9, 0x02, 0x02, 0x09, 0x1a, 0x1c, 0x14, + 0x0a, 0x05, 0x01, 0x00, 0xfe, 0xf9, 0xf7, 0xf9, 0xfd, 0xfe, 0xff, 0x01, + 0x07, 0x14, 0x10, 0x0d, 0x0b, 0x05, 0x09, 0x09, 0x05, 0x06, 0x09, 0x05, + 0xff, 0x0a, 0x10, 0x14, 0x0d, 0x09, 0x05, 0x07, 0x0a, 0x03, 0xff, 0xfe, + 0xfb, 0xf7, 0xf7, 0xfb, 0xf3, 0xf5, 0xf3, 0xf5, 0xfa, 0xf9, 0xf9, 0xfb, + 0x01, 0x03, 0x0a, 0x18, 0x14, 0x17, 0x12, 0x16, 0x13, 0x0f, 0x07, 0x07, + 0x06, 0x03, 0x01, 0x07, 0x0a, 0x0b, 0x03, 0x03, 0x07, 0x0d, 0x09, 0x01, + 0xfb, 0xfe, 0xfb, 0xf9, 0xfd, 0xfe, 0xfb, 0xfa, 0xf9, 0xfe, 0xff, 0x0a, + 0x16, 0x0f, 0x05, 0xfb, 0xfb, 0x03, 0xff, 0x00, 0x00, 0xff, 0x05, 0x06, + 0x06, 0x05, 0x03, 0x05, 0x07, 0x05, 0x00, 0xff, 0xff, 0x02, 0x07, 0x0d, + 0x0f, 0x13, 0x0e, 0x1a, 0x1d, 0x1a, 0x13, 0x0b, 0x07, 0x02, 0xfd, 0xff, + 0xff, 0xff, 0xfe, 0xfe, 0xfd, 0xf9, 0xf9, 0xfe, 0xfa, 0xf6, 0xf2, 0xf2, + 0xf3, 0xfd, 0x01, 0x00, 0x03, 0x0b, 0x0d, 0x13, 0x13, 0x0d, 0x05, 0x06, + 0x03, 0x01, 0x00, 0xfd, 0xfe, 0xfd, 0xfa, 0xfe, 0x07, 0x05, 0x06, 0x0a, + 0x10, 0x10, 0x0d, 0x0b, 0x06, 0x05, 0x02, 0x00, 0x07, 0x18, 0x0b, 0x02, + 0x07, 0x0e, 0x13, 0x0e, 0x07, 0x01, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xfd, + 0x03, 0xfe, 0xf9, 0xf7, 0xf7, 0xf9, 0xfa, 0xf9, 0xf7, 0xfd, 0xfe, 0x03, + 0x09, 0x0d, 0x09, 0x03, 0x07, 0x0a, 0x0a, 0x05, 0x03, 0x00, 0x00, 0x05, + 0x05, 0x0d, 0x0e, 0x12, 0x1b, 0x1c, 0x13, 0x06, 0x06, 0x07, 0x01, 0xfa, + 0xf9, 0xff, 0x02, 0x02, 0x02, 0x03, 0x07, 0xff, 0xff, 0x09, 0x03, 0x0e, + 0x03, 0xfb, 0xf5, 0xf0, 0xf2, 0xfa, 0xfd, 0x01, 0xfe, 0xfd, 0xfe, 0xfe, + 0x05, 0x0d, 0x07, 0x06, 0x03, 0x0b, 0x0f, 0x0a, 0x0e, 0x12, 0x12, 0x10, + 0x0e, 0x16, 0x10, 0x13, 0x0a, 0x05, 0x00, 0xfd, 0xff, 0xff, 0x03, 0x06, + 0x06, 0x05, 0xfb, 0xf9, 0xf3, 0xf6, 0xfb, 0xf5, 0xf3, 0xf6, 0xf2, 0xf5, + 0xfa, 0xf9, 0xff, 0x0e, 0x0f, 0x16, 0x1c, 0x1c, 0x17, 0x0b, 0x02, 0x00, + 0xfd, 0xfd, 0xfd, 0x00, 0x05, 0x05, 0x00, 0x00, 0x02, 0x02, 0x06, 0x0f, + 0x0f, 0x0f, 0x0b, 0x0b, 0x0f, 0x0f, 0x0e, 0x0f, 0x0b, 0x06, 0x12, 0x07, + 0x00, 0xfe, 0xf9, 0xf0, 0xf9, 0x00, 0xf9, 0xfd, 0x06, 0x02, 0xfa, 0xf6, + 0xfa, 0xfb, 0xf7, 0xf6, 0xf9, 0xff, 0xfd, 0x00, 0x02, 0x00, 0x0b, 0x14, + 0x0e, 0x06, 0x09, 0x10, 0x07, 0x03, 0xfe, 0xff, 0x03, 0x0d, 0x13, 0x0e, + 0x14, 0x12, 0x0b, 0x09, 0x06, 0x03, 0x03, 0x09, 0x07, 0x0a, 0x06, 0xfe, + 0x07, 0x00, 0xf9, 0x00, 0x01, 0xff, 0x01, 0x0e, 0x07, 0xfd, 0xff, 0x00, + 0xfa, 0xf9, 0xfa, 0xfd, 0x05, 0x05, 0x01, 0xfb, 0xff, 0x03, 0xfe, 0xfa, + 0xfd, 0xfb, 0x01, 0x03, 0x05, 0x03, 0x01, 0x06, 0x0e, 0x13, 0x10, 0x1d, + 0x21, 0x1b, 0x0d, 0x05, 0x05, 0x03, 0xff, 0x01, 0x0d, 0x0d, 0x09, 0x06, + 0x07, 0xff, 0xfa, 0xf9, 0xfb, 0xf7, 0xf3, 0xfb, 0xfe, 0xfb, 0xf9, 0xfe, + 0x03, 0x03, 0x00, 0x03, 0x0a, 0x06, 0x03, 0xfb, 0xf6, 0xf5, 0xfe, 0x0a, + 0x10, 0x14, 0x0f, 0x0b, 0x05, 0x02, 0x00, 0x00, 0x05, 0x0b, 0x10, 0x14, + 0x0f, 0x0d, 0x06, 0x07, 0x0d, 0x0b, 0x06, 0x09, 0x16, 0x14, 0x07, 0xfa, + 0xf5, 0xfa, 0xfa, 0xfe, 0x03, 0x00, 0xfd, 0xf0, 0xf0, 0xf0, 0xf1, 0xec, + 0xf5, 0xfd, 0x00, 0x0b, 0x0d, 0x0b, 0x05, 0x02, 0x01, 0x09, 0x14, 0x0a, + 0x0a, 0x16, 0x0f, 0x03, 0x00, 0x01, 0x05, 0x07, 0x14, 0x17, 0x10, 0x0d, + 0x10, 0x0d, 0x0f, 0x0e, 0x0a, 0x09, 0x05, 0x05, 0x01, 0x01, 0xfd, 0xed, + 0xe8, 0xee, 0xfb, 0x05, 0xff, 0x00, 0x00, 0xfb, 0xfa, 0xfb, 0x01, 0x05, + 0x07, 0x07, 0x03, 0x00, 0x03, 0x06, 0x03, 0x02, 0xfe, 0xfd, 0x00, 0x07, + 0x05, 0x06, 0x05, 0x05, 0x05, 0x09, 0x0b, 0x0e, 0x12, 0x10, 0x16, 0x09, + 0x01, 0xfd, 0xfa, 0xfd, 0x0a, 0x17, 0x12, 0x0b, 0x0f, 0x0d, 0x06, 0xfd, + 0x00, 0xfe, 0xfd, 0xfd, 0xfe, 0xfe, 0x00, 0x00, 0xfb, 0xfe, 0x02, 0x03, + 0xff, 0x01, 0x0a, 0x07, 0x01, 0x01, 0xfd, 0xfe, 0x02, 0x05, 0x01, 0xff, + 0xff, 0xfa, 0xf5, 0xf7, 0xf5, 0xfb, 0x06, 0x16, 0x12, 0x10, 0x1a, 0x14, + 0x10, 0x13, 0x16, 0x17, 0x0d, 0x09, 0x0d, 0x14, 0x0d, 0x05, 0xf9, 0xfb, + 0x05, 0x07, 0x03, 0xfa, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfd, 0xf6, + 0xf9, 0xf9, 0xf5, 0xea, 0xed, 0xf1, 0xf6, 0xfe, 0x05, 0x0f, 0x16, 0x18, + 0x1a, 0x13, 0x17, 0x10, 0x0e, 0x14, 0x12, 0x0f, 0x10, 0x10, 0x0a, 0x06, + 0x07, 0x0e, 0x0d, 0x05, 0x02, 0x03, 0x05, 0x06, 0x00, 0xfe, 0xfb, 0xf9, + 0xf7, 0xf0, 0xea, 0xea, 0xf9, 0xf1, 0xed, 0xee, 0xf1, 0x00, 0x0d, 0x0e, + 0x0b, 0x0b, 0x0a, 0x0e, 0x13, 0x12, 0x06, 0x03, 0x06, 0x09, 0x07, 0x05, + 0x03, 0x05, 0x0a, 0x0d, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x0f, 0x09, 0x0e, + 0x0a, 0x0a, 0x09, 0x02, 0xff, 0x00, 0xfd, 0xf3, 0xf2, 0xff, 0xfa, 0xf6, + 0xf5, 0x01, 0xff, 0x07, 0x0f, 0x07, 0x01, 0x02, 0x02, 0x05, 0x03, 0x05, + 0x0a, 0x0b, 0x00, 0x00, 0x03, 0x05, 0x03, 0x06, 0x05, 0x05, 0x02, 0xff, + 0x02, 0x07, 0x02, 0xfe, 0xfe, 0x00, 0xff, 0x00, 0x01, 0x06, 0x0d, 0x0e, + 0x0d, 0x0e, 0x09, 0x14, 0x17, 0x27, 0x20, 0x13, 0x0d, 0x0b, 0xfb, 0xfa, + 0xfd, 0xfd, 0xfd, 0xfe, 0x01, 0xfd, 0xf9, 0xf6, 0xf6, 0xfb, 0xfd, 0xfb, + 0xf2, 0xf1, 0xf6, 0xfd, 0xfd, 0xfd, 0xfe, 0xff, 0x00, 0x0a, 0x0d, 0x05, + 0x07, 0x0d, 0x13, 0x0f, 0x0d, 0x1d, 0x21, 0x1d, 0x1c, 0x18, 0x12, 0x0d, + 0x09, 0x06, 0x03, 0x06, 0x02, 0xfe, 0x00, 0x00, 0xff, 0xf6, 0xe8, 0xf6, + 0xfd, 0xf9, 0xfe, 0xfe, 0xfe, 0x00, 0xfe, 0x00, 0x02, 0x06, 0x00, 0xf6, + 0xfb, 0xf9, 0xfa, 0xfb, 0x01, 0x00, 0x05, 0x1c, 0x17, 0x12, 0x0d, 0x0a, + 0x0d, 0x0d, 0x0b, 0x0a, 0x07, 0x05, 0x0b, 0x10, 0x0d, 0x0f, 0x09, 0x07, + 0x07, 0x01, 0x00, 0x05, 0x03, 0x01, 0x01, 0x00, 0xfd, 0xf9, 0xf1, 0xf3, + 0xf5, 0xf3, 0xf3, 0xf6, 0xf7, 0xfb, 0xf7, 0xff, 0x0b, 0x18, 0x12, 0x0f, + 0x0a, 0x0a, 0x0a, 0x07, 0x0b, 0x0b, 0x07, 0x06, 0x0a, 0x02, 0x02, 0x00, + 0xfe, 0x00, 0x03, 0x03, 0x01, 0x01, 0x02, 0x0a, 0x0a, 0x14, 0x0e, 0x07, + 0x06, 0x05, 0x02, 0x05, 0x09, 0x05, 0x06, 0x00, 0xfd, 0xfd, 0xfb, 0x14, + 0x14, 0x09, 0x01, 0xfd, 0xfd, 0xfb, 0xfb, 0xfb, 0xfb, 0xf9, 0xf7, 0xf6, + 0xf3, 0xf3, 0xf9, 0xff, 0x05, 0x0f, 0x0b, 0x06, 0x13, 0x16, 0x13, 0x16, + 0x14, 0x0e, 0x09, 0x09, 0x03, 0x00, 0x03, 0x06, 0x0a, 0x02, 0x05, 0x09, + 0x0e, 0x12, 0x0a, 0x09, 0x03, 0x00, 0xfa, 0xf9, 0xfd, 0xf9, 0xf2, 0xf6, + 0xfe, 0x02, 0x00, 0xff, 0x01, 0x01, 0x01, 0x07, 0x0a, 0x07, 0xff, 0x00, + 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x00, 0x03, 0x09, + 0x13, 0x17, 0x16, 0x16, 0x14, 0x1a, 0x16, 0x12, 0x0f, 0x0a, 0x01, 0xff, + 0x01, 0x00, 0x00, 0xff, 0xfe, 0xf9, 0xf9, 0xfb, 0xff, 0xfb, 0x01, 0x07, + 0x05, 0xff, 0xfb, 0xff, 0x01, 0x02, 0xfe, 0xf6, 0xf6, 0x00, 0x07, 0x03, + 0xfe, 0x01, 0x03, 0x0f, 0x14, 0x12, 0x0b, 0x05, 0x00, 0xfe, 0x03, 0x03, + 0x00, 0x01, 0x00, 0x06, 0x0b, 0x07, 0x07, 0x0f, 0x18, 0x17, 0x13, 0x10, + 0x0f, 0x17, 0x14, 0x0a, 0x01, 0x01, 0x00, 0x02, 0xfa, 0xf0, 0xf5, 0xf5, + 0xf6, 0xf0, 0xf6, 0xf9, 0xf7, 0xf7, 0xfe, 0x05, 0xff, 0xf9, 0xf7, 0xfd, + 0xff, 0x00, 0x09, 0x0d, 0x0b, 0x13, 0x23, 0x1d, 0x1b, 0x16, 0x13, 0x18, + 0x1a, 0x12, 0x0b, 0x07, 0x00, 0xfd, 0xfe, 0x00, 0xf9, 0xf6, 0xf6, 0xf7, + 0xf9, 0xfa, 0xf5, 0xf7, 0xff, 0xff, 0x00, 0x02, 0x02, 0x07, 0x0e, 0x0e, + 0x05, 0x02, 0x09, 0x0a, 0x02, 0x01, 0x02, 0x12, 0x09, 0x00, 0xfe, 0xff, + 0x01, 0x06, 0x0a, 0x06, 0x03, 0x01, 0x00, 0x01, 0x02, 0x01, 0x01, 0x05, + 0x02, 0x06, 0x0d, 0x0a, 0x07, 0x06, 0x0d, 0x0a, 0x06, 0x09, 0x0f, 0x0a, + 0x01, 0xfb, 0xf3, 0xf9, 0xfd, 0xff, 0x09, 0x12, 0x05, 0x02, 0x03, 0x00, + 0xff, 0x02, 0x03, 0x01, 0x00, 0x05, 0x07, 0x06, 0x01, 0x00, 0xff, 0x02, + 0xfe, 0x00, 0xff, 0xfe, 0xff, 0xfd, 0x00, 0x01, 0xfe, 0x01, 0x03, 0x09, + 0x12, 0x09, 0x06, 0x09, 0x0e, 0x0d, 0x09, 0x0f, 0x17, 0x1d, 0x17, 0x1b, + 0x0a, 0x00, 0x05, 0x0b, 0x07, 0x06, 0x05, 0xfb, 0xf1, 0xf0, 0xf2, 0xf6, + 0xf6, 0xf6, 0xf2, 0xed, 0xea, 0xf3, 0xf5, 0xf3, 0xfb, 0xf9, 0xfa, 0x01, + 0x01, 0x0b, 0x10, 0x1b, 0x23, 0x20, 0x23, 0x1d, 0x14, 0x18, 0x21, 0x1a, + 0x10, 0x05, 0x00, 0xfd, 0xfd, 0xfe, 0x00, 0x0a, 0x0b, 0x06, 0x00, 0xf9, + 0xf2, 0xf1, 0xf2, 0xf3, 0xfa, 0xfa, 0xff, 0xfd, 0x00, 0x03, 0x06, 0x03, + 0xff, 0x00, 0xff, 0x07, 0x0a, 0x07, 0x06, 0x06, 0x01, 0x01, 0x05, 0x0b, + 0x0d, 0x12, 0x12, 0x0b, 0x05, 0x03, 0x03, 0x03, 0x0a, 0x0a, 0x0a, 0x09, + 0x0b, 0x05, 0x02, 0xfe, 0xf2, 0xf3, 0xf9, 0x00, 0x00, 0xf7, 0xf7, 0xf2, + 0xf3, 0xfb, 0x00, 0x06, 0x0a, 0x1c, 0x17, 0x05, 0x05, 0x07, 0x07, 0x0b, + 0x17, 0x14, 0x0d, 0x07, 0x09, 0x03, 0x05, 0x06, 0x00, 0x01, 0x02, 0x03, + 0xff, 0xf6, 0xf2, 0xf1, 0xf2, 0xfa, 0xf9, 0xfb, 0x00, 0x09, 0x05, 0x03, + 0x05, 0xff, 0xfd, 0x01, 0x0b, 0x1b, 0x1d, 0x25, 0x1f, 0x1d, 0x16, 0x0f, + 0x0b, 0x0d, 0x0b, 0x09, 0x06, 0xfe, 0xee, 0xe8, 0xf1, 0xf6, 0xf7, 0xfb, + 0xfe, 0xfd, 0xf7, 0xf5, 0xf0, 0xf0, 0xf0, 0xf1, 0xfd, 0xff, 0xff, 0x03, + 0x0d, 0x1f, 0x25, 0x21, 0x18, 0x1c, 0x17, 0x10, 0x12, 0x16, 0x0d, 0x07, + 0x02, 0x02, 0x02, 0x03, 0x06, 0x09, 0x05, 0xff, 0xfe, 0xfa, 0xf7, 0xf9, + 0x00, 0x02, 0xfe, 0xfe, 0x00, 0x02, 0xf9, 0xfb, 0xfd, 0xfe, 0xfe, 0x01, + 0x00, 0xff, 0x01, 0xff, 0x00, 0x00, 0xfd, 0x01, 0x09, 0x06, 0x0d, 0x0f, + 0x0a, 0x06, 0x0a, 0x0d, 0x0f, 0x10, 0x0d, 0x0d, 0x0b, 0x16, 0x0e, 0x09, + 0x05, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xfa, 0xf6, 0xf2, 0xf2, 0xf6, + 0xff, 0x05, 0x06, 0x0b, 0x17, 0x0a, 0xfe, 0xff, 0x01, 0x05, 0x06, 0x06, + 0x0d, 0x14, 0x16, 0x0b, 0x09, 0x02, 0x05, 0x05, 0x03, 0xfb, 0xf7, 0xf9, + 0x01, 0x05, 0x02, 0x02, 0x02, 0x01, 0x01, 0xff, 0xfd, 0xf5, 0xf1, 0xf9, + 0x00, 0xff, 0x03, 0x0b, 0x13, 0x17, 0x20, 0x1a, 0x10, 0x0a, 0x0b, 0x03, + 0x00, 0x05, 0x09, 0x01, 0xfe, 0xfa, 0xff, 0x06, 0x07, 0x03, 0x02, 0x00, + 0xfe, 0xfd, 0xfa, 0xf7, 0xf9, 0xfa, 0x00, 0x02, 0x00, 0x02, 0x0b, 0x0b, + 0x0b, 0x07, 0x07, 0x10, 0x14, 0x10, 0x0a, 0x09, 0x06, 0x02, 0xff, 0xfe, + 0xfe, 0xfb, 0xff, 0x0b, 0x10, 0x0a, 0x07, 0x09, 0x06, 0x07, 0x05, 0xff, + 0xfd, 0xfd, 0x06, 0x09, 0x06, 0xfe, 0xfd, 0xf9, 0xfb, 0xfb, 0xff, 0xff, + 0xfa, 0xfb, 0xfe, 0x03, 0x02, 0x05, 0x07, 0x07, 0x0a, 0x0d, 0x0e, 0x09, + 0x0d, 0x0d, 0x06, 0x03, 0x0a, 0x12, 0x14, 0x0e, 0x0e, 0x0d, 0x06, 0x06, + 0x05, 0xfe, 0xf7, 0xf9, 0xfa, 0xff, 0x02, 0xfe, 0xfd, 0x00, 0x01, 0xfe, + 0xfe, 0x02, 0x05, 0x05, 0xff, 0xfd, 0x05, 0x12, 0x0a, 0x05, 0x0d, 0x16, + 0x12, 0x06, 0xfa, 0xf3, 0xf5, 0xf9, 0x00, 0x07, 0x02, 0x00, 0x01, 0x07, + 0x09, 0x07, 0x02, 0x02, 0x05, 0x06, 0x00, 0xff, 0x06, 0x0a, 0x00, 0x00, + 0x01, 0x07, 0x13, 0x1a, 0x16, 0x14, 0x0b, 0x03, 0x09, 0x06, 0x01, 0xfe, + 0xfe, 0x02, 0x01, 0xfd, 0xf3, 0xf2, 0xf3, 0xfa, 0x02, 0x06, 0x05, 0x02, + 0x07, 0x07, 0xfd, 0xfb, 0xfd, 0xfa, 0x01, 0x0a, 0x0f, 0x17, 0x13, 0x0b, + 0x0d, 0x14, 0x13, 0x0b, 0x03, 0xfb, 0xfa, 0xf9, 0xfa, 0xff, 0x03, 0xff, + 0xfa, 0xfb, 0x03, 0x09, 0x06, 0x07, 0xfe, 0xf9, 0xff, 0xff, 0x07, 0x12, + 0x10, 0x0d, 0x05, 0xff, 0x06, 0x07, 0x01, 0x00, 0x03, 0x05, 0x0a, 0x0b, + 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x01, 0x03, 0x00, 0x01, 0x05, 0x02, 0x03, + 0x05, 0x02, 0x02, 0x06, 0x07, 0x07, 0x01, 0xfa, 0xf5, 0xfa, 0xfb, 0x01, + 0xff, 0x09, 0x0f, 0x0a, 0x0b, 0x0d, 0x05, 0x03, 0xfe, 0xfd, 0x01, 0x07, + 0x16, 0x14, 0x06, 0xfe, 0x01, 0x00, 0xfd, 0x05, 0x0a, 0x09, 0x06, 0x03, + 0x06, 0x02, 0xff, 0xfd, 0xf9, 0xfb, 0x07, 0x0b, 0x01, 0xfb, 0xfd, 0x01, + 0x03, 0x0a, 0x03, 0x02, 0x05, 0x0b, 0x0b, 0x06, 0x01, 0xff, 0x01, 0x0d, + 0x1c, 0x1c, 0x1b, 0x16, 0x10, 0x07, 0x00, 0xfd, 0xf9, 0xf6, 0xfa, 0xf9, + 0xf7, 0xf6, 0xf5, 0xf7, 0x00, 0x01, 0xff, 0x00, 0x09, 0x0a, 0xff, 0xf5, + 0xf2, 0xf0, 0xfa, 0x06, 0x13, 0x0f, 0x10, 0x10, 0x0d, 0x0f, 0x0f, 0x16, + 0x16, 0x10, 0x14, 0x0e, 0x06, 0x01, 0xfe, 0xfb, 0xfb, 0xf7, 0xfb, 0xfe, + 0x05, 0x0b, 0x02, 0x05, 0x06, 0x00, 0xfa, 0xfb, 0x03, 0x00, 0x05, 0x03, + 0xfb, 0xf1, 0xf3, 0xff, 0x0a, 0x0b, 0x0a, 0x0a, 0x07, 0x06, 0x10, 0x12, + 0x07, 0x01, 0x03, 0x03, 0x0d, 0x10, 0x0a, 0x06, 0x05, 0x03, 0x00, 0x01, + 0x05, 0xfd, 0xf9, 0xf9, 0xff, 0xff, 0xf7, 0xfb, 0xf9, 0xf6, 0xfd, 0x00, + 0x02, 0xfd, 0xfe, 0x06, 0x09, 0x07, 0x0a, 0x0a, 0x0e, 0x18, 0x18, 0x0d, + 0x05, 0x0d, 0x0b, 0x0f, 0x1a, 0x0f, 0x0d, 0x0a, 0x0e, 0x07, 0x03, 0xff, + 0xf7, 0xf2, 0xf5, 0xfd, 0xfd, 0xf9, 0x00, 0xfe, 0xfb, 0xfb, 0xfa, 0xfa, + 0xf9, 0xfa, 0xfd, 0x01, 0x00, 0xf7, 0xf9, 0x05, 0x12, 0x18, 0x1b, 0x1c, + 0x20, 0x1c, 0x17, 0x12, 0x0b, 0x02, 0x03, 0x06, 0x02, 0x01, 0xfe, 0xf6, + 0xf5, 0xf5, 0xf5, 0xf9, 0x00, 0x05, 0x01, 0xfe, 0x00, 0x00, 0xff, 0xf7, + 0xfe, 0xfb, 0xff, 0x06, 0x0f, 0x0d, 0x09, 0x07, 0x16, 0x1c, 0x1a, 0x18, + 0x0e, 0x0a, 0x0b, 0x07, 0xff, 0xfe, 0xfe, 0x03, 0x09, 0x0e, 0x0b, 0x03, + 0xff, 0xfe, 0xfb, 0xfb, 0xfa, 0xf5, 0xf6, 0xf6, 0xf5, 0xfd, 0xf7, 0xf1, + 0xf5, 0xf9, 0x03, 0x0b, 0x03, 0x06, 0x0b, 0x09, 0x0b, 0x0b, 0x0f, 0x0e, + 0x0e, 0x12, 0x0d, 0x09, 0x0a, 0x05, 0x03, 0x09, 0x18, 0x13, 0x09, 0x02, + 0x00, 0xff, 0x01, 0xf9, 0xf3, 0xf3, 0xf1, 0xfa, 0xfb, 0xfd, 0x00, 0x00, + 0xff, 0x00, 0x07, 0x0b, 0x05, 0x05, 0x07, 0x0b, 0x0f, 0x0b, 0x01, 0x05, + 0x12, 0x14, 0x10, 0x0e, 0x09, 0x03, 0x07, 0x09, 0x06, 0x03, 0xfe, 0x00, + 0xfe, 0xfa, 0xfb, 0xfd, 0xfb, 0xfb, 0xf9, 0xfa, 0xfb, 0xfd, 0xf6, 0xf2, + 0xf9, 0xfe, 0x02, 0xff, 0x03, 0x03, 0x09, 0x12, 0x0f, 0x0d, 0x12, 0x17, + 0x14, 0x1a, 0x16, 0x14, 0x0d, 0x05, 0x06, 0x07, 0x03, 0xfe, 0xff, 0x02, + 0x05, 0x0d, 0x0e, 0x05, 0x01, 0x00, 0xfd, 0xf9, 0xff, 0xf7, 0xf5, 0xfb, + 0xf5, 0xf9, 0x02, 0x06, 0x07, 0x09, 0x0f, 0x0f, 0x0a, 0x06, 0xff, 0x00, + 0x03, 0x03, 0x07, 0x00, 0x00, 0x01, 0x0a, 0x0b, 0x0d, 0x09, 0x03, 0x00, + 0x0b, 0x10, 0x0d, 0x06, 0xfe, 0xf6, 0xf3, 0xf9, 0xf5, 0xee, 0xf1, 0xf3, + 0x00, 0x03, 0x03, 0x06, 0x0d, 0x14, 0x17, 0x0a, 0x05, 0x07, 0x10, 0x09, + 0x03, 0x06, 0x09, 0x09, 0x12, 0x17, 0x0f, 0x0d, 0x07, 0x01, 0xfd, 0x00, + 0x03, 0x03, 0xfd, 0xfd, 0xfe, 0xfd, 0xfe, 0xfd, 0xfd, 0xff, 0xfd, 0xf7, + 0xfb, 0xff, 0x07, 0x05, 0x05, 0x0b, 0x0b, 0x02, 0x06, 0x06, 0x09, 0x0f, + 0x09, 0x02, 0xff, 0xfe, 0x03, 0x14, 0x0f, 0x05, 0x01, 0x02, 0x00, 0x00, + 0xff, 0x02, 0xff, 0xfe, 0x00, 0x01, 0x06, 0x06, 0x01, 0xf9, 0xf7, 0xfb, + 0x03, 0xff, 0x02, 0x0b, 0x0f, 0x0d, 0x07, 0x0d, 0x0f, 0x10, 0x12, 0x10, + 0x0f, 0x0b, 0x09, 0x03, 0x00, 0x01, 0x03, 0x01, 0xfd, 0xff, 0x03, 0x07, + 0x02, 0x03, 0x00, 0xfd, 0x00, 0x01, 0xff, 0xfd, 0xfb, 0xf9, 0xf9, 0xfb, + 0xfb, 0xff, 0x0d, 0x0a, 0x07, 0x0b, 0x09, 0x01, 0x05, 0x0e, 0x0a, 0x06, + 0x03, 0xfe, 0x00, 0x05, 0x05, 0x02, 0x00, 0x03, 0x13, 0x14, 0x0f, 0x0f, + 0x06, 0x00, 0x00, 0xfe, 0xf9, 0xfa, 0xfd, 0x00, 0xfe, 0x06, 0x06, 0x07, + 0x0d, 0x0e, 0x12, 0x0d, 0x07, 0x05, 0x01, 0x06, 0x06, 0x06, 0x07, 0x07, + 0x0a, 0x09, 0x05, 0x07, 0x03, 0xfa, 0xf9, 0xf7, 0xf3, 0xff, 0xff, 0x01, + 0xf7, 0xf6, 0xfa, 0xfb, 0x01, 0x05, 0x01, 0xff, 0xfd, 0x00, 0x02, 0x0e, + 0x17, 0x18, 0x18, 0x0f, 0x0e, 0x05, 0x05, 0x03, 0x01, 0x01, 0x00, 0x03, + 0x07, 0x0a, 0x0b, 0x09, 0x00, 0xfb, 0xfe, 0xfd, 0xff, 0xfe, 0xff, 0x00, + 0xfe, 0xfd, 0xfe, 0x01, 0x06, 0x06, 0x03, 0xff, 0x05, 0x07, 0x0e, 0x12, + 0x0b, 0x0f, 0x0a, 0x0b, 0x0f, 0x0b, 0x06, 0x02, 0x05, 0x02, 0x03, 0x05, + 0x05, 0x06, 0x09, 0x00, 0xf7, 0xf7, 0xf7, 0xfb, 0x03, 0xfe, 0xf6, 0xf9, + 0x09, 0x03, 0xfe, 0xfe, 0x00, 0xff, 0xfb, 0xf9, 0xfb, 0x02, 0x0d, 0x06, + 0x09, 0x0a, 0x12, 0x1f, 0x1b, 0x12, 0x0d, 0x03, 0x02, 0xff, 0xfd, 0xfa, + 0x00, 0x02, 0x05, 0x09, 0x18, 0x13, 0x0b, 0x09, 0x02, 0xfe, 0xfb, 0xf9, + 0xfa, 0x00, 0x00, 0xf2, 0xf6, 0xfa, 0xfd, 0x06, 0x06, 0x09, 0x0d, 0x0d, + 0x0d, 0x09, 0x06, 0x07, 0x0e, 0x0a, 0x06, 0x07, 0x0e, 0x0b, 0x06, 0x00, + 0xf7, 0xfb, 0xf9, 0xf9, 0xfa, 0x01, 0x03, 0xfe, 0xfe, 0xfe, 0xf7, 0xf9, + 0xfe, 0xfd, 0xfd, 0xfd, 0xfa, 0xfa, 0xff, 0x06, 0x16, 0x1b, 0x1b, 0x18, + 0x1b, 0x1b, 0x17, 0x13, 0x0b, 0x09, 0x09, 0x0b, 0x09, 0x07, 0x07, 0x02, + 0xfe, 0xf9, 0xfe, 0x00, 0xfe, 0xfe, 0x00, 0x05, 0xfb, 0xf1, 0xf2, 0xf2, + 0xf2, 0xf7, 0xf7, 0xfa, 0x07, 0x07, 0x05, 0x03, 0x06, 0x0d, 0x0d, 0x02, + 0x0a, 0x12, 0x10, 0x0e, 0x0b, 0x07, 0x0d, 0x0b, 0x0e, 0x10, 0x0e, 0x0a, + 0x02, 0xfe, 0xfe, 0xf5, 0xf6, 0xfd, 0xfb, 0xfe, 0x0a, 0x0b, 0x0a, 0x03, + 0xfd, 0xf6, 0xf1, 0xec, 0xf2, 0xfd, 0x03, 0x00, 0x00, 0x0a, 0x17, 0x14, + 0x1a, 0x1b, 0x13, 0x10, 0x0f, 0x0b, 0x0a, 0x06, 0x07, 0x0a, 0x03, 0x09, + 0x13, 0x0b, 0x06, 0x02, 0xfe, 0xf6, 0xf5, 0xf3, 0xf5, 0xfb, 0xfd, 0xfa, + 0xf5, 0xf6, 0xf9, 0xf3, 0xfb, 0x03, 0x06, 0x09, 0x0e, 0x05, 0x01, 0x01, + 0x0b, 0x0d, 0x0f, 0x10, 0x1b, 0x1b, 0x13, 0x09, 0x07, 0x02, 0xff, 0x01, + 0xff, 0x02, 0x03, 0x01, 0x01, 0xfd, 0xfa, 0xf7, 0xf5, 0xf7, 0xfb, 0xfd, + 0xfd, 0xfd, 0xfd, 0x00, 0x06, 0x02, 0x06, 0x14, 0x2d, 0x29, 0x17, 0x0d, + 0x10, 0x10, 0x09, 0x03, 0x03, 0x06, 0x05, 0x06, 0x05, 0x01, 0x00, 0x02, + 0x02, 0x00, 0x00, 0xfe, 0xf9, 0xf5, 0xf2, 0xf3, 0xee, 0xec, 0xf3, 0xfb, + 0x05, 0x01, 0x02, 0x0a, 0x0a, 0x01, 0xff, 0x0a, 0x0f, 0x0b, 0x0b, 0x0b, + 0x07, 0x09, 0x0d, 0x10, 0x0e, 0x0d, 0x10, 0x12, 0x0f, 0x06, 0x01, 0x03, + 0x03, 0x01, 0xfe, 0x05, 0x0f, 0x0f, 0x0d, 0x03, 0xfb, 0xf5, 0xec, 0xe9, + 0xed, 0xf7, 0xf9, 0xfe, 0x02, 0x05, 0x07, 0x0a, 0x09, 0x06, 0x0e, 0x14, + 0x0d, 0x06, 0x03, 0x05, 0x05, 0x03, 0x01, 0x0d, 0x17, 0x14, 0x0e, 0x09, + 0x09, 0x06, 0x00, 0xfa, 0xf9, 0xf7, 0xfa, 0xfd, 0xf9, 0xf7, 0xfa, 0xfd, + 0xfa, 0xf3, 0xf9, 0x03, 0x03, 0x05, 0x0b, 0x0b, 0x02, 0x01, 0x03, 0x16, + 0x28, 0x1c, 0x0f, 0x09, 0x05, 0x05, 0x02, 0xfe, 0x00, 0x03, 0x0b, 0x09, + 0x03, 0x06, 0x09, 0x06, 0x06, 0xff, 0xff, 0x00, 0xfb, 0xf1, 0xf3, 0xf3, + 0xf0, 0xf1, 0xf7, 0x06, 0x20, 0x18, 0x13, 0x10, 0x0f, 0x0e, 0x0a, 0x07, + 0x06, 0x05, 0x09, 0x09, 0x05, 0x05, 0xfe, 0xfb, 0x05, 0x00, 0xfd, 0xfe, + 0x03, 0x03, 0x00, 0xfa, 0xf7, 0xf9, 0xf9, 0xff, 0x0b, 0x06, 0x01, 0xfd, + 0x00, 0x06, 0x03, 0x02, 0x02, 0x05, 0x0e, 0x0e, 0x05, 0x09, 0x12, 0x0e, + 0x0b, 0x0b, 0x12, 0x14, 0x12, 0x09, 0x02, 0xfd, 0x00, 0x01, 0x02, 0x09, + 0x0f, 0x0e, 0x09, 0x01, 0xfe, 0x00, 0xfd, 0xf6, 0xed, 0xea, 0xf1, 0xf5, + 0xf7, 0xfb, 0xfb, 0x05, 0x03, 0x00, 0x06, 0x0d, 0x0b, 0x0d, 0x07, 0x02, + 0x06, 0x09, 0x02, 0x0f, 0x24, 0x25, 0x1a, 0x10, 0x02, 0xfe, 0xfd, 0xfd, + 0xfb, 0xf7, 0xf7, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x01, 0xfd, 0xfb, + 0xfd, 0x00, 0x05, 0xff, 0xff, 0x01, 0x06, 0x0e, 0x1b, 0x1d, 0x13, 0x0d, + 0x0a, 0x02, 0x01, 0x03, 0xff, 0x02, 0x02, 0x03, 0x03, 0x05, 0x01, 0xff, + 0x01, 0xff, 0xfd, 0xfe, 0xfe, 0xff, 0x02, 0xff, 0xf6, 0xf5, 0xf9, 0x05, + 0x0d, 0x14, 0x18, 0x0e, 0x05, 0x00, 0x07, 0x0f, 0x10, 0x0e, 0x09, 0x02, + 0x01, 0x01, 0x01, 0x03, 0x06, 0x01, 0x00, 0x02, 0x01, 0x02, 0x03, 0xff, + 0xf3, 0xed, 0xf5, 0x02, 0x09, 0x06, 0x0a, 0x06, 0x03, 0x03, 0x0a, 0x07, + 0x0b, 0x0b, 0x06, 0x06, 0x03, 0x09, 0x13, 0x12, 0x06, 0x07, 0x06, 0x06, + 0x03, 0x01, 0x03, 0x00, 0xf5, 0xfb, 0x05, 0x09, 0x14, 0x12, 0x0e, 0x0b, + 0x03, 0xfa, 0xf5, 0xf5, 0xf7, 0xf5, 0xf0, 0xf0, 0xf1, 0xfa, 0x03, 0x09, + 0x0d, 0x09, 0x06, 0x01, 0x03, 0x07, 0x0e, 0x0d, 0x06, 0x05, 0x06, 0x10, + 0x18, 0x18, 0x17, 0x12, 0x0a, 0x06, 0x02, 0x01, 0xfe, 0x00, 0xff, 0xfd, + 0x01, 0x03, 0x06, 0xfd, 0xfa, 0x00, 0xff, 0xfd, 0xfb, 0xfb, 0x00, 0x06, + 0x02, 0x02, 0x03, 0x09, 0x0d, 0x0f, 0x13, 0x0b, 0x0b, 0x07, 0xfd, 0xfd, + 0x02, 0x01, 0x00, 0xff, 0x00, 0xff, 0x00, 0xfd, 0xfb, 0x03, 0x06, 0x05, + 0x00, 0x02, 0x0a, 0x05, 0xff, 0xfe, 0xfe, 0x02, 0x01, 0x07, 0x0a, 0x0d, + 0x16, 0x10, 0x05, 0x07, 0x0d, 0x12, 0x0e, 0x07, 0x03, 0x02, 0x07, 0x05, + 0xfe, 0xff, 0x01, 0x01, 0x00, 0x00, 0xfb, 0xfa, 0xf3, 0xf3, 0xf5, 0xfe, + 0x0b, 0x0a, 0x05, 0x02, 0x07, 0x05, 0xfd, 0xf6, 0x00, 0x00, 0x03, 0x03, + 0x06, 0x06, 0x09, 0x0d, 0x13, 0x1f, 0x18, 0x0e, 0x02, 0x00, 0x01, 0x06, + 0x02, 0xfe, 0xfd, 0x06, 0x10, 0x14, 0x0b, 0xff, 0xff, 0x02, 0xf7, 0xf1, + 0xf2, 0xf6, 0xfe, 0xfa, 0xfb, 0xf7, 0xfa, 0xff, 0x01, 0x09, 0x02, 0xff, + 0x03, 0x03, 0x05, 0x07, 0x09, 0x0e, 0x16, 0x17, 0x18, 0x1c, 0x17, 0x0d, + 0x0b, 0x0e, 0x0b, 0x09, 0x06, 0x00, 0xfe, 0xfe, 0xfa, 0xf7, 0xf3, 0xfa, + 0xfb, 0xf7, 0xf7, 0xfd, 0x00, 0x00, 0xfe, 0x00, 0x06, 0x02, 0x03, 0x0e, + 0x0d, 0x09, 0x09, 0x09, 0x07, 0x0d, 0x0b, 0x06, 0x0d, 0x06, 0xff, 0xff, + 0xfe, 0xfe, 0x00, 0x03, 0x05, 0x01, 0xff, 0xff, 0x00, 0x07, 0x03, 0xff, + 0xfa, 0xfa, 0xfb, 0x00, 0x07, 0x0f, 0x12, 0x0d, 0x09, 0x09, 0x0e, 0x10, + 0x09, 0x07, 0x05, 0x05, 0x07, 0x07, 0x05, 0x0a, 0x0f, 0x07, 0x05, 0x01, + 0xfb, 0xfe, 0xfd, 0xfe, 0xfb, 0xf6, 0xf6, 0xfb, 0x03, 0x03, 0x03, 0x01, + 0xfe, 0xfa, 0xf7, 0xfe, 0xf9, 0xf5, 0xfb, 0x09, 0x0f, 0x0b, 0x0a, 0x0b, + 0x16, 0x17, 0x12, 0x0b, 0x09, 0x16, 0x0f, 0x06, 0x02, 0x05, 0x06, 0x0a, + 0x12, 0x17, 0x0d, 0x07, 0xff, 0xfd, 0xfe, 0x03, 0xfe, 0xf6, 0xf3, 0xec, + 0xf2, 0xf3, 0xf2, 0xf2, 0xf6, 0xf6, 0xfd, 0x01, 0x00, 0x09, 0x10, 0x0d, + 0x0a, 0x07, 0x0e, 0x12, 0x16, 0x1a, 0x16, 0x12, 0x0d, 0x06, 0x03, 0x09, + 0x0f, 0x0b, 0x0a, 0x03, 0xff, 0xfe, 0xff, 0xfe, 0x00, 0xfe, 0xfb, 0xf3, + 0xf7, 0xfb, 0xfe, 0xf7, 0xf3, 0xf6, 0x01, 0x05, 0x09, 0x0f, 0x0b, 0x0d, + 0x13, 0x0a, 0x06, 0x0a, 0x10, 0x10, 0x05, 0x00, 0xfd, 0xfe, 0x02, 0x05, + 0x05, 0x05, 0x03, 0x03, 0x01, 0x03, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x06, 0x0b, 0x05, 0x02, 0x07, 0x05, 0x09, 0x03, 0x01, 0x03, 0x00, 0x02, + 0x00, 0x02, 0x09, 0x0d, 0x10, 0x1a, 0x0f, 0x03, 0x00, 0xff, 0x00, 0xff, + 0xfe, 0xff, 0xff, 0xff, 0x05, 0x0a, 0x06, 0x03, 0xfe, 0xfd, 0xf9, 0xfa, + 0xfa, 0xfb, 0xfb, 0xf5, 0xf2, 0x00, 0x0b, 0x0d, 0x09, 0x0a, 0x06, 0x02, + 0x07, 0x13, 0x10, 0x10, 0x18, 0x1b, 0x1b, 0x0e, 0x0b, 0x0e, 0x0a, 0x09, + 0x06, 0x05, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xf0, 0xec, 0xf2, 0xfd, + 0xf9, 0xf7, 0xf5, 0xf2, 0xf9, 0x00, 0x02, 0x05, 0x07, 0x05, 0x02, 0x05, + 0x07, 0x0e, 0x14, 0x13, 0x13, 0x13, 0x13, 0x14, 0x10, 0x09, 0x06, 0x02, + 0x02, 0x03, 0x03, 0x09, 0x0a, 0x06, 0x03, 0xfd, 0xfe, 0xfb, 0xfd, 0xf9, + 0xfb, 0xfb, 0xf6, 0xfa, 0x05, 0x12, 0x0f, 0x07, 0x03, 0x02, 0x01, 0xff, + 0x00, 0xfd, 0xfa, 0xfd, 0x02, 0x07, 0x09, 0x0a, 0x0f, 0x0d, 0x0b, 0x09, + 0x03, 0x03, 0x03, 0x01, 0x03, 0x02, 0xff, 0xff, 0x02, 0x07, 0x0d, 0x07, + 0x05, 0x03, 0x00, 0x02, 0x07, 0x0b, 0x07, 0x05, 0xfe, 0xf5, 0xfa, 0x01, + 0x03, 0xff, 0xfe, 0x02, 0x0a, 0x07, 0x03, 0x00, 0x07, 0x0e, 0x10, 0x06, + 0x03, 0x0a, 0x0d, 0x07, 0x03, 0x00, 0xfd, 0xfe, 0xff, 0xfd, 0xf7, 0xf9, + 0xf9, 0xf5, 0xfa, 0x02, 0x0b, 0x0d, 0x06, 0x02, 0x05, 0x0a, 0x09, 0x07, + 0x09, 0x0b, 0x0e, 0x0a, 0x13, 0x16, 0x12, 0x0d, 0x06, 0x05, 0x07, 0x05, + 0x0b, 0x07, 0x01, 0xfa, 0xfb, 0xf3, 0xf6, 0xf9, 0xfb, 0xfa, 0xf7, 0xf7, + 0xf7, 0xf9, 0xf9, 0x00, 0x0a, 0x0d, 0x09, 0x05, 0x02, 0x07, 0x12, 0x12, + 0x09, 0x03, 0x02, 0x09, 0x12, 0x0a, 0x02, 0xfd, 0xfe, 0x0b, 0x0b, 0x0f, + 0x0e, 0x0d, 0x13, 0x0b, 0x06, 0x05, 0xfb, 0xf7, 0xf9, 0xfb, 0xfb, 0xf6, + 0xfb, 0x05, 0x0d, 0x12, 0x0b, 0x09, 0x03, 0x00, 0x01, 0x01, 0xfd, 0xf5, + 0xf7, 0x00, 0xfd, 0xfa, 0x01, 0x0a, 0x0d, 0x02, 0x00, 0x05, 0x02, 0x06, + 0x0d, 0x10, 0x0b, 0x05, 0x03, 0x05, 0x09, 0x06, 0x02, 0x02, 0x03, 0x07, + 0x05, 0x06, 0x0e, 0x0d, 0x0a, 0x0f, 0x02, 0xfb, 0xff, 0x02, 0x00, 0xfe, + 0xfa, 0xff, 0x01, 0x02, 0x02, 0x00, 0xff, 0x01, 0x07, 0x07, 0x03, 0x05, + 0x09, 0x0e, 0x01, 0xff, 0x02, 0x0d, 0x06, 0xfa, 0xf6, 0xfd, 0xff, 0xfd, + 0xff, 0x07, 0x09, 0x05, 0x02, 0x01, 0x00, 0x05, 0x12, 0x16, 0x10, 0x09, + 0x06, 0x07, 0x0e, 0x1f, 0x17, 0x0a, 0xfb, 0xf9, 0xff, 0xfe, 0xfa, 0xf9, + 0xfa, 0xf9, 0x02, 0xfd, 0xfa, 0xfb, 0xfa, 0x00, 0x05, 0xfe, 0xf9, 0x00, + 0x07, 0x0d, 0x0d, 0x07, 0x07, 0x0a, 0x0a, 0x0b, 0x0b, 0x09, 0x06, 0x02, + 0x01, 0x00, 0x00, 0x03, 0x03, 0x01, 0x06, 0x07, 0x06, 0x05, 0x03, 0x05, + 0x0d, 0x05, 0x02, 0x06, 0x0d, 0x01, 0xf3, 0xfd, 0xfb, 0x02, 0x00, 0x0a, + 0x12, 0x12, 0x0b, 0x03, 0x00, 0x00, 0x02, 0x03, 0x01, 0xf6, 0xfb, 0x00, + 0xff, 0xfd, 0x01, 0x06, 0x05, 0x03, 0x03, 0x05, 0x05, 0x03, 0x05, 0x07, + 0x05, 0xfd, 0xfe, 0x06, 0x0b, 0x0b, 0x0b, 0x03, 0xff, 0x03, 0x09, 0x10, + 0x10, 0x0a, 0x06, 0x0b, 0x09, 0xfe, 0xfd, 0x03, 0xff, 0xfb, 0xf9, 0xfa, + 0x06, 0x06, 0x0e, 0x07, 0x02, 0x02, 0x03, 0x06, 0x09, 0x03, 0xff, 0xfd, + 0xf9, 0xf7, 0xfb, 0xff, 0x03, 0x00, 0xfe, 0x01, 0x05, 0x06, 0x01, 0x00, + 0x05, 0x0b, 0x07, 0x02, 0x06, 0x13, 0x13, 0x0b, 0x09, 0x0a, 0x0b, 0x0b, + 0x12, 0x14, 0x1b, 0x16, 0x0a, 0xfa, 0x00, 0x00, 0xfa, 0xf9, 0xf6, 0xfb, + 0xf9, 0xf3, 0xf5, 0xf1, 0xf2, 0xf2, 0xfa, 0xff, 0x03, 0x09, 0x01, 0x00, + 0x07, 0x09, 0x0a, 0x13, 0x1b, 0x1b, 0x17, 0x0b, 0x02, 0x01, 0x03, 0x02, + 0x00, 0x00, 0x00, 0x07, 0x12, 0x0d, 0x07, 0x05, 0x07, 0x09, 0x02, 0x00, + 0xff, 0x02, 0x05, 0x02, 0xf9, 0xf1, 0xf6, 0xfe, 0x06, 0x05, 0x02, 0x05, + 0x00, 0xff, 0x00, 0x02, 0x10, 0x0b, 0x05, 0x05, 0x0d, 0x05, 0x01, 0xff, + 0x06, 0x10, 0x07, 0x02, 0x05, 0x07, 0x0b, 0x03, 0x05, 0x00, 0xfd, 0xfa, + 0xfb, 0x03, 0x01, 0x00, 0xff, 0xff, 0x03, 0x0b, 0x09, 0x05, 0x01, 0x03, + 0x0e, 0x0f, 0x0a, 0x05, 0xff, 0x03, 0x06, 0x01, 0xff, 0x01, 0x09, 0x0b, + 0x0b, 0x0f, 0x07, 0x03, 0x02, 0x00, 0x05, 0x02, 0x00, 0xfb, 0xff, 0xff, + 0xfd, 0xfa, 0xfa, 0xfa, 0xfe, 0x02, 0x05, 0x01, 0xff, 0xfd, 0xfb, 0xff, + 0x07, 0x07, 0x0a, 0x12, 0x12, 0x0b, 0x0b, 0x13, 0x16, 0x0e, 0x16, 0x14, + 0x14, 0x13, 0x12, 0x06, 0xfe, 0xf9, 0xf2, 0xf1, 0xf3, 0xff, 0xff, 0xfd, + 0xfe, 0xfd, 0xf5, 0xf7, 0xf7, 0xfa, 0x00, 0x06, 0x01, 0xfa, 0xfd, 0x02, + 0x0a, 0x0b, 0x10, 0x13, 0x12, 0x10, 0x07, 0xff, 0x02, 0x06, 0x03, 0x01, + 0x0b, 0x14, 0x0e, 0x0b, 0x09, 0x07, 0x03, 0x02, 0xfb, 0xfd, 0x03, 0x0a, + 0x0e, 0x0b, 0x0d, 0xff, 0xf7, 0xfa, 0xf9, 0xff, 0xfd, 0xfb, 0xfe, 0xfa, + 0xfd, 0x01, 0xff, 0xfa, 0x00, 0x06, 0x0a, 0x06, 0x01, 0x01, 0x01, 0x10, + 0x14, 0x12, 0x12, 0x0d, 0x10, 0x0d, 0x02, 0xfe, 0xf9, 0xfa, 0xfb, 0x01, + 0x05, 0x06, 0x09, 0x07, 0x05, 0x03, 0x03, 0x00, 0xfd, 0x01, 0x0a, 0x0b, + 0x09, 0x06, 0x01, 0xfa, 0xf9, 0xf6, 0xff, 0xff, 0x05, 0x07, 0x03, 0x0a, + 0x0b, 0x10, 0x0d, 0x0e, 0x0d, 0x0a, 0x07, 0x02, 0xfd, 0xff, 0xff, 0xff, + 0xfb, 0xff, 0x0a, 0x05, 0x00, 0xfb, 0xf6, 0xf2, 0xf7, 0xf9, 0x00, 0x01, + 0x05, 0x0d, 0x0a, 0x0e, 0x0d, 0x0e, 0x0b, 0x0b, 0x0d, 0x0d, 0x14, 0x18, + 0x0e, 0x09, 0x01, 0xff, 0xff, 0x00, 0x07, 0x02, 0xff, 0xfe, 0x02, 0xff, + 0xfe, 0xfd, 0xfd, 0xfd, 0x00, 0x02, 0x00, 0xfe, 0xfb, 0xfd, 0x05, 0x05, + 0x06, 0x0a, 0x0b, 0x09, 0x01, 0xff, 0xfe, 0x00, 0xfd, 0x00, 0x10, 0x13, + 0x13, 0x0a, 0x05, 0x03, 0x0a, 0x0b, 0x0d, 0x06, 0x01, 0x0d, 0x13, 0x10, + 0x0a, 0x01, 0xf7, 0xf6, 0xf9, 0xfe, 0xfd, 0xfd, 0xfa, 0x02, 0x01, 0xfe, + 0xfb, 0x01, 0x0d, 0x09, 0x03, 0x02, 0x02, 0x02, 0xff, 0x01, 0x0b, 0x0b, + 0x05, 0x0d, 0x16, 0x0e, 0x01, 0xf9, 0x02, 0x03, 0x07, 0x0a, 0x05, 0x05, + 0x06, 0x05, 0x03, 0x02, 0x00, 0x01, 0x05, 0x07, 0x02, 0x07, 0x07, 0x06, + 0x02, 0xff, 0x00, 0xfe, 0x00, 0x01, 0x05, 0x03, 0x00, 0x05, 0x09, 0x03, + 0x00, 0x05, 0x02, 0x05, 0x07, 0x00, 0xfa, 0xfd, 0x05, 0x07, 0x0a, 0x0b, + 0x0a, 0x0a, 0x09, 0x01, 0xf5, 0xf2, 0xfb, 0xfd, 0xff, 0x07, 0x0d, 0x06, + 0x03, 0x12, 0x10, 0x0a, 0x07, 0x0a, 0x0e, 0x07, 0x09, 0x13, 0x0e, 0x03, + 0xfb, 0xf3, 0xfb, 0x01, 0xfd, 0xff, 0x01, 0xf9, 0xfb, 0x05, 0x07, 0x03, + 0x03, 0x09, 0x12, 0x0a, 0x03, 0x02, 0x01, 0x01, 0xff, 0x03, 0x03, 0xff, + 0x00, 0x0a, 0x02, 0xfd, 0xf6, 0xfa, 0xfb, 0x07, 0x0b, 0x09, 0x09, 0x06, + 0x02, 0x02, 0x00, 0x06, 0x13, 0x0f, 0x0b, 0x0b, 0x0b, 0x07, 0x0a, 0x0e, + 0x00, 0x00, 0x00, 0xff, 0xfd, 0xff, 0x00, 0xfa, 0xfa, 0x03, 0x05, 0x06, + 0x0b, 0x0d, 0x06, 0x01, 0xfe, 0xff, 0xff, 0x00, 0x06, 0x0d, 0x0e, 0x07, + 0x05, 0x05, 0x02, 0xfb, 0xfd, 0xff, 0xff, 0xff, 0x02, 0x03, 0x05, 0x02, + 0x07, 0x0a, 0x05, 0x0b, 0x0f, 0x0d, 0x06, 0x01, 0x02, 0x05, 0x01, 0xfd, + 0x02, 0x06, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x12, 0x0f, 0x05, 0x01, 0x00, + 0x02, 0x02, 0x07, 0x07, 0xfd, 0xf7, 0xfa, 0x02, 0x0a, 0x05, 0xff, 0xfb, + 0xfa, 0x02, 0x03, 0xff, 0x00, 0x05, 0x09, 0x09, 0x05, 0x07, 0x07, 0x0b, + 0x0f, 0x0b, 0x09, 0x02, 0x05, 0x01, 0x03, 0x14, 0x0f, 0x07, 0x01, 0xfd, + 0x05, 0x03, 0x02, 0x00, 0xf9, 0xf7, 0xfa, 0xff, 0x00, 0x05, 0x03, 0x03, + 0xff, 0x00, 0x02, 0x05, 0x06, 0x00, 0xff, 0xff, 0x05, 0x0b, 0x09, 0x0b, + 0x0f, 0x06, 0xfb, 0xfb, 0x03, 0x06, 0x0b, 0x07, 0x03, 0x03, 0x07, 0x06, + 0x07, 0x0e, 0x10, 0x10, 0x07, 0x07, 0x07, 0x09, 0x05, 0xfd, 0xf2, 0xf1, + 0xf3, 0xfe, 0xf9, 0xf1, 0xff, 0x06, 0x03, 0x02, 0x0b, 0x0f, 0x0f, 0x0e, + 0x0e, 0x0a, 0x09, 0x02, 0xff, 0x05, 0x0f, 0x0f, 0x05, 0x02, 0x02, 0x05, + 0x05, 0xfd, 0xf6, 0xf2, 0xf3, 0xf9, 0x02, 0xff, 0x01, 0x00, 0xfa, 0xff, + 0x10, 0x13, 0x0d, 0x06, 0x01, 0xfb, 0x03, 0x0f, 0x0f, 0x06, 0x0a, 0x12, + 0x0f, 0x0e, 0x02, 0x03, 0x0a, 0x0e, 0x03, 0x01, 0xff, 0x02, 0x09, 0x0a, + 0x03, 0x05, 0xff, 0xf6, 0xff, 0x05, 0x01, 0x01, 0xff, 0xf9, 0xf7, 0xfa, + 0xf9, 0xfe, 0x02, 0x07, 0x06, 0x03, 0xfd, 0xff, 0x14, 0x13, 0x0e, 0x0d, + 0x0d, 0x07, 0x09, 0x0a, 0x0d, 0x0d, 0x0a, 0x02, 0x01, 0x00, 0x01, 0x01, + 0x02, 0xfd, 0xf5, 0xfb, 0x03, 0x03, 0x09, 0x0e, 0x09, 0x05, 0x00, 0x05, + 0x05, 0x02, 0xfd, 0xfb, 0xf9, 0xf5, 0xf9, 0xff, 0x01, 0x03, 0x0e, 0x05, + 0x0b, 0x10, 0x0a, 0x0b, 0x0f, 0x07, 0x05, 0x05, 0x0a, 0x0a, 0x0e, 0x13, + 0x0f, 0x07, 0x03, 0x01, 0x05, 0x07, 0x02, 0xfd, 0xf1, 0xf1, 0xf6, 0xff, + 0x02, 0x00, 0xfb, 0xf9, 0x00, 0x03, 0x02, 0x02, 0x03, 0xfd, 0xfb, 0x03, + 0x0e, 0x0a, 0x0a, 0x1a, 0x14, 0x0d, 0x0e, 0x12, 0x0f, 0x0b, 0x01, 0xfb, + 0xfa, 0xf6, 0xf7, 0xfb, 0x00, 0x01, 0x02, 0x01, 0x02, 0x0d, 0x0a, 0x09, + 0x0a, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x05, 0x06, 0x07, 0x03, 0xfd, 0xff, + 0x05, 0x09, 0x0a, 0x07, 0x05, 0x05, 0x02, 0x06, 0x0e, 0x0f, 0x09, 0x09, + 0x09, 0x0a, 0x00, 0xff, 0xff, 0xfe, 0xf7, 0xf3, 0xf9, 0xfa, 0xfb, 0x06, + 0x03, 0x00, 0xfd, 0xff, 0x00, 0xfe, 0xfe, 0x01, 0x03, 0x06, 0x06, 0x06, + 0x05, 0x0a, 0x16, 0x12, 0x18, 0x1b, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x01, + 0x01, 0x02, 0x02, 0x0d, 0x0a, 0x07, 0x01, 0xfd, 0xfb, 0xff, 0x00, 0xfe, + 0xfd, 0xf6, 0xf1, 0xf3, 0xfa, 0x00, 0xfe, 0xfd, 0x07, 0x05, 0x03, 0x07, + 0x07, 0x0a, 0x02, 0x07, 0x10, 0x0f, 0x10, 0x1a, 0x18, 0x13, 0x0e, 0x0a, + 0x09, 0x00, 0x00, 0x00, 0xfb, 0xf3, 0xec, 0xf0, 0xf5, 0xf6, 0xfb, 0x01, + 0x0b, 0x13, 0x0b, 0x05, 0x06, 0x05, 0x00, 0x00, 0x00, 0x03, 0x06, 0x0e, + 0x14, 0x10, 0x06, 0x01, 0x01, 0x0d, 0x0b, 0x02, 0xfb, 0xfe, 0x00, 0xfd, + 0xfb, 0xff, 0x06, 0x06, 0x0d, 0x0d, 0x07, 0x07, 0x05, 0x01, 0xfe, 0xfd, + 0xfe, 0x05, 0x0a, 0x10, 0x07, 0x00, 0xff, 0x03, 0x03, 0x00, 0x01, 0x07, + 0x0b, 0x05, 0xff, 0xfd, 0xfd, 0xfe, 0x05, 0x09, 0x0b, 0x0a, 0x0b, 0x06, + 0x01, 0xfe, 0xfe, 0x03, 0x09, 0x03, 0x03, 0x02, 0x06, 0x05, 0x02, 0x00, + 0xfb, 0xfb, 0x00, 0x00, 0xfb, 0xfd, 0x00, 0x03, 0x03, 0x05, 0x09, 0x16, + 0x1d, 0x1c, 0x12, 0x05, 0xff, 0x03, 0xff, 0xfd, 0x02, 0x00, 0x06, 0x0b, + 0x0a, 0x07, 0x05, 0x07, 0x07, 0x06, 0x01, 0x00, 0x00, 0xfd, 0xfe, 0xff, + 0xfa, 0xfa, 0xfa, 0xfe, 0x03, 0x02, 0xfe, 0x02, 0x01, 0x01, 0x03, 0x01, + 0x02, 0x06, 0x09, 0x0b, 0x0a, 0x09, 0x0d, 0x0f, 0x06, 0x0a, 0x0a, 0x05, + 0x00, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0x01, 0x03, 0x0d, 0x13, 0x0f, 0x0d, + 0x0d, 0x09, 0x01, 0xfa, 0xf7, 0xfa, 0x01, 0x05, 0x0a, 0x0f, 0x10, 0x0d, + 0x05, 0xfd, 0x00, 0x01, 0xf5, 0xf1, 0xf7, 0xf9, 0xfb, 0xf7, 0xff, 0x02, + 0x0a, 0x13, 0x09, 0x0b, 0x0d, 0x0b, 0x07, 0x06, 0x02, 0x07, 0x12, 0x0f, + 0x0d, 0x03, 0xf9, 0xfa, 0xf9, 0xf5, 0xf6, 0xfa, 0x05, 0x0e, 0x12, 0x0f, + 0x0d, 0x02, 0xff, 0x01, 0x0e, 0x16, 0x0a, 0x03, 0xfd, 0xfd, 0xfb, 0xfa, + 0xfd, 0xfb, 0x03, 0xfd, 0xfd, 0x02, 0x01, 0x05, 0x05, 0x01, 0x07, 0x0d, + 0x03, 0xfd, 0xfd, 0xfd, 0x00, 0xff, 0xff, 0x03, 0x1a, 0x25, 0x1c, 0x16, + 0x0d, 0x03, 0x01, 0xff, 0xff, 0x01, 0x02, 0x00, 0x05, 0x02, 0xfe, 0xff, + 0x00, 0x03, 0xfe, 0xfa, 0xf9, 0xf6, 0xf7, 0xfd, 0x00, 0x06, 0x02, 0x03, + 0x13, 0x20, 0x09, 0x01, 0x03, 0x02, 0x03, 0x09, 0x07, 0x07, 0x0b, 0x0a, + 0x09, 0x06, 0x05, 0x05, 0x07, 0x03, 0x00, 0x00, 0xfe, 0xfe, 0xfb, 0xf5, + 0xea, 0xf3, 0xff, 0x05, 0x05, 0x0b, 0x0f, 0x0d, 0x10, 0x13, 0x13, 0x0a, + 0x06, 0x0f, 0x09, 0x07, 0x05, 0x07, 0x13, 0x12, 0x0d, 0x07, 0x00, 0xff, + 0xf6, 0xf0, 0xf1, 0xf6, 0xf6, 0xf2, 0xf7, 0xf7, 0xfd, 0x09, 0x0b, 0x06, + 0xfe, 0xfd, 0xfe, 0x0a, 0x14, 0x0f, 0x0b, 0x14, 0x14, 0x13, 0x09, 0x00, + 0xff, 0x01, 0x02, 0x06, 0xfe, 0x07, 0x12, 0x0b, 0x07, 0x02, 0x03, 0x01, + 0x09, 0x0d, 0x0b, 0x06, 0xff, 0xff, 0xfa, 0xff, 0x03, 0xff, 0xf9, 0xf5, + 0xfb, 0xfa, 0xf7, 0xfa, 0xf9, 0x07, 0x0e, 0x06, 0x01, 0x00, 0x01, 0xff, + 0xfe, 0x00, 0x00, 0x06, 0x1a, 0x30, 0x30, 0x21, 0x10, 0x09, 0x00, 0xfe, + 0x03, 0x00, 0x00, 0xfd, 0xfa, 0xfe, 0x06, 0x07, 0x07, 0x07, 0x06, 0xfd, + 0xf7, 0xf5, 0xf6, 0xf2, 0xf6, 0xfa, 0x00, 0x0a, 0x0f, 0x03, 0x00, 0x02, + 0x02, 0x00, 0x02, 0x06, 0x16, 0x1d, 0x1d, 0x13, 0x10, 0x0d, 0x09, 0x05, + 0x00, 0xff, 0x02, 0x00, 0xfe, 0xfa, 0xfa, 0xfb, 0xf6, 0xf7, 0xfa, 0xfa, + 0x03, 0x05, 0x06, 0x09, 0x0b, 0x09, 0x03, 0x09, 0x13, 0x0b, 0x05, 0xfe, + 0xff, 0xff, 0x01, 0x0b, 0x10, 0x0e, 0x10, 0x0f, 0x00, 0x06, 0x06, 0x00, + 0xfb, 0xf7, 0xf6, 0xf6, 0x01, 0x06, 0x07, 0x05, 0x03, 0x01, 0x05, 0x09, + 0x02, 0xff, 0x01, 0x06, 0x07, 0x07, 0x01, 0xfe, 0xf1, 0x00, 0x05, 0x00, + 0xfa, 0xfa, 0x02, 0x0d, 0x0f, 0x12, 0x0e, 0x0a, 0x1b, 0x25, 0x21, 0x13, + 0x0b, 0x03, 0x00, 0x01, 0xff, 0xff, 0xfd, 0xf2, 0xf3, 0xf6, 0xf3, 0xfa, + 0xfa, 0xfd, 0xff, 0xfd, 0xf9, 0xf6, 0xf7, 0xf2, 0xf0, 0xf2, 0xfa, 0x06, + 0x16, 0x1f, 0x2a, 0x24, 0x23, 0x1d, 0x14, 0x0a, 0x0b, 0x0e, 0x13, 0x0d, + 0x09, 0x06, 0x00, 0xfd, 0xfd, 0xfd, 0xfe, 0xff, 0xff, 0xfa, 0xf3, 0xee, + 0xf9, 0x00, 0xfe, 0xfb, 0x06, 0x00, 0x00, 0x00, 0xfe, 0xfb, 0xfd, 0x02, + 0x0f, 0x18, 0x12, 0x0e, 0x10, 0x12, 0x0b, 0x0b, 0x0a, 0x03, 0x09, 0x0b, + 0x02, 0x02, 0xff, 0xfa, 0xfe, 0xf9, 0xed, 0xed, 0xfb, 0x06, 0x05, 0xff, + 0x02, 0x0b, 0x18, 0x14, 0x0d, 0x06, 0x02, 0x02, 0x02, 0x01, 0xfa, 0xfb, + 0x07, 0x12, 0x0f, 0x0e, 0x00, 0xf7, 0xfb, 0xfa, 0xf7, 0xf9, 0xfd, 0x00, + 0x0e, 0x12, 0x0b, 0x0b, 0x0b, 0x0e, 0x0e, 0x03, 0xfb, 0xfd, 0x03, 0x03, + 0x06, 0x07, 0x09, 0x0a, 0x02, 0xf3, 0xf3, 0xf5, 0xfa, 0xfd, 0xfa, 0x00, + 0x00, 0xfb, 0x07, 0x12, 0x18, 0x17, 0x16, 0x0f, 0x0f, 0x10, 0x0d, 0x00, + 0xfd, 0x01, 0x01, 0xfd, 0x00, 0x0a, 0x0a, 0xff, 0xfb, 0xfe, 0xfb, 0x00, + 0xfe, 0xf9, 0xfa, 0xfe, 0xfb, 0xf9, 0xfa, 0xfd, 0x05, 0x07, 0x0f, 0x14, + 0x10, 0x13, 0x13, 0x0e, 0x0b, 0x05, 0x03, 0x07, 0x0a, 0x07, 0x03, 0x01, + 0x00, 0x00, 0x05, 0x0f, 0x0d, 0x06, 0x01, 0xfe, 0xff, 0xf9, 0xf9, 0xfd, + 0x06, 0x02, 0xff, 0xf7, 0x00, 0x09, 0x02, 0xfe, 0x00, 0x01, 0x09, 0x07, + 0x06, 0x05, 0x05, 0x01, 0xfb, 0x03, 0x05, 0x06, 0x0f, 0x0b, 0x01, 0xff, + 0xff, 0xff, 0xfe, 0xfd, 0x0f, 0x13, 0x0f, 0x0b, 0x0f, 0x13, 0x0f, 0x06, + 0xff, 0xfe, 0xfb, 0xfa, 0x00, 0x03, 0x09, 0x06, 0x01, 0x0b, 0x07, 0x01, + 0xfa, 0xf9, 0xfa, 0xf7, 0xf2, 0xf0, 0xf6, 0x01, 0x10, 0x12, 0x0a, 0x02, + 0x06, 0x0f, 0x0a, 0x09, 0x09, 0x09, 0x0d, 0x0d, 0x0a, 0x07, 0x05, 0x06, + 0x03, 0xfd, 0xee, 0xf1, 0xf6, 0xf7, 0xf9, 0x01, 0x0a, 0x06, 0x00, 0x0b, + 0x21, 0x20, 0x10, 0x09, 0x0e, 0x13, 0x0b, 0x03, 0x06, 0x05, 0xfe, 0xf7, + 0xfb, 0xfb, 0xfb, 0xfd, 0xf7, 0xfb, 0x02, 0x01, 0x03, 0x02, 0x00, 0xfd, + 0xfb, 0xfa, 0xf7, 0xf9, 0x0b, 0x13, 0x0d, 0x13, 0x25, 0x1d, 0x14, 0x13, + 0x10, 0x05, 0x00, 0xfd, 0x00, 0x02, 0xfe, 0xfd, 0xfd, 0x00, 0x01, 0x01, + 0x01, 0xfe, 0xfd, 0xfe, 0xfe, 0xfe, 0xfa, 0xff, 0x13, 0x13, 0x01, 0xf9, + 0x01, 0x07, 0x0a, 0x05, 0x02, 0x03, 0x06, 0x10, 0x0e, 0x13, 0x12, 0x0d, + 0x09, 0x03, 0x02, 0x01, 0x02, 0x00, 0xf9, 0xf2, 0xee, 0xee, 0xf9, 0x06, + 0x09, 0x09, 0x05, 0x03, 0x10, 0x0b, 0x06, 0x0d, 0x0f, 0x0d, 0x07, 0x0a, + 0x0a, 0x03, 0x06, 0x06, 0x09, 0x06, 0x09, 0x0a, 0x01, 0xf7, 0xfb, 0x00, + 0xfb, 0xfb, 0xf7, 0xfe, 0x0a, 0x05, 0x02, 0xff, 0x00, 0x00, 0xfd, 0x00, + 0x06, 0x05, 0x01, 0x0b, 0x0b, 0x0a, 0x07, 0x09, 0x0a, 0x0a, 0x0a, 0xff, + 0x00, 0xff, 0xfe, 0x02, 0x01, 0x02, 0x0d, 0x0d, 0x16, 0x10, 0x0d, 0x0e, + 0x17, 0x12, 0x0d, 0x0e, 0x06, 0x00, 0xf7, 0xfa, 0xf3, 0xec, 0xf0, 0xf5, + 0xf6, 0xf6, 0x05, 0x00, 0xfe, 0xfd, 0xfd, 0xfb, 0xfa, 0xfd, 0xfe, 0x06, + 0x0f, 0x0d, 0x0f, 0x13, 0x1a, 0x1d, 0x13, 0x10, 0x0f, 0x0b, 0x07, 0xfe, + 0x01, 0x03, 0x06, 0x06, 0x02, 0xfe, 0xfe, 0x01, 0x05, 0x00, 0xfe, 0xfd, + 0xfb, 0xfb, 0xfe, 0x0e, 0x12, 0x03, 0x02, 0xfd, 0xff, 0xfe, 0xfe, 0x05, + 0x02, 0xff, 0x02, 0x03, 0x0b, 0x0e, 0x09, 0x07, 0x05, 0x03, 0x06, 0x03, + 0x03, 0x06, 0x09, 0x09, 0x02, 0x00, 0xff, 0x05, 0x0f, 0x07, 0xfa, 0xff, + 0x07, 0x03, 0xfa, 0xfe, 0x02, 0x06, 0x03, 0x02, 0xfe, 0xfb, 0xff, 0x03, + 0x03, 0x0a, 0x06, 0x06, 0x07, 0x09, 0x00, 0xf7, 0xfd, 0xfe, 0xfe, 0x03, + 0x12, 0x10, 0x09, 0x07, 0x13, 0x12, 0x06, 0x05, 0x05, 0x03, 0x00, 0x01, + 0x02, 0x00, 0xfd, 0xfd, 0xf6, 0xf6, 0x01, 0x00, 0xff, 0xf3, 0xf3, 0xf7, + 0x00, 0x06, 0x0a, 0x10, 0x1b, 0x1f, 0x16, 0x13, 0x1b, 0x17, 0x0a, 0x0d, + 0x10, 0x0a, 0x02, 0xfe, 0xf9, 0xf7, 0xf6, 0xf7, 0xf6, 0xf9, 0xfa, 0xfd, + 0xfe, 0xf7, 0xf9, 0xf5, 0xf2, 0xf0, 0xea, 0xf7, 0x0b, 0x0d, 0x0a, 0x0a, + 0x10, 0x10, 0x17, 0x24, 0x23, 0x18, 0x13, 0x14, 0x0b, 0x03, 0x07, 0x05, + 0x03, 0x02, 0x03, 0x01, 0x00, 0xfe, 0x00, 0x03, 0x02, 0xff, 0xff, 0x05, + 0x07, 0x07, 0xff, 0xf9, 0xfd, 0xf3, 0xec, 0xf2, 0xfa, 0x03, 0x05, 0x01, + 0xfe, 0xff, 0x0b, 0x0a, 0x0b, 0x09, 0x0a, 0x0b, 0x07, 0x05, 0x09, 0x0a, + 0x05, 0x01, 0x01, 0x01, 0x07, 0x10, 0x0a, 0x02, 0x00, 0x0b, 0x07, 0x09, + 0x09, 0x0a, 0x03, 0xfd, 0xfb, 0xfd, 0x01, 0x02, 0xfd, 0xfb, 0x01, 0x0b, + 0x03, 0x05, 0x05, 0x01, 0xfb, 0xfd, 0x06, 0x03, 0x03, 0x0d, 0x0a, 0x0a, + 0x09, 0x09, 0x02, 0x00, 0xfe, 0x02, 0x02, 0x01, 0xfa, 0xff, 0x0f, 0x12, + 0x09, 0x06, 0x06, 0x05, 0x02, 0xff, 0x01, 0xf7, 0xf6, 0xfa, 0xf7, 0xf3, + 0x01, 0x1b, 0x14, 0x0e, 0x0e, 0x12, 0x12, 0x16, 0x10, 0x0b, 0x06, 0x03, + 0x01, 0xfe, 0xfa, 0xf7, 0xf2, 0xf3, 0xf7, 0xf9, 0xfb, 0x05, 0x06, 0x06, + 0x0a, 0x06, 0x01, 0xfe, 0x01, 0x0e, 0x07, 0x05, 0x06, 0x0a, 0x07, 0x00, + 0x02, 0x07, 0x13, 0x10, 0x07, 0x0a, 0x05, 0xfb, 0x05, 0x02, 0x05, 0x02, + 0x01, 0x05, 0x09, 0x0a, 0x05, 0x02, 0x03, 0xfe, 0x01, 0x0b, 0x06, 0x06, + 0xff, 0x03, 0xff, 0xf6, 0xfe, 0xfd, 0xfb, 0x00, 0xfb, 0xf7, 0xf5, 0xf9, + 0x00, 0xfd, 0xff, 0x00, 0x0a, 0x0a, 0x0b, 0x0a, 0x07, 0x0a, 0x10, 0x0a, + 0x0f, 0x18, 0x1b, 0x17, 0x10, 0x0e, 0x03, 0xfe, 0x06, 0x07, 0x03, 0x00, + 0xff, 0xfe, 0x00, 0x02, 0x00, 0x03, 0x09, 0x02, 0xfa, 0xfa, 0xff, 0xfd, + 0xfb, 0xfa, 0xf1, 0xed, 0xf3, 0x09, 0x1a, 0x10, 0x07, 0x06, 0x0d, 0x0e, + 0x0b, 0x03, 0x03, 0x01, 0xff, 0x00, 0xfd, 0xff, 0x05, 0x05, 0x05, 0x02, + 0xfd, 0x00, 0x06, 0x03, 0x06, 0x06, 0x02, 0xff, 0xfe, 0x06, 0x0f, 0x10, + 0x0b, 0x06, 0x0a, 0x0f, 0x10, 0x07, 0x09, 0x0d, 0x07, 0x05, 0x02, 0x00, + 0x03, 0xfe, 0xf9, 0xf9, 0xf5, 0xfa, 0xff, 0x00, 0xff, 0xfe, 0xfe, 0xfa, + 0xfb, 0xfe, 0x03, 0x00, 0x05, 0x06, 0x0b, 0x10, 0x12, 0x13, 0x12, 0x18, + 0x13, 0x0d, 0x0b, 0x06, 0x03, 0xf6, 0xf5, 0xf3, 0xf9, 0x07, 0x0b, 0x06, + 0x00, 0x06, 0x09, 0x02, 0xfe, 0xfb, 0x05, 0x0b, 0x0d, 0x05, 0xfe, 0xfd, + 0x01, 0xf9, 0xf7, 0xf6, 0xfa, 0xfe, 0x02, 0x05, 0x0b, 0x0e, 0x12, 0x0f, + 0x0b, 0x0b, 0x09, 0x06, 0x03, 0x00, 0x01, 0xfd, 0xfa, 0xfd, 0x13, 0x1c, + 0x16, 0x12, 0x0e, 0x14, 0x03, 0xf7, 0xfe, 0x02, 0x00, 0x00, 0x01, 0x02, + 0x02, 0x03, 0x03, 0x06, 0xff, 0xfd, 0xff, 0x00, 0xfb, 0xfd, 0x0e, 0x09, + 0x00, 0xfa, 0x00, 0x0b, 0x07, 0x02, 0xfa, 0xfb, 0xfe, 0xf9, 0xfb, 0x00, + 0x0f, 0x0d, 0x02, 0x00, 0x05, 0x09, 0x0a, 0x09, 0x05, 0x05, 0x13, 0x14, + 0x0e, 0x07, 0x05, 0x02, 0xfa, 0xf7, 0xfb, 0x06, 0x09, 0x13, 0x0e, 0x0f, + 0x18, 0x10, 0x0e, 0x0a, 0x07, 0x05, 0x00, 0xfe, 0xf7, 0xf1, 0xf1, 0xf0, + 0xf1, 0xf3, 0x02, 0xff, 0xfe, 0x01, 0x0b, 0x05, 0xfe, 0xfd, 0x00, 0x09, + 0x09, 0x07, 0x03, 0x01, 0x06, 0x02, 0x03, 0x06, 0x07, 0x12, 0x0f, 0x10, + 0x10, 0x12, 0x18, 0x05, 0xfe, 0x01, 0x02, 0x05, 0xff, 0xfa, 0xfb, 0xfa, + 0xfa, 0xfe, 0xfe, 0x0d, 0x16, 0x0f, 0x0b, 0x05, 0x07, 0x02, 0x02, 0x02, + 0xfa, 0xfa, 0x00, 0x00, 0xfd, 0xf7, 0xf7, 0xfe, 0x06, 0x0b, 0x09, 0x02, + 0x00, 0x03, 0x0a, 0x0d, 0x05, 0x01, 0x07, 0x16, 0x1a, 0x16, 0x0d, 0x03, + 0x06, 0x03, 0xfa, 0xed, 0xf9, 0x0a, 0x0b, 0x05, 0x02, 0x03, 0x02, 0x01, + 0xfe, 0x00, 0x00, 0xfe, 0xfd, 0xfb, 0xfa, 0xfa, 0x02, 0x01, 0x02, 0x00, + 0x02, 0x06, 0x0b, 0x03, 0x03, 0x18, 0x14, 0x0f, 0x0d, 0x07, 0x06, 0x09, + 0x03, 0xfd, 0xf9, 0xf5, 0xf9, 0x00, 0x06, 0x10, 0x0e, 0x0b, 0x0b, 0x0f, + 0x0b, 0x06, 0xf9, 0xf1, 0x02, 0x05, 0x05, 0x02, 0x06, 0x0d, 0x0d, 0x12, + 0x10, 0x0f, 0x07, 0x05, 0x02, 0x02, 0x00, 0x02, 0xff, 0x00, 0x00, 0xfd, + 0xf5, 0xf2, 0xee, 0xec, 0xe9, 0xf0, 0xf6, 0xfa, 0x0b, 0x16, 0x0d, 0x09, + 0x09, 0x10, 0x09, 0x05, 0x05, 0x0b, 0x12, 0x1d, 0x20, 0x17, 0x12, 0x17, + 0x14, 0x07, 0xfa, 0xfe, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x03, 0x00, 0x00, + 0x06, 0x09, 0x00, 0xfa, 0xf2, 0xfb, 0xfb, 0xfd, 0xfd, 0xfb, 0x05, 0x0a, + 0x03, 0xff, 0x00, 0x06, 0x02, 0x02, 0x01, 0x0b, 0x0a, 0x03, 0x01, 0x01, + 0x05, 0x03, 0xff, 0xfe, 0x02, 0x13, 0x0f, 0x0d, 0x07, 0x03, 0x12, 0x18, + 0x13, 0x00, 0xfb, 0x00, 0x01, 0x02, 0xf9, 0xf9, 0xfd, 0xf9, 0xf9, 0x02, + 0x12, 0x0e, 0x05, 0x03, 0x07, 0x00, 0x00, 0x0a, 0x07, 0x0d, 0x0f, 0x0a, + 0xfe, 0xf6, 0xfe, 0x09, 0x05, 0x01, 0x06, 0x0a, 0x03, 0x01, 0xfd, 0x00, + 0x05, 0x01, 0xfd, 0x00, 0x07, 0x0d, 0x09, 0x05, 0x00, 0xfe, 0xfd, 0x00, + 0xfe, 0xfa, 0x0f, 0x12, 0x09, 0x02, 0x0b, 0x1a, 0x14, 0x0e, 0x0e, 0x0e, + 0x02, 0xfd, 0xf9, 0x00, 0x05, 0xf9, 0xf6, 0xfe, 0x00, 0xfe, 0xfd, 0xf3, + 0xee, 0xf1, 0xf6, 0x01, 0x0b, 0x12, 0x18, 0x0d, 0x01, 0xf9, 0xf7, 0x05, + 0x09, 0x07, 0x0e, 0x14, 0x1b, 0x16, 0x1f, 0x1f, 0x1b, 0x18, 0x12, 0x0b, + 0x05, 0xf5, 0xf2, 0xf2, 0xf1, 0xf9, 0xfd, 0xf9, 0xfa, 0xfb, 0x05, 0x07, + 0x00, 0xf5, 0xf1, 0xfa, 0x0a, 0x16, 0x10, 0x0e, 0x02, 0xfe, 0xff, 0xf7, + 0xee, 0xf7, 0xf7, 0xf7, 0xf9, 0x02, 0x17, 0x0b, 0x07, 0x12, 0x0f, 0x0b, + 0x06, 0x06, 0x0a, 0x0f, 0x0a, 0x07, 0x05, 0x0e, 0x1a, 0x17, 0x13, 0x12, + 0x02, 0xf5, 0xf9, 0xfb, 0x00, 0x02, 0xff, 0x06, 0x01, 0xff, 0x00, 0xf7, + 0xf9, 0xf9, 0xfb, 0xf7, 0xf1, 0xfb, 0x09, 0x1b, 0x1a, 0x0e, 0x05, 0x05, + 0x02, 0x0b, 0x09, 0x0a, 0x07, 0x00, 0xfe, 0xff, 0x01, 0x02, 0x00, 0xfb, + 0x00, 0xfb, 0xf9, 0xf9, 0x00, 0x05, 0x05, 0x00, 0x00, 0x0b, 0x0f, 0x17, + 0x0d, 0xfd, 0xf6, 0xf7, 0x00, 0x0d, 0x13, 0x12, 0x10, 0x17, 0x12, 0x0f, + 0x10, 0x12, 0x0e, 0x02, 0xfe, 0xf9, 0xf7, 0xf2, 0xf6, 0xf7, 0x00, 0xfe, + 0xf0, 0xf1, 0xf5, 0x01, 0x0a, 0x02, 0xfb, 0xf7, 0xfe, 0x09, 0x13, 0x1c, + 0x18, 0x0f, 0x0f, 0x0b, 0x07, 0x13, 0x0f, 0x0e, 0x10, 0x0a, 0x07, 0x0e, + 0x02, 0xfb, 0x00, 0x06, 0x00, 0xf7, 0xf6, 0xfa, 0x01, 0xfe, 0xf2, 0xf5, + 0xfd, 0xff, 0x00, 0x09, 0x05, 0x03, 0xfe, 0xff, 0xff, 0x03, 0x06, 0x06, + 0xfd, 0x00, 0x05, 0x0a, 0x07, 0x10, 0x09, 0x09, 0x02, 0x00, 0x00, 0x03, + 0x0e, 0x1d, 0x17, 0x0e, 0x10, 0x13, 0x12, 0x17, 0x10, 0x09, 0x00, 0xfd, + 0xed, 0xf2, 0xf9, 0xf9, 0xf9, 0xfa, 0xf7, 0xf9, 0xf7, 0xf7, 0xf9, 0x01, + 0x03, 0x03, 0x01, 0x06, 0x0b, 0x1c, 0x0a, 0x05, 0x02, 0x00, 0x01, 0x05, + 0x03, 0x00, 0xfd, 0x09, 0x0a, 0x03, 0x05, 0x0a, 0x05, 0x00, 0xfd, 0xfd, + 0xfb, 0xfd, 0x00, 0x01, 0x07, 0x07, 0x0a, 0x0e, 0x0d, 0x14, 0x10, 0x03, + 0xf9, 0x01, 0x05, 0x07, 0x14, 0x23, 0x1c, 0x10, 0x09, 0x01, 0x00, 0xff, + 0xfb, 0xf7, 0xf9, 0xf3, 0xf1, 0xfd, 0x00, 0xff, 0x01, 0x03, 0x01, 0xf6, + 0xe6, 0xed, 0xfb, 0x00, 0x05, 0x0a, 0x07, 0x0a, 0x10, 0x16, 0x0e, 0x0d, + 0x0b, 0x07, 0x07, 0x0b, 0x13, 0x10, 0x0d, 0x0d, 0x0d, 0x0b, 0x0b, 0xfb, + 0xea, 0xf5, 0xf5, 0xf9, 0xf6, 0xf7, 0x00, 0x0e, 0x0a, 0x05, 0x07, 0x10, + 0x0b, 0x0b, 0x05, 0xff, 0xff, 0xfe, 0x01, 0x03, 0x02, 0x07, 0x07, 0xfe, + 0xf6, 0xfd, 0xff, 0xff, 0x07, 0x0b, 0x06, 0x02, 0x02, 0x09, 0x0d, 0x16, + 0x0d, 0x07, 0x07, 0x07, 0x01, 0x07, 0x0e, 0x10, 0x0e, 0x13, 0x0b, 0xf9, + 0xf2, 0xf9, 0xf6, 0xf0, 0xf7, 0xfd, 0xfa, 0xf9, 0xfd, 0x01, 0x03, 0x03, + 0x02, 0x02, 0xfe, 0x07, 0x0b, 0x09, 0x0a, 0x0f, 0x0f, 0x0a, 0x16, 0x0b, + 0x03, 0x01, 0x09, 0x0a, 0x02, 0xf7, 0xf5, 0xfa, 0xfe, 0x00, 0x00, 0x0a, + 0x05, 0x02, 0x0b, 0x0f, 0x0d, 0x02, 0xff, 0x03, 0x0f, 0x0d, 0x0b, 0x00, + 0x00, 0x03, 0x02, 0x09, 0x0e, 0x0a, 0x07, 0x07, 0x05, 0x00, 0xfe, 0x00, + 0x02, 0x0b, 0x06, 0xfe, 0xf6, 0xf2, 0xf6, 0xfa, 0xf2, 0xf2, 0xf2, 0xe9, + 0xf5, 0x07, 0x07, 0x0d, 0x13, 0x0e, 0x09, 0x10, 0x0e, 0x0f, 0x0d, 0x0e, + 0x10, 0x0b, 0x0a, 0x0a, 0x10, 0x0f, 0x10, 0x13, 0x0b, 0x05, 0x00, 0xfa, + 0xf7, 0xf6, 0xfa, 0x02, 0x05, 0x10, 0x0b, 0x05, 0xfe, 0xf7, 0xf3, 0x01, + 0x00, 0xfe, 0xfa, 0x0a, 0x02, 0x00, 0x00, 0xff, 0x02, 0x09, 0x02, 0xf7, + 0xf7, 0xfd, 0x01, 0x0b, 0x14, 0x06, 0x00, 0x03, 0x07, 0x18, 0x13, 0x0b, + 0x0d, 0x0e, 0x0b, 0x0e, 0x0e, 0x14, 0x0a, 0x07, 0x05, 0xfd, 0xf5, 0xe1, + 0xdf, 0xf0, 0xf9, 0x00, 0x00, 0x06, 0x05, 0x02, 0x02, 0x06, 0x0b, 0x0b, + 0x02, 0x05, 0x0d, 0x0f, 0x0e, 0x12, 0x12, 0x0f, 0x17, 0x0f, 0x03, 0xfb, + 0xff, 0x00, 0xf9, 0xf5, 0xf3, 0xfd, 0x02, 0x06, 0x01, 0x01, 0xf9, 0xf6, + 0xf5, 0xfb, 0xff, 0x01, 0x02, 0x02, 0x14, 0x21, 0x1a, 0x1c, 0x10, 0x00, + 0x01, 0x02, 0x00, 0x05, 0x0d, 0x0a, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0xf9, 0xf2, 0xec, 0xf2, 0xfa, 0xfb, 0x02, 0xff, 0xff, 0x07, + 0xff, 0x01, 0x0d, 0x0b, 0x09, 0x0d, 0x10, 0x09, 0x07, 0x18, 0x17, 0x0e, + 0x06, 0x09, 0x0b, 0x0f, 0x0e, 0x07, 0x03, 0x06, 0x02, 0x01, 0xff, 0xf3, + 0xf3, 0xf9, 0x00, 0x07, 0x02, 0x00, 0x05, 0x00, 0x00, 0x05, 0x0f, 0x0d, + 0x02, 0x01, 0x02, 0xf9, 0xf2, 0xf6, 0xfd, 0x00, 0x00, 0xfd, 0xf7, 0x00, + 0x02, 0xfb, 0xfa, 0x0b, 0x14, 0x0a, 0x05, 0x13, 0x1f, 0x14, 0x13, 0x13, + 0x10, 0x16, 0x10, 0x0d, 0x03, 0x00, 0x05, 0x05, 0xfe, 0xfd, 0xfd, 0xf1, + 0xfd, 0x05, 0x07, 0x02, 0x00, 0xf7, 0xf3, 0xf9, 0xfb, 0xfd, 0x00, 0x00, + 0x0e, 0x0d, 0x0a, 0x13, 0x10, 0x0f, 0x13, 0x0e, 0x07, 0x00, 0xfe, 0xfb, + 0xfb, 0x03, 0x01, 0xff, 0x01, 0xff, 0xfe, 0xfd, 0xfd, 0xfd, 0xf5, 0xf9, + 0x02, 0x10, 0x13, 0x0d, 0x16, 0x1b, 0x0f, 0x07, 0x05, 0x0f, 0x0a, 0xfb, + 0xfe, 0xfd, 0xfb, 0x0d, 0x0a, 0x0a, 0x07, 0x05, 0x05, 0x02, 0x05, 0x05, + 0x00, 0xf9, 0xf5, 0xf9, 0xfb, 0xff, 0x00, 0xff, 0xf7, 0x05, 0x01, 0xfe, + 0x05, 0x10, 0x12, 0x16, 0x0f, 0x0a, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x01, 0x09, 0x02, 0x0e, 0x10, 0x0a, 0x0a, 0x0b, 0x03, 0xf7, + 0xfb, 0x05, 0x0b, 0x00, 0x05, 0x0d, 0x0a, 0x03, 0x00, 0xff, 0xf9, 0xf9, + 0x00, 0xfb, 0xfb, 0xfe, 0x00, 0x09, 0x00, 0xf9, 0xf6, 0x00, 0xfe, 0xf6, + 0xf5, 0xfe, 0x0a, 0x16, 0x0d, 0x0d, 0x18, 0x1b, 0x23, 0x25, 0x1d, 0x12, + 0x10, 0x09, 0xfe, 0xf9, 0xfb, 0xfb, 0xfb, 0xff, 0x01, 0x01, 0xf7, 0xf3, + 0xf9, 0xfa, 0xf7, 0xfa, 0xfd, 0xfe, 0x05, 0x06, 0x0d, 0x10, 0x16, 0x0f, + 0x07, 0x07, 0x0d, 0x0e, 0x06, 0x07, 0x00, 0xf3, 0xf6, 0x03, 0x03, 0x01, + 0xfd, 0xff, 0xfe, 0xf9, 0xf7, 0xf6, 0xfe, 0x00, 0x00, 0x00, 0x07, 0x0d, + 0x0d, 0x07, 0x0d, 0x16, 0x0e, 0x14, 0x1b, 0x16, 0x1d, 0x1c, 0x0d, 0xfb, + 0xf9, 0xfb, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf5, 0xf2, 0x01, + 0xfe, 0xf6, 0xf9, 0xfb, 0xf3, 0xf6, 0xf3, 0x07, 0x0a, 0x07, 0x16, 0x17, + 0x16, 0x0f, 0x07, 0x00, 0x00, 0xff, 0x01, 0x03, 0x09, 0x0f, 0x12, 0x0a, + 0x05, 0x01, 0x06, 0x0a, 0x05, 0x00, 0x00, 0x07, 0x0a, 0x09, 0xf7, 0xf9, + 0x02, 0x0d, 0x14, 0x05, 0x00, 0xff, 0xff, 0xfe, 0xf9, 0x00, 0x09, 0x05, + 0x00, 0x00, 0xfe, 0xfb, 0xf6, 0xf5, 0xf5, 0xff, 0x02, 0xfe, 0x00, 0x07, + 0x02, 0x05, 0x0f, 0x10, 0x1b, 0x20, 0x20, 0x1a, 0x12, 0x09, 0x02, 0xff, + 0xf9, 0xf7, 0xff, 0x09, 0x06, 0x01, 0x00, 0x02, 0x07, 0x05, 0xf6, 0xfe, + 0xfe, 0xfb, 0xfe, 0x00, 0xfd, 0xfe, 0x00, 0x02, 0x0f, 0x17, 0x12, 0x0a, + 0x0d, 0x0d, 0x14, 0x06, 0x00, 0xfb, 0x00, 0x01, 0x00, 0xf6, 0xf3, 0xf6, + 0xf6, 0xfb, 0xfe, 0xfd, 0xfd, 0x07, 0x06, 0x02, 0x0a, 0x07, 0x06, 0x0a, + 0x0d, 0x1f, 0x1c, 0x0a, 0x0a, 0x0d, 0x0e, 0x12, 0x0f, 0x00, 0xf1, 0xf1, + 0xf6, 0x06, 0x0a, 0x07, 0x09, 0x0d, 0x0a, 0x09, 0x05, 0xfe, 0xf9, 0xf3, + 0xf3, 0xf1, 0xee, 0xec, 0xf2, 0x0a, 0x14, 0x1a, 0x0f, 0x05, 0x02, 0x05, + 0x00, 0xfb, 0xfe, 0xfe, 0x02, 0x05, 0x07, 0x0a, 0x05, 0x00, 0x01, 0x01, + 0x01, 0x0f, 0x0f, 0x0f, 0x12, 0x1a, 0x1f, 0x1a, 0x0f, 0x0d, 0x10, 0x06, + 0xfe, 0xfe, 0xf9, 0xf7, 0xfb, 0xf7, 0xf9, 0xfb, 0xfb, 0x03, 0x00, 0xf7, + 0xf6, 0xf9, 0xf2, 0xec, 0xf3, 0x00, 0x05, 0x00, 0x01, 0x02, 0x00, 0x01, + 0x07, 0x1b, 0x30, 0x24, 0x21, 0x1f, 0x1f, 0x14, 0x0a, 0x02, 0x00, 0x00, + 0xfb, 0xf9, 0xf6, 0xf9, 0xf6, 0x00, 0x0a, 0x09, 0x02, 0xf5, 0xf3, 0xfe, + 0xf3, 0xf6, 0xfe, 0x00, 0x00, 0x05, 0x21, 0x1c, 0x0f, 0x09, 0x07, 0x05, + 0x03, 0x02, 0xf9, 0xfb, 0x00, 0x0d, 0x0b, 0x02, 0xfe, 0x00, 0x00, 0xfe, + 0xfe, 0xfe, 0xfe, 0xfb, 0xfe, 0x05, 0x00, 0x00, 0x01, 0x07, 0x1a, 0x1f, + 0x12, 0x0f, 0x07, 0x0d, 0x12, 0x14, 0x0d, 0x05, 0x00, 0xf6, 0xf9, 0xf9, + 0x00, 0x05, 0x02, 0x05, 0x02, 0x00, 0x05, 0x07, 0xff, 0x01, 0x00, 0xfb, + 0xf6, 0xf1, 0x00, 0x0d, 0x0d, 0x07, 0x02, 0x00, 0xfe, 0xfe, 0xfb, 0xf9, + 0xfb, 0x00, 0x05, 0x07, 0x02, 0x0d, 0x07, 0x05, 0x00, 0x00, 0x00, 0x05, + 0x14, 0x0d, 0x05, 0x0b, 0x16, 0x1d, 0x1c, 0x24, 0x1b, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xfb, 0xfe, 0x00, 0xfa, 0xf3, + 0xe6, 0xec, 0xf0, 0xf1, 0x07, 0x05, 0x00, 0x00, 0xfe, 0x05, 0x05, 0x16, + 0x25, 0x1a, 0x0d, 0x0e, 0x0d, 0x07, 0x05, 0x05, 0x05, 0x0d, 0x03, 0x00, + 0x02, 0x02, 0x07, 0x0d, 0x14, 0x0f, 0x0a, 0x05, 0xf7, 0xf6, 0xf3, 0xf1, + 0xf9, 0x02, 0x02, 0x01, 0x0d, 0x07, 0x07, 0x00, 0x05, 0x05, 0xfe, 0xf6, + 0xf9, 0xf9, 0xfb, 0x02, 0x05, 0x05, 0x05, 0x02, 0x00, 0x00, 0x02, 0x03, + 0x00, 0x0d, 0x0f, 0x0a, 0x07, 0x10, 0x0f, 0x0d, 0x1a, 0x12, 0x06, 0x02, + 0x02, 0x00, 0x02, 0x05, 0x02, 0xfe, 0xfd, 0xfb, 0xf7, 0xff, 0x02, 0x0a, + 0x03, 0x00, 0xfe, 0xfb, 0xfe, 0x05, 0x00, 0xff, 0x07, 0x0d, 0xfb, 0xfb, + 0x0d, 0x13, 0x0d, 0x07, 0x03, 0x02, 0x02, 0x00, 0x00, 0xfe, 0xfe, 0xfe, + 0xff, 0x00, 0x05, 0x00, 0xfe, 0xfb, 0xfd, 0x00, 0x00, 0x0d, 0x17, 0x1a, + 0x14, 0x1a, 0x14, 0x12, 0x1a, 0x21, 0x1a, 0x00, 0xf6, 0xf7, 0xfa, 0xfe, + 0x0a, 0x0d, 0x00, 0xfb, 0xfe, 0x05, 0x07, 0x00, 0xf6, 0xee, 0xee, 0xf1, + 0xf0, 0xfb, 0xfb, 0xfb, 0x00, 0x01, 0xfe, 0xf9, 0xfb, 0x07, 0x0f, 0x1f, + 0x1a, 0x12, 0x0f, 0x0a, 0x05, 0x02, 0x03, 0x01, 0x01, 0x01, 0x09, 0x0e, + 0x0b, 0x10, 0x13, 0x0e, 0x0b, 0x13, 0x06, 0xf5, 0x03, 0x09, 0x06, 0x03, + 0x03, 0x0b, 0x06, 0x06, 0xfd, 0xf7, 0xfb, 0xf6, 0xf0, 0xf0, 0xfa, 0xf2, + 0xf2, 0x0a, 0x13, 0x0e, 0x03, 0x00, 0xfd, 0xfd, 0xf7, 0xfd, 0x03, 0x03, + 0x0d, 0x0b, 0x0d, 0x13, 0x0b, 0x17, 0x1c, 0x1b, 0x10, 0x06, 0x06, 0x09, + 0x09, 0x03, 0x06, 0x0d, 0x09, 0x06, 0xfa, 0xf2, 0xf5, 0xfb, 0xfd, 0xf7, + 0xf1, 0xf2, 0x01, 0x18, 0x1d, 0x0b, 0xf2, 0xf2, 0xf2, 0x03, 0x09, 0x09, + 0x03, 0x00 +}; diff --git a/examples/PlayMODFromPROGMEMToPWM/PlayMODFromPROGMEMToPWM.ino b/examples/PlayMODFromPROGMEMToPWM/PlayMODFromPROGMEMToPWM.ino new file mode 100644 index 00000000..577da0e2 --- /dev/null +++ b/examples/PlayMODFromPROGMEMToPWM/PlayMODFromPROGMEMToPWM.ino @@ -0,0 +1,47 @@ +#include +#include "AudioFileSourcePROGMEM.h" +#include "AudioGeneratorMOD.h" +#include "AudioOutputPWM.h" + +#if !defined(ARDUINO_ARCH_RP2040) +void setup() { + Serial.begin(115200); + Serial.printf("Only for the RP2040/Raspberry Pi Pico\n"); +} + +void loop() { +} +#else + +// 5_steps.mod sample from the mod archive: https://modarchive.org/ +#include "5steps.h" + +AudioGeneratorMOD *mod; +AudioFileSourcePROGMEM *file; +AudioOutputPWM *out; + +void setup() { + Serial.begin(115200); + delay(1000); + + audioLogger = &Serial; + file = new AudioFileSourcePROGMEM(steps_mod, sizeof(steps_mod)); + out = new AudioOutputPWM(); + mod = new AudioGeneratorMOD(); + mod->SetBufferSize(3 * 1024); + mod->SetSampleRate(44100); + mod->SetStereoSeparation(32); + mod->begin(file, out); +} + +void loop() { + if (mod->isRunning()) { + if (!mod->loop()) { + mod->stop(); + } + } else { + Serial.printf("MOD done\n"); + delay(1000); + } +} +#endif diff --git a/examples/PlayMP3FromSPIFFS/PlayMP3FromSPIFFS.ino b/examples/PlayMP3FromSPIFFS/PlayMP3FromSPIFFS.ino index 364a7a89..eec99937 100644 --- a/examples/PlayMP3FromSPIFFS/PlayMP3FromSPIFFS.ino +++ b/examples/PlayMP3FromSPIFFS/PlayMP3FromSPIFFS.ino @@ -1,9 +1,14 @@ #include +#if defined(ARDUINO_ARCH_RP2040) +void setup() {} +void loop() {} +#else + #ifdef ESP32 - #include - #include "SPIFFS.h" +#include +#include "SPIFFS.h" #else - #include +#include #endif #include "AudioFileSourceSPIFFS.h" #include "AudioFileSourceID3.h" @@ -12,7 +17,7 @@ // To run, set your ESP8266 build to 160MHz, and include a SPIFFS of 512KB or greater. // Use the "Tools->ESP8266/ESP32 Sketch Data Upload" menu to write the MP3 to SPIFFS -// Then upload the sketch normally. +// Then upload the sketch normally. // pno_cs from https://ccrma.stanford.edu/~jos/pasp/Sound_Examples.html @@ -23,15 +28,14 @@ AudioFileSourceID3 *id3; // Called when a metadata event occurs (i.e. an ID3 tag, an ICY block, etc. -void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string) -{ +void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string) { (void)cbData; Serial.printf("ID3 callback for: %s = '", type); if (isUnicode) { string += 2; } - + while (*string) { char a = *(string++); if (isUnicode) { @@ -44,9 +48,8 @@ void MDCallback(void *cbData, const char *type, bool isUnicode, const char *stri } -void setup() -{ - WiFi.mode(WIFI_OFF); +void setup() { + WiFi.mode(WIFI_OFF); Serial.begin(115200); delay(1000); SPIFFS.begin(); @@ -61,12 +64,14 @@ void setup() mp3->begin(id3, out); } -void loop() -{ +void loop() { if (mp3->isRunning()) { - if (!mp3->loop()) mp3->stop(); + if (!mp3->loop()) { + mp3->stop(); + } } else { Serial.printf("MP3 done\n"); delay(1000); } } +#endif diff --git a/examples/PlayMP3ToSPDIF/PlayMP3ToSPDIF.ino b/examples/PlayMP3ToSPDIF/PlayMP3ToSPDIF.ino index 02dfb98f..9725e08a 100644 --- a/examples/PlayMP3ToSPDIF/PlayMP3ToSPDIF.ino +++ b/examples/PlayMP3ToSPDIF/PlayMP3ToSPDIF.ino @@ -1,17 +1,21 @@ #include +#ifdef ARDUINO_ARCH_RP2040 +void setup() {} +void loop() {} +#else #ifdef ESP32 - #include "SPIFFS.h" +#include "SPIFFS.h" #endif #include "AudioFileSourceSPIFFS.h" #include "AudioFileSourceID3.h" #include "AudioOutputSPDIF.h" #include "AudioGeneratorMP3.h" -// To run, set your ESP8266 build to 160MHz, and include a SPIFFS partition +// To run, set your ESP8266 build to 160MHz, and include a SPIFFS partition // big enough to hold your MP3 file. Find suitable MP3 file from i.e. // https://docs.espressif.com/projects/esp-adf/en/latest/design-guide/audio-samples.html -// and download it into 'data' directory. Use the "Tools->ESP8266/ESP32 Sketch Data Upload" -// menu to write the MP3 to SPIFFS. Then upload the sketch normally. +// and download it into 'data' directory. Use the "Tools->ESP8266/ESP32 Sketch Data Upload" +// menu to write the MP3 to SPIFFS. Then upload the sketch normally. AudioFileSourceSPIFFS *file; AudioFileSourceID3 *id3; @@ -19,15 +23,14 @@ AudioOutputSPDIF *out; AudioGeneratorMP3 *mp3; // Called when a metadata event occurs (i.e. an ID3 tag, an ICY block, etc. -void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string) -{ +void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string) { (void)cbData; Serial.printf("ID3 callback for: %s = '", type); if (isUnicode) { string += 2; } - + while (*string) { char a = *(string++); if (isUnicode) { @@ -40,15 +43,14 @@ void MDCallback(void *cbData, const char *type, bool isUnicode, const char *stri } -void setup() -{ +void setup() { Serial.begin(115200); delay(1000); Serial.println(); audioLogger = &Serial; SPIFFS.begin(); - file = new AudioFileSourceSPIFFS(); - id3 = NULL; + file = new AudioFileSourceSPIFFS(); + id3 = NULL; out = new AudioOutputSPDIF(); mp3 = new AudioGeneratorMP3(); String fileName = ""; @@ -56,7 +58,7 @@ void setup() // Find first MP3 file in SPIFF and play it #ifdef ESP32 - File dir, root = SPIFFS.open("/"); + File dir, root = SPIFFS.open("/"); while ((dir = root.openNextFile())) { if (String(dir.name()).endsWith(".mp3")) { if (file->open(dir.name())) { @@ -88,12 +90,14 @@ void setup() } } -void loop() -{ +void loop() { if (mp3->isRunning()) { - if (!mp3->loop()) mp3->stop(); + if (!mp3->loop()) { + mp3->stop(); + } } else { Serial.println("MP3 done"); delay(1000); } } +#endif diff --git a/examples/PlayOpusFromLittleFS/PlayOpusFromLittleFS.ino b/examples/PlayOpusFromLittleFS/PlayOpusFromLittleFS.ino new file mode 100644 index 00000000..8361b03f --- /dev/null +++ b/examples/PlayOpusFromLittleFS/PlayOpusFromLittleFS.ino @@ -0,0 +1,66 @@ +#include + +#ifdef ESP8266 + +void setup() { + Serial.begin(115200); +} + +void loop() { + Serial.println("OPUS not supported on the ESP8266, sorry!"); + delay(1000); +} + +#else + +#include +#include + +#include "AudioFileSourceLittleFS.h" +#include "AudioGeneratorOpus.h" +#include "AudioOutputI2S.h" + +// The includes OPUS file is from Kevin MacLeod (incompetech.com), Licensed under Creative Commons: By Attribution 3.0, http://creativecommons.org/licenses/by/3.0/ + +AudioGeneratorOpus *opus; +AudioFileSourceLittleFS *file; +AudioOutputI2S *out; + +#ifdef ESP32 +// We need more than the 8K default with other things running, so just double to avoid issues. +// Opus codes uses *lots* of stack variables in the internal decoder instead of a global working chunk +SET_LOOP_TASK_STACK_SIZE(16 * 1024); // 16KB +// On the Pico this is already taken care of using the built-in NONTHREADSAFE_PSEUDOSTACK in the config file. +#endif + +void setup() { + WiFi.mode(WIFI_OFF); + Serial.begin(115200); + delay(1000); + LittleFS.begin(); + Serial.printf("Sample Opus playback begins...\n"); + + audioLogger = &Serial; + file = new AudioFileSourceLittleFS("/gs-16b-2c-44100hz.opus"); +#ifdef ARDUINO_ARCH_RP2040 + out = new AudioOutputI2S(48000, 26, 22); +#else + out = new AudioOutputI2S(); + // out->SetPinout(0, 1, 2); // Set the pinout if needed +#endif + opus = new AudioGeneratorOpus(); + opus->begin(file, out); +} + +void loop() { + if (opus->isRunning()) { + if (!opus->loop()) { + opus->stop(); + } + } else { + Serial.printf("Opus done\n"); + delay(1000); + } +} + +#endif diff --git a/examples/PlayOpusFromSPIFFS/data/gs-16b-2c-44100hz.opus b/examples/PlayOpusFromLittleFS/data/gs-16b-2c-44100hz.opus similarity index 100% rename from examples/PlayOpusFromSPIFFS/data/gs-16b-2c-44100hz.opus rename to examples/PlayOpusFromLittleFS/data/gs-16b-2c-44100hz.opus diff --git a/examples/PlayOpusFromSPIFFS/PlayOpusFromSPIFFS.ino b/examples/PlayOpusFromSPIFFS/PlayOpusFromSPIFFS.ino deleted file mode 100644 index 44db7c4a..00000000 --- a/examples/PlayOpusFromSPIFFS/PlayOpusFromSPIFFS.ino +++ /dev/null @@ -1,41 +0,0 @@ -#include -#ifdef ESP32 - #include - #include "SPIFFS.h" -#else - #include -#endif -#include "AudioFileSourceSPIFFS.h" -#include "AudioGeneratorOpus.h" -#include "AudioOutputI2S.h" - -// The includes OPUS file is from Kevin MacLeod (incompetech.com), Licensed under Creative Commons: By Attribution 3.0, http://creativecommons.org/licenses/by/3.0/ - -AudioGeneratorOpus *opus; -AudioFileSourceSPIFFS *file; -AudioOutputI2S *out; - -void setup() -{ - WiFi.mode(WIFI_OFF); - Serial.begin(115200); - delay(1000); - SPIFFS.begin(); - Serial.printf("Sample Opus playback begins...\n"); - - audioLogger = &Serial; - file = new AudioFileSourceSPIFFS("/gs-16b-2c-44100hz.opus"); - out = new AudioOutputI2S(); - opus = new AudioGeneratorOpus(); - opus->begin(file, out); -} - -void loop() -{ - if (opus->isRunning()) { - if (!opus->loop()) opus->stop(); - } else { - Serial.printf("Opus done\n"); - delay(1000); - } -} diff --git a/examples/PlayRTTTLToI2SDAC/PlayRTTTLToI2SDAC.ino b/examples/PlayRTTTLToI2SDAC/PlayRTTTLToI2SDAC.ino index fa12eaad..a128471b 100644 --- a/examples/PlayRTTTLToI2SDAC/PlayRTTTLToI2SDAC.ino +++ b/examples/PlayRTTTLToI2SDAC/PlayRTTTLToI2SDAC.ino @@ -2,32 +2,32 @@ #include "AudioGeneratorRTTTL.h" #include "AudioOutputI2S.h" -const char rudolph[] PROGMEM = -"Rudolph the Red Nosed Raindeer:d=8,o=5,b=250:g,4a,g,4e,4c6,4a,2g.,g,a,g,a,4g,4c6,2b.,4p,f,4g,f,4d,4b,4a,2g.,g,a,g,a,4g,4a,2e.,4p,g,4a,a,4e,4c6,4a,2g.,g,a,g,a,4g,4c6,2b.,4p,f,4g,f,4d,4b,4a,2g.,g,a,g,a,4g,4d6,2c.6,4p,4a,4a,4c6,4a,4g,4e,2g,4d,4e,4g,4a,4b,4b,2b,4c6,4c6,4b,4a,4g,4f,2d,g,4a,g,4e,4c6,4a,2g.,g,a,g,a,4g,4c6,2b.,4p,f,4g,f,4d,4b,4a,2g.,4g,4a,4g,4a,2g,2d6,1c.6."; +const char rudolph[] PROGMEM = + "Rudolph the Red Nosed Raindeer:d=8,o=5,b=250:g,4a,g,4e,4c6,4a,2g.,g,a,g,a,4g,4c6,2b.,4p,f,4g,f,4d,4b,4a,2g.,g,a,g,a,4g,4a,2e.,4p,g,4a,a,4e,4c6,4a,2g.,g,a,g,a,4g,4c6,2b.,4p,f,4g,f,4d,4b,4a,2g.,g,a,g,a,4g,4d6,2c.6,4p,4a,4a,4c6,4a,4g,4e,2g,4d,4e,4g,4a,4b,4b,2b,4c6,4c6,4b,4a,4g,4f,2d,g,4a,g,4e,4c6,4a,2g.,g,a,g,a,4g,4c6,2b.,4p,f,4g,f,4d,4b,4a,2g.,4g,4a,4g,4a,2g,2d6,1c.6."; // Plenty more at: http://mines.lumpylumpy.com/Electronics/Computers/Software/Cpp/MFC/RingTones.RTTTL AudioGeneratorRTTTL *rtttl; AudioFileSourcePROGMEM *file; AudioOutputI2S *out; -void setup() -{ +void setup() { Serial.begin(115200); delay(1000); Serial.printf("RTTTL start\n"); audioLogger = &Serial; - file = new AudioFileSourcePROGMEM( rudolph, strlen_P(rudolph) ); + file = new AudioFileSourcePROGMEM(rudolph, strlen_P(rudolph)); out = new AudioOutputI2S(); rtttl = new AudioGeneratorRTTTL(); rtttl->begin(file, out); } -void loop() -{ +void loop() { if (rtttl->isRunning()) { - if (!rtttl->loop()) rtttl->stop(); + if (!rtttl->loop()) { + rtttl->stop(); + } } else { Serial.printf("RTTTL done\n"); delay(1000); diff --git a/examples/PlayWAVFromFunction/PlayWAVFromFunction.ino b/examples/PlayWAVFromFunction/PlayWAVFromFunction.ino new file mode 100644 index 00000000..eba92a14 --- /dev/null +++ b/examples/PlayWAVFromFunction/PlayWAVFromFunction.ino @@ -0,0 +1,80 @@ +#include +#include "AudioFileSourceFunction.h" +#include "AudioGeneratorWAV.h" +#include "AudioOutputI2SNoDAC.h" + +float hz = 440.f; + +// pre-defined function can also be used to generate the wave +float sine_wave(const float time) { + float v = sin(TWO_PI * hz * time); // C + v *= fmod(time, 1.f); // change linear + v *= 0.5; // scale + return v; +}; + +AudioGeneratorWAV* wav; +AudioFileSourceFunction* file; +AudioOutputI2SNoDAC* out; + +void setup() { + Serial.begin(115200); + delay(1000); + + // ===== create instance with length of song in [sec] ===== + file = new AudioFileSourceFunction(8.); + // + // you can set (sec, channels, hz, bit/sample) but you should care about + // the trade-off between performance and the audio quality + // + // file = new AudioFileSourceFunction(sec, channels, hz, bit/sample); + // channels : default = 1 + // hz : default = 8000 (8000, 11025, 22050, 44100, 48000, etc.) + // bit/sample : default = 16 (8, 16, 32) + + // ===== set your sound function ===== + file->addAudioGenerators([&](const float time) { + float v = sin(TWO_PI * hz * time); // generate sine wave + v *= fmod(time, 1.f); // change linear + v *= 0.5; // scale + return v; + }); + // + // sound function should have one argument(float) and one return(float) + // param : float (current time [sec] of the song) + // return : float (the amplitude of sound which varies from -1.f to +1.f) + // + // sound function can be registered only one or the same number with channels + // if the channels > 1 && the number of function == 1, + // same function are used to generate the sound in every channel + // + // file = new AudioFileSourceFunction(8., 2); + // file->addAudioGenerators( + // // L (channel 0) + // [](const float time) { + // return 0.25 * sin(TWO_PI * 440.f * time) * fmod(time, 1.f); // C + // }, + // // R (channel 1) + // [](const float time) { + // return 0.25 * sin(TWO_PI * 550.f * time) * fmod(time, 1.f); // E + // } + // ); + // + // you can also use the pre-defined function + // file->addAudioGenerators(sine_wave); + + out = new AudioOutputI2SNoDAC(); + wav = new AudioGeneratorWAV(); + wav->begin(file, out); +} + +void loop() { + if (wav->isRunning()) { + if (!wav->loop()) { + wav->stop(); + } + } else { + Serial.println("function done!"); + delay(1000); + } +} diff --git a/examples/PlayWAVFromPROGMEM/PlayWAVFromPROGMEM.ino b/examples/PlayWAVFromPROGMEM/PlayWAVFromPROGMEM.ino index 5221c913..1cf89c6a 100644 --- a/examples/PlayWAVFromPROGMEM/PlayWAVFromPROGMEM.ino +++ b/examples/PlayWAVFromPROGMEM/PlayWAVFromPROGMEM.ino @@ -1,9 +1,4 @@ #include -#ifdef ESP32 - #include -#else - #include -#endif #include "AudioFileSourcePROGMEM.h" #include "AudioGeneratorWAV.h" @@ -16,24 +11,23 @@ AudioGeneratorWAV *wav; AudioFileSourcePROGMEM *file; AudioOutputI2SNoDAC *out; -void setup() -{ - WiFi.mode(WIFI_OFF); +void setup() { Serial.begin(115200); delay(1000); Serial.printf("WAV start\n"); audioLogger = &Serial; - file = new AudioFileSourcePROGMEM( viola, sizeof(viola) ); + file = new AudioFileSourcePROGMEM(viola, sizeof(viola)); out = new AudioOutputI2SNoDAC(); wav = new AudioGeneratorWAV(); wav->begin(file, out); } -void loop() -{ +void loop() { if (wav->isRunning()) { - if (!wav->loop()) wav->stop(); + if (!wav->loop()) { + wav->stop(); + } } else { Serial.printf("WAV done\n"); delay(1000); diff --git a/examples/StreamMP3FromHTTP/StreamMP3FromHTTP.ino b/examples/StreamMP3FromHTTP/StreamMP3FromHTTP.ino index 8ea45157..1a5aafb0 100644 --- a/examples/StreamMP3FromHTTP/StreamMP3FromHTTP.ino +++ b/examples/StreamMP3FromHTTP/StreamMP3FromHTTP.ino @@ -1,9 +1,14 @@ #include -#ifdef ESP32 - #include +#if defined(ARDUINO_ARCH_RP2040) +void setup() {} +void loop() {} + +#else +#if defined(ESP32) +#include #else - #include +#include #endif #include "AudioFileSourceICYStream.h" #include "AudioFileSourceBuffer.h" @@ -22,7 +27,7 @@ const char* ssid = STASSID; const char* password = STAPSK; // Randomly picked URL -const char *URL="http://streaming.shoutcast.com/80sPlanet?lang=en-US"; +const char *URL = "http://kvbstreams.dyndns.org:8000/wkvi-am"; AudioGeneratorMP3 *mp3; AudioFileSourceICYStream *file; @@ -30,35 +35,32 @@ AudioFileSourceBuffer *buff; AudioOutputI2SNoDAC *out; // Called when a metadata event occurs (i.e. an ID3 tag, an ICY block, etc. -void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string) -{ +void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string) { const char *ptr = reinterpret_cast(cbData); (void) isUnicode; // Punt this ball for now // Note that the type and string may be in PROGMEM, so copy them to RAM for printf char s1[32], s2[64]; strncpy_P(s1, type, sizeof(s1)); - s1[sizeof(s1)-1]=0; + s1[sizeof(s1) - 1] = 0; strncpy_P(s2, string, sizeof(s2)); - s2[sizeof(s2)-1]=0; + s2[sizeof(s2) - 1] = 0; Serial.printf("METADATA(%s) '%s' = '%s'\n", ptr, s1, s2); Serial.flush(); } // Called when there's a warning or error (like a buffer underflow or decode hiccup) -void StatusCallback(void *cbData, int code, const char *string) -{ +void StatusCallback(void *cbData, int code, const char *string) { const char *ptr = reinterpret_cast(cbData); // Note that the string may be in PROGMEM, so copy it to RAM for printf char s1[64]; strncpy_P(s1, string, sizeof(s1)); - s1[sizeof(s1)-1]=0; + s1[sizeof(s1) - 1] = 0; Serial.printf("STATUS(%s) '%d' = '%s'\n", ptr, code, s1); Serial.flush(); } -void setup() -{ +void setup() { Serial.begin(115200); delay(1000); Serial.println("Connecting to WiFi"); @@ -66,7 +68,7 @@ void setup() WiFi.disconnect(); WiFi.softAPdisconnect(true); WiFi.mode(WIFI_STA); - + WiFi.begin(ssid, password); // Try forever @@ -88,20 +90,21 @@ void setup() } -void loop() -{ +void loop() { static int lastms = 0; if (mp3->isRunning()) { - if (millis()-lastms > 1000) { + if (millis() - lastms > 1000) { lastms = millis(); Serial.printf("Running for %d ms...\n", lastms); Serial.flush(); - } - if (!mp3->loop()) mp3->stop(); + } + if (!mp3->loop()) { + mp3->stop(); + } } else { Serial.printf("MP3 done\n"); delay(1000); } } - +#endif diff --git a/examples/StreamMP3FromHTTPToSPDIF/StreamMP3FromHTTPToSPDIF.ino b/examples/StreamMP3FromHTTPToSPDIF/StreamMP3FromHTTPToSPDIF.ino new file mode 100644 index 00000000..200a3e93 --- /dev/null +++ b/examples/StreamMP3FromHTTPToSPDIF/StreamMP3FromHTTPToSPDIF.ino @@ -0,0 +1,144 @@ +#include +#ifdef ARDUINO_ARCH_RP2040 +void setup() {} +void loop() {} +#else + +#if defined(ESP32) +#include +#else +#include +#endif +#include "AudioFileSourceICYStream.h" +#include "AudioFileSourceBuffer.h" +#include "AudioGeneratorMP3.h" +//#include "AudioOutputI2SNoDAC.h" +#include "AudioOutputSPDIF.h" + +// +// Stream MP3 from HTTP to SPDIF +// + +// To run, set your ESP8266 build to 160MHz, update the SSID info, and upload. + +// Note: +// If using ESP8266 NodeMCU connect LED to RX pin and GND pin + +// Enter your WiFi setup here: +#ifndef STASSID +#define STASSID "your-ssid" +#define STAPSK "your-password" +#endif + +const char* ssid = STASSID; +const char* password = STAPSK; + +// Examples URLs +//const char *URL="http://kvbstreams.dyndns.org:8000/wkvi-am"; + +// Italian Rock Radio +const char *URL = "http://streamingv2.shoutcast.com/radiofreccia"; + +// Stream URL of Logitech Media Server, aka LMS, Version: 8.2.0 (August 2021) +// const char *URL="http://192.168.1.121:9000/stream.mp3"; + +AudioGeneratorMP3 *mp3; +AudioFileSourceICYStream *file; +AudioFileSourceBuffer *buff; + +// Output device is SPDIF +AudioOutputSPDIF *out; + + +// Called when a metadata event occurs (i.e. an ID3 tag, an ICY block, etc. +void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string) { + const char *ptr = reinterpret_cast(cbData); + (void) isUnicode; // Punt this ball for now + // Note that the type and string may be in PROGMEM, so copy them to RAM for printf + char s1[32], s2[64]; + strncpy_P(s1, type, sizeof(s1)); + s1[sizeof(s1) - 1] = 0; + strncpy_P(s2, string, sizeof(s2)); + s2[sizeof(s2) - 1] = 0; + Serial.printf("METADATA(%s) '%s' = '%s'\n", ptr, s1, s2); + Serial.flush(); +} + +// Called when there's a warning or error (like a buffer underflow or decode hiccup) +void StatusCallback(void *cbData, int code, const char *string) { + const char *ptr = reinterpret_cast(cbData); + // Note that the string may be in PROGMEM, so copy it to RAM for printf + char s1[64]; + strncpy_P(s1, string, sizeof(s1)); + s1[sizeof(s1) - 1] = 0; + Serial.printf("STATUS(%s) '%d' = '%s'\n", ptr, code, s1); + Serial.flush(); +} + + +void setup() { + Serial.begin(115200); + delay(1000); + Serial.println("Connecting to WiFi"); + + WiFi.disconnect(); + WiFi.softAPdisconnect(true); + WiFi.mode(WIFI_STA); + + WiFi.begin(ssid, password); + + // Try forever + while (WiFi.status() != WL_CONNECTED) { + Serial.println("...Connecting to WiFi"); + delay(1000); + } + Serial.println("Connected"); + + audioLogger = &Serial; + file = new AudioFileSourceICYStream(URL); + + // Commented out for performance issues with high rate MP3 stream + //file->RegisterMetadataCB(MDCallback, (void*)"ICY"); + + buff = new AudioFileSourceBuffer(file, 4096); // Doubled form default 2048 + + // Commented out for performance issues with high rate MP3 stream + //buff->RegisterStatusCB(StatusCallback, (void*)"buffer"); + + // Set SPDIF output + out = new AudioOutputSPDIF(); + mp3 = new AudioGeneratorMP3(); + + // Commented out for performance issues with high rate MP3 stream + //mp3->RegisterStatusCB(StatusCallback, (void*)"mp3"); + + mp3->begin(buff, out); +} + + +void loop() { + // Commented out + //static int lastms = 0; + + if (mp3->isRunning()) { + /* Commented out + if (millis()-lastms > 1000) { + lastms = millis(); + Serial.printf("Running for %d ms...\n", lastms); + Serial.flush(); + } + */ + if (!mp3->loop()) { + mp3->stop(); + } + } else { + Serial.printf("MP3 done\n"); + + // Restart ESP when streaming is done or errored + delay(10000); + + ESP.restart(); + } +} + +#endif diff --git a/examples/StreamMP3FromHTTP_SPIRAM/StreamMP3FromHTTP_SPIRAM.ino b/examples/StreamMP3FromHTTP_SPIRAM/StreamMP3FromHTTP_SPIRAM.ino index 0b9ab092..8f6d5a71 100644 --- a/examples/StreamMP3FromHTTP_SPIRAM/StreamMP3FromHTTP_SPIRAM.ino +++ b/examples/StreamMP3FromHTTP_SPIRAM/StreamMP3FromHTTP_SPIRAM.ino @@ -1,8 +1,12 @@ #include -#ifdef ESP32 - #include +#if defined(ARDUINO_ARCH_RP2040) +void setup() {} +void loop() {} #else - #include +#if defined(ESP32) +#include +#else +#include #endif #include "AudioFileSourceICYStream.h" #include "AudioFileSourceSPIRAMBuffer.h" @@ -21,7 +25,7 @@ const char* ssid = STASSID; const char* password = STAPSK; // Randomly picked URL -const char *URL="http://kvbstreams.dyndns.org:8000/wkvi-am"; +const char *URL = "http://kvbstreams.dyndns.org:8000/wkvi-am"; AudioGeneratorMP3 *mp3; AudioFileSourceICYStream *file; @@ -29,8 +33,7 @@ AudioFileSourceSPIRAMBuffer *buff; AudioOutputI2SNoDAC *out; // Called when a metadata event occurs (i.e. an ID3 tag, an ICY block, etc. -void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string) -{ +void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string) { const char *ptr = reinterpret_cast(cbData); (void) isUnicode; // Punt this ball for now // Note that the type and string may be in PROGMEM, so copy them to RAM for printf @@ -40,8 +43,7 @@ void MDCallback(void *cbData, const char *type, bool isUnicode, const char *stri // Called when there's a warning or error (like a buffer underflow or decode hiccup) -void StatusCallback(void *cbData, int code, const char *string) -{ +void StatusCallback(void *cbData, int code, const char *string) { const char *ptr = reinterpret_cast(cbData); static uint32_t lastTime = 0; static int lastCode = -99999; @@ -54,8 +56,7 @@ void StatusCallback(void *cbData, int code, const char *string) } } -void setup() -{ +void setup() { Serial.begin(115200); delay(1000); Serial.println("Connecting to WiFi"); @@ -63,7 +64,7 @@ void setup() WiFi.disconnect(); WiFi.softAPdisconnect(true); WiFi.mode(WIFI_STA); - + WiFi.begin(ssid, password); // Try forever @@ -77,7 +78,7 @@ void setup() file = new AudioFileSourceICYStream(URL); file->RegisterMetadataCB(MDCallback, (void*)"ICY"); // Initialize 23LC1024 SPI RAM buffer with chip select ion GPIO4 and ram size of 128KByte - buff = new AudioFileSourceSPIRAMBuffer(file, 4, 128*1024); + buff = new AudioFileSourceSPIRAMBuffer(file, 4, 128 * 1024); buff->RegisterStatusCB(StatusCallback, (void*)"buffer"); out = new AudioOutputI2SNoDAC(); mp3 = new AudioGeneratorMP3(); @@ -85,20 +86,21 @@ void setup() mp3->begin(buff, out); } -void loop() -{ +void loop() { static int lastms = 0; if (mp3->isRunning()) { - if (millis()-lastms > 1000) { + if (millis() - lastms > 1000) { lastms = millis(); Serial.printf("Running for %d ms...\n", lastms); Serial.flush(); - } - if (!mp3->loop()) mp3->stop(); + } + if (!mp3->loop()) { + mp3->stop(); + } } else { Serial.printf("MP3 done\n"); delay(1000); } } - +#endif diff --git a/examples/StreamOnHost/AudioOutputLinuxDSP.h b/examples/StreamOnHost/AudioOutputLinuxDSP.h new file mode 100644 index 00000000..743410e8 --- /dev/null +++ b/examples/StreamOnHost/AudioOutputLinuxDSP.h @@ -0,0 +1,118 @@ +/* + AudioOutput + Base class of an audio output player + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _AUDIOOUTPUTNULLSLOW_H +#define _AUDIOOUTPUTNULLSLOW_H + +#include +#include +#include +#include +#include +#include +#include + +#include "AudioOutput.h" + +class AudioOutputNullSlow : public AudioOutput +{ + public: + AudioOutputNullSlow() { }; + ~AudioOutputNullSlow() {}; + virtual bool begin() { samples = 0; startms = millis(); return true; } + + virtual bool ConsumeSample(int16_t sample[2]) { + + if (fd < 0) { + fd = open("/dev/dsp", O_RDWR); + if (fd < 0) { + perror("open of /dev/dsp failed (Try with 'padsp this-exec')"); + exit(1); + } + } + + if (channels && lastchannels != channels) { + Serial.printf("CHANNELS=%d\n", channels); + int arg = channels; /* mono or stereo */ + int status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg); + if (status == -1) { + perror("SOUND_PCM_WRITE_CHANNELS ioctl failed"); + exit(1); + } else if (arg != channels) { + perror("unable to set number of channels"); + exit(1); + } + lastchannels = channels; + } + + if (lastchannels > 0 && hertz && lasthertz != hertz) { + Serial.printf("FREQ=%d\n", hertz); + int arg = hertz*4/lastchannels; /* sampling rate */ + int status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg); + if (status == -1) { + perror("SOUND_PCM_WRITE_RATE ioctl failed"); + exit(1); + } + lasthertz = hertz; + } + + if (bps && lastbps != bps) { + Serial.printf("BPS=%d\n", bps); + int arg = bps; /* sample size */ + int status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg); + if (status == -1) { + perror("SOUND_PCM_WRITE_BITS ioctl failed"); + exit(1); + } else if (arg != bps) { + perror("unable to set sample size"); + exit(1); + } + lastbps = bps; + } + + if ((++samples & ((1<<9)-1)) == 0) { + // let the main loop a chance to run + return false; + } + + if (write(fd, sample, sizeof(sample)) != sizeof(sample)) { + perror("doing sound"); + exit(1); + } + + return true; + } + + virtual bool stop() { endms = millis(); return true; }; + unsigned long GetMilliseconds() { return endms - startms; } + int GetSamples() { return samples; } + int GetFrequency() { return hertz; } + + protected: + unsigned long startms; + unsigned long endms; + int samples; + int lastchannels = -1; + int lasthertz = -1; + int lastbps = -1; + int fd = -1; +}; + +#endif diff --git a/examples/StreamOnHost/AudioOutputNullSlow.h b/examples/StreamOnHost/AudioOutputNullSlow.h new file mode 100644 index 00000000..3010862e --- /dev/null +++ b/examples/StreamOnHost/AudioOutputNullSlow.h @@ -0,0 +1,58 @@ +/* + AudioOutput + Base class of an audio output player + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _AUDIOOUTPUTNULLSLOW_H +#define _AUDIOOUTPUTNULLSLOW_H + +#include "AudioOutput.h" + +class AudioOutputNullSlow : public AudioOutput +{ + public: + AudioOutputNullSlow() { }; + ~AudioOutputNullSlow() {}; + virtual bool begin() { samples = 0; startms = millis(); return true; } + virtual bool ConsumeSample(int16_t sample[2]) { + (void) sample; + // return false (= output buffer full) + // sometimes to let the main loop running + constexpr int everylog2 = 10; + if ((++samples & ((1< 0) { + // simulate real time + delay(1000/(hertz >> everylog2)); + } + return false; + } + return true; + } + virtual bool stop() { endms = millis(); return true; }; + unsigned long GetMilliseconds() { return endms - startms; } + int GetSamples() { return samples; } + int GetFrequency() { return hertz; } + + protected: + unsigned long startms; + unsigned long endms; + int samples; +}; + +#endif + diff --git a/examples/StreamOnHost/StreamOnHost.ino b/examples/StreamOnHost/StreamOnHost.ino new file mode 100644 index 00000000..5494bdd9 --- /dev/null +++ b/examples/StreamOnHost/StreamOnHost.ino @@ -0,0 +1,120 @@ +#include + +#if defined(ARDUINO_ARCH_RP2040) +void setup() {} +void loop() {} +#else +#if defined(ESP32) +#include +#else +#include +#endif +#include "AudioFileSourceICYStream.h" +#include "AudioFileSourceBuffer.h" +#include "AudioGeneratorMP3.h" +#if AUDIO +// #pragma message("Outputting audio") +#include "AudioOutputLinuxDSP.h" +#else +// #pragma message("No audio") +#include "AudioOutputNullSlow.h" +#endif + +// To run, set your ESP8266 build to 160MHz, update the SSID info, and upload. + +// Enter your WiFi setup here: +#ifndef STASSID +#define STASSID "your-ssid" +#define STAPSK "your-password" +#endif + +const char* ssid = STASSID; +const char* password = STAPSK; + +// Randomly picked URL +//const char *URL="http://kvbstreams.dyndns.org:8000/wkvi-am"; +//const char *URL="http://stream2.pvpjamz.com:8706/stream"; +// that one is not well decoded: +const char *URL = "http://icecast.radiofrance.fr/franceinter-lofi.mp3"; + +AudioGeneratorMP3 *mp3; +AudioFileSourceICYStream *file; +AudioFileSourceBuffer *buff; +AudioOutputNullSlow *out; + +// Called when a metadata event occurs (i.e. an ID3 tag, an ICY block, etc. +void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string) { + const char *ptr = reinterpret_cast(cbData); + (void) isUnicode; // Punt this ball for now + // Note that the type and string may be in PROGMEM, so copy them to RAM for printf + char s1[32], s2[64]; + strncpy_P(s1, type, sizeof(s1)); + s1[sizeof(s1) - 1] = 0; + strncpy_P(s2, string, sizeof(s2)); + s2[sizeof(s2) - 1] = 0; + Serial.printf("METADATA(%s) '%s' = '%s'\n", ptr, s1, s2); + Serial.flush(); +} + +// Called when there's a warning or error (like a buffer underflow or decode hiccup) +void StatusCallback(void *cbData, int code, const char *string) { + const char *ptr = reinterpret_cast(cbData); + // Note that the string may be in PROGMEM, so copy it to RAM for printf + char s1[64]; + strncpy_P(s1, string, sizeof(s1)); + s1[sizeof(s1) - 1] = 0; + Serial.printf("STATUS(%s) '%d' = '%s'\n", ptr, code, s1); + Serial.flush(); +} + + +void setup() { + Serial.begin(115200); + delay(1000); + Serial.println("Connecting to WiFi"); + + WiFi.disconnect(); + WiFi.softAPdisconnect(true); + WiFi.mode(WIFI_STA); + + WiFi.begin(ssid, password); + + // Try forever + while (WiFi.status() != WL_CONNECTED) { + Serial.println("...Connecting to WiFi"); + delay(1000); + } + Serial.println("Connected"); + + audioLogger = &Serial; + file = new AudioFileSourceICYStream(); + file->RegisterMetadataCB(MDCallback, (void*)"ICY"); + file->useHTTP10(); + file->open(URL); + buff = new AudioFileSourceBuffer(file, 2048); + buff->RegisterStatusCB(StatusCallback, (void*)"buffer"); + out = new AudioOutputNullSlow(); + mp3 = new AudioGeneratorMP3(); + mp3->RegisterStatusCB(StatusCallback, (void*)"mp3"); + mp3->begin(buff, out); +} + + +void loop() { + static int lastms = 0; + + if (mp3->isRunning()) { + if (millis() - lastms > 1000) { + lastms = millis(); + Serial.printf("Running for %d ms...\n", lastms); + Serial.flush(); + } + if (!mp3->loop()) { + mp3->stop(); + } + } else { + Serial.printf("MP3 done\n"); + delay(1000); + } +} +#endif diff --git a/examples/StreamOnHost/onHost b/examples/StreamOnHost/onHost new file mode 100755 index 00000000..01484569 --- /dev/null +++ b/examples/StreamOnHost/onHost @@ -0,0 +1,66 @@ +#!/bin/bash + +ino=${PWD##*/} + +if [ ! -d "${ESP8266ARDUINO}/tests/host" ]; then + echo "\${ESP8266ARDUINO} should point to ESP8266 Arduino core directory" + exit 1 +fi + +THISLIB=$(pwd)/../.. +MAD=$(ls ${THISLIB}/src/libmad/*.c) +PAGER=${PAGER:-less} + +cd ${ESP8266ARDUINO}/tests/host + +if [ "$1" = "clean" ]; then + make clean + cd ${THISLIB} + rm -f src/*.o src/libmad/*.o + exit 0 +elif [ "$1" = diff ]; then + cd ${THISLIB}/examples + diff -u StreamMP3FromHTTP/StreamMP3FromHTTP.ino ${ino}/${ino}.ino | ${PAGER} + exit 0 +else + echo "" + echo "usage:" + echo " $0" + echo " $0 clean" + echo " $0 diff" + echo " AUDIO=a VALGRIND=v FORCE32=f $0" + echo " a=1 play sound (use padsp, open /dev/dsp)" + echo " v=1 run in native mode (FORCE32=0) with valgrind" + echo " f=1 run in 32 bits mode (if gcc-multilib is installed)" + echo "variable ESP8266ARDUINO must point to esp8266 Arduino core directory" + echo "" + [ "$1" = "-h" ] && exit 0 + sleep 1 +fi + +run="" + +[ -z "${FORCE32}" ] && FORCE32=0 +[ -z "${AUDIO}" ] && AUDIO=1 + +if [ "${AUDIO}" = 1 ]; then + run="${run} padsp" +fi + +if [ "${VALGRIND}" = 1 ]; then + FORCE32=0 + run="$run valgrind" +fi + +touch ${THISLIB}/examples/${ino}/${ino}.ino # rebuild + +eval make FORCE32=${FORCE32} -j \ + USERCSOURCES=\"${MAD}\" \ + USERCXXSOURCES=\"${THISLIB}/src/AudioFileSourceBuffer.cpp ${THISLIB}/src/AudioLogger.cpp ${THISLIB}/src/AudioGeneratorMP3.cpp ${THISLIB}/src/AudioFileSourceICYStream.cpp ${THISLIB}/src/AudioFileSourceHTTPStream.cpp\" \ + USERCFLAGS=\"-I${THISLIB}/src/ -DAUDIO=${AUDIO}\" \ + ${THISLIB}/examples/${ino}/${ino} + +set -x + +$run ./bin/${ino}/${ino} "$@" +stty sane diff --git a/examples/TalkingClockI2S/TalkingClockI2S.ino b/examples/TalkingClockI2S/TalkingClockI2S.ino index 6a2f7312..ea5e082f 100644 --- a/examples/TalkingClockI2S/TalkingClockI2S.ino +++ b/examples/TalkingClockI2S/TalkingClockI2S.ino @@ -2,10 +2,12 @@ // https://github.com/going-digital/Talkie/blob/master/Talkie/examples/Vocab_US_Clock/Vocab_US_Clock.ino // Released under GPL v2 -#ifdef ESP32 - #include +#include + +#ifdef ESP8266 +#include #else - #include +#include #endif #include @@ -24,67 +26,73 @@ const char *pass = STAPSK; long timezone = 2; byte daysavetime = 1; -uint8_t spTHE[] PROGMEM = {0x08,0xE8,0x3E,0x55,0x01,0xC3,0x86,0x27,0xAF,0x72,0x0D,0x4D,0x97,0xD5,0xBC,0x64,0x3C,0xF2,0x5C,0x51,0xF1,0x93,0x36,0x8F,0x4F,0x59,0x2A,0x42,0x7A,0x32,0xC3,0x64,0xFF,0x3F}; -uint8_t spTIME[] PROGMEM = {0x0E,0x28,0xAC,0x2D,0x01,0x5D,0xB6,0x0D,0x33,0xF3,0x54,0xB3,0x60,0xBA,0x8C,0x54,0x5C,0xCD,0x2D,0xD4,0x32,0x73,0x0F,0x8E,0x34,0x33,0xCB,0x4A,0x25,0xD4,0x25,0x83,0x2C,0x2B,0xD5,0x50,0x97,0x08,0x32,0xEC,0xD4,0xDC,0x4C,0x33,0xC8,0x70,0x73,0x0F,0x33,0xCD,0x20,0xC3,0xCB,0x43,0xDD,0x3C,0xCD,0x8C,0x20,0x77,0x89,0xF4,0x94,0xB2,0xE2,0xE2,0x35,0x22,0x5D,0xD6,0x4A,0x8A,0x96,0xCC,0x36,0x25,0x2D,0xC9,0x9A,0x7B,0xC2,0x18,0x87,0x24,0x4B,0x1C,0xC9,0x50,0x19,0x92,0x2C,0x71,0x34,0x4B,0x45,0x8A,0x8B,0xC4,0x96,0xB6,0x5A,0x29,0x2A,0x92,0x5A,0xCA,0x53,0x96,0x20,0x05,0x09,0xF5,0x92,0x5D,0xBC,0xE8,0x58,0x4A,0xDD,0xAE,0x73,0xBD,0x65,0x4B,0x8D,0x78,0xCA,0x2B,0x4E,0xD8,0xD9,0xED,0x22,0x20,0x06,0x75,0x00,0x00,0x80,0xFF,0x07}; -uint8_t spIS[] PROGMEM = {0x21,0x18,0x96,0x38,0xB7,0x14,0x8D,0x60,0x3A,0xA6,0xE8,0x51,0xB4,0xDC,0x2E,0x48,0x7B,0x5A,0xF1,0x70,0x1B,0xA3,0xEC,0x09,0xC6,0xCB,0xEB,0x92,0x3D,0xA7,0x69,0x1F,0xAF,0x71,0x89,0x9C,0xA2,0xB3,0xFC,0xCA,0x35,0x72,0x9A,0xD1,0xF0,0xAB,0x12,0xB3,0x2B,0xC6,0xCD,0x4F,0xCC,0x32,0x26,0x19,0x07,0xDF,0x0B,0x8F,0xB8,0xA4,0xED,0x7C,0xCF,0x23,0x62,0x8B,0x8E,0xF1,0x23,0x0A,0x8B,0x6E,0xCB,0xCE,0xEF,0x54,0x44,0x3C,0xDC,0x08,0x60,0x0B,0x37,0x01,0x1C,0x53,0x26,0x80,0x15,0x4E,0x14,0xB0,0x54,0x2B,0x02,0xA4,0x69,0xFF,0x7F}; -uint8_t spA_M_[] PROGMEM = {0xCD,0xEF,0x86,0xAB,0x57,0x6D,0x0F,0xAF,0x71,0xAD,0x49,0x55,0x3C,0xFC,0x2E,0xC5,0xB7,0x5C,0xF1,0xF2,0x87,0x66,0xDD,0x4E,0xC5,0xC3,0xEF,0x92,0xE2,0x3A,0x65,0xB7,0xA0,0x09,0xAA,0x1B,0x97,0x54,0x82,0x2E,0x28,0x77,0x5C,0x52,0x09,0x1A,0xA3,0xB8,0x76,0x49,0x25,0x68,0x8C,0x73,0xDB,0x24,0x95,0xA0,0x32,0xA9,0x6B,0xA7,0xD9,0x82,0x26,0xA9,0x76,0x42,0xD6,0x08,0xBA,0xE1,0xE8,0x0E,0x5A,0x2B,0xEA,0x9E,0x3D,0x27,0x18,0xAD,0xA8,0x07,0xF1,0x98,0x90,0x35,0xA2,0x96,0x44,0xA3,0x5D,0x66,0x8B,0x6B,0x12,0xCD,0x32,0x85,0x25,0xC9,0x81,0x2D,0xC3,0x64,0x85,0x34,0x58,0x89,0x94,0x52,0x1C,0x52,0x2F,0x35,0xDA,0xC7,0x51,0x48,0x23,0x97,0xCC,0x2C,0x97,0x2E,0xF3,0x5C,0xF3,0xA2,0x14,0xBA,0x2C,0x48,0xCE,0xCA,0x76,0xE8,0x32,0x2F,0x34,0xB2,0xDB,0x85,0xC9,0x83,0x90,0xA8,0x2C,0x57,0x26,0x8F,0x9C,0xBD,0xA2,0x53,0xD9,0xC2,0x54,0x59,0x28,0x99,0x4B,0x2C,0x5D,0xFF,0x3F}; -uint8_t spP_M_[] PROGMEM = {0x0E,0x98,0x41,0x54,0x00,0x43,0xA0,0x05,0xAB,0x42,0x8E,0x1D,0xA3,0x15,0xEC,0x4E,0x58,0xF7,0x92,0x66,0x70,0x1B,0x66,0xDB,0x73,0x99,0xC1,0xEB,0x98,0xED,0xD6,0x25,0x25,0x6F,0x70,0x92,0xDD,0x64,0xD8,0xFC,0x61,0xD0,0x66,0x83,0xD6,0x0A,0x86,0x23,0xAB,0x69,0xDA,0x2B,0x18,0x9E,0x3D,0x37,0x69,0x9D,0xA8,0x07,0x71,0x9F,0xA0,0xBD,0xA2,0x16,0xD5,0x7C,0x54,0xF6,0x88,0x6B,0x54,0x8B,0x34,0x49,0x2D,0x29,0x49,0x3C,0x34,0x64,0xA5,0x24,0x1B,0x36,0xD7,0x72,0x13,0x92,0xA4,0xC4,0x2D,0xC3,0xB3,0x4B,0xA3,0x62,0x0F,0x2B,0x37,0x6E,0x8B,0x5A,0xD4,0x3D,0xDD,0x9A,0x2D,0x50,0x93,0xF6,0x4C,0xAA,0xB6,0xC4,0x85,0x3B,0xB2,0xB1,0xD8,0x93,0x20,0x4D,0x8F,0x24,0xFF,0x0F}; -uint8_t spOH[] PROGMEM = {0xC6,0xC9,0x71,0x5A,0xA2,0x92,0x14,0x2F,0x6E,0x97,0x9C,0x46,0x9D,0xDC,0xB0,0x4D,0x62,0x1B,0x55,0x70,0xDD,0x55,0xBE,0x0E,0x36,0xC1,0x33,0x37,0xA9,0xA7,0x51,0x1B,0xCF,0x3C,0xA5,0x9E,0x44,0xAC,0x3C,0x7D,0x98,0x7B,0x52,0x96,0x72,0x65,0x4B,0xF6,0x1A,0xD9,0xCA,0xF5,0x91,0x2D,0xA2,0x2A,0x4B,0xF7,0xFF,0x01}; -uint8_t spOCLOCK[] PROGMEM = {0x21,0x4E,0x3D,0xB8,0x2B,0x19,0xBB,0x24,0x0E,0xE5,0xEC,0x60,0xE4,0xF2,0x90,0x13,0xD4,0x2A,0x11,0x80,0x00,0x42,0x69,0x26,0x40,0xD0,0x2B,0x04,0x68,0xE0,0x4D,0x00,0x3A,0x35,0x35,0x33,0xB6,0x51,0xD9,0x64,0x34,0x82,0xB4,0x9A,0x63,0x92,0x55,0x89,0x52,0x5B,0xCA,0x2E,0x34,0x25,0x4E,0x63,0x28,0x3A,0x50,0x95,0x26,0x8D,0xE6,0xAA,0x64,0x58,0xEA,0x92,0xCE,0xC2,0x46,0x15,0x9B,0x86,0xCD,0x2A,0x2E,0x37,0x00,0x00,0x00,0x0C,0xC8,0xDD,0x05,0x01,0xB9,0x33,0x21,0xA0,0x74,0xD7,0xFF,0x07}; -uint8_t spONE[] PROGMEM = {0xCC,0x67,0x75,0x42,0x59,0x5D,0x3A,0x4F,0x9D,0x36,0x63,0xB7,0x59,0xDC,0x30,0x5B,0x5C,0x23,0x61,0xF3,0xE2,0x1C,0xF1,0xF0,0x98,0xC3,0x4B,0x7D,0x39,0xCA,0x1D,0x2C,0x2F,0xB7,0x15,0xEF,0x70,0x79,0xBC,0xD2,0x46,0x7C,0x52,0xE5,0xF1,0x4A,0x6A,0xB3,0x71,0x47,0xC3,0x2D,0x39,0x34,0x4B,0x23,0x35,0xB7,0x7A,0x55,0x33,0x8F,0x59,0xDC,0xA2,0x44,0xB5,0xBC,0x66,0x72,0x8B,0x64,0xF5,0xF6,0x98,0xC1,0x4D,0x42,0xD4,0x27,0x62,0x38,0x2F,0x4A,0xB6,0x9C,0x88,0x68,0xBC,0xA6,0x95,0xF8,0x5C,0xA1,0x09,0x86,0x77,0x91,0x11,0x5B,0xFF,0x0F}; -uint8_t spTWO[] PROGMEM = {0x0E,0x38,0x6E,0x25,0x00,0xA3,0x0D,0x3A,0xA0,0x37,0xC5,0xA0,0x05,0x9E,0x56,0x35,0x86,0xAA,0x5E,0x8C,0xA4,0x82,0xB2,0xD7,0x74,0x31,0x22,0x69,0xAD,0x1C,0xD3,0xC1,0xD0,0xFA,0x28,0x2B,0x2D,0x47,0xC3,0x1B,0xC2,0xC4,0xAE,0xC6,0xCD,0x9C,0x48,0x53,0x9A,0xFF,0x0F}; -uint8_t spTHREE[] PROGMEM = {0x02,0xD8,0x2E,0x9C,0x01,0xDB,0xA6,0x33,0x60,0xFB,0x30,0x01,0xEC,0x20,0x12,0x8C,0xE4,0xD8,0xCA,0x32,0x96,0x73,0x63,0x41,0x39,0x89,0x98,0xC1,0x4D,0x0D,0xED,0xB0,0x2A,0x05,0x37,0x0F,0xB4,0xA5,0xAE,0x5C,0xDC,0x36,0xD0,0x83,0x2F,0x4A,0x71,0x7B,0x03,0xF7,0x38,0x59,0xCD,0xED,0x1E,0xB4,0x6B,0x14,0x35,0xB7,0x6B,0x94,0x99,0x91,0xD5,0xDC,0x26,0x48,0x77,0x4B,0x66,0x71,0x1B,0x21,0xDB,0x2D,0x8A,0xC9,0x6D,0x88,0xFC,0x26,0x28,0x3A,0xB7,0x21,0xF4,0x1F,0xA3,0x65,0xBC,0x02,0x38,0xBB,0x3D,0x8E,0xF0,0x2B,0xE2,0x08,0xB7,0x34,0xFF,0x0F}; -uint8_t spFOUR[] PROGMEM = {0x0C,0x18,0xB6,0x9A,0x01,0xC3,0x75,0x09,0x60,0xD8,0x0E,0x09,0x30,0xA0,0x9B,0xB6,0xA0,0xBB,0xB0,0xAA,0x16,0x4E,0x82,0xEB,0xEA,0xA9,0xFA,0x59,0x49,0x9E,0x59,0x23,0x9A,0x27,0x3B,0x78,0x66,0xAE,0x4A,0x9C,0x9C,0xE0,0x99,0xD3,0x2A,0xBD,0x72,0x92,0xEF,0xE6,0x88,0xE4,0x45,0x4D,0x7E,0x98,0x2D,0x62,0x67,0x37,0xF9,0xA1,0x37,0xA7,0x6C,0x94,0xE4,0xC7,0x1E,0xDC,0x3C,0xA5,0x83,0x1F,0x8B,0xEB,0x52,0x0E,0x0E,0x7E,0x2E,0x4E,0xC7,0x31,0xD2,0x79,0xA5,0x3A,0x0D,0xD9,0xC4,0xFF,0x07}; -uint8_t spFIVE[] PROGMEM = {0x02,0xE8,0x3E,0x8C,0x01,0xDD,0x65,0x08,0x60,0x98,0x4C,0x06,0x34,0x93,0xCE,0x80,0xE6,0xDA,0x9A,0x14,0x6B,0xAA,0x47,0xD1,0x5E,0x56,0xAA,0x6D,0x56,0xCD,0x78,0xD9,0xA9,0x1C,0x67,0x05,0x83,0xE1,0xA4,0xBA,0x38,0xEE,0x16,0x86,0x9B,0xFA,0x60,0x87,0x5B,0x18,0x6E,0xEE,0x8B,0x1D,0x6E,0x61,0xB9,0x69,0x36,0x65,0xBA,0x8D,0xE5,0xE5,0x3E,0x1C,0xE9,0x0E,0x96,0x9B,0x5B,0xAB,0x95,0x2B,0x58,0x6E,0xCE,0xE5,0x3A,0x6A,0xF3,0xB8,0x35,0x84,0x7B,0x05,0xA3,0xE3,0x36,0xEF,0x92,0x19,0xB4,0x86,0xDB,0xB4,0x69,0xB4,0xD1,0x2A,0x4E,0x65,0x9A,0x99,0xCE,0x28,0xD9,0x85,0x71,0x4C,0x18,0x6D,0x67,0x47,0xC6,0x5E,0x53,0x4A,0x9C,0xB5,0xE2,0x85,0x45,0x26,0xFE,0x7F}; -uint8_t spSIX[] PROGMEM = {0x0E,0xD8,0xAE,0xDD,0x03,0x0E,0x38,0xA6,0xD2,0x01,0xD3,0xB4,0x2C,0xAD,0x6A,0x35,0x9D,0xB1,0x7D,0xDC,0xEE,0xC4,0x65,0xD7,0xF1,0x72,0x47,0x24,0xB3,0x19,0xD9,0xD9,0x05,0x70,0x40,0x49,0xEA,0x02,0x98,0xBE,0x42,0x01,0xDF,0xA4,0x69,0x40,0x00,0xDF,0x95,0xFC,0x3F}; -uint8_t spSEVEN[] PROGMEM = {0x02,0xB8,0x3A,0x8C,0x01,0xDF,0xA4,0x73,0x40,0x01,0x47,0xB9,0x2F,0x33,0x3B,0x73,0x5F,0x53,0x7C,0xEC,0x9A,0xC5,0x63,0xD5,0xD1,0x75,0xAE,0x5B,0xFC,0x64,0x5C,0x35,0x87,0x91,0xF1,0x83,0x36,0xB5,0x68,0x55,0xC5,0x6F,0xDA,0x45,0x2D,0x1C,0x2D,0xB7,0x38,0x37,0x9F,0x60,0x3C,0xBC,0x9A,0x85,0xA3,0x25,0x66,0xF7,0x8A,0x57,0x1C,0xA9,0x67,0x56,0xCA,0x5E,0xF0,0xB2,0x16,0xB2,0xF1,0x89,0xCE,0x8B,0x92,0x25,0xC7,0x2B,0x33,0xCF,0x48,0xB1,0x99,0xB4,0xF3,0xFF}; -uint8_t spEIGHT[] PROGMEM = {0xC3,0x6C,0x86,0xB3,0x27,0x6D,0x0F,0xA7,0x48,0x99,0x4E,0x55,0x3C,0xBC,0x22,0x65,0x36,0x4D,0xD1,0xF0,0x32,0xD3,0xBE,0x34,0xDA,0xC3,0xEB,0x82,0xE2,0xDA,0x65,0x35,0xAF,0x31,0xF2,0x6B,0x97,0x95,0xBC,0x86,0xD8,0x6F,0x82,0xA6,0x73,0x0B,0xC6,0x9E,0x72,0x99,0xCC,0xCB,0x02,0xAD,0x3C,0x9A,0x10,0x60,0xAB,0x62,0x05,0x2C,0x37,0x84,0x00,0xA9,0x73,0x00,0x00,0xFE,0x1F}; -uint8_t spNINE[] PROGMEM = {0xCC,0xA1,0x26,0xBB,0x83,0x93,0x18,0xCF,0x4A,0xAD,0x2E,0x31,0xED,0x3C,0xA7,0x24,0x26,0xC3,0x54,0xF1,0x92,0x64,0x8B,0x8A,0x98,0xCB,0x2B,0x2E,0x34,0x53,0x2D,0x0E,0x2F,0x57,0xB3,0x0C,0x0D,0x3C,0xBC,0x3C,0x4C,0x4B,0xCA,0xF4,0xF0,0x72,0x0F,0x6E,0x49,0x53,0xCD,0xCB,0x53,0x2D,0x35,0x4D,0x0F,0x2F,0x0F,0xD7,0x0C,0x0D,0x3D,0xBC,0xDC,0x4D,0xD3,0xDD,0xC2,0xF0,0x72,0x52,0x4F,0x57,0x9B,0xC3,0xAB,0x89,0xBD,0x42,0x2D,0x0F,0xAF,0x5A,0xD1,0x71,0x91,0x55,0xBC,0x2C,0xC5,0x3B,0xD8,0x65,0xF2,0x82,0x94,0x18,0x4E,0x3B,0xC1,0x73,0x42,0x32,0x33,0x15,0x45,0x4F,0x79,0x52,0x6A,0x55,0xA6,0xA3,0xFF,0x07}; -uint8_t spTEN[] PROGMEM = {0x0E,0xD8,0xB1,0xDD,0x01,0x3D,0xA8,0x24,0x7B,0x04,0x27,0x76,0x77,0xDC,0xEC,0xC2,0xC5,0x23,0x84,0xCD,0x72,0x9A,0x51,0xF7,0x62,0x45,0xC7,0xEB,0x4E,0x35,0x4A,0x14,0x2D,0xBF,0x45,0xB6,0x0A,0x75,0xB8,0xFC,0x16,0xD9,0x2A,0xD9,0xD6,0x0A,0x5A,0x10,0xCD,0xA2,0x48,0x23,0xA8,0x81,0x35,0x4B,0x2C,0xA7,0x20,0x69,0x0A,0xAF,0xB6,0x15,0x82,0xA4,0x29,0x3C,0xC7,0x52,0x08,0xA2,0x22,0xCF,0x68,0x4B,0x2E,0xF0,0x8A,0xBD,0xA3,0x2C,0xAB,0x40,0x1B,0xCE,0xAA,0xB2,0x6C,0x82,0x40,0x4D,0x7D,0xC2,0x89,0x88,0x8A,0x61,0xCC,0x74,0xD5,0xFF,0x0F}; -uint8_t spELEVEN[] PROGMEM = {0xC3,0xCD,0x76,0x5C,0xAE,0x14,0x0F,0x37,0x9B,0x71,0xDE,0x92,0x55,0xBC,0x2C,0x27,0x70,0xD3,0x76,0xF0,0x83,0x5E,0xA3,0x5E,0x5A,0xC1,0xF7,0x61,0x58,0xA7,0x19,0x35,0x3F,0x99,0x31,0xDE,0x52,0x74,0xFC,0xA2,0x26,0x64,0x4B,0xD1,0xF1,0xAB,0xAE,0xD0,0x2D,0xC5,0xC7,0x2F,0x36,0xDD,0x27,0x15,0x0F,0x3F,0xD9,0x08,0x9F,0x62,0xE4,0xC2,0x2C,0xD4,0xD8,0xD3,0x89,0x0B,0x1B,0x57,0x11,0x0B,0x3B,0xC5,0xCF,0xD6,0xCC,0xC6,0x64,0x35,0xAF,0x18,0x73,0x1F,0xA1,0x5D,0xBC,0x62,0x45,0xB3,0x45,0x51,0xF0,0xA2,0x62,0xAB,0x4A,0x5B,0xC9,0x4B,0x8A,0x2D,0xB3,0x6C,0x06,0x2F,0x29,0xB2,0xAC,0x8A,0x18,0xBC,0x28,0xD9,0xAA,0xD2,0x92,0xF1,0xBC,0xE0,0x98,0x8C,0x48,0xCC,0x17,0x52,0xA3,0x27,0x6D,0x93,0xD0,0x4B,0x8E,0x0E,0x77,0x02,0x00,0xFF,0x0F}; -uint8_t spTWELVE[] PROGMEM = {0x06,0x28,0x46,0xD3,0x01,0x25,0x06,0x13,0x20,0xBA,0x70,0x70,0xB6,0x79,0xCA,0x36,0xAE,0x28,0x38,0xE1,0x29,0xC5,0x35,0xA3,0xE6,0xC4,0x16,0x6A,0x53,0x8C,0x97,0x9B,0x72,0x86,0x4F,0x28,0x1A,0x6E,0x0A,0x59,0x36,0xAE,0x68,0xF8,0x29,0x67,0xFA,0x06,0xA3,0x16,0xC4,0x96,0xE6,0x53,0xAC,0x5A,0x9C,0x56,0x72,0x77,0x31,0x4E,0x49,0x5C,0x8D,0x5B,0x29,0x3B,0x24,0x61,0x1E,0x6C,0x9B,0x6C,0x97,0xF8,0xA7,0x34,0x19,0x92,0x4C,0x62,0x9E,0x72,0x65,0x58,0x12,0xB1,0x7E,0x09,0xD5,0x2E,0x53,0xC5,0xBA,0x36,0x6B,0xB9,0x2D,0x17,0x05,0xEE,0x9A,0x6E,0x8E,0x05,0x50,0x6C,0x19,0x07,0x18,0x50,0xBD,0x3B,0x01,0x92,0x08,0x41,0x40,0x10,0xA6,0xFF,0x0F}; -uint8_t spTHIRTEEN[] PROGMEM = {0x08,0xE8,0x2C,0x15,0x01,0x43,0x07,0x13,0xE0,0x98,0xB4,0xA6,0x35,0xA9,0x1E,0xDE,0x56,0x8E,0x53,0x9C,0x7A,0xE7,0xCA,0x5E,0x76,0x8D,0x94,0xE5,0x2B,0xAB,0xD9,0xB5,0x62,0xA4,0x9C,0xE4,0xE6,0xB4,0x41,0x1E,0x7C,0xB6,0x93,0xD7,0x16,0x99,0x5A,0xCD,0x61,0x76,0x55,0xC2,0x91,0x61,0x1B,0xC0,0x01,0x5D,0x85,0x05,0xE0,0x68,0x51,0x07,0x1C,0xA9,0x64,0x80,0x1D,0x4C,0x9C,0x95,0x88,0xD4,0x04,0x3B,0x4D,0x4E,0x21,0x5C,0x93,0xA8,0x26,0xB9,0x05,0x4B,0x6E,0xA0,0xE2,0xE4,0x57,0xC2,0xB9,0xC1,0xB2,0x93,0x5F,0x09,0xD7,0x24,0xCB,0x4E,0x41,0x25,0x54,0x1D,0x62,0x3B,0x05,0x8D,0x52,0x57,0xAA,0xAD,0x10,0x24,0x26,0xE3,0xE1,0x36,0x5D,0x10,0x85,0xB4,0x97,0x85,0x72,0x41,0x14,0x52,0x5E,0x1A,0xCA,0xF9,0x91,0x6B,0x7A,0x5B,0xC4,0xE0,0x17,0x2D,0x54,0x1D,0x92,0x8C,0x1F,0x25,0x4B,0x8F,0xB2,0x16,0x41,0xA1,0x4A,0x3E,0xE6,0xFA,0xFF,0x01}; -uint8_t spFOURTEEN[] PROGMEM = {0x0C,0x58,0xAE,0x5C,0x01,0xD9,0x87,0x07,0x51,0xB7,0x25,0xB3,0x8A,0x15,0x2C,0xF7,0x1C,0x35,0x87,0x4D,0xB2,0xDD,0x53,0xCE,0x28,0x2B,0xC9,0x0E,0x97,0x2D,0xBD,0x2A,0x17,0x27,0x76,0x8E,0xD2,0x9A,0x6C,0x80,0x94,0x71,0x00,0x00,0x02,0xB0,0x58,0x58,0x00,0x9E,0x0B,0x0A,0xC0,0xB2,0xCE,0xC1,0xC8,0x98,0x7A,0x52,0x95,0x24,0x2B,0x11,0xED,0x36,0xD4,0x92,0xDC,0x4C,0xB5,0xC7,0xC8,0x53,0xF1,0x2A,0xE5,0x1A,0x17,0x55,0xC5,0xAF,0x94,0xBB,0xCD,0x1C,0x26,0xBF,0x52,0x9A,0x72,0x53,0x98,0xFC,0xC2,0x68,0xD2,0x4D,0x61,0xF0,0xA3,0x90,0xB6,0xD6,0x50,0xC1,0x8F,0x42,0xDA,0x4A,0x43,0x39,0x3F,0x48,0x2D,0x6B,0x33,0xF9,0xFF}; -uint8_t spFIFTEEN[] PROGMEM = {0x08,0xE8,0x2A,0x0D,0x01,0xDD,0xBA,0x31,0x60,0x6A,0xF7,0xA0,0xAE,0x54,0xAA,0x5A,0x76,0x97,0xD9,0x34,0x69,0xEF,0x32,0x1E,0x66,0xE1,0xE2,0xB3,0x43,0xA9,0x18,0x55,0x92,0x4E,0x37,0x2D,0x67,0x6F,0xDF,0xA2,0x5A,0xB6,0x04,0x30,0x55,0xA8,0x00,0x86,0x09,0xE7,0x00,0x01,0x16,0x17,0x05,0x70,0x40,0x57,0xE5,0x01,0xF8,0x21,0x34,0x00,0xD3,0x19,0x33,0x80,0x89,0x9A,0x62,0x34,0x4C,0xD5,0x49,0xAE,0x8B,0x53,0x09,0xF7,0x26,0xD9,0x6A,0x7E,0x23,0x5C,0x13,0x12,0xB3,0x04,0x9D,0x50,0x4F,0xB1,0xAD,0x14,0x15,0xC2,0xD3,0xA1,0xB6,0x42,0x94,0xA8,0x8C,0x87,0xDB,0x74,0xB1,0x70,0x59,0xE1,0x2E,0xC9,0xC5,0x81,0x5B,0x55,0xA4,0x4C,0x17,0x47,0xC1,0x6D,0xE3,0x81,0x53,0x9C,0x84,0x6A,0x46,0xD9,0x4C,0x51,0x31,0x42,0xD9,0x66,0xC9,0x44,0x85,0x29,0x6A,0x9B,0xAD,0xFF,0x07}; -uint8_t spSIXTEEN[] PROGMEM = {0x0A,0x58,0x5A,0x5D,0x00,0x93,0x97,0x0B,0x60,0xA9,0x48,0x05,0x0C,0x15,0xAE,0x80,0xAD,0x3D,0x14,0x30,0x7D,0xD9,0x50,0x92,0x92,0xAC,0x0D,0xC5,0xCD,0x2A,0x82,0xAA,0x3B,0x98,0x04,0xB3,0x4A,0xC8,0x9A,0x90,0x05,0x09,0x68,0x51,0xD4,0x01,0x23,0x9F,0x1A,0x60,0xA9,0x12,0x03,0xDC,0x50,0x81,0x80,0x22,0xDC,0x20,0x00,0xCB,0x06,0x3A,0x60,0x16,0xE3,0x64,0x64,0x42,0xDD,0xCD,0x6A,0x8A,0x5D,0x28,0x75,0x07,0xA9,0x2A,0x5E,0x65,0x34,0xED,0x64,0xBB,0xF8,0x85,0xF2,0x94,0x8B,0xAD,0xE4,0x37,0x4A,0x5B,0x21,0xB6,0x52,0x50,0x19,0xAD,0xA7,0xD8,0x4A,0x41,0x14,0xDA,0x5E,0x12,0x3A,0x04,0x91,0x4B,0x7B,0x69,0xA8,0x10,0x24,0x2E,0xE5,0xA3,0x81,0x52,0x90,0x94,0x5A,0x55,0x98,0x32,0x41,0x50,0xCC,0x93,0x2E,0x47,0x85,0x89,0x1B,0x5B,0x5A,0x62,0x04,0x44,0xE3,0x02,0x80,0x80,0x64,0xDD,0xFF,0x1F}; -uint8_t spSEVENTEEN[] PROGMEM = {0x02,0x98,0x3A,0x42,0x00,0x5B,0xA6,0x09,0x60,0xDB,0x52,0x06,0x1C,0x93,0x29,0x80,0xA9,0x52,0x87,0x9A,0xB5,0x99,0x4F,0xC8,0x3E,0x46,0xD6,0x5E,0x7E,0x66,0xFB,0x98,0xC5,0x5A,0xC6,0x9A,0x9C,0x63,0x15,0x6B,0x11,0x13,0x8A,0x9C,0x97,0xB9,0x9A,0x5A,0x39,0x71,0xEE,0xD2,0x29,0xC2,0xA6,0xB8,0x58,0x59,0x99,0x56,0x14,0xA3,0xE1,0x26,0x19,0x19,0xE3,0x8C,0x93,0x17,0xB4,0x46,0xB5,0x88,0x71,0x9E,0x97,0x9E,0xB1,0x2C,0xC5,0xF8,0x56,0xC4,0x58,0xA3,0x1C,0xE1,0x33,0x9D,0x13,0x41,0x8A,0x43,0x58,0xAD,0x95,0xA9,0xDB,0x36,0xC0,0xD1,0xC9,0x0E,0x58,0x4E,0x45,0x01,0x23,0xA9,0x04,0x37,0x13,0xAE,0x4D,0x65,0x52,0x82,0xCA,0xA9,0x37,0x99,0x4D,0x89,0xBA,0xC0,0xBC,0x14,0x36,0x25,0xEA,0x1C,0x73,0x52,0x1D,0x97,0xB8,0x33,0xAC,0x0E,0x75,0x9C,0xE2,0xCE,0xB0,0xDA,0xC3,0x51,0x4A,0x1A,0xA5,0xCA,0x70,0x5B,0x21,0xCE,0x4C,0x26,0xD2,0x6C,0xBA,0x38,0x71,0x2E,0x1F,0x2D,0xED,0xE2,0x24,0xB8,0xBC,0x3D,0x52,0x88,0xAB,0x50,0x8E,0xA8,0x48,0x22,0x4E,0x42,0xA0,0x26,0x55,0xFD,0x3F}; -uint8_t spEIGHTEEN[] PROGMEM = {0x2E,0x9C,0xD1,0x4D,0x54,0xEC,0x2C,0xBF,0x1B,0x8A,0x99,0x70,0x7C,0xFC,0x2E,0x29,0x6F,0x52,0xF6,0xF1,0xBA,0x20,0xBF,0x36,0xD9,0xCD,0xED,0x0C,0xF3,0x27,0x64,0x17,0x73,0x2B,0xA2,0x99,0x90,0x65,0xEC,0xED,0x40,0x73,0x32,0x12,0xB1,0xAF,0x30,0x35,0x0B,0xC7,0x00,0xE0,0x80,0xAE,0xDD,0x1C,0x70,0x43,0xAA,0x03,0x86,0x51,0x36,0xC0,0x30,0x64,0xCE,0x4C,0x98,0xFB,0x5C,0x65,0x07,0xAF,0x10,0xEA,0x0B,0x66,0x1B,0xFC,0x46,0xA8,0x3E,0x09,0x4D,0x08,0x2A,0xA6,0x3E,0x67,0x36,0x21,0x2A,0x98,0x67,0x9D,0x15,0xA7,0xA8,0x60,0xEE,0xB6,0x94,0x99,0xA2,0x4A,0x78,0x22,0xC2,0xA6,0x8B,0x8C,0x8E,0xCC,0x4C,0x8A,0x2E,0x8A,0x4C,0xD3,0x57,0x03,0x87,0x28,0x71,0x09,0x1F,0x2B,0xE4,0xA2,0xC4,0xC5,0x6D,0xAD,0x54,0x88,0xB2,0x63,0xC9,0xF2,0x50,0x2E,0x8A,0x4A,0x38,0x4A,0xEC,0x88,0x28,0x08,0xE3,0x28,0x49,0xF3,0xFF}; -uint8_t spNINETEEN[] PROGMEM = {0xC2,0xEA,0x8A,0x95,0x2B,0x6A,0x05,0x3F,0x71,0x71,0x5F,0x0D,0x12,0xFC,0x28,0x25,0x62,0x35,0xF0,0xF0,0xB3,0x48,0x1E,0x0F,0xC9,0xCB,0x2F,0x45,0x7C,0x2C,0x25,0x1F,0xBF,0x14,0xB3,0x2C,0xB5,0x75,0xFC,0x5A,0x5C,0xA3,0x5D,0xE1,0xF1,0x7A,0x76,0xB3,0x4E,0x45,0xC7,0xED,0x96,0x23,0x3B,0x18,0x37,0x7B,0x18,0xCC,0x09,0x51,0x13,0x4C,0xAB,0x6C,0x4C,0x4B,0x96,0xD2,0x49,0xAA,0x36,0x0B,0xC5,0xC2,0x20,0x26,0x27,0x35,0x63,0x09,0x3D,0x30,0x8B,0xF0,0x48,0x5C,0xCA,0x61,0xDD,0xCB,0xCD,0x91,0x03,0x8E,0x4B,0x76,0xC0,0xCC,0x4D,0x06,0x98,0x31,0x31,0x98,0x99,0x70,0x6D,0x2A,0xA3,0xE4,0x16,0xCA,0xBD,0xCE,0x5C,0x92,0x57,0x28,0xCF,0x09,0x69,0x2E,0x7E,0xA5,0x3C,0x63,0xA2,0x30,0x05,0x95,0xD2,0x74,0x98,0xCD,0x14,0x54,0xCA,0x53,0xA9,0x96,0x52,0x50,0x28,0x6F,0xBA,0xCB,0x0C,0x41,0x50,0xDE,0x65,0x2E,0xD3,0x05,0x89,0x4B,0x7B,0x6B,0x20,0x17,0x44,0xAE,0xED,0x23,0x81,0x52,0x90,0x85,0x73,0x57,0xD0,0x72,0x41,0xB1,0x02,0xDE,0x2E,0xDB,0x04,0x89,0x05,0x79,0xBB,0x62,0xE5,0x76,0x11,0xCA,0x61,0x0E,0xFF,0x1F}; -uint8_t spTWENTY[] PROGMEM = {0x01,0x98,0xD1,0xC2,0x00,0xCD,0xA4,0x32,0x20,0x79,0x13,0x04,0x28,0xE7,0x92,0xDC,0x70,0xCC,0x5D,0xDB,0x76,0xF3,0xD2,0x32,0x0B,0x0B,0x5B,0xC3,0x2B,0xCD,0xD4,0xDD,0x23,0x35,0xAF,0x44,0xE1,0xF0,0xB0,0x6D,0x3C,0xA9,0xAD,0x3D,0x35,0x0E,0xF1,0x0C,0x8B,0x28,0xF7,0x34,0x01,0x68,0x22,0xCD,0x00,0xC7,0xA4,0x04,0xBB,0x32,0xD6,0xAC,0x56,0x9C,0xDC,0xCA,0x28,0x66,0x53,0x51,0x70,0x2B,0xA5,0xBC,0x0D,0x9A,0xC1,0xEB,0x14,0x73,0x37,0x29,0x19,0xAF,0x33,0x8C,0x3B,0xA7,0x24,0xBC,0x42,0xB0,0xB7,0x59,0x09,0x09,0x3C,0x96,0xE9,0xF4,0x58,0xFF,0x0F}; -uint8_t spTHIRTY[] PROGMEM = {0x08,0x98,0xD6,0x15,0x01,0x43,0xBB,0x0A,0x20,0x1B,0x8B,0xE5,0x16,0xA3,0x1E,0xB6,0xB6,0x96,0x97,0x3C,0x57,0xD4,0x2A,0x5E,0x7E,0x4E,0xD8,0xE1,0x6B,0x7B,0xF8,0x39,0x63,0x0D,0x9F,0x95,0xE1,0xE7,0x4C,0x76,0xBC,0x91,0x5B,0x90,0x13,0xC6,0x68,0x57,0x4E,0x41,0x8B,0x10,0x5E,0x1D,0xA9,0x44,0xD3,0xBA,0x47,0xB8,0xDD,0xE4,0x35,0x86,0x11,0x93,0x94,0x92,0x5F,0x29,0xC7,0x4C,0x30,0x0C,0x41,0xC5,0x1C,0x3B,0x2E,0xD3,0x05,0x15,0x53,0x6C,0x07,0x4D,0x15,0x14,0x8C,0xB5,0xC9,0x6A,0x44,0x90,0x10,0x4E,0x9A,0xB6,0x21,0x81,0x23,0x3A,0x91,0x91,0xE8,0xFF,0x01}; -uint8_t spFOURTY[] PROGMEM = {0x04,0x18,0xB6,0x4C,0x00,0xC3,0x56,0x30,0xA0,0xE8,0xF4,0xA0,0x98,0x99,0x62,0x91,0xAE,0x83,0x6B,0x77,0x89,0x78,0x3B,0x09,0xAE,0xBD,0xA6,0x1E,0x63,0x3B,0x79,0x7E,0x71,0x5A,0x8F,0x95,0xE6,0xA5,0x4A,0x69,0xB9,0x4E,0x8A,0x5F,0x12,0x56,0xE4,0x58,0x69,0xE1,0x36,0xA1,0x69,0x2E,0x2B,0xF9,0x95,0x93,0x55,0x17,0xED,0xE4,0x37,0xC6,0xBA,0x93,0xB2,0x92,0xDF,0x19,0xD9,0x6E,0xC8,0x0A,0xFE,0x60,0xE8,0x37,0x21,0xC9,0xF9,0x8D,0x61,0x5F,0x32,0x13,0xE7,0x17,0x4C,0xD3,0xC6,0xB1,0x94,0x97,0x10,0x8F,0x8B,0xAD,0x11,0x7E,0xA1,0x9A,0x26,0x92,0xF6,0xFF,0x01}; -uint8_t spFIFTY[] PROGMEM = {0x08,0xE8,0x2E,0x84,0x00,0x23,0x84,0x13,0x60,0x38,0x95,0xA5,0x0F,0xCF,0xE2,0x79,0x8A,0x8F,0x37,0x02,0xB3,0xD5,0x2A,0x6E,0x5E,0x93,0x94,0x79,0x45,0xD9,0x05,0x5D,0x0A,0xB9,0x97,0x63,0x02,0x74,0xA7,0x82,0x80,0xEE,0xC3,0x10,0xD0,0x7D,0x28,0x03,0x6E,0x14,0x06,0x70,0xE6,0x0A,0xC9,0x9A,0x4E,0x37,0xD9,0x95,0x51,0xCE,0xBA,0xA2,0x14,0x0C,0x81,0x36,0x1B,0xB2,0x5C,0x30,0x38,0xFA,0x9C,0xC9,0x32,0x41,0xA7,0x18,0x3B,0xA2,0x48,0x04,0x05,0x51,0x4F,0x91,0x6D,0x12,0x04,0x20,0x9B,0x61,0x89,0xFF,0x1F}; -uint8_t spGOOD[] PROGMEM = {0x0A,0x28,0xCD,0x34,0x20,0xD9,0x1A,0x45,0x74,0xE4,0x66,0x24,0xAD,0xBA,0xB1,0x8C,0x9B,0x91,0xA5,0x64,0xE6,0x98,0x21,0x16,0x0B,0x96,0x9B,0x4C,0xE5,0xFF,0x01}; -uint8_t spMORNING[] PROGMEM = {0xCE,0x08,0x52,0x2A,0x35,0x5D,0x39,0x53,0x29,0x5B,0xB7,0x0A,0x15,0x0C,0xEE,0x2A,0x42,0x56,0x66,0xD2,0x55,0x2E,0x37,0x2F,0xD9,0x45,0xB3,0xD3,0xC5,0xCA,0x6D,0x27,0xD5,0xEE,0x50,0xF5,0x50,0x94,0x14,0x77,0x2D,0xD8,0x5D,0x49,0x92,0xFD,0xB1,0x64,0x2F,0xA9,0x49,0x0C,0x93,0x4B,0xAD,0x19,0x17,0x3E,0x66,0x1E,0xF1,0xA2,0x5B,0x84,0xE2,0x29,0x8F,0x8B,0x72,0x10,0xB5,0xB1,0x2E,0x4B,0xD4,0x45,0x89,0x4A,0xEC,0x5C,0x95,0x14,0x2B,0x8A,0x9C,0x34,0x52,0x5D,0xBC,0xCC,0xB5,0x3B,0x49,0x69,0x89,0x87,0xC1,0x98,0x56,0x3A,0x21,0x2B,0x82,0x67,0xCC,0x5C,0x85,0xB5,0x4A,0x8A,0xF6,0x64,0xA9,0x96,0xC4,0x69,0x3C,0x52,0x81,0x58,0x1C,0x97,0xF6,0x0E,0x1B,0xCC,0x0D,0x42,0x32,0xAA,0x65,0x12,0x67,0xD4,0x6A,0x61,0x52,0xFC,0xFF}; -uint8_t spAFTERNOON[] PROGMEM = {0xC7,0xCE,0xCE,0x3A,0xCB,0x58,0x1F,0x3B,0x07,0x9D,0x28,0x71,0xB4,0xAC,0x9C,0x74,0x5A,0x42,0x55,0x33,0xB2,0x93,0x0A,0x09,0xD4,0xC5,0x9A,0xD6,0x44,0x45,0xE3,0x38,0x60,0x9A,0x32,0x05,0xF4,0x18,0x01,0x09,0xD8,0xA9,0xC2,0x00,0x5E,0xCA,0x24,0xD5,0x5B,0x9D,0x4A,0x95,0xEA,0x34,0xEE,0x63,0x92,0x5C,0x4D,0xD0,0xA4,0xEE,0x58,0x0C,0xB9,0x4D,0xCD,0x42,0xA2,0x3A,0x24,0x37,0x25,0x8A,0xA8,0x8E,0xA0,0x53,0xE4,0x28,0x23,0x26,0x13,0x72,0x91,0xA2,0x76,0xBB,0x72,0x38,0x45,0x0A,0x46,0x63,0xCA,0x69,0x27,0x39,0x58,0xB1,0x8D,0x60,0x1C,0x34,0x1B,0x34,0xC3,0x55,0x8E,0x73,0x45,0x2D,0x4F,0x4A,0x3A,0x26,0x10,0xA1,0xCA,0x2D,0xE9,0x98,0x24,0x0A,0x1E,0x6D,0x97,0x29,0xD2,0xCC,0x71,0xA2,0xDC,0x86,0xC8,0x12,0xA7,0x8E,0x08,0x85,0x22,0x8D,0x9C,0x43,0xA7,0x12,0xB2,0x2E,0x50,0x09,0xEF,0x51,0xC5,0xBA,0x28,0x58,0xAD,0xDB,0xE1,0xFF,0x03}; -uint8_t spEVENING[] PROGMEM = {0xCD,0x6D,0x98,0x73,0x47,0x65,0x0D,0x6D,0x10,0xB2,0x5D,0x93,0x35,0x94,0xC1,0xD0,0x76,0x4D,0x66,0x93,0xA7,0x04,0xBD,0x71,0xD9,0x45,0xAE,0x92,0xD5,0xAC,0x53,0x07,0x6D,0xA5,0x76,0x63,0x51,0x92,0xD4,0xA1,0x83,0xD4,0xCB,0xB2,0x51,0x88,0xCD,0xF5,0x50,0x45,0xCE,0xA2,0x2E,0x27,0x28,0x54,0x15,0x37,0x0A,0xCF,0x75,0x61,0x5D,0xA2,0xC4,0xB5,0xC7,0x44,0x55,0x8A,0x0B,0xA3,0x6E,0x17,0x95,0x21,0xA9,0x0C,0x37,0xCD,0x15,0xBA,0xD4,0x2B,0x6F,0xB3,0x54,0xE4,0xD2,0xC8,0x64,0xBC,0x4C,0x91,0x49,0x12,0xE7,0xB2,0xB1,0xD0,0x22,0x0D,0x9C,0xDD,0xAB,0x62,0xA9,0x38,0x53,0x11,0xA9,0x74,0x2C,0xD2,0xCA,0x59,0x34,0xA3,0xE5,0xFF,0x03}; -uint8_t spPAUSE1[] PROGMEM = {0x00,0x00,0x00,0x00,0xFF,0x0F}; - -void sayTime(int hour, int minutes, AudioGeneratorTalkie *talkie) -{ +uint8_t spTHE[] PROGMEM = {0x08, 0xE8, 0x3E, 0x55, 0x01, 0xC3, 0x86, 0x27, 0xAF, 0x72, 0x0D, 0x4D, 0x97, 0xD5, 0xBC, 0x64, 0x3C, 0xF2, 0x5C, 0x51, 0xF1, 0x93, 0x36, 0x8F, 0x4F, 0x59, 0x2A, 0x42, 0x7A, 0x32, 0xC3, 0x64, 0xFF, 0x3F}; +uint8_t spTIME[] PROGMEM = {0x0E, 0x28, 0xAC, 0x2D, 0x01, 0x5D, 0xB6, 0x0D, 0x33, 0xF3, 0x54, 0xB3, 0x60, 0xBA, 0x8C, 0x54, 0x5C, 0xCD, 0x2D, 0xD4, 0x32, 0x73, 0x0F, 0x8E, 0x34, 0x33, 0xCB, 0x4A, 0x25, 0xD4, 0x25, 0x83, 0x2C, 0x2B, 0xD5, 0x50, 0x97, 0x08, 0x32, 0xEC, 0xD4, 0xDC, 0x4C, 0x33, 0xC8, 0x70, 0x73, 0x0F, 0x33, 0xCD, 0x20, 0xC3, 0xCB, 0x43, 0xDD, 0x3C, 0xCD, 0x8C, 0x20, 0x77, 0x89, 0xF4, 0x94, 0xB2, 0xE2, 0xE2, 0x35, 0x22, 0x5D, 0xD6, 0x4A, 0x8A, 0x96, 0xCC, 0x36, 0x25, 0x2D, 0xC9, 0x9A, 0x7B, 0xC2, 0x18, 0x87, 0x24, 0x4B, 0x1C, 0xC9, 0x50, 0x19, 0x92, 0x2C, 0x71, 0x34, 0x4B, 0x45, 0x8A, 0x8B, 0xC4, 0x96, 0xB6, 0x5A, 0x29, 0x2A, 0x92, 0x5A, 0xCA, 0x53, 0x96, 0x20, 0x05, 0x09, 0xF5, 0x92, 0x5D, 0xBC, 0xE8, 0x58, 0x4A, 0xDD, 0xAE, 0x73, 0xBD, 0x65, 0x4B, 0x8D, 0x78, 0xCA, 0x2B, 0x4E, 0xD8, 0xD9, 0xED, 0x22, 0x20, 0x06, 0x75, 0x00, 0x00, 0x80, 0xFF, 0x07}; +uint8_t spIS[] PROGMEM = {0x21, 0x18, 0x96, 0x38, 0xB7, 0x14, 0x8D, 0x60, 0x3A, 0xA6, 0xE8, 0x51, 0xB4, 0xDC, 0x2E, 0x48, 0x7B, 0x5A, 0xF1, 0x70, 0x1B, 0xA3, 0xEC, 0x09, 0xC6, 0xCB, 0xEB, 0x92, 0x3D, 0xA7, 0x69, 0x1F, 0xAF, 0x71, 0x89, 0x9C, 0xA2, 0xB3, 0xFC, 0xCA, 0x35, 0x72, 0x9A, 0xD1, 0xF0, 0xAB, 0x12, 0xB3, 0x2B, 0xC6, 0xCD, 0x4F, 0xCC, 0x32, 0x26, 0x19, 0x07, 0xDF, 0x0B, 0x8F, 0xB8, 0xA4, 0xED, 0x7C, 0xCF, 0x23, 0x62, 0x8B, 0x8E, 0xF1, 0x23, 0x0A, 0x8B, 0x6E, 0xCB, 0xCE, 0xEF, 0x54, 0x44, 0x3C, 0xDC, 0x08, 0x60, 0x0B, 0x37, 0x01, 0x1C, 0x53, 0x26, 0x80, 0x15, 0x4E, 0x14, 0xB0, 0x54, 0x2B, 0x02, 0xA4, 0x69, 0xFF, 0x7F}; +uint8_t spA_M_[] PROGMEM = {0xCD, 0xEF, 0x86, 0xAB, 0x57, 0x6D, 0x0F, 0xAF, 0x71, 0xAD, 0x49, 0x55, 0x3C, 0xFC, 0x2E, 0xC5, 0xB7, 0x5C, 0xF1, 0xF2, 0x87, 0x66, 0xDD, 0x4E, 0xC5, 0xC3, 0xEF, 0x92, 0xE2, 0x3A, 0x65, 0xB7, 0xA0, 0x09, 0xAA, 0x1B, 0x97, 0x54, 0x82, 0x2E, 0x28, 0x77, 0x5C, 0x52, 0x09, 0x1A, 0xA3, 0xB8, 0x76, 0x49, 0x25, 0x68, 0x8C, 0x73, 0xDB, 0x24, 0x95, 0xA0, 0x32, 0xA9, 0x6B, 0xA7, 0xD9, 0x82, 0x26, 0xA9, 0x76, 0x42, 0xD6, 0x08, 0xBA, 0xE1, 0xE8, 0x0E, 0x5A, 0x2B, 0xEA, 0x9E, 0x3D, 0x27, 0x18, 0xAD, 0xA8, 0x07, 0xF1, 0x98, 0x90, 0x35, 0xA2, 0x96, 0x44, 0xA3, 0x5D, 0x66, 0x8B, 0x6B, 0x12, 0xCD, 0x32, 0x85, 0x25, 0xC9, 0x81, 0x2D, 0xC3, 0x64, 0x85, 0x34, 0x58, 0x89, 0x94, 0x52, 0x1C, 0x52, 0x2F, 0x35, 0xDA, 0xC7, 0x51, 0x48, 0x23, 0x97, 0xCC, 0x2C, 0x97, 0x2E, 0xF3, 0x5C, 0xF3, 0xA2, 0x14, 0xBA, 0x2C, 0x48, 0xCE, 0xCA, 0x76, 0xE8, 0x32, 0x2F, 0x34, 0xB2, 0xDB, 0x85, 0xC9, 0x83, 0x90, 0xA8, 0x2C, 0x57, 0x26, 0x8F, 0x9C, 0xBD, 0xA2, 0x53, 0xD9, 0xC2, 0x54, 0x59, 0x28, 0x99, 0x4B, 0x2C, 0x5D, 0xFF, 0x3F}; +uint8_t spP_M_[] PROGMEM = {0x0E, 0x98, 0x41, 0x54, 0x00, 0x43, 0xA0, 0x05, 0xAB, 0x42, 0x8E, 0x1D, 0xA3, 0x15, 0xEC, 0x4E, 0x58, 0xF7, 0x92, 0x66, 0x70, 0x1B, 0x66, 0xDB, 0x73, 0x99, 0xC1, 0xEB, 0x98, 0xED, 0xD6, 0x25, 0x25, 0x6F, 0x70, 0x92, 0xDD, 0x64, 0xD8, 0xFC, 0x61, 0xD0, 0x66, 0x83, 0xD6, 0x0A, 0x86, 0x23, 0xAB, 0x69, 0xDA, 0x2B, 0x18, 0x9E, 0x3D, 0x37, 0x69, 0x9D, 0xA8, 0x07, 0x71, 0x9F, 0xA0, 0xBD, 0xA2, 0x16, 0xD5, 0x7C, 0x54, 0xF6, 0x88, 0x6B, 0x54, 0x8B, 0x34, 0x49, 0x2D, 0x29, 0x49, 0x3C, 0x34, 0x64, 0xA5, 0x24, 0x1B, 0x36, 0xD7, 0x72, 0x13, 0x92, 0xA4, 0xC4, 0x2D, 0xC3, 0xB3, 0x4B, 0xA3, 0x62, 0x0F, 0x2B, 0x37, 0x6E, 0x8B, 0x5A, 0xD4, 0x3D, 0xDD, 0x9A, 0x2D, 0x50, 0x93, 0xF6, 0x4C, 0xAA, 0xB6, 0xC4, 0x85, 0x3B, 0xB2, 0xB1, 0xD8, 0x93, 0x20, 0x4D, 0x8F, 0x24, 0xFF, 0x0F}; +uint8_t spOH[] PROGMEM = {0xC6, 0xC9, 0x71, 0x5A, 0xA2, 0x92, 0x14, 0x2F, 0x6E, 0x97, 0x9C, 0x46, 0x9D, 0xDC, 0xB0, 0x4D, 0x62, 0x1B, 0x55, 0x70, 0xDD, 0x55, 0xBE, 0x0E, 0x36, 0xC1, 0x33, 0x37, 0xA9, 0xA7, 0x51, 0x1B, 0xCF, 0x3C, 0xA5, 0x9E, 0x44, 0xAC, 0x3C, 0x7D, 0x98, 0x7B, 0x52, 0x96, 0x72, 0x65, 0x4B, 0xF6, 0x1A, 0xD9, 0xCA, 0xF5, 0x91, 0x2D, 0xA2, 0x2A, 0x4B, 0xF7, 0xFF, 0x01}; +uint8_t spOCLOCK[] PROGMEM = {0x21, 0x4E, 0x3D, 0xB8, 0x2B, 0x19, 0xBB, 0x24, 0x0E, 0xE5, 0xEC, 0x60, 0xE4, 0xF2, 0x90, 0x13, 0xD4, 0x2A, 0x11, 0x80, 0x00, 0x42, 0x69, 0x26, 0x40, 0xD0, 0x2B, 0x04, 0x68, 0xE0, 0x4D, 0x00, 0x3A, 0x35, 0x35, 0x33, 0xB6, 0x51, 0xD9, 0x64, 0x34, 0x82, 0xB4, 0x9A, 0x63, 0x92, 0x55, 0x89, 0x52, 0x5B, 0xCA, 0x2E, 0x34, 0x25, 0x4E, 0x63, 0x28, 0x3A, 0x50, 0x95, 0x26, 0x8D, 0xE6, 0xAA, 0x64, 0x58, 0xEA, 0x92, 0xCE, 0xC2, 0x46, 0x15, 0x9B, 0x86, 0xCD, 0x2A, 0x2E, 0x37, 0x00, 0x00, 0x00, 0x0C, 0xC8, 0xDD, 0x05, 0x01, 0xB9, 0x33, 0x21, 0xA0, 0x74, 0xD7, 0xFF, 0x07}; +uint8_t spONE[] PROGMEM = {0xCC, 0x67, 0x75, 0x42, 0x59, 0x5D, 0x3A, 0x4F, 0x9D, 0x36, 0x63, 0xB7, 0x59, 0xDC, 0x30, 0x5B, 0x5C, 0x23, 0x61, 0xF3, 0xE2, 0x1C, 0xF1, 0xF0, 0x98, 0xC3, 0x4B, 0x7D, 0x39, 0xCA, 0x1D, 0x2C, 0x2F, 0xB7, 0x15, 0xEF, 0x70, 0x79, 0xBC, 0xD2, 0x46, 0x7C, 0x52, 0xE5, 0xF1, 0x4A, 0x6A, 0xB3, 0x71, 0x47, 0xC3, 0x2D, 0x39, 0x34, 0x4B, 0x23, 0x35, 0xB7, 0x7A, 0x55, 0x33, 0x8F, 0x59, 0xDC, 0xA2, 0x44, 0xB5, 0xBC, 0x66, 0x72, 0x8B, 0x64, 0xF5, 0xF6, 0x98, 0xC1, 0x4D, 0x42, 0xD4, 0x27, 0x62, 0x38, 0x2F, 0x4A, 0xB6, 0x9C, 0x88, 0x68, 0xBC, 0xA6, 0x95, 0xF8, 0x5C, 0xA1, 0x09, 0x86, 0x77, 0x91, 0x11, 0x5B, 0xFF, 0x0F}; +uint8_t spTWO[] PROGMEM = {0x0E, 0x38, 0x6E, 0x25, 0x00, 0xA3, 0x0D, 0x3A, 0xA0, 0x37, 0xC5, 0xA0, 0x05, 0x9E, 0x56, 0x35, 0x86, 0xAA, 0x5E, 0x8C, 0xA4, 0x82, 0xB2, 0xD7, 0x74, 0x31, 0x22, 0x69, 0xAD, 0x1C, 0xD3, 0xC1, 0xD0, 0xFA, 0x28, 0x2B, 0x2D, 0x47, 0xC3, 0x1B, 0xC2, 0xC4, 0xAE, 0xC6, 0xCD, 0x9C, 0x48, 0x53, 0x9A, 0xFF, 0x0F}; +uint8_t spTHREE[] PROGMEM = {0x02, 0xD8, 0x2E, 0x9C, 0x01, 0xDB, 0xA6, 0x33, 0x60, 0xFB, 0x30, 0x01, 0xEC, 0x20, 0x12, 0x8C, 0xE4, 0xD8, 0xCA, 0x32, 0x96, 0x73, 0x63, 0x41, 0x39, 0x89, 0x98, 0xC1, 0x4D, 0x0D, 0xED, 0xB0, 0x2A, 0x05, 0x37, 0x0F, 0xB4, 0xA5, 0xAE, 0x5C, 0xDC, 0x36, 0xD0, 0x83, 0x2F, 0x4A, 0x71, 0x7B, 0x03, 0xF7, 0x38, 0x59, 0xCD, 0xED, 0x1E, 0xB4, 0x6B, 0x14, 0x35, 0xB7, 0x6B, 0x94, 0x99, 0x91, 0xD5, 0xDC, 0x26, 0x48, 0x77, 0x4B, 0x66, 0x71, 0x1B, 0x21, 0xDB, 0x2D, 0x8A, 0xC9, 0x6D, 0x88, 0xFC, 0x26, 0x28, 0x3A, 0xB7, 0x21, 0xF4, 0x1F, 0xA3, 0x65, 0xBC, 0x02, 0x38, 0xBB, 0x3D, 0x8E, 0xF0, 0x2B, 0xE2, 0x08, 0xB7, 0x34, 0xFF, 0x0F}; +uint8_t spFOUR[] PROGMEM = {0x0C, 0x18, 0xB6, 0x9A, 0x01, 0xC3, 0x75, 0x09, 0x60, 0xD8, 0x0E, 0x09, 0x30, 0xA0, 0x9B, 0xB6, 0xA0, 0xBB, 0xB0, 0xAA, 0x16, 0x4E, 0x82, 0xEB, 0xEA, 0xA9, 0xFA, 0x59, 0x49, 0x9E, 0x59, 0x23, 0x9A, 0x27, 0x3B, 0x78, 0x66, 0xAE, 0x4A, 0x9C, 0x9C, 0xE0, 0x99, 0xD3, 0x2A, 0xBD, 0x72, 0x92, 0xEF, 0xE6, 0x88, 0xE4, 0x45, 0x4D, 0x7E, 0x98, 0x2D, 0x62, 0x67, 0x37, 0xF9, 0xA1, 0x37, 0xA7, 0x6C, 0x94, 0xE4, 0xC7, 0x1E, 0xDC, 0x3C, 0xA5, 0x83, 0x1F, 0x8B, 0xEB, 0x52, 0x0E, 0x0E, 0x7E, 0x2E, 0x4E, 0xC7, 0x31, 0xD2, 0x79, 0xA5, 0x3A, 0x0D, 0xD9, 0xC4, 0xFF, 0x07}; +uint8_t spFIVE[] PROGMEM = {0x02, 0xE8, 0x3E, 0x8C, 0x01, 0xDD, 0x65, 0x08, 0x60, 0x98, 0x4C, 0x06, 0x34, 0x93, 0xCE, 0x80, 0xE6, 0xDA, 0x9A, 0x14, 0x6B, 0xAA, 0x47, 0xD1, 0x5E, 0x56, 0xAA, 0x6D, 0x56, 0xCD, 0x78, 0xD9, 0xA9, 0x1C, 0x67, 0x05, 0x83, 0xE1, 0xA4, 0xBA, 0x38, 0xEE, 0x16, 0x86, 0x9B, 0xFA, 0x60, 0x87, 0x5B, 0x18, 0x6E, 0xEE, 0x8B, 0x1D, 0x6E, 0x61, 0xB9, 0x69, 0x36, 0x65, 0xBA, 0x8D, 0xE5, 0xE5, 0x3E, 0x1C, 0xE9, 0x0E, 0x96, 0x9B, 0x5B, 0xAB, 0x95, 0x2B, 0x58, 0x6E, 0xCE, 0xE5, 0x3A, 0x6A, 0xF3, 0xB8, 0x35, 0x84, 0x7B, 0x05, 0xA3, 0xE3, 0x36, 0xEF, 0x92, 0x19, 0xB4, 0x86, 0xDB, 0xB4, 0x69, 0xB4, 0xD1, 0x2A, 0x4E, 0x65, 0x9A, 0x99, 0xCE, 0x28, 0xD9, 0x85, 0x71, 0x4C, 0x18, 0x6D, 0x67, 0x47, 0xC6, 0x5E, 0x53, 0x4A, 0x9C, 0xB5, 0xE2, 0x85, 0x45, 0x26, 0xFE, 0x7F}; +uint8_t spSIX[] PROGMEM = {0x0E, 0xD8, 0xAE, 0xDD, 0x03, 0x0E, 0x38, 0xA6, 0xD2, 0x01, 0xD3, 0xB4, 0x2C, 0xAD, 0x6A, 0x35, 0x9D, 0xB1, 0x7D, 0xDC, 0xEE, 0xC4, 0x65, 0xD7, 0xF1, 0x72, 0x47, 0x24, 0xB3, 0x19, 0xD9, 0xD9, 0x05, 0x70, 0x40, 0x49, 0xEA, 0x02, 0x98, 0xBE, 0x42, 0x01, 0xDF, 0xA4, 0x69, 0x40, 0x00, 0xDF, 0x95, 0xFC, 0x3F}; +uint8_t spSEVEN[] PROGMEM = {0x02, 0xB8, 0x3A, 0x8C, 0x01, 0xDF, 0xA4, 0x73, 0x40, 0x01, 0x47, 0xB9, 0x2F, 0x33, 0x3B, 0x73, 0x5F, 0x53, 0x7C, 0xEC, 0x9A, 0xC5, 0x63, 0xD5, 0xD1, 0x75, 0xAE, 0x5B, 0xFC, 0x64, 0x5C, 0x35, 0x87, 0x91, 0xF1, 0x83, 0x36, 0xB5, 0x68, 0x55, 0xC5, 0x6F, 0xDA, 0x45, 0x2D, 0x1C, 0x2D, 0xB7, 0x38, 0x37, 0x9F, 0x60, 0x3C, 0xBC, 0x9A, 0x85, 0xA3, 0x25, 0x66, 0xF7, 0x8A, 0x57, 0x1C, 0xA9, 0x67, 0x56, 0xCA, 0x5E, 0xF0, 0xB2, 0x16, 0xB2, 0xF1, 0x89, 0xCE, 0x8B, 0x92, 0x25, 0xC7, 0x2B, 0x33, 0xCF, 0x48, 0xB1, 0x99, 0xB4, 0xF3, 0xFF}; +uint8_t spEIGHT[] PROGMEM = {0xC3, 0x6C, 0x86, 0xB3, 0x27, 0x6D, 0x0F, 0xA7, 0x48, 0x99, 0x4E, 0x55, 0x3C, 0xBC, 0x22, 0x65, 0x36, 0x4D, 0xD1, 0xF0, 0x32, 0xD3, 0xBE, 0x34, 0xDA, 0xC3, 0xEB, 0x82, 0xE2, 0xDA, 0x65, 0x35, 0xAF, 0x31, 0xF2, 0x6B, 0x97, 0x95, 0xBC, 0x86, 0xD8, 0x6F, 0x82, 0xA6, 0x73, 0x0B, 0xC6, 0x9E, 0x72, 0x99, 0xCC, 0xCB, 0x02, 0xAD, 0x3C, 0x9A, 0x10, 0x60, 0xAB, 0x62, 0x05, 0x2C, 0x37, 0x84, 0x00, 0xA9, 0x73, 0x00, 0x00, 0xFE, 0x1F}; +uint8_t spNINE[] PROGMEM = {0xCC, 0xA1, 0x26, 0xBB, 0x83, 0x93, 0x18, 0xCF, 0x4A, 0xAD, 0x2E, 0x31, 0xED, 0x3C, 0xA7, 0x24, 0x26, 0xC3, 0x54, 0xF1, 0x92, 0x64, 0x8B, 0x8A, 0x98, 0xCB, 0x2B, 0x2E, 0x34, 0x53, 0x2D, 0x0E, 0x2F, 0x57, 0xB3, 0x0C, 0x0D, 0x3C, 0xBC, 0x3C, 0x4C, 0x4B, 0xCA, 0xF4, 0xF0, 0x72, 0x0F, 0x6E, 0x49, 0x53, 0xCD, 0xCB, 0x53, 0x2D, 0x35, 0x4D, 0x0F, 0x2F, 0x0F, 0xD7, 0x0C, 0x0D, 0x3D, 0xBC, 0xDC, 0x4D, 0xD3, 0xDD, 0xC2, 0xF0, 0x72, 0x52, 0x4F, 0x57, 0x9B, 0xC3, 0xAB, 0x89, 0xBD, 0x42, 0x2D, 0x0F, 0xAF, 0x5A, 0xD1, 0x71, 0x91, 0x55, 0xBC, 0x2C, 0xC5, 0x3B, 0xD8, 0x65, 0xF2, 0x82, 0x94, 0x18, 0x4E, 0x3B, 0xC1, 0x73, 0x42, 0x32, 0x33, 0x15, 0x45, 0x4F, 0x79, 0x52, 0x6A, 0x55, 0xA6, 0xA3, 0xFF, 0x07}; +uint8_t spTEN[] PROGMEM = {0x0E, 0xD8, 0xB1, 0xDD, 0x01, 0x3D, 0xA8, 0x24, 0x7B, 0x04, 0x27, 0x76, 0x77, 0xDC, 0xEC, 0xC2, 0xC5, 0x23, 0x84, 0xCD, 0x72, 0x9A, 0x51, 0xF7, 0x62, 0x45, 0xC7, 0xEB, 0x4E, 0x35, 0x4A, 0x14, 0x2D, 0xBF, 0x45, 0xB6, 0x0A, 0x75, 0xB8, 0xFC, 0x16, 0xD9, 0x2A, 0xD9, 0xD6, 0x0A, 0x5A, 0x10, 0xCD, 0xA2, 0x48, 0x23, 0xA8, 0x81, 0x35, 0x4B, 0x2C, 0xA7, 0x20, 0x69, 0x0A, 0xAF, 0xB6, 0x15, 0x82, 0xA4, 0x29, 0x3C, 0xC7, 0x52, 0x08, 0xA2, 0x22, 0xCF, 0x68, 0x4B, 0x2E, 0xF0, 0x8A, 0xBD, 0xA3, 0x2C, 0xAB, 0x40, 0x1B, 0xCE, 0xAA, 0xB2, 0x6C, 0x82, 0x40, 0x4D, 0x7D, 0xC2, 0x89, 0x88, 0x8A, 0x61, 0xCC, 0x74, 0xD5, 0xFF, 0x0F}; +uint8_t spELEVEN[] PROGMEM = {0xC3, 0xCD, 0x76, 0x5C, 0xAE, 0x14, 0x0F, 0x37, 0x9B, 0x71, 0xDE, 0x92, 0x55, 0xBC, 0x2C, 0x27, 0x70, 0xD3, 0x76, 0xF0, 0x83, 0x5E, 0xA3, 0x5E, 0x5A, 0xC1, 0xF7, 0x61, 0x58, 0xA7, 0x19, 0x35, 0x3F, 0x99, 0x31, 0xDE, 0x52, 0x74, 0xFC, 0xA2, 0x26, 0x64, 0x4B, 0xD1, 0xF1, 0xAB, 0xAE, 0xD0, 0x2D, 0xC5, 0xC7, 0x2F, 0x36, 0xDD, 0x27, 0x15, 0x0F, 0x3F, 0xD9, 0x08, 0x9F, 0x62, 0xE4, 0xC2, 0x2C, 0xD4, 0xD8, 0xD3, 0x89, 0x0B, 0x1B, 0x57, 0x11, 0x0B, 0x3B, 0xC5, 0xCF, 0xD6, 0xCC, 0xC6, 0x64, 0x35, 0xAF, 0x18, 0x73, 0x1F, 0xA1, 0x5D, 0xBC, 0x62, 0x45, 0xB3, 0x45, 0x51, 0xF0, 0xA2, 0x62, 0xAB, 0x4A, 0x5B, 0xC9, 0x4B, 0x8A, 0x2D, 0xB3, 0x6C, 0x06, 0x2F, 0x29, 0xB2, 0xAC, 0x8A, 0x18, 0xBC, 0x28, 0xD9, 0xAA, 0xD2, 0x92, 0xF1, 0xBC, 0xE0, 0x98, 0x8C, 0x48, 0xCC, 0x17, 0x52, 0xA3, 0x27, 0x6D, 0x93, 0xD0, 0x4B, 0x8E, 0x0E, 0x77, 0x02, 0x00, 0xFF, 0x0F}; +uint8_t spTWELVE[] PROGMEM = {0x06, 0x28, 0x46, 0xD3, 0x01, 0x25, 0x06, 0x13, 0x20, 0xBA, 0x70, 0x70, 0xB6, 0x79, 0xCA, 0x36, 0xAE, 0x28, 0x38, 0xE1, 0x29, 0xC5, 0x35, 0xA3, 0xE6, 0xC4, 0x16, 0x6A, 0x53, 0x8C, 0x97, 0x9B, 0x72, 0x86, 0x4F, 0x28, 0x1A, 0x6E, 0x0A, 0x59, 0x36, 0xAE, 0x68, 0xF8, 0x29, 0x67, 0xFA, 0x06, 0xA3, 0x16, 0xC4, 0x96, 0xE6, 0x53, 0xAC, 0x5A, 0x9C, 0x56, 0x72, 0x77, 0x31, 0x4E, 0x49, 0x5C, 0x8D, 0x5B, 0x29, 0x3B, 0x24, 0x61, 0x1E, 0x6C, 0x9B, 0x6C, 0x97, 0xF8, 0xA7, 0x34, 0x19, 0x92, 0x4C, 0x62, 0x9E, 0x72, 0x65, 0x58, 0x12, 0xB1, 0x7E, 0x09, 0xD5, 0x2E, 0x53, 0xC5, 0xBA, 0x36, 0x6B, 0xB9, 0x2D, 0x17, 0x05, 0xEE, 0x9A, 0x6E, 0x8E, 0x05, 0x50, 0x6C, 0x19, 0x07, 0x18, 0x50, 0xBD, 0x3B, 0x01, 0x92, 0x08, 0x41, 0x40, 0x10, 0xA6, 0xFF, 0x0F}; +uint8_t spTHIRTEEN[] PROGMEM = {0x08, 0xE8, 0x2C, 0x15, 0x01, 0x43, 0x07, 0x13, 0xE0, 0x98, 0xB4, 0xA6, 0x35, 0xA9, 0x1E, 0xDE, 0x56, 0x8E, 0x53, 0x9C, 0x7A, 0xE7, 0xCA, 0x5E, 0x76, 0x8D, 0x94, 0xE5, 0x2B, 0xAB, 0xD9, 0xB5, 0x62, 0xA4, 0x9C, 0xE4, 0xE6, 0xB4, 0x41, 0x1E, 0x7C, 0xB6, 0x93, 0xD7, 0x16, 0x99, 0x5A, 0xCD, 0x61, 0x76, 0x55, 0xC2, 0x91, 0x61, 0x1B, 0xC0, 0x01, 0x5D, 0x85, 0x05, 0xE0, 0x68, 0x51, 0x07, 0x1C, 0xA9, 0x64, 0x80, 0x1D, 0x4C, 0x9C, 0x95, 0x88, 0xD4, 0x04, 0x3B, 0x4D, 0x4E, 0x21, 0x5C, 0x93, 0xA8, 0x26, 0xB9, 0x05, 0x4B, 0x6E, 0xA0, 0xE2, 0xE4, 0x57, 0xC2, 0xB9, 0xC1, 0xB2, 0x93, 0x5F, 0x09, 0xD7, 0x24, 0xCB, 0x4E, 0x41, 0x25, 0x54, 0x1D, 0x62, 0x3B, 0x05, 0x8D, 0x52, 0x57, 0xAA, 0xAD, 0x10, 0x24, 0x26, 0xE3, 0xE1, 0x36, 0x5D, 0x10, 0x85, 0xB4, 0x97, 0x85, 0x72, 0x41, 0x14, 0x52, 0x5E, 0x1A, 0xCA, 0xF9, 0x91, 0x6B, 0x7A, 0x5B, 0xC4, 0xE0, 0x17, 0x2D, 0x54, 0x1D, 0x92, 0x8C, 0x1F, 0x25, 0x4B, 0x8F, 0xB2, 0x16, 0x41, 0xA1, 0x4A, 0x3E, 0xE6, 0xFA, 0xFF, 0x01}; +uint8_t spFOURTEEN[] PROGMEM = {0x0C, 0x58, 0xAE, 0x5C, 0x01, 0xD9, 0x87, 0x07, 0x51, 0xB7, 0x25, 0xB3, 0x8A, 0x15, 0x2C, 0xF7, 0x1C, 0x35, 0x87, 0x4D, 0xB2, 0xDD, 0x53, 0xCE, 0x28, 0x2B, 0xC9, 0x0E, 0x97, 0x2D, 0xBD, 0x2A, 0x17, 0x27, 0x76, 0x8E, 0xD2, 0x9A, 0x6C, 0x80, 0x94, 0x71, 0x00, 0x00, 0x02, 0xB0, 0x58, 0x58, 0x00, 0x9E, 0x0B, 0x0A, 0xC0, 0xB2, 0xCE, 0xC1, 0xC8, 0x98, 0x7A, 0x52, 0x95, 0x24, 0x2B, 0x11, 0xED, 0x36, 0xD4, 0x92, 0xDC, 0x4C, 0xB5, 0xC7, 0xC8, 0x53, 0xF1, 0x2A, 0xE5, 0x1A, 0x17, 0x55, 0xC5, 0xAF, 0x94, 0xBB, 0xCD, 0x1C, 0x26, 0xBF, 0x52, 0x9A, 0x72, 0x53, 0x98, 0xFC, 0xC2, 0x68, 0xD2, 0x4D, 0x61, 0xF0, 0xA3, 0x90, 0xB6, 0xD6, 0x50, 0xC1, 0x8F, 0x42, 0xDA, 0x4A, 0x43, 0x39, 0x3F, 0x48, 0x2D, 0x6B, 0x33, 0xF9, 0xFF}; +uint8_t spFIFTEEN[] PROGMEM = {0x08, 0xE8, 0x2A, 0x0D, 0x01, 0xDD, 0xBA, 0x31, 0x60, 0x6A, 0xF7, 0xA0, 0xAE, 0x54, 0xAA, 0x5A, 0x76, 0x97, 0xD9, 0x34, 0x69, 0xEF, 0x32, 0x1E, 0x66, 0xE1, 0xE2, 0xB3, 0x43, 0xA9, 0x18, 0x55, 0x92, 0x4E, 0x37, 0x2D, 0x67, 0x6F, 0xDF, 0xA2, 0x5A, 0xB6, 0x04, 0x30, 0x55, 0xA8, 0x00, 0x86, 0x09, 0xE7, 0x00, 0x01, 0x16, 0x17, 0x05, 0x70, 0x40, 0x57, 0xE5, 0x01, 0xF8, 0x21, 0x34, 0x00, 0xD3, 0x19, 0x33, 0x80, 0x89, 0x9A, 0x62, 0x34, 0x4C, 0xD5, 0x49, 0xAE, 0x8B, 0x53, 0x09, 0xF7, 0x26, 0xD9, 0x6A, 0x7E, 0x23, 0x5C, 0x13, 0x12, 0xB3, 0x04, 0x9D, 0x50, 0x4F, 0xB1, 0xAD, 0x14, 0x15, 0xC2, 0xD3, 0xA1, 0xB6, 0x42, 0x94, 0xA8, 0x8C, 0x87, 0xDB, 0x74, 0xB1, 0x70, 0x59, 0xE1, 0x2E, 0xC9, 0xC5, 0x81, 0x5B, 0x55, 0xA4, 0x4C, 0x17, 0x47, 0xC1, 0x6D, 0xE3, 0x81, 0x53, 0x9C, 0x84, 0x6A, 0x46, 0xD9, 0x4C, 0x51, 0x31, 0x42, 0xD9, 0x66, 0xC9, 0x44, 0x85, 0x29, 0x6A, 0x9B, 0xAD, 0xFF, 0x07}; +uint8_t spSIXTEEN[] PROGMEM = {0x0A, 0x58, 0x5A, 0x5D, 0x00, 0x93, 0x97, 0x0B, 0x60, 0xA9, 0x48, 0x05, 0x0C, 0x15, 0xAE, 0x80, 0xAD, 0x3D, 0x14, 0x30, 0x7D, 0xD9, 0x50, 0x92, 0x92, 0xAC, 0x0D, 0xC5, 0xCD, 0x2A, 0x82, 0xAA, 0x3B, 0x98, 0x04, 0xB3, 0x4A, 0xC8, 0x9A, 0x90, 0x05, 0x09, 0x68, 0x51, 0xD4, 0x01, 0x23, 0x9F, 0x1A, 0x60, 0xA9, 0x12, 0x03, 0xDC, 0x50, 0x81, 0x80, 0x22, 0xDC, 0x20, 0x00, 0xCB, 0x06, 0x3A, 0x60, 0x16, 0xE3, 0x64, 0x64, 0x42, 0xDD, 0xCD, 0x6A, 0x8A, 0x5D, 0x28, 0x75, 0x07, 0xA9, 0x2A, 0x5E, 0x65, 0x34, 0xED, 0x64, 0xBB, 0xF8, 0x85, 0xF2, 0x94, 0x8B, 0xAD, 0xE4, 0x37, 0x4A, 0x5B, 0x21, 0xB6, 0x52, 0x50, 0x19, 0xAD, 0xA7, 0xD8, 0x4A, 0x41, 0x14, 0xDA, 0x5E, 0x12, 0x3A, 0x04, 0x91, 0x4B, 0x7B, 0x69, 0xA8, 0x10, 0x24, 0x2E, 0xE5, 0xA3, 0x81, 0x52, 0x90, 0x94, 0x5A, 0x55, 0x98, 0x32, 0x41, 0x50, 0xCC, 0x93, 0x2E, 0x47, 0x85, 0x89, 0x1B, 0x5B, 0x5A, 0x62, 0x04, 0x44, 0xE3, 0x02, 0x80, 0x80, 0x64, 0xDD, 0xFF, 0x1F}; +uint8_t spSEVENTEEN[] PROGMEM = {0x02, 0x98, 0x3A, 0x42, 0x00, 0x5B, 0xA6, 0x09, 0x60, 0xDB, 0x52, 0x06, 0x1C, 0x93, 0x29, 0x80, 0xA9, 0x52, 0x87, 0x9A, 0xB5, 0x99, 0x4F, 0xC8, 0x3E, 0x46, 0xD6, 0x5E, 0x7E, 0x66, 0xFB, 0x98, 0xC5, 0x5A, 0xC6, 0x9A, 0x9C, 0x63, 0x15, 0x6B, 0x11, 0x13, 0x8A, 0x9C, 0x97, 0xB9, 0x9A, 0x5A, 0x39, 0x71, 0xEE, 0xD2, 0x29, 0xC2, 0xA6, 0xB8, 0x58, 0x59, 0x99, 0x56, 0x14, 0xA3, 0xE1, 0x26, 0x19, 0x19, 0xE3, 0x8C, 0x93, 0x17, 0xB4, 0x46, 0xB5, 0x88, 0x71, 0x9E, 0x97, 0x9E, 0xB1, 0x2C, 0xC5, 0xF8, 0x56, 0xC4, 0x58, 0xA3, 0x1C, 0xE1, 0x33, 0x9D, 0x13, 0x41, 0x8A, 0x43, 0x58, 0xAD, 0x95, 0xA9, 0xDB, 0x36, 0xC0, 0xD1, 0xC9, 0x0E, 0x58, 0x4E, 0x45, 0x01, 0x23, 0xA9, 0x04, 0x37, 0x13, 0xAE, 0x4D, 0x65, 0x52, 0x82, 0xCA, 0xA9, 0x37, 0x99, 0x4D, 0x89, 0xBA, 0xC0, 0xBC, 0x14, 0x36, 0x25, 0xEA, 0x1C, 0x73, 0x52, 0x1D, 0x97, 0xB8, 0x33, 0xAC, 0x0E, 0x75, 0x9C, 0xE2, 0xCE, 0xB0, 0xDA, 0xC3, 0x51, 0x4A, 0x1A, 0xA5, 0xCA, 0x70, 0x5B, 0x21, 0xCE, 0x4C, 0x26, 0xD2, 0x6C, 0xBA, 0x38, 0x71, 0x2E, 0x1F, 0x2D, 0xED, 0xE2, 0x24, 0xB8, 0xBC, 0x3D, 0x52, 0x88, 0xAB, 0x50, 0x8E, 0xA8, 0x48, 0x22, 0x4E, 0x42, 0xA0, 0x26, 0x55, 0xFD, 0x3F}; +uint8_t spEIGHTEEN[] PROGMEM = {0x2E, 0x9C, 0xD1, 0x4D, 0x54, 0xEC, 0x2C, 0xBF, 0x1B, 0x8A, 0x99, 0x70, 0x7C, 0xFC, 0x2E, 0x29, 0x6F, 0x52, 0xF6, 0xF1, 0xBA, 0x20, 0xBF, 0x36, 0xD9, 0xCD, 0xED, 0x0C, 0xF3, 0x27, 0x64, 0x17, 0x73, 0x2B, 0xA2, 0x99, 0x90, 0x65, 0xEC, 0xED, 0x40, 0x73, 0x32, 0x12, 0xB1, 0xAF, 0x30, 0x35, 0x0B, 0xC7, 0x00, 0xE0, 0x80, 0xAE, 0xDD, 0x1C, 0x70, 0x43, 0xAA, 0x03, 0x86, 0x51, 0x36, 0xC0, 0x30, 0x64, 0xCE, 0x4C, 0x98, 0xFB, 0x5C, 0x65, 0x07, 0xAF, 0x10, 0xEA, 0x0B, 0x66, 0x1B, 0xFC, 0x46, 0xA8, 0x3E, 0x09, 0x4D, 0x08, 0x2A, 0xA6, 0x3E, 0x67, 0x36, 0x21, 0x2A, 0x98, 0x67, 0x9D, 0x15, 0xA7, 0xA8, 0x60, 0xEE, 0xB6, 0x94, 0x99, 0xA2, 0x4A, 0x78, 0x22, 0xC2, 0xA6, 0x8B, 0x8C, 0x8E, 0xCC, 0x4C, 0x8A, 0x2E, 0x8A, 0x4C, 0xD3, 0x57, 0x03, 0x87, 0x28, 0x71, 0x09, 0x1F, 0x2B, 0xE4, 0xA2, 0xC4, 0xC5, 0x6D, 0xAD, 0x54, 0x88, 0xB2, 0x63, 0xC9, 0xF2, 0x50, 0x2E, 0x8A, 0x4A, 0x38, 0x4A, 0xEC, 0x88, 0x28, 0x08, 0xE3, 0x28, 0x49, 0xF3, 0xFF}; +uint8_t spNINETEEN[] PROGMEM = {0xC2, 0xEA, 0x8A, 0x95, 0x2B, 0x6A, 0x05, 0x3F, 0x71, 0x71, 0x5F, 0x0D, 0x12, 0xFC, 0x28, 0x25, 0x62, 0x35, 0xF0, 0xF0, 0xB3, 0x48, 0x1E, 0x0F, 0xC9, 0xCB, 0x2F, 0x45, 0x7C, 0x2C, 0x25, 0x1F, 0xBF, 0x14, 0xB3, 0x2C, 0xB5, 0x75, 0xFC, 0x5A, 0x5C, 0xA3, 0x5D, 0xE1, 0xF1, 0x7A, 0x76, 0xB3, 0x4E, 0x45, 0xC7, 0xED, 0x96, 0x23, 0x3B, 0x18, 0x37, 0x7B, 0x18, 0xCC, 0x09, 0x51, 0x13, 0x4C, 0xAB, 0x6C, 0x4C, 0x4B, 0x96, 0xD2, 0x49, 0xAA, 0x36, 0x0B, 0xC5, 0xC2, 0x20, 0x26, 0x27, 0x35, 0x63, 0x09, 0x3D, 0x30, 0x8B, 0xF0, 0x48, 0x5C, 0xCA, 0x61, 0xDD, 0xCB, 0xCD, 0x91, 0x03, 0x8E, 0x4B, 0x76, 0xC0, 0xCC, 0x4D, 0x06, 0x98, 0x31, 0x31, 0x98, 0x99, 0x70, 0x6D, 0x2A, 0xA3, 0xE4, 0x16, 0xCA, 0xBD, 0xCE, 0x5C, 0x92, 0x57, 0x28, 0xCF, 0x09, 0x69, 0x2E, 0x7E, 0xA5, 0x3C, 0x63, 0xA2, 0x30, 0x05, 0x95, 0xD2, 0x74, 0x98, 0xCD, 0x14, 0x54, 0xCA, 0x53, 0xA9, 0x96, 0x52, 0x50, 0x28, 0x6F, 0xBA, 0xCB, 0x0C, 0x41, 0x50, 0xDE, 0x65, 0x2E, 0xD3, 0x05, 0x89, 0x4B, 0x7B, 0x6B, 0x20, 0x17, 0x44, 0xAE, 0xED, 0x23, 0x81, 0x52, 0x90, 0x85, 0x73, 0x57, 0xD0, 0x72, 0x41, 0xB1, 0x02, 0xDE, 0x2E, 0xDB, 0x04, 0x89, 0x05, 0x79, 0xBB, 0x62, 0xE5, 0x76, 0x11, 0xCA, 0x61, 0x0E, 0xFF, 0x1F}; +uint8_t spTWENTY[] PROGMEM = {0x01, 0x98, 0xD1, 0xC2, 0x00, 0xCD, 0xA4, 0x32, 0x20, 0x79, 0x13, 0x04, 0x28, 0xE7, 0x92, 0xDC, 0x70, 0xCC, 0x5D, 0xDB, 0x76, 0xF3, 0xD2, 0x32, 0x0B, 0x0B, 0x5B, 0xC3, 0x2B, 0xCD, 0xD4, 0xDD, 0x23, 0x35, 0xAF, 0x44, 0xE1, 0xF0, 0xB0, 0x6D, 0x3C, 0xA9, 0xAD, 0x3D, 0x35, 0x0E, 0xF1, 0x0C, 0x8B, 0x28, 0xF7, 0x34, 0x01, 0x68, 0x22, 0xCD, 0x00, 0xC7, 0xA4, 0x04, 0xBB, 0x32, 0xD6, 0xAC, 0x56, 0x9C, 0xDC, 0xCA, 0x28, 0x66, 0x53, 0x51, 0x70, 0x2B, 0xA5, 0xBC, 0x0D, 0x9A, 0xC1, 0xEB, 0x14, 0x73, 0x37, 0x29, 0x19, 0xAF, 0x33, 0x8C, 0x3B, 0xA7, 0x24, 0xBC, 0x42, 0xB0, 0xB7, 0x59, 0x09, 0x09, 0x3C, 0x96, 0xE9, 0xF4, 0x58, 0xFF, 0x0F}; +uint8_t spTHIRTY[] PROGMEM = {0x08, 0x98, 0xD6, 0x15, 0x01, 0x43, 0xBB, 0x0A, 0x20, 0x1B, 0x8B, 0xE5, 0x16, 0xA3, 0x1E, 0xB6, 0xB6, 0x96, 0x97, 0x3C, 0x57, 0xD4, 0x2A, 0x5E, 0x7E, 0x4E, 0xD8, 0xE1, 0x6B, 0x7B, 0xF8, 0x39, 0x63, 0x0D, 0x9F, 0x95, 0xE1, 0xE7, 0x4C, 0x76, 0xBC, 0x91, 0x5B, 0x90, 0x13, 0xC6, 0x68, 0x57, 0x4E, 0x41, 0x8B, 0x10, 0x5E, 0x1D, 0xA9, 0x44, 0xD3, 0xBA, 0x47, 0xB8, 0xDD, 0xE4, 0x35, 0x86, 0x11, 0x93, 0x94, 0x92, 0x5F, 0x29, 0xC7, 0x4C, 0x30, 0x0C, 0x41, 0xC5, 0x1C, 0x3B, 0x2E, 0xD3, 0x05, 0x15, 0x53, 0x6C, 0x07, 0x4D, 0x15, 0x14, 0x8C, 0xB5, 0xC9, 0x6A, 0x44, 0x90, 0x10, 0x4E, 0x9A, 0xB6, 0x21, 0x81, 0x23, 0x3A, 0x91, 0x91, 0xE8, 0xFF, 0x01}; +uint8_t spFOURTY[] PROGMEM = {0x04, 0x18, 0xB6, 0x4C, 0x00, 0xC3, 0x56, 0x30, 0xA0, 0xE8, 0xF4, 0xA0, 0x98, 0x99, 0x62, 0x91, 0xAE, 0x83, 0x6B, 0x77, 0x89, 0x78, 0x3B, 0x09, 0xAE, 0xBD, 0xA6, 0x1E, 0x63, 0x3B, 0x79, 0x7E, 0x71, 0x5A, 0x8F, 0x95, 0xE6, 0xA5, 0x4A, 0x69, 0xB9, 0x4E, 0x8A, 0x5F, 0x12, 0x56, 0xE4, 0x58, 0x69, 0xE1, 0x36, 0xA1, 0x69, 0x2E, 0x2B, 0xF9, 0x95, 0x93, 0x55, 0x17, 0xED, 0xE4, 0x37, 0xC6, 0xBA, 0x93, 0xB2, 0x92, 0xDF, 0x19, 0xD9, 0x6E, 0xC8, 0x0A, 0xFE, 0x60, 0xE8, 0x37, 0x21, 0xC9, 0xF9, 0x8D, 0x61, 0x5F, 0x32, 0x13, 0xE7, 0x17, 0x4C, 0xD3, 0xC6, 0xB1, 0x94, 0x97, 0x10, 0x8F, 0x8B, 0xAD, 0x11, 0x7E, 0xA1, 0x9A, 0x26, 0x92, 0xF6, 0xFF, 0x01}; +uint8_t spFIFTY[] PROGMEM = {0x08, 0xE8, 0x2E, 0x84, 0x00, 0x23, 0x84, 0x13, 0x60, 0x38, 0x95, 0xA5, 0x0F, 0xCF, 0xE2, 0x79, 0x8A, 0x8F, 0x37, 0x02, 0xB3, 0xD5, 0x2A, 0x6E, 0x5E, 0x93, 0x94, 0x79, 0x45, 0xD9, 0x05, 0x5D, 0x0A, 0xB9, 0x97, 0x63, 0x02, 0x74, 0xA7, 0x82, 0x80, 0xEE, 0xC3, 0x10, 0xD0, 0x7D, 0x28, 0x03, 0x6E, 0x14, 0x06, 0x70, 0xE6, 0x0A, 0xC9, 0x9A, 0x4E, 0x37, 0xD9, 0x95, 0x51, 0xCE, 0xBA, 0xA2, 0x14, 0x0C, 0x81, 0x36, 0x1B, 0xB2, 0x5C, 0x30, 0x38, 0xFA, 0x9C, 0xC9, 0x32, 0x41, 0xA7, 0x18, 0x3B, 0xA2, 0x48, 0x04, 0x05, 0x51, 0x4F, 0x91, 0x6D, 0x12, 0x04, 0x20, 0x9B, 0x61, 0x89, 0xFF, 0x1F}; +uint8_t spGOOD[] PROGMEM = {0x0A, 0x28, 0xCD, 0x34, 0x20, 0xD9, 0x1A, 0x45, 0x74, 0xE4, 0x66, 0x24, 0xAD, 0xBA, 0xB1, 0x8C, 0x9B, 0x91, 0xA5, 0x64, 0xE6, 0x98, 0x21, 0x16, 0x0B, 0x96, 0x9B, 0x4C, 0xE5, 0xFF, 0x01}; +uint8_t spMORNING[] PROGMEM = {0xCE, 0x08, 0x52, 0x2A, 0x35, 0x5D, 0x39, 0x53, 0x29, 0x5B, 0xB7, 0x0A, 0x15, 0x0C, 0xEE, 0x2A, 0x42, 0x56, 0x66, 0xD2, 0x55, 0x2E, 0x37, 0x2F, 0xD9, 0x45, 0xB3, 0xD3, 0xC5, 0xCA, 0x6D, 0x27, 0xD5, 0xEE, 0x50, 0xF5, 0x50, 0x94, 0x14, 0x77, 0x2D, 0xD8, 0x5D, 0x49, 0x92, 0xFD, 0xB1, 0x64, 0x2F, 0xA9, 0x49, 0x0C, 0x93, 0x4B, 0xAD, 0x19, 0x17, 0x3E, 0x66, 0x1E, 0xF1, 0xA2, 0x5B, 0x84, 0xE2, 0x29, 0x8F, 0x8B, 0x72, 0x10, 0xB5, 0xB1, 0x2E, 0x4B, 0xD4, 0x45, 0x89, 0x4A, 0xEC, 0x5C, 0x95, 0x14, 0x2B, 0x8A, 0x9C, 0x34, 0x52, 0x5D, 0xBC, 0xCC, 0xB5, 0x3B, 0x49, 0x69, 0x89, 0x87, 0xC1, 0x98, 0x56, 0x3A, 0x21, 0x2B, 0x82, 0x67, 0xCC, 0x5C, 0x85, 0xB5, 0x4A, 0x8A, 0xF6, 0x64, 0xA9, 0x96, 0xC4, 0x69, 0x3C, 0x52, 0x81, 0x58, 0x1C, 0x97, 0xF6, 0x0E, 0x1B, 0xCC, 0x0D, 0x42, 0x32, 0xAA, 0x65, 0x12, 0x67, 0xD4, 0x6A, 0x61, 0x52, 0xFC, 0xFF}; +uint8_t spAFTERNOON[] PROGMEM = {0xC7, 0xCE, 0xCE, 0x3A, 0xCB, 0x58, 0x1F, 0x3B, 0x07, 0x9D, 0x28, 0x71, 0xB4, 0xAC, 0x9C, 0x74, 0x5A, 0x42, 0x55, 0x33, 0xB2, 0x93, 0x0A, 0x09, 0xD4, 0xC5, 0x9A, 0xD6, 0x44, 0x45, 0xE3, 0x38, 0x60, 0x9A, 0x32, 0x05, 0xF4, 0x18, 0x01, 0x09, 0xD8, 0xA9, 0xC2, 0x00, 0x5E, 0xCA, 0x24, 0xD5, 0x5B, 0x9D, 0x4A, 0x95, 0xEA, 0x34, 0xEE, 0x63, 0x92, 0x5C, 0x4D, 0xD0, 0xA4, 0xEE, 0x58, 0x0C, 0xB9, 0x4D, 0xCD, 0x42, 0xA2, 0x3A, 0x24, 0x37, 0x25, 0x8A, 0xA8, 0x8E, 0xA0, 0x53, 0xE4, 0x28, 0x23, 0x26, 0x13, 0x72, 0x91, 0xA2, 0x76, 0xBB, 0x72, 0x38, 0x45, 0x0A, 0x46, 0x63, 0xCA, 0x69, 0x27, 0x39, 0x58, 0xB1, 0x8D, 0x60, 0x1C, 0x34, 0x1B, 0x34, 0xC3, 0x55, 0x8E, 0x73, 0x45, 0x2D, 0x4F, 0x4A, 0x3A, 0x26, 0x10, 0xA1, 0xCA, 0x2D, 0xE9, 0x98, 0x24, 0x0A, 0x1E, 0x6D, 0x97, 0x29, 0xD2, 0xCC, 0x71, 0xA2, 0xDC, 0x86, 0xC8, 0x12, 0xA7, 0x8E, 0x08, 0x85, 0x22, 0x8D, 0x9C, 0x43, 0xA7, 0x12, 0xB2, 0x2E, 0x50, 0x09, 0xEF, 0x51, 0xC5, 0xBA, 0x28, 0x58, 0xAD, 0xDB, 0xE1, 0xFF, 0x03}; +uint8_t spEVENING[] PROGMEM = {0xCD, 0x6D, 0x98, 0x73, 0x47, 0x65, 0x0D, 0x6D, 0x10, 0xB2, 0x5D, 0x93, 0x35, 0x94, 0xC1, 0xD0, 0x76, 0x4D, 0x66, 0x93, 0xA7, 0x04, 0xBD, 0x71, 0xD9, 0x45, 0xAE, 0x92, 0xD5, 0xAC, 0x53, 0x07, 0x6D, 0xA5, 0x76, 0x63, 0x51, 0x92, 0xD4, 0xA1, 0x83, 0xD4, 0xCB, 0xB2, 0x51, 0x88, 0xCD, 0xF5, 0x50, 0x45, 0xCE, 0xA2, 0x2E, 0x27, 0x28, 0x54, 0x15, 0x37, 0x0A, 0xCF, 0x75, 0x61, 0x5D, 0xA2, 0xC4, 0xB5, 0xC7, 0x44, 0x55, 0x8A, 0x0B, 0xA3, 0x6E, 0x17, 0x95, 0x21, 0xA9, 0x0C, 0x37, 0xCD, 0x15, 0xBA, 0xD4, 0x2B, 0x6F, 0xB3, 0x54, 0xE4, 0xD2, 0xC8, 0x64, 0xBC, 0x4C, 0x91, 0x49, 0x12, 0xE7, 0xB2, 0xB1, 0xD0, 0x22, 0x0D, 0x9C, 0xDD, 0xAB, 0x62, 0xA9, 0x38, 0x53, 0x11, 0xA9, 0x74, 0x2C, 0xD2, 0xCA, 0x59, 0x34, 0xA3, 0xE5, 0xFF, 0x03}; +uint8_t spPAUSE1[] PROGMEM = {0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F}; + +void sayTime(int hour, int minutes, AudioGeneratorTalkie *talkie) { bool pm = (hour >= 12); uint8_t *spHour[] = { spTWELVE, spONE, spTWO, spTHREE, spFOUR, spFIVE, spSIX, - spSEVEN, spEIGHT, spNINE, spTEN, spELEVEN }; + spSEVEN, spEIGHT, spNINE, spTEN, spELEVEN + }; size_t spHourLen[] = { sizeof(spTWELVE), sizeof(spONE), sizeof(spTWO), sizeof(spTHREE), sizeof(spFOUR), sizeof(spFIVE), sizeof(spSIX), sizeof(spSEVEN), sizeof(spEIGHT), - sizeof(spNINE), sizeof(spTEN), sizeof(spELEVEN) }; + sizeof(spNINE), sizeof(spTEN), sizeof(spELEVEN) + }; uint8_t *spMinDec[] = { spOH, spTEN, spTWENTY, spTHIRTY, spFOURTY, spFIFTY }; size_t spMinDecLen[] = { sizeof(spOH), sizeof(spTEN), sizeof(spTWENTY), - sizeof(spTHIRTY), sizeof(spFOURTY), sizeof(spFIFTY) }; + sizeof(spTHIRTY), sizeof(spFOURTY), sizeof(spFIFTY) + }; uint8_t *spMinSpecial[] = { spELEVEN, spTWELVE, spTHIRTEEN, spFOURTEEN, spFIFTEEN, spSIXTEEN, spSEVENTEEN, spEIGHTEEN, - spNINETEEN }; + spNINETEEN + }; size_t spMinSpecialLen[] = { sizeof(spELEVEN), sizeof(spTWELVE), sizeof(spTHIRTEEN), sizeof(spFOURTEEN), sizeof(spFIFTEEN), sizeof(spSIXTEEN), sizeof(spSEVENTEEN), sizeof(spEIGHTEEN), - sizeof(spNINETEEN) }; + sizeof(spNINETEEN) + }; uint8_t *spMinLow[] = { spONE, spTWO, spTHREE, spFOUR, spFIVE, spSIX, - spSEVEN, spEIGHT, spNINE }; + spSEVEN, spEIGHT, spNINE + }; size_t spMinLowLen[] = { sizeof(spONE), sizeof(spTWO), sizeof(spTHREE), sizeof(spFOUR), sizeof(spFIVE), sizeof(spSIX), - sizeof(spSEVEN), sizeof(spEIGHT), sizeof(spNINE) }; + sizeof(spSEVEN), sizeof(spEIGHT), sizeof(spNINE) + }; talkie->say(spTHE, sizeof(spTHE)); talkie->say(spTIME, sizeof(spTIME)); @@ -92,10 +100,10 @@ void sayTime(int hour, int minutes, AudioGeneratorTalkie *talkie) hour = hour % 12; talkie->say(spHour[hour], spHourLen[hour]); - if (minutes==0) { + if (minutes == 0) { talkie->say(spOCLOCK, sizeof(spOCLOCK)); - } else if (minutes<=10 || minutes >=20) { - talkie->say(spMinDec[minutes / 10], spMinDecLen[minutes /10]); + } else if (minutes <= 10 || minutes >= 20) { + talkie->say(spMinDec[minutes / 10], spMinDecLen[minutes / 10]); if (minutes % 10) { talkie->say(spMinLow[(minutes % 10) - 1], spMinLowLen[(minutes % 10) - 1]); } @@ -136,8 +144,7 @@ bool GetLocalTime(struct tm * info, uint32_t ms) { return false; } -void setup() -{ +void setup() { Serial.begin(115200); delay(1000); // We start by connecting to a WiFi network @@ -156,7 +163,16 @@ void setup() Serial.println("IP address: "); Serial.println(WiFi.localIP()); Serial.println("Contacting Time Server"); +#if defined(ARDUINO_ARCH_RP2040) + NTP.begin("pool.ntp.org", "time.nist.gov"); + Serial.print("Waiting for NTP time sync: "); + NTP.waitSet([]() { + Serial.print("."); + }); + Serial.println(""); +#else configTime(3600 * timezone, daysavetime * 3600, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org"); +#endif struct tm tmstruct ; do { tmstruct.tm_year = 0; @@ -164,15 +180,14 @@ void setup() GetLocalTime(&tmstruct, 5000); delay(100); } while (tmstruct.tm_year < 100); - + audioLogger = &Serial; out = new AudioOutputI2S(); talkie = new AudioGeneratorTalkie(); talkie->begin(nullptr, out); } -void loop() -{ +void loop() { struct tm tmstruct ; tmstruct.tm_year = 0; GetLocalTime(&tmstruct, 5000); diff --git a/examples/WebRadio/WebRadio.ino b/examples/WebRadio/WebRadio.ino index e8a03261..538f1efe 100644 --- a/examples/WebRadio/WebRadio.ino +++ b/examples/WebRadio/WebRadio.ino @@ -1,7 +1,7 @@ /* WebRadio Example Very simple HTML app to control web streaming - + Copyright (C) 2017 Earle F. Philhower, III This program is free software: you can redistribute it and/or modify @@ -19,16 +19,29 @@ */ #include -#ifdef ESP32 - #include + +// ESP8266 server.available() is now server.accept() +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + +#ifdef ESP8266 +#include #else - #include +#include #endif + #include "AudioFileSourceICYStream.h" #include "AudioFileSourceBuffer.h" #include "AudioGeneratorMP3.h" #include "AudioGeneratorAAC.h" +#if defined(ARDUINO_ARCH_RP2040) +#include "AudioOutputPWM.h" +#define MOBO rp2040 +AudioOutputPWM *out = NULL; +#else #include "AudioOutputI2S.h" +AudioOutputI2S *out = NULL; +#define MOBO ESP +#endif #include // Custom web server that doesn't need much RAM @@ -50,7 +63,6 @@ WiFiServer server(80); AudioGenerator *decoder = NULL; AudioFileSourceICYStream *file = NULL; AudioFileSourceBuffer *buff = NULL; -AudioOutputI2S *out = NULL; int volume = 100; char title[64]; @@ -113,48 +125,44 @@ Change URL:
)KEWL"; -void HandleIndex(WiFiClient *client) -{ - char buff[sizeof(BODY) + sizeof(title) + sizeof(status) + sizeof(url) + 3*2]; - - Serial.printf_P(PSTR("Sending INDEX...Free mem=%d\n"), ESP.getFreeHeap()); +void HandleIndex(WiFiClient *client) { + char buff[std::max(sizeof(BODY) + sizeof(title) + sizeof(status) + sizeof(url) + 3 * 2, sizeof(HEAD))]; + + Serial.printf_P(PSTR("Sending INDEX...Free mem=%d\n"), MOBO.getFreeHeap()); WebHeaders(client, NULL); WebPrintf(client, DOCTYPE); - client->write_P( PSTR(""), 6 ); - client->write_P( HEAD, strlen_P(HEAD) ); + client->write("", 6); + strcpy_P(buff, HEAD); + client->write(buff, strlen(buff)); sprintf_P(buff, BODY, title, volume, volume, status, url); - client->write(buff, strlen(buff) ); - client->write_P( PSTR(""), 7 ); - Serial.printf_P(PSTR("Sent INDEX...Free mem=%d\n"), ESP.getFreeHeap()); + client->write(buff, strlen(buff)); + client->write("", 7); + Serial.printf_P(PSTR("Sent INDEX...Free mem=%d\n"), MOBO.getFreeHeap()); } -void HandleStatus(WiFiClient *client) -{ +void HandleStatus(WiFiClient *client) { WebHeaders(client, NULL); client->write(status, strlen(status)); } -void HandleTitle(WiFiClient *client) -{ +void HandleTitle(WiFiClient *client) { WebHeaders(client, NULL); client->write(title, strlen(title)); } -void HandleVolume(WiFiClient *client, char *params) -{ +void HandleVolume(WiFiClient *client, char *params) { char *namePtr; char *valPtr; - + while (ParseParam(¶ms, &namePtr, &valPtr)) { ParamInt("vol", volume); } Serial.printf_P(PSTR("Set volume: %d\n"), volume); - out->SetGain(((float)volume)/100.0); + out->SetGain(((float)volume) / 100.0); RedirectToIndex(client); } -void HandleChangeURL(WiFiClient *client, char *params) -{ +void HandleChangeURL(WiFiClient *client, char *params) { char *namePtr; char *valPtr; char newURL[sizeof(url)]; @@ -168,8 +176,8 @@ void HandleChangeURL(WiFiClient *client, char *params) } if (newURL[0] && newType[0]) { newUrl = true; - strncpy(url, newURL, sizeof(url)-1); - url[sizeof(url)-1] = 0; + strncpy(url, newURL, sizeof(url) - 1); + url[sizeof(url) - 1] = 0; if (!strcmp_P(newType, PSTR("aac"))) { isAAC = true; } else { @@ -183,13 +191,11 @@ void HandleChangeURL(WiFiClient *client, char *params) } } -void RedirectToIndex(WiFiClient *client) -{ +void RedirectToIndex(WiFiClient *client) { WebError(client, 301, PSTR("Location: /\r\n"), true); } -void StopPlaying() -{ +void StopPlaying() { if (decoder) { decoder->stop(); delete decoder; @@ -209,64 +215,65 @@ void StopPlaying() strcpy_P(title, PSTR("Stopped")); } -void HandleStop(WiFiClient *client) -{ +void HandleStop(WiFiClient *client) { Serial.printf_P(PSTR("HandleStop()\n")); StopPlaying(); RedirectToIndex(client); } -void MDCallback(void *cbData, const char *type, bool isUnicode, const char *str) -{ +void MDCallback(void *cbData, const char *type, bool isUnicode, const char *str) { const char *ptr = reinterpret_cast(cbData); (void) isUnicode; // Punt this ball for now (void) ptr; - if (strstr_P(type, PSTR("Title"))) { + if (strstr_P(type, PSTR("Title"))) { strncpy(title, str, sizeof(title)); - title[sizeof(title)-1] = 0; + title[sizeof(title) - 1] = 0; } else { // Who knows what to do? Not me! } } -void StatusCallback(void *cbData, int code, const char *string) -{ +void StatusCallback(void *cbData, int code, const char *string) { const char *ptr = reinterpret_cast(cbData); (void) code; (void) ptr; - strncpy_P(status, string, sizeof(status)-1); - status[sizeof(status)-1] = 0; + strncpy_P(status, string, sizeof(status) - 1); + status[sizeof(status) - 1] = 0; } #ifdef ESP8266 -const int preallocateBufferSize = 5*1024; +const int preallocateBufferSize = 5 * 1024; const int preallocateCodecSize = 29192; // MP3 codec max mem needed #else -const int preallocateBufferSize = 16*1024; +const int preallocateBufferSize = 16 * 1024; const int preallocateCodecSize = 85332; // AAC+SBR codec max mem needed #endif void *preallocateBuffer = NULL; void *preallocateCodec = NULL; -void setup() -{ +void setup() { // First, preallocate all the memory needed for the buffering and codecs, never to be freed preallocateBuffer = malloc(preallocateBufferSize); preallocateCodec = malloc(preallocateCodecSize); if (!preallocateBuffer || !preallocateCodec) { Serial.begin(115200); - Serial.printf_P(PSTR("FATAL ERROR: Unable to preallocate %d bytes for app\n"), preallocateBufferSize+preallocateCodecSize); - while (1) delay(1000); // Infinite halt + Serial.printf_P(PSTR("FATAL ERROR: Unable to preallocate %d bytes for app\n"), preallocateBufferSize + preallocateCodecSize); + while (1) { + delay(1000); // Infinite halt + } } Serial.begin(115200); - delay(1000); + delay(3000); +#ifndef ESP8266 + Serial.printf_P(PSTR("Consider using BackgroundAudio instead, it is much faster and stable.\nhttps://github.com/earlephilhower/BackgroundAudio\n")); +#endif Serial.printf_P(PSTR("Connecting to WiFi\n")); WiFi.disconnect(); WiFi.softAPdisconnect(true); WiFi.mode(WIFI_STA); - + WiFi.begin(ssid, password); // Try forever @@ -275,13 +282,13 @@ void setup() delay(1000); } Serial.printf_P(PSTR("Connected\n")); - + Serial.printf_P(PSTR("Go to http://")); Serial.print(WiFi.localIP()); Serial.printf_P(PSTR("/ to control the web radio.\n")); server.begin(); - + strcpy_P(url, PSTR("none")); strcpy_P(status, PSTR("OK")); strcpy_P(title, PSTR("Idle")); @@ -289,24 +296,27 @@ void setup() audioLogger = &Serial; file = NULL; buff = NULL; +#if defined(ARDUINO_ARCH_RP2040) + out = new AudioOutputPWM(44100, 0); +#else out = new AudioOutputI2S(); +#endif decoder = NULL; LoadSettings(); } -void StartNewURL() -{ +void StartNewURL() { Serial.printf_P(PSTR("Changing URL to: %s, vol=%d\n"), url, volume); newUrl = false; // Stop and free existing ones - Serial.printf_P(PSTR("Before stop...Free mem=%d\n"), ESP.getFreeHeap()); + Serial.printf_P(PSTR("Before stop...Free mem=%d\n"), MOBO.getFreeHeap()); StopPlaying(); - Serial.printf_P(PSTR("After stop...Free mem=%d\n"), ESP.getFreeHeap()); + Serial.printf_P(PSTR("After stop...Free mem=%d\n"), MOBO.getFreeHeap()); SaveSettings(); Serial.printf_P(PSTR("Saved settings\n")); - + file = new AudioFileSourceICYStream(url); Serial.printf_P(PSTR("created icystream\n")); file->RegisterMetadataCB(MDCallback, NULL); @@ -318,7 +328,7 @@ void StartNewURL() decoder->RegisterStatusCB(StatusCallback, NULL); Serial.printf_P("Decoder start...\n"); decoder->begin(buff, out); - out->SetGain(((float)volume)/100.0); + out->SetGain(((float)volume) / 100.0); if (!decoder->isRunning()) { Serial.printf_P(PSTR("Can't connect to URL")); StopPlaying(); @@ -328,31 +338,31 @@ void StartNewURL() Serial.printf_P("Done start new URL\n"); } -void LoadSettings() -{ +void LoadSettings() { // Restore from EEPROM, check the checksum matches Settings s; uint8_t *ptr = reinterpret_cast(&s); EEPROM.begin(sizeof(s)); - for (size_t i=0; i(&s); EEPROM.begin(sizeof(s)); - for (size_t i=0; iisRunning()) { strcpy_P(status, PSTR("Playing")); // By default we're OK unless the decoder says otherwise if (!decoder->loop()) { @@ -381,29 +392,28 @@ void PumpDecoder() StopPlaying(); retryms = millis() + 2000; } -} + } } -void loop() -{ +void loop() { static int lastms = 0; - if (millis()-lastms > 1000) { + if (millis() - lastms > 1000) { lastms = millis(); - Serial.printf_P(PSTR("Running for %d seconds%c...Free mem=%d\n"), lastms/1000, !decoder?' ':(decoder->isRunning()?'*':' '), ESP.getFreeHeap()); + Serial.printf_P(PSTR("Running for %d seconds%c...Free mem=%d\n"), lastms / 1000, !decoder ? ' ' : (decoder->isRunning() ? '*' : ' '), MOBO.getFreeHeap()); } - if (retryms && millis()-retryms>0) { + if (retryms && millis() - retryms > 0) { retryms = 0; newUrl = true; } - + if (newUrl) { StartNewURL(); } PumpDecoder(); - + char *reqUrl; char *params; WiFiClient client = server.available(); @@ -438,4 +448,3 @@ void loop() client.stop(); } } - diff --git a/examples/WebRadio/web.cpp b/examples/WebRadio/web.cpp index 75e68739..509ffda6 100644 --- a/examples/WebRadio/web.cpp +++ b/examples/WebRadio/web.cpp @@ -19,10 +19,10 @@ */ #include -#ifdef ESP32 - #include +#ifdef ESP8266 +#include #else - #include +#include #endif #include "web.h" @@ -308,7 +308,3 @@ void Read4Int(char *str, byte *p) str += ParseInt(str, &i); p[2] = i; if (*str) str++; str += ParseInt(str, &i); p[3] = i; } - - - - diff --git a/images/PWM.audio.amplifier.with.only.1.transistor.power.0.when.RX.signal.is.idle.high.pdf b/images/PWM.audio.amplifier.with.only.1.transistor.power.0.when.RX.signal.is.idle.high.pdf new file mode 100644 index 00000000..7923d4cb Binary files /dev/null and b/images/PWM.audio.amplifier.with.only.1.transistor.power.0.when.RX.signal.is.idle.high.pdf differ diff --git a/images/lpf.png b/images/lpf.png new file mode 100644 index 00000000..30023feb Binary files /dev/null and b/images/lpf.png differ diff --git a/keywords.txt b/keywords.txt index 251f431e..a718a06d 100644 --- a/keywords.txt +++ b/keywords.txt @@ -22,6 +22,8 @@ AudioGeneratorWAV KEYWORD1 AudioOutput KEYWORD1 AudioOutputI2S KEYWORD1 AudioOutputI2SNoDAC KEYWORD1 +AudioOutputI2SClass KEYWORD1 +AudioOutputPWM KEYWORD1 AudioOutputNull KEYWORD1 AudioOutputBuffer KEYWORD1 AudioOutputSerialWAV KEYWORD1 diff --git a/lib/install-opus.sh b/lib/install-opus.sh new file mode 100755 index 00000000..23ea8313 --- /dev/null +++ b/lib/install-opus.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +rm -rf libopus +mkdir libopus libopus/include libopus/src libopus/celt libopus/silk libopus/silk/fixed +cp opus/include/*.h libopus/include/. +cp opus.config.h libopus/include/config.h + +celt="arch.h bands.c bands.h celt.c celt_decoder.c celt.h celt_lpc.c celt_lpc.h cpu_support.h cwrs.c cwrs.h ecintrin.h entcode.c entcode.h entdec.c entdec.h entenc.c entenc.h fixed_debug.h fixed_generic.h float_cast.h kiss_fft.c _kiss_fft_guts.h kiss_fft.h laplace.c laplace.h mathops.c mathops.h mdct.c mdct.h mfrngcod.h modes.c modes.h os_support.h pitch.c pitch.h quant_bands.c quant_bands.h rate.c rate.h stack_alloc.h static_modes_fixed.h static_modes_float.h vq.c vq.h" +cd opus/celt +for i in $celt; do + cp -i $i ../../libopus/celt/. +done +incs="config.h opus_custom.h opus_defines.h opus.h opus_multistream.h opus_projection.h opus_types.h" +for i in $incs; do + echo '#include "../include/'$i'"' > ../../libopus/celt/$i +done +sed -i s/HAVE_CONFIG_H/__STDC__/g ../../libopus/celt/*.[ch] + +cd ../silk +silk="A2NLSF.c ana_filt_bank_1.c API.h biquad_alt.c bwexpander_32.c bwexpander.c check_control_input.c CNG.c code_signs.c control_audio_bandwidth.c control_codec.c control.h control_SNR.c debug.c debug.h dec_API.c decode_core.c decode_frame.c decode_indices.c decode_parameters.c decode_pitch.c decode_pulses.c decoder_set_fs.c define.h encode_indices.c encode_pulses.c errors.h gain_quant.c HP_variable_cutoff.c init_decoder.c Inlines.h inner_prod_aligned.c interpolate.c lin2log.c log2lin.c LPC_analysis_filter.c LPC_fit.c LPC_inv_pred_gain.c LP_variable_cutoff.c MacroCount.h MacroDebug.h macros.h main.h NLSF2A.c NLSF_decode.c NLSF_del_dec_quant.c NLSF_encode.c NLSF_stabilize.c NLSF_unpack.c NLSF_VQ.c NLSF_VQ_weights_laroia.c NSQ.h pitch_est_defines.h pitch_est_tables.c PLC.c PLC.h process_NLSFs.c quant_LTP_gains.c resampler.c resampler_down2_3.c resampler_down2.c resampler_private_AR2.c resampler_private_down_FIR.c resampler_private.h resampler_private_IIR_FIR.c resampler_private_up2_HQ.c resampler_rom.c resampler_rom.h resampler_structs.h shell_coder.c sigm_Q15.c SigProc_FIX.h sort.c stereo_decode_pred.c stereo_encode_pred.c stereo_find_predictor.c stereo_LR_to_MS.c stereo_MS_to_LR.c stereo_quant_pred.c structs.h sum_sqr_shift.c table_LSF_cos.c tables_gain.c tables.h tables_LTP.c tables_NLSF_CB_NB_MB.c tables_NLSF_CB_WB.c tables_other.c tables_pitch_lag.c tables_pulses_per_block.c tuning_parameters.h typedef.h VQ_WMat_EC.c" +for i in $silk; do + cp -i $i ../../libopus/silk/. +done +for i in $incs; do + echo '#include "../include/'$i'"' > ../../libopus/silk/$i +done +silkcelt="arch.h celt_lpc.h cpu_support.h ecintrin.h entdec.h entenc.h os_support.h stack_alloc.h" +for i in $silkcelt; do + echo '#include "../celt/'$i'"' > ../../libopus/silk/$i +done +silkfix="main_FIX.h structs_FIX.h" +for i in $silkfix; do + echo '#include "fixed/'$i'"' > ../../libopus/silk/$i +done +sed -i s/HAVE_CONFIG_H/__STDC__/g ../../libopus/silk/*.[ch] + +cd fixed +fixed="apply_sine_window_FIX.c autocorr_FIX.c burg_modified_FIX.c corrMatrix_FIX.c find_LPC_FIX.c find_LTP_FIX.c find_pred_coefs_FIX.c k2a_FIX.c k2a_Q16_FIX.c LTP_analysis_filter_FIX.c LTP_scale_ctrl_FIX.c main_FIX.h process_gains_FIX.c regularize_correlations_FIX.c residual_energy16_FIX.c residual_energy_FIX.c schur64_FIX.c schur_FIX.c structs_FIX.h vector_ops_FIX.c warped_autocorrelation_FIX.c" +for i in $fixed; do + cp -i $i ../../../libopus/silk/fixed/$i +done +incs="config.h" +for i in $incs; do + echo '#include "../../include/'$i'"' > ../../../libopus/silk/fixed/$i +done +fixedcelt="celt_lpc.h entdec.h entenc.h pitch.h stack_alloc.h" +for i in $fixedcelt; do + echo '#include "../../celt/'$i'"' > ../../../libopus/silk/fixed/$i +done +fixedsilk="control.h debug.h define.h main.h pitch_est_defines.h PLC.h SigProc_FIX.h structs.h tuning_parameters.h typedef.h" +for i in $fixedsilk; do + echo '#include "../'$i'"' > ../../../libopus/silk/fixed/$i +done +sed -i s/HAVE_CONFIG_H/__STDC__/g ../../../libopus/silk/fixed/*.[ch] + +cd ../../src +src="opus.c opus_decoder.c opus_private.h" +for i in $src; do + cp -i $i ../../libopus/src/$i +done +incs="config.h opus_custom.h opus_defines.h opus.h opus_multistream.h opus_projection.h opus_types.h" +for i in $incs; do + echo '#include "../include/'$i'"' > ../../libopus/src/$i +done +srccelt="arch.h celt.h cpu_support.h entdec.h float_cast.h mathops.h modes.h os_support.h stack_alloc.h" +for i in $srccelt; do + echo '#include "../celt/'$i'"' > ../../libopus/src/$i +done +srcsilk="API.h define.h structs.h" +for i in $srcsilk; do + echo '#include "../silk/'$i'"' > ../../libopus/src/$i +done +sed -i s/HAVE_CONFIG_H/__STDC__/g ../../libopus/src/*.[ch] + +cd ../ +root="AUTHORS COPYING LICENSE_PLEASE_READ.txt README" +for i in $root; do + cp -i $i ../libopus/. +done + +cd .. +rm -r ../src/libopus +mv libopus ../src/libopus diff --git a/lib/opus b/lib/opus new file mode 160000 index 00000000..ab4e8359 --- /dev/null +++ b/lib/opus @@ -0,0 +1 @@ +Subproject commit ab4e83598e7fc8b2ce82dc633a0fc0c452b629aa diff --git a/lib/opus.config.h b/lib/opus.config.h new file mode 100644 index 00000000..636dca03 --- /dev/null +++ b/lib/opus.config.h @@ -0,0 +1,247 @@ + +// CFLAGS="-m32 -g -O2 -fstack-usage -Wstack-usage=512" CPPFLAGS="-m32 -g -O2 -fstack-usage -Wstack-usage=512" ./configure --prefix=/tmp/opus --disable-float-api --enable-fixed-point --disable-hardening --disable-asm --disable-intrinsics + +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Get CPU Info by asm method */ +/* #undef CPU_INFO_BY_ASM */ + +/* Get CPU Info by c method */ +/* #undef CPU_INFO_BY_C */ + +/* Custom modes */ +/* #undef CUSTOM_MODES */ + +/* Disable DNN debug float */ +#define DISABLE_DEBUG_FLOAT 1 + +/* Disable dot product instructions */ +/* #undef DISABLE_DOT_PROD */ + +/* Do not build the float API */ +#define DISABLE_FLOAT_API 1 + +/* Disable bitstream fixes from RFC 8251 */ +/* #undef DISABLE_UPDATE_DRAFT */ + +/* Assertions */ +/* #undef ENABLE_ASSERTIONS */ + +/* Deep PLC */ +/* #undef ENABLE_DEEP_PLC */ + +/* DRED */ +/* #undef ENABLE_DRED */ + +/* Hardening */ +/* #undef ENABLE_HARDENING */ + +/* LOSSGEN */ +/* #undef ENABLE_LOSSGEN */ + +/* Enable Opus Speech Coding Enhancement */ +/* #undef ENABLE_OSCE */ + +/* Enable dumping of OSCE training data */ +/* #undef ENABLE_OSCE_TRAINING_DATA */ + +/* Debug fixed-point implementation */ +/* #undef FIXED_DEBUG */ + +/* Compile as fixed-point (for machines without a fast enough FPU) */ +#define FIXED_POINT 1 + +/* Float approximations */ +#define FLOAT_APPROX 1 + +/* Fuzzing */ +/* #undef FUZZING */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_ALLOCA_H */ + + +/* NE10 library is installed on host. Make sure it is on target! */ +/* #undef HAVE_ARM_NE10 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `lrint' function. */ +#define HAVE_LRINT 1 + +/* Define to 1 if you have the `lrintf' function. */ +#define HAVE_LRINTF 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `__malloc_hook' function. */ +/* #undef HAVE___MALLOC_HOOK */ + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#define LT_OBJDIR ".libs/" + +/* Make use of ARM asm optimization */ +/* #undef OPUS_ARM_ASM */ + +/* Use generic ARMv4 inline asm optimizations */ +/* #undef OPUS_ARM_INLINE_ASM */ + +/* Use ARMv5E inline asm optimizations */ +/* #undef OPUS_ARM_INLINE_EDSP */ + +/* Use ARMv6 inline asm optimizations */ +/* #undef OPUS_ARM_INLINE_MEDIA */ + +/* Use ARM NEON inline asm optimizations */ +/* #undef OPUS_ARM_INLINE_NEON */ + +/* Compiler supports Aarch64 DOTPROD Intrinsics */ +/* #undef OPUS_ARM_MAY_HAVE_DOTPROD */ + +/* Define if assembler supports EDSP instructions */ +/* #undef OPUS_ARM_MAY_HAVE_EDSP */ + +/* Define if assembler supports ARMv6 media instructions */ +/* #undef OPUS_ARM_MAY_HAVE_MEDIA */ + +/* Define if compiler supports NEON instructions */ +/* #undef OPUS_ARM_MAY_HAVE_NEON */ + +/* Compiler supports ARMv7/Aarch64 Neon Intrinsics */ +/* #undef OPUS_ARM_MAY_HAVE_NEON_INTR */ + +/* Define if binary requires Aarch64 Neon Intrinsics */ +/* #undef OPUS_ARM_PRESUME_AARCH64_NEON_INTR */ + +/* Define if binary requires Aarch64 dotprod Intrinsics */ +/* #undef OPUS_ARM_PRESUME_DOTPROD */ + +/* Define if binary requires EDSP instruction support */ +/* #undef OPUS_ARM_PRESUME_EDSP */ + +/* Define if binary requires ARMv6 media instruction support */ +/* #undef OPUS_ARM_PRESUME_MEDIA */ + +/* Define if binary requires NEON instruction support */ +/* #undef OPUS_ARM_PRESUME_NEON */ + +/* Define if binary requires NEON intrinsics support */ +/* #undef OPUS_ARM_PRESUME_NEON_INTR */ + +/* This is a build of OPUS */ +#define OPUS_BUILD /**/ + +/* Run bit-exactness checks between optimized and c implementations */ +/* #undef OPUS_CHECK_ASM */ + +/* Use run-time CPU capabilities detection */ +/* #undef OPUS_HAVE_RTCD */ + +/* Compiler supports X86 AVX2 Intrinsics */ +/* #undef OPUS_X86_MAY_HAVE_AVX2 */ + +/* Compiler supports X86 SSE Intrinsics */ +/* #undef OPUS_X86_MAY_HAVE_SSE */ + +/* Compiler supports X86 SSE2 Intrinsics */ +/* #undef OPUS_X86_MAY_HAVE_SSE2 */ + +/* Compiler supports X86 SSE4.1 Intrinsics */ +/* #undef OPUS_X86_MAY_HAVE_SSE4_1 */ + +/* Define if binary requires AVX2 intrinsics support */ +/* #undef OPUS_X86_PRESUME_AVX2 */ + +/* Define if binary requires SSE intrinsics support */ +/* #undef OPUS_X86_PRESUME_SSE */ + +/* Define if binary requires SSE2 intrinsics support */ +/* #undef OPUS_X86_PRESUME_SSE2 */ + +/* Define if binary requires SSE4.1 intrinsics support */ +/* #undef OPUS_X86_PRESUME_SSE4_1 */ + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "opus@xiph.org" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "opus" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "opus 1.5.2" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "opus" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "1.5.2" + +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ +#define STDC_HEADERS 1 + +/* Make use of alloca */ +#undef USE_ALLOCA + +/* Use C99 variable-size arrays */ +#define VAR_ARRAYS 1 + +// Enable heap-based stack on Pico. ESP32 should use larger task stack in the sketch +#ifdef ARDUINO_ARCH_RP2040 +#undef VAR_ARRAYS +#define NONTHREADSAFE_PSEUDOSTACK 1 +#endif + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to the equivalent of the C99 'restrict' keyword, or to + nothing if this is not supported. Do not define if restrict is + supported directly. */ +#define restrict __restrict +/* Work around a bug in Sun C++: it does not support _Restrict or + __restrict__, even though the corresponding Sun C compiler ends up with + "#define restrict _Restrict" or "#define restrict __restrict__" in the + previous line. Perhaps some future version of Sun C++ will work with + restrict; if so, hopefully it defines __RESTRICT like Sun C does. */ +#if defined __SUNPRO_CC && !defined __RESTRICT +# define _Restrict +# define __restrict__ +#endif diff --git a/library.json b/library.json index 3cdf7a46..1e7f3023 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP8266Audio", - "description": "Audio file format and I2S DAC library", + "description": "Audio file format and I2S DAC library for ESP8266, ESP32, and Raspberry Pi Pico RP2040", "keywords": "ESP8266, ESP32, MP3, AAC, WAV, MOD, FLAC, RTTTL, MIDI, I2S, DAC, Delta-Sigma, TTS", "authors": [ { @@ -12,15 +12,15 @@ ], "repository": { "type": "git", - "url": "https://github.com/earlephilhower/ESP8266Audio" + "url": "https://github.com/earlephilhower/ESP8266Audio" }, - "version": "1.5.0", + "version": "2.2.0", "homepage": "https://github.com/earlephilhower/ESP8266Audio", - "dependencies": { - "SPI": "1.0" - }, "frameworks": "Arduino", "examples": [ "examples/*/*.ino" - ] -} + ], + "build": { + "libLDFMode": "deep" + } +} \ No newline at end of file diff --git a/library.properties b/library.properties index 0eb36bee..0e4d7c15 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=ESP8266Audio -version=1.5.0 +version=2.2.0 author=Earle F. Philhower, III maintainer=Earle F. Philhower, III -sentence=Audio file and I2S sound playing routines. +sentence=Audio file and I2S sound playing routines for ESP8266, ESP32, and Raspberry Pi Pico RP2040 paragraph=Decode compressed MP3, AAC, FLAC, Screamtracker MOD, MIDI, RTTL, TI Talkie, and WAV and play on an I2S DAC or a software-driven delta-sigma DAC and 1-transistor amplifier. category=Signal Input/Output url=https://github.com/earlephilhower/ESP8266Audio -architectures=esp8266,esp32 +architectures=esp8266,esp32,rp2040 diff --git a/src/AudioFileSource.h b/src/AudioFileSource.h index ea746ef2..f67b2738 100644 --- a/src/AudioFileSource.h +++ b/src/AudioFileSource.h @@ -1,21 +1,21 @@ /* - AudioFileSource - Base class of an input "file" to be used by AudioGenerator - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioFileSource + Base class of an input "file" to be used by AudioGenerator + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOFILESOURCE_H @@ -24,28 +24,53 @@ #include #include "AudioStatus.h" -class AudioFileSource -{ - public: +class AudioFileSource { +public: AudioFileSource() {}; virtual ~AudioFileSource() {}; - virtual bool open(const char *filename) { (void)filename; return false; }; - virtual uint32_t read(void *data, uint32_t len) { (void)data; (void)len; return 0; }; - virtual uint32_t readNonBlock(void *data, uint32_t len) { return read(data, len); }; - virtual bool seek(int32_t pos, int dir) { (void)pos; (void)dir; return false; }; - virtual bool close() { return false; }; - virtual bool isOpen() { return false; }; - virtual uint32_t getSize() { return 0; }; - virtual uint32_t getPos() { return 0; }; - virtual bool loop() { return true; }; - - public: - virtual bool RegisterMetadataCB(AudioStatus::metadataCBFn fn, void *data) { return cb.RegisterMetadataCB(fn, data); } - virtual bool RegisterStatusCB(AudioStatus::statusCBFn fn, void *data) { return cb.RegisterStatusCB(fn, data); } - - protected: + virtual bool open(const char *filename) { + (void)filename; + return false; + }; + virtual uint32_t read(void *data, uint32_t len) { + (void)data; + (void)len; + return 0; + }; + virtual uint32_t readNonBlock(void *data, uint32_t len) { + return read(data, len); + }; + virtual bool seek(int32_t pos, int dir) { + (void)pos; + (void)dir; + return false; + }; + virtual bool close() { + return false; + }; + virtual bool isOpen() { + return false; + }; + virtual uint32_t getSize() { + return 0; + }; + virtual uint32_t getPos() { + return 0; + }; + virtual bool loop() { + return true; + }; + +public: + virtual bool RegisterMetadataCB(AudioStatus::metadataCBFn fn, void *data) { + return cb.RegisterMetadataCB(fn, data); + } + virtual bool RegisterStatusCB(AudioStatus::statusCBFn fn, void *data) { + return cb.RegisterStatusCB(fn, data); + } + +protected: AudioStatus cb; }; #endif - diff --git a/src/AudioFileSourceBuffer.cpp b/src/AudioFileSourceBuffer.cpp index 475f4f9f..5eb6790c 100644 --- a/src/AudioFileSourceBuffer.cpp +++ b/src/AudioFileSourceBuffer.cpp @@ -1,21 +1,21 @@ /* - AudioFileSourceBuffer - Double-buffered file source using system RAM - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioFileSourceBuffer + Double-buffered file source using system RAM + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include @@ -23,168 +23,172 @@ #pragma GCC optimize ("O3") -AudioFileSourceBuffer::AudioFileSourceBuffer(AudioFileSource *source, uint32_t buffSizeBytes) -{ - buffSize = buffSizeBytes; - buffer = (uint8_t*)malloc(sizeof(uint8_t) * buffSize); - if (!buffer) audioLogger->printf_P(PSTR("Unable to allocate AudioFileSourceBuffer::buffer[]\n")); - deallocateBuffer = true; - writePtr = 0; - readPtr = 0; - src = source; - length = 0; - filled = false; +AudioFileSourceBuffer::AudioFileSourceBuffer(AudioFileSource *source, uint32_t buffSizeBytes) { + buffSize = buffSizeBytes; + buffer = (uint8_t*)malloc(sizeof(uint8_t) * buffSize); + if (!buffer) { + audioLogger->printf_P(PSTR("Unable to allocate AudioFileSourceBuffer::buffer[]\n")); + } + deallocateBuffer = true; + writePtr = 0; + readPtr = 0; + src = source; + length = 0; + filled = false; } -AudioFileSourceBuffer::AudioFileSourceBuffer(AudioFileSource *source, void *inBuff, uint32_t buffSizeBytes) -{ - buffSize = buffSizeBytes; - buffer = (uint8_t*)inBuff; - deallocateBuffer = false; - writePtr = 0; - readPtr = 0; - src = source; - length = 0; - filled = false; +AudioFileSourceBuffer::AudioFileSourceBuffer(AudioFileSource *source, void *inBuff, uint32_t buffSizeBytes) { + buffSize = buffSizeBytes; + buffer = (uint8_t*)inBuff; + deallocateBuffer = false; + writePtr = 0; + readPtr = 0; + src = source; + length = 0; + filled = false; } -AudioFileSourceBuffer::~AudioFileSourceBuffer() -{ - if (deallocateBuffer) free(buffer); - buffer = NULL; +AudioFileSourceBuffer::~AudioFileSourceBuffer() { + if (deallocateBuffer) { + free(buffer); + } + buffer = NULL; } -bool AudioFileSourceBuffer::seek(int32_t pos, int dir) -{ - if(dir == SEEK_CUR && (readPtr+pos) < length) { - readPtr += pos; - return true; - } else { - // Invalidate - readPtr = 0; - writePtr = 0; - length = 0; - return src->seek(pos, dir); - } +bool AudioFileSourceBuffer::seek(int32_t pos, int dir) { + if (dir == SEEK_CUR && (readPtr + pos) < length) { + readPtr += pos; + return true; + } else { + // Invalidate + readPtr = 0; + writePtr = 0; + length = 0; + return src->seek(pos, dir); + } } -bool AudioFileSourceBuffer::close() -{ - if (deallocateBuffer) free(buffer); - buffer = NULL; - return src->close(); +bool AudioFileSourceBuffer::close() { + if (deallocateBuffer) { + free(buffer); + } + buffer = NULL; + return src->close(); } -bool AudioFileSourceBuffer::isOpen() -{ - return src->isOpen(); +bool AudioFileSourceBuffer::isOpen() { + return src->isOpen(); } -uint32_t AudioFileSourceBuffer::getSize() -{ - return src->getSize(); +uint32_t AudioFileSourceBuffer::getSize() { + return src->getSize(); } -uint32_t AudioFileSourceBuffer::getPos() -{ - return src->getPos(); +uint32_t AudioFileSourceBuffer::getPos() { + return src->getPos(); } -uint32_t AudioFileSourceBuffer::getFillLevel() -{ - return length; +uint32_t AudioFileSourceBuffer::getFillLevel() { + return length; } -uint32_t AudioFileSourceBuffer::read(void *data, uint32_t len) -{ - if (!buffer) return src->read(data, len); - - uint32_t bytes = 0; - if (!filled) { - // Fill up completely before returning any data at all - cb.st(STATUS_FILLING, PSTR("Refilling buffer")); - length = src->read(buffer, buffSize); - writePtr = length % buffSize; - filled = true; - } - - // Pull from buffer until we've got none left or we've satisfied the request - uint8_t *ptr = reinterpret_cast(data); - uint32_t toReadFromBuffer = (len < length) ? len : length; - if ( (toReadFromBuffer > 0) && (readPtr >= writePtr) ) { - uint32_t toReadToEnd = (toReadFromBuffer < (uint32_t)(buffSize - readPtr)) ? toReadFromBuffer : (buffSize - readPtr); - memcpy(ptr, &buffer[readPtr], toReadToEnd); - readPtr = (readPtr + toReadToEnd) % buffSize; - len -= toReadToEnd; - length -= toReadToEnd; - ptr += toReadToEnd; - bytes += toReadToEnd; - toReadFromBuffer -= toReadToEnd; - } - if (toReadFromBuffer > 0) { // We know RP < WP at this point - memcpy(ptr, &buffer[readPtr], toReadFromBuffer); - readPtr = (readPtr + toReadFromBuffer) % buffSize; - len -= toReadFromBuffer; - length -= toReadFromBuffer; - ptr += toReadFromBuffer; - bytes += toReadFromBuffer; - toReadFromBuffer -= toReadFromBuffer; - } - - if (len) { - // Still need more, try direct read from src - bytes += src->read(ptr, len); - // We're out of buffered data, need to force a complete refill. Thanks, @armSeb - readPtr = 0; - writePtr = 0; - length = 0; - filled = false; - cb.st(STATUS_UNDERFLOW, PSTR("Buffer underflow")); - } +uint32_t AudioFileSourceBuffer::read(void *data, uint32_t len) { + if (!buffer) { + return src->read(data, len); + } - fill(); + uint32_t bytes = 0; + if (!filled) { + // Fill up completely before returning any data at all + cb.st(STATUS_FILLING, PSTR("Refilling buffer")); + length = src->read(buffer, buffSize); + writePtr = length % buffSize; + filled = true; + } - return bytes; -} + // Pull from buffer until we've got none left or we've satisfied the request + uint8_t *ptr = reinterpret_cast(data); + uint32_t toReadFromBuffer = (len < length) ? len : length; + if ((toReadFromBuffer > 0) && (readPtr >= writePtr)) { + uint32_t toReadToEnd = (toReadFromBuffer < (uint32_t)(buffSize - readPtr)) ? toReadFromBuffer : (buffSize - readPtr); + memcpy(ptr, &buffer[readPtr], toReadToEnd); + readPtr = (readPtr + toReadToEnd) % buffSize; + len -= toReadToEnd; + length -= toReadToEnd; + ptr += toReadToEnd; + bytes += toReadToEnd; + toReadFromBuffer -= toReadToEnd; + } + if (toReadFromBuffer > 0) { // We know RP < WP at this point + memcpy(ptr, &buffer[readPtr], toReadFromBuffer); + readPtr = (readPtr + toReadFromBuffer) % buffSize; + len -= toReadFromBuffer; + length -= toReadFromBuffer; + ptr += toReadFromBuffer; + bytes += toReadFromBuffer; + toReadFromBuffer -= toReadFromBuffer; + } -void AudioFileSourceBuffer::fill() -{ - if (!buffer) return; - - if (length < buffSize) { - // Now try and opportunistically fill the buffer - if (readPtr > writePtr) { - if (readPtr == writePtr+1) return; - uint32_t bytesAvailMid = readPtr - writePtr - 1; - int cnt = src->readNonBlock(&buffer[writePtr], bytesAvailMid); - length += cnt; - writePtr = (writePtr + cnt) % buffSize; - return; + if (len) { + // Still need more, try direct read from src + bytes += src->read(ptr, len); + // We're out of buffered data, need to force a complete refill. Thanks, @armSeb + readPtr = 0; + writePtr = 0; + length = 0; + filled = false; + cb.st(STATUS_UNDERFLOW, PSTR("Buffer underflow")); } - if (buffSize > writePtr) { - uint32_t bytesAvailEnd = buffSize - writePtr; - int cnt = src->readNonBlock(&buffer[writePtr], bytesAvailEnd); - length += cnt; - writePtr = (writePtr + cnt) % buffSize; - if (cnt != (int)bytesAvailEnd) return; + fill(); + + return bytes; +} + +void AudioFileSourceBuffer::fill() { + if (!buffer) { + return; } - if (readPtr > 1) { - uint32_t bytesAvailStart = readPtr - 1; - int cnt = src->readNonBlock(&buffer[writePtr], bytesAvailStart); - length += cnt; - writePtr = (writePtr + cnt) % buffSize; + if (length < buffSize) { + // Now try and opportunistically fill the buffer + if (readPtr > writePtr) { + if (readPtr == writePtr + 1) { + return; + } + uint32_t bytesAvailMid = readPtr - writePtr - 1; + int cnt = src->readNonBlock(&buffer[writePtr], bytesAvailMid); + length += cnt; + writePtr = (writePtr + cnt) % buffSize; + return; + } + + if (buffSize > writePtr) { + uint32_t bytesAvailEnd = buffSize - writePtr; + int cnt = src->readNonBlock(&buffer[writePtr], bytesAvailEnd); + length += cnt; + writePtr = (writePtr + cnt) % buffSize; + if (cnt != (int)bytesAvailEnd) { + return; + } + } + + if (readPtr > 1) { + uint32_t bytesAvailStart = readPtr - 1; + int cnt = src->readNonBlock(&buffer[writePtr], bytesAvailStart); + length += cnt; + writePtr = (writePtr + cnt) % buffSize; + } } - } } -bool AudioFileSourceBuffer::loop() -{ - if (!src->loop()) return false; - fill(); - return true; -} +bool AudioFileSourceBuffer::loop() { + if (!src->loop()) { + return false; + } + fill(); + return true; +} diff --git a/src/AudioFileSourceBuffer.h b/src/AudioFileSourceBuffer.h index 6c8dc6c2..43b61011 100644 --- a/src/AudioFileSourceBuffer.h +++ b/src/AudioFileSourceBuffer.h @@ -1,21 +1,21 @@ /* - AudioFileSourceBuffer - Double-buffered input file using system RAM - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioFileSourceBuffer + Double-buffered input file using system RAM + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOFILESOURCEBUFFER_H @@ -24,13 +24,12 @@ #include "AudioFileSource.h" -class AudioFileSourceBuffer : public AudioFileSource -{ - public: +class AudioFileSourceBuffer : public AudioFileSource { +public: AudioFileSourceBuffer(AudioFileSource *in, uint32_t bufferBytes); AudioFileSourceBuffer(AudioFileSource *in, void *buffer, uint32_t bufferBytes); // Pre-allocated buffer by app virtual ~AudioFileSourceBuffer() override; - + virtual uint32_t read(void *data, uint32_t len) override; virtual bool seek(int32_t pos, int dir) override; virtual bool close() override; @@ -41,12 +40,12 @@ class AudioFileSourceBuffer : public AudioFileSource virtual uint32_t getFillLevel(); - enum { STATUS_FILLING=2, STATUS_UNDERFLOW }; + enum { STATUS_FILLING = 2, STATUS_UNDERFLOW }; - private: +private: virtual void fill(); - private: +private: AudioFileSource *src; uint32_t buffSize; uint8_t *buffer; diff --git a/src/AudioFileSourceFATFS.h b/src/AudioFileSourceFATFS.h index 88e43f07..46b24aad 100644 --- a/src/AudioFileSourceFATFS.h +++ b/src/AudioFileSourceFATFS.h @@ -1,21 +1,21 @@ /* - AudioFileSourceFS - Input Arduion "file" to be used by AudioGenerator - - Copyright (C) 2017 Earle F. Philhower, III + AudioFileSourceFS + Input Arduion "file" to be used by AudioGenerator - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + Copyright (C) 2017 Earle F. Philhower, III - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOFILESOURCEFATFS_H @@ -31,27 +31,26 @@ #include "AudioFileSourceFS.h" /* - AudioFileSource for FAT filesystem. - */ -class AudioFileSourceFATFS : public AudioFileSourceFS -{ - public: + AudioFileSource for FAT filesystem. +*/ +class AudioFileSourceFATFS : public AudioFileSourceFS { +public: AudioFileSourceFATFS() : AudioFileSourceFS(FFat) {}; AudioFileSourceFATFS(const char *filename) : AudioFileSourceFS(FFat) { - // We call open() ourselves because calling AudioFileSourceFS(FFat, filename) - // would call the parent open() and we do not want that - open(filename); + // We call open() ourselves because calling AudioFileSourceFS(FFat, filename) + // would call the parent open() and we do not want that + open(filename); }; virtual bool open(const char *filename) override { - // make sure that the FATFS filesystem has been mounted - if (!FFat.begin()) { - audioLogger->printf_P(PSTR("Unable to initialize FATFS filesystem\n")); - return false; - } else { - // now that the fielsystem has been mounted, we can call the regular parent open() function - return AudioFileSourceFS::open(filename); - } + // make sure that the FATFS filesystem has been mounted + if (!FFat.begin()) { + audioLogger->printf_P(PSTR("Unable to initialize FATFS filesystem\n")); + return false; + } else { + // now that the fielsystem has been mounted, we can call the regular parent open() function + return AudioFileSourceFS::open(filename); + } }; // Others are inherited from base diff --git a/src/AudioFileSourceFS.cpp b/src/AudioFileSourceFS.cpp index 05348f59..1ff86be0 100644 --- a/src/AudioFileSourceFS.cpp +++ b/src/AudioFileSourceFS.cpp @@ -1,21 +1,21 @@ /* - AudioFileSourceFS - Input "file" to be used by AudioGenerator - - Copyright (C) 2017 Earle F. Philhower, III + AudioFileSourceFS + Input "file" to be used by AudioGenerator - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + Copyright (C) 2017 Earle F. Philhower, III - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include "AudioFileSourceFS.h" @@ -23,51 +23,47 @@ #include "SPIFFS.h" #endif -AudioFileSourceFS::AudioFileSourceFS(FS &fs, const char *filename) -{ - filesystem = &fs; - open(filename); +AudioFileSourceFS::AudioFileSourceFS(FS &fs, const char *filename) { + filesystem = &fs; + open(filename); } -bool AudioFileSourceFS::open(const char *filename) -{ +bool AudioFileSourceFS::open(const char *filename) { #ifndef ESP32 - filesystem->begin(); + filesystem->begin(); #endif - f = filesystem->open(filename, "r"); - return f; + f = filesystem->open(filename, "r"); + return f; } -AudioFileSourceFS::~AudioFileSourceFS() -{ - if (f) f.close(); +AudioFileSourceFS::~AudioFileSourceFS() { + if (f) { + f.close(); + } } -uint32_t AudioFileSourceFS::read(void *data, uint32_t len) -{ - return f.read(reinterpret_cast(data), len); +uint32_t AudioFileSourceFS::read(void *data, uint32_t len) { + return f.read(reinterpret_cast(data), len); } -bool AudioFileSourceFS::seek(int32_t pos, int dir) -{ - return f.seek(pos, (dir==SEEK_SET)?SeekSet:(dir==SEEK_CUR)?SeekCur:SeekEnd); +bool AudioFileSourceFS::seek(int32_t pos, int dir) { + return f.seek(pos, (dir == SEEK_SET) ? SeekSet : (dir == SEEK_CUR) ? SeekCur : SeekEnd); } -bool AudioFileSourceFS::close() -{ - f.close(); - return true; +bool AudioFileSourceFS::close() { + f.close(); + return true; } -bool AudioFileSourceFS::isOpen() -{ - return f?true:false; +bool AudioFileSourceFS::isOpen() { + return f ? true : false; } -uint32_t AudioFileSourceFS::getSize() -{ - if (!f) return 0; - return f.size(); +uint32_t AudioFileSourceFS::getSize() { + if (!f) { + return 0; + } + return f.size(); } diff --git a/src/AudioFileSourceFS.h b/src/AudioFileSourceFS.h index fea34c29..3c54873a 100644 --- a/src/AudioFileSourceFS.h +++ b/src/AudioFileSourceFS.h @@ -1,21 +1,21 @@ /* - AudioFileSourceFS - Input Arduion "file" to be used by AudioGenerator - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioFileSourceFS + Input Arduion "file" to be used by AudioGenerator + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOFILESOURCEFS_H @@ -26,24 +26,31 @@ #include "AudioFileSource.h" -class AudioFileSourceFS : public AudioFileSource -{ - public: - AudioFileSourceFS(FS &fs) { filesystem = &fs; } - AudioFileSourceFS(FS &fs, const char *filename); +class AudioFileSourceFS : public AudioFileSource { +public: + AudioFileSourceFS(fs::FS &fs) { + filesystem = &fs; + } + AudioFileSourceFS(fs::FS &fs, const char *filename); virtual ~AudioFileSourceFS() override; - + virtual bool open(const char *filename) override; virtual uint32_t read(void *data, uint32_t len) override; virtual bool seek(int32_t pos, int dir) override; virtual bool close() override; virtual bool isOpen() override; virtual uint32_t getSize() override; - virtual uint32_t getPos() override { if (!f) return 0; else return f.position(); }; - - private: - FS *filesystem; - File f; + virtual uint32_t getPos() override { + if (!f) { + return 0; + } else { + return f.position(); + } + }; + +private: + fs::FS *filesystem; + fs::File f; }; diff --git a/src/AudioFileSourceFunction.cpp b/src/AudioFileSourceFunction.cpp new file mode 100644 index 00000000..62db87a8 --- /dev/null +++ b/src/AudioFileSourceFunction.cpp @@ -0,0 +1,153 @@ +/* + AudioFileSourceFunction + Audio output generator which can generate WAV file data from function + + Copyright (C) 2021 Hideaki Tai + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "AudioFileSourceFunction.h" + +AudioFileSourceFunction::AudioFileSourceFunction(float sec, uint16_t channels, uint32_t sample_per_sec, uint16_t bits_per_sample) { + uint32_t bytes_per_sec = sample_per_sec * channels * bits_per_sample / 8; + uint32_t len = uint32_t(sec * (float)bytes_per_sec); + + // RIFF chunk + memcpy(wav_header.riff.chunk_id, "RIFF", 4); + wav_header.riff.chunk_size = 4 // size of riff chunk w/o chunk_id and chunk_size + + 8 + 16 // size of format chunk + + 8 + len; // size of data chunk + memcpy(wav_header.riff.format, "WAVE", 4); + + // format chunk + memcpy(wav_header.format.chunk_id, "fmt ", 4); + wav_header.format.chunk_size = 16; + wav_header.format.format_tag = 0x0001; // PCM + wav_header.format.channels = channels; + wav_header.format.sample_per_sec = sample_per_sec; + wav_header.format.avg_bytes_per_sec = bytes_per_sec; + wav_header.format.block_align = channels * bits_per_sample / 8; + wav_header.format.bits_per_sample = bits_per_sample; + + // data chunk + memcpy(wav_header.data.chunk_id, "data", 4); + wav_header.data.chunk_size = len; + + funcs.reserve(channels); + pos = 0; + size = sizeof(WavHeader) + len; + is_ready = false; + is_unique = false; +} + +AudioFileSourceFunction::~AudioFileSourceFunction() { + close(); +} + +uint32_t AudioFileSourceFunction::read(void* data, uint32_t len) { + // callback size must be 1 or equal to channels + if (!is_ready) { + return 0; + } + + uint8_t* d = reinterpret_cast(data); + uint32_t i = 0; + while (i < len) { + uint32_t p = pos + i; + if (p < sizeof(WavHeader)) { + // header bytes + d[i] = wav_header.bytes[p]; + i += 1; + } else { + // data bytes + float time = (float)(p - sizeof(WavHeader)) / (float)wav_header.format.avg_bytes_per_sec; + float v = funcs[0](time); + for (size_t ch = 0; ch < wav_header.format.channels; ++ch) { + if (!is_unique && ch > 0) { + v = funcs[ch](time); + } + + switch (wav_header.format.bits_per_sample) { + case 8: { + Uint8AndInt8 vs {int8_t(v * (float)0x7F)}; + d[i] = vs.u; + break; + } + case 32: { + Uint8AndInt32 vs {int32_t(v * (float)0x7FFFFFFF)}; + d[i + 0] = vs.u[0]; + d[i + 1] = vs.u[1]; + d[i + 2] = vs.u[2]; + d[i + 3] = vs.u[3]; + break; + } + case 16: + default: { + Uint8AndInt16 vs {int16_t(v * (float)0x7FFF)}; + d[i + 0] = vs.u[0]; + d[i + 1] = vs.u[1]; + break; + } + } + } + i += wav_header.format.block_align; + } + } + pos += i; + return (pos >= size) ? 0 : i; +} + +bool AudioFileSourceFunction::seek(int32_t pos, int dir) { + if (dir == SEEK_SET) { + if (pos < 0 || (uint32_t)pos >= size) { + return false; + } + this->pos = pos; + } else if (dir == SEEK_CUR) { + int32_t p = (int32_t)this->pos + pos; + if (p < 0 || (uint32_t)p >= size) { + return false; + } + this->pos = p; + } else { + int32_t p = (int32_t)this->size + pos; + if (p < 0 || (uint32_t)p >= size) { + return false; + } + this->pos = p; + } + return true; +} + +bool AudioFileSourceFunction::close() { + funcs.clear(); + pos = 0; + size = 0; + is_ready = false; + is_unique = false; + return true; +} + +bool AudioFileSourceFunction::isOpen() { + return is_ready; +} + +uint32_t AudioFileSourceFunction::getSize() { + return size; +} + +uint32_t AudioFileSourceFunction::getPos() { + return pos; +} diff --git a/src/AudioFileSourceFunction.h b/src/AudioFileSourceFunction.h new file mode 100644 index 00000000..a422ccf2 --- /dev/null +++ b/src/AudioFileSourceFunction.h @@ -0,0 +1,119 @@ +/* + AudioFileSourceFunction + Audio output generator which can generate WAV file data from function + + Copyright (C) 2021 Hideaki Tai + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _AUDIOFILESOURCEFUNCTION_H +#define _AUDIOFILESOURCEFUNCTION_H + +#include +#include +#include + +#include "AudioFileSource.h" + +class AudioFileSourceFunction : public AudioFileSource { + union WavHeader { + struct { + // RIFF chunk + struct { + char chunk_id[4]; // "RIFF" + uint32_t chunk_size; // 4 + (8 + sizeof(format_chunk)(16)) + (8 + sizeof(data_chunk)) + char format[4]; // "WAVE" + } riff; + // format chunk + struct { + char chunk_id[4]; // "fmt " + uint32_t chunk_size; // 16 + uint16_t format_tag; // 1: PCM + uint16_t channels; // 1: MONO, 2: STEREO + uint32_t sample_per_sec; // 8000, 11025, 22050, 44100, 48000 + uint32_t avg_bytes_per_sec; // sample_per_sec * channels * bits_per_sample / 8 + uint16_t block_align; // channels * bits_per_sample / 8 + uint16_t bits_per_sample; // 8, 16, 32 + } format; + // data chunk + struct { + char chunk_id[4]; // "data" + uint32_t chunk_size; // num_samples * channels * bytes_per_sample + // audio data follows here... + } data; + }; + uint8_t bytes[44]; + } wav_header; + + union Uint8AndInt8 { + int8_t i; + uint8_t u; + }; + + union Uint8AndInt16 { + int16_t i; + uint8_t u[2]; + }; + + union Uint8AndInt32 { + int32_t i; + uint8_t u[4]; + }; + + using callback_t = std::function; + std::vector funcs; + uint32_t pos; + uint32_t size; + bool is_ready; + bool is_unique; + +public: + AudioFileSourceFunction(float sec, uint16_t channels = 1, uint32_t sample_per_sec = 8000, uint16_t bits_per_sample = 16); + virtual ~AudioFileSourceFunction() override; + + template + bool addAudioGenerators(const F& f, Fs&&... fs) { + funcs.emplace_back(f); + return addAudioGenerators(std::forward(fs)...); + } + bool addAudioGenerators() { + funcs.shrink_to_fit(); + if (funcs.size() == 1) { + is_ready = true; + is_unique = true; + return true; + } else if (funcs.size() == wav_header.format.channels) { + is_ready = true; + is_unique = false; + return true; + } else { + is_ready = false; + is_unique = false; + funcs.clear(); + return false; + } + } + + virtual uint32_t read(void* data, uint32_t len) override; + virtual bool seek(int32_t pos, int dir) override; + + virtual bool close() override; + virtual bool isOpen() override; + + virtual uint32_t getSize() override; + virtual uint32_t getPos() override; +}; + +#endif // _AUDIOFILESOURCEFUNCTION_H diff --git a/src/AudioFileSourceHTTPStream.cpp b/src/AudioFileSourceHTTPStream.cpp index ed659ee5..9fdc7958 100644 --- a/src/AudioFileSourceHTTPStream.cpp +++ b/src/AudioFileSourceHTTPStream.cpp @@ -1,154 +1,156 @@ /* - AudioFileSourceHTTPStream - Streaming HTTP source + AudioFileSourceHTTPStream + Streaming HTTP source - Copyright (C) 2017 Earle F. Philhower, III + Copyright (C) 2017 Earle F. Philhower, III - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include "AudioFileSourceHTTPStream.h" -AudioFileSourceHTTPStream::AudioFileSourceHTTPStream() -{ - pos = 0; - reconnectTries = 0; - saveURL[0] = 0; +AudioFileSourceHTTPStream::AudioFileSourceHTTPStream() { + pos = 0; + reconnectTries = 0; + saveURL[0] = 0; } -AudioFileSourceHTTPStream::AudioFileSourceHTTPStream(const char *url) -{ - saveURL[0] = 0; - reconnectTries = 0; - open(url); +AudioFileSourceHTTPStream::AudioFileSourceHTTPStream(const char *url) { + saveURL[0] = 0; + reconnectTries = 0; + open(url); } -bool AudioFileSourceHTTPStream::open(const char *url) -{ - pos = 0; - http.begin(client, url); - http.setReuse(true); +bool AudioFileSourceHTTPStream::open(const char *url) { + pos = 0; + http.begin(client, url); + http.setReuse(true); #ifndef ESP32 - http.setFollowRedirects(true); + http.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS); #endif - int code = http.GET(); - if (code != HTTP_CODE_OK) { - http.end(); - cb.st(STATUS_HTTPFAIL, PSTR("Can't open HTTP request")); - return false; - } - size = http.getSize(); - strncpy(saveURL, url, sizeof(saveURL)); - saveURL[sizeof(saveURL)-1] = 0; - return true; + int code = http.GET(); + if (code != HTTP_CODE_OK) { + http.end(); + cb.st(STATUS_HTTPFAIL, PSTR("Can't open HTTP request")); + return false; + } + size = http.getSize(); + strncpy(saveURL, url, sizeof(saveURL)); + saveURL[sizeof(saveURL) - 1] = 0; + return true; } -AudioFileSourceHTTPStream::~AudioFileSourceHTTPStream() -{ - http.end(); +AudioFileSourceHTTPStream::~AudioFileSourceHTTPStream() { + http.end(); } -uint32_t AudioFileSourceHTTPStream::read(void *data, uint32_t len) -{ - if (data==NULL) { - audioLogger->printf_P(PSTR("ERROR! AudioFileSourceHTTPStream::read passed NULL data\n")); - return 0; - } - return readInternal(data, len, false); +uint32_t AudioFileSourceHTTPStream::read(void *data, uint32_t len) { + if (data == NULL) { + audioLogger->printf_P(PSTR("ERROR! AudioFileSourceHTTPStream::read passed NULL data\n")); + return 0; + } + return readInternal(data, len, false); } -uint32_t AudioFileSourceHTTPStream::readNonBlock(void *data, uint32_t len) -{ - if (data==NULL) { - audioLogger->printf_P(PSTR("ERROR! AudioFileSourceHTTPStream::readNonBlock passed NULL data\n")); - return 0; - } - return readInternal(data, len, true); +uint32_t AudioFileSourceHTTPStream::readNonBlock(void *data, uint32_t len) { + if (data == NULL) { + audioLogger->printf_P(PSTR("ERROR! AudioFileSourceHTTPStream::readNonBlock passed NULL data\n")); + return 0; + } + return readInternal(data, len, true); } -uint32_t AudioFileSourceHTTPStream::readInternal(void *data, uint32_t len, bool nonBlock) -{ +uint32_t AudioFileSourceHTTPStream::readInternal(void *data, uint32_t len, bool nonBlock) { retry: - if (!http.connected()) { - cb.st(STATUS_DISCONNECTED, PSTR("Stream disconnected")); - http.end(); - for (int i = 0; i < reconnectTries; i++) { - char buff[32]; - sprintf_P(buff, PSTR("Attempting to reconnect, try %d"), i); - cb.st(STATUS_RECONNECTING, buff); - delay(reconnectDelayMs); - if (open(saveURL)) { - cb.st(STATUS_RECONNECTED, PSTR("Stream reconnected")); - break; - } - } if (!http.connected()) { - cb.st(STATUS_DISCONNECTED, PSTR("Unable to reconnect")); - return 0; + cb.st(STATUS_DISCONNECTED, PSTR("Stream disconnected")); + http.end(); + for (int i = 0; i < reconnectTries; i++) { + char buff[64]; + sprintf_P(buff, PSTR("Attempting to reconnect, try %d"), i); + cb.st(STATUS_RECONNECTING, buff); + delay(reconnectDelayMs); + if (open(saveURL)) { + cb.st(STATUS_RECONNECTED, PSTR("Stream reconnected")); + break; + } + } + if (!http.connected()) { + cb.st(STATUS_DISCONNECTED, PSTR("Unable to reconnect")); + return 0; + } + } + if ((size > 0) && (pos >= size)) { + return 0; } - } - if ((size > 0) && (pos >= size)) return 0; - WiFiClient *stream = http.getStreamPtr(); +#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR >= 3 + NetworkClient *stream = http.getStreamPtr(); +#else + WiFiClient *stream = http.getStreamPtr(); +#endif - // Can't read past EOF... - if ( (size > 0) && (len > (uint32_t)(pos - size)) ) len = pos - size; + // Can't read past EOF... + if ((size > 0) && (len > (uint32_t)(pos - size))) { + len = pos - size; + } - if (!nonBlock) { - int start = millis(); - while ((stream->available() < (int)len) && (millis() - start < 500)) yield(); - } + if (!nonBlock) { + int start = millis(); + while ((stream->available() < (int)len) && (millis() - start < 500)) { + yield(); + } + } - size_t avail = stream->available(); - if (!nonBlock && !avail) { - cb.st(STATUS_NODATA, PSTR("No stream data available")); - http.end(); - goto retry; - } - if (avail == 0) return 0; - if (avail < len) len = avail; - - int read = stream->read(reinterpret_cast(data), len); - pos += read; - return read; + size_t avail = stream->available(); + if (!nonBlock && !avail) { + cb.st(STATUS_NODATA, PSTR("No stream data available")); + http.end(); + goto retry; + } + if (avail == 0) { + return 0; + } + if (avail < len) { + len = avail; + } + + int read = stream->read(reinterpret_cast(data), len); + pos += read; + return read; } -bool AudioFileSourceHTTPStream::seek(int32_t pos, int dir) -{ - audioLogger->printf_P(PSTR("ERROR! AudioFileSourceHTTPStream::seek not implemented!")); - (void) pos; - (void) dir; - return false; +bool AudioFileSourceHTTPStream::seek(int32_t pos, int dir) { + audioLogger->printf_P(PSTR("ERROR! AudioFileSourceHTTPStream::seek not implemented!")); + (void) pos; + (void) dir; + return false; } -bool AudioFileSourceHTTPStream::close() -{ - http.end(); - return true; +bool AudioFileSourceHTTPStream::close() { + http.end(); + return true; } -bool AudioFileSourceHTTPStream::isOpen() -{ - return http.connected(); +bool AudioFileSourceHTTPStream::isOpen() { + return http.connected(); } -uint32_t AudioFileSourceHTTPStream::getSize() -{ - return size; +uint32_t AudioFileSourceHTTPStream::getSize() { + return size; } -uint32_t AudioFileSourceHTTPStream::getPos() -{ - return pos; +uint32_t AudioFileSourceHTTPStream::getPos() { + return pos; } diff --git a/src/AudioFileSourceHTTPStream.h b/src/AudioFileSourceHTTPStream.h index e7ef88d1..459827c7 100644 --- a/src/AudioFileSourceHTTPStream.h +++ b/src/AudioFileSourceHTTPStream.h @@ -1,43 +1,41 @@ /* - AudioFileSourceHTTPStream - Connect to a HTTP based streaming service - - Copyright (C) 2017 Earle F. Philhower, III + AudioFileSourceHTTPStream + Connect to a HTTP based streaming service - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + Copyright (C) 2017 Earle F. Philhower, III - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ -#ifndef _AUDIOFILESOURCEHTTPSTREAM_H -#define _AUDIOFILESOURCEHTTPSTREAM_H +#pragma once #include -#ifdef ESP32 - #include +#ifdef ESP8266 +#include #else - #include +#include #endif #include "AudioFileSource.h" -class AudioFileSourceHTTPStream : public AudioFileSource -{ - friend class AudioFileSourceICYStream; +class AudioFileSourceHTTPStream : public AudioFileSource { + friend class AudioFileSourceICYStream; - public: +public: AudioFileSourceHTTPStream(); AudioFileSourceHTTPStream(const char *url); virtual ~AudioFileSourceHTTPStream() override; - + virtual bool open(const char *url) override; virtual uint32_t read(void *data, uint32_t len) override; virtual uint32_t readNonBlock(void *data, uint32_t len) override; @@ -46,13 +44,24 @@ class AudioFileSourceHTTPStream : public AudioFileSource virtual bool isOpen() override; virtual uint32_t getSize() override; virtual uint32_t getPos() override; - bool SetReconnect(int tries, int delayms) { reconnectTries = tries; reconnectDelayMs = delayms; return true; } + bool SetReconnect(int tries, int delayms) { + reconnectTries = tries; + reconnectDelayMs = delayms; + return true; + } + void useHTTP10() { + http.useHTTP10(true); + } - enum { STATUS_HTTPFAIL=2, STATUS_DISCONNECTED, STATUS_RECONNECTING, STATUS_RECONNECTED, STATUS_NODATA }; + enum { STATUS_HTTPFAIL = 2, STATUS_DISCONNECTED, STATUS_RECONNECTING, STATUS_RECONNECTED, STATUS_NODATA }; - private: +private: virtual uint32_t readInternal(void *data, uint32_t len, bool nonBlock); +#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR >= 3 + NetworkClient client; +#else WiFiClient client; +#endif HTTPClient http; int pos; int size; @@ -60,7 +69,3 @@ class AudioFileSourceHTTPStream : public AudioFileSource int reconnectDelayMs; char saveURL[128]; }; - - -#endif - diff --git a/src/AudioFileSourceICYStream.cpp b/src/AudioFileSourceICYStream.cpp index cc7cc5e2..2ca9ad67 100644 --- a/src/AudioFileSourceICYStream.cpp +++ b/src/AudioFileSourceICYStream.cpp @@ -1,213 +1,260 @@ /* - AudioFileSourceICYStream - Streaming Shoutcast ICY source - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioFileSourceICYStream + Streaming Shoutcast ICY source + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifdef _GNU_SOURCE +#undef _GNU_SOURCE +#endif #define _GNU_SOURCE #include "AudioFileSourceICYStream.h" #include -AudioFileSourceICYStream::AudioFileSourceICYStream() -{ - pos = 0; - reconnectTries = 0; - saveURL[0] = 0; +AudioFileSourceICYStream::AudioFileSourceICYStream() { + pos = 0; + reconnectTries = 0; + saveURL[0] = 0; } -AudioFileSourceICYStream::AudioFileSourceICYStream(const char *url) -{ - saveURL[0] = 0; - reconnectTries = 0; - open(url); +AudioFileSourceICYStream::AudioFileSourceICYStream(const char *url) { + saveURL[0] = 0; + reconnectTries = 0; + open(url); } -bool AudioFileSourceICYStream::open(const char *url) -{ - static const char *hdr[] = { "icy-metaint", "icy-name", "icy-genre", "icy-br" }; - pos = 0; - http.begin(client, url); - http.addHeader("Icy-MetaData", "1"); - http.collectHeaders( hdr, 4 ); - http.setReuse(true); - int code = http.GET(); - if (code != HTTP_CODE_OK) { - http.end(); - cb.st(STATUS_HTTPFAIL, PSTR("Can't open HTTP request")); - return false; - } - if (http.hasHeader(hdr[0])) { - String ret = http.header(hdr[0]); - icyMetaInt = ret.toInt(); - } else { - icyMetaInt = 0; - } - if (http.hasHeader(hdr[1])) { - String ret = http.header(hdr[1]); -// cb.md("SiteName", false, ret.c_str()); - } - if (http.hasHeader(hdr[2])) { - String ret = http.header(hdr[2]); -// cb.md("Genre", false, ret.c_str()); - } - if (http.hasHeader(hdr[3])) { - String ret = http.header(hdr[3]); -// cb.md("Bitrate", false, ret.c_str()); - } - - icyByteCount = 0; - size = http.getSize(); - strncpy(saveURL, url, sizeof(saveURL)); - saveURL[sizeof(saveURL)-1] = 0; - return true; -} +bool AudioFileSourceICYStream::open(const char *url) { + static const char *hdr[] = { "icy-metaint", "icy-name", "icy-genre", "icy-br" }; + pos = 0; + http.begin(client, url); + http.addHeader("Icy-MetaData", "1"); + http.collectHeaders(hdr, 4); + http.setReuse(true); + http.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS); + int code = http.GET(); + if (code != HTTP_CODE_OK) { + http.end(); + cb.st(STATUS_HTTPFAIL, PSTR("Can't open HTTP request")); + return false; + } + if (http.hasHeader(hdr[0])) { + String ret = http.header(hdr[0]); + icyMetaInt = ret.toInt(); + } else { + icyMetaInt = 0; + } + if (http.hasHeader(hdr[1])) { + String ret = http.header(hdr[1]); + // cb.md("SiteName", false, ret.c_str()); + } + if (http.hasHeader(hdr[2])) { + String ret = http.header(hdr[2]); + // cb.md("Genre", false, ret.c_str()); + } + if (http.hasHeader(hdr[3])) { + String ret = http.header(hdr[3]); + // cb.md("Bitrate", false, ret.c_str()); + } -AudioFileSourceICYStream::~AudioFileSourceICYStream() -{ - http.end(); + icyByteCount = 0; + size = http.getSize(); + strncpy(saveURL, url, sizeof(saveURL)); + saveURL[sizeof(saveURL) - 1] = 0; + return true; } -uint32_t AudioFileSourceICYStream::readInternal(void *data, uint32_t len, bool nonBlock) -{ -retry: - if (!http.connected()) { - cb.st(STATUS_DISCONNECTED, PSTR("Stream disconnected")); +AudioFileSourceICYStream::~AudioFileSourceICYStream() { http.end(); - for (int i = 0; i < reconnectTries; i++) { - char buff[32]; - sprintf_P(buff, PSTR("Attempting to reconnect, try %d"), i); - cb.st(STATUS_RECONNECTING, buff); - delay(reconnectDelayMs); - if (open(saveURL)) { - cb.st(STATUS_RECONNECTED, PSTR("Stream reconnected")); - break; - } +} + +uint32_t AudioFileSourceICYStream::readInternal(void *data, uint32_t len, bool nonBlock) { + // Ensure we can't possibly read 2 ICY headers in a single go #355 + if (icyMetaInt > 1) { + len = std::min((int)(icyMetaInt >> 1), (int)len); } +retry: if (!http.connected()) { - cb.st(STATUS_DISCONNECTED, PSTR("Unable to reconnect")); - return 0; + cb.st(STATUS_DISCONNECTED, PSTR("Stream disconnected")); + http.end(); + for (int i = 0; i < reconnectTries; i++) { + char buff[64]; + sprintf_P(buff, PSTR("Attempting to reconnect, try %d"), i); + cb.st(STATUS_RECONNECTING, buff); + delay(reconnectDelayMs); + if (open(saveURL)) { + cb.st(STATUS_RECONNECTED, PSTR("Stream reconnected")); + break; + } + } + if (!http.connected()) { + cb.st(STATUS_DISCONNECTED, PSTR("Unable to reconnect")); + return 0; + } + } + if ((size > 0) && (pos >= size)) { + return 0; } - } - if ((size > 0) && (pos >= size)) return 0; - WiFiClient *stream = http.getStreamPtr(); +#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR >= 3 + NetworkClient *stream = http.getStreamPtr(); +#else + WiFiClient *stream = http.getStreamPtr(); +#endif - // Can't read past EOF... - if ( (size > 0) && (len > (uint32_t)(pos - size)) ) len = pos - size; + // Can't read past EOF... + if ((size > 0) && (len > (uint32_t)(pos - size))) { + len = pos - size; + } - if (!nonBlock) { - int start = millis(); - while ((stream->available() < (int)len) && (millis() - start < 500)) yield(); - } + if (!nonBlock) { + int start = millis(); + while ((stream->available() < (int)len) && (millis() - start < 500)) { + yield(); + } + } - size_t avail = stream->available(); - if (!nonBlock && !avail) { - cb.st(STATUS_NODATA, PSTR("No stream data available")); - http.end(); - goto retry; - } - if (avail == 0) return 0; - if (avail < len) len = avail; - - int read = 0; - int ret = 0; - // If the read would hit an ICY block, split it up... - if (((int)(icyByteCount + len) > (int)icyMetaInt) && (icyMetaInt > 0)) { - int beforeIcy = icyMetaInt - icyByteCount; - if (beforeIcy > 0) { - ret = stream->read(reinterpret_cast(data), beforeIcy); - if (ret < 0) ret = 0; - read += ret; - pos += ret; - len -= ret; - data = (void *)(reinterpret_cast(data) + ret); - icyByteCount += ret; - if (ret != beforeIcy) return read; // Partial read + size_t avail = stream->available(); + if (!nonBlock && !avail) { + cb.st(STATUS_NODATA, PSTR("No stream data available")); + http.end(); + goto retry; + } + if (avail == 0) { + return 0; + } + if (avail < len) { + len = avail; } - // ICY MD handling - int mdSize; - uint8_t c; - int mdret = stream->read(&c, 1); - if (mdret==0) return read; - mdSize = c * 16; - if ((mdret == 1) && (mdSize > 0)) { - // This is going to get ugly fast. - char icyBuff[256 + 16 + 1]; - char *readInto = icyBuff + 16; - memset(icyBuff, 0, 16); // Ensure no residual matches occur - while (mdSize) { - int toRead = mdSize > 256 ? 256 : mdSize; - int ret = stream->read((uint8_t*)readInto, toRead); - if (ret < 0) return read; - if (ret == 0) { delay(1); continue; } - mdSize -= ret; - // At this point we have 0...15 = last 15 chars read from prior read plus new data - int end = 16 + ret; // The last byte of valid data - char *header = (char *)memmem((void*)icyBuff, end, (void*)"StreamTitle=", 12); - if (!header) { - // No match, so move the last 16 bytes back to the start and continue - memmove(icyBuff, icyBuff+end-16, 16); - delay(1); - continue; + int read = 0; + int ret = 0; + // If the read would hit an ICY block, split it up... + if (((int)(icyByteCount + len) > (int)icyMetaInt) && (icyMetaInt > 0)) { + int beforeIcy = icyMetaInt - icyByteCount; + if (beforeIcy > 0) { + ret = stream->read(reinterpret_cast(data), beforeIcy); + if (ret < 0) { + ret = 0; + } + read += ret; + pos += ret; + len -= ret; + data = (void *)(reinterpret_cast(data) + ret); + icyByteCount += ret; + if (ret != beforeIcy) { + return read; // Partial read + } } - // Found header, now move it to the front - int lastValidByte = end - (header -icyBuff) + 1; - memmove(icyBuff, header, lastValidByte); - // Now fill the buffer to the end with read data - while (mdSize && lastValidByte < 255) { - int toRead = mdSize > (256 - lastValidByte) ? (256 - lastValidByte) : mdSize; - ret = stream->read((uint8_t*)icyBuff + lastValidByte, toRead); - if (ret==-1) return read; // error - if (ret == 0) { delay(1); continue; } - mdSize -= ret; - lastValidByte += ret; - } - // Buffer now contains StreamTitle=....., parse it - char *p = icyBuff+12; - if (*p=='\'' || *p== '"' ) { - char closing[] = { *p, ';', '\0' }; - char *psz = strstr( p+1, closing ); - if( !psz ) psz = strchr( &icyBuff[13], ';' ); - if( psz ) *psz = '\0'; - p++; - } else { - char *psz = strchr( p, ';' ); - if( psz ) *psz = '\0'; + + // ICY MD handling + int mdSize; + uint8_t c; + int mdret = stream->read(&c, 1); + if (mdret == 0) { + return read; } - cb.md("StreamTitle", false, p); - - // Now skip rest of MD block - while (mdSize) { - int toRead = mdSize > 256 ? 256 : mdSize; - ret = stream->read((uint8_t*)icyBuff, toRead); - if (ret < 0) return read; - if (ret == 0) { delay(1); continue; } - mdSize -= ret; + mdSize = c * 16; + if ((mdret == 1) && (mdSize > 0)) { + // This is going to get ugly fast. + char icyBuff[256 + 16 + 1]; + char *readInto = icyBuff + 16; + memset(icyBuff, 0, 16); // Ensure no residual matches occur + while (mdSize) { + int toRead = mdSize > 256 ? 256 : mdSize; + int ret = stream->read((uint8_t*)readInto, toRead); + if (ret < 0) { + return read; + } + if (ret == 0) { + delay(1); + continue; + } + mdSize -= ret; + // At this point we have 0...15 = last 15 chars read from prior read plus new data + int end = 16 + ret; // The last byte of valid data + char *header = (char *)memmem((void*)icyBuff, end, (void*)"StreamTitle=", 12); + if (!header) { + // No match, so move the last 16 bytes back to the start and continue + memmove(icyBuff, icyBuff + end - 16, 16); + delay(1); + continue; + } + // Found header, now move it to the front + int lastValidByte = end - (header - icyBuff) + 1; + memmove(icyBuff, header, lastValidByte); + // Now fill the buffer to the end with read data + while (mdSize && lastValidByte < 255) { + int toRead = mdSize > (256 - lastValidByte) ? (256 - lastValidByte) : mdSize; + ret = stream->read((uint8_t*)icyBuff + lastValidByte, toRead); + if (ret == -1) { + return read; // error + } + if (ret == 0) { + delay(1); + continue; + } + mdSize -= ret; + lastValidByte += ret; + } + // Buffer now contains StreamTitle=....., parse it + char *p = icyBuff + 12; + if (*p == '\'' || *p == '"') { + char closing[] = { *p, ';', '\0' }; + char *psz = strstr(p + 1, closing); + if (!psz) { + psz = strchr(&icyBuff[13], ';'); + } + if (psz) { + *psz = '\0'; + } + p++; + } else { + char *psz = strchr(p, ';'); + if (psz) { + *psz = '\0'; + } + } + cb.md("StreamTitle", false, p); + + // Now skip rest of MD block + while (mdSize) { + int toRead = mdSize > 256 ? 256 : mdSize; + ret = stream->read((uint8_t*)icyBuff, toRead); + if (ret < 0) { + return read; + } + if (ret == 0) { + delay(1); + continue; + } + mdSize -= ret; + } + } } - } + icyByteCount = 0; } - icyByteCount = 0; - } - - ret = stream->read(reinterpret_cast(data), len); - if (ret < 0) ret = 0; - read += ret; - pos += ret; - icyByteCount += ret; - return read; + + ret = stream->read(reinterpret_cast(data), len); + if (ret < 0) { + ret = 0; + } + read += ret; + pos += ret; + icyByteCount += ret; + return read; } diff --git a/src/AudioFileSourceICYStream.h b/src/AudioFileSourceICYStream.h index 479c16b4..2b210233 100644 --- a/src/AudioFileSourceICYStream.h +++ b/src/AudioFileSourceICYStream.h @@ -1,50 +1,44 @@ /* - AudioFileSourceHTTPStream - Connect to a HTTP based streaming service - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioFileSourceHTTPStream + Connect to a HTTP based streaming service + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ -#ifndef _AUDIOFILESOURCEICYSTREAM_H -#define _AUDIOFILESOURCEICYSTREAM_H +#pragma once #include -#ifdef ESP32 - #include +#ifdef ESP8266 +#include #else - #include +#include #endif #include "AudioFileSourceHTTPStream.h" -class AudioFileSourceICYStream : public AudioFileSourceHTTPStream -{ - public: +class AudioFileSourceICYStream : public AudioFileSourceHTTPStream { +public: AudioFileSourceICYStream(); AudioFileSourceICYStream(const char *url); virtual ~AudioFileSourceICYStream() override; - + virtual bool open(const char *url) override; - private: +private: virtual uint32_t readInternal(void *data, uint32_t len, bool nonBlock) override; int icyMetaInt; int icyByteCount; }; - - -#endif - diff --git a/src/AudioFileSourceID3.cpp b/src/AudioFileSourceID3.cpp index 1723b8d4..b4b89eeb 100644 --- a/src/AudioFileSourceID3.cpp +++ b/src/AudioFileSourceID3.cpp @@ -1,29 +1,28 @@ /* - AudioFileSourceID3 - ID3 filter that extracts any ID3 fields and sends to CB function - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioFileSourceID3 + ID3 filter that extracts any ID3 fields and sends to CB function + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include "AudioFileSourceID3.h" // Handle unsync operation in ID3 with custom class -class AudioFileSourceUnsync : public AudioFileSource -{ - public: +class AudioFileSourceUnsync : public AudioFileSource { +public: AudioFileSourceUnsync(AudioFileSource *src, int len, bool unsync); virtual ~AudioFileSourceUnsync() override; virtual uint32_t read(void *data, uint32_t len) override; @@ -31,235 +30,264 @@ class AudioFileSourceUnsync : public AudioFileSource int getByte(); bool eof(); - private: +private: AudioFileSource *src; int remaining; bool unsync; int savedByte; }; -AudioFileSourceUnsync::AudioFileSourceUnsync(AudioFileSource *src, int len, bool unsync) -{ - this->src = src; - this->remaining = len; - this->unsync = unsync; - this->savedByte = -1; +AudioFileSourceUnsync::AudioFileSourceUnsync(AudioFileSource *src, int len, bool unsync) { + this->src = src; + this->remaining = len; + this->unsync = unsync; + this->savedByte = -1; } -AudioFileSourceUnsync::~AudioFileSourceUnsync() -{ +AudioFileSourceUnsync::~AudioFileSourceUnsync() { } -uint32_t AudioFileSourceUnsync::read(void *data, uint32_t len) -{ - uint32_t bytes = 0; - uint8_t *ptr = reinterpret_cast(data); - - // This is only used during ID3 parsing, so no need to optimize here... - while (len--) { - int b = getByte(); - if (b >= 0) { - *(ptr++) = (uint8_t)b; - bytes++; +uint32_t AudioFileSourceUnsync::read(void *data, uint32_t len) { + uint32_t bytes = 0; + uint8_t *ptr = reinterpret_cast(data); + + // This is only used during ID3 parsing, so no need to optimize here... + while (len--) { + int b = getByte(); + if (b >= 0) { + *(ptr++) = (uint8_t)b; + bytes++; + } } - } - return bytes; + return bytes; } -int AudioFileSourceUnsync::getByte() -{ - // If we're not unsync, just read. - if (!unsync) { - uint8_t c; - if (!remaining) return -1; - remaining--; - if (1 != src->read(&c, 1)) return -1; - return c; - } - - // If we've saved a pre-read character, return it immediately - if (savedByte >= 0) { - int s = savedByte; - savedByte = -1; - return s; - } - - if (remaining <= 0) { - return -1; - } else if (remaining == 1) { - remaining--; - uint8_t c; - if (1 != src->read(&c, 1)) return -1; - else return c; - } else { - uint8_t c; - remaining--; - if (1 != src->read(&c, 1)) return -1; - if (c != 0xff) { - return c; +int AudioFileSourceUnsync::getByte() { + // If we're not unsync, just read. + if (!unsync) { + uint8_t c; + if (!remaining) { + return -1; + } + remaining--; + if (1 != src->read(&c, 1)) { + return -1; + } + return c; } - // Saw 0xff, check next byte. If 0 then eat it, OTW return the 0xff - uint8_t d; - remaining--; - if (1 != src->read(&d, 1)) return c; - if (d != 0x00) { - savedByte = d; + + // If we've saved a pre-read character, return it immediately + if (savedByte >= 0) { + int s = savedByte; + savedByte = -1; + return s; + } + + if (remaining <= 0) { + return -1; + } else if (remaining == 1) { + remaining--; + uint8_t c; + if (1 != src->read(&c, 1)) { + return -1; + } else { + return c; + } + } else { + uint8_t c; + remaining--; + if (1 != src->read(&c, 1)) { + return -1; + } + if (c != 0xff) { + return c; + } + // Saw 0xff, check next byte. If 0 then eat it, OTW return the 0xff + uint8_t d; + remaining--; + if (1 != src->read(&d, 1)) { + return c; + } + if (d != 0x00) { + savedByte = d; + } + return c; } - return c; - } } -bool AudioFileSourceUnsync::eof() -{ - if (remaining<=0) return true; - else return false; +bool AudioFileSourceUnsync::eof() { + if (remaining <= 0) { + return true; + } else { + return false; + } } -AudioFileSourceID3::AudioFileSourceID3(AudioFileSource *src) -{ - this->src = src; - this->checked = false; +AudioFileSourceID3::AudioFileSourceID3(AudioFileSource *src) { + this->src = src; + this->checked = false; } -AudioFileSourceID3::~AudioFileSourceID3() -{ +AudioFileSourceID3::~AudioFileSourceID3() { } -uint32_t AudioFileSourceID3::read(void *data, uint32_t len) -{ - int rev = 0; +uint32_t AudioFileSourceID3::read(void *data, uint32_t len) { + int rev = 0; - if (checked) { - return src->read(data, len); - } - checked = true; - // <10 bytes initial read, not enough space to check header - if (len<10) return src->read(data, len); + if (checked) { + return src->read(data, len); + } + checked = true; + // <10 bytes initial read, not enough space to check header + if (len < 10) { + return src->read(data, len); + } - uint8_t *buff = reinterpret_cast(data); - int ret = src->read(data, 10); - if (ret<10) return ret; + uint8_t *buff = reinterpret_cast(data); + int ret = src->read(data, 10); + if (ret < 10) { + return ret; + } - if ((buff[0]!='I') || (buff[1]!='D') || (buff[2]!='3') || (buff[3]>0x04) || (buff[3]<0x02) || (buff[4]!=0)) { - return 10 + src->read(buff+10, len-10); - } + if ((buff[0] != 'I') || (buff[1] != 'D') || (buff[2] != '3') || (buff[3] > 0x04) || (buff[3] < 0x02) || (buff[4] != 0)) { + cb.md("eof", false, "id3"); + return 10 + src->read(buff + 10, len - 10); + } - rev = buff[3]; - bool unsync = false; - bool exthdr = false; + rev = buff[3]; + bool unsync = false; + bool exthdr = false; - switch(rev) { + switch (rev) { case 2: - unsync = (buff[5] & 0x80); - exthdr = false; - break; + unsync = (buff[5] & 0x80); + exthdr = false; + break; case 3: case 4: - unsync = (buff[5] & 0x80); - exthdr = (buff[5] & 0x40); - break; - }; - - int id3Size = buff[6]; - id3Size = id3Size << 7; - id3Size |= buff[7]; - id3Size = id3Size << 7; - id3Size |= buff[8]; - id3Size = id3Size << 7; - id3Size |= buff[9]; - // Every read from now may be unsync'd - AudioFileSourceUnsync id3(src, id3Size, unsync); - - if (exthdr) { - int ehsz = (id3.getByte()<<24) | (id3.getByte()<<16) | (id3.getByte()<<8) | (id3.getByte()); - for (int j=0; jread(data, len); + do { + unsigned char frameid[4]; + int framesize; + bool compressed; + + frameid[0] = id3.getByte(); + frameid[1] = id3.getByte(); + frameid[2] = id3.getByte(); + if (rev == 2) { + frameid[3] = 0; + } else { + frameid[3] = id3.getByte(); + } + + if (frameid[0] == 0 && frameid[1] == 0 && frameid[2] == 0 && frameid[3] == 0) { + // We're in padding + while (!id3.eof()) { + id3.getByte(); + } + } else { + if (rev == 2) { + framesize = (id3.getByte() << 16) | (id3.getByte() << 8) | (id3.getByte()); + compressed = false; + } else { + framesize = (id3.getByte() << 24) | (id3.getByte() << 16) | (id3.getByte() << 8) | (id3.getByte()); + id3.getByte(); // skip 1st flag + compressed = id3.getByte() & 0x80; + } + if (compressed) { + int decompsize = (id3.getByte() << 24) | (id3.getByte() << 16) | (id3.getByte() << 8) | (id3.getByte()); + // TODO - add libz decompression, for now ignore this one... + (void)decompsize; + for (int j = 0; j < framesize; j++) { + id3.getByte(); + } + } + + // Read the value and send to callback + char value[64]; + uint32_t i; + bool isUnicode = (id3.getByte() == 1) ? true : false; + for (i = 0; i < (uint32_t)framesize - 1; i++) { + if (i < sizeof(value) - 1) { + value[i] = id3.getByte(); + } else { + (void)id3.getByte(); + } + } + value[i < sizeof(value) - 1 ? i : sizeof(value) - 1] = 0; // Terminate the string... + if ((frameid[0] == 'T' && frameid[1] == 'A' && frameid[2] == 'L' && frameid[3] == 'B') || + (frameid[0] == 'T' && frameid[1] == 'A' && frameid[2] == 'L' && rev == 2)) { + cb.md("Album", isUnicode, value); + } else if ((frameid[0] == 'T' && frameid[1] == 'I' && frameid[2] == 'T' && frameid[3] == '2') || + (frameid[0] == 'T' && frameid[1] == 'T' && frameid[2] == '2' && rev == 2)) { + cb.md("Title", isUnicode, value); + } else if ((frameid[0] == 'T' && frameid[1] == 'P' && frameid[2] == 'E' && frameid[3] == '1') || + (frameid[0] == 'T' && frameid[1] == 'P' && frameid[2] == '1' && rev == 2)) { + cb.md("Performer", isUnicode, value); + } else if ((frameid[0] == 'T' && frameid[1] == 'Y' && frameid[2] == 'E' && frameid[3] == 'R') || + (frameid[0] == 'T' && frameid[1] == 'Y' && frameid[2] == 'E' && rev == 2)) { + cb.md("Year", isUnicode, value); + } else if ((frameid[0] == 'T' && frameid[1] == 'R' && frameid[2] == 'C' && frameid[3] == 'K') || + (frameid[0] == 'T' && frameid[1] == 'R' && frameid[2] == 'K' && rev == 2)) { + cb.md("track", isUnicode, value); + } else if ((frameid[0] == 'T' && frameid[1] == 'P' && frameid[2] == 'O' && frameid[3] == 'S') || + (frameid[0] == 'T' && frameid[1] == 'P' && frameid[2] == 'A' && rev == 2)) { + cb.md("Set", isUnicode, value); + } else if ((frameid[0] == 'P' && frameid[1] == 'O' && frameid[2] == 'P' && frameid[3] == 'M') || + (frameid[0] == 'P' && frameid[1] == 'O' && frameid[2] == 'P' && rev == 2)) { + cb.md("Popularimeter", isUnicode, value); + } else if ((frameid[0] == 'T' && frameid[1] == 'C' && frameid[2] == 'M' && frameid[3] == 'P')) { + cb.md("Compilation", isUnicode, value); + } + } + } while (!id3.eof()); + + // use callback function to signal end of tags and beginning of content. + cb.md("eof", false, "id3"); + + // All ID3 processing done, return to main caller + return src->read(data, len); } -bool AudioFileSourceID3::seek(int32_t pos, int dir) -{ - return src->seek(pos, dir); +bool AudioFileSourceID3::seek(int32_t pos, int dir) { + return src->seek(pos, dir); } -bool AudioFileSourceID3::close() -{ - return src->close(); +bool AudioFileSourceID3::close() { + return src->close(); } -bool AudioFileSourceID3::isOpen() -{ - return src->isOpen(); +bool AudioFileSourceID3::isOpen() { + return src->isOpen(); } -uint32_t AudioFileSourceID3::getSize() -{ - return src->getSize(); +uint32_t AudioFileSourceID3::getSize() { + return src->getSize(); } -uint32_t AudioFileSourceID3::getPos() -{ - return src->getPos(); +uint32_t AudioFileSourceID3::getPos() { + return src->getPos(); } diff --git a/src/AudioFileSourceID3.h b/src/AudioFileSourceID3.h index 9d12f296..23f3c301 100644 --- a/src/AudioFileSourceID3.h +++ b/src/AudioFileSourceID3.h @@ -1,21 +1,21 @@ /* - AudioFileSourceID3 - ID3 filter that extracts any ID3 fields and sends to CB function - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioFileSourceID3 + ID3 filter that extracts any ID3 fields and sends to CB function + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOFILESOURCEID3_H @@ -25,12 +25,11 @@ #include "AudioFileSource.h" -class AudioFileSourceID3 : public AudioFileSource -{ - public: +class AudioFileSourceID3 : public AudioFileSource { +public: AudioFileSourceID3(AudioFileSource *src); virtual ~AudioFileSourceID3() override; - + virtual uint32_t read(void *data, uint32_t len) override; virtual bool seek(int32_t pos, int dir) override; virtual bool close() override; @@ -38,7 +37,7 @@ class AudioFileSourceID3 : public AudioFileSource virtual uint32_t getSize() override; virtual uint32_t getPos() override; - private: +private: AudioFileSource *src; bool checked; }; diff --git a/src/AudioFileSourceLittleFS.h b/src/AudioFileSourceLittleFS.h index 27d94bb8..b0bb4ceb 100644 --- a/src/AudioFileSourceLittleFS.h +++ b/src/AudioFileSourceLittleFS.h @@ -1,27 +1,25 @@ /* - AudioFileSourceFS - Input Arduion "file" to be used by AudioGenerator - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ + AudioFileSourceFS + Input Arduion "file" to be used by AudioGenerator + + Copyright (C) 2017 Earle F. Philhower, III -#ifndef _AUDIOFILESOURCESPIFFS_H -#define _AUDIOFILESOURCESPIFFS_H + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. -#ifndef ESP32 // No LittleFS there, yet + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _AUDIOFILESOURCELITTLEFS_H +#define _AUDIOFILESOURCELITTLEFS_H #include #include @@ -29,9 +27,8 @@ #include "AudioFileSource.h" #include "AudioFileSourceFS.h" -class AudioFileSourceLittleFS : public AudioFileSourceFS -{ - public: +class AudioFileSourceLittleFS : public AudioFileSourceFS { +public: AudioFileSourceLittleFS() : AudioFileSourceFS(LittleFS) { }; AudioFileSourceLittleFS(const char *filename) : AudioFileSourceFS(LittleFS, filename) {}; // Others are inherited from base @@ -39,5 +36,3 @@ class AudioFileSourceLittleFS : public AudioFileSourceFS #endif -#endif - diff --git a/src/AudioFileSourcePROGMEM.cpp b/src/AudioFileSourcePROGMEM.cpp index 46427e4b..629fc3db 100644 --- a/src/AudioFileSourcePROGMEM.cpp +++ b/src/AudioFileSourcePROGMEM.cpp @@ -1,99 +1,104 @@ /* - AudioFileSourcePROGMEM - Store a "file" as a PROGMEM array and use it as audio source data - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioFileSourcePROGMEM + Store a "file" as a PROGMEM array and use it as audio source data + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include "AudioFileSourcePROGMEM.h" -AudioFileSourcePROGMEM::AudioFileSourcePROGMEM() -{ - opened = false; - progmemData = NULL; - progmemLen = 0; - filePointer = 0; +AudioFileSourcePROGMEM::AudioFileSourcePROGMEM() { + opened = false; + progmemData = NULL; + progmemLen = 0; + filePointer = 0; } -AudioFileSourcePROGMEM::AudioFileSourcePROGMEM(const void *data, uint32_t len) -{ - open(data, len); +AudioFileSourcePROGMEM::AudioFileSourcePROGMEM(const void *data, uint32_t len) { + open(data, len); } -AudioFileSourcePROGMEM::~AudioFileSourcePROGMEM() -{ +AudioFileSourcePROGMEM::~AudioFileSourcePROGMEM() { } -bool AudioFileSourcePROGMEM::open(const void *data, uint32_t len) -{ - if (!data || !len) return false; +bool AudioFileSourcePROGMEM::open(const void *data, uint32_t len) { + if (!data || !len) { + return false; + } - opened = true; - progmemData = data; - progmemLen = len; - filePointer = 0; - return true; + opened = true; + progmemData = data; + progmemLen = len; + filePointer = 0; + return true; } -uint32_t AudioFileSourcePROGMEM::getSize() -{ - if (!opened) return 0; - return progmemLen; +uint32_t AudioFileSourcePROGMEM::getSize() { + if (!opened) { + return 0; + } + return progmemLen; } -bool AudioFileSourcePROGMEM::isOpen() -{ - return opened; +bool AudioFileSourcePROGMEM::isOpen() { + return opened; } -bool AudioFileSourcePROGMEM::close() -{ - opened = false; - progmemData = NULL; - progmemLen = 0; - filePointer = 0; - return true; -} - -bool AudioFileSourcePROGMEM::seek(int32_t pos, int dir) -{ - if (!opened) return false; - uint32_t newPtr; - switch (dir) { +bool AudioFileSourcePROGMEM::close() { + opened = false; + progmemData = NULL; + progmemLen = 0; + filePointer = 0; + return true; +} + +bool AudioFileSourcePROGMEM::seek(int32_t pos, int dir) { + if (!opened) { + return false; + } + uint32_t newPtr; + switch (dir) { case SEEK_SET: newPtr = pos; break; case SEEK_CUR: newPtr = filePointer + pos; break; case SEEK_END: newPtr = progmemLen - pos; break; default: return false; - } - if (newPtr > progmemLen) return false; - filePointer = newPtr; - return true; + } + if (newPtr > progmemLen) { + return false; + } + filePointer = newPtr; + return true; } -uint32_t AudioFileSourcePROGMEM::read(void *data, uint32_t len) -{ - if (!opened) return 0; - if (filePointer >= progmemLen) return 0; - - uint32_t toRead = progmemLen - filePointer; - if (toRead > len) toRead = len; - - memcpy_P(data, reinterpret_cast(progmemData)+filePointer, toRead); - filePointer += toRead; - return toRead; +uint32_t AudioFileSourcePROGMEM::read(void *data, uint32_t len) { + if (!opened) { + return 0; + } + if (filePointer >= progmemLen) { + return 0; + } + + uint32_t toRead = progmemLen - filePointer; + if (toRead > len) { + toRead = len; + } + + memcpy_P(data, reinterpret_cast(progmemData) + filePointer, toRead); + filePointer += toRead; + return toRead; } diff --git a/src/AudioFileSourcePROGMEM.h b/src/AudioFileSourcePROGMEM.h index cca3cf73..f1f5b90f 100644 --- a/src/AudioFileSourcePROGMEM.h +++ b/src/AudioFileSourcePROGMEM.h @@ -1,21 +1,21 @@ /* - AudioFileSourcePROGMEM - Store a "file" as a PROGMEM array and use it as audio source data - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioFileSourcePROGMEM + Store a "file" as a PROGMEM array and use it as audio source data + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOFILESOURCEPROGMEM_H @@ -23,9 +23,8 @@ #include "AudioFileSource.h" -class AudioFileSourcePROGMEM : public AudioFileSource -{ - public: +class AudioFileSourcePROGMEM : public AudioFileSource { +public: AudioFileSourcePROGMEM(); AudioFileSourcePROGMEM(const void *data, uint32_t len); virtual ~AudioFileSourcePROGMEM() override; @@ -34,11 +33,17 @@ class AudioFileSourcePROGMEM : public AudioFileSource virtual bool close() override; virtual bool isOpen() override; virtual uint32_t getSize() override; - virtual uint32_t getPos() override { if (!opened) return 0; else return filePointer; }; + virtual uint32_t getPos() override { + if (!opened) { + return 0; + } else { + return filePointer; + } + }; bool open(const void *data, uint32_t len); - private: +private: bool opened; const void *progmemData; uint32_t progmemLen; diff --git a/src/AudioFileSourceSD.cpp b/src/AudioFileSourceSD.cpp index 8e1fcfb7..e9caeaac 100644 --- a/src/AudioFileSourceSD.cpp +++ b/src/AudioFileSourceSD.cpp @@ -1,78 +1,80 @@ /* - AudioFileSourceSPIFFS - Input SD card "file" to be used by AudioGenerator - - Copyright (C) 2017 Earle F. Philhower, III + AudioFileSourceSPIFFS + Input SD card "file" to be used by AudioGenerator - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + Copyright (C) 2017 Earle F. Philhower, III - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include "AudioFileSourceSD.h" -AudioFileSourceSD::AudioFileSourceSD() -{ +AudioFileSourceSD::AudioFileSourceSD() { } -AudioFileSourceSD::AudioFileSourceSD(const char *filename) -{ - open(filename); +AudioFileSourceSD::AudioFileSourceSD(const char *filename) { + open(filename); } -bool AudioFileSourceSD::open(const char *filename) -{ - f = SD.open(filename, FILE_READ); - return f; +bool AudioFileSourceSD::open(const char *filename) { + f = SD.open(filename, FILE_READ); + return f; } -AudioFileSourceSD::~AudioFileSourceSD() -{ - if (f) f.close(); +AudioFileSourceSD::~AudioFileSourceSD() { + if (f) { + f.close(); + } } -uint32_t AudioFileSourceSD::read(void *data, uint32_t len) -{ - return f.read(reinterpret_cast(data), len); +uint32_t AudioFileSourceSD::read(void *data, uint32_t len) { + return f.read(reinterpret_cast(data), len); } -bool AudioFileSourceSD::seek(int32_t pos, int dir) -{ - if (!f) return false; - if (dir==SEEK_SET) return f.seek(pos); - else if (dir==SEEK_CUR) return f.seek(f.position() + pos); - else if (dir==SEEK_END) return f.seek(f.size() + pos); - return false; +bool AudioFileSourceSD::seek(int32_t pos, int dir) { + if (!f) { + return false; + } + if (dir == SEEK_SET) { + return f.seek(pos); + } else if (dir == SEEK_CUR) { + return f.seek(f.position() + pos); + } else if (dir == SEEK_END) { + return f.seek(f.size() + pos); + } + return false; } -bool AudioFileSourceSD::close() -{ - f.close(); - return true; +bool AudioFileSourceSD::close() { + f.close(); + return true; } -bool AudioFileSourceSD::isOpen() -{ - return f?true:false; +bool AudioFileSourceSD::isOpen() { + return f ? true : false; } -uint32_t AudioFileSourceSD::getSize() -{ - if (!f) return 0; - return f.size(); +uint32_t AudioFileSourceSD::getSize() { + if (!f) { + return 0; + } + return f.size(); } -uint32_t AudioFileSourceSD::getPos() -{ - if (!f) return 0; - return f.position(); +uint32_t AudioFileSourceSD::getPos() { + if (!f) { + return 0; + } + return f.position(); } diff --git a/src/AudioFileSourceSD.h b/src/AudioFileSourceSD.h index eacd9918..0a6cdb60 100644 --- a/src/AudioFileSourceSD.h +++ b/src/AudioFileSourceSD.h @@ -1,21 +1,21 @@ /* - AudioFileSourceSPIFFS - Input SD card "file" to be used by AudioGenerator - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioFileSourceSPIFFS + Input SD card "file" to be used by AudioGenerator + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOFILESOURCESD_H @@ -25,13 +25,12 @@ #include -class AudioFileSourceSD : public AudioFileSource -{ - public: +class AudioFileSourceSD : public AudioFileSource { +public: AudioFileSourceSD(); AudioFileSourceSD(const char *filename); virtual ~AudioFileSourceSD() override; - + virtual bool open(const char *filename) override; virtual uint32_t read(void *data, uint32_t len) override; virtual bool seek(int32_t pos, int dir) override; @@ -40,7 +39,7 @@ class AudioFileSourceSD : public AudioFileSource virtual uint32_t getSize() override; virtual uint32_t getPos() override; - private: +private: File f; }; diff --git a/src/AudioFileSourceSPIFFS.h b/src/AudioFileSourceSPIFFS.h index 74efefa4..8112db1d 100644 --- a/src/AudioFileSourceSPIFFS.h +++ b/src/AudioFileSourceSPIFFS.h @@ -1,21 +1,21 @@ /* - AudioFileSourceFS - Input Arduion "file" to be used by AudioGenerator - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioFileSourceFS + Input Arduion "file" to be used by AudioGenerator + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOFILESOURCESPIFFS_H @@ -27,9 +27,11 @@ #include "AudioFileSource.h" #include "AudioFileSourceFS.h" -class AudioFileSourceSPIFFS : public AudioFileSourceFS -{ - public: +// Yes, I know SPIFFS is deprecated +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + +class AudioFileSourceSPIFFS : public AudioFileSourceFS { +public: AudioFileSourceSPIFFS() : AudioFileSourceFS(SPIFFS) { }; AudioFileSourceSPIFFS(const char *filename) : AudioFileSourceFS(SPIFFS, filename) {}; // Others are inherited from base diff --git a/src/AudioFileSourceSPIRAMBuffer.cpp b/src/AudioFileSourceSPIRAMBuffer.cpp index fafadcea..ef9456a5 100644 --- a/src/AudioFileSourceSPIRAMBuffer.cpp +++ b/src/AudioFileSourceSPIRAMBuffer.cpp @@ -1,34 +1,35 @@ /* - AudioFileSourceSPIRAMBuffer - Buffered file source in external SPI RAM + AudioFileSourceSPIRAMBuffer + Buffered file source in external SPI RAM - Copyright (C) 2017 Sebastien Decourriere - Based on AudioFileSourceBuffer class from Earle F. Philhower, III + Copyright (C) 2017 Sebastien Decourriere + Based on AudioFileSourceBuffer class from Earle F. Philhower, III - Copyright (C) 2020 Earle F. Philhower, III - Rewritten for speed and functionality + Copyright (C) 2020 Earle F. Philhower, III + Rewritten for speed and functionality - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ +#if defined(ESP32) || defined(ESP8266) + #include #include "AudioFileSourceSPIRAMBuffer.h" #pragma GCC optimize ("O3") -AudioFileSourceSPIRAMBuffer::AudioFileSourceSPIRAMBuffer(AudioFileSource *source, uint8_t csPin, uint32_t buffSizeBytes) -{ +AudioFileSourceSPIRAMBuffer::AudioFileSourceSPIRAMBuffer(AudioFileSource *source, uint8_t csPin, uint32_t buffSizeBytes) { ram.begin(40, csPin); ramSize = buffSizeBytes; writePtr = 0; @@ -38,13 +39,11 @@ AudioFileSourceSPIRAMBuffer::AudioFileSourceSPIRAMBuffer(AudioFileSource *source audioLogger->printf_P(PSTR("SPI RAM buffer size: %u Bytes\n"), ramSize); } -AudioFileSourceSPIRAMBuffer::~AudioFileSourceSPIRAMBuffer() -{ +AudioFileSourceSPIRAMBuffer::~AudioFileSourceSPIRAMBuffer() { ram.end(); } -bool AudioFileSourceSPIRAMBuffer::seek(int32_t pos, int dir) -{ +bool AudioFileSourceSPIRAMBuffer::seek(int32_t pos, int dir) { // Invalidate readPtr = 0; writePtr = 0; @@ -52,28 +51,23 @@ bool AudioFileSourceSPIRAMBuffer::seek(int32_t pos, int dir) return src->seek(pos, dir); } -bool AudioFileSourceSPIRAMBuffer::close() -{ +bool AudioFileSourceSPIRAMBuffer::close() { return src->close(); } -bool AudioFileSourceSPIRAMBuffer::isOpen() -{ +bool AudioFileSourceSPIRAMBuffer::isOpen() { return src->isOpen(); } -uint32_t AudioFileSourceSPIRAMBuffer::getSize() -{ +uint32_t AudioFileSourceSPIRAMBuffer::getSize() { return src->getSize(); } -uint32_t AudioFileSourceSPIRAMBuffer::getPos() -{ +uint32_t AudioFileSourceSPIRAMBuffer::getPos() { return src->getPos() - (writePtr - readPtr); } -uint32_t AudioFileSourceSPIRAMBuffer::read(void *data, uint32_t len) -{ +uint32_t AudioFileSourceSPIRAMBuffer::read(void *data, uint32_t len) { uint32_t bytes = 0; // Check if the buffer isn't empty, otherwise we try to fill completely @@ -88,7 +82,9 @@ uint32_t AudioFileSourceSPIRAMBuffer::read(void *data, uint32_t len) int length = src->read(buffer, toRead); if (length > 0) { #ifdef FAKERAM - for (size_t i=0; i(data); if (toReadFromBuffer > 0) { #ifdef FAKERAM - for (size_t i=0; ireadNonBlock(buffer, sizeof(buffer)); if (cnt) { #ifdef FAKERAM - for (size_t i=0; iloop()) return false; + if (!src->loop()) { + return false; + } fill(); if ((ESP.getCycleCount() - last) > microsecondsToClockCycles(1000000)) { last = ESP.getCycleCount(); - char str[65]; - memset(str, '#', 64); - str[64] = 0; - str[((writePtr - readPtr) * 64)/ramSize] = 0; - cb.st(((writePtr - readPtr) * 100)/ramSize, str); + char str[65]; + memset(str, '#', 64); + str[64] = 0; + str[((writePtr - readPtr) * 64) / ramSize] = 0; + cb.st(((writePtr - readPtr) * 100) / ramSize, str); } return true; } + +#endif diff --git a/src/AudioFileSourceSPIRAMBuffer.h b/src/AudioFileSourceSPIRAMBuffer.h index 19d915f1..1f2053a0 100644 --- a/src/AudioFileSourceSPIRAMBuffer.h +++ b/src/AudioFileSourceSPIRAMBuffer.h @@ -1,26 +1,26 @@ /* - AudioFileSourceSPIRAMBuffer - Buffered file source in external SPI RAM + AudioFileSourceSPIRAMBuffer + Buffered file source in external SPI RAM - Copyright (C) 2017 Sebastien Decourriere - Based on AudioFileSourceBuffer class from Earle F. Philhower, III + Copyright (C) 2017 Sebastien Decourriere + Based on AudioFileSourceBuffer class from Earle F. Philhower, III - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ -#ifndef _AUDIOFILESOURCESPIRAMBUFFER_H -#define _AUDIOFILESOURCESPIRAMBUFFER_H +#if defined(ESP32) || defined(ESP8266) +#pragma once #include "AudioFileSource.h" #include @@ -28,13 +28,12 @@ //#define FAKERAM // #define SPIBUF_DEBUG -class AudioFileSourceSPIRAMBuffer : public AudioFileSource -{ - public: +class AudioFileSourceSPIRAMBuffer : public AudioFileSource { +public: #ifdef FAKERAM AudioFileSourceSPIRAMBuffer(AudioFileSource *in, uint8_t csPin = 15, uint32_t bufferBytes = 2048); #else - AudioFileSourceSPIRAMBuffer(AudioFileSource *in, uint8_t csPin = 15, uint32_t bufferBytes = 128*1024); + AudioFileSourceSPIRAMBuffer(AudioFileSource *in, uint8_t csPin = 15, uint32_t bufferBytes = 128 * 1024); #endif virtual ~AudioFileSourceSPIRAMBuffer() override; @@ -46,10 +45,10 @@ class AudioFileSourceSPIRAMBuffer : public AudioFileSource virtual uint32_t getPos() override; virtual bool loop() override; - private: +private: virtual void fill(); - private: +private: AudioFileSource *src; ESP8266SPIRAM ram; size_t ramSize; diff --git a/src/AudioFileSourceSTDIO.cpp b/src/AudioFileSourceSTDIO.cpp index 75d0cd12..8c8499a6 100644 --- a/src/AudioFileSourceSTDIO.cpp +++ b/src/AudioFileSourceSTDIO.cpp @@ -1,22 +1,22 @@ /* - AudioFileSourceSTDIO - Input STDIO "file" to be used by AudioGenerator - Only for hot-based testing - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioFileSourceSTDIO + Input STDIO "file" to be used by AudioGenerator + Only for hot-based testing + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include @@ -25,73 +25,68 @@ #include "AudioFileSourceSTDIO.h" -AudioFileSourceSTDIO::AudioFileSourceSTDIO() -{ - f = NULL; - srand(time(NULL)); +AudioFileSourceSTDIO::AudioFileSourceSTDIO() { + f = NULL; + srand(time(NULL)); } -AudioFileSourceSTDIO::AudioFileSourceSTDIO(const char *filename) -{ - open(filename); +AudioFileSourceSTDIO::AudioFileSourceSTDIO(const char *filename) { + open(filename); } -bool AudioFileSourceSTDIO::open(const char *filename) -{ - f = fopen(filename, "rb"); - return f; +bool AudioFileSourceSTDIO::open(const char *filename) { + f = fopen(filename, "rb"); + return f; } -AudioFileSourceSTDIO::~AudioFileSourceSTDIO() -{ - if (f) fclose(f); - f = NULL; +AudioFileSourceSTDIO::~AudioFileSourceSTDIO() { + if (f) { + fclose(f); + } + f = NULL; } -uint32_t AudioFileSourceSTDIO::read(void *data, uint32_t len) -{ -// if (rand() % 100 == 69) { // Give 0 data 1% -// printf("0 read\n"); -// len = 0; -// } else if (rand() % 100 == 1) { // Give short reads 1% -// printf("0 read\n"); -// len = 0; -// } - int ret = fread(reinterpret_cast(data), 1, len, f); -// if (ret && rand() % 100 < 5 ) { -// // We're really mean...throw bad data in the mix -// printf("bad data\n"); -// for (int i=0; i<100; i++) -// *(reinterpret_cast(data) + (rand() % ret)) = rand(); -// } - return ret; +uint32_t AudioFileSourceSTDIO::read(void *data, uint32_t len) { + // if (rand() % 100 == 69) { // Give 0 data 1% + // printf("0 read\n"); + // len = 0; + // } else if (rand() % 100 == 1) { // Give short reads 1% + // printf("0 read\n"); + // len = 0; + // } + int ret = fread(reinterpret_cast(data), 1, len, f); + // if (ret && rand() % 100 < 5 ) { + // // We're really mean...throw bad data in the mix + // printf("bad data\n"); + // for (int i=0; i<100; i++) + // *(reinterpret_cast(data) + (rand() % ret)) = rand(); + // } + return ret; } -bool AudioFileSourceSTDIO::seek(int32_t pos, int dir) -{ - return fseek(f, pos, dir); +bool AudioFileSourceSTDIO::seek(int32_t pos, int dir) { + return fseek(f, pos, dir) == 0; } -bool AudioFileSourceSTDIO::close() -{ - fclose(f); - f = NULL; - return true; +bool AudioFileSourceSTDIO::close() { + fclose(f); + f = NULL; + return true; } -bool AudioFileSourceSTDIO::isOpen() -{ - return f?true:false; +bool AudioFileSourceSTDIO::isOpen() { + return f ? true : false; } -uint32_t AudioFileSourceSTDIO::getSize() -{ - if (!f) return 0; - uint32_t p = ftell(f); - fseek(f, 0, SEEK_END); - uint32_t len = ftell(f); - fseek(f, p, SEEK_SET); - return len; +uint32_t AudioFileSourceSTDIO::getSize() { + if (!f) { + return 0; + } + uint32_t p = ftell(f); + fseek(f, 0, SEEK_END); + uint32_t len = ftell(f); + fseek(f, p, SEEK_SET); + return len; } diff --git a/src/AudioFileSourceSTDIO.h b/src/AudioFileSourceSTDIO.h index 46a46813..eaa6001d 100644 --- a/src/AudioFileSourceSTDIO.h +++ b/src/AudioFileSourceSTDIO.h @@ -1,22 +1,22 @@ /* - AudioFileSourceSTDIO - Input SPIFFS "file" to be used by AudioGenerator - Only for host-based testing, not Arduino - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioFileSourceSTDIO + Input SPIFFS "file" to be used by AudioGenerator + Only for host-based testing, not Arduino + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOFILESOURCESTDIO_H @@ -28,22 +28,27 @@ #include "AudioFileSource.h" -class AudioFileSourceSTDIO : public AudioFileSource -{ - public: +class AudioFileSourceSTDIO : public AudioFileSource { +public: AudioFileSourceSTDIO(); AudioFileSourceSTDIO(const char *filename); virtual ~AudioFileSourceSTDIO() override; - + virtual bool open(const char *filename) override; virtual uint32_t read(void *data, uint32_t len) override; virtual bool seek(int32_t pos, int dir) override; virtual bool close() override; virtual bool isOpen() override; virtual uint32_t getSize() override; - virtual uint32_t getPos() override { if (!f) return 0; else return (uint32_t)ftell(f); }; - - private: + virtual uint32_t getPos() override { + if (!f) { + return 0; + } else { + return (uint32_t)ftell(f); + } + }; + +private: FILE *f; }; diff --git a/src/AudioFileStream.cpp b/src/AudioFileStream.cpp index 82c5d503..64051416 100644 --- a/src/AudioFileStream.cpp +++ b/src/AudioFileStream.cpp @@ -2,60 +2,71 @@ #include "AudioFileStream.h" -AudioFileStream::AudioFileStream(AudioFileSource *source, int definedLen) -{ - src = source; - len = definedLen; - ptr = 0; - saved = -1; +AudioFileStream::AudioFileStream(AudioFileSource *source, int definedLen) { + src = source; + len = definedLen; + ptr = 0; + saved = -1; } -AudioFileStream::~AudioFileStream() -{ - // If there's a defined len, read until we're empty - if (len) { - while (ptr++ < len) (void)read(); - } +AudioFileStream::~AudioFileStream() { + // If there's a defined len, read until we're empty + if (len) { + while (ptr++ < len) { + (void)read(); + } + } } -int AudioFileStream::available() -{ - if (saved >= 0) return 1; - else if (len) return ptr - len; - else if (src->getSize()) return (src->getPos() - src->getSize()); - else return 1; +int AudioFileStream::available() { + if (saved >= 0) { + return 1; + } else if (len) { + return ptr - len; + } else if (src->getSize()) { + return (src->getPos() - src->getSize()); + } else { + return 1; + } } -int AudioFileStream::read() -{ - uint8_t c; - int r; - if (ptr >= len) return -1; - ptr++; - if (saved >= 0) { - c = (uint8_t)saved; - saved = -1; - r = 1; - } else { - r = src->read(&c, 1); - } - if (r != 1) return -1; - return (int)c; +int AudioFileStream::read() { + uint8_t c; + int r; + if (ptr >= len) { + return -1; + } + ptr++; + if (saved >= 0) { + c = (uint8_t)saved; + saved = -1; + r = 1; + } else { + r = src->read(&c, 1); + } + if (r != 1) { + return -1; + } + return (int)c; } -int AudioFileStream::peek() -{ - uint8_t c; - if ((ptr+1) >= len) return -1; - if (saved >= 0) return saved; - int r = src->read(&c, 1); - if (r<1) return -1; - saved = c; - return saved; +int AudioFileStream::peek() { + uint8_t c; + if ((ptr + 1) >= len) { + return -1; + } + if (saved >= 0) { + return saved; + } + int r = src->read(&c, 1); + if (r < 1) { + return -1; + } + saved = c; + return saved; } -void AudioFileStream::flush() -{ - /* noop? */ +void AudioFileStream::flush() { + /* noop? */ } diff --git a/src/AudioFileStream.h b/src/AudioFileStream.h index e165751c..f2b5ee79 100644 --- a/src/AudioFileStream.h +++ b/src/AudioFileStream.h @@ -1,21 +1,21 @@ /* - AudioFileStream - Convert an AudioFileSource* to a Stream* - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioFileStream + Convert an AudioFileSource* to a Stream* + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef AUDIOFILESTREAM_H @@ -24,25 +24,27 @@ #include #include "AudioFileSource.h" -class AudioFileStream : public Stream -{ +class AudioFileStream : public Stream { public: - AudioFileStream(AudioFileSource *source, int definedLen); - virtual ~AudioFileStream(); + AudioFileStream(AudioFileSource *source, int definedLen); + virtual ~AudioFileStream(); public: - // Stream interface - see the Arduino library documentation. - virtual int available() override; - virtual int read() override; - virtual int peek() override; - virtual void flush() override; - virtual size_t write(uint8_t x) override { (void)x; return 0; }; + // Stream interface - see the Arduino library documentation. + virtual int available() override; + virtual int read() override; + virtual int peek() override; + virtual void flush() override; + virtual size_t write(uint8_t x) override { + (void)x; + return 0; + }; private: - AudioFileSource *src; - int saved; - int len; - int ptr; + AudioFileSource *src; + int saved; + int len; + int ptr; }; #endif diff --git a/src/AudioGenerator.h b/src/AudioGenerator.h index 889b2285..cda6ba84 100644 --- a/src/AudioGenerator.h +++ b/src/AudioGenerator.h @@ -1,21 +1,21 @@ /* - AudioGenerator - Base class of an audio output generator - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioGenerator + Base class of an audio output generator + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOGENERATOR_H @@ -26,27 +26,44 @@ #include "AudioFileSource.h" #include "AudioOutput.h" -class AudioGenerator -{ - public: - AudioGenerator() { lastSample[0] = 0; lastSample[1] = 0; }; +class AudioGenerator { +public: + AudioGenerator() { + lastSample[0] = 0; + lastSample[1] = 0; + }; virtual ~AudioGenerator() {}; - virtual bool begin(AudioFileSource *source, AudioOutput *output) { (void)source; (void)output; return false; }; - virtual bool loop() { return false; }; - virtual bool stop() { return false; }; - virtual bool isRunning() { return false;}; + virtual bool begin(AudioFileSource *source, AudioOutput *output) { + (void)source; + (void)output; + return false; + }; + virtual bool loop() { + return false; + }; + virtual bool stop() { + return false; + }; + virtual bool isRunning() { + return false; + }; + virtual void desync() { }; - public: - virtual bool RegisterMetadataCB(AudioStatus::metadataCBFn fn, void *data) { return cb.RegisterMetadataCB(fn, data); } - virtual bool RegisterStatusCB(AudioStatus::statusCBFn fn, void *data) { return cb.RegisterStatusCB(fn, data); } +public: + virtual bool RegisterMetadataCB(AudioStatus::metadataCBFn fn, void *data) { + return cb.RegisterMetadataCB(fn, data); + } + virtual bool RegisterStatusCB(AudioStatus::statusCBFn fn, void *data) { + return cb.RegisterStatusCB(fn, data); + } - protected: +protected: bool running; AudioFileSource *file; AudioOutput *output; int16_t lastSample[2]; - protected: +protected: AudioStatus cb; }; diff --git a/src/AudioGeneratorAAC.cpp b/src/AudioGeneratorAAC.cpp index 98f72078..b8848b7d 100644 --- a/src/AudioGeneratorAAC.cpp +++ b/src/AudioGeneratorAAC.cpp @@ -1,214 +1,223 @@ /* - AudioGeneratorAAC - Audio output generator using the Helix AAC decoder - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioGeneratorAAC + Audio output generator using the Helix AAC decoder + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #pragma GCC optimize ("O3") #include "AudioGeneratorAAC.h" -AudioGeneratorAAC::AudioGeneratorAAC() -{ - preallocateSpace = NULL; - preallocateSize = 0; - - running = false; - file = NULL; - output = NULL; - - buff = (uint8_t*)malloc(buffLen); - outSample = (int16_t*)malloc(1024 * 2 * sizeof(uint16_t)); - if (!buff || !outSample) { - audioLogger->printf_P(PSTR("ERROR: Out of memory in AAC\n")); - Serial.flush(); - } - - hAACDecoder = AACInitDecoder(); - if (!hAACDecoder) { - audioLogger->printf_P(PSTR("Out of memory error! hAACDecoder==NULL\n")); - Serial.flush(); - } - - buffValid = 0; - lastFrameEnd = 0; - validSamples = 0; - curSample = 0; - lastRate = 0; - lastChannels = 0; -} +AudioGeneratorAAC::AudioGeneratorAAC() { + preallocateSpace = NULL; + preallocateSize = 0; -AudioGeneratorAAC::AudioGeneratorAAC(void *preallocateData, int preallocateSz) -{ - preallocateSpace = preallocateData; - preallocateSize = preallocateSz; - - running = false; - file = NULL; - output = NULL; - - uint8_t *p = (uint8_t*)preallocateSpace; - buff = (uint8_t*) p; - p += (buffLen + 7) & ~7; - outSample = (int16_t*) p; - p += (1024 * 2 * sizeof(int16_t) + 7) & ~7; - int used = p - (uint8_t*)preallocateSpace; - int availSpace = preallocateSize - used; - if (availSpace < 0 ) { - audioLogger->printf_P(PSTR("ERROR: Out of memory in AAC\n")); - } - - hAACDecoder = AACInitDecoderPre(p, availSpace); - if (!hAACDecoder) { - audioLogger->printf_P(PSTR("Out of memory error! hAACDecoder==NULL\n")); - Serial.flush(); - } - buffValid = 0; - lastFrameEnd = 0; - validSamples = 0; - curSample = 0; - lastRate = 0; - lastChannels = 0; -} + running = false; + file = NULL; + output = NULL; + buff = (uint8_t*)malloc(buffLen); + outSample = (int16_t*)malloc(1024 * 2 * sizeof(uint16_t)); + if (!buff || !outSample) { + audioLogger->printf_P(PSTR("ERROR: Out of memory in AAC\n")); + Serial.flush(); + } + hAACDecoder = AACInitDecoder(); + if (!hAACDecoder) { + audioLogger->printf_P(PSTR("Out of memory error! hAACDecoder==NULL\n")); + Serial.flush(); + } -AudioGeneratorAAC::~AudioGeneratorAAC() -{ - if (!preallocateSpace) { - AACFreeDecoder(hAACDecoder); - free(buff); - free(outSample); - } + buffValid = 0; + lastFrameEnd = 0; + validSamples = 0; + curSample = 0; + lastRate = 0; + lastChannels = 0; } -bool AudioGeneratorAAC::stop() -{ - running = false; - output->stop(); - return file->close(); -} +AudioGeneratorAAC::AudioGeneratorAAC(void *preallocateData, int preallocateSz) { + preallocateSpace = preallocateData; + preallocateSize = preallocateSz; + + running = false; + file = NULL; + output = NULL; + + uint8_t *p = (uint8_t*)preallocateSpace; + buff = (uint8_t*) p; + p += (buffLen + 7) & ~7; + outSample = (int16_t*) p; + p += (1024 * 2 * sizeof(int16_t) + 7) & ~7; + int used = p - (uint8_t*)preallocateSpace; + int availSpace = preallocateSize - used; + if (availSpace < 0) { + audioLogger->printf_P(PSTR("ERROR: Out of memory in AAC\n")); + } -bool AudioGeneratorAAC::isRunning() -{ - return running; + hAACDecoder = AACInitDecoderPre(p, availSpace); + if (!hAACDecoder) { + audioLogger->printf_P(PSTR("Out of memory error! hAACDecoder==NULL\n")); + Serial.flush(); + } + buffValid = 0; + lastFrameEnd = 0; + validSamples = 0; + curSample = 0; + lastRate = 0; + lastChannels = 0; } -bool AudioGeneratorAAC::FillBufferWithValidFrame() -{ - buff[0] = 0; // Destroy any existing sync word @ 0 - int nextSync; - do { - nextSync = AACFindSyncWord(buff + lastFrameEnd, buffValid - lastFrameEnd); - if (nextSync >= 0) nextSync += lastFrameEnd; - lastFrameEnd = 0; - if (nextSync == -1) { - if (buffValid && buff[buffValid-1]==0xff) { // Could be 1st half of syncword, preserve it... - buff[0] = 0xff; - buffValid = file->read(buff+1, buffLen-1); - if (buffValid==0) return false; // No data available, EOF - } else { // Try a whole new buffer - buffValid = file->read(buff, buffLen-1); - if (buffValid==0) return false; // No data available, EOF - } + + +AudioGeneratorAAC::~AudioGeneratorAAC() { + if (!preallocateSpace) { + AACFreeDecoder(hAACDecoder); + free(buff); + free(outSample); } - } while (nextSync == -1); +} - // Move the frame to start at offset 0 in the buffer - buffValid -= nextSync; // Throw out prior to nextSync - memmove(buff, buff+nextSync, buffValid); +bool AudioGeneratorAAC::stop() { + running = false; + output->stop(); + return file->close(); +} - // We have a sync word at 0 now, try and fill remainder of buffer - buffValid += file->read(buff + buffValid, buffLen - buffValid); +bool AudioGeneratorAAC::isRunning() { + return running; +} - return true; +bool AudioGeneratorAAC::FillBufferWithValidFrame() { + buff[0] = 0; // Destroy any existing sync word @ 0 + int nextSync; + do { + nextSync = AACFindSyncWord(buff + lastFrameEnd, buffValid - lastFrameEnd); + if (nextSync >= 0) { + nextSync += lastFrameEnd; + } + lastFrameEnd = 0; + if (nextSync == -1) { + if (buffValid && buff[buffValid - 1] == 0xff) { // Could be 1st half of syncword, preserve it... + buff[0] = 0xff; + buffValid = file->read(buff + 1, buffLen - 1); + if (buffValid == 0) { + return false; // No data available, EOF + } + } else { // Try a whole new buffer + buffValid = file->read(buff, buffLen - 1); + if (buffValid == 0) { + return false; // No data available, EOF + } + } + } + } while (nextSync == -1); + + // Move the frame to start at offset 0 in the buffer + buffValid -= nextSync; // Throw out prior to nextSync + memmove(buff, buff + nextSync, buffValid); + + // We have a sync word at 0 now, try and fill remainder of buffer + buffValid += file->read(buff + buffValid, buffLen - buffValid); + + return true; } -bool AudioGeneratorAAC::loop() -{ - if (!running) goto done; // Nothing to do here! - - // If we've got data, try and pump it out... - while (validSamples) { - lastSample[0] = outSample[curSample*2]; - lastSample[1] = outSample[curSample*2 + 1]; - if (!output->ConsumeSample(lastSample)) goto done; // Can't send, but no error detected - validSamples--; - curSample++; - } - - // No samples available, need to decode a new frame - if (FillBufferWithValidFrame()) { - // buff[0] start of frame, decode it... - unsigned char *inBuff = reinterpret_cast(buff); - int bytesLeft = buffValid; - int ret = AACDecode(hAACDecoder, &inBuff, &bytesLeft, outSample); - if (ret) { - // Error, skip the frame... - char buff[48]; - sprintf_P(buff, PSTR("AAC decode error %d"), ret); - cb.st(ret, buff); +bool AudioGeneratorAAC::loop() { + if (!running) { + goto done; // Nothing to do here! + } + + // If we've got data, try and pump it out... + while (validSamples) { + if (lastChannels == 1) { + lastSample[0] = outSample[curSample]; + lastSample[1] = outSample[curSample]; + } else { + lastSample[0] = outSample[curSample * 2]; + lastSample[1] = outSample[curSample * 2 + 1]; + } + if (!output->ConsumeSample(lastSample)) { + goto done; // Can't send, but no error detected + } + validSamples--; + curSample++; + } + + // No samples available, need to decode a new frame + if (FillBufferWithValidFrame()) { + // buff[0] start of frame, decode it... + unsigned char *inBuff = reinterpret_cast(buff); + int bytesLeft = buffValid; + int ret = AACDecode(hAACDecoder, &inBuff, &bytesLeft, outSample); + if (ret) { + // Error, skip the frame... + char buff[48]; + sprintf_P(buff, PSTR("AAC decode error %d"), ret); + cb.st(ret, buff); + } else { + lastFrameEnd = buffValid - bytesLeft; + AACFrameInfo fi; + AACGetLastFrameInfo(hAACDecoder, &fi); + if ((int)fi.sampRateOut != (int)lastRate) { + output->SetRate(fi.sampRateOut); + lastRate = fi.sampRateOut; + } + if (fi.nChans != lastChannels) { + output->SetChannels(fi.nChans); + lastChannels = fi.nChans; + } + curSample = 0; + validSamples = fi.outputSamps / lastChannels; + } } else { - lastFrameEnd = buffValid - bytesLeft; - AACFrameInfo fi; - AACGetLastFrameInfo(hAACDecoder, &fi); - if ((int)fi.sampRateOut != (int)lastRate) { - output->SetRate(fi.sampRateOut); - lastRate = fi.sampRateOut; - } - if (fi.nChans != lastChannels) { - output->SetChannels(fi.nChans); - lastChannels = fi.nChans; - } - curSample = 0; - validSamples = fi.outputSamps / lastChannels; + running = false; // No more data, we're done here... } - } else { - running = false; // No more data, we're done here... - } done: - file->loop(); - output->loop(); + file->loop(); + output->loop(); - return running; + return running; } -bool AudioGeneratorAAC::begin(AudioFileSource *source, AudioOutput *output) -{ - if (!source) return false; - file = source; - if (!output) return false; - this->output = output; - if (!file->isOpen()) return false; // Error - - output->begin(); - - // AAC always comes out at 16 bits - output->SetBitsPerSample(16); - - - memset(buff, 0, buffLen); - memset(outSample, 0, 1024*2*sizeof(int16_t)); - - - running = true; - - return true; +bool AudioGeneratorAAC::begin(AudioFileSource *source, AudioOutput *output) { + if (!source) { + return false; + } + file = source; + if (!output) { + return false; + } + this->output = output; + if (!file->isOpen()) { + return false; // Error + } + + output->begin(); + + memset(buff, 0, buffLen); + memset(outSample, 0, 1024 * 2 * sizeof(int16_t)); + + + running = true; + + return true; } diff --git a/src/AudioGeneratorAAC.h b/src/AudioGeneratorAAC.h index 2184e7e0..b8ad0b5b 100644 --- a/src/AudioGeneratorAAC.h +++ b/src/AudioGeneratorAAC.h @@ -1,21 +1,21 @@ /* - AudioGeneratorAAC - Audio output generator using the Helix AAC decoder - - Copyright (C) 2017 Earle F. Philhower, III + AudioGeneratorAAC + Audio output generator using the Helix AAC decoder - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + Copyright (C) 2017 Earle F. Philhower, III - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOGENERATORAAC_H @@ -24,9 +24,8 @@ #include "AudioGenerator.h" #include "libhelix-aac/aacdec.h" -class AudioGeneratorAAC : public AudioGenerator -{ - public: +class AudioGeneratorAAC : public AudioGenerator { +public: AudioGeneratorAAC(); AudioGeneratorAAC(void *preallocateData, int preallocateSize); virtual ~AudioGeneratorAAC() override; @@ -35,7 +34,7 @@ class AudioGeneratorAAC : public AudioGenerator virtual bool stop() override; virtual bool isRunning() override; - protected: +protected: void *preallocateSpace; int preallocateSize; diff --git a/src/AudioGeneratorFLAC.cpp b/src/AudioGeneratorFLAC.cpp index 1af00ce3..813e93f3 100644 --- a/src/AudioGeneratorFLAC.cpp +++ b/src/AudioGeneratorFLAC.cpp @@ -1,199 +1,238 @@ /* - AudioGeneratorFLAC - Audio output generator that plays FLAC audio files - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioGeneratorFLAC + Audio output generator that plays FLAC audio files + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include -AudioGeneratorFLAC::AudioGeneratorFLAC() -{ - flac = NULL; - channels = 0; - sampleRate = 0; - bitsPerSample = 0; - buff[0] = NULL; - buff[1] = NULL; - buffPtr = 0; - buffLen = 0; - running = false; +AudioGeneratorFLAC::AudioGeneratorFLAC() { + flac = NULL; + channels = 0; + sampleRate = 0; + bitsPerSample = 0; + buff[0] = NULL; + buff[1] = NULL; + buffPtr = 0; + buffLen = 0; + running = false; } -AudioGeneratorFLAC::~AudioGeneratorFLAC() -{ - if (flac) - FLAC__stream_decoder_delete(flac); - flac = NULL; +AudioGeneratorFLAC::~AudioGeneratorFLAC() { + if (flac) { + FLAC__stream_decoder_delete(flac); + } + flac = NULL; } -bool AudioGeneratorFLAC::begin(AudioFileSource *source, AudioOutput *output) -{ - if (!source) return false; - file = source; - if (!output) return false; - this->output = output; - if (!file->isOpen()) return false; // Error - - flac = FLAC__stream_decoder_new(); - if (!flac) return false; - - (void)FLAC__stream_decoder_set_md5_checking(flac, false); - - FLAC__StreamDecoderInitStatus ret = FLAC__stream_decoder_init_stream(flac, _read_cb, _seek_cb, _tell_cb, _length_cb, _eof_cb, _write_cb, _metadata_cb, _error_cb, reinterpret_cast(this) ); - if (ret != FLAC__STREAM_DECODER_INIT_STATUS_OK) { - FLAC__stream_decoder_delete(flac); - flac = NULL; - return false; - } +bool AudioGeneratorFLAC::begin(AudioFileSource *source, AudioOutput *output) { + if (!source) { + return false; + } + file = source; + if (!output) { + return false; + } + this->output = output; + if (!file->isOpen()) { + return false; // Error + } - output->begin(); - running = true; - return true; -} + flac = FLAC__stream_decoder_new(); + if (!flac) { + return false; + } + + (void)FLAC__stream_decoder_set_md5_checking(flac, false); -bool AudioGeneratorFLAC::loop() -{ - FLAC__bool ret; + FLAC__StreamDecoderInitStatus ret = FLAC__stream_decoder_init_stream(flac, _read_cb, _seek_cb, _tell_cb, _length_cb, _eof_cb, _write_cb, _metadata_cb, _error_cb, reinterpret_cast(this)); + if (ret != FLAC__STREAM_DECODER_INIT_STATUS_OK) { + FLAC__stream_decoder_delete(flac); + flac = NULL; + return false; + } - if (!running) goto done; + output->begin(); + running = true; + lastSample[0] = 0; + lastSample[1] = 0; + channels = 0; + return true; +} - if (!output->ConsumeSample(lastSample)) goto done; // Try and send last buffered sample +bool AudioGeneratorFLAC::loop() { + FLAC__bool ret; - do { - if (buffPtr == buffLen) { - ret = FLAC__stream_decoder_process_single(flac); - if (!ret) { - running = false; + if (!running) { goto done; - } else { - // We might be done... - if (FLAC__stream_decoder_get_state(flac)==FLAC__STREAM_DECODER_END_OF_STREAM) { - running = false; - goto done; - } - unsigned newsr = FLAC__stream_decoder_get_sample_rate(flac); - unsigned newch = FLAC__stream_decoder_get_channels(flac); - unsigned newbps = FLAC__stream_decoder_get_bits_per_sample(flac); - if (newsr != sampleRate) output->SetRate(sampleRate = newsr); - if (newch != channels) output->SetChannels(channels = newch); - if (newbps != bitsPerSample) output->SetBitsPerSample( bitsPerSample = newbps); - } } - // Check for some weird case where above didn't give any data - if (buffPtr == buffLen) { - goto done; // At some point the flac better error and we'll return - } - if (bitsPerSample <= 16) { - lastSample[AudioOutput::LEFTCHANNEL] = buff[0][buffPtr] & 0xffff; - if (channels==2) lastSample[AudioOutput::RIGHTCHANNEL] = buff[1][buffPtr] & 0xffff; - else lastSample[AudioOutput::RIGHTCHANNEL] = lastSample[AudioOutput::LEFTCHANNEL]; - } else if (bitsPerSample <= 24) { - lastSample[AudioOutput::LEFTCHANNEL] = (buff[0][buffPtr]>>8) & 0xffff; - if (channels==2) lastSample[AudioOutput::RIGHTCHANNEL] = (buff[1][buffPtr]>>8) & 0xffff; - else lastSample[AudioOutput::RIGHTCHANNEL] = lastSample[AudioOutput::LEFTCHANNEL]; - } else { - lastSample[AudioOutput::LEFTCHANNEL] = (buff[0][buffPtr]>>16) & 0xffff; - if (channels==2) lastSample[AudioOutput::RIGHTCHANNEL] = (buff[1][buffPtr]>>16) & 0xffff; - else lastSample[AudioOutput::RIGHTCHANNEL] = lastSample[AudioOutput::LEFTCHANNEL]; + if (channels && !output->ConsumeSample(lastSample)) { + goto done; // Try and send last buffered sample } - buffPtr++; - } while (running && output->ConsumeSample(lastSample)); + + do { + if (buffPtr == buffLen) { + ret = FLAC__stream_decoder_process_single(flac); + if (!ret) { + running = false; + goto done; + } else { + // We might be done... + if (FLAC__stream_decoder_get_state(flac) == FLAC__STREAM_DECODER_END_OF_STREAM) { + running = false; + goto done; + } + unsigned newsr = FLAC__stream_decoder_get_sample_rate(flac); + unsigned newch = FLAC__stream_decoder_get_channels(flac); + unsigned newbps = FLAC__stream_decoder_get_bits_per_sample(flac); + if (newsr != sampleRate) { + output->SetRate(sampleRate = newsr); + } + if (newch != channels) { + output->SetChannels(channels = newch); + } + if (newbps != bitsPerSample) { + bitsPerSample = newbps; + } + } + } + + // Check for some weird case where above didn't give any data + if (buffPtr == buffLen) { + goto done; // At some point the flac better error and we'll return + } + if (bitsPerSample <= 8) { + lastSample[AudioOutput::LEFTCHANNEL] = buff[0][buffPtr] & 0xffff; + if (channels == 2) { + lastSample[AudioOutput::RIGHTCHANNEL] = buff[1][buffPtr] & 0xffff; + } else { + lastSample[AudioOutput::RIGHTCHANNEL] = lastSample[AudioOutput::LEFTCHANNEL]; + } + // Upsample from unsigned 8 bits to signed 16 bits + lastSample[AudioOutput::LEFTCHANNEL] = (((int16_t)(lastSample[AudioOutput::LEFTCHANNEL] & 0xff)) - 128) << 8; + lastSample[AudioOutput::RIGHTCHANNEL] = (((int16_t)(lastSample[AudioOutput::RIGHTCHANNEL] & 0xff)) - 128) << 8; + } else if (bitsPerSample <= 16) { + lastSample[AudioOutput::LEFTCHANNEL] = buff[0][buffPtr] & 0xffff; + if (channels == 2) { + lastSample[AudioOutput::RIGHTCHANNEL] = buff[1][buffPtr] & 0xffff; + } else { + lastSample[AudioOutput::RIGHTCHANNEL] = lastSample[AudioOutput::LEFTCHANNEL]; + } + } else if (bitsPerSample <= 24) { + lastSample[AudioOutput::LEFTCHANNEL] = (buff[0][buffPtr] >> 8) & 0xffff; + if (channels == 2) { + lastSample[AudioOutput::RIGHTCHANNEL] = (buff[1][buffPtr] >> 8) & 0xffff; + } else { + lastSample[AudioOutput::RIGHTCHANNEL] = lastSample[AudioOutput::LEFTCHANNEL]; + } + } else { + lastSample[AudioOutput::LEFTCHANNEL] = (buff[0][buffPtr] >> 16) & 0xffff; + if (channels == 2) { + lastSample[AudioOutput::RIGHTCHANNEL] = (buff[1][buffPtr] >> 16) & 0xffff; + } else { + lastSample[AudioOutput::RIGHTCHANNEL] = lastSample[AudioOutput::LEFTCHANNEL]; + } + } + buffPtr++; + } while (running && output->ConsumeSample(lastSample)); done: - file->loop(); - output->loop(); + file->loop(); + output->loop(); - return running; + return running; } -bool AudioGeneratorFLAC::stop() -{ - if (flac) - FLAC__stream_decoder_delete(flac); - flac = NULL; - running = false; - output->stop(); - return true; +bool AudioGeneratorFLAC::stop() { + if (flac) { + FLAC__stream_decoder_delete(flac); + } + flac = NULL; + running = false; + output->stop(); + return true; } -bool AudioGeneratorFLAC::isRunning() -{ - return running; +bool AudioGeneratorFLAC::isRunning() { + return running; } -FLAC__StreamDecoderReadStatus AudioGeneratorFLAC::read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes) -{ - (void) decoder; - if (*bytes==0) return FLAC__STREAM_DECODER_READ_STATUS_ABORT; - *bytes = file->read(buffer, sizeof(FLAC__byte) * (*bytes)); - if (*bytes==0) return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; - return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; +FLAC__StreamDecoderReadStatus AudioGeneratorFLAC::read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes) { + (void) decoder; + if (*bytes == 0) { + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + } + *bytes = file->read(buffer, sizeof(FLAC__byte) * (*bytes)); + if (*bytes == 0) { + return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; + } + return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; } -FLAC__StreamDecoderSeekStatus AudioGeneratorFLAC::seek_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset) -{ - (void) decoder; - if (!file->seek((int32_t)absolute_byte_offset, 0)) return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; - return FLAC__STREAM_DECODER_SEEK_STATUS_OK; +FLAC__StreamDecoderSeekStatus AudioGeneratorFLAC::seek_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset) { + (void) decoder; + if (!file->seek((int32_t)absolute_byte_offset, 0)) { + return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; + } + return FLAC__STREAM_DECODER_SEEK_STATUS_OK; } -FLAC__StreamDecoderTellStatus AudioGeneratorFLAC::tell_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset) -{ - (void) decoder; - *absolute_byte_offset = file->getPos(); - return FLAC__STREAM_DECODER_TELL_STATUS_OK; +FLAC__StreamDecoderTellStatus AudioGeneratorFLAC::tell_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset) { + (void) decoder; + *absolute_byte_offset = file->getPos(); + return FLAC__STREAM_DECODER_TELL_STATUS_OK; } -FLAC__StreamDecoderLengthStatus AudioGeneratorFLAC::length_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length) -{ - (void) decoder; - *stream_length = file->getSize(); - return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; +FLAC__StreamDecoderLengthStatus AudioGeneratorFLAC::length_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length) { + (void) decoder; + *stream_length = file->getSize(); + return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; } -FLAC__bool AudioGeneratorFLAC::eof_cb(const FLAC__StreamDecoder *decoder) -{ - (void) decoder; - if (file->getPos() >= file->getSize()) return true; - return false; +FLAC__bool AudioGeneratorFLAC::eof_cb(const FLAC__StreamDecoder *decoder) { + (void) decoder; + if (file->getPos() >= file->getSize()) { + return true; + } + return false; } -FLAC__StreamDecoderWriteStatus AudioGeneratorFLAC::write_cb(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[]) -{ - (void) decoder; - // Hackish warning here. FLAC sends the buffer but doesn't free it until the next call to decode_frame, so we stash - // the pointers here and use it in our loop() instead of memcpy()'ing into yet another buffer. - buffLen = frame->header.blocksize; - buff[0] = buffer[0]; - if (frame->header.channels>1) buff[1] = buffer[1]; - else buff[1] = buffer[0]; - buffPtr = 0; - return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; +FLAC__StreamDecoderWriteStatus AudioGeneratorFLAC::write_cb(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[]) { + (void) decoder; + // Hackish warning here. FLAC sends the buffer but doesn't free it until the next call to decode_frame, so we stash + // the pointers here and use it in our loop() instead of memcpy()'ing into yet another buffer. + buffLen = frame->header.blocksize; + buff[0] = (const int *)buffer[0]; + if (frame->header.channels > 1) { + buff[1] = (const int *)buffer[1]; + } else { + buff[1] = (const int *)buffer[0]; + } + buffPtr = 0; + return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } -void AudioGeneratorFLAC::metadata_cb(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata) -{ - (void) decoder; - (void) metadata; - audioLogger->printf_P(PSTR("Metadata\n")); +void AudioGeneratorFLAC::metadata_cb(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata) { + (void) decoder; + (void) metadata; + audioLogger->printf_P(PSTR("Metadata\n")); } char AudioGeneratorFLAC::error_cb_str[64]; -void AudioGeneratorFLAC::error_cb(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status) -{ - (void) decoder; - strncpy_P(error_cb_str, FLAC__StreamDecoderErrorStatusString[status], 64); - cb.st((int)status, error_cb_str); +void AudioGeneratorFLAC::error_cb(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status) { + (void) decoder; + strncpy_P(error_cb_str, FLAC__StreamDecoderErrorStatusString[status], sizeof(AudioGeneratorFLAC::error_cb_str) - 1); + cb.st((int)status, error_cb_str); } diff --git a/src/AudioGeneratorFLAC.h b/src/AudioGeneratorFLAC.h index 716cd0c1..7ba505b7 100644 --- a/src/AudioGeneratorFLAC.h +++ b/src/AudioGeneratorFLAC.h @@ -1,21 +1,21 @@ /* - AudioGeneratorFLAC - Audio output generator that plays FLAC audio files - - Copyright (C) 2017 Earle F. Philhower, III + AudioGeneratorFLAC + Audio output generator that plays FLAC audio files - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + Copyright (C) 2017 Earle F. Philhower, III - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOGENERATORFLAC_H @@ -23,12 +23,11 @@ #include extern "C" { - #include "libflac/FLAC/stream_decoder.h" +#include "libflac/FLAC/stream_decoder.h" }; -class AudioGeneratorFLAC : public AudioGenerator -{ - public: +class AudioGeneratorFLAC : public AudioGenerator { +public: AudioGeneratorFLAC(); virtual ~AudioGeneratorFLAC() override; virtual bool begin(AudioFileSource *source, AudioOutput *output) override; @@ -36,7 +35,7 @@ class AudioGeneratorFLAC : public AudioGenerator virtual bool stop() override; virtual bool isRunning() override; - protected: +protected: // FLAC info uint16_t channels; uint32_t sampleRate; @@ -50,28 +49,28 @@ class AudioGeneratorFLAC : public AudioGenerator // FLAC callbacks, need static functions to bounce into c++ from c static FLAC__StreamDecoderReadStatus _read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) { - return static_cast(client_data)->read_cb(decoder, buffer, bytes); + return static_cast(client_data)->read_cb(decoder, buffer, bytes); }; static FLAC__StreamDecoderSeekStatus _seek_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) { - return static_cast(client_data)->seek_cb(decoder, absolute_byte_offset); + return static_cast(client_data)->seek_cb(decoder, absolute_byte_offset); }; static FLAC__StreamDecoderTellStatus _tell_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) { - return static_cast(client_data)->tell_cb(decoder, absolute_byte_offset); + return static_cast(client_data)->tell_cb(decoder, absolute_byte_offset); }; static FLAC__StreamDecoderLengthStatus _length_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) { - return static_cast(client_data)->length_cb(decoder, stream_length); + return static_cast(client_data)->length_cb(decoder, stream_length); }; static FLAC__bool _eof_cb(const FLAC__StreamDecoder *decoder, void *client_data) { - return static_cast(client_data)->eof_cb(decoder); + return static_cast(client_data)->eof_cb(decoder); }; static FLAC__StreamDecoderWriteStatus _write_cb(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data) { - return static_cast(client_data)->write_cb(decoder, frame, buffer); + return static_cast(client_data)->write_cb(decoder, frame, buffer); }; static void _metadata_cb(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) { - static_cast(client_data)->metadata_cb(decoder, metadata); + static_cast(client_data)->metadata_cb(decoder, metadata); }; static void _error_cb(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) { - static_cast(client_data)->error_cb(decoder, status); + static_cast(client_data)->error_cb(decoder, status); }; // Actual FLAC callbacks FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes); diff --git a/src/AudioGeneratorMIDI.cpp b/src/AudioGeneratorMIDI.cpp index e3be2b2d..06e9e82e 100644 --- a/src/AudioGeneratorMIDI.cpp +++ b/src/AudioGeneratorMIDI.cpp @@ -1,63 +1,67 @@ /* - AudioGeneratorMIDI - Audio output generator that plays MIDI files using a SF2 SoundFont - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioGeneratorMIDI + Audio output generator that plays MIDI files using an SF2 SoundFont + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ /* - The MIDI processing engine is a heavily modified version of MIDITONES, - by Len Shustek, https://github.com/LenShustek/miditones . - Whereas MIDITONES original simply parsed a file beforehand to a byte - stream to be played by another program, this does the parsing and - playback in real-time. - - Here's his original header/readme w/MIT license, which is subsumed by the - GPL license of the ESP8266Audio project. + The MIDI processing engine is a heavily modified version of MIDITONES, + by Len Shustek, https://github.com/LenShustek/miditones . + Whereas MIDITONES original simply parsed a file beforehand to a byte + stream to be played by another program, this does the parsing and + playback in real-time. + + Here's his original header/readme w/MIT license, which is subsumed by the + GPL license of the ESP8266Audio project. */ /*************************************************************************** - MIDITONES: Convert a MIDI file into a simple bytestream of notes + MIDITONES: Convert a MIDI file into a simple bytestream of notes - ------------------------------------------------------------------------- - The MIT License (MIT) - Copyright (c) 2011,2013,2015,2016, Len Shustek + ------------------------------------------------------------------------- + The MIT License (MIT) + Copyright (c) 2011,2013,2015,2016, Len Shustek - 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: + 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 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. + 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. **************************************************************************/ #include "AudioGeneratorMIDI.h" +#if defined(ESP32) && (__GNUC__ >= 8) && (__XTENSA__) +// Do not build, Espressif's GCC8+ has a compiler bug +#else // __GNUC__ == 8 + #pragma GCC optimize ("O3") #define TSF_NO_STDIO @@ -68,572 +72,594 @@ /* announce a fatal MIDI file format error */ -void AudioGeneratorMIDI::midi_error(const char *msg, int curpos) -{ - cb.st(curpos, msg); +void AudioGeneratorMIDI::midi_error(const char *msg, int curpos) { + cb.st(curpos, msg); #if 0 - int ptr; - audioLogger->printf("---> MIDI file error at position %04X (%d): %s\n", (uint16_t) curpos, (uint16_t) curpos, msg); - /* print some bytes surrounding the error */ - ptr = curpos - 16; - if (ptr < 0) ptr = 0; - buffer.seek( buffer.data, ptr ); - for (int i = 0; i < 32; i++) { - char c; - buffer.read (buffer.data, &c, 1); - audioLogger->printf((ptr + i) == curpos ? " [%02X] " : "%02X ", (int) c & 0xff); - } - audioLogger->printf("\n"); + int ptr; + audioLogger->printf("---> MIDI file error at position %04X (%d): %s\n", (uint16_t) curpos, (uint16_t) curpos, msg); + /* print some bytes surrounding the error */ + ptr = curpos - 16; + if (ptr < 0) { + ptr = 0; + } + buffer.seek(buffer.data, ptr); + for (int i = 0; i < 32; i++) { + char c; + buffer.read(buffer.data, &c, 1); + audioLogger->printf((ptr + i) == curpos ? " [%02X] " : "%02X ", (int) c & 0xff); + } + audioLogger->printf("\n"); #endif - running = false; + running = false; } /* check that we have a specified number of bytes left in the buffer */ -void AudioGeneratorMIDI::chk_bufdata (int ptr, unsigned long int len) { - if ((unsigned) (ptr + len) > buflen) - midi_error ("data missing", ptr); +void AudioGeneratorMIDI::chk_bufdata(int ptr, unsigned long int len) { + if ((unsigned)(ptr + len) > buflen) { + midi_error("data missing", ptr); + } } /* fetch big-endian numbers */ -uint16_t AudioGeneratorMIDI::rev_short (uint16_t val) { - return ((val & 0xff) << 8) | ((val >> 8) & 0xff); +uint16_t AudioGeneratorMIDI::rev_short(uint16_t val) { + return ((val & 0xff) << 8) | ((val >> 8) & 0xff); } -uint32_t AudioGeneratorMIDI::rev_long (uint32_t val) { - return (((rev_short ((uint16_t) val) & 0xffff) << 16) | - (rev_short ((uint16_t) (val >> 16)) & 0xffff)); +uint32_t AudioGeneratorMIDI::rev_long(uint32_t val) { + return (((rev_short((uint16_t) val) & 0xffff) << 16) | + (rev_short((uint16_t)(val >> 16)) & 0xffff)); } /************** process the MIDI file header *****************/ -void AudioGeneratorMIDI::process_header (void) { - struct midi_header hdr; - unsigned int time_division; - - chk_bufdata (hdrptr, sizeof (struct midi_header)); - buffer.seek (buffer.data, hdrptr); - buffer.read (buffer.data, &hdr, sizeof (hdr)); - if (!charcmp ((char *) hdr.MThd, "MThd")) - midi_error ("Missing 'MThd'", hdrptr); - num_tracks = rev_short (hdr.number_of_tracks); - time_division = rev_short (hdr.time_division); - if (time_division < 0x8000) - ticks_per_beat = time_division; - else - ticks_per_beat = ((time_division >> 8) & 0x7f) /* SMTE frames/sec */ *(time_division & 0xff); /* ticks/SMTE frame */ - hdrptr += rev_long (hdr.header_size) + 8; /* point past header to track header, presumably. */ - return; +void AudioGeneratorMIDI::process_header(void) { + struct midi_header hdr; + unsigned int time_division; + + chk_bufdata(hdrptr, sizeof(struct midi_header)); + buffer.seek(buffer.data, hdrptr); + buffer.read(buffer.data, &hdr, sizeof(hdr)); + if (!charcmp((char *) hdr.MThd, "MThd")) { + midi_error("Missing 'MThd'", hdrptr); + } + num_tracks = rev_short(hdr.number_of_tracks); + time_division = rev_short(hdr.time_division); + if (time_division < 0x8000) { + ticks_per_beat = time_division; + } else { + ticks_per_beat = ((time_division >> 8) & 0x7f) /* SMTE frames/sec */ *(time_division & 0xff); /* ticks/SMTE frame */ + } + hdrptr += rev_long(hdr.header_size) + 8; /* point past header to track header, presumably. */ + return; } /**************** Process a MIDI track header *******************/ -void AudioGeneratorMIDI::start_track (int tracknum) { - struct track_header hdr; - unsigned long tracklen; - - chk_bufdata (hdrptr, sizeof (struct track_header)); - buffer.seek (buffer.data, hdrptr); - buffer.read (buffer.data, &hdr, sizeof (hdr)); - if (!charcmp ((char *) (hdr.MTrk), "MTrk")) - midi_error ("Missing 'MTrk'", hdrptr); - tracklen = rev_long (hdr.track_size); - hdrptr += sizeof (struct track_header); /* point past header */ - chk_bufdata (hdrptr, tracklen); - track[tracknum].trkptr = hdrptr; - hdrptr += tracklen; /* point to the start of the next track */ - track[tracknum].trkend = hdrptr; /* the point past the end of the track */ +void AudioGeneratorMIDI::start_track(int tracknum) { + struct track_header hdr; + unsigned long tracklen; + + chk_bufdata(hdrptr, sizeof(struct track_header)); + buffer.seek(buffer.data, hdrptr); + buffer.read(buffer.data, &hdr, sizeof(hdr)); + if (!charcmp((char *)(hdr.MTrk), "MTrk")) { + midi_error("Missing 'MTrk'", hdrptr); + } + tracklen = rev_long(hdr.track_size); + hdrptr += sizeof(struct track_header); /* point past header */ + chk_bufdata(hdrptr, tracklen); + track[tracknum].trkptr = hdrptr; + hdrptr += tracklen; /* point to the start of the next track */ + track[tracknum].trkend = hdrptr; /* the point past the end of the track */ } -unsigned char AudioGeneratorMIDI::buffer_byte (int offset) { - unsigned char c; - buffer.seek (buffer.data, offset); - buffer.read (buffer.data, &c, 1); - return c; +unsigned char AudioGeneratorMIDI::buffer_byte(int offset) { + unsigned char c; + buffer.seek(buffer.data, offset); + buffer.read(buffer.data, &c, 1); + return c; } -unsigned short AudioGeneratorMIDI::buffer_short (int offset) { - unsigned short s; - buffer.seek (buffer.data, offset); - buffer.read (buffer.data, &s, sizeof (short)); - return s; +unsigned short AudioGeneratorMIDI::buffer_short(int offset) { + unsigned short s; + buffer.seek(buffer.data, offset); + buffer.read(buffer.data, &s, sizeof(short)); + return s; } -unsigned int AudioGeneratorMIDI::buffer_int32 (int offset) { - uint32_t i; - buffer.seek (buffer.data, offset); - buffer.read (buffer.data, &i, sizeof (i)); - return i; +unsigned int AudioGeneratorMIDI::buffer_int32(int offset) { + uint32_t i; + buffer.seek(buffer.data, offset); + buffer.read(buffer.data, &i, sizeof(i)); + return i; } /* Get a MIDI-style variable-length integer */ -unsigned long AudioGeneratorMIDI::get_varlen (int *ptr) { - /* Get a 1-4 byte variable-length value and adjust the pointer past it. - These are a succession of 7-bit values with a MSB bit of zero marking the end */ - - unsigned long val; - int i, byte; - - val = 0; - for (i = 0; i < 4; ++i) { - byte = buffer_byte ((*ptr)++); - val = (val << 7) | (byte & 0x7f); - if (!(byte & 0x80)) - return val; - } - return val; +unsigned long AudioGeneratorMIDI::get_varlen(int *ptr) { + /* Get a 1-4 byte variable-length value and adjust the pointer past it. + These are a succession of 7-bit values with an MSB bit of zero marking the end */ + + unsigned long val; + int i, byte; + + val = 0; + for (i = 0; i < 4; ++i) { + byte = buffer_byte((*ptr)++); + val = (val << 7) | (byte & 0x7f); + if (!(byte & 0x80)) { + return val; + } + } + return val; } /*************** Process the MIDI track data ***************************/ -/* Skip in the track for the next "note on", "note off" or "set tempo" command, - then record that information in the track status block and return. */ - -void AudioGeneratorMIDI::find_note (int tracknum) { - unsigned long int delta_time; - int event, chan; - int note, velocity, controller, pressure, pitchbend, instrument; - int meta_cmd, meta_length; - unsigned long int sysex_length; - struct track_status *t; - const char *tag; - - /* process events */ - - t = &track[tracknum]; /* our track status structure */ - while (t->trkptr < t->trkend) { - - delta_time = get_varlen (&t->trkptr); - t->time += delta_time; - if (buffer_byte (t->trkptr) < 0x80) - event = t->last_event; /* using "running status": same event as before */ - else { /* otherwise get new "status" (event type) */ - event = buffer_byte (t->trkptr++); - } - if (event == 0xff) { /* meta-event */ - meta_cmd = buffer_byte (t->trkptr++); - meta_length = get_varlen(&t->trkptr); - switch (meta_cmd) { - case 0x00: - break; - case 0x01: - tag = "description"; - goto show_text; - case 0x02: - tag = "copyright"; - goto show_text; - case 0x03: - tag = "track name"; - goto show_text; - case 0x04: - tag = "instrument name"; - goto show_text; - case 0x05: - tag = "lyric"; - goto show_text; - case 0x06: - tag = "marked point"; - goto show_text; - case 0x07: - tag = "cue point"; +/* Skip in the track for the next "note on", "note off" or "set tempo" command, + then record that information in the track status block and return. */ + +void AudioGeneratorMIDI::find_note(int tracknum) { + unsigned long int delta_time; + int event, chan; + int note, velocity, controller, pressure, pitchbend, instrument; + int meta_cmd, meta_length; + unsigned long int sysex_length; + struct track_status *t; + const char *tag; + + /* process events */ + + t = &track[tracknum]; /* our track status structure */ + while (t->trkptr < t->trkend) { + + delta_time = get_varlen(&t->trkptr); + t->time += delta_time; + if (buffer_byte(t->trkptr) < 0x80) { + event = t->last_event; /* using "running status": same event as before */ + } else { /* otherwise get new "status" (event type) */ + event = buffer_byte(t->trkptr++); + } + if (event == 0xff) { /* meta-event */ + meta_cmd = buffer_byte(t->trkptr++); + meta_length = get_varlen(&t->trkptr); + switch (meta_cmd) { + case 0x00: + break; + case 0x01: + tag = "description"; + goto show_text; + case 0x02: + tag = "copyright"; + goto show_text; + case 0x03: + tag = "track name"; + goto show_text; + case 0x04: + tag = "instrument name"; + goto show_text; + case 0x05: + tag = "lyric"; + goto show_text; + case 0x06: + tag = "marked point"; + goto show_text; + case 0x07: + tag = "cue point"; show_text: - break; - case 0x20: - break; - case 0x2f: - break; - case 0x51: /* tempo: 3 byte big-endian integer! */ - t->cmd = CMD_TEMPO; - t->tempo = rev_long (buffer_int32 (t->trkptr - 1)) & 0xffffffL; - t->trkptr += meta_length; - return; - case 0x54: - break; - case 0x58: - break; - case 0x59: - break; - case 0x7f: - tag = "sequencer data"; - goto show_hex; - default: /* unknown meta command */ - tag = "???"; + break; + case 0x20: + break; + case 0x2f: + break; + case 0x51: /* tempo: 3 byte big-endian integer! */ + t->cmd = CMD_TEMPO; + t->tempo = rev_long(buffer_int32(t->trkptr - 1)) & 0xffffffL; + t->trkptr += meta_length; + return; + case 0x54: + break; + case 0x58: + break; + case 0x59: + break; + case 0x7f: + tag = "sequencer data"; + goto show_hex; + default: /* unknown meta command */ + tag = "???"; show_hex: - break; - } - t->trkptr += meta_length; - } + break; + } + t->trkptr += meta_length; + } - else if (event < 0x80) - midi_error ("Unknown MIDI event type", t->trkptr); - - else { - if (event < 0xf0) - t->last_event = event; // remember "running status" if not meta or sysex event - chan = event & 0xf; - t->chan = chan; - switch (event >> 4) { - case 0x8: - t->note = buffer_byte (t->trkptr++); - velocity = buffer_byte (t->trkptr++); + else if (event < 0x80) { + midi_error("Unknown MIDI event type", t->trkptr); + } + + else { + if (event < 0xf0) { + t->last_event = event; // remember "running status" if not meta or sysex event + } + chan = event & 0xf; + t->chan = chan; + switch (event >> 4) { + case 0x8: + t->note = buffer_byte(t->trkptr++); + velocity = buffer_byte(t->trkptr++); note_off: - t->cmd = CMD_STOPNOTE; - return; /* stop processing and return */ - case 0x9: - t->note = buffer_byte (t->trkptr++); - velocity = buffer_byte (t->trkptr++); - if (velocity == 0) /* some scores use note-on with zero velocity for off! */ - goto note_off; - t->velocity = velocity; - t->cmd = CMD_PLAYNOTE; - return; /* stop processing and return */ - case 0xa: - note = buffer_byte (t->trkptr++); - velocity = buffer_byte (t->trkptr++); - break; - case 0xb: - controller = buffer_byte (t->trkptr++); - velocity = buffer_byte (t->trkptr++); - break; - case 0xc: - instrument = buffer_byte (t->trkptr++); - midi_chan_instrument[chan] = instrument; // record new instrument for this channel - break; - case 0xd: - pressure = buffer_byte (t->trkptr++); - break; - case 0xe: - pitchbend = buffer_byte (t->trkptr) | (buffer_byte (t->trkptr + 1) << 7); - t->trkptr += 2; - break; - case 0xf: - sysex_length = get_varlen (&t->trkptr); - t->trkptr += sysex_length; - break; - default: - midi_error ("Unknown MIDI command", t->trkptr); - } + t->cmd = CMD_STOPNOTE; + return; /* stop processing and return */ + case 0x9: + t->note = buffer_byte(t->trkptr++); + velocity = buffer_byte(t->trkptr++); + if (velocity == 0) { /* some scores use note-on with zero velocity for off! */ + goto note_off; + } + t->velocity = velocity; + t->cmd = CMD_PLAYNOTE; + return; /* stop processing and return */ + case 0xa: + note = buffer_byte(t->trkptr++); + velocity = buffer_byte(t->trkptr++); + break; + case 0xb: + controller = buffer_byte(t->trkptr++); + velocity = buffer_byte(t->trkptr++); + break; + case 0xc: + instrument = buffer_byte(t->trkptr++); + midi_chan_instrument[chan] = instrument; // record new instrument for this channel + break; + case 0xd: + pressure = buffer_byte(t->trkptr++); + break; + case 0xe: + pitchbend = buffer_byte(t->trkptr) | (buffer_byte(t->trkptr + 1) << 7); + t->trkptr += 2; + break; + case 0xf: + sysex_length = get_varlen(&t->trkptr); + t->trkptr += sysex_length; + break; + default: + midi_error("Unknown MIDI command", t->trkptr); + } + } } - } - t->cmd = CMD_TRACKDONE; /* no more notes to process */ - ++tracks_done; - - // Remove unused warnings..maybe some day we'll look at these - (void)note; - (void)controller; - (void)pressure; - (void)pitchbend; - (void)tag; + t->cmd = CMD_TRACKDONE; /* no more notes to process */ + ++tracks_done; + + // Remove unused warnings..maybe some day we'll look at these + (void)note; + (void)controller; + (void)pressure; + (void)pitchbend; + (void)tag; } -// Open file, parse headers, get ready tio process MIDI -void AudioGeneratorMIDI::PrepareMIDI(AudioFileSource *src) -{ - MakeStreamFromAFS(src, &afsMIDI); - tsf_stream_wrap_cached(&afsMIDI, 32, 64, &buffer); - buflen = buffer.size (buffer.data); +// Open file, parse headers, get ready to process MIDI +void AudioGeneratorMIDI::PrepareMIDI(AudioFileSource *src) { + MakeStreamFromAFS(src, &afsMIDI); + tsf_stream_wrap_cached(&afsMIDI, 32, 64, &buffer); + buflen = buffer.size(buffer.data); - /* process the MIDI file header */ + /* process the MIDI file header */ - hdrptr = buffer.tell (buffer.data); /* pointer to file and track headers */ - process_header (); - printf (" Processing %d tracks.\n", num_tracks); - if (num_tracks > MAX_TRACKS) - midi_error ("Too many tracks", buffer.tell (buffer.data)); + hdrptr = buffer.tell(buffer.data); /* pointer to file and track headers */ + process_header(); + printf(" Processing %d tracks.\n", num_tracks); + if (num_tracks > MAX_TRACKS) { + midi_error("Too many tracks", buffer.tell(buffer.data)); + } - /* initialize processing of all the tracks */ + /* initialize processing of all the tracks */ - for (tracknum = 0; tracknum < num_tracks; ++tracknum) { - start_track (tracknum); /* process the track header */ - find_note (tracknum); /* position to the first note on/off */ - } + for (tracknum = 0; tracknum < num_tracks; ++tracknum) { + start_track(tracknum); /* process the track header */ + find_note(tracknum); /* position to the first note on/off */ + } - notes_skipped = 0; - tracknum = 0; - earliest_tracknum = 0; - earliest_time = 0; + notes_skipped = 0; + tracknum = 0; + earliest_tracknum = 0; + earliest_time = 0; } // Parses the note on/offs until we are ready to render some more samples. Then return the // total number of samples to render before we need to be called again -int AudioGeneratorMIDI::PlayMIDI() -{ - /* Continue processing all tracks, in an order based on the simulated time. - This is not unlike multiway merging used for tape sorting algoritms in the 50's! */ - - do { /* while there are still track notes to process */ - static struct track_status *trk; - static struct tonegen_status *tg; - static int tgnum; - static int count_tracks; - static unsigned long delta_time, delta_msec; - - /* Find the track with the earliest event time, - and output a delay command if time has advanced. - - A potential improvement: If there are multiple tracks with the same time, - first do the ones with STOPNOTE as the next command, if any. That would - help avoid running out of tone generators. In practice, though, most MIDI - files do all the STOPNOTEs first anyway, so it won't have much effect. - */ - - earliest_time = 0x7fffffff; - - /* Usually we start with the track after the one we did last time (tracknum), - so that if we run out of tone generators, we have been fair to all the tracks. - The alternate "strategy1" says we always start with track 0, which means - that we favor early tracks over later ones when there aren't enough tone generators. - */ - - count_tracks = num_tracks; - do { - if (++tracknum >= num_tracks) - tracknum = 0; - trk = &track[tracknum]; - if (trk->cmd != CMD_TRACKDONE && trk->time < earliest_time) { - earliest_time = trk->time; - earliest_tracknum = tracknum; - } - } while (--count_tracks); - - tracknum = earliest_tracknum; /* the track we picked */ - trk = &track[tracknum]; - if (earliest_time < timenow) - midi_error ("INTERNAL: time went backwards", trk->trkptr); - - /* If time has advanced, output a "delay" command */ - - delta_time = earliest_time - timenow; - if (delta_time) { - /* Convert ticks to milliseconds based on the current tempo */ - unsigned long long temp; - temp = ((unsigned long long) delta_time * tempo) / ticks_per_beat; - delta_msec = temp / 1000; // get around LCC compiler bug - if (delta_msec > 0x7fff) - midi_error ("INTERNAL: time delta too big", trk->trkptr); - int samples = (((int) delta_msec) * freq) / 1000; - timenow = earliest_time; - return samples; - } - timenow = earliest_time; +int AudioGeneratorMIDI::PlayMIDI() { + /* Continue processing all tracks, in an order based on the simulated time. + This is not unlike multiway merging used for tape sorting algorithms in the 50's! */ + + do { /* while there are still track notes to process */ + static struct track_status *trk; + static struct tonegen_status *tg; + static int tgnum; + static int count_tracks; + static unsigned long delta_time, delta_msec; + + /* Find the track with the earliest event time, + and output a delay command if time has advanced. + + A potential improvement: If there are multiple tracks with the same time, + first do the ones with STOPNOTE as the next command, if any. That would + help avoid running out of tone generators. In practice, though, most MIDI + files do all the STOPNOTEs first anyway, so it won't have much effect. + */ + + earliest_time = 0x7fffffff; + + /* Usually we start with the track after the one we did last time (tracknum), + so that if we run out of tone generators, we have been fair to all the tracks. + The alternate "strategy1" says we always start with track 0, which means + that we favor early tracks over later ones when there aren't enough tone generators. + */ + + count_tracks = num_tracks; + do { + if (++tracknum >= num_tracks) { + tracknum = 0; + } + trk = &track[tracknum]; + if (trk->cmd != CMD_TRACKDONE && trk->time < earliest_time) { + earliest_time = trk->time; + earliest_tracknum = tracknum; + } + } while (--count_tracks); + + tracknum = earliest_tracknum; /* the track we picked */ + trk = &track[tracknum]; + if (earliest_time < timenow) { + midi_error("INTERNAL: time went backwards", trk->trkptr); + } - /* If this track event is "set tempo", just change the global tempo. - That affects how we generate "delay" commands. */ + /* If time has advanced, output a "delay" command */ + + delta_time = earliest_time - timenow; + if (delta_time) { + /* Convert ticks to milliseconds based on the current tempo */ + unsigned long long temp; + temp = ((unsigned long long) delta_time * tempo) / ticks_per_beat; + delta_msec = temp / 1000; // get around LCC compiler bug + if (delta_msec > 0x7fff) { + midi_error("INTERNAL: time delta too big", trk->trkptr); + } + int samples = (((int) delta_msec) * freq) / 1000; + timenow = earliest_time; + return samples; + } + timenow = earliest_time; - if (trk->cmd == CMD_TEMPO) { - tempo = trk->tempo; - find_note (tracknum); - } + /* If this track event is "set tempo", just change the global tempo. + That affects how we generate "delay" commands. */ - /* If this track event is "stop note", process it and all subsequent "stop notes" for this track - that are happening at the same time. Doing so frees up as many tone generators as possible. */ - - else if (trk->cmd == CMD_STOPNOTE) - do { - // stop a note - for (tgnum = 0; tgnum < num_tonegens; ++tgnum) { /* find which generator is playing it */ - tg = &tonegen[tgnum]; - if (tg->playing && tg->track == tracknum && tg->note == trk->note) { - tsf_note_off (g_tsf, tg->instrument, tg->note); - tg->playing = false; - trk->tonegens[tgnum] = false; - } + if (trk->cmd == CMD_TEMPO) { + tempo = trk->tempo; + find_note(tracknum); } - find_note (tracknum); // use up the note - } while (trk->cmd == CMD_STOPNOTE && trk->time == timenow); - - /* If this track event is "start note", process only it. - Don't do more than one, so we allow other tracks their chance at grabbing tone generators. */ - - else if (trk->cmd == CMD_PLAYNOTE) { - bool foundgen = false; - /* if not, then try for any free tone generator */ - if (!foundgen) - for (tgnum = 0; tgnum < num_tonegens; ++tgnum) { - tg = &tonegen[tgnum]; - if (!tg->playing) { - foundgen = true; - break; - } - } - if (foundgen) { - if (tgnum + 1 > num_tonegens_used) - num_tonegens_used = tgnum + 1; - tg->playing = true; - tg->track = tracknum; - tg->note = trk->note; - trk->tonegens[tgnum] = true; - trk->preferred_tonegen = tgnum; - if (tg->instrument != midi_chan_instrument[trk->chan]) { /* new instrument for this generator */ - tg->instrument = midi_chan_instrument[trk->chan]; + + /* If this track event is "stop note", process it and all subsequent "stop notes" for this track + that are happening at the same time. Doing so frees up as many tone generators as possible. */ + + else if (trk->cmd == CMD_STOPNOTE) + do { + // stop a note + for (tgnum = 0; tgnum < num_tonegens; ++tgnum) { /* find which generator is playing it */ + tg = &tonegen[tgnum]; + if (tg->playing && tg->track == tracknum && tg->note == trk->note) { + tsf_note_off_fast(g_tsf, tg->instrument, tg->note, tg->playIndex); + tg->playing = false; + tg->playIndex = -1; + trk->tonegens[tgnum] = false; + } + } + find_note(tracknum); // use up the note + } while (trk->cmd == CMD_STOPNOTE && trk->time == timenow); + + /* If this track event is "start note", process only it. + Don't do more than one, so we allow other tracks their chance at grabbing tone generators. */ + + else if (trk->cmd == CMD_PLAYNOTE) { + bool foundgen = false; + /* if not, then try for any free tone generator */ + if (!foundgen) + for (tgnum = 0; tgnum < num_tonegens; ++tgnum) { + tg = &tonegen[tgnum]; + if (!tg->playing) { + foundgen = true; + break; + } + } + if (foundgen) { + if (tgnum + 1 > num_tonegens_used) { + num_tonegens_used = tgnum + 1; + } + tg->playing = true; + tg->track = tracknum; + tg->note = trk->note; + trk->tonegens[tgnum] = true; + trk->preferred_tonegen = tgnum; + if (tg->instrument != midi_chan_instrument[trk->chan]) { /* new instrument for this generator */ + tg->instrument = midi_chan_instrument[trk->chan]; + } + tg->playIndex = tsf_note_on_fast(g_tsf, tg->instrument, tg->note, trk->velocity / 127.0); // velocity = 0...127 + } else { + ++notes_skipped; + } + find_note(tracknum); // use up the note } - tsf_note_on (g_tsf, tg->instrument, tg->note, trk->velocity / 127.0); // velocity = 0...127 - } else { - ++notes_skipped; - } - find_note (tracknum); // use up the note - } - } - while (tracks_done < num_tracks); - return -1; // EOF + } while (tracks_done < num_tracks); + return -1; // EOF } -void AudioGeneratorMIDI::StopMIDI() -{ +void AudioGeneratorMIDI::StopMIDI() { - buffer.close(buffer.data); - tsf_close(g_tsf); - printf (" %s %d tone generators were used.\n", - num_tonegens_used < num_tonegens ? "Only" : "All", num_tonegens_used); - if (notes_skipped) - printf - (" %d notes were skipped because there weren't enough tone generators.\n", notes_skipped); + buffer.close(buffer.data); + tsf_close(g_tsf); + printf(" %s %d tone generators were used.\n", + num_tonegens_used < num_tonegens ? "Only" : "All", num_tonegens_used); + if (notes_skipped) + printf + (" %d notes were skipped because there weren't enough tone generators.\n", notes_skipped); - printf (" Done.\n"); + printf(" Done.\n"); } -bool AudioGeneratorMIDI::begin(AudioFileSource *src, AudioOutput *out) -{ - // Clear out status variables - for (int i=0; iSetRate( freq )) return false; - if (!out->SetBitsPerSample( 16 )) return false; - if (!out->SetChannels( 1 )) return false; - if (!out->begin()) return false; + if (!out->SetRate(freq)) { + return false; + } + if (!out->SetChannels(1)) { + return false; + } + if (!out->begin()) { + return false; + } - output = out; - file = src; + output = out; + file = src; - running = true; + running = true; - PrepareMIDI(src); + PrepareMIDI(src); - samplesToPlay = 0; - numSamplesRendered = 0; - sentSamplesRendered = 0; - - sawEOF = false; - return running; + samplesToPlay = 0; + numSamplesRendered = 0; + sentSamplesRendered = 0; + + sawEOF = false; + return running; } -bool AudioGeneratorMIDI::loop() -{ - static int c = 0; +bool AudioGeneratorMIDI::loop() { + static int c = 0; - if (!running) goto done; // Nothing to do here! + if (!running) { + goto done; // Nothing to do here! + } - // First, try and push in the stored sample. If we can't, then punt and try later - if (!output->ConsumeSample(lastSample)) goto done; // Can't send, but no error detected + // First, try and push in the stored sample. If we can't, then punt and try later + if (!output->ConsumeSample(lastSample)) { + goto done; // Can't send, but no error detected + } - // Try and stuff the buffer one sample at a time - do { - c++; - if (c%44100 == 0) yield(); + // Try and stuff the buffer one sample at a time + do { + c++; + if (c % 44100 == 0) { + yield(); + } play: - if (sentSamplesRendered < numSamplesRendered) { - lastSample[AudioOutput::LEFTCHANNEL] = samplesRendered[sentSamplesRendered]; - lastSample[AudioOutput::RIGHTCHANNEL] = samplesRendered[sentSamplesRendered]; - sentSamplesRendered++; - } else if (samplesToPlay) { - numSamplesRendered = sizeof(samplesRendered)/sizeof(samplesRendered[0]); - if ((int)samplesToPlay < (int)(sizeof(samplesRendered)/sizeof(samplesRendered[0]))) numSamplesRendered = samplesToPlay; - tsf_render_short_fast(g_tsf, samplesRendered, numSamplesRendered, 0); - lastSample[AudioOutput::LEFTCHANNEL] = samplesRendered[0]; - lastSample[AudioOutput::RIGHTCHANNEL] = samplesRendered[0]; - sentSamplesRendered = 1; - samplesToPlay -= numSamplesRendered; - } else { - numSamplesRendered = 0; - sentSamplesRendered = 0; - if (sawEOF) { - running = false; - } else { - samplesToPlay = PlayMIDI(); - if (samplesToPlay == -1) { - sawEOF = true; - samplesToPlay = freq / 2; + if (sentSamplesRendered < numSamplesRendered) { + lastSample[AudioOutput::LEFTCHANNEL] = samplesRendered[sentSamplesRendered]; + lastSample[AudioOutput::RIGHTCHANNEL] = samplesRendered[sentSamplesRendered]; + sentSamplesRendered++; + } else if (samplesToPlay) { + numSamplesRendered = sizeof(samplesRendered) / sizeof(samplesRendered[0]); + if ((int)samplesToPlay < (int)(sizeof(samplesRendered) / sizeof(samplesRendered[0]))) { + numSamplesRendered = samplesToPlay; + } + tsf_render_short_fast(g_tsf, samplesRendered, numSamplesRendered, 0); + lastSample[AudioOutput::LEFTCHANNEL] = samplesRendered[0]; + lastSample[AudioOutput::RIGHTCHANNEL] = samplesRendered[0]; + sentSamplesRendered = 1; + samplesToPlay -= numSamplesRendered; + } else { + numSamplesRendered = 0; + sentSamplesRendered = 0; + if (sawEOF) { + running = false; + } else { + samplesToPlay = PlayMIDI(); + if (samplesToPlay == -1) { + sawEOF = true; + samplesToPlay = freq / 2; + } + goto play; + } } - goto play; - } - } - } while (running && output->ConsumeSample(lastSample)); + } while (running && output->ConsumeSample(lastSample)); done: - file->loop(); - output->loop(); + file->loop(); + output->loop(); - return running; + return running; } - -bool AudioGeneratorMIDI::stop() -{ - StopMIDI(); - output->stop(); - return true; + +bool AudioGeneratorMIDI::stop() { + StopMIDI(); + output->stop(); + return true; } -int AudioGeneratorMIDI::afs_read(void *data, void *ptr, unsigned int size) -{ - AudioFileSource *s = reinterpret_cast(data); - return s->read(ptr, size); +int AudioGeneratorMIDI::afs_read(void *data, void *ptr, unsigned int size) { + AudioFileSource *s = reinterpret_cast(data); + return s->read(ptr, size); } -int AudioGeneratorMIDI::afs_tell(void *data) -{ - AudioFileSource *s = reinterpret_cast(data); - return s->getPos(); +int AudioGeneratorMIDI::afs_tell(void *data) { + AudioFileSource *s = reinterpret_cast(data); + return s->getPos(); } -int AudioGeneratorMIDI::afs_skip(void *data, unsigned int count) -{ - AudioFileSource *s = reinterpret_cast(data); - return s->seek(count, SEEK_CUR); +int AudioGeneratorMIDI::afs_skip(void *data, unsigned int count) { + AudioFileSource *s = reinterpret_cast(data); + return s->seek(count, SEEK_CUR); } -int AudioGeneratorMIDI::afs_seek(void *data, unsigned int pos) -{ - AudioFileSource *s = reinterpret_cast(data); - return s->seek(pos, SEEK_SET); +int AudioGeneratorMIDI::afs_seek(void *data, unsigned int pos) { + AudioFileSource *s = reinterpret_cast(data); + return s->seek(pos, SEEK_SET); } -int AudioGeneratorMIDI::afs_close(void *data) -{ - AudioFileSource *s = reinterpret_cast(data); - return s->close(); +int AudioGeneratorMIDI::afs_close(void *data) { + AudioFileSource *s = reinterpret_cast(data); + return s->close(); } -int AudioGeneratorMIDI::afs_size(void *data) -{ - AudioFileSource *s = reinterpret_cast(data); - return s->getSize(); +int AudioGeneratorMIDI::afs_size(void *data) { + AudioFileSource *s = reinterpret_cast(data); + return s->getSize(); } -void AudioGeneratorMIDI::MakeStreamFromAFS(AudioFileSource *src, tsf_stream *afs) -{ - afs->data = reinterpret_cast(src); - afs->read = &afs_read; - afs->tell = &afs_tell; - afs->skip = &afs_skip; - afs->seek = &afs_seek; - afs->close = &afs_close; - afs->size = &afs_size; +void AudioGeneratorMIDI::MakeStreamFromAFS(AudioFileSource *src, tsf_stream *afs) { + afs->data = reinterpret_cast(src); + afs->read = &afs_read; + afs->tell = &afs_tell; + afs->skip = &afs_skip; + afs->seek = &afs_seek; + afs->close = &afs_close; + afs->size = &afs_size; } +#endif //__GNUC__ == 8 + diff --git a/src/AudioGeneratorMIDI.h b/src/AudioGeneratorMIDI.h index 8a1ac3f9..23ae17ad 100644 --- a/src/AudioGeneratorMIDI.h +++ b/src/AudioGeneratorMIDI.h @@ -1,53 +1,65 @@ /* - AudioGeneratorMIDI - Audio output generator that plays MIDI files using a SF2 SoundFont - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioGeneratorMIDI + Audio output generator that plays MIDI files using a SF2 SoundFont + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOGENERATORMIDI_H #define _AUDIOGENERATORMIDI_H +#if defined(ESP32) && (__GNUC__ >= 8) && (__XTENSA__) +// Do not build, Espressif's GCC8+ has a compiler bug +#else // __GNUC__ == 8 + #include "AudioGenerator.h" #define TSF_NO_STDIO #include "libtinysoundfont/tsf.h" -class AudioGeneratorMIDI : public AudioGenerator -{ - public: - AudioGeneratorMIDI() { freq=44100; running = false; }; +class AudioGeneratorMIDI : public AudioGenerator { +public: + AudioGeneratorMIDI() { + freq = 44100; + running = false; + }; virtual ~AudioGeneratorMIDI() override {}; bool SetSoundfont(AudioFileSource *newsf2) { - if (isRunning()) return false; - sf2 = newsf2; - MakeStreamFromAFS(sf2, &afsSF2); - return true; + if (isRunning()) { + return false; + } + sf2 = newsf2; + MakeStreamFromAFS(sf2, &afsSF2); + return true; } bool SetSampleRate(int newfreq) { - if (isRunning()) return false; - freq = newfreq; - return true; + if (isRunning()) { + return false; + } + freq = newfreq; + return true; } virtual bool begin(AudioFileSource *mid, AudioOutput *output) override; virtual bool loop() override; virtual bool stop() override; - virtual bool isRunning() override { return running; }; + virtual bool isRunning() override { + return running; + }; - private: +private: int freq; tsf *g_tsf; struct tsf_stream buffer; @@ -56,18 +68,18 @@ class AudioGeneratorMIDI : public AudioGenerator AudioFileSource *sf2; AudioFileSource *midi; - protected: +protected: struct midi_header { - int8_t MThd[4]; - uint32_t header_size; - uint16_t format_type; - uint16_t number_of_tracks; - uint16_t time_division; + int8_t MThd[4]; + uint32_t header_size; + uint16_t format_type; + uint16_t number_of_tracks; + uint16_t time_division; }; struct track_header { - int8_t MTrk[4]; - uint32_t track_size; + int8_t MTrk[4]; + uint32_t track_size; }; enum { MAX_TONEGENS = 32, /* max tone generators: tones we can play simultaneously */ @@ -90,24 +102,27 @@ class AudioGeneratorMIDI : public AudioGenerator unsigned long earliest_time = 0; struct tonegen_status { /* current status of a tone generator */ - bool playing; /* is it playing? */ - char track; /* if so, which track is the note from? */ - char note; /* what note is playing? */ - char instrument; /* what instrument? */ + bool playing; /* is it playing? */ + char track; /* if so, which track is the note from? */ + char note; /* what note is playing? */ + char instrument; /* what instrument? */ + int playIndex; /* is index provided? + Unique identifier generated when note starts playing. + This help us to turn the note off faster */ } tonegen[MAX_TONEGENS]; struct track_status { /* current processing point of a MIDI track */ - int trkptr; /* ptr to the next note change */ - int trkend; /* ptr past the end of the track */ - unsigned long time; /* what time we're at in the score */ - unsigned long tempo; /* the tempo last set, in usec per qnote */ - unsigned int preferred_tonegen; /* for strategy2, try to use this generator */ - unsigned char cmd; /* CMD_xxxx next to do */ - unsigned char note; /* for which note */ - unsigned char chan; /* from which channel it was */ - unsigned char velocity; /* the current volume */ - unsigned char last_event; /* the last event, for MIDI's "running status" */ - bool tonegens[MAX_TONEGENS]; /* which tone generators our notes are playing on */ + int trkptr; /* ptr to the next note change */ + int trkend; /* ptr past the end of the track */ + unsigned long time; /* what time we're at in the score */ + unsigned long tempo; /* the tempo last set, in usec per qnote */ + unsigned int preferred_tonegen; /* for strategy2, try to use this generator */ + unsigned char cmd; /* CMD_xxxx next to do */ + unsigned char note; /* for which note */ + unsigned char chan; /* from which channel it was */ + unsigned char velocity; /* the current volume */ + unsigned char last_event; /* the last event, for MIDI's "running status" */ + bool tonegens[MAX_TONEGENS]; /* which tone generators our notes are playing on */ } track[MAX_TRACKS]; int midi_chan_instrument[16]; /* which instrument is currently being played on each channel */ @@ -125,37 +140,38 @@ class AudioGeneratorMIDI : public AudioGenerator /* portable string length */ - int strlength (const char *str) { - int i; - for (i = 0; str[i] != '\0'; ++i); - return i; + int strlength(const char *str) { + int i; + for (i = 0; str[i] != '\0'; ++i); + return i; } /* match a constant character sequence */ - int charcmp (const char *buf, const char *match) { - int len, i; - len = strlength (match); - for (i = 0; i < len; ++i) - if (buf[i] != match[i]) - return 0; - return 1; + int charcmp(const char *buf, const char *match) { + int len, i; + len = strlength(match); + for (i = 0; i < len; ++i) + if (buf[i] != match[i]) { + return 0; + } + return 1; } - unsigned char buffer_byte (int offset); - unsigned short buffer_short (int offset); - unsigned int buffer_int32 (int offset); + unsigned char buffer_byte(int offset); + unsigned short buffer_short(int offset); + unsigned int buffer_int32(int offset); - void midi_error (const char *msg, int curpos); - void chk_bufdata (int ptr, unsigned long int len); - uint16_t rev_short (uint16_t val); - uint32_t rev_long (uint32_t val); - void process_header (void); - void start_track (int tracknum); + void midi_error(const char *msg, int curpos); + void chk_bufdata(int ptr, unsigned long int len); + uint16_t rev_short(uint16_t val); + uint32_t rev_long(uint32_t val); + void process_header(void); + void start_track(int tracknum); - unsigned long get_varlen (int *ptr); - void find_note (int tracknum); + unsigned long get_varlen(int *ptr); + void find_note(int tracknum); void PrepareMIDI(AudioFileSource *src); int PlayMIDI(); void StopMIDI(); @@ -176,6 +192,7 @@ class AudioGeneratorMIDI : public AudioGenerator short samplesRendered[256]; }; +#endif //__GNUC__ == 8 #endif diff --git a/src/AudioGeneratorMOD.cpp b/src/AudioGeneratorMOD.cpp index f42154f8..18ba3958 100644 --- a/src/AudioGeneratorMOD.cpp +++ b/src/AudioGeneratorMOD.cpp @@ -1,36 +1,36 @@ /* - AudioGeneratorMOD - Audio output generator that plays Amiga MOD tracker files - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioGeneratorMOD + Audio output generator that plays Amiga MOD tracker files + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #define PGM_READ_UNALIGNED 0 #include "AudioGeneratorMOD.h" -/* - Ported/hacked out from STELLARPLAYER by Ronen K. - http://mobile4dev.blogspot.com/2012/11/stellaris-launchpad-mod-player.html - A version exists in GitHub at https://github.com/steveway/stellarplayer - and also at https://github.com/MikesModz/StellarPlayer - Both which were themselves a port of the PIC32 MOD player - https://www.youtube.com/watch?v=i3Yl0TISQBE (seems to no longer be available.) - - Most changes involved reducing memory usage by changing data structures, - moving constants to PROGMEM and minor tweaks to allow non pow2 buffer sizes. +/* + Ported/hacked out from STELLARPLAYER by Ronen K. + http://mobile4dev.blogspot.com/2012/11/stellaris-launchpad-mod-player.html + A version exists in GitHub at https://github.com/steveway/stellarplayer + and also at https://github.com/MikesModz/StellarPlayer + Both which were themselves a port of the PIC32 MOD player + https://www.youtube.com/watch?v=i3Yl0TISQBE (seems to no longer be available.) + + Most changes involved reducing memory usage by changing data structures, + moving constants to PROGMEM and minor tweaks to allow non pow2 buffer sizes. */ #pragma GCC optimize ("O3") @@ -41,836 +41,1009 @@ #define min(X,Y) ((X) < (Y) ? (X) : (Y)) #endif -AudioGeneratorMOD::AudioGeneratorMOD() -{ - sampleRate = 44100; - fatBufferSize = 6 * 1024; - stereoSeparation = 32; - mixerTick = 0; - usePAL = false; - UpdateAmiga(); - running = false; - file = NULL; - output = NULL; +AudioGeneratorMOD::AudioGeneratorMOD() { + sampleRate = 44100; + fatBufferSize = 6 * 1024; + stereoSeparation = 32; + mixerTick = 0; + usePAL = false; + UpdateAmiga(); + running = false; + file = NULL; + output = NULL; } -AudioGeneratorMOD::~AudioGeneratorMOD() -{ - // Free any remaining buffers - for (int i = 0; i < CHANNELS; i++) { - FatBuffer.channels[i] = NULL; - } +AudioGeneratorMOD::~AudioGeneratorMOD() { + // Free any remaining buffers + for (int i = 0; i < CHANNELS; i++) { + FatBuffer.channels[i] = NULL; + } } -bool AudioGeneratorMOD::stop() -{ - // We may be stopping because of allocation failures, so always deallocate - for (int i = 0; i < CHANNELS; i++) { - free(FatBuffer.channels[i]); - FatBuffer.channels[i] = NULL; - } - if (file) file->close(); - running = false; - output->stop(); - return true; -} +bool AudioGeneratorMOD::stop() { + // We may be stopping because of allocation failures, so always deallocate + for (int i = 0; i < CHANNELS; i++) { + free(FatBuffer.channels[i]); + FatBuffer.channels[i] = NULL; + } + + if (running || ((file != NULL) && (file->isOpen() == true))) { + output->flush(); //flush I2S output buffer, if the player was actually running before. + } -bool AudioGeneratorMOD::loop() -{ - if (!running) goto done; // Easy-peasy + if (file) { + file->close(); + } + running = false; + output->stop(); + return true; +} - // First, try and push in the stored sample. If we can't, then punt and try later - if (!output->ConsumeSample(lastSample)) goto done; // FIFO full, wait... +bool AudioGeneratorMOD::loop() { + if (!running) { + goto done; // Easy-peasy + } - // Now advance enough times to fill the i2s buffer - do { - if (mixerTick == 0) { - running = RunPlayer(); - if (!running) { - stop(); - goto done; - } - mixerTick = Player.samplesPerTick; + // First, try and push in the stored sample. If we can't, then punt and try later + if (!output->ConsumeSample(lastSample)) { + goto done; // FIFO full, wait... } - GetSample( lastSample ); - mixerTick--; - } while (output->ConsumeSample(lastSample)); + + // Now advance enough times to fill the i2s buffer + do { + if (mixerTick == 0) { + running = RunPlayer(); + if (!running) { + stop(); + goto done; + } + mixerTick = Player.samplesPerTick; + } + GetSample(lastSample); + mixerTick--; + } while (output->ConsumeSample(lastSample)); done: - file->loop(); - output->loop(); + file->loop(); + output->loop(); - // We'll be left with one sample still in our buffer because it couldn't fit in the FIFO - return running; + // We'll be left with one sample still in our buffer because it couldn't fit in the FIFO + return running; } -bool AudioGeneratorMOD::begin(AudioFileSource *source, AudioOutput *out) -{ - if (running) stop(); - - if (!source) return false; - file = source; - if (!out) return false; - output = out; - - if (!file->isOpen()) return false; // Can't read the file! - - // Set the output values properly - if (!output->SetRate(sampleRate)) return false; - if (!output->SetBitsPerSample(16)) return false; - if (!output->SetChannels(2)) return false; - if (!output->begin()) return false; - - UpdateAmiga(); - - for (int i = 0; i < CHANNELS; i++) { - FatBuffer.channels[i] = reinterpret_cast(malloc(fatBufferSize)); - if (!FatBuffer.channels[i]) { - stop(); - return false; - } - } - if (!LoadMOD()) { - stop(); - return false; - } - running = true; - return true; +bool AudioGeneratorMOD::begin(AudioFileSource *source, AudioOutput *out) { + if (running) { + stop(); + } + + if (!source) { + return false; + } + file = source; + if (!out) { + return false; + } + output = out; + + if (!file->isOpen()) { + return false; // Can't read the file! + } + + // Set the output values properly + if (!output->SetRate(sampleRate)) { + return false; + } + if (!output->SetChannels(2)) { + return false; + } + if (!output->begin()) { + return false; + } + + UpdateAmiga(); + + for (int i = 0; i < CHANNELS; i++) { + FatBuffer.channels[i] = reinterpret_cast(calloc(fatBufferSize, 1)); + if (!FatBuffer.channels[i]) { + stop(); + return false; + } + } + if (!LoadMOD()) { + stop(); + return false; + } + running = true; + return true; } // Sorted Amiga periods static const uint16_t amigaPeriods[296] PROGMEM = { - 907, 900, 894, 887, 881, 875, 868, 862, // -8 to -1 - 856, 850, 844, 838, 832, 826, 820, 814, // C-1 to +7 - 808, 802, 796, 791, 785, 779, 774, 768, // C#1 to +7 - 762, 757, 752, 746, 741, 736, 730, 725, // D-1 to +7 - 720, 715, 709, 704, 699, 694, 689, 684, // D#1 to +7 - 678, 675, 670, 665, 660, 655, 651, 646, // E-1 to +7 - 640, 636, 632, 628, 623, 619, 614, 610, // F-1 to +7 - 604, 601, 597, 592, 588, 584, 580, 575, // F#1 to +7 - 570, 567, 563, 559, 555, 551, 547, 543, // G-1 to +7 - 538, 535, 532, 528, 524, 520, 516, 513, // G#1 to +7 - 508, 505, 502, 498, 494, 491, 487, 484, // A-1 to +7 - 480, 477, 474, 470, 467, 463, 460, 457, // A#1 to +7 - 453, 450, 447, 444, 441, 437, 434, 431, // B-1 to +7 - 428, 425, 422, 419, 416, 413, 410, 407, // C-2 to +7 - 404, 401, 398, 395, 392, 390, 387, 384, // C#2 to +7 - 381, 379, 376, 373, 370, 368, 365, 363, // D-2 to +7 - 360, 357, 355, 352, 350, 347, 345, 342, // D#2 to +7 - 339, 337, 335, 332, 330, 328, 325, 323, // E-2 to +7 - 320, 318, 316, 314, 312, 309, 307, 305, // F-2 to +7 - 302, 300, 298, 296, 294, 292, 290, 288, // F#2 to +7 - 285, 284, 282, 280, 278, 276, 274, 272, // G-2 to +7 - 269, 268, 266, 264, 262, 260, 258, 256, // G#2 to +7 - 254, 253, 251, 249, 247, 245, 244, 242, // A-2 to +7 - 240, 238, 237, 235, 233, 232, 230, 228, // A#2 to +7 - 226, 225, 223, 222, 220, 219, 217, 216, // B-2 to +7 - 214, 212, 211, 209, 208, 206, 205, 203, // C-3 to +7 - 202, 200, 199, 198, 196, 195, 193, 192, // C#3 to +7 - 190, 189, 188, 187, 185, 184, 183, 181, // D-3 to +7 - 180, 179, 177, 176, 175, 174, 172, 171, // D#3 to +7 - 170, 169, 167, 166, 165, 164, 163, 161, // E-3 to +7 - 160, 159, 158, 157, 156, 155, 154, 152, // F-3 to +7 - 151, 150, 149, 148, 147, 146, 145, 144, // F#3 to +7 - 143, 142, 141, 140, 139, 138, 137, 136, // G-3 to +7 - 135, 134, 133, 132, 131, 130, 129, 128, // G#3 to +7 - 127, 126, 125, 125, 123, 123, 122, 121, // A-3 to +7 - 120, 119, 118, 118, 117, 116, 115, 114, // A#3 to +7 - 113, 113, 112, 111, 110, 109, 109, 108 // B-3 to +7 + 907, 900, 894, 887, 881, 875, 868, 862, // -8 to -1 + 856, 850, 844, 838, 832, 826, 820, 814, // C-1 to +7 + 808, 802, 796, 791, 785, 779, 774, 768, // C#1 to +7 + 762, 757, 752, 746, 741, 736, 730, 725, // D-1 to +7 + 720, 715, 709, 704, 699, 694, 689, 684, // D#1 to +7 + 678, 675, 670, 665, 660, 655, 651, 646, // E-1 to +7 + 640, 636, 632, 628, 623, 619, 614, 610, // F-1 to +7 + 604, 601, 597, 592, 588, 584, 580, 575, // F#1 to +7 + 570, 567, 563, 559, 555, 551, 547, 543, // G-1 to +7 + 538, 535, 532, 528, 524, 520, 516, 513, // G#1 to +7 + 508, 505, 502, 498, 494, 491, 487, 484, // A-1 to +7 + 480, 477, 474, 470, 467, 463, 460, 457, // A#1 to +7 + 453, 450, 447, 444, 441, 437, 434, 431, // B-1 to +7 + 428, 425, 422, 419, 416, 413, 410, 407, // C-2 to +7 + 404, 401, 398, 395, 392, 390, 387, 384, // C#2 to +7 + 381, 379, 376, 373, 370, 368, 365, 363, // D-2 to +7 + 360, 357, 355, 352, 350, 347, 345, 342, // D#2 to +7 + 339, 337, 335, 332, 330, 328, 325, 323, // E-2 to +7 + 320, 318, 316, 314, 312, 309, 307, 305, // F-2 to +7 + 302, 300, 298, 296, 294, 292, 290, 288, // F#2 to +7 + 285, 284, 282, 280, 278, 276, 274, 272, // G-2 to +7 + 269, 268, 266, 264, 262, 260, 258, 256, // G#2 to +7 + 254, 253, 251, 249, 247, 245, 244, 242, // A-2 to +7 + 240, 238, 237, 235, 233, 232, 230, 228, // A#2 to +7 + 226, 225, 223, 222, 220, 219, 217, 216, // B-2 to +7 + 214, 212, 211, 209, 208, 206, 205, 203, // C-3 to +7 + 202, 200, 199, 198, 196, 195, 193, 192, // C#3 to +7 + 190, 189, 188, 187, 185, 184, 183, 181, // D-3 to +7 + 180, 179, 177, 176, 175, 174, 172, 171, // D#3 to +7 + 170, 169, 167, 166, 165, 164, 163, 161, // E-3 to +7 + 160, 159, 158, 157, 156, 155, 154, 152, // F-3 to +7 + 151, 150, 149, 148, 147, 146, 145, 144, // F#3 to +7 + 143, 142, 141, 140, 139, 138, 137, 136, // G-3 to +7 + 135, 134, 133, 132, 131, 130, 129, 128, // G#3 to +7 + 127, 126, 125, 125, 123, 123, 122, 121, // A-3 to +7 + 120, 119, 118, 118, 117, 116, 115, 114, // A#3 to +7 + 113, 113, 112, 111, 110, 109, 109, 108 // B-3 to +7 }; #define ReadAmigaPeriods(a) (uint16_t)pgm_read_word(amigaPeriods + (a)) static const uint8_t sine[64] PROGMEM = { - 0, 24, 49, 74, 97, 120, 141, 161, - 180, 197, 212, 224, 235, 244, 250, 253, - 255, 253, 250, 244, 235, 224, 212, 197, - 180, 161, 141, 120, 97, 74, 49, 24 + 0, 24, 49, 74, 97, 120, 141, 161, + 180, 197, 212, 224, 235, 244, 250, 253, + 255, 253, 250, 244, 235, 224, 212, 197, + 180, 161, 141, 120, 97, 74, 49, 24 }; #define ReadSine(a) pgm_read_byte(sine + (a)) -static inline uint16_t MakeWord(uint8_t h, uint8_t l) { return h << 8 | l; } - -bool AudioGeneratorMOD::LoadHeader() -{ - uint8_t i; - uint8_t temp[4]; - uint8_t junk[22]; - - if (20 != file->read(/*Mod.name*/junk, 20)) return false; // Skip MOD name - for (i = 0; i < SAMPLES; i++) { - if (22 != file->read(junk /*Mod.samples[i].name*/, 22)) return false; // Skip sample name - if (2 != file->read(temp, 2)) return false; - Mod.samples[i].length = MakeWord(temp[0], temp[1]) * 2; - if (1 != file->read(reinterpret_cast(&Mod.samples[i].fineTune), 1)) return false; - if (Mod.samples[i].fineTune > 7) Mod.samples[i].fineTune -= 16; - if (1 != file->read(&Mod.samples[i].volume, 1)) return false; - if (2 != file->read(temp, 2)) return false; - Mod.samples[i].loopBegin = MakeWord(temp[0], temp[1]) * 2; - if (2 != file->read(temp, 2)) return false; - Mod.samples[i].loopLength = MakeWord(temp[0], temp[1]) * 2; - if (Mod.samples[i].loopBegin + Mod.samples[i].loopLength > Mod.samples[i].length) - Mod.samples[i].loopLength = Mod.samples[i].length - Mod.samples[i].loopBegin; - } - - if (1 != file->read(&Mod.songLength, 1)) return false; - if (1 != file->read(temp, 1)) return false; // Discard this byte - - Mod.numberOfPatterns = 0; - for (i = 0; i < 128; i++) { - if (1 != file->read(&Mod.order[i], 1)) return false; - if (Mod.order[i] > Mod.numberOfPatterns) - Mod.numberOfPatterns = Mod.order[i]; - } - Mod.numberOfPatterns++; - - // Offset 1080 - if (4 != file->read(temp, 4)) return false;; - if (!strncmp(reinterpret_cast(temp + 1), "CHN", 3)) - Mod.numberOfChannels = temp[0] - '0'; - else if (!strncmp(reinterpret_cast(temp + 2), "CH", 2)) - Mod.numberOfChannels = (temp[0] - '0') * 10 + temp[1] - '0'; - else - Mod.numberOfChannels = 4; - - return true; +static inline uint16_t MakeWord(uint8_t h, uint8_t l) { + return h << 8 | l; } -void AudioGeneratorMOD::LoadSamples() -{ - uint8_t i; - uint32_t fileOffset = 1084 + Mod.numberOfPatterns * ROWS * Mod.numberOfChannels * 4 - 1; +bool AudioGeneratorMOD::LoadHeader() { + uint8_t i; + uint8_t temp[4]; + uint8_t junk[22]; - for (i = 0; i < SAMPLES; i++) { + if (20 != file->read(/*Mod.name*/junk, 20)) { + return false; // Skip MOD name + } + for (i = 0; i < SAMPLES; i++) { + if (22 != file->read(junk /*Mod.samples[i].name*/, 22)) { + return false; // Skip sample name + } + if (2 != file->read(temp, 2)) { + return false; + } + Mod.samples[i].length = MakeWord(temp[0], temp[1]) * 2; + if (1 != file->read(reinterpret_cast(&Mod.samples[i].fineTune), 1)) { + return false; + } + if (Mod.samples[i].fineTune > 7) { + Mod.samples[i].fineTune -= 16; + } + if (1 != file->read(&Mod.samples[i].volume, 1)) { + return false; + } + if (2 != file->read(temp, 2)) { + return false; + } + Mod.samples[i].loopBegin = MakeWord(temp[0], temp[1]) * 2; + if (2 != file->read(temp, 2)) { + return false; + } + Mod.samples[i].loopLength = MakeWord(temp[0], temp[1]) * 2; + if (Mod.samples[i].loopBegin + Mod.samples[i].loopLength > Mod.samples[i].length) { + Mod.samples[i].loopLength = Mod.samples[i].length - Mod.samples[i].loopBegin; + } + } - if (Mod.samples[i].length) { - Mixer.sampleBegin[i] = fileOffset; - Mixer.sampleEnd[i] = fileOffset + Mod.samples[i].length; - if (Mod.samples[i].loopLength > 2) { - Mixer.sampleloopBegin[i] = fileOffset + Mod.samples[i].loopBegin; - Mixer.sampleLoopLength[i] = Mod.samples[i].loopLength; - Mixer.sampleLoopEnd[i] = Mixer.sampleloopBegin[i] + Mixer.sampleLoopLength[i]; - } else { - Mixer.sampleloopBegin[i] = 0; - Mixer.sampleLoopLength[i] = 0; - Mixer.sampleLoopEnd[i] = 0; - } - fileOffset += Mod.samples[i].length; + if (1 != file->read(&Mod.songLength, 1)) { + return false; + } + if (1 != file->read(temp, 1)) { + return false; // Discard this byte } - } + Mod.numberOfPatterns = 0; + for (i = 0; i < 128; i++) { + if (1 != file->read(&Mod.order[i], 1)) { + return false; + } + if (Mod.order[i] > Mod.numberOfPatterns) { + Mod.numberOfPatterns = Mod.order[i]; + } + } + Mod.numberOfPatterns++; + + // Offset 1080 + if (4 != file->read(temp, 4)) { + return false; + }; + if (!strncmp(reinterpret_cast(temp + 1), "CHN", 3)) { + Mod.numberOfChannels = temp[0] - '0'; + } else if (!strncmp(reinterpret_cast(temp + 2), "CH", 2)) { + Mod.numberOfChannels = (temp[0] - '0') * 10 + temp[1] - '0'; + } else { + Mod.numberOfChannels = 4; + } + + if (Mod.numberOfChannels > CHANNELS) { + audioLogger->printf("\nAudioGeneratorMOD::LoadHeader abort - too many channels (configured: %d, needed: %d)\n", CHANNELS, Mod.numberOfChannels); + return (false); + } + return true; } -bool AudioGeneratorMOD::LoadPattern(uint8_t pattern) -{ - uint8_t row; - uint8_t channel; - uint8_t i; - uint8_t temp[4]; - uint16_t amigaPeriod; +void AudioGeneratorMOD::LoadSamples() { + uint8_t i; + uint32_t fileOffset = 1084 + Mod.numberOfPatterns * ROWS * Mod.numberOfChannels * 4 - 1; + + for (i = 0; i < SAMPLES; i++) { + + if (Mod.samples[i].length) { + Mixer.sampleBegin[i] = fileOffset; + Mixer.sampleEnd[i] = fileOffset + Mod.samples[i].length; + if (Mod.samples[i].loopLength > 2) { + Mixer.sampleloopBegin[i] = fileOffset + Mod.samples[i].loopBegin; + Mixer.sampleLoopLength[i] = Mod.samples[i].loopLength; + Mixer.sampleLoopEnd[i] = Mixer.sampleloopBegin[i] + Mixer.sampleLoopLength[i]; + } else { + Mixer.sampleloopBegin[i] = 0; + Mixer.sampleLoopLength[i] = 0; + Mixer.sampleLoopEnd[i] = 0; + } + fileOffset += Mod.samples[i].length; + } - if (!file->seek(1084 + pattern * ROWS * Mod.numberOfChannels * 4, SEEK_SET)) return false; + } - for (row = 0; row < ROWS; row++) { - for (channel = 0; channel < Mod.numberOfChannels; channel++) { +} + +bool AudioGeneratorMOD::LoadPattern(uint8_t pattern) { + uint8_t row; + uint8_t channel; + uint8_t i; + uint8_t temp[4]; + uint16_t amigaPeriod; + + if (!file->seek(1084 + pattern * ROWS * Mod.numberOfChannels * 4, SEEK_SET)) { + return false; + } + + for (row = 0; row < ROWS; row++) { + for (channel = 0; channel < Mod.numberOfChannels; channel++) { - if (4 != file->read(temp, 4)) return false; + if (4 != file->read(temp, 4)) { + return false; + } - Player.currentPattern.sampleNumber[row][channel] = (temp[0] & 0xF0) + (temp[2] >> 4); + Player.currentPattern.sampleNumber[row][channel] = (temp[0] & 0xF0) + (temp[2] >> 4); - amigaPeriod = ((temp[0] & 0xF) << 8) + temp[1]; - // Player.currentPattern.note[row][channel] = NONOTE; - Player.currentPattern.note8[row][channel] = NONOTE8; - for (i = 1; i < 37; i++) - if (amigaPeriod > ReadAmigaPeriods(i * 8) - 3 && - amigaPeriod < ReadAmigaPeriods(i * 8) + 3) - Player.currentPattern.note8[row][channel] = i; + amigaPeriod = ((temp[0] & 0xF) << 8) + temp[1]; + // Player.currentPattern.note[row][channel] = NONOTE; + Player.currentPattern.note8[row][channel] = NONOTE8; + for (i = 1; i < 37; i++) + if (amigaPeriod > ReadAmigaPeriods(i * 8) - 3 && + amigaPeriod < ReadAmigaPeriods(i * 8) + 3) { + Player.currentPattern.note8[row][channel] = i; + } - Player.currentPattern.effectNumber[row][channel] = temp[2] & 0xF; - Player.currentPattern.effectParameter[row][channel] = temp[3]; + Player.currentPattern.effectNumber[row][channel] = temp[2] & 0xF; + Player.currentPattern.effectParameter[row][channel] = temp[3]; + } } - } - return true; + return true; } -void AudioGeneratorMOD::Portamento(uint8_t channel) -{ - if (Player.lastAmigaPeriod[channel] < Player.portamentoNote[channel]) { - Player.lastAmigaPeriod[channel] += Player.portamentoSpeed[channel]; - if (Player.lastAmigaPeriod[channel] > Player.portamentoNote[channel]) - Player.lastAmigaPeriod[channel] = Player.portamentoNote[channel]; - } - if (Player.lastAmigaPeriod[channel] > Player.portamentoNote[channel]) { - Player.lastAmigaPeriod[channel] -= Player.portamentoSpeed[channel]; - if (Player.lastAmigaPeriod[channel] < Player.portamentoNote[channel]) - Player.lastAmigaPeriod[channel] = Player.portamentoNote[channel]; - } - Mixer.channelFrequency[channel] = Player.amiga / Player.lastAmigaPeriod[channel]; +void AudioGeneratorMOD::Portamento(uint8_t channel) { + if (Player.lastAmigaPeriod[channel] < Player.portamentoNote[channel]) { + Player.lastAmigaPeriod[channel] += Player.portamentoSpeed[channel]; + if (Player.lastAmigaPeriod[channel] > Player.portamentoNote[channel]) { + Player.lastAmigaPeriod[channel] = Player.portamentoNote[channel]; + } + } + if (Player.lastAmigaPeriod[channel] > Player.portamentoNote[channel]) { + Player.lastAmigaPeriod[channel] -= Player.portamentoSpeed[channel]; + if (Player.lastAmigaPeriod[channel] < Player.portamentoNote[channel]) { + Player.lastAmigaPeriod[channel] = Player.portamentoNote[channel]; + } + } + Mixer.channelFrequency[channel] = Player.amiga / Player.lastAmigaPeriod[channel]; } -void AudioGeneratorMOD::Vibrato(uint8_t channel) -{ - uint16_t delta; - uint16_t temp; +void AudioGeneratorMOD::Vibrato(uint8_t channel) { + uint16_t delta; + uint16_t temp; - temp = Player.vibratoPos[channel] & 31; + temp = Player.vibratoPos[channel] & 31; - switch (Player.waveControl[channel] & 3) { + switch (Player.waveControl[channel] & 3) { case 0: - delta = ReadSine(temp); - break; + delta = ReadSine(temp); + break; case 1: - temp <<= 3; - if (Player.vibratoPos[channel] < 0) - temp = 255 - temp; - delta = temp; - break; + temp <<= 3; + if (Player.vibratoPos[channel] < 0) { + temp = 255 - temp; + } + delta = temp; + break; case 2: - delta = 255; - break; + delta = 255; + break; case 3: - delta = rand() & 255; - break; - } + delta = rand() & 255; + break; + } - delta *= Player.vibratoDepth[channel]; - delta >>= 7; + delta *= Player.vibratoDepth[channel]; + delta >>= 7; - if (Player.vibratoPos[channel] >= 0) - Mixer.channelFrequency[channel] = Player.amiga / (Player.lastAmigaPeriod[channel] + delta); - else - Mixer.channelFrequency[channel] = Player.amiga / (Player.lastAmigaPeriod[channel] - delta); + if (Player.vibratoPos[channel] >= 0) { + Mixer.channelFrequency[channel] = Player.amiga / (Player.lastAmigaPeriod[channel] + delta); + } else { + Mixer.channelFrequency[channel] = Player.amiga / (Player.lastAmigaPeriod[channel] - delta); + } - Player.vibratoPos[channel] += Player.vibratoSpeed[channel]; - if (Player.vibratoPos[channel] > 31) Player.vibratoPos[channel] -= 64; + Player.vibratoPos[channel] += Player.vibratoSpeed[channel]; + if (Player.vibratoPos[channel] > 31) { + Player.vibratoPos[channel] -= 64; + } } -void AudioGeneratorMOD::Tremolo(uint8_t channel) -{ - uint16_t delta; - uint16_t temp; +void AudioGeneratorMOD::Tremolo(uint8_t channel) { + uint16_t delta; + uint16_t temp; - temp = Player.tremoloPos[channel] & 31; + temp = Player.tremoloPos[channel] & 31; - switch (Player.waveControl[channel] & 3) { + switch (Player.waveControl[channel] & 3) { case 0: - delta = ReadSine(temp); - break; + delta = ReadSine(temp); + break; case 1: - temp <<= 3; - if (Player.tremoloPos[channel] < 0) - temp = 255 - temp; - delta = temp; - break; + temp <<= 3; + if (Player.tremoloPos[channel] < 0) { + temp = 255 - temp; + } + delta = temp; + break; case 2: - delta = 255; - break; + delta = 255; + break; case 3: - delta = rand() & 255; - break; - } - - delta *= Player.tremoloDepth[channel]; - delta >>= 6; - - if (Player.tremoloPos[channel] >= 0) { - if (Player.volume[channel] + delta > 64) delta = 64 - Player.volume[channel]; - Mixer.channelVolume[channel] = Player.volume[channel] + delta; - } else { - if (Player.volume[channel] - delta < 0) delta = Player.volume[channel]; - Mixer.channelVolume[channel] = Player.volume[channel] - delta; - } - - Player.tremoloPos[channel] += Player.tremoloSpeed[channel]; - if (Player.tremoloPos[channel] > 31) Player.tremoloPos[channel] -= 64; -} - -bool AudioGeneratorMOD::ProcessRow() -{ - bool jumpFlag; - bool breakFlag; - uint8_t channel; - uint8_t sampleNumber; - uint16_t note; - uint8_t effectNumber; - uint8_t effectParameter; - uint8_t effectParameterX; - uint8_t effectParameterY; - uint16_t sampleOffset; - - if (!running) return false; - - Player.lastRow = Player.row++; - jumpFlag = false; - breakFlag = false; - for (channel = 0; channel < Mod.numberOfChannels; channel++) { - - sampleNumber = Player.currentPattern.sampleNumber[Player.lastRow][channel]; - note = NOTE(Player.lastRow, channel); - effectNumber = Player.currentPattern.effectNumber[Player.lastRow][channel]; - effectParameter = Player.currentPattern.effectParameter[Player.lastRow][channel]; - effectParameterX = effectParameter >> 4; - effectParameterY = effectParameter & 0xF; - sampleOffset = 0; - - if (sampleNumber) { - Player.lastSampleNumber[channel] = sampleNumber - 1; - if (!(effectParameter == 0xE && effectParameterX == NOTEDELAY)) - Player.volume[channel] = Mod.samples[Player.lastSampleNumber[channel]].volume; - } - - if (note != NONOTE) { - Player.lastNote[channel] = note; - Player.amigaPeriod[channel] = ReadAmigaPeriods(note + Mod.samples[Player.lastSampleNumber[channel]].fineTune); - - if (effectNumber != TONEPORTAMENTO && effectNumber != PORTAMENTOVOLUMESLIDE) - Player.lastAmigaPeriod[channel] = Player.amigaPeriod[channel]; - - if (!(Player.waveControl[channel] & 0x80)) Player.vibratoPos[channel] = 0; - if (!(Player.waveControl[channel] & 0x08)) Player.tremoloPos[channel] = 0; - } - - switch (effectNumber) { - case TONEPORTAMENTO: - if (effectParameter) Player.portamentoSpeed[channel] = effectParameter; - Player.portamentoNote[channel] = Player.amigaPeriod[channel]; - note = NONOTE; + delta = rand() & 255; break; + } - case VIBRATO: - if (effectParameterX) Player.vibratoSpeed[channel] = effectParameterX; - if (effectParameterY) Player.vibratoDepth[channel] = effectParameterY; - break; + delta *= Player.tremoloDepth[channel]; + delta >>= 6; - case PORTAMENTOVOLUMESLIDE: - Player.portamentoNote[channel] = Player.amigaPeriod[channel]; - note = NONOTE; - break; + if (Player.tremoloPos[channel] >= 0) { + if (Player.volume[channel] + delta > 64) { + delta = 64 - Player.volume[channel]; + } + Mixer.channelVolume[channel] = Player.volume[channel] + delta; + } else { + if (Player.volume[channel] - delta < 0) { + delta = Player.volume[channel]; + } + Mixer.channelVolume[channel] = Player.volume[channel] - delta; + } - case TREMOLO: - if (effectParameterX) Player.tremoloSpeed[channel] = effectParameterX; - if (effectParameterY) Player.tremoloDepth[channel] = effectParameterY; - break; + Player.tremoloPos[channel] += Player.tremoloSpeed[channel]; + if (Player.tremoloPos[channel] > 31) { + Player.tremoloPos[channel] -= 64; + } +} - case SETCHANNELPANNING: - Mixer.channelPanning[channel] = effectParameter >> 1; - break; +bool AudioGeneratorMOD::ProcessRow() { + bool jumpFlag; + bool breakFlag; + uint8_t channel; + uint8_t sampleNumber; + uint16_t note; + uint8_t effectNumber; + uint8_t effectParameter; + uint8_t effectParameterX; + uint8_t effectParameterY; + uint16_t sampleOffset; + + if (!running) { + return false; + } - case SETSAMPLEOFFSET: - sampleOffset = effectParameter << 8; - if (sampleOffset > Mod.samples[Player.lastSampleNumber[channel]].length) - sampleOffset = Mod.samples[Player.lastSampleNumber[channel]].length; - break; + Player.lastRow = Player.row++; + jumpFlag = false; + breakFlag = false; + for (channel = 0; channel < Mod.numberOfChannels; channel++) { - case JUMPTOORDER: - Player.orderIndex = effectParameter; - if (Player.orderIndex >= Mod.songLength) - Player.orderIndex = 0; - Player.row = 0; - jumpFlag = true; - break; + sampleNumber = Player.currentPattern.sampleNumber[Player.lastRow][channel]; + note = NOTE(Player.lastRow, channel); + effectNumber = Player.currentPattern.effectNumber[Player.lastRow][channel]; + effectParameter = Player.currentPattern.effectParameter[Player.lastRow][channel]; + effectParameterX = effectParameter >> 4; + effectParameterY = effectParameter & 0xF; + sampleOffset = 0; + + if (sampleNumber) { + Player.lastSampleNumber[channel] = sampleNumber - 1; + if (!(effectNumber == 0xE && effectParameterX == NOTEDELAY)) { + Player.volume[channel] = Mod.samples[Player.lastSampleNumber[channel]].volume; + } + } - case SETVOLUME: - if (effectParameter > 64) Player.volume[channel] = 64; - else Player.volume[channel] = effectParameter; - break; + if (note != NONOTE) { + Player.lastNote[channel] = note; + Player.amigaPeriod[channel] = ReadAmigaPeriods(note + Mod.samples[Player.lastSampleNumber[channel]].fineTune); - case BREAKPATTERNTOROW: - Player.row = effectParameterX * 10 + effectParameterY; - if (Player.row >= ROWS) - Player.row = 0; - if (!jumpFlag && !breakFlag) { - Player.orderIndex++; - if (Player.orderIndex >= Mod.songLength) - Player.orderIndex = 0; - } - breakFlag = true; - break; + if (effectNumber != TONEPORTAMENTO && effectNumber != PORTAMENTOVOLUMESLIDE) { + Player.lastAmigaPeriod[channel] = Player.amigaPeriod[channel]; + } - case 0xE: - switch (effectParameterX) { - case FINEPORTAMENTOUP: - Player.lastAmigaPeriod[channel] -= effectParameterY; - break; + if (!(Player.waveControl[channel] & 0x80)) { + Player.vibratoPos[channel] = 0; + } + if (!(Player.waveControl[channel] & 0x08)) { + Player.tremoloPos[channel] = 0; + } + } - case FINEPORTAMENTODOWN: - Player.lastAmigaPeriod[channel] += effectParameterY; + switch (effectNumber) { + case TONEPORTAMENTO: + if (effectParameter) { + Player.portamentoSpeed[channel] = effectParameter; + } + Player.portamentoNote[channel] = Player.amigaPeriod[channel]; + note = NONOTE; break; - case SETVIBRATOWAVEFORM: - Player.waveControl[channel] &= 0xF0; - Player.waveControl[channel] |= effectParameterY; + case VIBRATO: + if (effectParameterX) { + Player.vibratoSpeed[channel] = effectParameterX; + } + if (effectParameterY) { + Player.vibratoDepth[channel] = effectParameterY; + } break; - case SETFINETUNE: - Mod.samples[Player.lastSampleNumber[channel]].fineTune = effectParameterY; - if (Mod.samples[Player.lastSampleNumber[channel]].fineTune > 7) - Mod.samples[Player.lastSampleNumber[channel]].fineTune -= 16; + case PORTAMENTOVOLUMESLIDE: + Player.portamentoNote[channel] = Player.amigaPeriod[channel]; + note = NONOTE; break; - case PATTERNLOOP: + case TREMOLO: + if (effectParameterX) { + Player.tremoloSpeed[channel] = effectParameterX; + } if (effectParameterY) { - if (Player.patternLoopCount[channel]) - Player.patternLoopCount[channel]--; - else - Player.patternLoopCount[channel] = effectParameterY; - if (Player.patternLoopCount[channel]) - Player.row = Player.patternLoopRow[channel] - 1; - } else - Player.patternLoopRow[channel] = Player.row; + Player.tremoloDepth[channel] = effectParameterY; + } break; - case SETTREMOLOWAVEFORM: - Player.waveControl[channel] &= 0xF; - Player.waveControl[channel] |= effectParameterY << 4; + case SETCHANNELPANNING: + Mixer.channelPanning[channel] = effectParameter >> 1; break; - case FINEVOLUMESLIDEUP: - Player.volume[channel] += effectParameterY; - if (Player.volume[channel] > 64) Player.volume[channel] = 64; + case SETSAMPLEOFFSET: + sampleOffset = effectParameter << 8; + if (sampleOffset > Mod.samples[Player.lastSampleNumber[channel]].length) { + sampleOffset = Mod.samples[Player.lastSampleNumber[channel]].length; + } break; - case FINEVOLUMESLIDEDOWN: - Player.volume[channel] -= effectParameterY; - if (Player.volume[channel] < 0) Player.volume[channel] = 0; + case JUMPTOORDER: + Player.orderIndex = effectParameter; + if (Player.orderIndex >= Mod.songLength) { + Player.orderIndex = 0; + } + Player.row = 0; + jumpFlag = true; break; - case NOTECUT: - note = NONOTE; + case SETVOLUME: + if (effectParameter > 64) { + Player.volume[channel] = 64; + } else { + Player.volume[channel] = effectParameter; + } break; - case PATTERNDELAY: - Player.patternDelay = effectParameterY; + case BREAKPATTERNTOROW: + Player.row = effectParameterX * 10 + effectParameterY; + if (Player.row >= ROWS) { + Player.row = 0; + } + if (!jumpFlag && !breakFlag) { + Player.orderIndex++; + if (Player.orderIndex >= Mod.songLength) { + Player.orderIndex = 0; + } + } + breakFlag = true; break; - case INVERTLOOP: + case 0xE: + switch (effectParameterX) { + case FINEPORTAMENTOUP: + Player.lastAmigaPeriod[channel] -= effectParameterY; + break; - break; - } - break; + case FINEPORTAMENTODOWN: + Player.lastAmigaPeriod[channel] += effectParameterY; + break; - case SETSPEED: - if (effectParameter < 0x20) - Player.speed = effectParameter; - else - Player.samplesPerTick = sampleRate / (2 * effectParameter / 5); - break; - } + case SETVIBRATOWAVEFORM: + Player.waveControl[channel] &= 0xF0; + Player.waveControl[channel] |= effectParameterY; + break; - if (note != NONOTE || (Player.lastAmigaPeriod[channel] && - effectNumber != VIBRATO && effectNumber != VIBRATOVOLUMESLIDE && - !(effectNumber == 0xE && effectParameterX == NOTEDELAY))) - Mixer.channelFrequency[channel] = Player.amiga / Player.lastAmigaPeriod[channel]; + case SETFINETUNE: + Mod.samples[Player.lastSampleNumber[channel]].fineTune = effectParameterY; + if (Mod.samples[Player.lastSampleNumber[channel]].fineTune > 7) { + Mod.samples[Player.lastSampleNumber[channel]].fineTune -= 16; + } + break; - if (note != NONOTE) - Mixer.channelSampleOffset[channel] = sampleOffset << DIVIDER; + case PATTERNLOOP: + if (effectParameterY) { + if (Player.patternLoopCount[channel]) { + Player.patternLoopCount[channel]--; + } else { + Player.patternLoopCount[channel] = effectParameterY; + } + if (Player.patternLoopCount[channel]) { + Player.row = Player.patternLoopRow[channel] - 1; + } + } else { + Player.patternLoopRow[channel] = Player.row; + } + break; - if (sampleNumber) - Mixer.channelSampleNumber[channel] = Player.lastSampleNumber[channel]; + case SETTREMOLOWAVEFORM: + Player.waveControl[channel] &= 0xF; + Player.waveControl[channel] |= effectParameterY << 4; + break; - if (effectNumber != TREMOLO) - Mixer.channelVolume[channel] = Player.volume[channel]; + case FINEVOLUMESLIDEUP: + Player.volume[channel] += effectParameterY; + if (Player.volume[channel] > 64) { + Player.volume[channel] = 64; + } + break; - } - return true; -} + case FINEVOLUMESLIDEDOWN: + Player.volume[channel] -= effectParameterY; + if (Player.volume[channel] < 0) { + Player.volume[channel] = 0; + } + break; -bool AudioGeneratorMOD::ProcessTick() -{ - uint8_t channel; - uint8_t sampleNumber; - uint16_t note; - uint8_t effectNumber; - uint8_t effectParameter; - uint8_t effectParameterX; - uint8_t effectParameterY; - uint16_t tempNote; - - if (!running) return false; - - for (channel = 0; channel < Mod.numberOfChannels; channel++) { - - if (Player.lastAmigaPeriod[channel]) { - - sampleNumber = Player.currentPattern.sampleNumber[Player.lastRow][channel]; - // note = Player.currentPattern.note[Player.lastRow][channel]; - note = NOTE(Player.lastRow, channel); - effectNumber = Player.currentPattern.effectNumber[Player.lastRow][channel]; - effectParameter = Player.currentPattern.effectParameter[Player.lastRow][channel]; - effectParameterX = effectParameter >> 4; - effectParameterY = effectParameter & 0xF; - - switch (effectNumber) { - case ARPEGGIO: - if (effectParameter) - switch (Player.tick % 3) { - case 0: - Mixer.channelFrequency[channel] = Player.amiga / Player.lastAmigaPeriod[channel]; + case NOTECUT: + note = NONOTE; break; - case 1: - tempNote = Player.lastNote[channel] + effectParameterX * 8 + Mod.samples[Player.lastSampleNumber[channel]].fineTune; - if (tempNote < 296) Mixer.channelFrequency[channel] = Player.amiga / ReadAmigaPeriods(tempNote); + + case PATTERNDELAY: + Player.patternDelay = effectParameterY; break; - case 2: - tempNote = Player.lastNote[channel] + effectParameterY * 8 + Mod.samples[Player.lastSampleNumber[channel]].fineTune; - if (tempNote < 296) Mixer.channelFrequency[channel] = Player.amiga / ReadAmigaPeriods(tempNote); + + case INVERTLOOP: + break; } - break; + break; - case PORTAMENTOUP: - Player.lastAmigaPeriod[channel] -= effectParameter; - if (Player.lastAmigaPeriod[channel] < 113) Player.lastAmigaPeriod[channel] = 113; - Mixer.channelFrequency[channel] = Player.amiga / Player.lastAmigaPeriod[channel]; - break; + case SETSPEED: + if (effectParameter < 0x20) { + Player.speed = effectParameter; + } else { + Player.samplesPerTick = sampleRate / (2 * effectParameter / 5); + } + break; + } - case PORTAMENTODOWN: - Player.lastAmigaPeriod[channel] += effectParameter; - if (Player.lastAmigaPeriod[channel] > 856) Player.lastAmigaPeriod[channel] = 856; - Mixer.channelFrequency[channel] = Player.amiga / Player.lastAmigaPeriod[channel]; - break; + if (note != NONOTE || (Player.lastAmigaPeriod[channel] && + effectNumber != VIBRATO && effectNumber != VIBRATOVOLUMESLIDE && + !(effectNumber == 0xE && effectParameterX == NOTEDELAY))) { + Mixer.channelFrequency[channel] = Player.amiga / Player.lastAmigaPeriod[channel]; + } - case TONEPORTAMENTO: - Portamento(channel); - break; + if (note != NONOTE) { + Mixer.channelSampleOffset[channel] = sampleOffset << FIXED_DIVIDER; + } - case VIBRATO: - Vibrato(channel); - break; + if (sampleNumber) { + Mixer.channelSampleNumber[channel] = Player.lastSampleNumber[channel]; + } - case PORTAMENTOVOLUMESLIDE: - Portamento(channel); - Player.volume[channel] += effectParameterX - effectParameterY; - if (Player.volume[channel] < 0) Player.volume[channel] = 0; - else if (Player.volume[channel] > 64) Player.volume[channel] = 64; - Mixer.channelVolume[channel] = Player.volume[channel]; - break; - - case VIBRATOVOLUMESLIDE: - Vibrato(channel); - Player.volume[channel] += effectParameterX - effectParameterY; - if (Player.volume[channel] < 0) Player.volume[channel] = 0; - else if (Player.volume[channel] > 64) Player.volume[channel] = 64; - Mixer.channelVolume[channel] = Player.volume[channel]; - break; + if (effectNumber != TREMOLO) { + Mixer.channelVolume[channel] = Player.volume[channel]; + } - case TREMOLO: - Tremolo(channel); - break; + } + return true; +} - case VOLUMESLIDE: - Player.volume[channel] += effectParameterX - effectParameterY; - if (Player.volume[channel] < 0) Player.volume[channel] = 0; - else if (Player.volume[channel] > 64) Player.volume[channel] = 64; - Mixer.channelVolume[channel] = Player.volume[channel]; - break; +bool AudioGeneratorMOD::ProcessTick() { + uint8_t channel; + uint8_t sampleNumber; + uint16_t note; + uint8_t effectNumber; + uint8_t effectParameter; + uint8_t effectParameterX; + uint8_t effectParameterY; + uint16_t tempNote; + + if (!running) { + return false; + } - case 0xE: - switch (effectParameterX) { - case RETRIGGERNOTE: - if (!effectParameterY) break; - if (!(Player.tick % effectParameterY)) { - Mixer.channelSampleOffset[channel] = 0; - } - break; + for (channel = 0; channel < Mod.numberOfChannels; channel++) { - case NOTECUT: - if (Player.tick == effectParameterY) - Mixer.channelVolume[channel] = Player.volume[channel] = 0; - break; - - case NOTEDELAY: - if (Player.tick == effectParameterY) { - if (sampleNumber) Player.volume[channel] = Mod.samples[Player.lastSampleNumber[channel]].volume; - if (note != NONOTE) Mixer.channelSampleOffset[channel] = 0; + if (Player.lastAmigaPeriod[channel]) { + + sampleNumber = Player.currentPattern.sampleNumber[Player.lastRow][channel]; + // note = Player.currentPattern.note[Player.lastRow][channel]; + note = NOTE(Player.lastRow, channel); + effectNumber = Player.currentPattern.effectNumber[Player.lastRow][channel]; + effectParameter = Player.currentPattern.effectParameter[Player.lastRow][channel]; + effectParameterX = effectParameter >> 4; + effectParameterY = effectParameter & 0xF; + + switch (effectNumber) { + case ARPEGGIO: + if (effectParameter) + switch (Player.tick % 3) { + case 0: + Mixer.channelFrequency[channel] = Player.amiga / Player.lastAmigaPeriod[channel]; + break; + case 1: + tempNote = Player.lastNote[channel] + effectParameterX * 8 + Mod.samples[Player.lastSampleNumber[channel]].fineTune; + if (tempNote < 296) { + Mixer.channelFrequency[channel] = Player.amiga / ReadAmigaPeriods(tempNote); + } + break; + case 2: + tempNote = Player.lastNote[channel] + effectParameterY * 8 + Mod.samples[Player.lastSampleNumber[channel]].fineTune; + if (tempNote < 296) { + Mixer.channelFrequency[channel] = Player.amiga / ReadAmigaPeriods(tempNote); + } + break; + } + break; + + case PORTAMENTOUP: + Player.lastAmigaPeriod[channel] -= effectParameter; + if (Player.lastAmigaPeriod[channel] < 113) { + Player.lastAmigaPeriod[channel] = 113; + } + Mixer.channelFrequency[channel] = Player.amiga / Player.lastAmigaPeriod[channel]; + break; + + case PORTAMENTODOWN: + Player.lastAmigaPeriod[channel] += effectParameter; + if (Player.lastAmigaPeriod[channel] > 856) { + Player.lastAmigaPeriod[channel] = 856; + } Mixer.channelFrequency[channel] = Player.amiga / Player.lastAmigaPeriod[channel]; + break; + + case TONEPORTAMENTO: + Portamento(channel); + break; + + case VIBRATO: + Vibrato(channel); + break; + + case PORTAMENTOVOLUMESLIDE: + Portamento(channel); + Player.volume[channel] += effectParameterX - effectParameterY; + if (Player.volume[channel] < 0) { + Player.volume[channel] = 0; + } else if (Player.volume[channel] > 64) { + Player.volume[channel] = 64; + } Mixer.channelVolume[channel] = Player.volume[channel]; - } - break; - } - break; - } + break; - } + case VIBRATOVOLUMESLIDE: + Vibrato(channel); + Player.volume[channel] += effectParameterX - effectParameterY; + if (Player.volume[channel] < 0) { + Player.volume[channel] = 0; + } else if (Player.volume[channel] > 64) { + Player.volume[channel] = 64; + } + Mixer.channelVolume[channel] = Player.volume[channel]; + break; - } - return true; -} + case TREMOLO: + Tremolo(channel); + break; + + case VOLUMESLIDE: + Player.volume[channel] += effectParameterX - effectParameterY; + if (Player.volume[channel] < 0) { + Player.volume[channel] = 0; + } else if (Player.volume[channel] > 64) { + Player.volume[channel] = 64; + } + Mixer.channelVolume[channel] = Player.volume[channel]; + break; -bool AudioGeneratorMOD::RunPlayer() -{ - if (!running) return false; + case 0xE: + switch (effectParameterX) { + case RETRIGGERNOTE: + if (!effectParameterY) { + break; + } + if (!(Player.tick % effectParameterY)) { + Mixer.channelSampleOffset[channel] = 0; + } + break; + + case NOTECUT: + if (Player.tick == effectParameterY) { + Mixer.channelVolume[channel] = Player.volume[channel] = 0; + } + break; + + case NOTEDELAY: + if (Player.tick == effectParameterY) { + if (sampleNumber) { + Player.volume[channel] = Mod.samples[Player.lastSampleNumber[channel]].volume; + } + if (note != NONOTE) { + Mixer.channelSampleOffset[channel] = 0; + } + Mixer.channelFrequency[channel] = Player.amiga / Player.lastAmigaPeriod[channel]; + Mixer.channelVolume[channel] = Player.volume[channel]; + } + break; + } + break; + } - if (Player.tick == Player.speed) { - Player.tick = 0; + } - if (Player.row == ROWS) { - Player.orderIndex++; - if (Player.orderIndex == Mod.songLength) - { - //Player.orderIndex = 0; - // No loop, just say we're done! + } + return true; +} + +bool AudioGeneratorMOD::RunPlayer() { + if (!running) { return false; - } - Player.row = 0; } - if (Player.patternDelay) { - Player.patternDelay--; + if (Player.tick == Player.speed) { + Player.tick = 0; + + if (Player.row == ROWS) { + Player.orderIndex++; + if (Player.orderIndex == Mod.songLength) { + //Player.orderIndex = 0; + // No loop, just say we're done! + return false; + } + Player.row = 0; + } + + if (Player.patternDelay) { + Player.patternDelay--; + } else { + if (Player.orderIndex != Player.oldOrderIndex) + if (!LoadPattern(Mod.order[Player.orderIndex])) { + return false; + } + Player.oldOrderIndex = Player.orderIndex; + if (!ProcessRow()) { + return false; + } + } + } else { - if (Player.orderIndex != Player.oldOrderIndex) - if (!LoadPattern(Mod.order[Player.orderIndex])) return false; - Player.oldOrderIndex = Player.orderIndex; - if (!ProcessRow()) return false; + if (!ProcessTick()) { + return false; + } } - - } else { - if (!ProcessTick()) return false; - } - Player.tick++; - return true; + Player.tick++; + return true; } -void AudioGeneratorMOD::GetSample(int16_t sample[2]) -{ - int16_t sumL; - int16_t sumR; - uint8_t channel; - uint32_t samplePointer; - int8_t current; - int8_t next; - int16_t out; +void AudioGeneratorMOD::GetSample(int16_t sample[2]) { + int32_t sumL; + int32_t sumR; + uint8_t channel; + uint32_t samplePointer; + int8_t current; + int8_t next; + int16_t out; + int32_t out32; + + if (!running) { + return; + } - if (!running) return; + sumL = 0; + sumR = 0; + for (channel = 0; channel < Mod.numberOfChannels; channel++) { - sumL = 0; - sumR = 0; - for (channel = 0; channel < Mod.numberOfChannels; channel++) { + if (!Mixer.channelFrequency[channel] || + !Mod.samples[Mixer.channelSampleNumber[channel]].length) { + continue; + } - if (!Mixer.channelFrequency[channel] || - !Mod.samples[Mixer.channelSampleNumber[channel]].length) continue; + Mixer.channelSampleOffset[channel] += Mixer.channelFrequency[channel]; - Mixer.channelSampleOffset[channel] += Mixer.channelFrequency[channel]; + if (!Mixer.channelVolume[channel]) { + continue; + } - if (!Mixer.channelVolume[channel]) continue; + samplePointer = Mixer.sampleBegin[Mixer.channelSampleNumber[channel]] + + (Mixer.channelSampleOffset[channel] >> FIXED_DIVIDER); - samplePointer = Mixer.sampleBegin[Mixer.channelSampleNumber[channel]] + - (Mixer.channelSampleOffset[channel] >> DIVIDER); + if (Mixer.sampleLoopLength[Mixer.channelSampleNumber[channel]]) { - if (Mixer.sampleLoopLength[Mixer.channelSampleNumber[channel]]) { + if (samplePointer >= Mixer.sampleLoopEnd[Mixer.channelSampleNumber[channel]]) { + Mixer.channelSampleOffset[channel] -= Mixer.sampleLoopLength[Mixer.channelSampleNumber[channel]] << FIXED_DIVIDER; + samplePointer -= Mixer.sampleLoopLength[Mixer.channelSampleNumber[channel]]; + } - if (samplePointer >= Mixer.sampleLoopEnd[Mixer.channelSampleNumber[channel]]) { - Mixer.channelSampleOffset[channel] -= Mixer.sampleLoopLength[Mixer.channelSampleNumber[channel]] << DIVIDER; - samplePointer -= Mixer.sampleLoopLength[Mixer.channelSampleNumber[channel]]; - } + } else { - } else { + if (samplePointer >= Mixer.sampleEnd[Mixer.channelSampleNumber[channel]]) { + Mixer.channelFrequency[channel] = 0; + samplePointer = Mixer.sampleEnd[Mixer.channelSampleNumber[channel]]; + } - if (samplePointer >= Mixer.sampleEnd[Mixer.channelSampleNumber[channel]]) { - Mixer.channelFrequency[channel] = 0; - samplePointer = Mixer.sampleEnd[Mixer.channelSampleNumber[channel]]; - } + } - } + if (samplePointer < FatBuffer.samplePointer[channel] || + samplePointer >= FatBuffer.samplePointer[channel] + fatBufferSize - 1 || + Mixer.channelSampleNumber[channel] != FatBuffer.channelSampleNumber[channel]) { - if (samplePointer < FatBuffer.samplePointer[channel] || - samplePointer >= FatBuffer.samplePointer[channel] + fatBufferSize - 1 || - Mixer.channelSampleNumber[channel] != FatBuffer.channelSampleNumber[channel]) { + uint32_t toRead = Mixer.sampleEnd[Mixer.channelSampleNumber[channel]] - samplePointer + 1; + if (toRead > (uint32_t)fatBufferSize) { + toRead = fatBufferSize; + } - uint16_t toRead = Mixer.sampleEnd[Mixer.channelSampleNumber[channel]] - samplePointer + 1; - if (toRead > fatBufferSize) toRead = fatBufferSize; + if (!file->seek(samplePointer, SEEK_SET)) { + stop(); + return; + } + if (toRead != file->read(FatBuffer.channels[channel], toRead)) { + stop(); + return; + } - if (!file->seek(samplePointer, SEEK_SET)) { - stop(); - return; - } - if (toRead != file->read(FatBuffer.channels[channel], toRead)) { - stop(); - return; - } + FatBuffer.samplePointer[channel] = samplePointer; + FatBuffer.channelSampleNumber[channel] = Mixer.channelSampleNumber[channel]; + } - FatBuffer.samplePointer[channel] = samplePointer; - FatBuffer.channelSampleNumber[channel] = Mixer.channelSampleNumber[channel]; - } + current = FatBuffer.channels[channel][(samplePointer - FatBuffer.samplePointer[channel]) /*& (FATBUFFERSIZE - 1)*/]; + next = FatBuffer.channels[channel][(samplePointer + 1 - FatBuffer.samplePointer[channel]) /*& (FATBUFFERSIZE - 1)*/]; + + // preserve a few more bits from sample interpolation, by upscaling input values. + // This does (slightly) reduce quantization noise in higher frequencies, typically above 8kHz. + // Actually we could could even gain more bits, I was just not sure if more bits would cause overflows in other conputations. + int16_t current16 = (int16_t) current << 2; + int16_t next16 = (int16_t) next << 2; - current = FatBuffer.channels[channel][(samplePointer - FatBuffer.samplePointer[channel]) /*& (FATBUFFERSIZE - 1)*/]; - next = FatBuffer.channels[channel][(samplePointer + 1 - FatBuffer.samplePointer[channel]) /*& (FATBUFFERSIZE - 1)*/]; + out = current16; - out = current; + // Integer linear interpolation - only works correctly in 16bit + out += (next16 - current16) * (Mixer.channelSampleOffset[channel] & ((1 << FIXED_DIVIDER) - 1)) >> FIXED_DIVIDER; - // Integer linear interpolation - out += (next - current) * (Mixer.channelSampleOffset[channel] & ((1 << DIVIDER) - 1)) >> DIVIDER; + // Upscale to BITDEPTH, considering the we already gained two bits in the previous step + out32 = (int32_t)out << (BITDEPTH - 10); - // Upscale to BITDEPTH - out <<= BITDEPTH - 8; + // Channel volume + out32 = out32 * Mixer.channelVolume[channel] >> 6; - // Channel volume - out = out * Mixer.channelVolume[channel] >> 6; + // Channel panning + sumL += out32 * min(128 - Mixer.channelPanning[channel], 64) >> 6; + sumR += out32 * min(Mixer.channelPanning[channel], 64) >> 6; + } - // Channel panning - sumL += out * min(128 - Mixer.channelPanning[channel], 64) >> 6; - sumR += out * min(Mixer.channelPanning[channel], 64) >> 6; - } + // Downscale to BITDEPTH - a bit faster because the compiler can replaced division by constants with proper "right shift" + correct handling of sign bit + if (Mod.numberOfChannels <= 4) { + // up to 4 channels + sumL /= 4; + sumR /= 4; + } else { + if (Mod.numberOfChannels <= 6) { + // 5 or 6 channels - pre-multiply be 1.5, then divide by 8 -> same as division by 6 + sumL = (sumL + (sumL / 2)) / 8; + sumR = (sumR + (sumR / 2)) / 8; + } else { + // 7,8, or more channels + sumL /= 8; + sumR /= 8; + } + } - // Downscale to BITDEPTH - sumL /= Mod.numberOfChannels; - sumR /= Mod.numberOfChannels; + // clip samples to 16bit (with saturation in case of overflow) + if (sumL <= INT16_MIN) { + sumL = INT16_MIN; + } else if (sumL >= INT16_MAX) { + sumL = INT16_MAX; + } + if (sumR <= INT16_MIN) { + sumR = INT16_MIN; + } else if (sumR >= INT16_MAX) { + sumR = INT16_MAX; + } - // Fill the sound buffer with unsigned values - sample[AudioOutput::LEFTCHANNEL] = sumL + (1 << (BITDEPTH - 1)); - sample[AudioOutput::RIGHTCHANNEL] = sumR + (1 << (BITDEPTH - 1)); + // Fill the sound buffer with signed values + sample[AudioOutput::LEFTCHANNEL] = sumL; + sample[AudioOutput::RIGHTCHANNEL] = sumR; } -bool AudioGeneratorMOD::LoadMOD() -{ - uint8_t channel; +bool AudioGeneratorMOD::LoadMOD() { + uint8_t channel; - if (!LoadHeader()) return false; - LoadSamples(); + if (!LoadHeader()) { + return false; + } + LoadSamples(); - Player.amiga = AMIGA; - Player.samplesPerTick = sampleRate / (2 * 125 / 5); // Hz = 2 * BPM / 5 - Player.speed = 6; - Player.tick = Player.speed; - Player.row = 0; + Player.amiga = AMIGA; + Player.samplesPerTick = sampleRate / (2 * 125 / 5); // Hz = 2 * BPM / 5 + Player.speed = 6; + Player.tick = Player.speed; + Player.row = 0; - Player.orderIndex = 0; - Player.oldOrderIndex = 0xFF; - Player.patternDelay = 0; + Player.orderIndex = 0; + Player.oldOrderIndex = 0xFF; + Player.patternDelay = 0; - for (channel = 0; channel < Mod.numberOfChannels; channel++) { - Player.patternLoopCount[channel] = 0; - Player.patternLoopRow[channel] = 0; + for (channel = 0; channel < Mod.numberOfChannels; channel++) { + Player.patternLoopCount[channel] = 0; + Player.patternLoopRow[channel] = 0; - Player.lastAmigaPeriod[channel] = 0; + Player.lastAmigaPeriod[channel] = 0; - Player.waveControl[channel] = 0; + Player.waveControl[channel] = 0; - Player.vibratoSpeed[channel] = 0; - Player.vibratoDepth[channel] = 0; - Player.vibratoPos[channel] = 0; + Player.vibratoSpeed[channel] = 0; + Player.vibratoDepth[channel] = 0; + Player.vibratoPos[channel] = 0; - Player.tremoloSpeed[channel] = 0; - Player.tremoloDepth[channel] = 0; - Player.tremoloPos[channel] = 0; + Player.tremoloSpeed[channel] = 0; + Player.tremoloDepth[channel] = 0; + Player.tremoloPos[channel] = 0; - FatBuffer.samplePointer[channel] = 0; - FatBuffer.channelSampleNumber[channel] = 0xFF; + FatBuffer.samplePointer[channel] = 0; + FatBuffer.channelSampleNumber[channel] = 0xFF; - Mixer.channelSampleOffset[channel] = 0; - Mixer.channelFrequency[channel] = 0; - Mixer.channelVolume[channel] = 0; - switch (channel % 4) { - case 0: - case 3: - Mixer.channelPanning[channel] = stereoSeparation; - break; - default: - Mixer.channelPanning[channel] = 128 - stereoSeparation; + Mixer.channelSampleOffset[channel] = 0; + Mixer.channelFrequency[channel] = 0; + Mixer.channelVolume[channel] = 0; + switch (channel % 4) { + case 0: + case 3: + Mixer.channelPanning[channel] = stereoSeparation; + break; + default: + Mixer.channelPanning[channel] = 128 - stereoSeparation; + } } - } - return true; + return true; } diff --git a/src/AudioGeneratorMOD.h b/src/AudioGeneratorMOD.h index 87fac18e..09e1ea19 100644 --- a/src/AudioGeneratorMOD.h +++ b/src/AudioGeneratorMOD.h @@ -1,21 +1,21 @@ /* - AudioGeneratorMOD - Audio output generator that plays Amiga MOD tracker files - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioGeneratorMOD + Audio output generator that plays Amiga MOD tracker files + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOGENERATORMOD_H @@ -23,21 +23,42 @@ #include "AudioGenerator.h" -class AudioGeneratorMOD : public AudioGenerator -{ - public: +class AudioGeneratorMOD : public AudioGenerator { +public: AudioGeneratorMOD(); virtual ~AudioGeneratorMOD() override; virtual bool begin(AudioFileSource *source, AudioOutput *output) override; virtual bool loop() override; virtual bool stop() override; - virtual bool isRunning() override { return running; } - bool SetSampleRate(int hz) { if (running || (hz < 1) || (hz > 96000) ) return false; sampleRate = hz; return true; } - bool SetBufferSize(int sz) { if (running || (sz < 1) ) return false; fatBufferSize = sz; return true; } - bool SetStereoSeparation(int sep) { if (running || (sep<0) || (sep>64)) return false; stereoSeparation = sep; return true; } - bool SetPAL(bool use) { if (running) return false; usePAL = use; return true; } + virtual bool isRunning() override { + return running; + } + bool SetSampleRate(int hz) { + if (running || (hz < 1) || (hz > 96000)) { + return false; + } sampleRate = hz; + return true; + } + bool SetBufferSize(int sz) { + if (running || (sz < 1)) { + return false; + } fatBufferSize = sz; + return true; + } + bool SetStereoSeparation(int sep) { + if (running || (sep < 0) || (sep > 64)) { + return false; + } stereoSeparation = sep; + return true; + } + bool SetPAL(bool use) { + if (running) { + return false; + } usePAL = use; + return true; + } - protected: +protected: bool LoadMOD(); bool LoadHeader(); void GetSample(int16_t sample[2]); @@ -51,112 +72,122 @@ class AudioGeneratorMOD : public AudioGenerator void Vibrato(uint8_t channel); - protected: +protected: int mixerTick; - enum {BITDEPTH = 15}; - int sampleRate; + enum {BITDEPTH = 16}; + int sampleRate; int fatBufferSize; //(6*1024) // File system buffers per-CHANNEL (i.e. total mem required is 4 * FATBUFFERSIZE) - enum {DIVIDER = 10}; // Fixed-point mantissa used for integer arithmetic + enum {FIXED_DIVIDER = 10}; // Fixed-point mantissa used for integer arithmetic int stereoSeparation; //STEREOSEPARATION = 32; // 0 (max) to 64 (mono) bool usePAL; - + // Hz = 7093789 / (amigaPeriod * 2) for PAL // Hz = 7159091 / (amigaPeriod * 2) for NTSC int AMIGA; - void UpdateAmiga() { AMIGA = ((usePAL?7159091:7093789) / 2 / sampleRate << DIVIDER); } - + void UpdateAmiga() { + AMIGA = ((usePAL ? 7159091 : 7093789) / 2 / sampleRate << FIXED_DIVIDER); + } + +#ifdef ESP8266 // Not sure if C3/C2 have RAM constraints, maybe add them here? + // support max 4 channels enum {ROWS = 64, SAMPLES = 31, CHANNELS = 4, NONOTE = 0xFFFF, NONOTE8 = 0xff }; +#else + // support max 8 channels + enum {ROWS = 64, SAMPLES = 31, CHANNELS = 8, NONOTE = 0xFFFF, NONOTE8 = 0xff }; +#endif typedef struct Sample { - uint16_t length; - int8_t fineTune; - uint8_t volume; - uint16_t loopBegin; - uint16_t loopLength; + uint16_t length; + int8_t fineTune; + uint8_t volume; + uint16_t loopBegin; + uint16_t loopLength; } Sample; - + typedef struct mod { - Sample samples[SAMPLES]; - uint8_t songLength; - uint8_t numberOfPatterns; - uint8_t order[128]; - uint8_t numberOfChannels; + Sample samples[SAMPLES]; + uint8_t songLength; + uint8_t numberOfPatterns; + uint8_t order[128]; + uint8_t numberOfChannels; } mod; - + // Save 256 bytes by storing raw note values, unpack with macro NOTE typedef struct Pattern { - uint8_t sampleNumber[ROWS][CHANNELS]; - uint8_t note8[ROWS][CHANNELS]; - uint8_t effectNumber[ROWS][CHANNELS]; - uint8_t effectParameter[ROWS][CHANNELS]; + uint8_t sampleNumber[ROWS][CHANNELS]; + uint8_t note8[ROWS][CHANNELS]; + uint8_t effectNumber[ROWS][CHANNELS]; + uint8_t effectParameter[ROWS][CHANNELS]; } Pattern; - + typedef struct player { - Pattern currentPattern; - - uint32_t amiga; - uint16_t samplesPerTick; - uint8_t speed; - uint8_t tick; - uint8_t row; - uint8_t lastRow; - - uint8_t orderIndex; - uint8_t oldOrderIndex; - uint8_t patternDelay; - uint8_t patternLoopCount[CHANNELS]; - uint8_t patternLoopRow[CHANNELS]; - - uint8_t lastSampleNumber[CHANNELS]; - int8_t volume[CHANNELS]; - uint16_t lastNote[CHANNELS]; - uint16_t amigaPeriod[CHANNELS]; - int16_t lastAmigaPeriod[CHANNELS]; - - uint16_t portamentoNote[CHANNELS]; - uint8_t portamentoSpeed[CHANNELS]; - - uint8_t waveControl[CHANNELS]; - - uint8_t vibratoSpeed[CHANNELS]; - uint8_t vibratoDepth[CHANNELS]; - int8_t vibratoPos[CHANNELS]; - - uint8_t tremoloSpeed[CHANNELS]; - uint8_t tremoloDepth[CHANNELS]; - int8_t tremoloPos[CHANNELS]; + Pattern currentPattern; + + uint32_t amiga; + uint16_t samplesPerTick; + uint8_t speed; + uint8_t tick; + uint8_t row; + uint8_t lastRow; + + uint8_t orderIndex; + uint8_t oldOrderIndex; + uint8_t patternDelay; + uint8_t patternLoopCount[CHANNELS]; + uint8_t patternLoopRow[CHANNELS]; + + uint8_t lastSampleNumber[CHANNELS]; + int8_t volume[CHANNELS]; + uint16_t lastNote[CHANNELS]; + uint16_t amigaPeriod[CHANNELS]; + int16_t lastAmigaPeriod[CHANNELS]; + + uint16_t portamentoNote[CHANNELS]; + uint8_t portamentoSpeed[CHANNELS]; + + uint8_t waveControl[CHANNELS]; + + uint8_t vibratoSpeed[CHANNELS]; + uint8_t vibratoDepth[CHANNELS]; + int8_t vibratoPos[CHANNELS]; + + uint8_t tremoloSpeed[CHANNELS]; + uint8_t tremoloDepth[CHANNELS]; + int8_t tremoloPos[CHANNELS]; } player; - + typedef struct mixer { - uint32_t sampleBegin[SAMPLES]; - uint32_t sampleEnd[SAMPLES]; - uint32_t sampleloopBegin[SAMPLES]; - uint16_t sampleLoopLength[SAMPLES]; - uint32_t sampleLoopEnd[SAMPLES]; - - uint8_t channelSampleNumber[CHANNELS]; - uint32_t channelSampleOffset[CHANNELS]; - uint16_t channelFrequency[CHANNELS]; - uint8_t channelVolume[CHANNELS]; - uint8_t channelPanning[CHANNELS]; + uint32_t sampleBegin[SAMPLES]; + uint32_t sampleEnd[SAMPLES]; + uint32_t sampleloopBegin[SAMPLES]; + uint16_t sampleLoopLength[SAMPLES]; + uint32_t sampleLoopEnd[SAMPLES]; + + uint8_t channelSampleNumber[CHANNELS]; + uint32_t channelSampleOffset[CHANNELS]; + uint16_t channelFrequency[CHANNELS]; + uint8_t channelVolume[CHANNELS]; + uint8_t channelPanning[CHANNELS]; } mixer; - + typedef struct fatBuffer { - uint8_t *channels[CHANNELS]; // Make dynamically allocated [FATBUFFERSIZE]; - uint32_t samplePointer[CHANNELS]; - uint8_t channelSampleNumber[CHANNELS]; + uint8_t *channels[CHANNELS]; // Make dynamically allocated [FATBUFFERSIZE]; + uint32_t samplePointer[CHANNELS]; + uint8_t channelSampleNumber[CHANNELS]; } fatBuffer; // Effects typedef enum { ARPEGGIO = 0, PORTAMENTOUP, PORTAMENTODOWN, TONEPORTAMENTO, VIBRATO, PORTAMENTOVOLUMESLIDE, VIBRATOVOLUMESLIDE, TREMOLO, SETCHANNELPANNING, SETSAMPLEOFFSET, VOLUMESLIDE, JUMPTOORDER, - SETVOLUME, BREAKPATTERNTOROW, ESUBSET, SETSPEED } EffectsValues; - + SETVOLUME, BREAKPATTERNTOROW, ESUBSET, SETSPEED + } EffectsValues; + // 0xE subset typedef enum { SETFILTER = 0, FINEPORTAMENTOUP, FINEPORTAMENTODOWN, GLISSANDOCONTROL, SETVIBRATOWAVEFORM, SETFINETUNE, PATTERNLOOP, SETTREMOLOWAVEFORM, SUBEFFECT8, RETRIGGERNOTE, FINEVOLUMESLIDEUP, - FINEVOLUMESLIDEDOWN, NOTECUT, NOTEDELAY, PATTERNDELAY, INVERTLOOP } Effect08Subvalues; - + FINEVOLUMESLIDEDOWN, NOTECUT, NOTEDELAY, PATTERNDELAY, INVERTLOOP + } Effect08Subvalues; + // Our state lives here... player Player; mod Mod; diff --git a/src/AudioGeneratorMP3.cpp b/src/AudioGeneratorMP3.cpp index 7c09289c..ddfd9712 100644 --- a/src/AudioGeneratorMP3.cpp +++ b/src/AudioGeneratorMP3.cpp @@ -1,352 +1,447 @@ /* - AudioGeneratorMP3 - Wrap libmad MP3 library to play audio - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioGeneratorMP3 + Wrap libmad MP3 library to play audio + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include "AudioGeneratorMP3.h" -AudioGeneratorMP3::AudioGeneratorMP3() -{ - running = false; - file = NULL; - output = NULL; - buff = NULL; - nsCountMax = 1152/32; - madInitted = false; - preallocateSpace = NULL; - preallocateSize = 0; +AudioGeneratorMP3::AudioGeneratorMP3() { + running = false; + file = NULL; + output = NULL; + buff = NULL; + synth = NULL; + frame = NULL; + stream = NULL; + nsCountMax = 1152 / 32; + madInitted = false; +} + +AudioGeneratorMP3::AudioGeneratorMP3(void *space, int size): preallocateSpace(space), preallocateSize(size) { + running = false; + file = NULL; + output = NULL; + buff = NULL; + synth = NULL; + frame = NULL; + stream = NULL; + nsCountMax = 1152 / 32; + madInitted = false; } -AudioGeneratorMP3::AudioGeneratorMP3(void *space, int size) -{ - running = false; - file = NULL; - output = NULL; - buff = NULL; - nsCountMax = 1152/32; - madInitted = false; - preallocateSpace = space; - preallocateSize = size; +AudioGeneratorMP3::AudioGeneratorMP3(void *buff, int buffSize, void *stream, int streamSize, void *frame, int frameSize, void *synth, int synthSize): + preallocateSpace(buff), preallocateSize(buffSize), + preallocateStreamSpace(stream), preallocateStreamSize(streamSize), + preallocateFrameSpace(frame), preallocateFrameSize(frameSize), + preallocateSynthSpace(synth), preallocateSynthSize(synthSize) { + running = false; + file = NULL; + output = NULL; + buff = NULL; + synth = NULL; + frame = NULL; + stream = NULL; + nsCountMax = 1152 / 32; + madInitted = false; } -AudioGeneratorMP3::~AudioGeneratorMP3() -{ - if (!preallocateSpace) { - free(buff); - free(synth); - free(frame); - free(stream); - } +AudioGeneratorMP3::~AudioGeneratorMP3() { + if (!preallocateSpace) { + free(buff); + free(synth); + free(frame); + free(stream); + } } -bool AudioGeneratorMP3::stop() -{ - if (madInitted) { - mad_synth_finish(synth); - mad_frame_finish(frame); - mad_stream_finish(stream); - madInitted = false; - } - - if (!preallocateSpace) { - free(buff); - free(synth); - free(frame); - free(stream); - } - - buff = NULL; - synth = NULL; - frame = NULL; - stream = NULL; - - running = false; - output->stop(); - return file->close(); +bool AudioGeneratorMP3::stop() { + if (madInitted) { + mad_synth_finish(synth); + mad_frame_finish(frame); + mad_stream_finish(stream); + madInitted = false; + } + + if (!preallocateSpace) { + free(buff); + free(synth); + free(frame); + free(stream); + } + + buff = NULL; + synth = NULL; + frame = NULL; + stream = NULL; + + running = false; + output->stop(); + return file->close(); } -bool AudioGeneratorMP3::isRunning() -{ - return running; +bool AudioGeneratorMP3::isRunning() { + return running; } -enum mad_flow AudioGeneratorMP3::ErrorToFlow() -{ - char err[64]; - char errLine[128]; +enum mad_flow AudioGeneratorMP3::ErrorToFlow() { + char err[64]; + char errLine[128]; - // Special case - eat "lost sync @ byte 0" as it always occurs and is not really correct....it never had sync! - if ((lastReadPos==0) && (stream->error==MAD_ERROR_LOSTSYNC)) return MAD_FLOW_CONTINUE; + // Special case - eat "lost sync @ byte 0" as it always occurs and is not really correct....it never had sync! + if ((lastReadPos == 0) && (stream->error == MAD_ERROR_LOSTSYNC)) { + return MAD_FLOW_CONTINUE; + } - strcpy_P(err, mad_stream_errorstr(stream)); - snprintf_P(errLine, sizeof(errLine), PSTR("Decoding error '%s' at byte offset %d"), - err, (stream->this_frame - buff) + lastReadPos); - yield(); // Something bad happened anyway, ensure WiFi gets some time, too - cb.st(stream->error, errLine); - return MAD_FLOW_CONTINUE; + strcpy_P(err, mad_stream_errorstr(stream)); + snprintf_P(errLine, sizeof(errLine), PSTR("Decoding error '%s' at byte offset %d"), + err, (stream->this_frame - buff) + lastReadPos); + yield(); // Something bad happened anyway, ensure WiFi gets some time, too + cb.st(stream->error, errLine); + return MAD_FLOW_CONTINUE; } -enum mad_flow AudioGeneratorMP3::Input() -{ - int unused = 0; - - if (stream->next_frame) { - unused = lastBuffLen - (stream->next_frame - buff); - memmove(buff, stream->next_frame, unused); - stream->next_frame = NULL; - } - - if (unused == lastBuffLen) { - // Something wicked this way came, throw it all out and try again - unused = 0; - } - - lastReadPos = file->getPos() - unused; - int len = buffLen - unused; - len = file->read(buff + unused, len); - if ((len == 0) && (unused == 0)) { - // Can't read any from the file, and we don't have anything left. It's done.... - return MAD_FLOW_STOP; - } - - lastBuffLen = len + unused; - mad_stream_buffer(stream, buff, lastBuffLen); - - return MAD_FLOW_CONTINUE; +enum mad_flow AudioGeneratorMP3::Input() { + int unused = 0; + + if (stream->next_frame) { + unused = lastBuffLen - (stream->next_frame - buff); + if (unused < 0) { + desync(); + unused = 0; + } else { + memmove(buff, stream->next_frame, unused); + } + stream->next_frame = NULL; + } + + if (unused == lastBuffLen) { + // Something wicked this way came, throw it all out and try again + unused = 0; + } + + bool foundHeader = false; + do { + lastReadPos = file->getPos() - unused; + int len = buffLen - unused; + len = file->read(buff + unused, len); + if ((len == 0) && (unused == 0)) { + // Can't read any from the file, and we don't have anything left. It's done.... + return MAD_FLOW_STOP; + } + if (len < 0) { + desync(); + unused = 0; + } + + lastBuffLen = len + unused; + for (int i = 0; i < lastBuffLen; i++) { + if ((buff[i] == 0xff) && ((buff[i + 1] & 0xe0) == 0xe0)) { + // We have a header! + if (i) { + memmove(buff, buff + i, lastBuffLen - i); + lastBuffLen -= i; + } + foundHeader = true; + break; + } + } + if (!foundHeader) { + unused = 0; + } else { + // Try and fill rest of buffer in case there was some shiftage + len = file->read(buff + lastBuffLen, buffLen - lastBuffLen); + if (len < 0) { + desync(); + unused = 0; + } + lastBuffLen += len; + if (lastBuffLen < 8) { + return MAD_FLOW_STOP; + } + } + } while (!foundHeader); + + mad_stream_buffer(stream, buff, lastBuffLen); + + return MAD_FLOW_CONTINUE; } +void AudioGeneratorMP3::desync() { + audioLogger->printf_P(PSTR("MP3:desync\n")); + if (stream) { + stream->next_frame = nullptr; + stream->this_frame = nullptr; + stream->sync = 0; + } + lastBuffLen = 0; +} -bool AudioGeneratorMP3::DecodeNextFrame() -{ - if (mad_frame_decode(frame, stream) == -1) { - ErrorToFlow(); // Always returns CONTINUE - return false; - } - nsCountMax = MAD_NSBSAMPLES(&frame->header); - return true; +bool AudioGeneratorMP3::DecodeNextFrame() { + if (mad_frame_decode(frame, stream) == -1) { + ErrorToFlow(); // Always returns CONTINUE + return false; + } + nsCountMax = MAD_NSBSAMPLES(&frame->header); + return true; } -bool AudioGeneratorMP3::GetOneSample(int16_t sample[2]) -{ - if (synth->pcm.samplerate != lastRate) { - output->SetRate(synth->pcm.samplerate); - lastRate = synth->pcm.samplerate; - } - if (synth->pcm.channels != lastChannels) { - output->SetChannels(synth->pcm.channels); - lastChannels = synth->pcm.channels; - } - - // If we're here, we have one decoded frame and sent 0 or more samples out - if (samplePtr < synth->pcm.length) { - sample[AudioOutput::LEFTCHANNEL ] = synth->pcm.samples[0][samplePtr]; - sample[AudioOutput::RIGHTCHANNEL] = synth->pcm.samples[1][samplePtr]; - samplePtr++; - } else { - samplePtr = 0; - - switch ( mad_synth_frame_onens(synth, frame, nsCount++) ) { +bool AudioGeneratorMP3::GetOneSample(int16_t sample[2]) { + if (synth->pcm.samplerate != lastRate) { + output->SetRate(synth->pcm.samplerate); + lastRate = synth->pcm.samplerate; + } + if (synth->pcm.channels != lastChannels) { + output->SetChannels(synth->pcm.channels); + lastChannels = synth->pcm.channels; + } + + // If we're here, we have one decoded frame and sent 0 or more samples out + if (samplePtr < synth->pcm.length) { + sample[AudioOutput::LEFTCHANNEL ] = synth->pcm.samples[0][samplePtr]; + sample[AudioOutput::RIGHTCHANNEL] = synth->pcm.samples[1][samplePtr]; + samplePtr++; + } else { + samplePtr = 0; + + switch (mad_synth_frame_onens(synth, frame, nsCount++)) { case MAD_FLOW_STOP: case MAD_FLOW_BREAK: audioLogger->printf_P(PSTR("msf1ns failed\n")); - return false; // Either way we're done + return false; // Either way we're done default: - break; // Do nothing + break; // Do nothing + } + // for IGNORE and CONTINUE, just play what we have now + sample[AudioOutput::LEFTCHANNEL ] = synth->pcm.samples[0][samplePtr]; + sample[AudioOutput::RIGHTCHANNEL] = synth->pcm.samples[1][samplePtr]; + samplePtr++; } - // for IGNORE and CONTINUE, just play what we have now - sample[AudioOutput::LEFTCHANNEL ] = synth->pcm.samples[0][samplePtr]; - sample[AudioOutput::RIGHTCHANNEL] = synth->pcm.samples[1][samplePtr]; - samplePtr++; - } - return true; + return true; } -bool AudioGeneratorMP3::loop() -{ - if (!running) goto done; // Nothing to do here! - - // First, try and push in the stored sample. If we can't, then punt and try later - if (!output->ConsumeSample(lastSample)) goto done; // Can't send, but no error detected - - // Try and stuff the buffer one sample at a time - do - { - // Decode next frame if we're beyond the existing generated data - if ( (samplePtr >= synth->pcm.length) && (nsCount >= nsCountMax) ) { -retry: - if (Input() == MAD_FLOW_STOP) { - return false; - } - - if (!DecodeNextFrame()) { - goto retry; - } - samplePtr = 9999; - nsCount = 0; +bool AudioGeneratorMP3::loop() { + if (!running) { + goto done; // Nothing to do here! } - if (!GetOneSample(lastSample)) { - audioLogger->printf_P(PSTR("G1S failed\n")); - running = false; - goto done; + // First, try and push in the stored sample. If we can't, then punt and try later + if (!output->ConsumeSample(lastSample)) { + goto done; // Can't send, but no error detected } - } while (running && output->ConsumeSample(lastSample)); + + // Try and stuff the buffer one sample at a time + do { + // Decode next frame if we're beyond the existing generated data + if ((samplePtr >= synth->pcm.length) && (nsCount >= nsCountMax)) { +retry: + if (Input() == MAD_FLOW_STOP) { + return false; + } + + if (!DecodeNextFrame()) { + if (stream->error == MAD_ERROR_BUFLEN) { + // randomly seeking can lead to endless + // and unrecoverable "MAD_ERROR_BUFLEN" loop + audioLogger->printf_P(PSTR("MP3:ERROR_BUFLEN %d\n"), unrecoverable); + if (++unrecoverable >= 3) { + unrecoverable = 0; + stop(); + return running; + } + } else { + unrecoverable = 0; + } + goto retry; + } + samplePtr = 9999; + nsCount = 0; + } + + if (!GetOneSample(lastSample)) { + audioLogger->printf_P(PSTR("G1S failed\n")); + running = false; + goto done; + } + if (lastChannels == 1) { + lastSample[1] = lastSample[0]; + } + } while (running && output->ConsumeSample(lastSample)); done: - file->loop(); - output->loop(); + file->loop(); + output->loop(); - return running; + return running; } -bool AudioGeneratorMP3::begin(AudioFileSource *source, AudioOutput *output) -{ - if (!source) return false; - file = source; - if (!output) return false; - this->output = output; - if (!file->isOpen()) { - audioLogger->printf_P(PSTR("MP3 source file not open\n")); - return false; // Error - } - - output->SetBitsPerSample(16); // Constant for MP3 decoder - output->SetChannels(2); - - if (!output->begin()) return false; - - // Where we are in generating one frame's data, set to invalid so we will run loop on first getsample() - samplePtr = 9999; - nsCount = 9999; - lastRate = 0; - lastChannels = 0; - lastReadPos = 0; - lastBuffLen = 0; - - // Allocate all large memory chunks - if (preallocateSpace) { - uint8_t *p = reinterpret_cast(preallocateSpace); - buff = reinterpret_cast(p); - p += (buffLen+7) & ~7; - stream = reinterpret_cast(p); - p += (sizeof(struct mad_stream)+7) & ~7; - frame = reinterpret_cast(p); - p += (sizeof(struct mad_frame)+7) & ~7; - synth = reinterpret_cast(p); - p += (sizeof(struct mad_synth)+7) & ~7; - int neededBytes = p - reinterpret_cast(preallocateSpace); - if (neededBytes > preallocateSize) { - audioLogger->printf_P("OOM error in MP3: Want %d bytes, have %d bytes preallocated.\n", neededBytes, preallocateSize); - return false; +bool AudioGeneratorMP3::begin(AudioFileSource *source, AudioOutput *output) { + if (!source) { + return false; + } + file = source; + if (!output) { + return false; } - } else { - buff = reinterpret_cast(malloc(buffLen)); - stream = reinterpret_cast(malloc(sizeof(struct mad_stream))); - frame = reinterpret_cast(malloc(sizeof(struct mad_frame))); - synth = reinterpret_cast(malloc(sizeof(struct mad_synth))); - if (!buff || !stream || !frame || !synth) { - free(buff); - free(stream); - free(frame); - free(synth); - buff = NULL; - stream = NULL; - frame = NULL; - synth = NULL; - return false; + this->output = output; + if (!file->isOpen()) { + audioLogger->printf_P(PSTR("MP3 source file not open\n")); + return false; // Error } - } - - mad_stream_init(stream); - mad_frame_init(frame); - mad_synth_init(synth); - synth->pcm.length = 0; - mad_stream_options(stream, 0); // TODO - add options support - madInitted = true; - - running = true; - return true; + + // Reset error count from previous file + unrecoverable = 0; + + output->SetChannels(2); + + if (!output->begin()) { + return false; + } + + // Where we are in generating one frame's data, set to invalid so we will run loop on first getsample() + samplePtr = 9999; + nsCount = 9999; + lastRate = 0; + lastChannels = 0; + lastReadPos = 0; + lastBuffLen = 0; + + // Allocate all large memory chunks + if (preallocateStreamSize + preallocateFrameSize + preallocateSynthSize) { + if (preallocateSize >= preAllocBuffSize() && + preallocateStreamSize >= preAllocStreamSize() && + preallocateFrameSize >= preAllocFrameSize() && + preallocateSynthSize >= preAllocSynthSize()) { + buff = reinterpret_cast(preallocateSpace); + stream = reinterpret_cast(preallocateStreamSpace); + frame = reinterpret_cast(preallocateFrameSpace); + synth = reinterpret_cast(preallocateSynthSpace); + } else { + output->stop(); + audioLogger->printf_P("OOM error in MP3: Want %d/%d/%d/%d bytes, have %d/%d/%d/%d bytes preallocated.\n", + preAllocBuffSize(), preAllocStreamSize(), preAllocFrameSize(), preAllocSynthSize(), + preallocateSize, preallocateStreamSize, preallocateFrameSize, preallocateSynthSize); + return false; + } + } else if (preallocateSpace) { + uint8_t *p = reinterpret_cast(preallocateSpace); + buff = reinterpret_cast(p); + p += preAllocBuffSize(); + stream = reinterpret_cast(p); + p += preAllocStreamSize(); + frame = reinterpret_cast(p); + p += preAllocFrameSize(); + synth = reinterpret_cast(p); + p += preAllocSynthSize(); + int neededBytes = p - reinterpret_cast(preallocateSpace); + if (neededBytes > preallocateSize) { + output->stop(); + audioLogger->printf_P("OOM error in MP3: Want %d bytes, have %d bytes preallocated.\n", neededBytes, preallocateSize); + return false; + } + } else { + buff = reinterpret_cast(malloc(buffLen)); + stream = reinterpret_cast(malloc(sizeof(struct mad_stream))); + frame = reinterpret_cast(malloc(sizeof(struct mad_frame))); + synth = reinterpret_cast(malloc(sizeof(struct mad_synth))); + if (!buff || !stream || !frame || !synth) { + free(buff); + free(stream); + free(frame); + free(synth); + buff = NULL; + stream = NULL; + frame = NULL; + synth = NULL; + + output->stop(); + audioLogger->printf_P("OOM error in MP3\n"); + return false; + } + } + + mad_stream_init(stream); + mad_frame_init(frame); + mad_synth_init(synth); + synth->pcm.length = 0; + mad_stream_options(stream, 0); // TODO - add options support + madInitted = true; + + running = true; + return true; } // The following are helper routines for use in libmad to check stack/heap free // and to determine if there's enough stack space to allocate some blocks there // instead of precious heap. -#undef stack +#undef stackenter extern "C" { #ifdef ESP32 - //TODO - add ESP32 checks - void stack(const char *s, const char *t, int i) - { - } - int stackfree() - { - return 8192; - } -#elif defined(ESP8266) - #include - extern cont_t g_cont; - - void stack(const char *s, const char *t, int i) - { - (void) t; - (void) i; - register uint32_t *sp asm("a1"); - int freestack = 4 * (sp - g_cont.stack); - int freeheap = ESP.getFreeHeap(); - if ((freestack < 512) || (freeheap < 5120)) { - static int laststack, lastheap; - if (laststack!=freestack|| lastheap !=freeheap) { - audioLogger->printf_P(PSTR("%s: FREESTACK=%d, FREEHEAP=%d\n"), s, /*t, i,*/ freestack, /*cont_get_free_stack(&g_cont),*/ freeheap); - } - if (freestack < 256) { - audioLogger->printf_P(PSTR("out of stack!\n")); - } - if (freeheap < 1024) { - audioLogger->printf_P(PSTR("out of heap!\n")); - } - Serial.flush(); - laststack = freestack; - lastheap = freeheap; + //TODO - add ESP32 checks + void stackenter(const char *s, const char *t, int i) { + } + int stackfree() { + return 8192; + } +#elif defined(ESP8266) && !defined(CORE_MOCK) +#include + extern cont_t g_cont; + + void stackenter(const char *s, const char *t, int i) { + (void) t; + (void) i; + register uint32_t *sp asm("a1"); + int freestack = 4 * (sp - g_cont.stack); + int freeheap = ESP.getFreeHeap(); + if ((freestack < 512) || (freeheap < 5120)) { + static int laststack, lastheap; + if (laststack != freestack || lastheap != freeheap) { + audioLogger->printf_P(PSTR("%s: FREESTACK=%d, FREEHEAP=%d\n"), s, /*t, i,*/ freestack, /*cont_get_free_stack(&g_cont),*/ freeheap); + } + if (freestack < 256) { + audioLogger->printf_P(PSTR("out of stack!\n")); + } + if (freeheap < 1024) { + audioLogger->printf_P(PSTR("out of heap!\n")); + } + Serial.flush(); + laststack = freestack; + lastheap = freeheap; + } + } + + int stackfree() { + register uint32_t *sp asm("a1"); + int freestack = 4 * (sp - g_cont.stack); + return freestack; } - } - - int stackfree() - { - register uint32_t *sp asm("a1"); - int freestack = 4 * (sp - g_cont.stack); - return freestack; - } #else - void stack(const char *s, const char *t, int i) - { - (void) s; - (void) t; - (void) i; - } - int stackfree() - { - return 8192; - } + void stackenter(const char *s, const char *t, int i) { + (void) s; + (void) t; + (void) i; + } + int stackfree() { + return 8192; + } #endif } - diff --git a/src/AudioGeneratorMP3.h b/src/AudioGeneratorMP3.h index 750cecac..eeffac83 100644 --- a/src/AudioGeneratorMP3.h +++ b/src/AudioGeneratorMP3.h @@ -1,21 +1,21 @@ /* - AudioGeneratorMP3 - Wrap libmad MP3 library to play audio - - Copyright (C) 2017 Earle F. Philhower, III + AudioGeneratorMP3 + Wrap libmad MP3 library to play audio - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + Copyright (C) 2017 Earle F. Philhower, III - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOGENERATORMP3_H @@ -25,28 +25,51 @@ #include "libmad/config.h" #include "libmad/mad.h" -class AudioGeneratorMP3 : public AudioGenerator -{ - public: +class AudioGeneratorMP3 : public AudioGenerator { +public: AudioGeneratorMP3(); AudioGeneratorMP3(void *preallocateSpace, int preallocateSize); + AudioGeneratorMP3(void *buff, int buffSize, void *stream, int streamSize, void *frame, int frameSize, void *synth, int synthSize); virtual ~AudioGeneratorMP3() override; virtual bool begin(AudioFileSource *source, AudioOutput *output) override; virtual bool loop() override; virtual bool stop() override; virtual bool isRunning() override; - - protected: - void *preallocateSpace; - int preallocateSize; + virtual void desync() override; + + static constexpr int preAllocSize() { + return preAllocBuffSize() + preAllocStreamSize() + preAllocFrameSize() + preAllocSynthSize(); + } + static constexpr int preAllocBuffSize() { + return ((buffLen + 7) & ~7); + } + static constexpr int preAllocStreamSize() { + return ((sizeof(struct mad_stream) + 7) & ~7); + } + static constexpr int preAllocFrameSize() { + return (sizeof(struct mad_frame) + 7) & ~7; + } + static constexpr int preAllocSynthSize() { + return (sizeof(struct mad_synth) + 7) & ~7; + } - const int buffLen = 0x600; // Slightly larger than largest MP3 frame +protected: + void *preallocateSpace = nullptr; + int preallocateSize = 0; + void *preallocateStreamSpace = nullptr; + int preallocateStreamSize = 0; + void *preallocateFrameSpace = nullptr; + int preallocateFrameSize = 0; + void *preallocateSynthSpace = nullptr; + int preallocateSynthSize = 0; + + static constexpr int buffLen = 0x600; // Slightly larger than largest MP3 frame unsigned char *buff; int lastReadPos; int lastBuffLen; unsigned int lastRate; int lastChannels; - + // Decoding bits bool madInitted; struct mad_stream *stream; @@ -62,6 +85,8 @@ class AudioGeneratorMP3 : public AudioGenerator bool DecodeNextFrame(); bool GetOneSample(int16_t sample[2]); +private: + int unrecoverable = 0; }; #endif diff --git a/src/AudioGeneratorMP3a.cpp b/src/AudioGeneratorMP3a.cpp index f75846a9..c2ae350a 100644 --- a/src/AudioGeneratorMP3a.cpp +++ b/src/AudioGeneratorMP3a.cpp @@ -1,21 +1,21 @@ /* - AudioGeneratorMP3 - Audio output generator using the Helix MP3 decoder - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioGeneratorMP3 + Audio output generator using the Helix MP3 decoder + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #pragma GCC optimize ("O3") @@ -23,140 +23,148 @@ #include "AudioGeneratorMP3a.h" -AudioGeneratorMP3a::AudioGeneratorMP3a() -{ - running = false; - file = NULL; - output = NULL; - hMP3Decoder = MP3InitDecoder(); - if (!hMP3Decoder) { - audioLogger->printf_P(PSTR("Out of memory error! hMP3Decoder==NULL\n")); - Serial.flush(); - } - // For sanity's sake... - memset(buff, 0, sizeof(buff)); - memset(outSample, 0, sizeof(outSample)); - buffValid = 0; - lastFrameEnd = 0; - validSamples = 0; - curSample = 0; - lastRate = 0; - lastChannels = 0; +AudioGeneratorMP3a::AudioGeneratorMP3a() { + running = false; + file = NULL; + output = NULL; + hMP3Decoder = MP3InitDecoder(); + if (!hMP3Decoder) { + audioLogger->printf_P(PSTR("Out of memory error! hMP3Decoder==NULL\n")); + Serial.flush(); + } + // For sanity's sake... + memset(buff, 0, sizeof(buff)); + memset(outSample, 0, sizeof(outSample)); + buffValid = 0; + lastFrameEnd = 0; + validSamples = 0; + curSample = 0; + lastRate = 0; + lastChannels = 0; } -AudioGeneratorMP3a::~AudioGeneratorMP3a() -{ - MP3FreeDecoder(hMP3Decoder); +AudioGeneratorMP3a::~AudioGeneratorMP3a() { + MP3FreeDecoder(hMP3Decoder); } -bool AudioGeneratorMP3a::stop() -{ - if (!running) return true; - running = false; - output->stop(); - return file->close(); +bool AudioGeneratorMP3a::stop() { + if (!running) { + return true; + } + running = false; + output->stop(); + return file->close(); } -bool AudioGeneratorMP3a::isRunning() -{ - return running; +bool AudioGeneratorMP3a::isRunning() { + return running; } -bool AudioGeneratorMP3a::FillBufferWithValidFrame() -{ - buff[0] = 0; // Destroy any existing sync word @ 0 - int nextSync; - do { - nextSync = MP3FindSyncWord(buff + lastFrameEnd, buffValid - lastFrameEnd); - if (nextSync >= 0) nextSync += lastFrameEnd; - lastFrameEnd = 0; - if (nextSync == -1) { - if (buff[buffValid-1]==0xff) { // Could be 1st half of syncword, preserve it... - buff[0] = 0xff; - buffValid = file->read(buff+1, sizeof(buff)-1); - if (buffValid==0) return false; // No data available, EOF - } else { // Try a whole new buffer - buffValid = file->read(buff, sizeof(buff)); - if (buffValid==0) return false; // No data available, EOF - } - } - } while (nextSync == -1); - - // Move the frame to start at offset 0 in the buffer - buffValid -= nextSync; // Throw out prior to nextSync - memmove(buff, buff+nextSync, buffValid); +bool AudioGeneratorMP3a::FillBufferWithValidFrame() { + buff[0] = 0; // Destroy any existing sync word @ 0 + int nextSync; + do { + nextSync = MP3FindSyncWord(buff + lastFrameEnd, buffValid - lastFrameEnd); + if (nextSync >= 0) { + nextSync += lastFrameEnd; + } + lastFrameEnd = 0; + if (nextSync == -1) { + if (buff[buffValid - 1] == 0xff) { // Could be 1st half of syncword, preserve it... + buff[0] = 0xff; + buffValid = file->read(buff + 1, sizeof(buff) - 1); + if (buffValid == 0) { + return false; // No data available, EOF + } + } else { // Try a whole new buffer + buffValid = file->read(buff, sizeof(buff)); + if (buffValid == 0) { + return false; // No data available, EOF + } + } + } + } while (nextSync == -1); + + // Move the frame to start at offset 0 in the buffer + buffValid -= nextSync; // Throw out prior to nextSync + memmove(buff, buff + nextSync, buffValid); + + // We have a sync word at 0 now, try and fill remainder of buffer + buffValid += file->read(buff + buffValid, sizeof(buff) - buffValid); + + return true; +} - // We have a sync word at 0 now, try and fill remainder of buffer - buffValid += file->read(buff + buffValid, sizeof(buff) - buffValid); +bool AudioGeneratorMP3a::loop() { + if (!running) { + goto done; // Nothing to do here! + } - return true; -} + // If we've got data, try and pump it out... + while (validSamples) { + lastSample[0] = outSample[curSample * 2]; + lastSample[1] = outSample[curSample * 2 + 1]; + if (!output->ConsumeSample(lastSample)) { + goto done; // Can't send, but no error detected + } + validSamples--; + curSample++; + } -bool AudioGeneratorMP3a::loop() -{ - if (!running) goto done; // Nothing to do here! - - // If we've got data, try and pump it out... - while (validSamples) { - lastSample[0] = outSample[curSample*2]; - lastSample[1] = outSample[curSample*2 + 1]; - if (!output->ConsumeSample(lastSample)) goto done; // Can't send, but no error detected - validSamples--; - curSample++; - } - - // No samples available, need to decode a new frame - if (FillBufferWithValidFrame()) { - // buff[0] start of frame, decode it... - unsigned char *inBuff = reinterpret_cast(buff); - int bytesLeft = buffValid; - int ret = MP3Decode(hMP3Decoder, &inBuff, &bytesLeft, outSample, 0); - if (ret) { - // Error, skip the frame... - char buff[48]; - sprintf(buff, "MP3 decode error %d", ret); - cb.st(ret, buff); + // No samples available, need to decode a new frame + if (FillBufferWithValidFrame()) { + // buff[0] start of frame, decode it... + unsigned char *inBuff = reinterpret_cast(buff); + int bytesLeft = buffValid; + int ret = MP3Decode(hMP3Decoder, &inBuff, &bytesLeft, outSample, 0); + if (ret) { + // Error, skip the frame... + char buff[48]; + sprintf(buff, "MP3 decode error %d", ret); + cb.st(ret, buff); + } else { + lastFrameEnd = buffValid - bytesLeft; + MP3FrameInfo fi; + MP3GetLastFrameInfo(hMP3Decoder, &fi); + if ((int)fi.samprate != (int)lastRate) { + output->SetRate(fi.samprate); + lastRate = fi.samprate; + } + if (fi.nChans != lastChannels) { + output->SetChannels(fi.nChans); + lastChannels = fi.nChans; + } + curSample = 0; + validSamples = fi.outputSamps / lastChannels; + } } else { - lastFrameEnd = buffValid - bytesLeft; - MP3FrameInfo fi; - MP3GetLastFrameInfo(hMP3Decoder, &fi); - if ((int)fi.samprate!= (int)lastRate) { - output->SetRate(fi.samprate); - lastRate = fi.samprate; - } - if (fi.nChans != lastChannels) { - output->SetChannels(fi.nChans); - lastChannels = fi.nChans; - } - curSample = 0; - validSamples = fi.outputSamps / lastChannels; + running = false; // No more data, we're done here... } - } else { - running = false; // No more data, we're done here... - } done: - file->loop(); - output->loop(); + file->loop(); + output->loop(); - return running; + return running; } -bool AudioGeneratorMP3a::begin(AudioFileSource *source, AudioOutput *output) -{ - if (!source) return false; - file = source; - if (!output) return false; - this->output = output; - if (!file->isOpen()) return false; // Error - - output->begin(); - - // AAC always comes out at 16 bits - output->SetBitsPerSample(16); - - running = true; - - return true; +bool AudioGeneratorMP3a::begin(AudioFileSource *source, AudioOutput *output) { + if (!source) { + return false; + } + file = source; + if (!output) { + return false; + } + this->output = output; + if (!file->isOpen()) { + return false; // Error + } + + output->begin(); + + running = true; + + return true; } diff --git a/src/AudioGeneratorMP3a.h b/src/AudioGeneratorMP3a.h index 4cf879d7..f6805351 100644 --- a/src/AudioGeneratorMP3a.h +++ b/src/AudioGeneratorMP3a.h @@ -1,21 +1,21 @@ /* - AudioGeneratorMP3 - Audio output generator using the Helix MP3 decoder - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioGeneratorMP3 + Audio output generator using the Helix MP3 decoder + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOGENERATORMP3A_H @@ -24,9 +24,8 @@ #include "AudioGenerator.h" #include "libhelix-mp3/mp3dec.h" -class AudioGeneratorMP3a : public AudioGenerator -{ - public: +class AudioGeneratorMP3a : public AudioGenerator { +public: AudioGeneratorMP3a(); virtual ~AudioGeneratorMP3a() override; virtual bool begin(AudioFileSource *source, AudioOutput *output) override; @@ -34,7 +33,7 @@ class AudioGeneratorMP3a : public AudioGenerator virtual bool stop() override; virtual bool isRunning() override; - protected: +protected: // Helix MP3 decoder HMP3Decoder hMP3Decoder; diff --git a/src/AudioGeneratorOpus.cpp b/src/AudioGeneratorOpus.cpp index c8b80e89..aed7c58c 100644 --- a/src/AudioGeneratorOpus.cpp +++ b/src/AudioGeneratorOpus.cpp @@ -1,143 +1,278 @@ /* - AudioGeneratorOpus - Audio output generator that plays Opus audio files - - Copyright (C) 2020 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioGeneratorOpus + Audio output generator that plays Opus audio files + + Copyright (C) 2025 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include -AudioGeneratorOpus::AudioGeneratorOpus() -{ - of = nullptr; - buff = nullptr; - buffPtr = 0; - buffLen = 0; - running = false; +AudioGeneratorOpus::AudioGeneratorOpus() { + od = nullptr; + buff = nullptr; + buffPtr = 0; + packet = nullptr; + buffLen = 0; + running = false; } -AudioGeneratorOpus::~AudioGeneratorOpus() -{ - if (of) op_free(of); - of = nullptr; - free(buff); - buff = nullptr; +AudioGeneratorOpus::~AudioGeneratorOpus() { + if (od) { + free(od); + } + od = nullptr; + free(buff); + buff = nullptr; + free(packet); + packet = nullptr; } -#define OPUS_BUFF 1024 +bool AudioGeneratorOpus::begin(AudioFileSource *source, AudioOutput *output) { + buff = (opus_int16*)malloc(4096 * sizeof(opus_int16)); + if (!buff) { + return false; + } -bool AudioGeneratorOpus::begin(AudioFileSource *source, AudioOutput *output) -{ - buff = (int16_t*)malloc(OPUS_BUFF * sizeof(int16_t)); - if (!buff) return false; + packet = (uint8_t *)malloc(1024); + if (!packet) { + free(buff); + buff = nullptr; + return false; + } + packetOff = 0; - if (!source) return false; - file = source; - if (!output) return false; - this->output = output; - if (!file->isOpen()) return false; // Error + od = (OpusDecoder *) malloc(opus_decoder_get_size(2)); + if (!od) { + free(buff); + buff = nullptr; + free(packet); + packet = nullptr; + return false; + } + opus_decoder_init(od, 48000, 2); - of = op_open_callbacks((void*)this, &cb, nullptr, 0, nullptr); - if (!of) return false; + if (!source) { + return false; + } + file = source; - prev_li = -1; - lastSample[0] = 0; - lastSample[1] = 0; + if (!output) { + return false; + } + this->output = output; - buffPtr = 0; - buffLen = 0; + if (!file->isOpen()) { + return false; // Error + } - output->begin(); + lastSample[0] = 0; + lastSample[1] = 0; - // These are fixed by Opus - output->SetRate(48000); - output->SetBitsPerSample(16); - output->SetChannels(2); + buffPtr = 0; + buffLen = 0; - running = true; - return true; -} + bzero(hdr, sizeof(hdr)); + packetOff = 0; + state = WaitHeader; + preskip = 0; -bool AudioGeneratorOpus::loop() -{ + output->begin(); - if (!running) goto done; + // These are fixed by Opus + output->SetRate(48000); + output->SetChannels(2); - if (!output->ConsumeSample(lastSample)) goto done; // Try and send last buffered sample + running = true; + return true; +} - do { - if (buffPtr == buffLen) { - int ret = op_read_stereo(of, (opus_int16 *)buff, OPUS_BUFF); - if (ret == OP_HOLE) { - // fprintf(stderr,"\nHole detected! Corrupt file segment?\n"); - continue; - } else if (ret < 0) { - running = false; - goto done; - } - buffPtr = 0; - buffLen = ret * 2; - } +bool AudioGeneratorOpus::demux() { + int r; + uint8_t b; + //static int pktno = 0; - lastSample[AudioOutput::LEFTCHANNEL] = buff[buffPtr] & 0xffff; - lastSample[AudioOutput::RIGHTCHANNEL] = buff[buffPtr+1] & 0xffff; - buffPtr += 2; - } while (running && output->ConsumeSample(lastSample)); + while (true) { + switch (state) { + case WaitHeader: + //audioLogger->printf("STATE: WaitHeader\n"); + if (!file->read(&b, 1)) { + return false; // No data + } + memmove(hdr, hdr + 1, 26); + hdr[26] = b; + if ((hdr[0] == 'O') && (hdr[1] == 'g') && (hdr[2] == 'g') && (hdr[3] == 'S') && (hdr[4] == 0)) { + // We have a header! + type = hdr[5]; + agp = hdr[13]; + for (int i = 1; i < 7; i++) { + agp <<= 8; + agp |= hdr[13 - i]; + } + ssn = hdr[14] | (hdr[15] << 8) | (hdr[16] << 16) | (hdr[17] << 24); + psn = hdr[18] | (hdr[19] << 8) | (hdr[20] << 16) | (hdr[21] << 24); + pcs = hdr[22] | (hdr[23] << 8) | (hdr[24] << 16) | (hdr[25] << 24); + ps = hdr[26]; + readPS = 0; + //audioLogger->printf("HEADER: typ: %d, agp: %llu, ssn: %08x, psn: %08x, pcs: %08x, ps: %d\n", type, agp, ssn, psn, pcs, ps); + state = WaitSegment; + } + break; + case WaitSegment: + //audioLogger->printf("STATE: WaitSegment\n"); + r = file->read(seg + readPS, ps - readPS); + readPS += r; // Keep track of what we read + if (readPS < ps) { + // Not enough data avail to finish, loop + return false; + } + //audioLogger->printf("SEGMENTS (%d): ", ps); + for (int i = 0; i < ps; i++) { + //audioLogger->printf(" %02x", seg[i]); + } + //audioLogger->printf("\n"); + curSeg = 0; + lacingBytesToRead = seg[0]; + state = ReadPacket; + break; + case ReadPacket: + //audioLogger->printf("STATE: ReadPacket\n"); + //audioLogger->printf("readpacket seg %d len %d\n", curSeg, seg[curSeg]); + r = file->read(packet + packetOff, lacingBytesToRead); + packetOff += r; + lacingBytesToRead -= r; + if (lacingBytesToRead) { + //audioLogger->printf("short read\n"); + return false; // Not enough avail + } + // Read lacing bit, see if there's more + if (seg[curSeg] != 0xff) { + //audioLogger->printf("PACKET %d (%d): ", pktno++, packetOff); + for (uint32_t i = 0; i < packetOff; i++) { + //audioLogger->printf(" %02X", packet[i]); + } + //audioLogger->printf("\n"); + // We have a full packet in the buffer, decode it + // First, is it a header? + if ((packetOff >= 17) && !memcmp(packet, "OpusHead", 8) && (packet[8] == 1)) { + channels = packet[9]; + preskip = packet[10] | (packet[11] << 8); + samplerate = packet[12] | (packet[13] << 8) | (packet[14] << 16) | (packet[15] << 24); + gain = packet[16] | (packet[17]++); + //audioLogger->printf("HEADER: chan: %d, sr: %d, skip %d\n", channels, samplerate, preskip); + packetOff = 0; // For better or worse, we've processed this pkt + } else if ((packetOff >= 9) && !memcmp(packet, "OpusTags", 8)) { + // This is an unparsed TAG. TODO find metadata format + packetOff = 0; // For better or worse, we've processed this pkt + } else { + // This should be a regular packet + int ret = opus_decode(od, packet, packetOff, buff, 2048, 0); + packetOff = 0; // For better or worse, we've processed this pkt + if (ret > 0) { + buffLen = ret * 2; + if (preskip) { + if (buffLen >= preskip) { + buffPtr = preskip; + preskip = 0; + //audioLogger->printf("donepreskip\n"); + } else { + buffPtr = buffLen; + preskip -= buffLen; + } + } else { + buffPtr = 0; + } + curSeg++; + if (curSeg >= ps) { + state = WaitHeader; + lacingBytesToRead = 0; + } else { + lacingBytesToRead = seg[curSeg]; + } + return true; // We have filled a buffer + } else { + //audioLogger->printf("nodecode\n"); + // Could be header pkt, we ignore them here + // That means we ignore the preskip value, for now + } + packetOff = 0; // For better or worse, we've processed this pkt + } + } + // Only have partial pkt, need next segment + curSeg++; + if (curSeg >= ps) { + state = WaitHeader; + lacingBytesToRead = 0; + } else { + lacingBytesToRead = seg[curSeg]; + } + break; + default: + state = WaitHeader; + break; + } + } +} -done: - file->loop(); - output->loop(); - return running; -} +bool AudioGeneratorOpus::loop() { + if (!running) { + goto done; + } -bool AudioGeneratorOpus::stop() -{ - if (of) op_free(of); - of = nullptr; - free(buff); - buff = nullptr; - running = false; - output->stop(); - return true; -} + if (!output->ConsumeSample(lastSample)) { + goto done; // Try and send last buffered sample + } -bool AudioGeneratorOpus::isRunning() -{ - return running; -} + do { + if (buffPtr == buffLen) { + // Will run until we either run out of data, would block, or decode something + if (!demux()) { + running = false; + goto done; + } + } + if (buffPtr == buffLen) { + // Still nothing + goto done; + } + lastSample[AudioOutput::LEFTCHANNEL] = buff[buffPtr] & 0xffff; + lastSample[AudioOutput::RIGHTCHANNEL] = buff[buffPtr + 1] & 0xffff; + buffPtr += 2; + } while (running && output->ConsumeSample(lastSample)); -int AudioGeneratorOpus::read_cb(unsigned char *_ptr, int _nbytes) { - if (_nbytes == 0) return 0; - _nbytes = file->read(_ptr, _nbytes); - if (_nbytes == 0) return -1; - return _nbytes; -} +done: + file->loop(); + output->loop(); -int AudioGeneratorOpus::seek_cb(opus_int64 _offset, int _whence) { - if (!file->seek((int32_t)_offset, _whence)) return -1; - return 0; + return running; } -opus_int64 AudioGeneratorOpus::tell_cb() { - return file->getPos(); +bool AudioGeneratorOpus::stop() { + if (od) { + free(od); + } + od = nullptr; + free(buff); + buff = nullptr; + running = false; + output->stop(); + return true; } -int AudioGeneratorOpus::close_cb() { - // NO OP, we close in main loop - return 0; +bool AudioGeneratorOpus::isRunning() { + return running; } diff --git a/src/AudioGeneratorOpus.h b/src/AudioGeneratorOpus.h index 171bd36d..624de81d 100644 --- a/src/AudioGeneratorOpus.h +++ b/src/AudioGeneratorOpus.h @@ -1,33 +1,31 @@ /* - AudioGeneratorOpus - Audio output generator that plays Opus audio files - - Copyright (C) 2020 Earle F. Philhower, III + AudioGeneratorOpus + Audio output generator that plays Opus audio files - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + Copyright (C) 2025 Earle F. Philhower, III - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOGENERATOROPUS_H #define _AUDIOGENERATOROPUS_H #include -//#include "libopus/opus.h" -#include "opusfile/opusfile.h" +#include "libopus/include/opus.h" -class AudioGeneratorOpus : public AudioGenerator -{ - public: +class AudioGeneratorOpus : public AudioGenerator { +public: AudioGeneratorOpus(); virtual ~AudioGeneratorOpus() override; virtual bool begin(AudioFileSource *source, AudioOutput *output) override; @@ -35,35 +33,34 @@ class AudioGeneratorOpus : public AudioGenerator virtual bool stop() override; virtual bool isRunning() override; - protected: - // Opus callbacks, need static functions to bounce into C++ from C - static int OPUS_read(void *_stream, unsigned char *_ptr, int _nbytes) { - return static_cast(_stream)->read_cb(_ptr, _nbytes); - } - static int OPUS_seek(void *_stream, opus_int64 _offset, int _whence) { - return static_cast(_stream)->seek_cb(_offset, _whence); - } - static opus_int64 OPUS_tell(void *_stream) { - return static_cast(_stream)->tell_cb(); - } - static int OPUS_close(void *_stream) { - return static_cast(_stream)->close_cb(); - } - - // Actual Opus callbacks - int read_cb(unsigned char *_ptr, int _nbytes); - int seek_cb(opus_int64 _offset, int _whence); - opus_int64 tell_cb(); - int close_cb(); +private: + OpusDecoder *od = nullptr; - private: - OpusFileCallbacks cb = {OPUS_read, OPUS_seek, OPUS_tell, OPUS_close}; - OggOpusFile *of; - int prev_li; // To detect changes in streams - - int16_t *buff; + uint8_t *packet; // Raw compressed, demuxed packet + uint32_t packetOff; + opus_int16 *buff; // Decoded PCM uint32_t buffPtr; uint32_t buffLen; + + bool demux(); + uint8_t hdr[27]; // Page header + enum {WaitHeader, WaitSegment, ReadPacket} state; + uint8_t type; + uint64_t agp; + uint32_t ssn; + uint32_t psn; + uint32_t pcs; + uint16_t ps; // packet lacing segments + uint16_t readPS; + uint8_t seg[256]; // Packet lacing in the current page + uint16_t curSeg; + uint32_t lacingBytesToRead; + void processPacket(); + // From the OpusHead + uint16_t preskip; + uint8_t channels; + uint32_t samplerate; + uint16_t gain; }; #endif diff --git a/src/AudioGeneratorRTTTL.cpp b/src/AudioGeneratorRTTTL.cpp index 87825bd9..235f8427 100644 --- a/src/AudioGeneratorRTTTL.cpp +++ b/src/AudioGeneratorRTTTL.cpp @@ -1,155 +1,209 @@ /* - AudioGeneratorRTTTL - Audio output generator that plays RTTTL (Nokia ringtone) - - Based on the Rtttl Arduino library by James BM, https://github.com/spicajames/Rtttl - Based on the gist from Daniel Hall https://gist.github.com/smarthall/1618800 - - Copyright (C) 2018 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioGeneratorRTTTL + Audio output generator that plays RTTTL (Nokia ringtone) + + Based on the Rtttl Arduino library by James BM, https://github.com/spicajames/Rtttl + Based on the gist from Daniel Hall https://gist.github.com/smarthall/1618800 + + Copyright (C) 2018 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include "AudioGeneratorRTTTL.h" -AudioGeneratorRTTTL::AudioGeneratorRTTTL() -{ - running = false; - file = NULL; - output = NULL; - rate = 22050; - buff = nullptr; - ptr = 0; +AudioGeneratorRTTTL::AudioGeneratorRTTTL() { + running = false; + file = NULL; + output = NULL; + rate = 22050; + buff = nullptr; + ptr = 0; } -AudioGeneratorRTTTL::~AudioGeneratorRTTTL() -{ - free(buff); +AudioGeneratorRTTTL::~AudioGeneratorRTTTL() { + free(buff); } -bool AudioGeneratorRTTTL::stop() -{ - if (!running) return true; - running = false; - output->stop(); - return file->close(); +bool AudioGeneratorRTTTL::stop() { + if (!file || !output) { + return false; + } + running = false; + output->stop(); + return file->close(); } -bool AudioGeneratorRTTTL::isRunning() -{ - return running; +bool AudioGeneratorRTTTL::isRunning() { + return running; } -bool AudioGeneratorRTTTL::loop() -{ - if (!running) goto done; // Nothing to do here! +bool AudioGeneratorRTTTL::loop() { + if (!running) { + goto done; // Nothing to do here! + } - // Load the next note, if we've hit the end of the last one - if (samplesSent == ttlSamples) { - if (!GetNextNote()) { - running = false; - goto done; + // Load the next note, if we've hit the end of the last one + if (samplesSent == ttlSamples) { + if (!GetNextNote()) { + running = false; + goto done; + } + samplesSent = 0; + } + + // Try and send out the remainder of the existing note, one per loop() + if (ttlSamplesPerWaveFP10 == 0) { // Mute + int16_t mute[2] = {0, 0}; + while ((samplesSent < ttlSamples) && output->ConsumeSample(mute)) { + samplesSent++; + } + } else { + while (samplesSent < ttlSamples) { + int samplesSentFP10 = samplesSent << 10; + int rem = samplesSentFP10 % ttlSamplesPerWaveFP10; + int16_t val = (rem > ttlSamplesPerWaveFP10 / 2) ? 8192 : -8192; + int16_t s[2] = { val, val }; + if (!output->ConsumeSample(s)) { + goto done; + } + samplesSent++; + } } - samplesSent = 0; - } - - // Try and send out the remainder of the existing note, one per loop() - if (ttlSamplesPerWaveFP10 == 0) { // Mute - int16_t mute[2] = {0, 0}; - while ((samplesSent < ttlSamples) && output->ConsumeSample(mute)) { - samplesSent++; - } - } else { - while (samplesSent < ttlSamples) { - int samplesSentFP10 = samplesSent << 10; - int rem = samplesSentFP10 % ttlSamplesPerWaveFP10; - int16_t val = (rem > ttlSamplesPerWaveFP10/2) ? 8192:-8192; - int16_t s[2] = { val, val }; - if (!output->ConsumeSample(s)) goto done; - samplesSent++; - } - } done: - file->loop(); - output->loop(); + file->loop(); + output->loop(); - return running; + return running; } -bool AudioGeneratorRTTTL::SkipWhitespace() -{ - while ((ptr < len) && (buff[ptr] == ' ')) ptr++; - return ptr < len; +bool AudioGeneratorRTTTL::SkipWhitespace() { + while ((ptr < len) && (buff[ptr] == ' ')) { + ptr++; + } + return ptr < len; } -bool AudioGeneratorRTTTL::ReadInt(int *dest) -{ - if (ptr >= len) return false; +bool AudioGeneratorRTTTL::ReadInt(int *dest) { + if (ptr >= len) { + return false; + } - SkipWhitespace(); - if (ptr >= len) return false; - if ((buff[ptr] <'0') || (buff[ptr] > '9')) return false; + SkipWhitespace(); + if (ptr >= len) { + return false; + } + if ((buff[ptr] < '0') || (buff[ptr] > '9')) { + return false; + } - int t = 0; - while ((buff[ptr] >= '0') && (buff[ptr] <='9')) { - t = (t * 10) + (buff[ptr] - '0'); - ptr++; - } - *dest = t; - return true; + int t = 0; + while ((buff[ptr] >= '0') && (buff[ptr] <= '9')) { + t = (t * 10) + (buff[ptr] - '0'); + ptr++; + } + *dest = t; + return true; } - - -bool AudioGeneratorRTTTL::ParseHeader() -{ - // Skip the title - while ((ptr < len) && (buff[ptr] != ':')) ptr++; - if (ptr >= len) return false; - if (buff[ptr++] != ':') return false; - if (!SkipWhitespace()) return false; - if ((buff[ptr] != 'd') && (buff[ptr] != 'D')) return false; - ptr++; - if (!SkipWhitespace()) return false; - if (buff[ptr++] != '=') return false; - if (!ReadInt(&defaultDuration)) return false; - if (!SkipWhitespace()) return false; - if (buff[ptr++] != ',') return false; - - if (!SkipWhitespace()) return false; - if ((buff[ptr] != 'o') && (buff[ptr] != 'O')) return false; - ptr++; - if (!SkipWhitespace()) return false; - if (buff[ptr++] != '=') return false; - if (!ReadInt(&defaultOctave)) return false; - if (!SkipWhitespace()) return false; - if (buff[ptr++] != ',') return false; - - int bpm; - if (!SkipWhitespace()) return false; - if ((buff[ptr] != 'b') && (buff[ptr] != 'B')) return false; - ptr++; - if (!SkipWhitespace()) return false; - if (buff[ptr++] != '=') return false; - if (!ReadInt(&bpm)) return false; - if (!SkipWhitespace()) return false; - if (buff[ptr++] != ':') return false; - - wholeNoteMS = (60 * 1000 * 4) / bpm; - - return true; + + +bool AudioGeneratorRTTTL::ParseHeader() { + // Skip the title + while ((ptr < len) && (buff[ptr] != ':')) { + ptr++; + } + if (ptr >= len) { + return false; + } + if (buff[ptr++] != ':') { + return false; + } + if (!SkipWhitespace()) { + return false; + } + if ((buff[ptr] != 'd') && (buff[ptr] != 'D')) { + return false; + } + ptr++; + if (!SkipWhitespace()) { + return false; + } + if (buff[ptr++] != '=') { + return false; + } + if (!ReadInt(&defaultDuration)) { + return false; + } + if (!SkipWhitespace()) { + return false; + } + if (buff[ptr++] != ',') { + return false; + } + + if (!SkipWhitespace()) { + return false; + } + if ((buff[ptr] != 'o') && (buff[ptr] != 'O')) { + return false; + } + ptr++; + if (!SkipWhitespace()) { + return false; + } + if (buff[ptr++] != '=') { + return false; + } + if (!ReadInt(&defaultOctave)) { + return false; + } + if (!SkipWhitespace()) { + return false; + } + if (buff[ptr++] != ',') { + return false; + } + + int bpm; + if (!SkipWhitespace()) { + return false; + } + if ((buff[ptr] != 'b') && (buff[ptr] != 'B')) { + return false; + } + ptr++; + if (!SkipWhitespace()) { + return false; + } + if (buff[ptr++] != '=') { + return false; + } + if (!ReadInt(&bpm)) { + return false; + } + if (!SkipWhitespace()) { + return false; + } + if (buff[ptr++] != ':') { + return false; + } + + wholeNoteMS = (60 * 1000 * 4) / bpm; + + return true; } #define NOTE_C4 262 @@ -201,24 +255,28 @@ bool AudioGeneratorRTTTL::ParseHeader() #define NOTE_AS7 3729 #define NOTE_B7 3951 static int notes[49] = { 0, - NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4, - NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5, - NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6, - NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7 }; - -bool AudioGeneratorRTTTL::GetNextNote() -{ - int dur, note, scale; - if (ptr >= len) return false; - - if (!ReadInt(&dur)) { - dur = defaultDuration; - } - dur = wholeNoteMS / dur; - - if (ptr >= len) return false; - note = 0; - switch (buff[ptr++]) { + NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4, + NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5, + NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6, + NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7 + }; + +bool AudioGeneratorRTTTL::GetNextNote() { + int dur, note, scale; + if (ptr >= len) { + return false; + } + + if (!ReadInt(&dur)) { + dur = defaultDuration; + } + dur = wholeNoteMS / dur; + + if (ptr >= len) { + return false; + } + note = 0; + switch (buff[ptr++]) { case 'c': case 'C': note = 1; break; case 'd': case 'D': note = 3; break; case 'e': case 'E': note = 5; break; @@ -228,65 +286,85 @@ bool AudioGeneratorRTTTL::GetNextNote() case 'b': case 'B': note = 12; break; case 'p': case 'P': note = 0; break; default: return false; - } - if ((ptr < len) && (buff[ptr] == '#')) { - ptr++; - note++; - } - if ((ptr < len) && (buff[ptr] == '.')) { - ptr++; - dur += dur / 2; - } - if (!ReadInt(&scale)) { - scale = defaultOctave; - } - // Eat any trailing whitespace and comma - SkipWhitespace(); - if ((ptr < len) && (buff[ptr]==',')) { - ptr++; - } - - if (scale < 4) scale = 4; - if (scale > 7) scale = 7; - if (note) { - int freq = notes[(scale - 4) * 12 + note]; - // Convert from frequency in Hz to high and low samples in fixed point - ttlSamplesPerWaveFP10 = (rate << 10) / freq; - } else { - ttlSamplesPerWaveFP10 = 0; - } - ttlSamples = (rate * dur ) / 1000; - - //audioLogger->printf("%d %d %d %d %d\n", dur, note, scale, ttlSamplesPerWaveFP10, ttlSamples ); - - return true; + } + if ((ptr < len) && (buff[ptr] == '#')) { + ptr++; + note++; + } + if (!ReadInt(&scale)) { + scale = defaultOctave; + } + if ((ptr < len) && (buff[ptr] == '.')) { + ptr++; + dur += dur / 2; + } + // Eat any trailing whitespace and comma + SkipWhitespace(); + if ((ptr < len) && (buff[ptr] == ',')) { + ptr++; + } + + if (scale < 4) { + scale = 4; + } + if (scale > 7) { + scale = 7; + } + if (note) { + int freq = notes[(scale - 4) * 12 + note]; + // Convert from frequency in Hz to high and low samples in fixed point + ttlSamplesPerWaveFP10 = (rate << 10) / freq; + } else { + ttlSamplesPerWaveFP10 = 0; + } + ttlSamples = (rate * dur) / 1000; + + //audioLogger->printf("%d %d %d %d %d\n", dur, note, scale, ttlSamplesPerWaveFP10, ttlSamples ); + + return true; } -bool AudioGeneratorRTTTL::begin(AudioFileSource *source, AudioOutput *output) -{ - if (!source) return false; - file = source; - if (!output) return false; - this->output = output; - if (!file->isOpen()) return false; // Error - - len = file->getSize(); - buff = (char *)malloc(len); - if (!buff) return false; - if (file->read(buff, len) != (uint32_t)len) return false; - - ptr = 0; - samplesSent = 0; - ttlSamples = 0; - - if (!ParseHeader()) return false; - - if (!output->SetRate( rate )) return false; - if (!output->SetBitsPerSample( 16 )) return false; - if (!output->SetChannels( 2 )) return false; - if (!output->begin()) return false; - - running = true; - - return true; +bool AudioGeneratorRTTTL::begin(AudioFileSource *source, AudioOutput *output) { + if (!source) { + return false; + } + file = source; + if (!output) { + return false; + } + this->output = output; + if (!file->isOpen()) { + return false; // Error + } + + len = file->getSize(); + buff = (char *)malloc(len); + if (!buff) { + return false; + } + if (file->read(buff, len) != (uint32_t)len) { + return false; + } + + ptr = 0; + samplesSent = 0; + ttlSamples = 0; + + if (!ParseHeader()) { + return false; + } + + if (!output->SetRate(rate)) { + return false; + } + if (!output->SetChannels(2)) { + return false; + } + if (!output->begin()) { + return false; + } + + running = true; + + return true; } diff --git a/src/AudioGeneratorRTTTL.h b/src/AudioGeneratorRTTTL.h index d9f1d779..dc377a7c 100644 --- a/src/AudioGeneratorRTTTL.h +++ b/src/AudioGeneratorRTTTL.h @@ -1,24 +1,24 @@ /* - AudioGeneratorRTTTL - Audio output generator that plays RTTTL (Nokia ringtones) + AudioGeneratorRTTTL + Audio output generator that plays RTTTL (Nokia ringtones) - Based on the Rtttl Arduino library by James BM, https://github.com/spicajames/Rtttl - Based on the gist from Daniel Hall https://gist.github.com/smarthall/1618800 - - Copyright (C) 2018 Earle F. Philhower, III + Based on the Rtttl Arduino library by James BM, https://github.com/spicajames/Rtttl + Based on the gist from Daniel Hall https://gist.github.com/smarthall/1618800 - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + Copyright (C) 2018 Earle F. Philhower, III - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOGENERATORRTTTL_H @@ -26,24 +26,25 @@ #include "AudioGenerator.h" -class AudioGeneratorRTTTL : public AudioGenerator -{ - public: +class AudioGeneratorRTTTL : public AudioGenerator { +public: AudioGeneratorRTTTL(); virtual ~AudioGeneratorRTTTL() override; virtual bool begin(AudioFileSource *source, AudioOutput *output) override; virtual bool loop() override; virtual bool stop() override; virtual bool isRunning() override; - void SetRate(uint16_t hz) { rate = hz; } + void SetRate(uint16_t hz) { + rate = hz; + } - private: +private: bool SkipWhitespace(); bool ReadInt(int *dest); bool ParseHeader(); bool GetNextNote(); - - protected: + +protected: uint16_t rate; // We copy the entire tiny song to a buffer for easier access diff --git a/src/AudioGeneratorTalkie.cpp b/src/AudioGeneratorTalkie.cpp index 48ea14ae..631ecc93 100644 --- a/src/AudioGeneratorTalkie.cpp +++ b/src/AudioGeneratorTalkie.cpp @@ -1,302 +1,322 @@ /* - AudioGeneratorTalkie - Audio output generator that speaks using the LPC code in old TI speech chips - Output is locked at 8khz as that's that the hardcoded LPC coefficients are built around - - Based on the Talkie Arduino library by Peter Knight, https://github.com/going-digital/Talkie - - Copyright (C) 2020 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioGeneratorTalkie + Audio output generator that speaks using the LPC code in old TI speech chips + Output is locked at 8khz as that's that the hardcoded LPC coefficients are built around + + Based on the Talkie Arduino library by Peter Knight, https://github.com/going-digital/Talkie + + Copyright (C) 2020 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include "AudioGeneratorTalkie.h" -AudioGeneratorTalkie::AudioGeneratorTalkie() -{ - running = false; - lastFrame = false; - file = nullptr; - output = nullptr; - buff = nullptr; +AudioGeneratorTalkie::AudioGeneratorTalkie() { + running = false; + lastFrame = false; + file = nullptr; + output = nullptr; + buff = nullptr; } -AudioGeneratorTalkie::~AudioGeneratorTalkie() -{ - free(buff); +AudioGeneratorTalkie::~AudioGeneratorTalkie() { + free(buff); } bool AudioGeneratorTalkie::say(const uint8_t *data, size_t len, bool async) { - // Finish saying anything in the pipe - while (running) { - loop(); - delay(0); - } - buff = (uint8_t*)realloc(buff, len); - if (!buff) return false; - memcpy_P(buff, data, len); - - // Reset the interpreter to the start of the stream - ptrAddr = buff; - ptrBit = 0; - frameLeft = 0; - lastFrame = false; - - running = true; - - if (!async) { // Finish saying anything in the pipe while (running) { - loop(); - delay(0); + loop(); + delay(0); } - } - - return true; -} + buff = (uint8_t*)realloc(buff, len); + if (!buff) { + return false; + } + memcpy_P(buff, data, len); -bool AudioGeneratorTalkie::begin(AudioFileSource *source, AudioOutput *output) -{ - if (!output) return false; - this->output = output; - if (source) { - file = source; - if (!file->isOpen()) return false; // Error - auto len = file->getSize(); - uint8_t *temp = (uint8_t *)malloc(len); - if (!temp) return false; - if (file->read(temp, len) != (uint32_t)len) return false; - say(temp, len); - free(temp); - } else { // Reset the interpreter to the start of the stream ptrAddr = buff; ptrBit = 0; frameLeft = 0; - running = false; - } - - if (!output->SetRate( 8000 )) return false; - if (!output->SetBitsPerSample( 16 )) return false; - if (!output->SetChannels( 2 )) return false; - if (!output->begin()) return false; + lastFrame = false; + + running = true; + + if (!async) { + // Finish saying anything in the pipe + while (running) { + loop(); + delay(0); + } + } + + return true; +} + +bool AudioGeneratorTalkie::begin(AudioFileSource *source, AudioOutput *output) { + if (!output) { + return false; + } + this->output = output; + + if (!output->SetChannels(2)) { + return false; + } + if (!output->begin()) { + return false; + } + if (!output->SetRate(8000)) { + return false; + } + + if (source) { + file = source; + if (!file->isOpen()) { + return false; // Error + } + auto len = file->getSize(); + uint8_t *temp = (uint8_t *)malloc(len); + if (!temp) { + return false; + } + if (file->read(temp, len) != (uint32_t)len) { + return false; + } + say(temp, len); + free(temp); + } else { + // Reset the interpreter to the start of the stream + ptrAddr = buff; + ptrBit = 0; + frameLeft = 0; + running = false; + } - return true; + return true; } -bool AudioGeneratorTalkie::stop() -{ - if (!running) return true; - running = false; - output->stop(); - return file ? file->close() : true; +bool AudioGeneratorTalkie::stop() { + if (!running) { + return true; + } + running = false; + output->stop(); + return file ? file->close() : true; } -bool AudioGeneratorTalkie::isRunning() -{ - return running; +bool AudioGeneratorTalkie::isRunning() { + return running; } -bool AudioGeneratorTalkie::loop() -{ - if (!running) goto done; // Nothing to do here! +bool AudioGeneratorTalkie::loop() { + if (!running) { + goto done; // Nothing to do here! + } - if (!frameLeft) { - if (lastFrame) { - running = false; - goto done; + if (!frameLeft) { + if (lastFrame) { + running = false; + goto done; + } + lastFrame = genOneFrame(); } - lastFrame = genOneFrame(); - } - - if (frameLeft) { - for ( ; frameLeft; frameLeft--) { - auto res = genOneSample(); - int16_t r[2] = {res, res}; - if (!output->ConsumeSample(r)) break; + + if (frameLeft) { + for (; frameLeft; frameLeft--) { + auto res = genOneSample(); + int16_t r[2] = {res, res}; + if (!output->ConsumeSample(r)) { + break; + } + } } - } - + done: - if (file) file->loop(); - output->loop(); + if (file) { + file->loop(); + } + output->loop(); - return running; + return running; } // The ROMs used with the TI speech were serial, not byte wide. // Here's a handy routine to flip ROM data which is usually reversed. -uint8_t AudioGeneratorTalkie::rev(uint8_t a) -{ - // 76543210 - a = (a>>4) | (a<<4); // Swap in groups of 4 - // 32107654 - a = ((a & 0xcc)>>2) | ((a & 0x33)<<2); // Swap in groups of 2 - // 10325476 - a = ((a & 0xaa)>>1) | ((a & 0x55)<<1); // Swap bit pairs - // 01234567 - return a; +uint8_t AudioGeneratorTalkie::rev(uint8_t a) { + // 76543210 + a = (a >> 4) | (a << 4); // Swap in groups of 4 + // 32107654 + a = ((a & 0xcc) >> 2) | ((a & 0x33) << 2); // Swap in groups of 2 + // 10325476 + a = ((a & 0xaa) >> 1) | ((a & 0x55) << 1); // Swap bit pairs + // 01234567 + return a; } uint8_t AudioGeneratorTalkie::getBits(uint8_t bits) { - uint8_t value; - uint16_t data; - data = rev(ptrAddr[0])<<8; - if (ptrBit+bits > 8) { - data |= rev(ptrAddr[1]); - } - data <<= ptrBit; - value = data >> (16-bits); - ptrBit += bits; - if (ptrBit >= 8) { - ptrBit -= 8; - ptrAddr++; - } - return value; + uint8_t value; + uint16_t data; + data = rev(ptrAddr[0]) << 8; + if (ptrBit + bits > 8) { + data |= rev(ptrAddr[1]); + } + data <<= ptrBit; + value = data >> (16 - bits); + ptrBit += bits; + if (ptrBit >= 8) { + ptrBit -= 8; + ptrAddr++; + } + return value; } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnarrowing" // Constant LPC coefficient tables -static const uint8_t tmsEnergy[0x10] = {0x00,0x02,0x03,0x04,0x05,0x07,0x0a,0x0f,0x14,0x20,0x29,0x39,0x51,0x72,0xa1,0xff}; -static const uint8_t tmsPeriod[0x40] = {0x00,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2D,0x2F,0x31,0x33,0x35,0x36,0x39,0x3B,0x3D,0x3F,0x42,0x45,0x47,0x49,0x4D,0x4F,0x51,0x55,0x57,0x5C,0x5F,0x63,0x66,0x6A,0x6E,0x73,0x77,0x7B,0x80,0x85,0x8A,0x8F,0x95,0x9A,0xA0}; -static const int16_t tmsK1[0x20] = {0x82C0,0x8380,0x83C0,0x8440,0x84C0,0x8540,0x8600,0x8780,0x8880,0x8980,0x8AC0,0x8C00,0x8D40,0x8F00,0x90C0,0x92C0,0x9900,0xA140,0xAB80,0xB840,0xC740,0xD8C0,0xEBC0,0x0000,0x1440,0x2740,0x38C0,0x47C0,0x5480,0x5EC0,0x6700,0x6D40}; -static const int16_t tmsK2[0x20] = {0xAE00,0xB480,0xBB80,0xC340,0xCB80,0xD440,0xDDC0,0xE780,0xF180,0xFBC0,0x0600,0x1040,0x1A40,0x2400,0x2D40,0x3600,0x3E40,0x45C0,0x4CC0,0x5300,0x5880,0x5DC0,0x6240,0x6640,0x69C0,0x6CC0,0x6F80,0x71C0,0x73C0,0x7580,0x7700,0x7E80}; -static const int8_t tmsK3[0x10] = {0x92,0x9F,0xAD,0xBA,0xC8,0xD5,0xE3,0xF0,0xFE,0x0B,0x19,0x26,0x34,0x41,0x4F,0x5C}; -static const int8_t tmsK4[0x10] = {0xAE,0xBC,0xCA,0xD8,0xE6,0xF4,0x01,0x0F,0x1D,0x2B,0x39,0x47,0x55,0x63,0x71,0x7E}; -static const int8_t tmsK5[0x10] = {0xAE,0xBA,0xC5,0xD1,0xDD,0xE8,0xF4,0xFF,0x0B,0x17,0x22,0x2E,0x39,0x45,0x51,0x5C}; -static const int8_t tmsK6[0x10] = {0xC0,0xCB,0xD6,0xE1,0xEC,0xF7,0x03,0x0E,0x19,0x24,0x2F,0x3A,0x45,0x50,0x5B,0x66}; -static const int8_t tmsK7[0x10] = {0xB3,0xBF,0xCB,0xD7,0xE3,0xEF,0xFB,0x07,0x13,0x1F,0x2B,0x37,0x43,0x4F,0x5A,0x66}; -static const int8_t tmsK8[0x08] = {0xC0,0xD8,0xF0,0x07,0x1F,0x37,0x4F,0x66}; -static const int8_t tmsK9[0x08] = {0xC0,0xD4,0xE8,0xFC,0x10,0x25,0x39,0x4D}; -static const int8_t tmsK10[0x08] = {0xCD,0xDF,0xF1,0x04,0x16,0x20,0x3B,0x4D}; +static const uint8_t tmsEnergy[0x10] = {0x00, 0x02, 0x03, 0x04, 0x05, 0x07, 0x0a, 0x0f, 0x14, 0x20, 0x29, 0x39, 0x51, 0x72, 0xa1, 0xff}; +static const uint8_t tmsPeriod[0x40] = {0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2D, 0x2F, 0x31, 0x33, 0x35, 0x36, 0x39, 0x3B, 0x3D, 0x3F, 0x42, 0x45, 0x47, 0x49, 0x4D, 0x4F, 0x51, 0x55, 0x57, 0x5C, 0x5F, 0x63, 0x66, 0x6A, 0x6E, 0x73, 0x77, 0x7B, 0x80, 0x85, 0x8A, 0x8F, 0x95, 0x9A, 0xA0}; +static const int16_t tmsK1[0x20] = {0x82C0, 0x8380, 0x83C0, 0x8440, 0x84C0, 0x8540, 0x8600, 0x8780, 0x8880, 0x8980, 0x8AC0, 0x8C00, 0x8D40, 0x8F00, 0x90C0, 0x92C0, 0x9900, 0xA140, 0xAB80, 0xB840, 0xC740, 0xD8C0, 0xEBC0, 0x0000, 0x1440, 0x2740, 0x38C0, 0x47C0, 0x5480, 0x5EC0, 0x6700, 0x6D40}; +static const int16_t tmsK2[0x20] = {0xAE00, 0xB480, 0xBB80, 0xC340, 0xCB80, 0xD440, 0xDDC0, 0xE780, 0xF180, 0xFBC0, 0x0600, 0x1040, 0x1A40, 0x2400, 0x2D40, 0x3600, 0x3E40, 0x45C0, 0x4CC0, 0x5300, 0x5880, 0x5DC0, 0x6240, 0x6640, 0x69C0, 0x6CC0, 0x6F80, 0x71C0, 0x73C0, 0x7580, 0x7700, 0x7E80}; +static const int8_t tmsK3[0x10] = {0x92, 0x9F, 0xAD, 0xBA, 0xC8, 0xD5, 0xE3, 0xF0, 0xFE, 0x0B, 0x19, 0x26, 0x34, 0x41, 0x4F, 0x5C}; +static const int8_t tmsK4[0x10] = {0xAE, 0xBC, 0xCA, 0xD8, 0xE6, 0xF4, 0x01, 0x0F, 0x1D, 0x2B, 0x39, 0x47, 0x55, 0x63, 0x71, 0x7E}; +static const int8_t tmsK5[0x10] = {0xAE, 0xBA, 0xC5, 0xD1, 0xDD, 0xE8, 0xF4, 0xFF, 0x0B, 0x17, 0x22, 0x2E, 0x39, 0x45, 0x51, 0x5C}; +static const int8_t tmsK6[0x10] = {0xC0, 0xCB, 0xD6, 0xE1, 0xEC, 0xF7, 0x03, 0x0E, 0x19, 0x24, 0x2F, 0x3A, 0x45, 0x50, 0x5B, 0x66}; +static const int8_t tmsK7[0x10] = {0xB3, 0xBF, 0xCB, 0xD7, 0xE3, 0xEF, 0xFB, 0x07, 0x13, 0x1F, 0x2B, 0x37, 0x43, 0x4F, 0x5A, 0x66}; +static const int8_t tmsK8[0x08] = {0xC0, 0xD8, 0xF0, 0x07, 0x1F, 0x37, 0x4F, 0x66}; +static const int8_t tmsK9[0x08] = {0xC0, 0xD4, 0xE8, 0xFC, 0x10, 0x25, 0x39, 0x4D}; +static const int8_t tmsK10[0x08] = {0xCD, 0xDF, 0xF1, 0x04, 0x16, 0x20, 0x3B, 0x4D}; // The chirp we active the filter using -static const int8_t chirp[] = {0x00,0x2a,0xd4,0x32,0xb2,0x12,0x25,0x14,0x02,0xe1,0xc5,0x02,0x5f,0x5a,0x05,0x0f,0x26,0xfc,0xa5,0xa5,0xd6,0xdd,0xdc,0xfc,0x25,0x2b,0x22,0x21,0x0f,0xff,0xf8,0xee,0xed,0xef,0xf7,0xf6,0xfa,0x00,0x03,0x02,0x01}; +static const int8_t chirp[] = {0x00, 0x2a, 0xd4, 0x32, 0xb2, 0x12, 0x25, 0x14, 0x02, 0xe1, 0xc5, 0x02, 0x5f, 0x5a, 0x05, 0x0f, 0x26, 0xfc, 0xa5, 0xa5, 0xd6, 0xdd, 0xdc, 0xfc, 0x25, 0x2b, 0x22, 0x21, 0x0f, 0xff, 0xf8, 0xee, 0xed, 0xef, 0xf7, 0xf6, 0xfa, 0x00, 0x03, 0x02, 0x01}; #pragma GCC diagnostic pop bool AudioGeneratorTalkie::genOneFrame() { - uint8_t energy; - uint8_t repeat; - - // Read speech data, processing the variable size frames. - - energy = getBits(4); - if (energy == 0) { - // Energy = 0: rest frame - synthEnergy = 0; - } else if (energy == 0xf) { - // Energy = 15: stop frame. Silence the synthesiser. - synthEnergy = 0; - synthK1 = 0; - synthK2 = 0; - synthK3 = 0; - synthK4 = 0; - synthK5 = 0; - synthK6 = 0; - synthK7 = 0; - synthK8 = 0; - synthK9 = 0; - synthK10 = 0; - } else { - synthEnergy = tmsEnergy[energy]; - repeat = getBits(1); - synthPeriod = tmsPeriod[getBits(6)]; - // A repeat frame uses the last coefficients - if (!repeat) { - // All frames use the first 4 coefficients - synthK1 = tmsK1[getBits(5)]; - synthK2 = tmsK2[getBits(5)]; - synthK3 = tmsK3[getBits(4)]; - synthK4 = tmsK4[getBits(4)]; - if (synthPeriod) { - // Voiced frames use 6 extra coefficients. - synthK5 = tmsK5[getBits(4)]; - synthK6 = tmsK6[getBits(4)]; - synthK7 = tmsK7[getBits(4)]; - synthK8 = tmsK8[getBits(3)]; - synthK9 = tmsK9[getBits(3)]; - synthK10 = tmsK10[getBits(3)]; - } + uint8_t energy; + uint8_t repeat; + + // Read speech data, processing the variable size frames. + + energy = getBits(4); + if (energy == 0) { + // Energy = 0: rest frame + synthEnergy = 0; + } else if (energy == 0xf) { + // Energy = 15: stop frame. Silence the synthesiser. + synthEnergy = 0; + synthK1 = 0; + synthK2 = 0; + synthK3 = 0; + synthK4 = 0; + synthK5 = 0; + synthK6 = 0; + synthK7 = 0; + synthK8 = 0; + synthK9 = 0; + synthK10 = 0; + } else { + synthEnergy = tmsEnergy[energy]; + repeat = getBits(1); + synthPeriod = tmsPeriod[getBits(6)]; + // A repeat frame uses the last coefficients + if (!repeat) { + // All frames use the first 4 coefficients + synthK1 = tmsK1[getBits(5)]; + synthK2 = tmsK2[getBits(5)]; + synthK3 = tmsK3[getBits(4)]; + synthK4 = tmsK4[getBits(4)]; + if (synthPeriod) { + // Voiced frames use 6 extra coefficients. + synthK5 = tmsK5[getBits(4)]; + synthK6 = tmsK6[getBits(4)]; + synthK7 = tmsK7[getBits(4)]; + synthK8 = tmsK8[getBits(3)]; + synthK9 = tmsK9[getBits(3)]; + synthK10 = tmsK10[getBits(3)]; + } + } } - } - frameLeft = 8000 / 40; - - return (energy == 0xf); // Last frame will return true -} + frameLeft = 8000 / 40; -int16_t AudioGeneratorTalkie::genOneSample() -{ - static uint8_t periodCounter; - static int16_t x0,x1,x2,x3,x4,x5,x6,x7,x8,x9; - int16_t u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10; + return (energy == 0xf); // Last frame will return true +} - if (synthPeriod) { - // Voiced source - if (periodCounter < synthPeriod) { - periodCounter++; +int16_t AudioGeneratorTalkie::genOneSample() { + static uint8_t periodCounter; + static int16_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9; + int16_t u0, u1, u2, u3, u4, u5, u6, u7, u8, u9, u10; + + if (synthPeriod) { + // Voiced source + if (periodCounter < synthPeriod) { + periodCounter++; + } else { + periodCounter = 0; + } + if (periodCounter < sizeof(chirp)) { + u10 = ((chirp[periodCounter]) * (uint32_t) synthEnergy) >> 8; + } else { + u10 = 0; + } } else { - periodCounter = 0; + // Unvoiced source + static uint16_t synthRand = 1; + synthRand = (synthRand >> 1) ^ ((synthRand & 1) ? 0xB800 : 0); + u10 = (synthRand & 1) ? synthEnergy : -synthEnergy; } - if (periodCounter < sizeof(chirp)) { - u10 = ((chirp[periodCounter]) * (uint32_t) synthEnergy) >> 8; - } else { - u10 = 0; + // Lattice filter forward path + u9 = u10 - (((int16_t)synthK10 * x9) >> 7); + u8 = u9 - (((int16_t)synthK9 * x8) >> 7); + u7 = u8 - (((int16_t)synthK8 * x7) >> 7); + u6 = u7 - (((int16_t)synthK7 * x6) >> 7); + u5 = u6 - (((int16_t)synthK6 * x5) >> 7); + u4 = u5 - (((int16_t)synthK5 * x4) >> 7); + u3 = u4 - (((int16_t)synthK4 * x3) >> 7); + u2 = u3 - (((int16_t)synthK3 * x2) >> 7); + u1 = u2 - (((int32_t)synthK2 * x1) >> 15); + u0 = u1 - (((int32_t)synthK1 * x0) >> 15); + + // Output clamp + if (u0 > 511) { + u0 = 511; } - } else { - // Unvoiced source - static uint16_t synthRand = 1; - synthRand = (synthRand >> 1) ^ ((synthRand & 1) ? 0xB800 : 0); - u10 = (synthRand & 1) ? synthEnergy : -synthEnergy; - } - // Lattice filter forward path - u9 = u10 - (((int16_t)synthK10*x9) >> 7); - u8 = u9 - (((int16_t)synthK9*x8) >> 7); - u7 = u8 - (((int16_t)synthK8*x7) >> 7); - u6 = u7 - (((int16_t)synthK7*x6) >> 7); - u5 = u6 - (((int16_t)synthK6*x5) >> 7); - u4 = u5 - (((int16_t)synthK5*x4) >> 7); - u3 = u4 - (((int16_t)synthK4*x3) >> 7); - u2 = u3 - (((int16_t)synthK3*x2) >> 7); - u1 = u2 - (((int32_t)synthK2*x1) >> 15); - u0 = u1 - (((int32_t)synthK1*x0) >> 15); - - // Output clamp - if (u0 > 511) u0 = 511; - if (u0 < -512) u0 = -512; - - // Lattice filter reverse path - x9 = x8 + (((int16_t)synthK9*u8) >> 7); - x8 = x7 + (((int16_t)synthK8*u7) >> 7); - x7 = x6 + (((int16_t)synthK7*u6) >> 7); - x6 = x5 + (((int16_t)synthK6*u5) >> 7); - x5 = x4 + (((int16_t)synthK5*u4) >> 7); - x4 = x3 + (((int16_t)synthK4*u3) >> 7); - x3 = x2 + (((int16_t)synthK3*u2) >> 7); - x2 = x1 + (((int32_t)synthK2*u1) >> 15); - x1 = x0 + (((int32_t)synthK1*u0) >> 15); - x0 = u0; - - uint16_t v = u0; // 10 bits - v <<= 6; // Now full 16 - return v; + if (u0 < -512) { + u0 = -512; + } + + // Lattice filter reverse path + x9 = x8 + (((int16_t)synthK9 * u8) >> 7); + x8 = x7 + (((int16_t)synthK8 * u7) >> 7); + x7 = x6 + (((int16_t)synthK7 * u6) >> 7); + x6 = x5 + (((int16_t)synthK6 * u5) >> 7); + x5 = x4 + (((int16_t)synthK5 * u4) >> 7); + x4 = x3 + (((int16_t)synthK4 * u3) >> 7); + x3 = x2 + (((int16_t)synthK3 * u2) >> 7); + x2 = x1 + (((int32_t)synthK2 * u1) >> 15); + x1 = x0 + (((int32_t)synthK1 * u0) >> 15); + x0 = u0; + + uint16_t v = u0; // 10 bits + v <<= 6; // Now full 16 + return v; } diff --git a/src/AudioGeneratorTalkie.h b/src/AudioGeneratorTalkie.h index dbf06abb..b8fd6d45 100644 --- a/src/AudioGeneratorTalkie.h +++ b/src/AudioGeneratorTalkie.h @@ -1,24 +1,24 @@ /* - AudioGeneratorTalkie - Audio output generator that speaks using the LPC code in old TI speech chips - Output is locked at 8khz as that's that the hardcoded LPC coefficients are built around - - Based on the Talkie Arduino library by Peter Knight, https://github.com/going-digital/Talkie - - Copyright (C) 2020 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioGeneratorTalkie + Audio output generator that speaks using the LPC code in old TI speech chips + Output is locked at 8khz as that's that the hardcoded LPC coefficients are built around + + Based on the Talkie Arduino library by Peter Knight, https://github.com/going-digital/Talkie + + Copyright (C) 2020 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOGENERATORTALKIE_H @@ -26,9 +26,8 @@ #include "AudioGenerator.h" -class AudioGeneratorTalkie : public AudioGenerator -{ - public: +class AudioGeneratorTalkie : public AudioGenerator { +public: AudioGeneratorTalkie(); virtual ~AudioGeneratorTalkie() override; virtual bool begin(AudioFileSource *source, AudioOutput *output) override; @@ -36,11 +35,11 @@ class AudioGeneratorTalkie : public AudioGenerator virtual bool stop() override; virtual bool isRunning() override; bool say(const uint8_t *data, size_t len, bool async = false); - - protected: + +protected: // The data stream we're playing uint8_t *buff; - + // Codeword stream handlers uint8_t *ptrAddr; uint8_t ptrBit; @@ -48,7 +47,7 @@ class AudioGeneratorTalkie : public AudioGenerator bool lastFrame; bool genOneFrame(); // Fill up one frame's worth of data, returns if this is the last frame int16_t genOneSample(); // Generate one sample of a frame - + // Utilities uint8_t rev(uint8_t a); uint8_t getBits(uint8_t bits); @@ -58,7 +57,7 @@ class AudioGeneratorTalkie : public AudioGenerator uint16_t synthEnergy; int16_t synthK1, synthK2; int8_t synthK3, synthK4, synthK5, synthK6, synthK7, synthK8, synthK9, synthK10; - + int frameLeft; }; diff --git a/src/AudioGeneratorWAV.cpp b/src/AudioGeneratorWAV.cpp index 6c8f7a24..b85bb9c0 100644 --- a/src/AudioGeneratorWAV.cpp +++ b/src/AudioGeneratorWAV.cpp @@ -1,316 +1,330 @@ /* - AudioGeneratorWAV - Audio output generator that reads 8 and 16-bit WAV files - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioGeneratorWAV + Audio output generator that reads 8 and 16-bit WAV files + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include "AudioGeneratorWAV.h" -AudioGeneratorWAV::AudioGeneratorWAV() -{ - running = false; - file = NULL; - output = NULL; - buffSize = 128; - buff = NULL; - buffPtr = 0; - buffLen = 0; +AudioGeneratorWAV::AudioGeneratorWAV() { + running = false; + file = NULL; + output = NULL; + buffSize = 128; + buff = NULL; + buffPtr = 0; + buffLen = 0; } -AudioGeneratorWAV::~AudioGeneratorWAV() -{ - free(buff); - buff = NULL; +AudioGeneratorWAV::~AudioGeneratorWAV() { + free(buff); + buff = NULL; } -bool AudioGeneratorWAV::stop() -{ - if (!running) return true; - running = false; - free(buff); - buff = NULL; - output->stop(); - return file->close(); +bool AudioGeneratorWAV::stop() { + if (!running) { + return true; + } + running = false; + free(buff); + buff = NULL; + output->stop(); + return file->close(); } -bool AudioGeneratorWAV::isRunning() -{ - return running; +bool AudioGeneratorWAV::isRunning() { + return running; } // Handle buffered reading, reload each time we run out of data -bool AudioGeneratorWAV::GetBufferedData(int bytes, void *dest) -{ - if (!running) return false; // Nothing to do here! - uint8_t *p = reinterpret_cast(dest); - while (bytes--) { - // Potentially load next batch of data... - if (buffPtr >= buffLen) { - buffPtr = 0; - uint32_t toRead = availBytes > buffSize ? buffSize : availBytes; - buffLen = file->read( buff, toRead ); - availBytes -= buffLen; +bool AudioGeneratorWAV::GetBufferedData(int bytes, void *dest) { + if (!running) { + return false; // Nothing to do here! + } + uint8_t *p = reinterpret_cast(dest); + while (bytes--) { + // Potentially load next batch of data... + if (buffPtr >= buffLen) { + buffPtr = 0; + uint32_t toRead = availBytes > buffSize ? buffSize : availBytes; + buffLen = file->read(buff, toRead); + availBytes -= buffLen; + } + if (buffPtr >= buffLen) { + return false; // No data left! + } + *(p++) = buff[buffPtr++]; } - if (buffPtr >= buffLen) - return false; // No data left! - *(p++) = buff[buffPtr++]; - } - return true; + return true; } -bool AudioGeneratorWAV::loop() -{ - if (!running) goto done; // Nothing to do here! - - // First, try and push in the stored sample. If we can't, then punt and try later - if (!output->ConsumeSample(lastSample)) goto done; // Can't send, but no error detected - - // Try and stuff the buffer one sample at a time - do - { - if (bitsPerSample == 8) { - uint8_t l, r; - if (!GetBufferedData(1, &l)) stop(); - if (channels == 2) { - if (!GetBufferedData(1, &r)) stop(); - } else { - r = 0; - } - lastSample[AudioOutput::LEFTCHANNEL] = l; - lastSample[AudioOutput::RIGHTCHANNEL] = r; - } else if (bitsPerSample == 16) { - if (!GetBufferedData(2, &lastSample[AudioOutput::LEFTCHANNEL])) stop(); - if (channels == 2) { - if (!GetBufferedData(2, &lastSample[AudioOutput::RIGHTCHANNEL])) stop(); - } else { - lastSample[AudioOutput::RIGHTCHANNEL] = 0; - } +bool AudioGeneratorWAV::loop() { + if (!running) { + goto done; // Nothing to do here! } - } while (running && output->ConsumeSample(lastSample)); + + // First, try and push in the stored sample. If we can't, then punt and try later + if (!output->ConsumeSample(lastSample)) { + goto done; // Can't send, but no error detected + } + + // Try and stuff the buffer one sample at a time + do { + if (bitsPerSample == 8) { + uint8_t l, r; + if (!GetBufferedData(1, &l)) { + stop(); + } + if (channels == 2) { + if (!GetBufferedData(1, &r)) { + stop(); + } + } else { + r = 0; + } + + // Upsample from unsigned 8 bits to signed 16 bits + lastSample[AudioOutput::LEFTCHANNEL] = (((int16_t)(lastSample[AudioOutput::LEFTCHANNEL] & 0xff)) - 128) << 8; + lastSample[AudioOutput::RIGHTCHANNEL] = (((int16_t)(lastSample[AudioOutput::RIGHTCHANNEL] & 0xff)) - 128) << 8; + + } else if (bitsPerSample == 16) { + if (!GetBufferedData(2, &lastSample[AudioOutput::LEFTCHANNEL])) { + stop(); + } + if (channels == 2) { + if (!GetBufferedData(2, &lastSample[AudioOutput::RIGHTCHANNEL])) { + stop(); + } + } else { + lastSample[AudioOutput::RIGHTCHANNEL] = 0; + } + } + } while (running && output->ConsumeSample(lastSample)); done: - file->loop(); - output->loop(); + file->loop(); + output->loop(); - return running; + return running; } -bool AudioGeneratorWAV::ReadWAVInfo() -{ - uint32_t u32; - uint16_t u16; - int toSkip; - - // WAV specification document: - // https://www.aelius.com/njh/wavemetatools/doc/riffmci.pdf - - // Header == "RIFF" - if (!ReadU32(&u32)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); - return false; - }; - if (u32 != 0x46464952) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, invalid RIFF header, got: %08X \n"), (uint32_t) u32); - return false; - } - - // Skip ChunkSize - if (!ReadU32(&u32)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); - return false; - }; - - // Format == "WAVE" - if (!ReadU32(&u32)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); - return false; - }; - if (u32 != 0x45564157) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, invalid WAVE header, got: %08X \n"), (uint32_t) u32); - return false; - } - - // there might be JUNK or PAD - ignore it by continuing reading until we get to "fmt " - while (1) { +bool AudioGeneratorWAV::ReadWAVInfo() { + uint32_t u32; + uint16_t u16; + int toSkip; + + // WAV specification document: + // https://www.aelius.com/njh/wavemetatools/doc/riffmci.pdf + + // Header == "RIFF" if (!ReadU32(&u32)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); - return false; + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); + return false; }; - if (u32 == 0x20746d66) break; // 'fmt ' - }; - - // subchunk size - if (!ReadU32(&u32)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); - return false; - }; - if (u32 == 16) { toSkip = 0; } - else if (u32 == 18) { toSkip = 18 - 16; } - else if (u32 == 40) { toSkip = 40 - 16; } - else { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, appears not to be standard PCM \n")); - return false; - } // we only do standard PCM - - // AudioFormat - if (!ReadU16(&u16)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); - return false; - }; - if (u16 != 1) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, AudioFormat appears not to be standard PCM \n")); - return false; - } // we only do standard PCM - - // NumChannels - if (!ReadU16(&channels)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); - return false; - }; - if ((channels<1) || (channels>2)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, only mono and stereo are supported \n")); - return false; - } // Mono or stereo support only - - // SampleRate - if (!ReadU32(&sampleRate)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); - return false; - }; - if (sampleRate < 1) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, unknown sample rate \n")); - return false; - } // Weird rate, punt. Will need to check w/DAC to see if supported - - // Ignore byterate and blockalign - if (!ReadU32(&u32)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); - return false; - }; - if (!ReadU16(&u16)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); - return false; - }; - - // Bits per sample - if (!ReadU16(&bitsPerSample)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); - return false; - }; - if ((bitsPerSample!=8) && (bitsPerSample != 16)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, only 8 or 16 bits is supported \n")); - return false; - } // Only 8 or 16 bits - - // Skip any extra header - while (toSkip) { - uint8_t ign; - if (!ReadU8(&ign)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); - return false; + if (u32 != 0x46464952) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, invalid RIFF header\n")); + return false; + } + + // Skip ChunkSize + if (!ReadU32(&u32)) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); + return false; }; - toSkip--; - } - // look for data subchunk - do { - // id == "data" + // Format == "WAVE" if (!ReadU32(&u32)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); - return false; + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); + return false; + }; + if (u32 != 0x45564157) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, invalid WAVE header\n")); + return false; + } + + // there might be JUNK or PAD - ignore it by continuing reading until we get to "fmt " + while (1) { + if (!ReadU32(&u32)) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); + return false; + }; + if (u32 == 0x20746d66) { + break; // 'fmt ' + } + }; + + // subchunk size + if (!ReadU32(&u32)) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); + return false; + }; + if (u32 == 16) { + toSkip = 0; + } else if (u32 == 18) { + toSkip = 18 - 16; + } else if (u32 == 40) { + toSkip = 40 - 16; + } else { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, appears not to be standard PCM \n")); + return false; + } // we only do standard PCM + + // AudioFormat + if (!ReadU16(&u16)) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); + return false; + }; + if (u16 != 1) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, AudioFormat appears not to be standard PCM \n")); + return false; + } // we only do standard PCM + + // NumChannels + if (!ReadU16(&channels)) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); + return false; }; - if (u32 == 0x61746164) break; // "data" - // Skip size, read until end of chunk + if ((channels < 1) || (channels > 2)) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, only mono and stereo are supported \n")); + return false; + } // Mono or stereo support only + + // SampleRate + if (!ReadU32(&sampleRate)) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); + return false; + }; + if (sampleRate < 1) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, unknown sample rate \n")); + return false; + } // Weird rate, punt. Will need to check w/DAC to see if supported + + // Ignore byterate and blockalign if (!ReadU32(&u32)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); - return false; + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); + return false; + }; + if (!ReadU16(&u16)) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); + return false; }; - if(!file->seek(u32, SEEK_CUR)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data, seek failed\n")); - return false; + + // Bits per sample + if (!ReadU16(&bitsPerSample)) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); + return false; + }; + if ((bitsPerSample != 8) && (bitsPerSample != 16)) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, only 8 or 16 bits is supported \n")); + return false; + } // Only 8 or 16 bits + + // Skip any extra header + while (toSkip) { + uint8_t ign; + if (!ReadU8(&ign)) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); + return false; + }; + toSkip--; } - } while (1); - if (!file->isOpen()) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, file is not open\n")); - return false; - }; - - // Skip size, read until end of file... - if (!ReadU32(&u32)) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); - return false; - }; - availBytes = u32; - - // Now set up the buffer or fail - buff = reinterpret_cast(malloc(buffSize)); - if (!buff) { - Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, failed to set up buffer \n")); - return false; - }; - buffPtr = 0; - buffLen = 0; - - return true; + + // look for data subchunk + do { + // id == "data" + if (!ReadU32(&u32)) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); + return false; + }; + if (u32 == 0x61746164) { + break; // "data" + } + // Skip size, read until end of chunk + if (!ReadU32(&u32)) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); + return false; + }; + if (!file->seek(u32, SEEK_CUR)) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data, seek failed\n")); + return false; + } + } while (1); + if (!file->isOpen()) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, file is not open\n")); + return false; + }; + + // Skip size, read until end of file... + if (!ReadU32(&u32)) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: failed to read WAV data\n")); + return false; + }; + availBytes = u32; + + // Now set up the buffer or fail + buff = reinterpret_cast(malloc(buffSize)); + if (!buff) { + Serial.printf_P(PSTR("AudioGeneratorWAV::ReadWAVInfo: cannot read WAV, failed to set up buffer \n")); + return false; + }; + buffPtr = 0; + buffLen = 0; + + return true; } -bool AudioGeneratorWAV::begin(AudioFileSource *source, AudioOutput *output) -{ - if (!source) { - Serial.printf_P(PSTR("AudioGeneratorWAV::begin: failed: invalid source\n")); - return false; - } - file = source; - if (!output) { - Serial.printf_P(PSTR("AudioGeneratorWAV::begin: invalid output\n")); - return false; - } - this->output = output; - if (!file->isOpen()) { - Serial.printf_P(PSTR("AudioGeneratorWAV::begin: file not open\n")); - return false; - } // Error - - if (!ReadWAVInfo()) { - Serial.printf_P(PSTR("AudioGeneratorWAV::begin: failed during ReadWAVInfo\n")); - return false; - } - - if (!output->SetRate( sampleRate )) { - Serial.printf_P(PSTR("AudioGeneratorWAV::begin: failed to SetRate in output\n")); - return false; - } - if (!output->SetBitsPerSample( bitsPerSample )) { - Serial.printf_P(PSTR("AudioGeneratorWAV::begin: failed to SetBitsPerSample in output\n")); - return false; - } - if (!output->SetChannels( channels )) { - Serial.printf_P(PSTR("AudioGeneratorWAV::begin: failed to SetChannels in output\n")); - return false; - } - if (!output->begin()) { - Serial.printf_P(PSTR("AudioGeneratorWAV::begin: output's begin did not return true\n")); - return false; - } - - running = true; - - return true; +bool AudioGeneratorWAV::begin(AudioFileSource *source, AudioOutput *output) { + if (!source) { + Serial.printf_P(PSTR("AudioGeneratorWAV::begin: failed: invalid source\n")); + return false; + } + file = source; + if (!output) { + Serial.printf_P(PSTR("AudioGeneratorWAV::begin: invalid output\n")); + return false; + } + this->output = output; + if (!file->isOpen()) { + Serial.printf_P(PSTR("AudioGeneratorWAV::begin: file not open\n")); + return false; + } // Error + + if (!ReadWAVInfo()) { + Serial.printf_P(PSTR("AudioGeneratorWAV::begin: failed during ReadWAVInfo\n")); + return false; + } + + if (!output->SetRate(sampleRate)) { + Serial.printf_P(PSTR("AudioGeneratorWAV::begin: failed to SetRate in output\n")); + return false; + } + if (!output->SetChannels(channels)) { + Serial.printf_P(PSTR("AudioGeneratorWAV::begin: failed to SetChannels in output\n")); + return false; + } + if (!output->begin()) { + Serial.printf_P(PSTR("AudioGeneratorWAV::begin: output's begin did not return true\n")); + return false; + } + + running = true; + + return true; } diff --git a/src/AudioGeneratorWAV.h b/src/AudioGeneratorWAV.h index 185454f1..8d7853fa 100644 --- a/src/AudioGeneratorWAV.h +++ b/src/AudioGeneratorWAV.h @@ -1,21 +1,21 @@ /* - AudioGeneratorWAV - Audio output generator that reads 8 and 16-bit WAV files - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioGeneratorWAV + Audio output generator that reads 8 and 16-bit WAV files + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOGENERATORWAV_H @@ -23,31 +23,38 @@ #include "AudioGenerator.h" -class AudioGeneratorWAV : public AudioGenerator -{ - public: +class AudioGeneratorWAV : public AudioGenerator { +public: AudioGeneratorWAV(); virtual ~AudioGeneratorWAV() override; virtual bool begin(AudioFileSource *source, AudioOutput *output) override; virtual bool loop() override; virtual bool stop() override; virtual bool isRunning() override; - void SetBufferSize(int sz) { buffSize = sz; } + void SetBufferSize(int sz) { + buffSize = sz; + } - private: - bool ReadU32(uint32_t *dest) { return file->read(reinterpret_cast(dest), 4); } - bool ReadU16(uint16_t *dest) { return file->read(reinterpret_cast(dest), 2); } - bool ReadU8(uint8_t *dest) { return file->read(reinterpret_cast(dest), 1); } +private: + bool ReadU32(uint32_t *dest) { + return file->read(reinterpret_cast(dest), 4); + } + bool ReadU16(uint16_t *dest) { + return file->read(reinterpret_cast(dest), 2); + } + bool ReadU8(uint8_t *dest) { + return file->read(reinterpret_cast(dest), 1); + } bool GetBufferedData(int bytes, void *dest); bool ReadWAVInfo(); - - protected: + +protected: // WAV info uint16_t channels; uint32_t sampleRate; uint16_t bitsPerSample; - + uint32_t availBytes; // We need to buffer some data in-RAM to avoid doing 1000s of small reads diff --git a/src/AudioLogger.h b/src/AudioLogger.h index 3ea08989..dfc091c6 100644 --- a/src/AudioLogger.h +++ b/src/AudioLogger.h @@ -4,10 +4,11 @@ #ifndef _AUDIOLOGGER_H #define _AUDIOLOGGER_H -class DevNullOut: public Print -{ +class DevNullOut: public Print { public: - virtual size_t write(uint8_t) { return 1; } + virtual size_t write(uint8_t) { + return 1; + } }; extern DevNullOut silencedLogger; diff --git a/src/AudioOutput.h b/src/AudioOutput.h index dc157428..86e33adb 100644 --- a/src/AudioOutput.h +++ b/src/AudioOutput.h @@ -1,21 +1,21 @@ /* - AudioOutput - Base class of an audio output player - - Copyright (C) 2017 Earle F. Philhower, III + AudioOutput + Base class of an audio output player - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + Copyright (C) 2017 Earle F. Philhower, III - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOOUTPUT_H @@ -24,60 +24,87 @@ #include #include "AudioStatus.h" -class AudioOutput -{ - public: +class AudioOutput { +public: AudioOutput() { }; virtual ~AudioOutput() {}; - virtual bool SetRate(int hz) { hertz = hz; return true; } - virtual bool SetBitsPerSample(int bits) { bps = bits; return true; } - virtual bool SetChannels(int chan) { channels = chan; return true; } - virtual bool SetGain(float f) { if (f>4.0) f = 4.0; if (f<0.0) f=0.0; gainF2P6 = (uint8_t)(f*(1<<6)); return true; } - virtual bool begin() { return false; }; - typedef enum { LEFTCHANNEL=0, RIGHTCHANNEL=1 } SampleIndex; - virtual bool ConsumeSample(int16_t sample[2]) { (void)sample; return false; } - virtual uint16_t ConsumeSamples(int16_t *samples, uint16_t count) - { - for (uint16_t i=0; i 4.0f) { + f = 4.0f; + } else if (f < 0.0f) { + f = 0.0f; + } + gainF2P6 = (uint8_t)(f * (1 << 6)); + return true; + } + virtual bool begin() { + return false; + }; + typedef enum { LEFTCHANNEL = 0, RIGHTCHANNEL = 1 } SampleIndex; + virtual bool ConsumeSample(int16_t sample[2]) { + (void)sample; + return false; + } + virtual uint16_t ConsumeSamples(int16_t *samples, uint16_t count) { + for (uint16_t i = 0; i < count; i++) { + if (!ConsumeSample(samples)) { + return i; + } + samples += 2; + } + return count; + } + virtual bool stop() { + return false; + } + virtual void flush() { + return; + } + virtual bool loop() { + return true; } - virtual bool stop() { return false; } - virtual void flush() { return; } - virtual bool loop() { return true; } - public: - virtual bool RegisterMetadataCB(AudioStatus::metadataCBFn fn, void *data) { return cb.RegisterMetadataCB(fn, data); } - virtual bool RegisterStatusCB(AudioStatus::statusCBFn fn, void *data) { return cb.RegisterStatusCB(fn, data); } +public: + virtual bool RegisterMetadataCB(AudioStatus::metadataCBFn fn, void *data) { + return cb.RegisterMetadataCB(fn, data); + } + virtual bool RegisterStatusCB(AudioStatus::statusCBFn fn, void *data) { + return cb.RegisterStatusCB(fn, data); + } - protected: +protected: void MakeSampleStereo16(int16_t sample[2]) { - // Mono to "stereo" conversion - if (channels == 1) - sample[RIGHTCHANNEL] = sample[LEFTCHANNEL]; - if (bps == 8) { - // Upsample from unsigned 8 bits to signed 16 bits - sample[LEFTCHANNEL] = (((int16_t)(sample[LEFTCHANNEL]&0xff)) - 128) << 8; - sample[RIGHTCHANNEL] = (((int16_t)(sample[RIGHTCHANNEL]&0xff)) - 128) << 8; - } + // Mono to "stereo" conversion + if (channels == 1) { + sample[RIGHTCHANNEL] = sample[LEFTCHANNEL]; + } }; inline int16_t Amplify(int16_t s) { - int32_t v = (s * gainF2P6)>>6; - if (v < -32767) return -32767; - else if (v > 32767) return 32767; - else return (int16_t)(v&0xffff); + int32_t v = (s * gainF2P6) >> 6; + if (v < -32767) { + return -32767; + } else if (v > 32767) { + return 32767; + } else { + return (int16_t)(v & 0xffff); + } } - protected: +protected: uint16_t hertz; - uint8_t bps; uint8_t channels; uint8_t gainF2P6; // Fixed point 2.6 - protected: +protected: AudioStatus cb; }; diff --git a/src/AudioOutputBuffer.cpp b/src/AudioOutputBuffer.cpp index a22f72e5..5e153ce9 100644 --- a/src/AudioOutputBuffer.cpp +++ b/src/AudioOutputBuffer.cpp @@ -1,89 +1,79 @@ /* - AudioOutputBuffer - Adds additional bufferspace to the output chain - - Copyright (C) 2017 Earle F. Philhower, III + AudioOutputBuffer + Adds additional bufferspace to the output chain - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + Copyright (C) 2017 Earle F. Philhower, III - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include #include "AudioOutputBuffer.h" -AudioOutputBuffer::AudioOutputBuffer(int buffSizeSamples, AudioOutput *dest) -{ - buffSize = buffSizeSamples; - leftSample = (int16_t*)malloc(sizeof(int16_t) * buffSize); - rightSample = (int16_t*)malloc(sizeof(int16_t) * buffSize); - writePtr = 0; - readPtr = 0; - sink = dest; -} - -AudioOutputBuffer::~AudioOutputBuffer() -{ - free(leftSample); - free(rightSample); +AudioOutputBuffer::AudioOutputBuffer(int buffSizeSamples, AudioOutput *dest) { + buffSize = buffSizeSamples; + leftSample = (int16_t*)malloc(sizeof(int16_t) * buffSize); + rightSample = (int16_t*)malloc(sizeof(int16_t) * buffSize); + writePtr = 0; + readPtr = 0; + sink = dest; } -bool AudioOutputBuffer::SetRate(int hz) -{ - return sink->SetRate(hz); +AudioOutputBuffer::~AudioOutputBuffer() { + free(leftSample); + free(rightSample); } -bool AudioOutputBuffer::SetBitsPerSample(int bits) -{ - return sink->SetBitsPerSample(bits); +bool AudioOutputBuffer::SetRate(int hz) { + return sink->SetRate(hz); } -bool AudioOutputBuffer::SetChannels(int channels) -{ - return sink->SetChannels(channels); +bool AudioOutputBuffer::SetChannels(int channels) { + return sink->SetChannels(channels); } -bool AudioOutputBuffer::begin() -{ - filled = false; - return sink->begin(); +bool AudioOutputBuffer::begin() { + filled = false; + return sink->begin(); } -bool AudioOutputBuffer::ConsumeSample(int16_t sample[2]) -{ - // First, try and fill I2S... - if (filled) { - while (readPtr != writePtr) { - int16_t s[2] = {leftSample[readPtr], rightSample[readPtr]}; - if (!sink->ConsumeSample(s)) break; // Can't stuff any more in I2S... - readPtr = (readPtr + 1) % buffSize; +bool AudioOutputBuffer::ConsumeSample(int16_t sample[2]) { + // First, try and fill I2S... + if (filled) { + while (readPtr != writePtr) { + int16_t s[2] = {leftSample[readPtr], rightSample[readPtr]}; + if (!sink->ConsumeSample(s)) { + break; // Can't stuff any more in I2S... + } + readPtr = (readPtr + 1) % buffSize; + } } - } - // Now, do we have space for a new sample? - int nextWritePtr = (writePtr + 1) % buffSize; - if (nextWritePtr == readPtr) { - filled = true; - return false; - } - leftSample[writePtr] = sample[LEFTCHANNEL]; - rightSample[writePtr] = sample[RIGHTCHANNEL]; - writePtr = nextWritePtr; - return true; + // Now, do we have space for a new sample? + int nextWritePtr = (writePtr + 1) % buffSize; + if (nextWritePtr == readPtr) { + filled = true; + return false; + } + leftSample[writePtr] = sample[LEFTCHANNEL]; + rightSample[writePtr] = sample[RIGHTCHANNEL]; + writePtr = nextWritePtr; + return true; } -bool AudioOutputBuffer::stop() -{ - return sink->stop(); +bool AudioOutputBuffer::stop() { + return sink->stop(); } diff --git a/src/AudioOutputBuffer.h b/src/AudioOutputBuffer.h index 56c10a7c..ac4d4c55 100644 --- a/src/AudioOutputBuffer.h +++ b/src/AudioOutputBuffer.h @@ -1,21 +1,21 @@ /* - AudioOutputBuffer - Adds additional bufferspace to the output chain - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioOutputBuffer + Adds additional bufferspace to the output chain + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOOUTPUTBUFFER_H @@ -23,19 +23,17 @@ #include "AudioOutput.h" -class AudioOutputBuffer : public AudioOutput -{ - public: +class AudioOutputBuffer : public AudioOutput { +public: AudioOutputBuffer(int bufferSizeSamples, AudioOutput *dest); virtual ~AudioOutputBuffer() override; virtual bool SetRate(int hz) override; - virtual bool SetBitsPerSample(int bits) override; virtual bool SetChannels(int channels) override; virtual bool begin() override; virtual bool ConsumeSample(int16_t sample[2]) override; virtual bool stop() override; - - protected: + +protected: AudioOutput *sink; int buffSize; int16_t *leftSample; diff --git a/src/AudioOutputFilterBiquad.cpp b/src/AudioOutputFilterBiquad.cpp new file mode 100644 index 00000000..75396c07 --- /dev/null +++ b/src/AudioOutputFilterBiquad.cpp @@ -0,0 +1,224 @@ +/* + AudioOutputFilterBiquad + Implements a Biquad filter + + Copyright (C) 2012 Nigel Redmon + Copyright (C) 2021 William Bérubé + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include "AudioOutputFilterBiquad.h" + +AudioOutputFilterBiquad::AudioOutputFilterBiquad(AudioOutput *sink) { + this->sink = sink; + + type = bq_type_lowpass; + a0 = 1.0; + a1 = a2 = b1 = b2 = 0.0; + Fc = 0.50; + Q = 0.707; + peakGain = 0.0; + z1 = z2 = 0.0; +} + +AudioOutputFilterBiquad::AudioOutputFilterBiquad(int type, float Fc, float Q, float peakGain, AudioOutput *sink) { + this->sink = sink; + + SetBiquad(type, Fc, Q, peakGain); + z1 = z2 = 0.0; +} + +AudioOutputFilterBiquad::~AudioOutputFilterBiquad() {} + +bool AudioOutputFilterBiquad::SetRate(int hz) { + return sink->SetRate(hz); +} + +bool AudioOutputFilterBiquad::SetChannels(int channels) { + return sink->SetChannels(channels); +} + +bool AudioOutputFilterBiquad::SetGain(float gain) { + return sink->SetGain(gain); +} + +void AudioOutputFilterBiquad::SetType(int type) { + this->type = type; + CalcBiquad(); +} + +void AudioOutputFilterBiquad::SetFc(float Fc) { + this->Fc = Fc; + CalcBiquad(); +} + +void AudioOutputFilterBiquad::SetQ(float Q) { + this->Q = Q; + CalcBiquad(); +} + +void AudioOutputFilterBiquad::SetPeakGain(float peakGain) { + this->peakGain = peakGain; + CalcBiquad(); +} + +void AudioOutputFilterBiquad::SetBiquad(int type, float Fc, float Q, float peakGain) { + this->type = type; + this->Fc = Fc; + this->Q = Q; + this->peakGain = peakGain; + CalcBiquad(); +} + +void AudioOutputFilterBiquad::CalcBiquad() { + float norm; + float V = pow(10, fabs(peakGain) / 20.0); + float K = tan(M_PI * Fc); + + switch (this->type) { + case bq_type_lowpass: + norm = 1 / (1 + K / Q + K * K); + a0 = K * K * norm; + a1 = 2 * a0; + a2 = a0; + b1 = 2 * (K * K - 1) * norm; + b2 = (1 - K / Q + K * K) * norm; + break; + + case bq_type_highpass: + norm = 1 / (1 + K / Q + K * K); + a0 = 1 * norm; + a1 = -2 * a0; + a2 = a0; + b1 = 2 * (K * K - 1) * norm; + b2 = (1 - K / Q + K * K) * norm; + break; + + case bq_type_bandpass: + norm = 1 / (1 + K / Q + K * K); + a0 = K / Q * norm; + a1 = 0; + a2 = -a0; + b1 = 2 * (K * K - 1) * norm; + b2 = (1 - K / Q + K * K) * norm; + break; + + case bq_type_notch: + norm = 1 / (1 + K / Q + K * K); + a0 = (1 + K * K) * norm; + a1 = 2 * (K * K - 1) * norm; + a2 = a0; + b1 = a1; + b2 = (1 - K / Q + K * K) * norm; + break; + + case bq_type_peak: + if (peakGain >= 0) { // boost + norm = 1 / (1 + 1 / Q * K + K * K); + a0 = (1 + V / Q * K + K * K) * norm; + a1 = 2 * (K * K - 1) * norm; + a2 = (1 - V / Q * K + K * K) * norm; + b1 = a1; + b2 = (1 - 1 / Q * K + K * K) * norm; + } else { // cut + norm = 1 / (1 + V / Q * K + K * K); + a0 = (1 + 1 / Q * K + K * K) * norm; + a1 = 2 * (K * K - 1) * norm; + a2 = (1 - 1 / Q * K + K * K) * norm; + b1 = a1; + b2 = (1 - V / Q * K + K * K) * norm; + } + break; + + case bq_type_lowshelf: + if (peakGain >= 0) { // boost + norm = 1 / (1 + sqrt(2) * K + K * K); + a0 = (1 + sqrt(2 * V) * K + V * K * K) * norm; + a1 = 2 * (V * K * K - 1) * norm; + a2 = (1 - sqrt(2 * V) * K + V * K * K) * norm; + b1 = 2 * (K * K - 1) * norm; + b2 = (1 - sqrt(2) * K + K * K) * norm; + } else { // cut + norm = 1 / (1 + sqrt(2 * V) * K + V * K * K); + a0 = (1 + sqrt(2) * K + K * K) * norm; + a1 = 2 * (K * K - 1) * norm; + a2 = (1 - sqrt(2) * K + K * K) * norm; + b1 = 2 * (V * K * K - 1) * norm; + b2 = (1 - sqrt(2 * V) * K + V * K * K) * norm; + } + break; + + case bq_type_highshelf: + if (peakGain >= 0) { // boost + norm = 1 / (1 + sqrt(2) * K + K * K); + a0 = (V + sqrt(2 * V) * K + K * K) * norm; + a1 = 2 * (K * K - V) * norm; + a2 = (V - sqrt(2 * V) * K + K * K) * norm; + b1 = 2 * (K * K - 1) * norm; + b2 = (1 - sqrt(2) * K + K * K) * norm; + } else { // cut + norm = 1 / (V + sqrt(2 * V) * K + K * K); + a0 = (1 + sqrt(2) * K + K * K) * norm; + a1 = 2 * (K * K - 1) * norm; + a2 = (1 - sqrt(2) * K + K * K) * norm; + b1 = 2 * (K * K - V) * norm; + b2 = (V - sqrt(2 * V) * K + K * K) * norm; + } + break; + } + + i_a0 = a0 * BQ_DECAL; + i_a1 = a1 * BQ_DECAL; + i_a2 = a2 * BQ_DECAL; + + i_b1 = b1 * BQ_DECAL; + i_b2 = b2 * BQ_DECAL; + + i_lz1 = i_rz1 = z1 * BQ_DECAL; + i_lz2 = i_rz2 = z2 * BQ_DECAL; + + i_Fc = Fc * BQ_DECAL; + i_Q = Q * BQ_DECAL; + i_peakGain = peakGain * BQ_DECAL; +} + +bool AudioOutputFilterBiquad::begin() { + return sink->begin(); +} + +bool AudioOutputFilterBiquad::ConsumeSample(int16_t sample[2]) { + + int32_t leftSample = (sample[LEFTCHANNEL] << BQ_SHIFT) / 2; + int32_t rightSample = (sample[RIGHTCHANNEL] << BQ_SHIFT) / 2; + + int64_t leftOutput = ((leftSample * i_a0) >> BQ_SHIFT) + i_lz1; + i_lz1 = ((leftSample * i_a1) >> BQ_SHIFT) + i_lz2 - ((i_b1 * leftOutput) >> BQ_SHIFT); + i_lz2 = ((leftSample * i_a2) >> BQ_SHIFT) - ((i_b2 * leftOutput) >> BQ_SHIFT); + + int64_t rightOutput = ((rightSample * i_a0) >> BQ_SHIFT) + i_rz1; + i_rz1 = ((rightSample * i_a1) >> BQ_SHIFT) + i_rz2 - ((i_b1 * rightOutput) >> BQ_SHIFT); + i_rz2 = ((rightSample * i_a2) >> BQ_SHIFT) - ((i_b2 * rightOutput) >> BQ_SHIFT); + + int16_t out[2]; + out[LEFTCHANNEL] = (int16_t)(leftOutput >> BQ_SHIFT); + out[RIGHTCHANNEL] = (int16_t)(rightOutput >> BQ_SHIFT); + + return sink->ConsumeSample(out); +} + +bool AudioOutputFilterBiquad::stop() { + return sink->stop(); +} diff --git a/src/AudioOutputFilterBiquad.h b/src/AudioOutputFilterBiquad.h new file mode 100644 index 00000000..71880605 --- /dev/null +++ b/src/AudioOutputFilterBiquad.h @@ -0,0 +1,78 @@ +/* + AudioOutputFilterBiquad + Implements a Biquad filter + + Copyright (C) 2012 Nigel Redmon + Copyright (C) 2021 William Bérubé + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _AudioOutputFilterBiquad_H +#define _AudioOutputFilterBiquad_H + +#include "AudioOutput.h" + +#define BQ_SHIFT 16 +#define BQ_DECAL 65536 + +enum { + bq_type_lowpass = 0, + bq_type_highpass, + bq_type_bandpass, + bq_type_notch, + bq_type_peak, + bq_type_lowshelf, + bq_type_highshelf +}; + +class AudioOutputFilterBiquad : public AudioOutput { +public: + AudioOutputFilterBiquad(AudioOutput *sink); + AudioOutputFilterBiquad(int type, float Fc, float Q, float peakGain, AudioOutput *sink); + virtual ~AudioOutputFilterBiquad() override; + virtual bool SetRate(int hz) override; + virtual bool SetChannels(int chan) override; + virtual bool SetGain(float f) override; + virtual bool begin() override; + virtual bool ConsumeSample(int16_t sample[2]) override; + virtual bool stop() override; + +private: + void SetType(int type); + void SetFc(float Fc); + void SetQ(float Q); + void SetPeakGain(float peakGain); + void SetBiquad(int type, float Fc, float Q, float peakGain); + +protected: + AudioOutput *sink; + int buffSize; + int16_t *leftSample; + int16_t *rightSample; + int writePtr; + int readPtr; + bool filled; + int type; + void CalcBiquad(); + int64_t i_a0, i_a1, i_a2, i_b1, i_b2; + int64_t i_Fc, i_Q, i_peakGain; + int64_t i_lz1, i_lz2, i_rz1, i_rz2; + float a0, a1, a2, b1, b2; + float Fc, Q, peakGain; + float z1, z2; +}; + +#endif + diff --git a/src/AudioOutputFilterDecimate.cpp b/src/AudioOutputFilterDecimate.cpp index 7453e844..ee5831c6 100644 --- a/src/AudioOutputFilterDecimate.cpp +++ b/src/AudioOutputFilterDecimate.cpp @@ -1,112 +1,101 @@ /* - AudioOutputFilter - Implements a user-defined FIR on a passthrough + AudioOutputFilter + Implements a user-defined FIR on a passthrough - Copyright (C) 2017 Earle F. Philhower, III + Copyright (C) 2017 Earle F. Philhower, III - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include #include "AudioOutputFilterDecimate.h" -AudioOutputFilterDecimate::AudioOutputFilterDecimate(uint8_t taps, const int16_t *tap, int num, int den, AudioOutput *sink) -{ - this->sink = sink; - - // The filter state. Passed in TAPS must be available throughout object lifetime - this->taps = taps; - this->tap = (int16_t*)malloc(sizeof(int16_t) * taps); - memcpy_P(this->tap, tap, sizeof(int16_t) * taps); - this->hist[0] = (int16_t*)malloc(sizeof(int16_t) * taps); - memset(this->hist[0], 0, sizeof(int16_t) * taps); - this->hist[1] = (int16_t*)malloc(sizeof(int16_t) * taps); - memset(this->hist[1], 0, sizeof(int16_t) * taps); - this->idx = 0; - - // Decimator numerator and denominator with an error signal. Not great, but fast and simple - this->num = num; - this->den = den; - this->err = 0; +AudioOutputFilterDecimate::AudioOutputFilterDecimate(uint8_t taps, const int16_t *tap, int num, int den, AudioOutput *sink) { + this->sink = sink; + + // The filter state. Passed in TAPS must be available throughout object lifetime + this->taps = taps; + this->tap = (int16_t*)malloc(sizeof(int16_t) * taps); + memcpy_P(this->tap, tap, sizeof(int16_t) * taps); + this->hist[0] = (int16_t*)malloc(sizeof(int16_t) * taps); + memset(this->hist[0], 0, sizeof(int16_t) * taps); + this->hist[1] = (int16_t*)malloc(sizeof(int16_t) * taps); + memset(this->hist[1], 0, sizeof(int16_t) * taps); + this->idx = 0; + + // Decimator numerator and denominator with an error signal. Not great, but fast and simple + this->num = num; + this->den = den; + this->err = 0; } -AudioOutputFilterDecimate::~AudioOutputFilterDecimate() -{ - free(hist[1]); - free(hist[0]); - free(tap); +AudioOutputFilterDecimate::~AudioOutputFilterDecimate() { + free(hist[1]); + free(hist[0]); + free(tap); } -bool AudioOutputFilterDecimate::SetRate(int hz) -{ - // Modify input frequency to account for decimation - hz *= den; - hz /= num; - return sink->SetRate(hz); +bool AudioOutputFilterDecimate::SetRate(int hz) { + // Modify input frequency to account for decimation + hz *= den; + hz /= num; + return sink->SetRate(hz); } -bool AudioOutputFilterDecimate::SetBitsPerSample(int bits) -{ - return sink->SetBitsPerSample(bits); +bool AudioOutputFilterDecimate::SetChannels(int channels) { + return sink->SetChannels(channels); } -bool AudioOutputFilterDecimate::SetChannels(int channels) -{ - return sink->SetChannels(channels); +bool AudioOutputFilterDecimate::SetGain(float gain) { + return sink->SetGain(gain); } -bool AudioOutputFilterDecimate::SetGain(float gain) -{ - return sink->SetGain(gain); +bool AudioOutputFilterDecimate::begin() { + return sink->begin(); } -bool AudioOutputFilterDecimate::begin() -{ - return sink->begin(); +bool AudioOutputFilterDecimate::ConsumeSample(int16_t sample[2]) { + // Store the data samples in history always + hist[LEFTCHANNEL][idx] = sample[LEFTCHANNEL]; + hist[RIGHTCHANNEL][idx] = sample[RIGHTCHANNEL]; + idx++; + if (idx == taps) { + idx = 0; + } + + // Only output if the error signal says we're ready to decimate. This simplistic way might give some aliasing noise + err += num; + if (err >= den) { + err -= den; + // Need to output a sample, so actually calculate the filter at this point in time + // Smarter might actually shift the history by the fractional remainder or take two filters and interpolate + int32_t accL = 0; + int32_t accR = 0; + int index = idx; + for (size_t i = 0; i < taps; i++) { + index = index != 0 ? index - 1 : taps - 1; + accL += (int32_t)hist[LEFTCHANNEL][index] * tap[i]; + accR += (int32_t)hist[RIGHTCHANNEL][index] * tap[i]; + }; + int16_t out[2]; + out[LEFTCHANNEL] = accL >> 16; + out[RIGHTCHANNEL] = accR >> 16; + return sink->ConsumeSample(out); + } + return true; // Nothing to do here... } -bool AudioOutputFilterDecimate::ConsumeSample(int16_t sample[2]) -{ - // Store the data samples in history always - hist[LEFTCHANNEL][idx] = sample[LEFTCHANNEL]; - hist[RIGHTCHANNEL][idx] = sample[RIGHTCHANNEL]; - idx++; - if (idx == taps) idx = 0; - - // Only output if the error signal says we're ready to decimate. This simplistic way might give some aliasing noise - err += num; - if (err >= den) { - err -= den; - // Need to output a sample, so actually calculate the filter at this point in time - // Smarter might actually shift the history by the fractional remainder or take two filters and interpolate - int32_t accL = 0; - int32_t accR = 0; - int index = idx; - for (size_t i=0; i < taps; i++) { - index = index != 0 ? index-1 : taps-1; - accL += (int32_t)hist[LEFTCHANNEL][index] * tap[i]; - accR += (int32_t)hist[RIGHTCHANNEL][index] * tap[i]; - }; - int16_t out[2]; - out[LEFTCHANNEL] = accL >> 16; - out[RIGHTCHANNEL] = accR >> 16; - return sink->ConsumeSample(out); - } - return true; // Nothing to do here... -} - -bool AudioOutputFilterDecimate::stop() -{ - return sink->stop(); +bool AudioOutputFilterDecimate::stop() { + return sink->stop(); } diff --git a/src/AudioOutputFilterDecimate.h b/src/AudioOutputFilterDecimate.h index eee59908..fff1d482 100644 --- a/src/AudioOutputFilterDecimate.h +++ b/src/AudioOutputFilterDecimate.h @@ -1,21 +1,21 @@ /* - AudioOutputFilterDecimate - Implements a user-defined FIR on a passthrough w/rational decimation - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioOutputFilterDecimate + Implements a user-defined FIR on a passthrough w/rational decimation + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOOUTPUTFILTERDECIMATE_H @@ -23,20 +23,18 @@ #include "AudioOutput.h" -class AudioOutputFilterDecimate : public AudioOutput -{ - public: +class AudioOutputFilterDecimate : public AudioOutput { +public: AudioOutputFilterDecimate(uint8_t taps, const int16_t *tap, int num, int den, AudioOutput *sink); virtual ~AudioOutputFilterDecimate() override; virtual bool SetRate(int hz) override; - virtual bool SetBitsPerSample(int bits) override; virtual bool SetChannels(int chan) override; virtual bool SetGain(float f) override; virtual bool begin() override; virtual bool ConsumeSample(int16_t sample[2]) override; virtual bool stop() override; - protected: +protected: AudioOutput *sink; uint8_t taps; int16_t *tap; diff --git a/src/AudioOutputI2S.cpp b/src/AudioOutputI2S.cpp index f7e194ea..80e98cef 100644 --- a/src/AudioOutputI2S.cpp +++ b/src/AudioOutputI2S.cpp @@ -1,223 +1,378 @@ /* - AudioOutputI2S - Base class for I2S interface port - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioOutputI2S + Base class for I2S interface port + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include #ifdef ESP32 - #include "driver/i2s.h" -#else - #include +#include "driver/i2s.h" +#elif defined(ARDUINO_ARCH_RP2040) || ARDUINO_ESP8266_MAJOR >= 3 +#include +#elif ARDUINO_ESP8266_MAJOR < 3 +#include #endif #include "AudioOutputI2S.h" -AudioOutputI2S::AudioOutputI2S(int port, int output_mode, int dma_buf_count, int use_apll) -{ - this->portNo = port; - this->i2sOn = false; - this->dma_buf_count = dma_buf_count; - if (output_mode != EXTERNAL_I2S && output_mode != INTERNAL_DAC && output_mode != INTERNAL_PDM) { - output_mode = EXTERNAL_I2S; - } - this->output_mode = output_mode; -#ifdef ESP32 - if (!i2sOn) { - if (use_apll == APLL_AUTO) { - // don't use audio pll on buggy rev0 chips - use_apll = APLL_DISABLE; - esp_chip_info_t out_info; - esp_chip_info(&out_info); - if(out_info.revision > 0) { - use_apll = APLL_ENABLE; - } - } - - i2s_mode_t mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX); - if (output_mode == INTERNAL_DAC) { - mode = (i2s_mode_t)(mode | I2S_MODE_DAC_BUILT_IN); - } else if (output_mode == INTERNAL_PDM) { - mode = (i2s_mode_t)(mode | I2S_MODE_PDM); +#if defined(ESP32) || defined(ESP8266) +AudioOutputI2S::AudioOutputI2S(int port, int output_mode, int dma_buf_count, int use_apll) { + this->portNo = port; + this->i2sOn = false; + this->dma_buf_count = dma_buf_count; + if (output_mode != EXTERNAL_I2S && output_mode != INTERNAL_DAC && output_mode != INTERNAL_PDM) { + output_mode = EXTERNAL_I2S; } + this->output_mode = output_mode; + this->use_apll = use_apll; - i2s_comm_format_t comm_fmt = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB); - if (output_mode == INTERNAL_DAC) { - comm_fmt = (i2s_comm_format_t)I2S_COMM_FORMAT_I2S_MSB; - } - - i2s_config_t i2s_config_dac = { - .mode = mode, - .sample_rate = 44100, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = comm_fmt, - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // lowest interrupt priority - .dma_buf_count = dma_buf_count, - .dma_buf_len = 64, - .use_apll = use_apll // Use audio PLL - }; - audioLogger->printf("+%d %p\n", portNo, &i2s_config_dac); - if (i2s_driver_install((i2s_port_t)portNo, &i2s_config_dac, 0, NULL) != ESP_OK) { - audioLogger->println("ERROR: Unable to install I2S drives\n"); - } + //set defaults + mono = false; + lsb_justified = false; + channels = 2; + hertz = 0; // Needs to be application-set + bclkPin = 26; + wclkPin = 25; + doutPin = 22; + mclkPin = 0; + use_mclk = false; + SetGain(1.0); +} + +#elif defined(ARDUINO_ARCH_RP2040) +AudioOutputI2S::AudioOutputI2S(long sampleRate, pin_size_t sck, pin_size_t data) { + i2sOn = false; + mono = false; + channels = 2; + hertz = sampleRate; + bclkPin = sck; + doutPin = data; + mclkPin = 0; + use_mclk = false; + swap_clocks = false; + SetGain(1.0); +} +#endif + +AudioOutputI2S::~AudioOutputI2S() { + stop(); +} + +bool AudioOutputI2S::SetPinout() { +#ifdef ESP32 if (output_mode == INTERNAL_DAC || output_mode == INTERNAL_PDM) { - i2s_set_pin((i2s_port_t)portNo, NULL); - i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); - } else { - SetPinout(26, 25, 22); + return false; // Not allowed } - i2s_zero_dma_buffer((i2s_port_t)portNo); - } -#else - (void) dma_buf_count; - (void) use_apll; - if (!i2sOn) { - orig_bck = READ_PERI_REG(PERIPHS_IO_MUX_MTDO_U); - orig_ws = READ_PERI_REG(PERIPHS_IO_MUX_GPIO2_U); - i2s_begin(); - } -#endif - i2sOn = true; - mono = false; - bps = 16; - channels = 2; - SetGain(1.0); - SetRate(44100); // Default -} - -AudioOutputI2S::~AudioOutputI2S() -{ -#ifdef ESP32 - if (i2sOn) { - audioLogger->printf("UNINSTALL I2S\n"); - i2s_driver_uninstall((i2s_port_t)portNo); //stop & destroy i2s driver - } + + i2s_pin_config_t pins = { +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) + .mck_io_num = use_mclk ? mclkPin : I2S_PIN_NO_CHANGE, +#endif + .bck_io_num = bclkPin, + .ws_io_num = wclkPin, + .data_out_num = doutPin, + .data_in_num = I2S_PIN_NO_CHANGE + }; + i2s_set_pin((i2s_port_t)portNo, &pins); + return true; #else - if (i2sOn) i2s_end(); + return false; #endif - i2sOn = false; } -bool AudioOutputI2S::SetPinout(int bclk, int wclk, int dout) -{ -#ifdef ESP32 - if (output_mode == INTERNAL_DAC || output_mode == INTERNAL_PDM) return false; // Not allowed - - i2s_pin_config_t pins = { - .bck_io_num = bclk, - .ws_io_num = wclk, - .data_out_num = dout, - .data_in_num = I2S_PIN_NO_CHANGE - }; - i2s_set_pin((i2s_port_t)portNo, &pins); - return true; +bool AudioOutputI2S::SetPinout(int bclk, int wclk, int dout) { + bclkPin = bclk; + wclkPin = wclk; + doutPin = dout; + use_mclk = false; + if (i2sOn) { + return SetPinout(); + } + + return true; +} + +bool AudioOutputI2S::SetPinout(int bclk, int wclk, int dout, int mclk) { + bclkPin = bclk; + wclkPin = wclk; + doutPin = dout; +#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) + mclkPin = mclk; + use_mclk = true; + if (i2sOn) { + return SetPinout(); + } #else - (void) bclk; - (void) wclk; - (void) dout; - return false; + (void)mclk; #endif + return true; } -bool AudioOutputI2S::SetRate(int hz) -{ - // TODO - have a list of allowable rates from constructor, check them - this->hertz = hz; +bool AudioOutputI2S::SetRate(int hz) { + if (this->hertz == hz) { + return true; + } + this->hertz = hz; + if (i2sOn) { #ifdef ESP32 - i2s_set_sample_rates((i2s_port_t)portNo, AdjustI2SRate(hz)); -#else - i2s_set_rate(AdjustI2SRate(hz)); + i2s_set_sample_rates((i2s_port_t)portNo, AdjustI2SRate(hz)); +#elif defined(ESP8266) + i2s_set_rate(AdjustI2SRate(hz)); +#elif defined(ARDUINO_ARCH_RP2040) + i2s.setFrequency(hz); #endif - return true; + } + return true; } -bool AudioOutputI2S::SetBitsPerSample(int bits) -{ - if ( (bits != 16) && (bits != 8) ) return false; - this->bps = bits; - return true; +bool AudioOutputI2S::SetChannels(int channels) { + if ((channels < 1) || (channels > 2)) { + return false; + } + this->channels = channels; + return true; } -bool AudioOutputI2S::SetChannels(int channels) -{ - if ( (channels < 1) || (channels > 2) ) return false; - this->channels = channels; - return true; +bool AudioOutputI2S::SetOutputModeMono(bool mono) { + this->mono = mono; + return true; } -bool AudioOutputI2S::SetOutputModeMono(bool mono) -{ - this->mono = mono; - return true; +bool AudioOutputI2S::SetLsbJustified(bool lsbJustified) { + this->lsb_justified = lsbJustified; + return true; } -bool AudioOutputI2S::begin() -{ - return true; +bool AudioOutputI2S::SwapClocks(bool swap_clocks) { + if (i2sOn) { + return false; // Not allowed + } + this->swap_clocks = swap_clocks; + return true; } -bool AudioOutputI2S::ConsumeSample(int16_t sample[2]) -{ - int16_t ms[2]; +bool AudioOutputI2S::SetMclk(bool enabled) { + (void)enabled; +#ifdef ESP32 + if (output_mode == INTERNAL_DAC || output_mode == INTERNAL_PDM) { + return false; // Not allowed + } - ms[0] = sample[0]; - ms[1] = sample[1]; - MakeSampleStereo16( ms ); + use_mclk = enabled; +#elif defined(ARDUINO_ARCH_RP2040) + use_mclk = enabled; +#endif + return true; +} - if (this->mono) { - // Average the two samples and overwrite - int32_t ttl = ms[LEFTCHANNEL] + ms[RIGHTCHANNEL]; - ms[LEFTCHANNEL] = ms[RIGHTCHANNEL] = (ttl>>1) & 0xffff; - } +bool AudioOutputI2S::begin(bool txDAC) { #ifdef ESP32 - uint32_t s32; - if (output_mode == INTERNAL_DAC) { - int16_t l = Amplify(ms[LEFTCHANNEL]) + 0x8000; - int16_t r = Amplify(ms[RIGHTCHANNEL]) + 0x8000; - s32 = (r<<16) | (l&0xffff); - } else { - s32 = ((Amplify(ms[RIGHTCHANNEL]))<<16) | (Amplify(ms[LEFTCHANNEL]) & 0xffff); - } - return i2s_write_bytes((i2s_port_t)portNo, (const char*)&s32, sizeof(uint32_t), 0); + if (!i2sOn) { + if (use_apll == APLL_AUTO) { + // don't use audio pll on buggy rev0 chips + use_apll = APLL_DISABLE; + //esp_chip_info_t out_info; + //esp_chip_info(&out_info); + //if (out_info.revision > 0) + { + use_apll = APLL_ENABLE; + } + } + + i2s_mode_t mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX); + if (output_mode == INTERNAL_DAC) { +#if CONFIG_IDF_TARGET_ESP32 + mode = (i2s_mode_t)(mode | I2S_MODE_DAC_BUILT_IN); #else - uint32_t s32 = ((Amplify(ms[RIGHTCHANNEL]))<<16) | (Amplify(ms[LEFTCHANNEL]) & 0xffff); - return i2s_write_sample_nb(s32); // If we can't store it, return false. OTW true + return false; #endif + } else if (output_mode == INTERNAL_PDM) { +#if CONFIG_IDF_TARGET_ESP32 + mode = (i2s_mode_t)(mode | I2S_MODE_PDM); +#else + return false; +#endif + } + + i2s_comm_format_t comm_fmt; + if (output_mode == INTERNAL_DAC) { +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) + comm_fmt = (i2s_comm_format_t) I2S_COMM_FORMAT_STAND_MSB; +#else + comm_fmt = (i2s_comm_format_t) I2S_COMM_FORMAT_I2S_MSB; +#endif + } else if (lsb_justified) { +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) + comm_fmt = (i2s_comm_format_t) I2S_COMM_FORMAT_STAND_MSB; +#else + comm_fmt = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB); +#endif + } else { +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) + comm_fmt = (i2s_comm_format_t)(I2S_COMM_FORMAT_STAND_I2S); +#else + comm_fmt = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB); +#endif + } + + i2s_config_t i2s_config_dac = { + .mode = mode, + .sample_rate = 44100, + .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, + .communication_format = comm_fmt, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // lowest interrupt priority + .dma_buf_count = dma_buf_count, + .dma_buf_len = 128, + .use_apll = use_apll, // Use audio PLL + .tx_desc_auto_clear = true, // Silence on underflow + .fixed_mclk = use_mclk, // Unused +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) + .mclk_multiple = I2S_MCLK_MULTIPLE_256, // Unused + .bits_per_chan = I2S_BITS_PER_CHAN_DEFAULT // Use bits per sample +#endif + }; + audioLogger->printf("+%d %p\n", portNo, &i2s_config_dac); + if (i2s_driver_install((i2s_port_t)portNo, &i2s_config_dac, 0, NULL) != ESP_OK) { + audioLogger->println("ERROR: Unable to install I2S drives\n"); + } + if (output_mode == INTERNAL_DAC || output_mode == INTERNAL_PDM) { +#if CONFIG_IDF_TARGET_ESP32 + i2s_set_pin((i2s_port_t)portNo, NULL); + i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); +#else + return false; +#endif + } else { + SetPinout(); + } + i2s_zero_dma_buffer((i2s_port_t)portNo); + } +#elif defined(ESP8266) + (void)dma_buf_count; + (void)use_apll; + if (!i2sOn) { + orig_bck = READ_PERI_REG(PERIPHS_IO_MUX_MTDO_U); + orig_ws = READ_PERI_REG(PERIPHS_IO_MUX_GPIO2_U); +#ifdef I2S_HAS_BEGIN_RXTX_DRIVE_CLOCKS + if (!i2s_rxtxdrive_begin(false, true, false, txDAC)) { + return false; + } +#else + if (!i2s_rxtx_begin(false, true)) { + return false; + } + if (!txDAC) { + audioLogger->printf_P(PSTR("I2SNoDAC: esp8266 arduino core should be upgraded to avoid conflicts with SPI\n")); + } +#endif + } +#elif defined(ARDUINO_ARCH_RP2040) + (void)txDAC; + if (!i2sOn) { + i2s.setSysClk(hertz); + i2s.setBCLK(bclkPin); + i2s.setDATA(doutPin); + if (use_mclk) { + i2s.setMCLK(mclkPin); + i2s.setMCLKmult(256); + } + if (swap_clocks) { + i2s.swapClocks(); + } + i2s.setBitsPerSample(16); + i2s.begin(hertz); + } +#endif + i2sOn = true; + SetRate(hertz ? hertz : 44100); // Default + return true; } -void AudioOutputI2S::flush() { +bool AudioOutputI2S::ConsumeSample(int16_t sample[2]) { + + //return if we haven't called ::begin yet + if (!i2sOn) { + return false; + } + + int16_t ms[2]; + + ms[0] = sample[0]; + ms[1] = sample[1]; + MakeSampleStereo16(ms); + + if (this->mono) { + // Average the two samples and overwrite + int32_t ttl = ms[LEFTCHANNEL] + ms[RIGHTCHANNEL]; + ms[LEFTCHANNEL] = ms[RIGHTCHANNEL] = (ttl >> 1) & 0xffff; + } #ifdef ESP32 - // makes sure that all stored DMA samples are consumed / played - int buffersize = 64 * this->dma_buf_count; - int16_t samples[2] = {0x0,0x0}; - for (int i=0;idma_buf_count; + int16_t samples[2] = {0x0, 0x0}; + for (int i = 0; i < buffersize; i++) { + while (!ConsumeSample(samples)) { + delay(10); + } + } +#elif defined(ARDUINO_ARCH_RP2040) + i2s.flush(); #endif - return true; } +bool AudioOutputI2S::stop() { + if (!i2sOn) { + return false; + } +#ifdef ESP32 + i2s_zero_dma_buffer((i2s_port_t)portNo); + audioLogger->printf("UNINSTALL I2S\n"); + i2s_driver_uninstall((i2s_port_t)portNo); //stop & destroy i2s driver +#elif defined(ESP8266) + i2s_end(); +#elif defined(ARDUINO_ARCH_RP2040) + i2s.end(); +#endif + i2sOn = false; + return true; +} diff --git a/src/AudioOutputI2S.h b/src/AudioOutputI2S.h index 6070ca4e..f1ba7b37 100644 --- a/src/AudioOutputI2S.h +++ b/src/AudioOutputI2S.h @@ -1,58 +1,83 @@ /* - AudioOutputI2S - Base class for an I2S output port - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioOutputI2S + Base class for an I2S output port + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ -#ifndef _AUDIOOUTPUTI2S_H -#define _AUDIOOUTPUTI2S_H +#pragma once #include "AudioOutput.h" -class AudioOutputI2S : public AudioOutput -{ - public: - AudioOutputI2S(int port=0, int output_mode=EXTERNAL_I2S, int dma_buf_count = 8, int use_apll=APLL_DISABLE); - virtual ~AudioOutputI2S() override; +#if defined(ARDUINO_ARCH_RP2040) +#include +#include +#endif + +class AudioOutputI2S : public AudioOutput { +public: +#if defined(ESP32) || defined(ESP8266) + AudioOutputI2S(int port = 0, int output_mode = EXTERNAL_I2S, int dma_buf_count = 8, int use_apll = APLL_DISABLE); + enum : int { APLL_AUTO = -1, APLL_ENABLE = 1, APLL_DISABLE = 0 }; + enum : int { EXTERNAL_I2S = 0, INTERNAL_DAC = 1, INTERNAL_PDM = 2 }; +#elif defined(ARDUINO_ARCH_RP2040) + AudioOutputI2S(long sampleRate = 44100, pin_size_t sck = 26, pin_size_t data = 28); +#endif bool SetPinout(int bclkPin, int wclkPin, int doutPin); + bool SetPinout(int bclkPin, int wclkPin, int doutPin, int mclkPin); + virtual ~AudioOutputI2S() override; virtual bool SetRate(int hz) override; - virtual bool SetBitsPerSample(int bits) override; virtual bool SetChannels(int channels) override; - virtual bool begin() override; + virtual bool begin() override { + return begin(true); + } virtual bool ConsumeSample(int16_t sample[2]) override; virtual void flush() override; virtual bool stop() override; - - bool SetOutputModeMono(bool mono); // Force mono output no matter the input - enum : int { APLL_AUTO = -1, APLL_ENABLE = 1, APLL_DISABLE = 0 }; - enum : int { EXTERNAL_I2S = 0, INTERNAL_DAC = 1, INTERNAL_PDM = 2 }; + bool begin(bool txDAC); + bool SetOutputModeMono(bool mono); // Force mono output no matter the input + bool SetLsbJustified(bool lsbJustified); // Allow supporting non-I2S chips, e.g. PT8211 + bool SetMclk(bool enabled); // Enable MCLK output (if supported) + bool SwapClocks(bool swap_clocks); // Swap BCLK and WCLK - protected: - virtual int AdjustI2SRate(int hz) { return hz; } +protected: + bool SetPinout(); + virtual int AdjustI2SRate(int hz) { + return hz; + } uint8_t portNo; int output_mode; bool mono; + int lsb_justified; bool i2sOn; int dma_buf_count; + int use_apll; + bool use_mclk; + bool swap_clocks; // We can restore the old values and free up these pins when in NoDAC mode uint32_t orig_bck; uint32_t orig_ws; -}; -#endif + uint8_t bclkPin; + uint8_t wclkPin; + uint8_t doutPin; + uint8_t mclkPin; +#if defined(ARDUINO_ARCH_RP2040) + I2S i2s; +#endif +}; diff --git a/src/AudioOutputI2SNoDAC.cpp b/src/AudioOutputI2SNoDAC.cpp index cb36e13e..8a3efc3a 100644 --- a/src/AudioOutputI2SNoDAC.cpp +++ b/src/AudioOutputI2SNoDAC.cpp @@ -1,108 +1,143 @@ /* - AudioOutputI2SNoDAC - Audio player using SW delta-sigma to generate "analog" on I2S data - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioOutputI2SNoDAC + Audio player using SW delta-sigma to generate "analog" on I2S data + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include #ifdef ESP32 - #include "driver/i2s.h" -#else - #include +#include "driver/i2s.h" +#elif defined(ARDUINO_ARCH_RP2040) || ARDUINO_ESP8266_MAJOR >= 3 +#include +#elif ARDUINO_ESP8266_MAJOR < 3 +#include #endif #include "AudioOutputI2SNoDAC.h" -AudioOutputI2SNoDAC::AudioOutputI2SNoDAC(int port) : AudioOutputI2S(port, false) -{ - SetOversampling(32); - lastSamp = 0; - cumErr = 0; -#ifndef ESP32 - WRITE_PERI_REG(PERIPHS_IO_MUX_MTDO_U, orig_bck); - WRITE_PERI_REG(PERIPHS_IO_MUX_GPIO2_U, orig_ws); +#if defined(ARDUINO_ARCH_RP2040) +// +// Create an alternate constructor for the RP2040. The AudioOutputI2S has an alternate +// constructor for the RP2040, so the code was passing port to the sampleRate and false to sck. +// +// AudioOutputI2S(long sampleRate = 44100, pin_size_t sck = 26, pin_size_t data = 28); +// +// So this new constructor adds the ability to pass both port and sck to the underlying class, but +// uses the same defaults in the AudioOutputI2S constructor. +// +AudioOutputI2SNoDAC::AudioOutputI2SNoDAC(int port, int sck) : AudioOutputI2S(44100, sck, port) { + SetOversampling(32); + lastSamp = 0; + cumErr = 0; +} + +#else + +AudioOutputI2SNoDAC::AudioOutputI2SNoDAC(int port) : AudioOutputI2S(port, false) { + SetOversampling(32); + lastSamp = 0; + cumErr = 0; +#ifdef ESP8266 + WRITE_PERI_REG(PERIPHS_IO_MUX_MTDO_U, orig_bck); + WRITE_PERI_REG(PERIPHS_IO_MUX_GPIO2_U, orig_ws); #endif + } +#endif + -AudioOutputI2SNoDAC::~AudioOutputI2SNoDAC() -{ +AudioOutputI2SNoDAC::~AudioOutputI2SNoDAC() { } bool AudioOutputI2SNoDAC::SetOversampling(int os) { - if (os % 32) return false; // Only Nx32 oversampling supported - if (os > 256) return false; // Don't be silly now! - if (os < 32) return false; // Nothing under 32 allowed + if (os % 32) { + return false; // Only Nx32 oversampling supported + } + if (os > 256) { + return false; // Don't be silly now! + } + if (os < 32) { + return false; // Nothing under 32 allowed + } - oversample = os; - return SetRate(hertz); + oversample = os; + return SetRate(hertz); } -void AudioOutputI2SNoDAC::DeltaSigma(int16_t sample[2], uint32_t dsBuff[8]) -{ - // Not shift 8 because addition takes care of one mult x 2 - int32_t sum = (((int32_t)sample[0]) + ((int32_t)sample[1])) >> 1; - fixed24p8_t newSamp = ( (int32_t)Amplify(sum) ) << 8; - - int oversample32 = oversample / 32; - // How much the comparison signal changes each oversample step - fixed24p8_t diffPerStep = (newSamp - lastSamp) >> (4 + oversample32); - - // Don't need lastSamp anymore, store this one for next round - lastSamp = newSamp; - - for (int j = 0; j < oversample32; j++) { - uint32_t bits = 0; // The bits we convert the sample into, MSB to go on the wire first - - for (int i = 32; i > 0; i--) { - bits = bits << 1; - if (cumErr < 0) { - bits |= 1; - cumErr += fixedPosValue - newSamp; - } else { - // Bits[0] = 0 handled already by left shift - cumErr -= fixedPosValue + newSamp; - } - newSamp += diffPerStep; // Move the reference signal towards destination +void AudioOutputI2SNoDAC::DeltaSigma(int16_t sample[2], uint32_t dsBuff[8]) { + // Not shift 8 because addition takes care of one mult x 2 + int32_t sum = (((int32_t)sample[0]) + ((int32_t)sample[1])) >> 1; + fixed24p8_t newSamp = ((int32_t)Amplify(sum)) << 8; + + int oversample32 = oversample / 32; + // How much the comparison signal changes each oversample step + fixed24p8_t diffPerStep = (newSamp - lastSamp) >> (4 + oversample32); + + // Don't need lastSamp anymore, store this one for next round + lastSamp = newSamp; + + for (int j = 0; j < oversample32; j++) { + uint32_t bits = 0; // The bits we convert the sample into, MSB to go on the wire first + + for (int i = 32; i > 0; i--) { + bits = bits << 1; + if (cumErr < 0) { + bits |= 1; + cumErr += fixedPosValue - newSamp; + } else { + // Bits[0] = 0 handled already by left shift + cumErr -= fixedPosValue + newSamp; + } + newSamp += diffPerStep; // Move the reference signal towards destination + } + dsBuff[j] = bits; } - dsBuff[j] = bits; - } } -bool AudioOutputI2SNoDAC::ConsumeSample(int16_t sample[2]) -{ - int16_t ms[2]; - ms[0] = sample[0]; - ms[1] = sample[1]; - MakeSampleStereo16( ms ); +bool AudioOutputI2SNoDAC::ConsumeSample(int16_t sample[2]) { + int16_t ms[2]; + ms[0] = sample[0]; + ms[1] = sample[1]; + MakeSampleStereo16(ms); - // Make delta-sigma filled buffer - uint32_t dsBuff[8]; - DeltaSigma(ms, dsBuff); + // Make delta-sigma filled buffer + uint32_t dsBuff[8]; + DeltaSigma(ms, dsBuff); - // Either send complete pulse stream or nothing + // Either send complete pulse stream or nothing #ifdef ESP32 - if (!i2s_write_bytes((i2s_port_t)portNo, (const char *)dsBuff, sizeof(uint32_t) * (oversample/32), 0)) - return false; -#else - if (!i2s_write_sample_nb(dsBuff[0])) return false; // No room at the inn - // At this point we've sent in first of possibly 8 32-bits, need to send - // remaining ones even if they block. - for (int i = 32; i < oversample; i+=32) - i2s_write_sample( dsBuff[i / 32]); + size_t i2s_bytes_written; + i2s_write((i2s_port_t)portNo, (const char *)dsBuff, sizeof(uint32_t) * (oversample / 32), &i2s_bytes_written, 0); + if (!i2s_bytes_written) { + return false; + } +#elif defined(ESP8266) + if (!i2s_write_sample_nb(dsBuff[0])) { + return false; // No room at the inn + } + // At this point we've sent in first of possibly 8 32-bits, need to send + // remaining ones even if they block. + for (int i = 32; i < oversample; i += 32) { + i2s_write_sample(dsBuff[i / 32]); + } +#elif defined(ARDUINO_ARCH_RP2040) + for (int i = 0; i < oversample / 32; i++) { + i2s.write((int32_t)dsBuff[i], true); + } #endif - return true; + return true; } diff --git a/src/AudioOutputI2SNoDAC.h b/src/AudioOutputI2SNoDAC.h index b5f32145..7d1af34c 100644 --- a/src/AudioOutputI2SNoDAC.h +++ b/src/AudioOutputI2SNoDAC.h @@ -1,46 +1,55 @@ /* - AudioOutputI2SNoDAC - Audio player using SW delta-sigma to generate "analog" on I2S data - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioOutputI2SNoDAC + Audio player using SW delta-sigma to generate "analog" on I2S data + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ -#ifndef _AUDIOOUTPUTI2SNODAC_H -#define _AUDIOOUTPUTI2SNODAC_H +#pragma once #include "AudioOutputI2S.h" -class AudioOutputI2SNoDAC : public AudioOutputI2S -{ - public: +class AudioOutputI2SNoDAC : public AudioOutputI2S { +public: + // + // Define a different constructor for the RP2040, as this class calls the constructor + // of the AudioOutputI2S which has an alternate constructor for the RP2040 + // +#if defined(ARDUINO_ARCH_RP2040) + AudioOutputI2SNoDAC(int port = 28, int sck = 26); +#else AudioOutputI2SNoDAC(int port = 0); +#endif + virtual ~AudioOutputI2SNoDAC() override; + virtual bool begin() override { + return AudioOutputI2S::begin(false); + } virtual bool ConsumeSample(int16_t sample[2]) override; - + bool SetOversampling(int os); - - protected: - virtual int AdjustI2SRate(int hz) override { return hz * oversample/32; } - uint8_t oversample; + +protected: + virtual int AdjustI2SRate(int hz) override { + return hz * oversample / 32; + } + int oversample; void DeltaSigma(int16_t sample[2], uint32_t dsBuff[4]); typedef int32_t fixed24p8_t; - enum {fixedPosValue=0x007fff00}; /* 24.8 of max-signed-int */ + enum {fixedPosValue = 0x007fff00}; /* 24.8 of max-signed-int */ fixed24p8_t lastSamp; // Last sample value fixed24p8_t cumErr; // Running cumulative error since time began }; - -#endif - diff --git a/src/AudioOutputInternalDAC.h b/src/AudioOutputInternalDAC.h new file mode 100644 index 00000000..fcb31aa1 --- /dev/null +++ b/src/AudioOutputInternalDAC.h @@ -0,0 +1,151 @@ +#include "AudioOutput.h" +#include + +class AudioOutputInternalDAC : public AudioOutput { + const int buffer_sz; + std::vector buffer; + dac_continuous_handle_t dac_handle = nullptr; + + void dac_init() { + ESP_LOGI("dac_init", "bps=%d, ch=%d, freq=%d", 16, channels, hertz); + + if (dac_handle) { + dac_continuous_disable(dac_handle); + dac_continuous_del_channels(dac_handle); + } + + dac_continuous_config_t dac_config = { + .chan_mask = channels == 2 ? DAC_CHANNEL_MASK_ALL : DAC_CHANNEL_MASK_CH0, + .desc_num = 2, // we dont need more + .buf_size = buffer_sz, + .freq_hz = hertz, + .offset = 0, + .clk_src = DAC_DIGI_CLK_SRC_APLL, + .chan_mode = channels == 2 ? DAC_CHANNEL_MODE_ALTER : DAC_CHANNEL_MODE_SIMUL, + }; + + dac_continuous_new_channels(&dac_config, &dac_handle); + dac_continuous_enable(dac_handle); + } + + void dac_deinit() { + if (dac_handle) { + dac_continuous_disable(dac_handle); + dac_continuous_del_channels(dac_handle); + dac_handle = nullptr; + } + + // prevent frying of your audio amplifier + // dac pins like to go high after deinit + +#if defined(CONFIG_IDF_TARGET_ESP32) + int dac_1_gpio = 25, dac_2_gpio = 26; +#elif defined(CONFIG_IDF_TARGET_ESP32S2) + int dac_1_gpio = 17, dac_2_gpio = 18; +#else + static_assert(0, "AudioOutputInternalDAC: Unsupported Target " CONFIG_IDF_TARGET); +#endif + + pinMode(dac_1_gpio, OUTPUT); + digitalWrite(dac_1_gpio, LOW); + + if (channels == 2) { + pinMode(dac_2_gpio, OUTPUT); + digitalWrite(dac_2_gpio, LOW); + } + } + + void dac_write(uint8_t* samples, uint16_t count) { + if (buffer.size() + count >= buffer_sz) { + size_t needed = buffer_sz - buffer.size(); + buffer.insert(buffer.end(), samples, samples + needed); + samples += needed; count -= needed; + + dac_continuous_write(dac_handle, buffer.data(), buffer_sz, NULL, -1); + buffer.clear(); + + while (count >= buffer_sz) { + dac_continuous_write(dac_handle, samples, buffer_sz, NULL, -1); + samples += buffer_sz; count -= buffer_sz; + } + } + + if (count) { + buffer.insert(buffer.end(), samples, samples + count); + } + } + +public: + // buffer_size should be in rannge [32, 4092]. large values can cause out + // of memory situation which can have side effects like wifi not working + AudioOutputInternalDAC(uint16_t buffer_size = 256): buffer_sz{buffer_size} { + dac_deinit(); //sets the pins low until dac_init + } + + ~AudioOutputInternalDAC() { + dac_deinit(); + } + + uint16_t ConsumeSamples(int16_t* samples, uint16_t count) override { + if (!dac_handle) { + dac_init(); + } + auto u8_samples = (uint8_t*)samples; + + for (int i = 0 ; i < count ; ++i) { + u8_samples[i] = (samples[i] + 32768) / 257; + } + + dac_write(u8_samples, count); + return count; + } + + bool ConsumeSample(int16_t samples[2]) { + if (!dac_handle) { + dac_init(); + } + uint8_t u8_samples[2]; + + u8_samples[0] = (samples[0] + 32768) / 257; + u8_samples[1] = (samples[1] + 32768) / 257; + + dac_write(u8_samples, channels); + return true; + } + + bool begin() override { + hertz = 44100; + return true; + } + + void flush() override { + if (dac_handle) { + buffer.resize(buffer_sz); buffer.back() = 0; //ensure last sample is 0 + dac_continuous_write(dac_handle, buffer.data(), buffer_sz, NULL, -1); + } + buffer.clear(); + } + + bool stop() override { + flush(); + return true; + } + + bool SetRate(int hz) override { + if (hertz != hz) { + hertz = hz; + flush(); + dac_deinit(); + } + return true; + } + + bool SetChannels(int ch) override { + if (channels != ch) { + channels = ch; + flush(); + dac_deinit(); + } + return true; + } +}; diff --git a/src/AudioOutputMixer.cpp b/src/AudioOutputMixer.cpp index 57a1c06a..1b0982ff 100644 --- a/src/AudioOutputMixer.cpp +++ b/src/AudioOutputMixer.cpp @@ -1,244 +1,217 @@ /* - AudioOutputMixer - Simple mixer which can combine multiple inputs to a single output stream - - Copyright (C) 2018 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioOutputMixer + Simple mixer which can combine multiple inputs to a single output stream + + Copyright (C) 2018 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include #include "AudioOutputMixer.h" -AudioOutputMixerStub::AudioOutputMixerStub(AudioOutputMixer *sink, int id) : AudioOutput() -{ - this->id = id; - this->parent = sink; - SetGain(1.0); +AudioOutputMixerStub::AudioOutputMixerStub(AudioOutputMixer *sink, int id) : AudioOutput() { + this->id = id; + this->parent = sink; + SetGain(1.0); + this->newHz = 44100; + this->lastHz = -1; } -AudioOutputMixerStub::~AudioOutputMixerStub() -{ - parent->RemoveInput(id); +AudioOutputMixerStub::~AudioOutputMixerStub() { + parent->RemoveInput(id); } -bool AudioOutputMixerStub::SetRate(int hz) -{ - return parent->SetRate(hz, id); +bool AudioOutputMixerStub::SetRate(int hz) { + newHz = hz; + return true; } -bool AudioOutputMixerStub::SetBitsPerSample(int bits) -{ - return parent->SetBitsPerSample(bits, id); +bool AudioOutputMixerStub::SetChannels(int channels) { + this->channels = channels; + return parent->SetChannels(channels, id); } -bool AudioOutputMixerStub::SetChannels(int channels) -{ - return parent->SetChannels(channels, id); +bool AudioOutputMixerStub::begin() { + return parent->begin(id); } -bool AudioOutputMixerStub::begin() -{ - return parent->begin(id); -} +bool AudioOutputMixerStub::ConsumeSample(int16_t sample[2]) { + int16_t ms[2]; -bool AudioOutputMixerStub::ConsumeSample(int16_t sample[2]) -{ - int16_t amp[2]; - amp[LEFTCHANNEL] = Amplify(sample[LEFTCHANNEL]); - amp[RIGHTCHANNEL] = Amplify(sample[RIGHTCHANNEL]); - return parent->ConsumeSample(amp, id); + ms[0] = sample[0]; + ms[1] = sample[1]; + MakeSampleStereo16(ms); + ms[LEFTCHANNEL] = Amplify(ms[LEFTCHANNEL]); + ms[RIGHTCHANNEL] = Amplify(ms[RIGHTCHANNEL]); + if (newHz != lastHz) { // Avoid setting on each sample unless things change + parent->SetRate(newHz, id); + lastHz = newHz; + } + return parent->ConsumeSample(ms, id); } -bool AudioOutputMixerStub::stop() -{ - return parent->stop(id); +bool AudioOutputMixerStub::stop() { + return parent->stop(id); } -AudioOutputMixer::AudioOutputMixer(int buffSizeSamples, AudioOutput *dest) : AudioOutput() -{ - buffSize = buffSizeSamples; - leftAccum = (int32_t*)calloc(sizeof(int32_t), buffSize); - rightAccum = (int32_t*)calloc(sizeof(int32_t), buffSize); - for (int i=0; iSetRate(hz); -} - -bool AudioOutputMixer::SetBitsPerSample(int bits, int id) -{ - (void) id; - return sink->SetBitsPerSample(bits); +bool AudioOutputMixer::SetRate(int hz, int id) { + (void) id; + return sink->SetRate(hz); } -bool AudioOutputMixer::SetChannels(int channels, int id) -{ - (void) id; - return sink->SetChannels(channels); +bool AudioOutputMixer::SetChannels(int channels, int id) { + (void) id; + return sink->SetChannels(channels); } -bool AudioOutputMixer::begin(int id) -{ - stubRunning[id] = true; +bool AudioOutputMixer::begin(int id) { + stubRunning[id] = true; - if (!sinkStarted) { - sinkStarted = true; - return sink->begin(); - } else { - return true; - } -} - -AudioOutputMixerStub *AudioOutputMixer::NewInput() -{ - for (int i=0; ibegin(); + } else { + return true; } - if (avail) { - int16_t s[2]; - if (leftAccum[readPtr] > 32767) { - s[LEFTCHANNEL] = 32767; - } else if (leftAccum[readPtr] < -32767) { - s[LEFTCHANNEL] = -32767; - } else { - s[LEFTCHANNEL] = leftAccum[readPtr]; - } - if (rightAccum[readPtr] > 32767) { - s[RIGHTCHANNEL] = 32767; - } else if (rightAccum[readPtr] < -32767) { - s[RIGHTCHANNEL] = -32767; - } else { - s[RIGHTCHANNEL] = rightAccum[readPtr]; - } -// s[LEFTCHANNEL] = Amplify(s[LEFTCHANNEL]); -// s[RIGHTCHANNEL] = Amplify(s[RIGHTCHANNEL]); - if (!sink->ConsumeSample(s)) { - break; // Can't stuff any more in I2S... - } - // Clear the accums and advance the pointer to next potential sample - leftAccum[readPtr] = 0; - rightAccum[readPtr] = 0; - readPtr = (readPtr + 1) % buffSize; +} + +AudioOutputMixerStub *AudioOutputMixer::NewInput() { + for (int i = 0; i < maxStubs; i++) { + if (!stubAllocated[i]) { + stubAllocated[i] = true; + stubRunning[i] = false; + writePtr[i] = readPtr; // TODO - should it be 1 before readPtr? + AudioOutputMixerStub *stub = new AudioOutputMixerStub(this, i); + return stub; + } } - } while (avail); - return true; + return nullptr; +} + +void AudioOutputMixer::RemoveInput(int id) { + stubAllocated[id] = false; + stubRunning[id] = false; +} + +bool AudioOutputMixer::loop() { + // First, try and fill I2S... + // This is not optimal, but algorithmically should work fine + bool avail; + do { + avail = true; + for (int i = 0; i < maxStubs && avail; i++) { + if (stubRunning[i] && writePtr[i] == readPtr) { + avail = false; // The read pointer is touching an active writer, can't advance + } + } + if (avail) { + int16_t s[2]; + if (leftAccum[readPtr] > 32767) { + s[LEFTCHANNEL] = 32767; + } else if (leftAccum[readPtr] < -32767) { + s[LEFTCHANNEL] = -32767; + } else { + s[LEFTCHANNEL] = leftAccum[readPtr]; + } + if (rightAccum[readPtr] > 32767) { + s[RIGHTCHANNEL] = 32767; + } else if (rightAccum[readPtr] < -32767) { + s[RIGHTCHANNEL] = -32767; + } else { + s[RIGHTCHANNEL] = rightAccum[readPtr]; + } + // s[LEFTCHANNEL] = Amplify(s[LEFTCHANNEL]); + // s[RIGHTCHANNEL] = Amplify(s[RIGHTCHANNEL]); + if (!sink->ConsumeSample(s)) { + break; // Can't stuff any more in I2S... + } + // Clear the accums and advance the pointer to next potential sample + leftAccum[readPtr] = 0; + rightAccum[readPtr] = 0; + readPtr = (readPtr + 1) % buffSize; + } + } while (avail); + return true; } -bool AudioOutputMixer::ConsumeSample(int16_t sample[2], int id) -{ - loop(); // Send any pre-existing, completed I2S data we can fit +bool AudioOutputMixer::ConsumeSample(int16_t sample[2], int id) { + loop(); // Send any pre-existing, completed I2S data we can fit - // Now, do we have space for a new sample? - int nextWritePtr = (writePtr[id] + 1) % buffSize; - if (nextWritePtr == readPtr) { - return false; - } + // Now, do we have space for a new sample? + int nextWritePtr = (writePtr[id] + 1) % buffSize; + if (nextWritePtr == readPtr) { + return false; + } - leftAccum[writePtr[id]] += sample[LEFTCHANNEL]; - rightAccum[writePtr[id]] += sample[RIGHTCHANNEL]; - writePtr[id] = nextWritePtr; - return true; + leftAccum[writePtr[id]] += sample[LEFTCHANNEL]; + rightAccum[writePtr[id]] += sample[RIGHTCHANNEL]; + writePtr[id] = nextWritePtr; + return true; } -bool AudioOutputMixer::stop(int id) -{ - stubRunning[id] = false; - return true; +bool AudioOutputMixer::stop(int id) { + stubRunning[id] = false; + return true; } diff --git a/src/AudioOutputMixer.h b/src/AudioOutputMixer.h index 2d2d1ec7..c17f2eff 100644 --- a/src/AudioOutputMixer.h +++ b/src/AudioOutputMixer.h @@ -1,21 +1,21 @@ /* - AudioOutputMixer - Simple mixer which can combine multiple inputs to a single output stream - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioOutputMixer + Simple mixer which can combine multiple inputs to a single output stream + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOOUTPUTMIXER_H @@ -27,31 +27,29 @@ class AudioOutputMixer; // The output stub exported by the mixer for use by the generator -class AudioOutputMixerStub : public AudioOutput -{ - public: +class AudioOutputMixerStub : public AudioOutput { +public: AudioOutputMixerStub(AudioOutputMixer *sink, int id); virtual ~AudioOutputMixerStub() override; virtual bool SetRate(int hz) override; - virtual bool SetBitsPerSample(int bits) override; virtual bool SetChannels(int channels) override; virtual bool begin() override; virtual bool ConsumeSample(int16_t sample[2]) override; virtual bool stop() override; - protected: +protected: AudioOutputMixer *parent; int id; + int newHz; + int lastHz; }; // Single mixer object per output -class AudioOutputMixer : public AudioOutput -{ - public: +class AudioOutputMixer : public AudioOutput { +public: AudioOutputMixer(int samples, AudioOutput *sink); virtual ~AudioOutputMixer() override; virtual bool SetRate(int hz) override; - virtual bool SetBitsPerSample(int bits) override; virtual bool SetChannels(int channels) override; virtual bool begin() override; virtual bool ConsumeSample(int16_t sample[2]) override; @@ -60,18 +58,17 @@ class AudioOutputMixer : public AudioOutput AudioOutputMixerStub *NewInput(); // Get a new stub to pass to a generator - // Stub called functions - friend class AudioOutputMixerStub; - private: + // Stub called functions + friend class AudioOutputMixerStub; +private: void RemoveInput(int id); bool SetRate(int hz, int id); - bool SetBitsPerSample(int bits, int id); bool SetChannels(int channels, int id); bool begin(int id); bool ConsumeSample(int16_t sample[2], int id); bool stop(int id); - protected: +protected: enum { maxStubs = 8 }; AudioOutput *sink; bool sinkStarted; diff --git a/src/AudioOutputNull.h b/src/AudioOutputNull.h index 4e66c899..d8a4e255 100644 --- a/src/AudioOutputNull.h +++ b/src/AudioOutputNull.h @@ -1,21 +1,21 @@ /* - AudioOutput - Base class of an audio output player - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioOutput + Base class of an audio output player + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOOUTPUTNULL_H @@ -23,19 +23,35 @@ #include "AudioOutput.h" -class AudioOutputNull : public AudioOutput -{ - public: +class AudioOutputNull : public AudioOutput { +public: AudioOutputNull() {}; ~AudioOutputNull() {}; - virtual bool begin() { samples = 0; startms = millis(); return true; } - virtual bool ConsumeSample(int16_t sample[2]) { (void)sample; samples++; return true; } - virtual bool stop() { endms = millis(); return true; }; - unsigned long GetMilliseconds() { return endms - startms; } - int GetSamples() { return samples; } - int GetFrequency() { return hertz; } - - protected: + virtual bool begin() { + samples = 0; + startms = millis(); + return true; + } + virtual bool ConsumeSample(int16_t sample[2]) { + (void)sample; + samples++; + return true; + } + virtual bool stop() { + endms = millis(); + return true; + }; + unsigned long GetMilliseconds() { + return endms - startms; + } + int GetSamples() { + return samples; + } + int GetFrequency() { + return hertz; + } + +protected: unsigned long startms; unsigned long endms; int samples; diff --git a/src/AudioOutputPWM.cpp b/src/AudioOutputPWM.cpp new file mode 100644 index 00000000..299f1e2a --- /dev/null +++ b/src/AudioOutputPWM.cpp @@ -0,0 +1,115 @@ +/* + AudioOutputPWM + Base class for the RP2040 PWM audio + + Copyright (C) 2023 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#if defined(ARDUINO_ARCH_RP2040) +#include +#include "AudioOutputPWM.h" + +AudioOutputPWM::AudioOutputPWM(long sampleRate, pin_size_t data) { + pwmOn = false; + mono = false; + channels = 2; + hertz = sampleRate; + doutPin = data; + SetGain(1.0); + pwm.setStereo(true); +} + +AudioOutputPWM::~AudioOutputPWM() { + stop(); +} + +bool AudioOutputPWM::SetRate(int hz) { + this->hertz = hz; + if (pwmOn) { + pwm.setFrequency(hz); + } + return true; +} + +bool AudioOutputPWM::SetChannels(int channels) { + if ((channels < 1) || (channels > 2)) { + return false; + } + this->channels = channels; + return true; +} + +bool AudioOutputPWM::SetOutputModeMono(bool mono) { + this->mono = mono; + return true; +} + +bool AudioOutputPWM::begin() { + if (!pwmOn) { + pwm.setPin(doutPin); + pwm.setBuffers(8, 128); + pwm.begin(hertz); + } + pwmOn = true; + SetRate(hertz); // Default + return true; +} + +bool AudioOutputPWM::ConsumeSample(int16_t sample[2]) { + + if (!pwmOn) { + return false; + } + + int16_t ms[2]; + + ms[0] = sample[0]; + ms[1] = sample[1]; + MakeSampleStereo16(ms); + + if (this->mono) { + // Average the two samples and overwrite + int32_t ttl = ms[LEFTCHANNEL] + ms[RIGHTCHANNEL]; + ms[LEFTCHANNEL] = ms[RIGHTCHANNEL] = (ttl >> 1) & 0xffff; + } + + ms[LEFTCHANNEL] = Amplify(ms[LEFTCHANNEL]); + ms[RIGHTCHANNEL] = Amplify(ms[RIGHTCHANNEL]); + + if (pwm.available()) { + pwm.write((int16_t) ms[0]); + pwm.write((int16_t) ms[1]); + return true; + } else { + return false; + } +} + +void AudioOutputPWM::flush() { + pwm.flush(); +} + +bool AudioOutputPWM::stop() { + if (!pwmOn) { + return false; + } + + pwm.end(); + pwmOn = false; + return true; +} + +#endif diff --git a/src/AudioOutputPWM.h b/src/AudioOutputPWM.h new file mode 100644 index 00000000..4aeb5dea --- /dev/null +++ b/src/AudioOutputPWM.h @@ -0,0 +1,57 @@ +/* + AudioOutputPWM + Base class for the RP2040 PWM audio output + + Copyright (C) 2023 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "AudioOutput.h" + +#if defined(ARDUINO_ARCH_RP2040) +#include +#include + +class AudioOutputPWM : public AudioOutput { +public: + AudioOutputPWM(long sampleRate = 44100, pin_size_t data = 0); + virtual ~AudioOutputPWM() override; + virtual bool SetRate(int hz) override; + virtual bool SetChannels(int channels) override; + virtual bool begin() override; + virtual bool ConsumeSample(int16_t sample[2]) override; + virtual void flush() override; + virtual bool stop() override; + + bool SetOutputModeMono(bool mono); // Force mono output no matter the input + +protected: + bool SetPinout(); + virtual int AdjustI2SRate(int hz) { + return hz; + } + uint8_t portNo; + int output_mode; + bool mono; + bool pwmOn; + + uint8_t doutPin; + + PWMAudio pwm; +}; + +#endif diff --git a/src/AudioOutputSPDIF.cpp b/src/AudioOutputSPDIF.cpp index 8c993c5f..76f76c25 100644 --- a/src/AudioOutputSPDIF.cpp +++ b/src/AudioOutputSPDIF.cpp @@ -1,288 +1,312 @@ /* - AudioOutputSPDIF - - S/PDIF output via I2S - - Needs transciever from CMOS level to either optical or coaxial interface - See: https://www.epanorama.net/documents/audio/spdif.html + AudioOutputSPDIF - Original idea and sources: - Forum thread dicussing implementation + S/PDIF output via I2S + + Needs transceiver from CMOS level to either optical or coaxial interface + See: https://www.epanorama.net/documents/audio/spdif.html + + Original idea and sources: + Forum thread discussing implementation https://forum.pjrc.com/threads/28639-S-pdif - Teensy Audio Library + Teensy Audio Library https://github.com/PaulStoffregen/Audio/blob/master/output_spdif2.cpp - - Adapted for ESP8266Audio - NOTE: This module operates I2S at 4x sampling rate, as it needs to - send out each bit as two output symbols, packed into + Adapted for ESP8266Audio + + NOTE: This module operates I2S at 4x sampling rate, as it needs to + send out each bit as two output symbols, packed into 32-bit words. Even for mono sound, S/PDIF is specified minimum - for 2 channels, each as 32-bits sub-frame. This drains I2S - buffers 4x more quickly so you may need 4x bigger output - buffers than usual, configurable with 'dma_buf_count' + for 2 channels, each as 32-bits sub-frame. This drains I2S + buffers 4x more quickly so you may need 4x bigger output + buffers than usual, configurable with 'dma_buf_count' constructor parameter. - Copyright (C) 2020 Ivan Kostoski + Copyright (C) 2020 Ivan Kostoski - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ +#if defined(ESP32) || defined(ESP8266) #include #if defined(ESP32) - #include "driver/i2s.h" - #include "soc/rtc.h" +#include "driver/i2s.h" +#include "soc/rtc.h" #elif defined(ESP8266) - #include "driver/SinglePinI2SDriver.h" +#include "driver/SinglePinI2SDriver.h" #endif #include "AudioOutputSPDIF.h" // BMC (Biphase Mark Coded) values (bit order reversed, i.e. LSB first) -static const uint16_t spdif_bmclookup[256] PROGMEM = { - 0xcccc, 0x4ccc, 0x2ccc, 0xaccc, 0x34cc, 0xb4cc, 0xd4cc, 0x54cc, - 0x32cc, 0xb2cc, 0xd2cc, 0x52cc, 0xcacc, 0x4acc, 0x2acc, 0xaacc, - 0x334c, 0xb34c, 0xd34c, 0x534c, 0xcb4c, 0x4b4c, 0x2b4c, 0xab4c, - 0xcd4c, 0x4d4c, 0x2d4c, 0xad4c, 0x354c, 0xb54c, 0xd54c, 0x554c, - 0x332c, 0xb32c, 0xd32c, 0x532c, 0xcb2c, 0x4b2c, 0x2b2c, 0xab2c, - 0xcd2c, 0x4d2c, 0x2d2c, 0xad2c, 0x352c, 0xb52c, 0xd52c, 0x552c, - 0xccac, 0x4cac, 0x2cac, 0xacac, 0x34ac, 0xb4ac, 0xd4ac, 0x54ac, - 0x32ac, 0xb2ac, 0xd2ac, 0x52ac, 0xcaac, 0x4aac, 0x2aac, 0xaaac, - 0x3334, 0xb334, 0xd334, 0x5334, 0xcb34, 0x4b34, 0x2b34, 0xab34, - 0xcd34, 0x4d34, 0x2d34, 0xad34, 0x3534, 0xb534, 0xd534, 0x5534, - 0xccb4, 0x4cb4, 0x2cb4, 0xacb4, 0x34b4, 0xb4b4, 0xd4b4, 0x54b4, - 0x32b4, 0xb2b4, 0xd2b4, 0x52b4, 0xcab4, 0x4ab4, 0x2ab4, 0xaab4, - 0xccd4, 0x4cd4, 0x2cd4, 0xacd4, 0x34d4, 0xb4d4, 0xd4d4, 0x54d4, - 0x32d4, 0xb2d4, 0xd2d4, 0x52d4, 0xcad4, 0x4ad4, 0x2ad4, 0xaad4, - 0x3354, 0xb354, 0xd354, 0x5354, 0xcb54, 0x4b54, 0x2b54, 0xab54, - 0xcd54, 0x4d54, 0x2d54, 0xad54, 0x3554, 0xb554, 0xd554, 0x5554, - 0x3332, 0xb332, 0xd332, 0x5332, 0xcb32, 0x4b32, 0x2b32, 0xab32, - 0xcd32, 0x4d32, 0x2d32, 0xad32, 0x3532, 0xb532, 0xd532, 0x5532, - 0xccb2, 0x4cb2, 0x2cb2, 0xacb2, 0x34b2, 0xb4b2, 0xd4b2, 0x54b2, - 0x32b2, 0xb2b2, 0xd2b2, 0x52b2, 0xcab2, 0x4ab2, 0x2ab2, 0xaab2, - 0xccd2, 0x4cd2, 0x2cd2, 0xacd2, 0x34d2, 0xb4d2, 0xd4d2, 0x54d2, - 0x32d2, 0xb2d2, 0xd2d2, 0x52d2, 0xcad2, 0x4ad2, 0x2ad2, 0xaad2, - 0x3352, 0xb352, 0xd352, 0x5352, 0xcb52, 0x4b52, 0x2b52, 0xab52, - 0xcd52, 0x4d52, 0x2d52, 0xad52, 0x3552, 0xb552, 0xd552, 0x5552, - 0xccca, 0x4cca, 0x2cca, 0xacca, 0x34ca, 0xb4ca, 0xd4ca, 0x54ca, - 0x32ca, 0xb2ca, 0xd2ca, 0x52ca, 0xcaca, 0x4aca, 0x2aca, 0xaaca, - 0x334a, 0xb34a, 0xd34a, 0x534a, 0xcb4a, 0x4b4a, 0x2b4a, 0xab4a, - 0xcd4a, 0x4d4a, 0x2d4a, 0xad4a, 0x354a, 0xb54a, 0xd54a, 0x554a, - 0x332a, 0xb32a, 0xd32a, 0x532a, 0xcb2a, 0x4b2a, 0x2b2a, 0xab2a, - 0xcd2a, 0x4d2a, 0x2d2a, 0xad2a, 0x352a, 0xb52a, 0xd52a, 0x552a, - 0xccaa, 0x4caa, 0x2caa, 0xacaa, 0x34aa, 0xb4aa, 0xd4aa, 0x54aa, - 0x32aa, 0xb2aa, 0xd2aa, 0x52aa, 0xcaaa, 0x4aaa, 0x2aaa, 0xaaaa +static const uint16_t spdif_bmclookup[256] PROGMEM = { + 0xcccc, 0x4ccc, 0x2ccc, 0xaccc, 0x34cc, 0xb4cc, 0xd4cc, 0x54cc, + 0x32cc, 0xb2cc, 0xd2cc, 0x52cc, 0xcacc, 0x4acc, 0x2acc, 0xaacc, + 0x334c, 0xb34c, 0xd34c, 0x534c, 0xcb4c, 0x4b4c, 0x2b4c, 0xab4c, + 0xcd4c, 0x4d4c, 0x2d4c, 0xad4c, 0x354c, 0xb54c, 0xd54c, 0x554c, + 0x332c, 0xb32c, 0xd32c, 0x532c, 0xcb2c, 0x4b2c, 0x2b2c, 0xab2c, + 0xcd2c, 0x4d2c, 0x2d2c, 0xad2c, 0x352c, 0xb52c, 0xd52c, 0x552c, + 0xccac, 0x4cac, 0x2cac, 0xacac, 0x34ac, 0xb4ac, 0xd4ac, 0x54ac, + 0x32ac, 0xb2ac, 0xd2ac, 0x52ac, 0xcaac, 0x4aac, 0x2aac, 0xaaac, + 0x3334, 0xb334, 0xd334, 0x5334, 0xcb34, 0x4b34, 0x2b34, 0xab34, + 0xcd34, 0x4d34, 0x2d34, 0xad34, 0x3534, 0xb534, 0xd534, 0x5534, + 0xccb4, 0x4cb4, 0x2cb4, 0xacb4, 0x34b4, 0xb4b4, 0xd4b4, 0x54b4, + 0x32b4, 0xb2b4, 0xd2b4, 0x52b4, 0xcab4, 0x4ab4, 0x2ab4, 0xaab4, + 0xccd4, 0x4cd4, 0x2cd4, 0xacd4, 0x34d4, 0xb4d4, 0xd4d4, 0x54d4, + 0x32d4, 0xb2d4, 0xd2d4, 0x52d4, 0xcad4, 0x4ad4, 0x2ad4, 0xaad4, + 0x3354, 0xb354, 0xd354, 0x5354, 0xcb54, 0x4b54, 0x2b54, 0xab54, + 0xcd54, 0x4d54, 0x2d54, 0xad54, 0x3554, 0xb554, 0xd554, 0x5554, + 0x3332, 0xb332, 0xd332, 0x5332, 0xcb32, 0x4b32, 0x2b32, 0xab32, + 0xcd32, 0x4d32, 0x2d32, 0xad32, 0x3532, 0xb532, 0xd532, 0x5532, + 0xccb2, 0x4cb2, 0x2cb2, 0xacb2, 0x34b2, 0xb4b2, 0xd4b2, 0x54b2, + 0x32b2, 0xb2b2, 0xd2b2, 0x52b2, 0xcab2, 0x4ab2, 0x2ab2, 0xaab2, + 0xccd2, 0x4cd2, 0x2cd2, 0xacd2, 0x34d2, 0xb4d2, 0xd4d2, 0x54d2, + 0x32d2, 0xb2d2, 0xd2d2, 0x52d2, 0xcad2, 0x4ad2, 0x2ad2, 0xaad2, + 0x3352, 0xb352, 0xd352, 0x5352, 0xcb52, 0x4b52, 0x2b52, 0xab52, + 0xcd52, 0x4d52, 0x2d52, 0xad52, 0x3552, 0xb552, 0xd552, 0x5552, + 0xccca, 0x4cca, 0x2cca, 0xacca, 0x34ca, 0xb4ca, 0xd4ca, 0x54ca, + 0x32ca, 0xb2ca, 0xd2ca, 0x52ca, 0xcaca, 0x4aca, 0x2aca, 0xaaca, + 0x334a, 0xb34a, 0xd34a, 0x534a, 0xcb4a, 0x4b4a, 0x2b4a, 0xab4a, + 0xcd4a, 0x4d4a, 0x2d4a, 0xad4a, 0x354a, 0xb54a, 0xd54a, 0x554a, + 0x332a, 0xb32a, 0xd32a, 0x532a, 0xcb2a, 0x4b2a, 0x2b2a, 0xab2a, + 0xcd2a, 0x4d2a, 0x2d2a, 0xad2a, 0x352a, 0xb52a, 0xd52a, 0x552a, + 0xccaa, 0x4caa, 0x2caa, 0xacaa, 0x34aa, 0xb4aa, 0xd4aa, 0x54aa, + 0x32aa, 0xb2aa, 0xd2aa, 0x52aa, 0xcaaa, 0x4aaa, 0x2aaa, 0xaaaa }; -AudioOutputSPDIF::AudioOutputSPDIF(int dout_pin, int port, int dma_buf_count) -{ - this->portNo = port; +AudioOutputSPDIF::AudioOutputSPDIF(int dout_pin, int port, int dma_buf_count) { + this->portNo = port; #if defined(ESP32) - // Configure ESP32 I2S to roughly compatible to ESP8266 peripheral - i2s_config_t i2s_config_spdif = { - .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX), - .sample_rate = 88200, // 2 x sampling_rate - .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, // 32bit words - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, // Right than left - .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB), - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // lowest interrupt priority - .dma_buf_count = dma_buf_count, - .dma_buf_len = DMA_BUF_SIZE_DEFAULT, // bigger buffers, reduces interrupts - .use_apll = true // Audio PLL is needed for low clock jitter - }; - if (i2s_driver_install((i2s_port_t)portNo, &i2s_config_spdif, 0, NULL) != ESP_OK) { - audioLogger->println(F("ERROR: Unable to install I2S drivers")); - return; - } - i2s_zero_dma_buffer((i2s_port_t)portNo); - SetPinout(I2S_PIN_NO_CHANGE, I2S_PIN_NO_CHANGE, dout_pin); - rate_multiplier = 2; // 2x32bit words + // Configure ESP32 I2S to roughly compatible to ESP8266 peripheral + i2s_config_t i2s_config_spdif = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX), + .sample_rate = 88200, // 2 x sampling_rate + .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, // 32bit words + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, // Right than left +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) + .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_STAND_I2S), +#else + .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB), +#endif + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // lowest interrupt priority + .dma_buf_count = dma_buf_count, + .dma_buf_len = DMA_BUF_SIZE_DEFAULT, // bigger buffers, reduces interrupts + .use_apll = true, // Audio PLL is needed for low clock jitter + .tx_desc_auto_clear = true, // Silence on underflow + .fixed_mclk = 0, // Unused +#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR >= 3 + .mclk_multiple = I2S_MCLK_MULTIPLE_512, // Unused + .bits_per_chan = I2S_BITS_PER_CHAN_DEFAULT // Use bits per sample +#elif ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) + .mclk_multiple = I2S_MCLK_MULTIPLE_DEFAULT, // Unused + .bits_per_chan = I2S_BITS_PER_CHAN_DEFAULT // Use bits per sample +#endif + }; + if (i2s_driver_install((i2s_port_t)portNo, &i2s_config_spdif, 0, NULL) != ESP_OK) { + audioLogger->println(F("ERROR: Unable to install I2S drivers")); + return; + } + i2s_zero_dma_buffer((i2s_port_t)portNo); + SetPinout(I2S_PIN_NO_CHANGE, I2S_PIN_NO_CHANGE, dout_pin); + rate_multiplier = 2; // 2x32bit words #elif defined(ESP8266) - (void) dout_pin; - if (!I2SDriver.begin(dma_buf_count, DMA_BUF_SIZE_DEFAULT)) { - audioLogger->println(F("ERROR: Unable to start I2S driver")); - return; - } - rate_multiplier = 4; // 4x16 bit words + (void) dout_pin; + if (!I2SDriver.begin(dma_buf_count, DMA_BUF_SIZE_DEFAULT)) { + audioLogger->println(F("ERROR: Unable to start I2S driver")); + return; + } + rate_multiplier = 4; // 4x16 bit words #endif - i2sOn = true; - mono = false; - bps = 16; - channels = 2; - frame_num = 0; - SetGain(1.0); - hertz = 0; - SetRate(44100); + i2sOn = true; + mono = false; + channels = 2; + frame_num = 0; + SetGain(1.0); + hertz = 0; + SetRate(44100); } -AudioOutputSPDIF::~AudioOutputSPDIF() -{ +AudioOutputSPDIF::~AudioOutputSPDIF() { #if defined(ESP32) - if (i2sOn) { - i2s_stop((i2s_port_t)this->portNo); - audioLogger->printf("UNINSTALL I2S\n"); - i2s_driver_uninstall((i2s_port_t)this->portNo); //stop & destroy i2s driver - } + if (i2sOn) { + i2s_stop((i2s_port_t)this->portNo); + audioLogger->printf("UNINSTALL I2S\n"); + i2s_driver_uninstall((i2s_port_t)this->portNo); //stop & destroy i2s driver + } #elif defined(ESP8266) - if (i2sOn) I2SDriver.stop(); + if (i2sOn) { + I2SDriver.stop(); + } #endif - i2sOn = false; + i2sOn = false; } -bool AudioOutputSPDIF::SetPinout(int bclk, int wclk, int dout) -{ +bool AudioOutputSPDIF::SetPinout(int bclk, int wclk, int dout) { #if defined(ESP32) - i2s_pin_config_t pins = { - .bck_io_num = bclk, - .ws_io_num = wclk, - .data_out_num = dout, - .data_in_num = I2S_PIN_NO_CHANGE - }; - if (i2s_set_pin((i2s_port_t)portNo, &pins) != ESP_OK) { - audioLogger->println("ERROR setting up S/PDIF I2S pins\n"); - return false; - } - return true; + i2s_pin_config_t pins = { +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) + .mck_io_num = 0, // unused +#endif + .bck_io_num = bclk, + .ws_io_num = wclk, + .data_out_num = dout, + .data_in_num = I2S_PIN_NO_CHANGE + }; + if (i2s_set_pin((i2s_port_t)portNo, &pins) != ESP_OK) { + audioLogger->println("ERROR setting up S/PDIF I2S pins\n"); + return false; + } + return true; #else - (void) bclk; - (void) wclk; - (void) dout; - return false; + (void) bclk; + (void) wclk; + (void) dout; + return false; #endif } -bool AudioOutputSPDIF::SetRate(int hz) -{ - if (!i2sOn) return false; - if (hz < 32000) return false; - if (hz == this->hertz) return true; - this->hertz = hz; - int adjustedHz = AdjustI2SRate(hz); +bool AudioOutputSPDIF::SetRate(int hz) { + if (!i2sOn) { + return false; + } + if (hz < 32000) { + return false; + } + if (hz == this->hertz) { + return true; + } + this->hertz = hz; + int adjustedHz = AdjustI2SRate(hz); #if defined(ESP32) - if (i2s_set_sample_rates((i2s_port_t)portNo, adjustedHz) == ESP_OK) { - if (adjustedHz == 88200) { - // Manually fix the APLL rate for 44100. - // See: https://github.com/espressif/esp-idf/issues/2634 - // sdm0 = 28, sdm1 = 8, sdm2 = 5, odir = 0 -> 88199.977 - rtc_clk_apll_enable(1, 28, 8, 5, 0); + if (i2s_set_sample_rates((i2s_port_t)portNo, adjustedHz) == ESP_OK) { +#if defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR < 3) + if (adjustedHz == 88200) { + // Manually fix the APLL rate for 44100. + // See: https://github.com/espressif/esp-idf/issues/2634 + // sdm0 = 28, sdm1 = 8, sdm2 = 5, odir = 0 -> 88199.977 + rtc_clk_apll_enable(1, 28, 8, 5, 0); + } +#endif + } else { + audioLogger->println("ERROR changing S/PDIF sample rate"); } - } else { - audioLogger->println("ERROR changing S/PDIF sample rate"); - } #elif defined(ESP8266) - I2SDriver.setRate(adjustedHz); - audioLogger->printf_P(PSTR("S/PDIF rate set: %.3f\n"), I2SDriver.getActualRate()/4); + I2SDriver.setRate(adjustedHz); + audioLogger->printf_P(PSTR("S/PDIF rate set: %.3f\n"), I2SDriver.getActualRate() / 4); #endif - return true; + return true; } -bool AudioOutputSPDIF::SetBitsPerSample(int bits) -{ - if ( (bits != 16) && (bits != 8) ) return false; - this->bps = bits; - return true; -} - -bool AudioOutputSPDIF::SetChannels(int channels) -{ - if ( (channels < 1) || (channels > 2) ) return false; - this->channels = channels; - return true; +bool AudioOutputSPDIF::SetChannels(int channels) { + if ((channels < 1) || (channels > 2)) { + return false; + } + this->channels = channels; + return true; } -bool AudioOutputSPDIF::SetOutputModeMono(bool mono) -{ - this->mono = mono; - // Just use the left channel for mono - if (mono) SetChannels(1); - return true; +bool AudioOutputSPDIF::SetOutputModeMono(bool mono) { + this->mono = mono; + // Just use the left channel for mono + if (mono) { + SetChannels(1); + } + return true; } -bool AudioOutputSPDIF::begin() -{ - return true; +bool AudioOutputSPDIF::begin() { + return true; } -bool AudioOutputSPDIF::ConsumeSample(int16_t sample[2]) -{ - if (!i2sOn) return true; // Sink the data - int16_t ms[2]; - uint16_t hi, lo, aux; - uint32_t buf[4]; +bool AudioOutputSPDIF::ConsumeSample(int16_t sample[2]) { + if (!i2sOn) { + return true; // Sink the data + } + int16_t ms[2]; + uint16_t hi, lo, aux; + uint32_t buf[4]; - ms[0] = sample[0]; - ms[1] = sample[1]; - MakeSampleStereo16(ms); + ms[0] = sample[0]; + ms[1] = sample[1]; + MakeSampleStereo16(ms); - // S/PDIF encoding: - // http://www.hardwarebook.info/S/PDIF - // Original sources: Teensy Audio Library - // https://github.com/PaulStoffregen/Audio/blob/master/output_spdif2.cpp - // - // Order of bits, before BMC encoding, from the definition of SPDIF format - // PPPP AAAA SSSS SSSS SSSS SSSS SSSS VUCP - // are sent rearanged as - // VUCP PPPP AAAA 0000 SSSS SSSS SSSS SSSS - // This requires a bit less shifting as 16 sample bits align and can be - // BMC encoded with two table lookups (and at the same time flipped to LSB first). - // There is no separate word-clock, so hopefully the receiver won't notice. + // S/PDIF encoding: + // http://www.hardwarebook.info/S/PDIF + // Original sources: Teensy Audio Library + // https://github.com/PaulStoffregen/Audio/blob/master/output_spdif2.cpp + // + // Order of bits, before BMC encoding, from the definition of SPDIF format + // PPPP AAAA SSSS SSSS SSSS SSSS SSSS VUCP + // are sent rearanged as + // VUCP PPPP AAAA 0000 SSSS SSSS SSSS SSSS + // This requires a bit less shifting as 16 sample bits align and can be + // BMC encoded with two table lookups (and at the same time flipped to LSB first). + // There is no separate word-clock, so hopefully the receiver won't notice. - uint16_t sample_left = Amplify(ms[LEFTCHANNEL]); - // BMC encode and flip left channel bits - hi = pgm_read_word(&spdif_bmclookup[(uint8_t)(sample_left >> 8)]); - lo = pgm_read_word(&spdif_bmclookup[(uint8_t)sample_left]); - // Low word is inverted depending on first bit of high word - lo ^= (~((int16_t)hi) >> 16); - buf[0] = ((uint32_t)lo << 16) | hi; - // Fixed 4 bits auxillary-audio-databits, the first used as parity - // Depending on first bit of low word, invert the bits - aux = 0xb333 ^ (((uint32_t)((int16_t)lo)) >> 17); - // Send 'B' preamble only for the first frame of data-block - if (frame_num == 0) { - buf[1] = VUCP_PREAMBLE_B | aux; - } else { - buf[1] = VUCP_PREAMBLE_M | aux; - } + uint16_t sample_left = Amplify(ms[LEFTCHANNEL]); + // BMC encode and flip left channel bits + hi = pgm_read_word(&spdif_bmclookup[(uint8_t)(sample_left >> 8)]); + lo = pgm_read_word(&spdif_bmclookup[(uint8_t)sample_left]); + // Low word is inverted depending on first bit of high word + lo ^= (~((int16_t)hi) >> 16); + buf[0] = ((uint32_t)lo << 16) | hi; + // Fixed 4 bits auxillary-audio-databits, the first used as parity + // Depending on first bit of low word, invert the bits + aux = 0xb333 ^ (((uint32_t)((int16_t)lo)) >> 17); + // Send 'B' preamble only for the first frame of data-block + if (frame_num == 0) { + buf[1] = VUCP_PREAMBLE_B | aux; + } else { + buf[1] = VUCP_PREAMBLE_M | aux; + } - uint16_t sample_right = Amplify(ms[RIGHTCHANNEL]); - // BMC encode right channel, similar as above - hi = pgm_read_word(&spdif_bmclookup[(uint8_t)(sample_right >> 8)]); - lo = pgm_read_word(&spdif_bmclookup[(uint8_t)sample_right]); - lo ^= (~((int16_t)hi) >> 16); - buf[2] = ((uint32_t)lo << 16) | hi; - aux = 0xb333 ^ (((uint32_t)((int16_t)lo)) >> 17); - buf[3] = VUCP_PREAMBLE_W | aux; + uint16_t sample_right = Amplify(ms[RIGHTCHANNEL]); + // BMC encode right channel, similar as above + hi = pgm_read_word(&spdif_bmclookup[(uint8_t)(sample_right >> 8)]); + lo = pgm_read_word(&spdif_bmclookup[(uint8_t)sample_right]); + lo ^= (~((int16_t)hi) >> 16); + buf[2] = ((uint32_t)lo << 16) | hi; + aux = 0xb333 ^ (((uint32_t)((int16_t)lo)) >> 17); + buf[3] = VUCP_PREAMBLE_W | aux; #if defined(ESP32) - // Assume DMA buffers are multiples of 16 bytes. Either we write all bytes or none. - uint32_t bytes_written; - esp_err_t ret = i2s_write((i2s_port_t)portNo, (const char*)&buf, 8 * channels, &bytes_written, 0); - // If we didn't write all bytes, return false early and do not increment frame_num - if ((ret != ESP_OK) || (bytes_written != (8 * channels))) return false; + // Assume DMA buffers are multiples of 16 bytes. Either we write all bytes or none. + size_t bytes_written; + esp_err_t ret = i2s_write((i2s_port_t)portNo, (const char*)&buf, 8 * channels, &bytes_written, 0); + // If we didn't write all bytes, return false early and do not increment frame_num + if ((ret != ESP_OK) || (bytes_written != (8 * channels))) { + return false; + } #elif defined(ESP8266) - if (!I2SDriver.writeInterleaved(buf)) return false; + if (!I2SDriver.writeInterleaved(buf)) { + return false; + } #endif - // Increment and rotate frame number - if (++frame_num > 191) frame_num = 0; - return true; + // Increment and rotate frame number + if (++frame_num > 191) { + frame_num = 0; + } + return true; } -bool AudioOutputSPDIF::stop() -{ +bool AudioOutputSPDIF::stop() { #if defined(ESP32) - i2s_zero_dma_buffer((i2s_port_t)portNo); + i2s_zero_dma_buffer((i2s_port_t)portNo); #elif defined(ESP8266) - I2SDriver.stop(); + I2SDriver.stop(); #endif - frame_num = 0; - return true; + frame_num = 0; + return true; } + +#endif diff --git a/src/AudioOutputSPDIF.h b/src/AudioOutputSPDIF.h index 92a4e46e..c721a47d 100644 --- a/src/AudioOutputSPDIF.h +++ b/src/AudioOutputSPDIF.h @@ -1,37 +1,37 @@ /* - AudioOutputSPDIF - - S/PDIF output via I2S - - Needs transciever from CMOS level to either optical or coaxial interface - See: https://www.epanorama.net/documents/audio/spdif.html - - Original idea and sources: - Forum thread dicussing implementation + AudioOutputSPDIF + + S/PDIF output via I2S + + Needs transceiver from CMOS level to either optical or coaxial interface + See: https://www.epanorama.net/documents/audio/spdif.html + + Original idea and sources: + Forum thread discussing implementation https://forum.pjrc.com/threads/28639-S-pdif - Teensy Audio Library + Teensy Audio Library https://github.com/PaulStoffregen/Audio/blob/master/output_spdif2.cpp - - Adapted for ESP8266Audio - Copyright (C) 2020 Ivan Kostoski + Adapted for ESP8266Audio + + Copyright (C) 2020 Ivan Kostoski - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ -#ifndef _AUDIOOUTPUTSPDIF_H -#define _AUDIOOUTPUTSPDIF_H +#if defined(ESP32) || defined(ESP8266) +#pragma once #include "AudioOutput.h" @@ -45,14 +45,12 @@ #define DMA_BUF_SIZE_DEFAULT 64 #endif -class AudioOutputSPDIF : public AudioOutput -{ - public: - AudioOutputSPDIF(int dout_pin=SPDIF_OUT_PIN_DEFAULT, int port=0, int dma_buf_count = DMA_BUF_COUNT_DEFAULT); +class AudioOutputSPDIF : public AudioOutput { +public: + AudioOutputSPDIF(int dout_pin = SPDIF_OUT_PIN_DEFAULT, int port = 0, int dma_buf_count = DMA_BUF_COUNT_DEFAULT); virtual ~AudioOutputSPDIF() override; bool SetPinout(int bclkPin, int wclkPin, int doutPin); virtual bool SetRate(int hz) override; - virtual bool SetBitsPerSample(int bits) override; virtual bool SetChannels(int channels) override; virtual bool begin() override; virtual bool ConsumeSample(int16_t sample[2]) override; @@ -64,8 +62,10 @@ class AudioOutputSPDIF : public AudioOutput const uint32_t VUCP_PREAMBLE_M = 0xCCE20000; // 11001100 11100010 const uint32_t VUCP_PREAMBLE_W = 0xCCE40000; // 11001100 11100100 - protected: - virtual inline int AdjustI2SRate(int hz) { return rate_multiplier * hz; } +protected: + virtual inline int AdjustI2SRate(int hz) { + return rate_multiplier * hz; + } uint8_t portNo; bool mono; bool i2sOn; diff --git a/src/AudioOutputSPIFFSWAV.cpp b/src/AudioOutputSPIFFSWAV.cpp index 44a5022c..c9c1169d 100644 --- a/src/AudioOutputSPIFFSWAV.cpp +++ b/src/AudioOutputSPIFFSWAV.cpp @@ -1,113 +1,119 @@ /* - AudioOutputSPIFFSWAV - Writes a WAV file to the SPIFFS filesystem - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioOutputSPIFFSWAV + Writes a WAV file to the SPIFFS filesystem + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ +#if !defined(ARDUINO_ARCH_RP2040) + #include #include #ifdef ESP32 #include "SPIFFS.h" #endif +// Yes, I know SPIFFS is deprecated +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + + #include "AudioOutputSPIFFSWAV.h" static const uint8_t wavHeaderTemplate[] PROGMEM = { // Hardcoded simple WAV header with 0xffffffff lengths all around 0x52, 0x49, 0x46, 0x46, 0xff, 0xff, 0xff, 0xff, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x22, 0x56, 0x00, 0x00, 0x88, 0x58, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, - 0x64, 0x61, 0x74, 0x61, 0xff, 0xff, 0xff, 0xff }; + 0x64, 0x61, 0x74, 0x61, 0xff, 0xff, 0xff, 0xff +}; -void AudioOutputSPIFFSWAV::SetFilename(const char *name) -{ - if (filename) free(filename); - filename = strdup(name); +void AudioOutputSPIFFSWAV::SetFilename(const char *name) { + if (filename) { + free(filename); + } + filename = strdup(name); } -bool AudioOutputSPIFFSWAV::begin() -{ - uint8_t wavHeader[sizeof(wavHeaderTemplate)]; - memset(wavHeader, 0, sizeof(wavHeader)); - - if (f) return false; // Already open! - SPIFFS.remove(filename); - f = SPIFFS.open(filename, "w+"); - if (!f) return false; - - // We'll fix the header up when we close the file - f.write(wavHeader, sizeof(wavHeader)); - return true; +bool AudioOutputSPIFFSWAV::begin() { + uint8_t wavHeader[sizeof(wavHeaderTemplate)]; + memset(wavHeader, 0, sizeof(wavHeader)); + + if (f) { + return false; // Already open! + } + SPIFFS.remove(filename); + f = SPIFFS.open(filename, "w+"); + if (!f) { + return false; + } + + // We'll fix the header up when we close the file + f.write(wavHeader, sizeof(wavHeader)); + return true; } -bool AudioOutputSPIFFSWAV::ConsumeSample(int16_t sample[2]) -{ - for (int i=0; i> 8) & 0xff; - f.write(&l, sizeof(l)); - f.write(&h, sizeof(h)); +bool AudioOutputSPIFFSWAV::ConsumeSample(int16_t sample[2]) { + for (int i = 0; i < channels; i++) { + uint8_t l = sample[i] & 0xff; + uint8_t h = (sample[i] >> 8) & 0xff; + f.write(&l, sizeof(l)); + f.write(&h, sizeof(h)); } - } - return true; + return true; } -bool AudioOutputSPIFFSWAV::stop() -{ - uint8_t wavHeader[sizeof(wavHeaderTemplate)]; - - memcpy_P(wavHeader, wavHeaderTemplate, sizeof(wavHeaderTemplate)); - - int chunksize = f.size() - 8; - wavHeader[4] = chunksize & 0xff; - wavHeader[5] = (chunksize>>8)&0xff; - wavHeader[6] = (chunksize>>16)&0xff; - wavHeader[7] = (chunksize>>24)&0xff; - - wavHeader[22] = channels & 0xff; - wavHeader[23] = 0; - - wavHeader[24] = hertz & 0xff; - wavHeader[25] = (hertz >> 8) & 0xff; - wavHeader[26] = (hertz >> 16) & 0xff; - wavHeader[27] = (hertz >> 24) & 0xff; - int byteRate = hertz * bps * channels / 8; - wavHeader[28] = byteRate & 0xff; - wavHeader[29] = (byteRate >> 8) & 0xff; - wavHeader[30] = (byteRate >> 16) & 0xff; - wavHeader[31] = (byteRate >> 24) & 0xff; - wavHeader[32] = channels * bps / 8; - wavHeader[33] = 0; - wavHeader[34] = bps; - wavHeader[35] = 0; - - int datasize = f.size() - sizeof(wavHeader); - wavHeader[40] = datasize & 0xff; - wavHeader[41] = (datasize>>8)&0xff; - wavHeader[42] = (datasize>>16)&0xff; - wavHeader[43] = (datasize>>24)&0xff; - - // Write real header out - f.seek(0, SeekSet); - f.write(wavHeader, sizeof(wavHeader)); - f.close(); - return true; +bool AudioOutputSPIFFSWAV::stop() { + uint8_t wavHeader[sizeof(wavHeaderTemplate)]; + + memcpy_P(wavHeader, wavHeaderTemplate, sizeof(wavHeaderTemplate)); + + int chunksize = f.size() - 8; + wavHeader[4] = chunksize & 0xff; + wavHeader[5] = (chunksize >> 8) & 0xff; + wavHeader[6] = (chunksize >> 16) & 0xff; + wavHeader[7] = (chunksize >> 24) & 0xff; + + wavHeader[22] = channels & 0xff; + wavHeader[23] = 0; + + wavHeader[24] = hertz & 0xff; + wavHeader[25] = (hertz >> 8) & 0xff; + wavHeader[26] = (hertz >> 16) & 0xff; + wavHeader[27] = (hertz >> 24) & 0xff; + int byteRate = hertz * 16 * channels / 8; + wavHeader[28] = byteRate & 0xff; + wavHeader[29] = (byteRate >> 8) & 0xff; + wavHeader[30] = (byteRate >> 16) & 0xff; + wavHeader[31] = (byteRate >> 24) & 0xff; + wavHeader[32] = channels * 16 / 8; + wavHeader[33] = 0; + wavHeader[34] = 16; + wavHeader[35] = 0; + + int datasize = f.size() - sizeof(wavHeader); + wavHeader[40] = datasize & 0xff; + wavHeader[41] = (datasize >> 8) & 0xff; + wavHeader[42] = (datasize >> 16) & 0xff; + wavHeader[43] = (datasize >> 24) & 0xff; + + // Write real header out + f.seek(0, SeekSet); + f.write(wavHeader, sizeof(wavHeader)); + f.close(); + return true; } - + + +#endif diff --git a/src/AudioOutputSPIFFSWAV.h b/src/AudioOutputSPIFFSWAV.h index 4a2afaf4..93fc90a6 100644 --- a/src/AudioOutputSPIFFSWAV.h +++ b/src/AudioOutputSPIFFSWAV.h @@ -1,45 +1,51 @@ /* - AudioOutputSPIFFSWAV - Writes a WAV file to the SPIFFS filesystem - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioOutputSPIFFSWAV + Writes a WAV file to the SPIFFS filesystem + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOOUTPUTSPIFFSWAV_H #define _AUDIOOUTPUTSPIFFSWAV_H +#if !defined(ARDUINO_ARCH_RP2040) + #include #include #include "AudioOutput.h" -class AudioOutputSPIFFSWAV : public AudioOutput -{ - public: - AudioOutputSPIFFSWAV() { filename = NULL; }; - ~AudioOutputSPIFFSWAV() { free(filename); }; +class AudioOutputSPIFFSWAV : public AudioOutput { +public: + AudioOutputSPIFFSWAV() { + filename = NULL; + }; + ~AudioOutputSPIFFSWAV() { + free(filename); + }; virtual bool begin() override; virtual bool ConsumeSample(int16_t sample[2]) override; virtual bool stop() override; void SetFilename(const char *name); - private: +private: File f; char *filename; }; #endif +#endif diff --git a/src/AudioOutputSTDIO.cpp b/src/AudioOutputSTDIO.cpp index 33bbd34f..9503e2ea 100644 --- a/src/AudioOutputSTDIO.cpp +++ b/src/AudioOutputSTDIO.cpp @@ -1,22 +1,22 @@ /* - AudioOutputSTDIO - Writes a WAV file to the STDIO filesystem - Only for host-based testing + AudioOutputSTDIO + Writes a WAV file to the STDIO filesystem + Only for host-based testing - Copyright (C) 2017 Earle F. Philhower, III + Copyright (C) 2017 Earle F. Philhower, III - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include @@ -29,87 +29,88 @@ static const uint8_t wavHeaderTemplate[] PROGMEM = { // Hardcoded simple WAV header with 0xffffffff lengths all around 0x52, 0x49, 0x46, 0x46, 0xff, 0xff, 0xff, 0xff, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x22, 0x56, 0x00, 0x00, 0x88, 0x58, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, - 0x64, 0x61, 0x74, 0x61, 0xff, 0xff, 0xff, 0xff }; + 0x64, 0x61, 0x74, 0x61, 0xff, 0xff, 0xff, 0xff +}; -void AudioOutputSTDIO::SetFilename(const char *name) -{ - free(filename); - filename = strdup(name); +void AudioOutputSTDIO::SetFilename(const char *name) { + free(filename); + filename = strdup(name); } -bool AudioOutputSTDIO::begin() -{ - uint8_t wavHeader[sizeof(wavHeaderTemplate)]; - memset(wavHeader, 0, sizeof(wavHeader)); - - if (f) return false; // Already open! - unlink(filename); - f = fopen(filename, "wb+"); - if (!f) return false; - - // We'll fix the header up when we close the file - fwrite(wavHeader, sizeof(wavHeader), 1, f); - return true; +bool AudioOutputSTDIO::begin() { + uint8_t wavHeader[sizeof(wavHeaderTemplate)]; + memset(wavHeader, 0, sizeof(wavHeader)); + + if (f) { + return false; // Already open! + } + unlink(filename); + f = fopen(filename, "wb+"); + if (!f) { + return false; + } + + // We'll fix the header up when we close the file + fwrite(wavHeader, sizeof(wavHeader), 1, f); + return true; } -bool AudioOutputSTDIO::ConsumeSample(int16_t sample[2]) -{ - for (int i=0; i> 8) & 0xff; - fwrite(&l, sizeof(l), 1, f); - fwrite(&h, sizeof(h), 1, f); +bool AudioOutputSTDIO::ConsumeSample(int16_t sample[2]) { + static int avail = 100; + if (!(--avail)) { + avail = 100; + return false; + } + for (int i = 0; i < channels; i++) { + uint8_t l = sample[i] & 0xff; + uint8_t h = (sample[i] >> 8) & 0xff; + fwrite(&l, sizeof(l), 1, f); + fwrite(&h, sizeof(h), 1, f); } - } - return true; + return true; } -bool AudioOutputSTDIO::stop() -{ - uint8_t wavHeader[sizeof(wavHeaderTemplate)]; - - memcpy_P(wavHeader, wavHeaderTemplate, sizeof(wavHeaderTemplate)); - - int chunksize = ftell(f) - 8; - wavHeader[4] = chunksize & 0xff; - wavHeader[5] = (chunksize>>8)&0xff; - wavHeader[6] = (chunksize>>16)&0xff; - wavHeader[7] = (chunksize>>24)&0xff; - - wavHeader[22] = channels & 0xff; - wavHeader[23] = 0; - - wavHeader[24] = hertz & 0xff; - wavHeader[25] = (hertz >> 8) & 0xff; - wavHeader[26] = (hertz >> 16) & 0xff; - wavHeader[27] = (hertz >> 24) & 0xff; - int byteRate = hertz * bps * channels / 8; - wavHeader[28] = byteRate & 0xff; - wavHeader[29] = (byteRate >> 8) & 0xff; - wavHeader[30] = (byteRate >> 16) & 0xff; - wavHeader[31] = (byteRate >> 24) & 0xff; - wavHeader[32] = channels * bps / 8; - wavHeader[33] = 0; - wavHeader[34] = bps; - wavHeader[35] = 0; - - int datasize = ftell(f) - sizeof(wavHeader); - wavHeader[40] = datasize & 0xff; - wavHeader[41] = (datasize>>8)&0xff; - wavHeader[42] = (datasize>>16)&0xff; - wavHeader[43] = (datasize>>24)&0xff; - - // Write real header out - fseek(f, 0, SEEK_SET); - fwrite(wavHeader, sizeof(wavHeader), 1, f); - fclose(f); - return true; +bool AudioOutputSTDIO::stop() { + uint8_t wavHeader[sizeof(wavHeaderTemplate)]; + + memcpy_P(wavHeader, wavHeaderTemplate, sizeof(wavHeaderTemplate)); + + int chunksize = ftell(f) - 8; + wavHeader[4] = chunksize & 0xff; + wavHeader[5] = (chunksize >> 8) & 0xff; + wavHeader[6] = (chunksize >> 16) & 0xff; + wavHeader[7] = (chunksize >> 24) & 0xff; + + wavHeader[22] = channels & 0xff; + wavHeader[23] = 0; + + wavHeader[24] = hertz & 0xff; + wavHeader[25] = (hertz >> 8) & 0xff; + wavHeader[26] = (hertz >> 16) & 0xff; + wavHeader[27] = (hertz >> 24) & 0xff; + int byteRate = hertz * 16 * channels / 8; + wavHeader[28] = byteRate & 0xff; + wavHeader[29] = (byteRate >> 8) & 0xff; + wavHeader[30] = (byteRate >> 16) & 0xff; + wavHeader[31] = (byteRate >> 24) & 0xff; + wavHeader[32] = channels * 16 / 8; + wavHeader[33] = 0; + wavHeader[34] = 16; + wavHeader[35] = 0; + + int datasize = ftell(f) - sizeof(wavHeader); + wavHeader[40] = datasize & 0xff; + wavHeader[41] = (datasize >> 8) & 0xff; + wavHeader[42] = (datasize >> 16) & 0xff; + wavHeader[43] = (datasize >> 24) & 0xff; + + // Write real header out + fseek(f, 0, SEEK_SET); + fwrite(wavHeader, sizeof(wavHeader), 1, f); + fclose(f); + return true; } #endif - + diff --git a/src/AudioOutputSTDIO.h b/src/AudioOutputSTDIO.h index f5a10288..86149eec 100644 --- a/src/AudioOutputSTDIO.h +++ b/src/AudioOutputSTDIO.h @@ -1,22 +1,22 @@ /* - AudioOutputSTDIO - Writes a WAV file to the STDIO filesystem - Only for host-based testing + AudioOutputSTDIO + Writes a WAV file to the STDIO filesystem + Only for host-based testing - Copyright (C) 2017 Earle F. Philhower, III + Copyright (C) 2017 Earle F. Philhower, III - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOOUTPUTSTDIO_H @@ -27,17 +27,21 @@ #include "AudioOutput.h" -class AudioOutputSTDIO : public AudioOutput -{ - public: - AudioOutputSTDIO() { filename = NULL; f = NULL; }; - ~AudioOutputSTDIO() { free(filename); }; +class AudioOutputSTDIO : public AudioOutput { +public: + AudioOutputSTDIO() { + filename = NULL; + f = NULL; + }; + ~AudioOutputSTDIO() { + free(filename); + }; virtual bool begin() override; virtual bool ConsumeSample(int16_t sample[2]) override; virtual bool stop() override; void SetFilename(const char *name); - private: +private: FILE *f; char *filename; }; diff --git a/src/AudioOutputSerialWAV.cpp b/src/AudioOutputSerialWAV.cpp index 458860fb..a70f1b7c 100644 --- a/src/AudioOutputSerialWAV.cpp +++ b/src/AudioOutputSerialWAV.cpp @@ -1,21 +1,21 @@ /* - AudioOutputSerialWAV - Writes a mostly correct WAV file to the serial port - - Copyright (C) 2017 Earle F. Philhower, III + AudioOutputSerialWAV + Writes a mostly correct WAV file to the serial port - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + Copyright (C) 2017 Earle F. Philhower, III - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include "AudioOutputSerialWAV.h" @@ -23,56 +23,48 @@ static const uint8_t wavHeaderTemplate[] PROGMEM = { // Hardcoded simple WAV header with 0xffffffff lengths all around 0x52, 0x49, 0x46, 0x46, 0xff, 0xff, 0xff, 0xff, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x22, 0x56, 0x00, 0x00, 0x88, 0x58, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, - 0x64, 0x61, 0x74, 0x61, 0xff, 0xff, 0xff, 0xff }; + 0x64, 0x61, 0x74, 0x61, 0xff, 0xff, 0xff, 0xff +}; -bool AudioOutputSerialWAV::begin() -{ - uint8_t wavHeader[sizeof(wavHeaderTemplate)]; - memcpy_P(wavHeader, wavHeaderTemplate, sizeof(wavHeaderTemplate)); - wavHeader[22] = channels & 0xff; - wavHeader[23] = 0; - wavHeader[24] = hertz & 0xff; - wavHeader[25] = (hertz >> 8) & 0xff; - wavHeader[26] = (hertz >> 16) & 0xff; - wavHeader[27] = (hertz >> 24) & 0xff; - int byteRate = hertz * bps * channels / 8; - wavHeader[28] = byteRate & 0xff; - wavHeader[29] = (byteRate >> 8) & 0xff; - wavHeader[30] = (byteRate >> 16) & 0xff; - wavHeader[31] = (byteRate >> 24) & 0xff; - wavHeader[32] = channels * bps / 8; - wavHeader[33] = 0; - wavHeader[34] = bps; - wavHeader[35] = 0; - Serial.write(wavHeader, sizeof(wavHeader)); - count = 0; - return true; +bool AudioOutputSerialWAV::begin() { + uint8_t wavHeader[sizeof(wavHeaderTemplate)]; + memcpy_P(wavHeader, wavHeaderTemplate, sizeof(wavHeaderTemplate)); + wavHeader[22] = channels & 0xff; + wavHeader[23] = 0; + wavHeader[24] = hertz & 0xff; + wavHeader[25] = (hertz >> 8) & 0xff; + wavHeader[26] = (hertz >> 16) & 0xff; + wavHeader[27] = (hertz >> 24) & 0xff; + int byteRate = hertz * 16 * channels / 8; + wavHeader[28] = byteRate & 0xff; + wavHeader[29] = (byteRate >> 8) & 0xff; + wavHeader[30] = (byteRate >> 16) & 0xff; + wavHeader[31] = (byteRate >> 24) & 0xff; + wavHeader[32] = channels * 16 / 8; + wavHeader[33] = 0; + wavHeader[34] = 16; + wavHeader[35] = 0; + Serial.write(wavHeader, sizeof(wavHeader)); + count = 0; + return true; } -bool AudioOutputSerialWAV::ConsumeSample(int16_t sample[2]) -{ - if (++count == 200) { - count = 0; - return false; - } - for (int i=0; i> 8) & 0xff; - Serial.write(l); - Serial.write(h); +bool AudioOutputSerialWAV::ConsumeSample(int16_t sample[2]) { + if (++count == 200) { + count = 0; + return false; + } + for (int i = 0; i < channels; i++) { + uint8_t l = sample[i] & 0xff; + uint8_t h = (sample[i] >> 8) & 0xff; + Serial.write(l); + Serial.write(h); } - } - return true; + return true; } -bool AudioOutputSerialWAV::stop() -{ - audioLogger->printf_P(PSTR("\n\n\nEOF\n\n\n")); - return true; +bool AudioOutputSerialWAV::stop() { + audioLogger->printf_P(PSTR("\n\n\nEOF\n\n\n")); + return true; } - diff --git a/src/AudioOutputSerialWAV.h b/src/AudioOutputSerialWAV.h index 5e26bbba..1aa027d6 100644 --- a/src/AudioOutputSerialWAV.h +++ b/src/AudioOutputSerialWAV.h @@ -1,21 +1,21 @@ /* - AudioOutputSerialWAV - Writes a mostly correct WAV file to the serial port - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioOutputSerialWAV + Writes a mostly correct WAV file to the serial port + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOOUTPUTSERIALWAV_H @@ -23,15 +23,14 @@ #include "AudioOutput.h" -class AudioOutputSerialWAV : public AudioOutput -{ - public: +class AudioOutputSerialWAV : public AudioOutput { +public: AudioOutputSerialWAV() {}; ~AudioOutputSerialWAV() {}; virtual bool begin() override; virtual bool ConsumeSample(int16_t sample[2]) override; virtual bool stop() override; - private: +private: int count; }; diff --git a/src/AudioOutputULP.cpp b/src/AudioOutputULP.cpp new file mode 100644 index 00000000..cf5a339a --- /dev/null +++ b/src/AudioOutputULP.cpp @@ -0,0 +1,276 @@ +/* + AudioOutputULP + Outputs to ESP32 DAC through the ULP, freeing I2S for other uses + + Copyright (C) 2020 Martin Laclaustra, based on bitluni's code + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef ESP32 + +#include "AudioOutputULP.h" + +#if CONFIG_IDF_TARGET_ESP32 + +#include +#include +#include +#include +#include +#include + +uint32_t create_I_WR_REG(uint32_t reg, uint32_t low_bit, uint32_t high_bit, uint32_t val) { + typedef union { + ulp_insn_t ulp_ins; + uint32_t ulp_bin; + } ulp_union; + const ulp_insn_t singleinstruction[] = {I_WR_REG(reg, low_bit, high_bit, val)}; + ulp_union recover_ins; + recover_ins.ulp_ins = singleinstruction[0]; + return (uint32_t)(recover_ins.ulp_bin); +} + +uint32_t create_I_BXI(uint32_t imm_pc) { + typedef union { + ulp_insn_t ulp_ins; + uint32_t ulp_bin; + } ulp_union; + const ulp_insn_t singleinstruction[] = {I_BXI(imm_pc)}; + ulp_union recover_ins; + recover_ins.ulp_ins = singleinstruction[0]; + return (uint32_t)(recover_ins.ulp_bin); +} + +bool AudioOutputULP::begin() { + if (!stereoOutput) { + waitingOddSample = false; + //totalSampleWords += 512; + //dacTableStart2 = dacTableStart1; + } + + //calculate the actual ULP clock + unsigned long rtc_8md256_period = rtc_clk_cal(RTC_CAL_8MD256, 1000); + // If that failed, (return 0) then we need to wait for calibration to happen... + while (!rtc_8md256_period) { + delay(20); // Don't hog the CPU + rtc_8md256_period = rtc_clk_cal(RTC_CAL_8MD256, 1000); + } + unsigned long rtc_fast_freq_hz = 1000000ULL * (1 << RTC_CLK_CAL_FRACT) * 256 / rtc_8md256_period; + + //initialize DACs + if (activeDACs & 1) { + dac_output_enable(DAC_CHANNEL_1); + dac_output_voltage(DAC_CHANNEL_1, 128); + } + if (activeDACs & 2) { + dac_output_enable(DAC_CHANNEL_2); + dac_output_voltage(DAC_CHANNEL_2, 128); + } + + int retAddress1 = 9; + int retAddress2 = 14; + + int loopCycles = 134; + int loopHalfCycles1 = 90; + int loopHalfCycles2 = 44; + + Serial.print("Real RTC clock: "); + Serial.println(rtc_fast_freq_hz); + + uint32_t dt = (rtc_fast_freq_hz / hertz) - loopCycles; + uint32_t dt2 = 0; + if (!stereoOutput) { + dt = (rtc_fast_freq_hz / hertz) - loopHalfCycles1; + dt2 = (rtc_fast_freq_hz / hertz) - loopHalfCycles2; + } + + Serial.print("dt: "); + Serial.println(dt); + + Serial.print("dt2: "); + Serial.println(dt2); + + const ulp_insn_t stereo[] = { + //reset offset register + I_MOVI(R3, 0), + //delay to get the right sampling rate + I_DELAY(dt), // 6 + dt + //reset sample index + I_MOVI(R0, 0), // 6 + //write the index back to memory for the main cpu + I_ST(R0, R3, indexAddress), // 8 + //load the samples + I_LD(R1, R0, bufferStart), // 8 + //mask the lower 8 bits + I_ANDI(R2, R1, 0x00ff), // 6 + //multiply by 2 + I_LSHI(R2, R2, 1), // 6 + //add start position + I_ADDI(R2, R2, dacTableStart1),// 6 + //jump to the dac opcode + I_BXR(R2), // 4 + //back from first dac + //delay between the two samples in mono rendering + I_DELAY(dt2), // 6 + dt2 + //mask the upper 8 bits + I_ANDI(R2, R1, 0xff00), // 6 + //shift the upper bits to right and multiply by 2 + I_RSHI(R2, R2, 8 - 1), // 6 + //add start position of second dac table + I_ADDI(R2, R2, dacTableStart2),// 6 + //jump to the dac opcode + I_BXR(R2), // 4 + //here we get back from writing the second sample + //load 0x8080 as sample + I_MOVI(R1, 0x8080), // 6 + //write 0x8080 in the sample buffer + I_ST(R1, R0, indexAddress), // 8 + //increment the sample index + I_ADDI(R0, R0, 1), // 6 + //if reached end of the buffer, jump relative to index reset + I_BGE(-16, totalSampleWords), // 4 + //wait to get the right sample rate (2 cycles more to compensate the index reset) + I_DELAY((unsigned int)dt + 2), // 8 + dt + //if not, jump absolute to where index is written to memory + I_BXI(3) // 4 + }; + // write io and jump back another 12 + 4 + 12 + 4 + + size_t load_addr = 0; + size_t size = sizeof(stereo) / sizeof(ulp_insn_t); + ulp_process_macros_and_load(load_addr, stereo, &size); + // this is how to get the opcodes + // for(int i = 0; i < size; i++) + // Serial.println(RTC_SLOW_MEM[i], HEX); + + //create DAC opcode tables + switch (activeDACs) { + case 1: + for (int i = 0; i < 256; i++) { + RTC_SLOW_MEM[dacTableStart1 + i * 2] = create_I_WR_REG(RTC_IO_PAD_DAC1_REG, 19, 26, i); //dac1: 0x1D4C0121 | (i << 10) + RTC_SLOW_MEM[dacTableStart1 + 1 + i * 2] = create_I_BXI(retAddress1); // 0x80000000 + retAddress1 * 4 + RTC_SLOW_MEM[dacTableStart2 + i * 2] = create_I_WR_REG(RTC_IO_PAD_DAC1_REG, 19, 26, i); //dac2: 0x1D4C0122 | (i << 10) + RTC_SLOW_MEM[dacTableStart2 + 1 + i * 2] = create_I_BXI(retAddress2); // 0x80000000 + retAddress2 * 4 + } + break; + case 2: + for (int i = 0; i < 256; i++) { + RTC_SLOW_MEM[dacTableStart1 + i * 2] = create_I_WR_REG(RTC_IO_PAD_DAC2_REG, 19, 26, i); //dac1: 0x1D4C0121 | (i << 10) + RTC_SLOW_MEM[dacTableStart1 + 1 + i * 2] = create_I_BXI(retAddress1); // 0x80000000 + retAddress1 * 4 + RTC_SLOW_MEM[dacTableStart2 + i * 2] = create_I_WR_REG(RTC_IO_PAD_DAC2_REG, 19, 26, i); //dac2: 0x1D4C0122 | (i << 10) + RTC_SLOW_MEM[dacTableStart2 + 1 + i * 2] = create_I_BXI(retAddress2); // 0x80000000 + retAddress2 * 4 + } + break; + case 3: + for (int i = 0; i < 256; i++) { + RTC_SLOW_MEM[dacTableStart1 + i * 2] = create_I_WR_REG(RTC_IO_PAD_DAC1_REG, 19, 26, i); //dac1: 0x1D4C0121 | (i << 10) + RTC_SLOW_MEM[dacTableStart1 + 1 + i * 2] = create_I_BXI(retAddress1); // 0x80000000 + retAddress1 * 4 + RTC_SLOW_MEM[dacTableStart2 + i * 2] = create_I_WR_REG(RTC_IO_PAD_DAC2_REG, 19, 26, i); //dac2: 0x1D4C0122 | (i << 10) + RTC_SLOW_MEM[dacTableStart2 + 1 + i * 2] = create_I_BXI(retAddress2); // 0x80000000 + retAddress2 * 4 + } + break; + } + + //set all samples to 128 (silence) + for (int i = 0; i < totalSampleWords; i++) { + RTC_SLOW_MEM[bufferStart + i] = 0x8080; + } + + //start + RTC_SLOW_MEM[indexAddress] = 0; + ulp_run(0); + + //wait until ULP starts using samples and the index of output sample advances + while (RTC_SLOW_MEM[indexAddress] == 0) { + delay(1); + } + + return true; +} + +bool AudioOutputULP::ConsumeSample(int16_t sample[2]) { + int16_t ms[2]; + ms[0] = sample[0]; + ms[1] = sample[1]; + MakeSampleStereo16(ms); + + // TODO: needs improvement (counting is different here with respect to ULP code) + int currentSample = RTC_SLOW_MEM[indexAddress] & 0xffff; + int currentWord = currentSample >> 1; + + for (int i = 0; i < 2; i++) { + ms[i] = ((ms[i] >> 8) + 128) & 0xff; + } + if (!stereoOutput) { // mix both channels + ms[0] = (uint16_t)(((uint32_t)((int32_t)(ms[0]) + (int32_t)(ms[1])) >> 1) & 0xff); + } + + if (waitingOddSample) { // always true for stereo because samples are consumed in pairs + if (lastFilledWord != currentWord) { // accept sample if writing index lastFilledWord has not reached index of output sample + unsigned int w; + if (stereoOutput) { + w = ms[0]; + w |= ms[1] << 8; + } else { + w = bufferedOddSample; + w |= ms[0] << 8; + bufferedOddSample = 128; + waitingOddSample = false; + } + RTC_SLOW_MEM[bufferStart + lastFilledWord] = w; + lastFilledWord++; + if (lastFilledWord == totalSampleWords) { + lastFilledWord = 0; + } + return true; + } else { + return false; + } + } else { + bufferedOddSample = ms[0]; + waitingOddSample = true; + return true; + } +} + + +bool AudioOutputULP::stop() { + audioLogger->printf_P(PSTR("\n\n\nstop\n\n\n")); + const ulp_insn_t stopulp[] = { + //stop the timer + I_END(), + //end the program + I_HALT() + }; + + size_t load_addr = 0; + size_t size = sizeof(stopulp) / sizeof(ulp_insn_t); + ulp_process_macros_and_load(load_addr, stopulp, &size); + + //start + ulp_run(0); + + if (activeDACs & 1) { + dac_output_voltage(DAC_CHANNEL_1, 128); + } + if (activeDACs & 2) { + dac_output_voltage(DAC_CHANNEL_2, 128); + } + + return true; +} + +#endif +#endif diff --git a/src/AudioOutputULP.h b/src/AudioOutputULP.h new file mode 100644 index 00000000..e8fe95ee --- /dev/null +++ b/src/AudioOutputULP.h @@ -0,0 +1,69 @@ +/* + AudioOutputULP + Outputs to ESP32 DAC through the ULP, freeing I2S for other uses + + Copyright (C) 2020 Martin Laclaustra, based on bitluni's code + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +// Instructions: +// AudioOutputULP out = new AudioOutputULP(); // stereo +// Connect left channel on pin 25 +// Connect right channel on pin 26 +// OR +// Connect mono channel on either of them (stereo samples are downmixed) +// AudioOutputULP out = new AudioOutputULP(1); // mono, only DAC 1 +// OR +// AudioOutputULP out = new AudioOutputULP(2); // mono, only DAC 2 + + +#ifndef _AUDIOOUTPUTULP_H +#define _AUDIOOUTPUTULP_H + +#include "AudioOutput.h" + +#ifdef ESP32 + +class AudioOutputULP : public AudioOutput { +public: + AudioOutputULP(int argActiveDACs = 3) { + if (argActiveDACs < 1 || argActiveDACs > 2) { + argActiveDACs = 3; + } activeDACs = argActiveDACs; + stereoOutput = activeDACs == 3; + }; + ~AudioOutputULP() {}; + virtual bool begin() override; + virtual bool ConsumeSample(int16_t sample[2]) override; + virtual bool stop() override; + enum : int { DAC1 = 1, DAC2 = 2 }; +private: + int lastFilledWord = 0; + uint8_t bufferedOddSample = 128; + bool waitingOddSample = true; // must be set to false for mono output + int activeDACs = 3; // 1:DAC1; 2:DAC2; 3:both; + bool stereoOutput = true; + const int opcodeCount = 20; + const uint32_t dacTableStart1 = 2048 - 512; + const uint32_t dacTableStart2 = dacTableStart1 - 512; + uint32_t totalSampleWords = 2048 - 512 - 512 - (opcodeCount + 1); // add 512 for mono + const int totalSamples = totalSampleWords * 2; + const uint32_t indexAddress = opcodeCount; + const uint32_t bufferStart = indexAddress + 1; +}; + +#endif + +#endif diff --git a/src/AudioStatus.h b/src/AudioStatus.h index 62e663f2..ac9723f0 100644 --- a/src/AudioStatus.h +++ b/src/AudioStatus.h @@ -1,21 +1,21 @@ /* - AudioStatus - Base class for Audio* status/metadata reporting - - Copyright (C) 2017 Earle F. Philhower, III - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . + AudioStatus + Base class for Audio* status/metadata reporting + + Copyright (C) 2017 Earle F. Philhower, III + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef _AUDIOSTATUS_H @@ -25,28 +25,48 @@ #include "AudioLogger.h" -class AudioStatus -{ - public: - AudioStatus() { ClearCBs(); }; +class AudioStatus { +public: + AudioStatus() { + ClearCBs(); + }; virtual ~AudioStatus() {}; - void ClearCBs() { mdFn = NULL; stFn = NULL; }; + void ClearCBs() { + mdFn = NULL; + stFn = NULL; + }; typedef void (*metadataCBFn)(void *cbData, const char *type, bool isUnicode, const char *str); - bool RegisterMetadataCB(metadataCBFn f, void *cbData) { mdFn = f; mdData = cbData; return true; } + bool RegisterMetadataCB(metadataCBFn f, void *cbData) { + mdFn = f; + mdData = cbData; + return true; + } // Returns a unique warning/error code, varying by the object. The string may be a PSTR, use _P functions! typedef void (*statusCBFn)(void *cbData, int code, const char *string); - bool RegisterStatusCB(statusCBFn f, void *cbData) { stFn = f; stData = cbData; return true; } + bool RegisterStatusCB(statusCBFn f, void *cbData) { + stFn = f; + stData = cbData; + return true; + } // Safely call the md function, if defined - inline void md(const char *type, bool isUnicode, const char *string) { if (mdFn) mdFn(mdData, type, isUnicode, string); } + inline void md(const char *type, bool isUnicode, const char *string) { + if (mdFn) { + mdFn(mdData, type, isUnicode, string); + } + } // Safely call the st function, if defined - inline void st(int code, const char *string) { if (stFn) stFn(stData, code, string); } + inline void st(int code, const char *string) { + if (stFn) { + stFn(stData, code, string); + } + } - private: +private: metadataCBFn mdFn; void *mdData; statusCBFn stFn; diff --git a/src/ESP8266Audio.h b/src/ESP8266Audio.h new file mode 100644 index 00000000..9fdeb912 --- /dev/null +++ b/src/ESP8266Audio.h @@ -0,0 +1,51 @@ +// Lazy "include all the things" header for simplicity. +// In general a user should only include the specific headers they need +// to miniimize build times. + +// Input stage +#include "AudioFileSourceBuffer.h" +#include "AudioFileSourceFATFS.h" +#include "AudioFileSourceFS.h" +#include "AudioFileSource.h" +#include "AudioFileSourceHTTPStream.h" +#include "AudioFileSourceICYStream.h" +#include "AudioFileSourceID3.h" +#include "AudioFileSourceLittleFS.h" +#include "AudioFileSourcePROGMEM.h" +#include "AudioFileSourceSD.h" +#include "AudioFileSourceSPIFFS.h" +#include "AudioFileSourceSPIRAMBuffer.h" +#include "AudioFileSourceSTDIO.h" + +// Misc. plumbing +#include "AudioFileStream.h" +#include "AudioLogger.h" +#include "AudioStatus.h" + +// Actual decode/audio generation logic +#include "AudioGeneratorAAC.h" +#include "AudioGeneratorFLAC.h" +#include "AudioGenerator.h" +#include "AudioGeneratorMIDI.h" +#include "AudioGeneratorMOD.h" +#include "AudioGeneratorMP3a.h" +#include "AudioGeneratorMP3.h" +#include "AudioGeneratorOpus.h" +#include "AudioGeneratorRTTTL.h" +#include "AudioGeneratorTalkie.h" +#include "AudioGeneratorWAV.h" + +// Render(output) sounds +#include "AudioOutputBuffer.h" +#include "AudioOutputFilterDecimate.h" +#include "AudioOutput.h" +#include "AudioOutputI2S.h" +#include "AudioOutputI2SNoDAC.h" +#include "AudioOutputPWM.h" +#include "AudioOutputMixer.h" +#include "AudioOutputNull.h" +#include "AudioOutputSerialWAV.h" +#include "AudioOutputSPDIF.h" +#include "AudioOutputSPIFFSWAV.h" +#include "AudioOutputSTDIO.h" +#include "AudioOutputULP.h" diff --git a/src/driver/SinglePinI2SDriver.cpp b/src/driver/SinglePinI2SDriver.cpp index 3d08efaf..243fc59f 100644 --- a/src/driver/SinglePinI2SDriver.cpp +++ b/src/driver/SinglePinI2SDriver.cpp @@ -1,283 +1,290 @@ /* - SinglePinI2SDriver - ESP8266Audio I2S Minimal driver - - Most of this code is taken and reworked from ESP8266 Arduino core, - which itsef is reworked from Espessif's I2S examples. - Original code is licensed under LGPL 2.1 or above - - Reasons for rewrite: - - Non-configurable size of DMA buffers - - We only need GPIO3 connected to I2SO_DATA - - No API to queue data from ISR. Callbacks are unusable - as i2s_write_* functions are not in IRAM and may re-enable + SinglePinI2SDriver + ESP8266Audio I2S Minimal driver + + Most of this code is taken and reworked from ESP8266 Arduino core, + which itself is reworked from Espessif's I2S examples. + Original code is licensed under LGPL 2.1 or above + + Reasons for rewrite: + - Non-configurable size of DMA buffers + - We only need GPIO3 connected to I2SO_DATA + - No API to queue data from ISR. Callbacks are unusable + as i2s_write_* functions are not in IRAM and may re-enable SLC interrupt before returning - - ISR overhead is not needed + - ISR overhead is not needed - Copyright (C) 2020 Ivan Kostoski + Copyright (C) 2020 Ivan Kostoski - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #if defined(ESP8266) #include "SinglePinI2SDriver.h" -SinglePinI2SDriver::~SinglePinI2SDriver() -{ - stopI2S(); - freeBuffers(bufCount); +SinglePinI2SDriver::~SinglePinI2SDriver() { + stopI2S(); + freeBuffers(bufCount); } -bool SinglePinI2SDriver::begin(uint8_t bufCount, uint16_t bufSize) -{ - if (bufCount < 4) return false; - if ((bufSize < 32) || (bufSize > 1020) || ((bufSize % 4) != 0)) return false; - - stopSLC(); - - if ((bufCount != this->bufCount) || (bufSize != this->bufSize)) freeBuffers(this->bufCount); - this->bufCount = bufCount; - this->bufSize = bufSize; - if (!allocateBuffers()) return false; - - zeroBuffers(); - configureSLC(); - startI2S(); - - // Send out at least one buffer, so we have valid address of - // finished descriptor in SLCRXEDA - head = &descriptors[0]; - head->owner = 1; - startSLC(); - while (!lastSentDescriptor()) delayMicroseconds(1); - // By here, SLC should be stalled (next descriptor owner is 0) - head->owner = 0; - head = head->next_link_ptr; - headPos = 0; - underflowCount = -1; - return true; +bool SinglePinI2SDriver::begin(uint8_t bufCount, uint16_t bufSize) { + if (bufCount < 4) { + return false; + } + if ((bufSize < 32) || (bufSize > 1020) || ((bufSize % 4) != 0)) { + return false; + } + + stopSLC(); + + if ((bufCount != this->bufCount) || (bufSize != this->bufSize)) { + freeBuffers(this->bufCount); + } + this->bufCount = bufCount; + this->bufSize = bufSize; + if (!allocateBuffers()) { + return false; + } + + zeroBuffers(); + configureSLC(); + startI2S(); + + // Send out at least one buffer, so we have valid address of + // finished descriptor in SLCRXEDA + head = &descriptors[0]; + head->owner = 1; + startSLC(); + while (!lastSentDescriptor()) { + delayMicroseconds(1); + } + // By here, SLC should be stalled (next descriptor owner is 0) + head->owner = 0; + head = head->next_link_ptr; + headPos = 0; + underflowCount = -1; + return true; }; -void SinglePinI2SDriver::stop() -{ - stopI2S(); +void SinglePinI2SDriver::stop() { + stopI2S(); } -bool SinglePinI2SDriver::allocateBuffers() -{ - // Allocate output (RXLINK) descriptors and bufferss - if (descriptors) return true; - descriptors = (SLCDecriptor*) calloc(bufCount, sizeof(SLCDecriptor)); - if (!descriptors) return false; - int allocated; - for (allocated = 0; allocated < bufCount; allocated++) { - uint32_t* buffer = (uint32_t*)malloc(bufSize * sizeof(uint32_t)); - if (!buffer) break; - auto descriptor = &descriptors[allocated]; - descriptor->eof = 1; // Needed for SLC to update SLCRXEDA - descriptor->datalen = bufSize * sizeof(uint32_t); - descriptor->blocksize = bufSize * sizeof(uint32_t); - descriptor->buf_ptr = buffer; - descriptor->next_link_ptr = &descriptors[(allocated+1) % bufCount]; - } - // Release memory if not all buffers were allocated - if (allocated < bufCount) { - freeBuffers(allocated); - return false; - } - zeroBuffers(); - return true; +bool SinglePinI2SDriver::allocateBuffers() { + // Allocate output (RXLINK) descriptors and bufferss + if (descriptors) { + return true; + } + descriptors = (SLCDecriptor*) calloc(bufCount, sizeof(SLCDecriptor)); + if (!descriptors) { + return false; + } + int allocated; + for (allocated = 0; allocated < bufCount; allocated++) { + uint32_t* buffer = (uint32_t*)malloc(bufSize * sizeof(uint32_t)); + if (!buffer) { + break; + } + auto descriptor = &descriptors[allocated]; + descriptor->eof = 1; // Needed for SLC to update SLCRXEDA + descriptor->datalen = bufSize * sizeof(uint32_t); + descriptor->blocksize = bufSize * sizeof(uint32_t); + descriptor->buf_ptr = buffer; + descriptor->next_link_ptr = &descriptors[(allocated + 1) % bufCount]; + } + // Release memory if not all buffers were allocated + if (allocated < bufCount) { + freeBuffers(allocated); + return false; + } + zeroBuffers(); + return true; } -void SinglePinI2SDriver::freeBuffers(int allocated) -{ - if (!descriptors) return; - while (--allocated >= 0) { - if (descriptors[allocated].buf_ptr) { - free(descriptors[allocated].buf_ptr); - descriptors[allocated].buf_ptr = NULL; +void SinglePinI2SDriver::freeBuffers(int allocated) { + if (!descriptors) { + return; } - } - free(descriptors); - descriptors = NULL; + while (--allocated >= 0) { + if (descriptors[allocated].buf_ptr) { + free(descriptors[allocated].buf_ptr); + descriptors[allocated].buf_ptr = NULL; + } + } + free(descriptors); + descriptors = NULL; } -void SinglePinI2SDriver::zeroBuffers() -{ - for(int i = 0; i < bufCount; i++) { - auto descriptor = &descriptors[i]; - ets_memset((void *)descriptor->buf_ptr, 0, bufSize * sizeof(uint32_t)); - } +void SinglePinI2SDriver::zeroBuffers() { + for (int i = 0; i < bufCount; i++) { + auto descriptor = &descriptors[i]; + ets_memset((void *)descriptor->buf_ptr, 0, bufSize * sizeof(uint32_t)); + } } -inline void SinglePinI2SDriver::advanceHead(const SLCDecriptor *lastSent) -{ - if (headPos >= bufSize) { - head->owner = 1; // Owned by SLC - head = head->next_link_ptr; - head->owner = 0; // Owned by CPU - headPos = 0; - // If SLC stopped, fill-up the buffers before (re)starting - if (isSLCStopped() && (head->next_link_ptr == lastSent)) { - underflowCount++; - startSLC(); +inline void SinglePinI2SDriver::advanceHead(const SLCDecriptor *lastSent) { + if (headPos >= bufSize) { + head->owner = 1; // Owned by SLC + head = head->next_link_ptr; + head->owner = 0; // Owned by CPU + headPos = 0; + // If SLC stopped, fill-up the buffers before (re)starting + if (isSLCStopped() && (head->next_link_ptr == lastSent)) { + underflowCount++; + startSLC(); + } } - } } -bool SinglePinI2SDriver::write(uint32_t sample) -{ - auto lastSent = lastSentDescriptor(); - if (isSLCRunning() && (lastSent->next_link_ptr == head)) return false; - head->buf_ptr[headPos++] = sample; - advanceHead(lastSent); - return true; +bool SinglePinI2SDriver::write(uint32_t sample) { + auto lastSent = lastSentDescriptor(); + if (isSLCRunning() && (lastSent->next_link_ptr == head)) { + return false; + } + head->buf_ptr[headPos++] = sample; + advanceHead(lastSent); + return true; }; -bool SinglePinI2SDriver::writeInterleaved(uint32_t samples[4]) -{ - auto lastSent = lastSentDescriptor(); - if (isSLCRunning() && (lastSent->next_link_ptr == head)) return false; - uint32_t* buf = head->buf_ptr; - buf[headPos++] = samples[1]; - buf[headPos++] = samples[0]; - buf[headPos++] = samples[3]; - buf[headPos++] = samples[2]; - advanceHead(lastSent); - return true; +bool SinglePinI2SDriver::writeInterleaved(uint32_t samples[4]) { + auto lastSent = lastSentDescriptor(); + if (isSLCRunning() && (lastSent->next_link_ptr == head)) { + return false; + } + uint32_t* buf = head->buf_ptr; + buf[headPos++] = samples[1]; + buf[headPos++] = samples[0]; + buf[headPos++] = samples[3]; + buf[headPos++] = samples[2]; + advanceHead(lastSent); + return true; }; -void SinglePinI2SDriver::configureSLC() -{ - ETS_SLC_INTR_DISABLE(); - // Reset SLC, clear interrupts - SLCC0 |= SLCRXLR | SLCTXLR; - SLCC0 &= ~(SLCRXLR | SLCTXLR); - SLCIC = 0xFFFFFFFF; - // Configure SLC DMA in mode 1 - SLCC0 &= ~(SLCMM << SLCM); - SLCC0 |= (1 << SLCM); - SLCRXDC |= SLCBINR | SLCBTNR; - SLCRXDC &= ~(SLCBRXFE | SLCBRXEM | SLCBRXFM); - // RXLINK is output DMA, but TXLINK must be configured with valid descriptr - SLCTXL &= ~(SLCTXLAM << SLCTXLA); - SLCRXL &= ~(SLCRXLAM << SLCRXLA); - SLCTXL |= (uint32)&descriptors[0] << SLCTXLA; - SLCRXL |= (uint32)&descriptors[0] << SLCRXLA; - // Not setting up interrupts. Not starting DMA here +void SinglePinI2SDriver::configureSLC() { + ETS_SLC_INTR_DISABLE(); + // Reset SLC, clear interrupts + SLCC0 |= SLCRXLR | SLCTXLR; + SLCC0 &= ~(SLCRXLR | SLCTXLR); + SLCIC = 0xFFFFFFFF; + // Configure SLC DMA in mode 1 + SLCC0 &= ~(SLCMM << SLCM); + SLCC0 |= (1 << SLCM); + SLCRXDC |= SLCBINR | SLCBTNR; + SLCRXDC &= ~(SLCBRXFE | SLCBRXEM | SLCBRXFM); + // RXLINK is output DMA, but TXLINK must be configured with valid descriptr + SLCTXL &= ~(SLCTXLAM << SLCTXLA); + SLCRXL &= ~(SLCRXLAM << SLCRXLA); + SLCTXL |= (uint32)&descriptors[0] << SLCTXLA; + SLCRXL |= (uint32)&descriptors[0] << SLCRXLA; + // Not setting up interrupts. Not starting DMA here } -void SinglePinI2SDriver::stopSLC() -{ - // Stop SLC, reset descriptors and clear interrupts - ETS_SLC_INTR_DISABLE(); - SLCTXL |= SLCTXLE; - SLCRXL |= SLCRXLE; - SLCTXL &= ~(SLCTXLAM << SLCTXLA); - SLCRXL &= ~(SLCRXLAM << SLCRXLA); - SLCIC = 0xFFFFFFFF; +void SinglePinI2SDriver::stopSLC() { + // Stop SLC, reset descriptors and clear interrupts + ETS_SLC_INTR_DISABLE(); + SLCTXL |= SLCTXLE; + SLCRXL |= SLCRXLE; + SLCTXL &= ~(SLCTXLAM << SLCTXLA); + SLCRXL &= ~(SLCRXLAM << SLCRXLA); + SLCIC = 0xFFFFFFFF; } -void SinglePinI2SDriver::setDividers(uint8_t div1, uint8_t div2) -{ - // Ensure dividers fit in bit fields - div1 &= I2SBDM; - div2 &= I2SCDM; - // trans master(active low), recv master(active_low), !bits mod(==16 bits/chanel), clear clock dividers - I2SC &= ~(I2STSM | I2SRSM | (I2SBMM << I2SBM) | (I2SBDM << I2SBD) | (I2SCDM << I2SCD)); - // I2SRF = Send/recv right channel first - // I2SMR = MSB recv/xmit first - // I2SRMS, I2STMS = We don't really care about WS delay here - // div1, div2 = Set I2S WS clock frequency. BCLK seems to be generated from 32x this - I2SC |= I2SRF | I2SMR | I2SRMS | I2STMS | (div1 << I2SBD) | (div2 << I2SCD); +void SinglePinI2SDriver::setDividers(uint8_t div1, uint8_t div2) { + // Ensure dividers fit in bit fields + div1 &= I2SBDM; + div2 &= I2SCDM; + // trans master(active low), recv master(active_low), !bits mod(==16 bits/channel), clear clock dividers + I2SC &= ~(I2STSM | I2SRSM | (I2SBMM << I2SBM) | (I2SBDM << I2SBD) | (I2SCDM << I2SCD)); + // I2SRF = Send/recv right channel first + // I2SMR = MSB recv/xmit first + // I2SRMS, I2STMS = We don't really care about WS delay here + // div1, div2 = Set I2S WS clock frequency. BCLK seems to be generated from 32x this + I2SC |= I2SRF | I2SMR | I2SRMS | I2STMS | (div1 << I2SBD) | (div2 << I2SCD); } -void SinglePinI2SDriver::setRate(const uint32_t rateHz) -{ - if (rateHz == currentRate) return; - currentRate = rateHz; - - uint32_t scaledBaseFreq = I2SBASEFREQ / 32; - float bestDelta = scaledBaseFreq; - uint8_t sbdDivBest=1; - uint8_t scdDivBest=1; - for (uint8_t i = 1; i < 64; i++) { - for (uint8_t j = i; j < 64; j++) { - float delta = fabs(((float)scaledBaseFreq/i/j) - rateHz); - if (delta < bestDelta){ - bestDelta = delta; - sbdDivBest = i; - scdDivBest = j; - } +void SinglePinI2SDriver::setRate(const uint32_t rateHz) { + if (rateHz == currentRate) { + return; + } + currentRate = rateHz; + + uint32_t scaledBaseFreq = I2SBASEFREQ / 32; + float bestDelta = scaledBaseFreq; + uint8_t sbdDivBest = 1; + uint8_t scdDivBest = 1; + for (uint8_t i = 1; i < 64; i++) { + for (uint8_t j = i; j < 64; j++) { + float delta = fabs(((float)scaledBaseFreq / i / j) - rateHz); + if (delta < bestDelta) { + bestDelta = delta; + sbdDivBest = i; + scdDivBest = j; + } + } } - } - setDividers(sbdDivBest, scdDivBest); + setDividers(sbdDivBest, scdDivBest); } -float SinglePinI2SDriver::getActualRate() -{ - return (float)I2SBASEFREQ/32/((I2SC>>I2SBD) & I2SBDM)/((I2SC >> I2SCD) & I2SCDM); +float SinglePinI2SDriver::getActualRate() { + return (float)I2SBASEFREQ / 32 / ((I2SC >> I2SBD) & I2SBDM) / ((I2SC >> I2SCD) & I2SCDM); } -void SinglePinI2SDriver::startI2S() -{ - // Setup only I2S SD pin for output - pinMode(I2SO_DATA, FUNCTION_1); - I2S_CLK_ENABLE(); - // Reset I2S - I2SIC = 0x3F; - I2SIE = 0; - I2SC &= ~(I2SRST); - I2SC |= I2SRST; - I2SC &= ~(I2SRST); - // I2STXFMM, I2SRXFMM=0 => 16-bit, dual channel data - I2SFC &= ~(I2SDE | (I2STXFMM << I2STXFM) | (I2SRXFMM << I2SRXFM)); - I2SFC |= I2SDE; // Enable DMA - // I2STXCMM, I2SRXCMM=0 => Dual channel mode, RX/TX CHAN_MOD=0 - I2SCC &= ~((I2STXCMM << I2STXCM) | (I2SRXCMM << I2SRXCM)); - // Set dividers to something resonable - currentRate = 0; - setRate(44100); - // Start I2S peripheral - I2SC |= I2STXS; +void SinglePinI2SDriver::startI2S() { + // Setup only I2S SD pin for output + pinMode(I2SO_DATA, FUNCTION_1); + I2S_CLK_ENABLE(); + // Reset I2S + I2SIC = 0x3F; + I2SIE = 0; + I2SC &= ~(I2SRST); + I2SC |= I2SRST; + I2SC &= ~(I2SRST); + // I2STXFMM, I2SRXFMM=0 => 16-bit, dual channel data + I2SFC &= ~(I2SDE | (I2STXFMM << I2STXFM) | (I2SRXFMM << I2SRXFM)); + I2SFC |= I2SDE; // Enable DMA + // I2STXCMM, I2SRXCMM=0 => Dual channel mode, RX/TX CHAN_MOD=0 + I2SCC &= ~((I2STXCMM << I2STXCM) | (I2SRXCMM << I2SRXCM)); + // Set dividers to something reasonable + currentRate = 0; + setRate(44100); + // Start I2S peripheral + I2SC |= I2STXS; } -void SinglePinI2SDriver::stopI2S() -{ - // Disable any I2S send or receive - I2SC &= ~(I2STXS | I2SRXS); - // Reset I2S - I2SC &= ~(I2SRST); - I2SC |= I2SRST; - I2SC &= ~(I2SRST); - - stopSLC(); - // Reconnect RX0 ? - //pinMode(I2SO_DATA, SPECIAL); +void SinglePinI2SDriver::stopI2S() { + // Disable any I2S send or receive + I2SC &= ~(I2STXS | I2SRXS); + // Reset I2S + I2SC &= ~(I2SRST); + I2SC |= I2SRST; + I2SC &= ~(I2SRST); + + stopSLC(); + // Reconnect RX0 ? + //pinMode(I2SO_DATA, SPECIAL); } -int SinglePinI2SDriver::getUnderflowCount() -{ - int count = underflowCount; - underflowCount = 0; - return count; +int SinglePinI2SDriver::getUnderflowCount() { + int count = underflowCount; + underflowCount = 0; + return count; } // Global instance SinglePinI2SDriver I2SDriver; -#endif // defined(ESP8266) \ No newline at end of file +#endif // defined(ESP8266) diff --git a/src/driver/SinglePinI2SDriver.h b/src/driver/SinglePinI2SDriver.h index e5ad8c85..ad280bb0 100644 --- a/src/driver/SinglePinI2SDriver.h +++ b/src/driver/SinglePinI2SDriver.h @@ -1,22 +1,22 @@ /* - SinglePinI2SDriver - ESP8266Audio I2S Minimal driver + SinglePinI2SDriver + ESP8266Audio I2S Minimal driver - Copyright (C) 2020 Ivan Kostoski + Copyright (C) 2020 Ivan Kostoski - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once @@ -28,19 +28,18 @@ #include "i2s_reg.h" struct SLCDecriptor { - uint32_t blocksize : 12; - uint32_t datalen : 12; - uint32_t unused : 5; - uint32_t sub_sof : 1; - uint32_t eof : 1; - volatile uint32_t owner : 1; - uint32_t* buf_ptr; - SLCDecriptor* next_link_ptr; + uint32_t blocksize : 12; + uint32_t datalen : 12; + uint32_t unused : 5; + uint32_t sub_sof : 1; + uint32_t eof : 1; + volatile uint32_t owner : 1; + uint32_t* buf_ptr; + SLCDecriptor* next_link_ptr; }; -class SinglePinI2SDriver -{ - public: +class SinglePinI2SDriver { +public: enum : uint8_t { I2SO_DATA = 3 }; // GPIO3/RX0 SinglePinI2SDriver(): descriptors(NULL), bufCount(0), bufSize(0) {}; @@ -54,7 +53,7 @@ class SinglePinI2SDriver bool writeInterleaved(uint32_t samples[4]); int getUnderflowCount(); - protected: +protected: bool allocateBuffers(); void freeBuffers(int allocated); void zeroBuffers(); @@ -73,10 +72,19 @@ class SinglePinI2SDriver int underflowCount; // (Re)Start transmission ("TX" DMA always needed to be enabled) - static inline void startSLC() { SLCTXL |= SLCTXLS; SLCRXL |= SLCRXLS; } - static inline uint32_t isSLCRunning() { return (SLCRXS & SLCRXF); }; - static inline uint32_t isSLCStopped() { return (SLCRXS & SLCRXE); }; - static inline SLCDecriptor *lastSentDescriptor() { return (SLCDecriptor*)SLCRXEDA; } + static inline void startSLC() { + SLCTXL |= SLCTXLS; + SLCRXL |= SLCRXLS; + } + static inline uint32_t isSLCRunning() { + return (SLCRXS & SLCRXF); + }; + static inline uint32_t isSLCStopped() { + return (SLCRXS & SLCRXE); + }; + static inline SLCDecriptor *lastSentDescriptor() { + return (SLCDecriptor*)SLCRXEDA; + } }; // Global instance diff --git a/src/libflac/FLAC/assert.h b/src/libflac/FLAC/assert.h index 55b34777..3a695c5a 100644 --- a/src/libflac/FLAC/assert.h +++ b/src/libflac/FLAC/assert.h @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2001-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__ASSERT_H #define FLAC__ASSERT_H diff --git a/src/libflac/FLAC/callback.h b/src/libflac/FLAC/callback.h index 38e23002..a30c8058 100644 --- a/src/libflac/FLAC/callback.h +++ b/src/libflac/FLAC/callback.h @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2004-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2004-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__CALLBACK_H #define FLAC__CALLBACK_H @@ -37,143 +37,143 @@ #include /* for size_t */ /** \file include/FLAC/callback.h - * - * \brief - * This module defines the structures for describing I/O callbacks - * to the other FLAC interfaces. - * - * See the detailed documentation for callbacks in the - * \link flac_callbacks callbacks \endlink module. - */ + + \brief + This module defines the structures for describing I/O callbacks + to the other FLAC interfaces. + + See the detailed documentation for callbacks in the + \link flac_callbacks callbacks \endlink module. +*/ /** \defgroup flac_callbacks FLAC/callback.h: I/O callback structures - * \ingroup flac - * - * \brief - * This module defines the structures for describing I/O callbacks - * to the other FLAC interfaces. - * - * The purpose of the I/O callback functions is to create a common way - * for the metadata interfaces to handle I/O. - * - * Originally the metadata interfaces required filenames as the way of - * specifying FLAC files to operate on. This is problematic in some - * environments so there is an additional option to specify a set of - * callbacks for doing I/O on the FLAC file, instead of the filename. - * - * In addition to the callbacks, a FLAC__IOHandle type is defined as an - * opaque structure for a data source. - * - * The callback function prototypes are similar (but not identical) to the - * stdio functions fread, fwrite, fseek, ftell, feof, and fclose. If you use - * stdio streams to implement the callbacks, you can pass fread, fwrite, and - * fclose anywhere a FLAC__IOCallback_Read, FLAC__IOCallback_Write, or - * FLAC__IOCallback_Close is required, and a FILE* anywhere a FLAC__IOHandle - * is required. \warning You generally CANNOT directly use fseek or ftell - * for FLAC__IOCallback_Seek or FLAC__IOCallback_Tell since on most systems - * these use 32-bit offsets and FLAC requires 64-bit offsets to deal with - * large files. You will have to find an equivalent function (e.g. ftello), - * or write a wrapper. The same is true for feof() since this is usually - * implemented as a macro, not as a function whose address can be taken. - * - * \{ - */ + \ingroup flac + + \brief + This module defines the structures for describing I/O callbacks + to the other FLAC interfaces. + + The purpose of the I/O callback functions is to create a common way + for the metadata interfaces to handle I/O. + + Originally the metadata interfaces required filenames as the way of + specifying FLAC files to operate on. This is problematic in some + environments so there is an additional option to specify a set of + callbacks for doing I/O on the FLAC file, instead of the filename. + + In addition to the callbacks, a FLAC__IOHandle type is defined as an + opaque structure for a data source. + + The callback function prototypes are similar (but not identical) to the + stdio functions fread, fwrite, fseek, ftell, feof, and fclose. If you use + stdio streams to implement the callbacks, you can pass fread, fwrite, and + fclose anywhere a FLAC__IOCallback_Read, FLAC__IOCallback_Write, or + FLAC__IOCallback_Close is required, and a FILE* anywhere a FLAC__IOHandle + is required. \warning You generally CANNOT directly use fseek or ftell + for FLAC__IOCallback_Seek or FLAC__IOCallback_Tell since on most systems + these use 32-bit offsets and FLAC requires 64-bit offsets to deal with + large files. You will have to find an equivalent function (e.g. ftello), + or write a wrapper. The same is true for feof() since this is usually + implemented as a macro, not as a function whose address can be taken. + + \{ +*/ #ifdef __cplusplus extern "C" { #endif /** This is the opaque handle type used by the callbacks. Typically - * this is a \c FILE* or address of a file descriptor. - */ + this is a \c FILE* or address of a file descriptor. +*/ typedef void* FLAC__IOHandle; /** Signature for the read callback. - * The signature and semantics match POSIX fread() implementations - * and can generally be used interchangeably. - * - * \param ptr The address of the read buffer. - * \param size The size of the records to be read. - * \param nmemb The number of records to be read. - * \param handle The handle to the data source. - * \retval size_t - * The number of records read. - */ -typedef size_t (*FLAC__IOCallback_Read) (void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle); + The signature and semantics match POSIX fread() implementations + and can generally be used interchangeably. + + \param ptr The address of the read buffer. + \param size The size of the records to be read. + \param nmemb The number of records to be read. + \param handle The handle to the data source. + \retval size_t + The number of records read. +*/ +typedef size_t (*FLAC__IOCallback_Read)(void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle); /** Signature for the write callback. - * The signature and semantics match POSIX fwrite() implementations - * and can generally be used interchangeably. - * - * \param ptr The address of the write buffer. - * \param size The size of the records to be written. - * \param nmemb The number of records to be written. - * \param handle The handle to the data source. - * \retval size_t - * The number of records written. - */ -typedef size_t (*FLAC__IOCallback_Write) (const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle); + The signature and semantics match POSIX fwrite() implementations + and can generally be used interchangeably. + + \param ptr The address of the write buffer. + \param size The size of the records to be written. + \param nmemb The number of records to be written. + \param handle The handle to the data source. + \retval size_t + The number of records written. +*/ +typedef size_t (*FLAC__IOCallback_Write)(const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle); /** Signature for the seek callback. - * The signature and semantics mostly match POSIX fseek() WITH ONE IMPORTANT - * EXCEPTION: the offset is a 64-bit type whereas fseek() is generally 'long' - * and 32-bits wide. - * - * \param handle The handle to the data source. - * \param offset The new position, relative to \a whence - * \param whence \c SEEK_SET, \c SEEK_CUR, or \c SEEK_END - * \retval int - * \c 0 on success, \c -1 on error. - */ -typedef int (*FLAC__IOCallback_Seek) (FLAC__IOHandle handle, FLAC__int64 offset, int whence); + The signature and semantics mostly match POSIX fseek() WITH ONE IMPORTANT + EXCEPTION: the offset is a 64-bit type whereas fseek() is generally 'long' + and 32-bits wide. + + \param handle The handle to the data source. + \param offset The new position, relative to \a whence + \param whence \c SEEK_SET, \c SEEK_CUR, or \c SEEK_END + \retval int + \c 0 on success, \c -1 on error. +*/ +typedef int (*FLAC__IOCallback_Seek)(FLAC__IOHandle handle, FLAC__int64 offset, int whence); /** Signature for the tell callback. - * The signature and semantics mostly match POSIX ftell() WITH ONE IMPORTANT - * EXCEPTION: the offset is a 64-bit type whereas ftell() is generally 'long' - * and 32-bits wide. - * - * \param handle The handle to the data source. - * \retval FLAC__int64 - * The current position on success, \c -1 on error. - */ -typedef FLAC__int64 (*FLAC__IOCallback_Tell) (FLAC__IOHandle handle); + The signature and semantics mostly match POSIX ftell() WITH ONE IMPORTANT + EXCEPTION: the offset is a 64-bit type whereas ftell() is generally 'long' + and 32-bits wide. + + \param handle The handle to the data source. + \retval FLAC__int64 + The current position on success, \c -1 on error. +*/ +typedef FLAC__int64(*FLAC__IOCallback_Tell)(FLAC__IOHandle handle); /** Signature for the EOF callback. - * The signature and semantics mostly match POSIX feof() but WATCHOUT: - * on many systems, feof() is a macro, so in this case a wrapper function - * must be provided instead. - * - * \param handle The handle to the data source. - * \retval int - * \c 0 if not at end of file, nonzero if at end of file. - */ -typedef int (*FLAC__IOCallback_Eof) (FLAC__IOHandle handle); + The signature and semantics mostly match POSIX feof() but WATCHOUT: + on many systems, feof() is a macro, so in this case a wrapper function + must be provided instead. + + \param handle The handle to the data source. + \retval int + \c 0 if not at end of file, nonzero if at end of file. +*/ +typedef int (*FLAC__IOCallback_Eof)(FLAC__IOHandle handle); /** Signature for the close callback. - * The signature and semantics match POSIX fclose() implementations - * and can generally be used interchangeably. - * - * \param handle The handle to the data source. - * \retval int - * \c 0 on success, \c EOF on error. - */ -typedef int (*FLAC__IOCallback_Close) (FLAC__IOHandle handle); + The signature and semantics match POSIX fclose() implementations + and can generally be used interchangeably. + + \param handle The handle to the data source. + \retval int + \c 0 on success, \c EOF on error. +*/ +typedef int (*FLAC__IOCallback_Close)(FLAC__IOHandle handle); /** A structure for holding a set of callbacks. - * Each FLAC interface that requires a FLAC__IOCallbacks structure will - * describe which of the callbacks are required. The ones that are not - * required may be set to NULL. - * - * If the seek requirement for an interface is optional, you can signify that - * a data source is not seekable by setting the \a seek field to \c NULL. - */ + Each FLAC interface that requires a FLAC__IOCallbacks structure will + describe which of the callbacks are required. The ones that are not + required may be set to NULL. + + If the seek requirement for an interface is optional, you can signify that + a data source is not seekable by setting the \a seek field to \c NULL. +*/ typedef struct { - FLAC__IOCallback_Read read; - FLAC__IOCallback_Write write; - FLAC__IOCallback_Seek seek; - FLAC__IOCallback_Tell tell; - FLAC__IOCallback_Eof eof; - FLAC__IOCallback_Close close; + FLAC__IOCallback_Read read; + FLAC__IOCallback_Write write; + FLAC__IOCallback_Seek seek; + FLAC__IOCallback_Tell tell; + FLAC__IOCallback_Eof eof; + FLAC__IOCallback_Close close; } FLAC__IOCallbacks; /* \} */ diff --git a/src/libflac/FLAC/export.h b/src/libflac/FLAC/export.h index 3e3e7648..01c6747c 100644 --- a/src/libflac/FLAC/export.h +++ b/src/libflac/FLAC/export.h @@ -1,60 +1,60 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2000-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__EXPORT_H #define FLAC__EXPORT_H /** \file include/FLAC/export.h - * - * \brief - * This module contains \#defines and symbols for exporting function - * calls, and providing version information and compiled-in features. - * - * See the \link flac_export export \endlink module. - */ + + \brief + This module contains \#defines and symbols for exporting function + calls, and providing version information and compiled-in features. + + See the \link flac_export export \endlink module. +*/ /** \defgroup flac_export FLAC/export.h: export symbols - * \ingroup flac - * - * \brief - * This module contains \#defines and symbols for exporting function - * calls, and providing version information and compiled-in features. - * - * If you are compiling with MSVC and will link to the static library - * (libFLAC.lib) you should define FLAC__NO_DLL in your project to - * make sure the symbols are exported properly. - * - * \{ - */ + \ingroup flac + + \brief + This module contains \#defines and symbols for exporting function + calls, and providing version information and compiled-in features. + + If you are compiling with MSVC and will link to the static library + (libFLAC.lib) you should define FLAC__NO_DLL in your project to + make sure the symbols are exported properly. + + \{ +*/ #if defined(FLAC__NO_DLL) #define FLAC_API @@ -75,8 +75,8 @@ #endif /** These \#defines will mirror the libtool-based library version number, see - * http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning - */ + http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning +*/ #define FLAC_API_VERSION_CURRENT 11 #define FLAC_API_VERSION_REVISION 0 /**< see above */ #define FLAC_API_VERSION_AGE 3 /**< see above */ diff --git a/src/libflac/FLAC/format.h b/src/libflac/FLAC/format.h index 769ab8af..3e2dc06c 100644 --- a/src/libflac/FLAC/format.h +++ b/src/libflac/FLAC/format.h @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2000-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__FORMAT_H #define FLAC__FORMAT_H @@ -41,47 +41,47 @@ extern "C" { #endif /** \file include/FLAC/format.h - * - * \brief - * This module contains structure definitions for the representation - * of FLAC format components in memory. These are the basic - * structures used by the rest of the interfaces. - * - * See the detailed documentation in the - * \link flac_format format \endlink module. - */ + + \brief + This module contains structure definitions for the representation + of FLAC format components in memory. These are the basic + structures used by the rest of the interfaces. + + See the detailed documentation in the + \link flac_format format \endlink module. +*/ /** \defgroup flac_format FLAC/format.h: format components - * \ingroup flac - * - * \brief - * This module contains structure definitions for the representation - * of FLAC format components in memory. These are the basic - * structures used by the rest of the interfaces. - * - * First, you should be familiar with the - * FLAC format. Many of the values here - * follow directly from the specification. As a user of libFLAC, the - * interesting parts really are the structures that describe the frame - * header and metadata blocks. - * - * The format structures here are very primitive, designed to store - * information in an efficient way. Reading information from the - * structures is easy but creating or modifying them directly is - * more complex. For the most part, as a user of a library, editing - * is not necessary; however, for metadata blocks it is, so there are - * convenience functions provided in the \link flac_metadata metadata - * module \endlink to simplify the manipulation of metadata blocks. - * - * \note - * It's not the best convention, but symbols ending in _LEN are in bits - * and _LENGTH are in bytes. _LENGTH symbols are \#defines instead of - * global variables because they are usually used when declaring byte - * arrays and some compilers require compile-time knowledge of array - * sizes when declared on the stack. - * - * \{ - */ + \ingroup flac + + \brief + This module contains structure definitions for the representation + of FLAC format components in memory. These are the basic + structures used by the rest of the interfaces. + + First, you should be familiar with the + FLAC format. Many of the values here + follow directly from the specification. As a user of libFLAC, the + interesting parts really are the structures that describe the frame + header and metadata blocks. + + The format structures here are very primitive, designed to store + information in an efficient way. Reading information from the + structures is easy but creating or modifying them directly is + more complex. For the most part, as a user of a library, editing + is not necessary; however, for metadata blocks it is, so there are + convenience functions provided in the \link flac_metadata metadata + module \endlink to simplify the manipulation of metadata blocks. + + \note + It's not the best convention, but symbols ending in _LEN are in bits + and _LENGTH are in bytes. _LENGTH symbols are \#defines instead of + global variables because they are usually used when declaring byte + arrays and some compilers require compile-time knowledge of array + sizes when declared on the stack. + + \{ +*/ /* @@ -99,7 +99,7 @@ extern "C" { #define FLAC__MAX_BLOCK_SIZE (65535u) /** The maximum block size, in samples, permitted by the FLAC subset for - * sample rates up to 48kHz. */ + sample rates up to 48kHz. */ #define FLAC__SUBSET_MAX_BLOCK_SIZE_48000HZ (4608u) /** The maximum number of channels permitted by the format. */ @@ -112,36 +112,36 @@ extern "C" { #define FLAC__MAX_BITS_PER_SAMPLE (32u) /** The maximum sample resolution permitted by libFLAC. - * - * \warning - * FLAC__MAX_BITS_PER_SAMPLE is the limit of the FLAC format. However, - * the reference encoder/decoder is currently limited to 24 bits because - * of prevalent 32-bit math, so make sure and use this value when - * appropriate. - */ + + \warning + FLAC__MAX_BITS_PER_SAMPLE is the limit of the FLAC format. However, + the reference encoder/decoder is currently limited to 24 bits because + of prevalent 32-bit math, so make sure and use this value when + appropriate. +*/ #define FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE (24u) /** The maximum sample rate permitted by the format. The value is - * ((2 ^ 16) - 1) * 10; see FLAC format - * as to why. - */ + ((2 ^ 16) - 1) * 10; see FLAC format + as to why. +*/ #define FLAC__MAX_SAMPLE_RATE (655350u) /** The maximum LPC order permitted by the format. */ #define FLAC__MAX_LPC_ORDER (32u) /** The maximum LPC order permitted by the FLAC subset for sample rates - * up to 48kHz. */ + up to 48kHz. */ #define FLAC__SUBSET_MAX_LPC_ORDER_48000HZ (12u) /** The minimum quantized linear predictor coefficient precision - * permitted by the format. - */ + permitted by the format. +*/ #define FLAC__MIN_QLP_COEFF_PRECISION (5u) /** The maximum quantized linear predictor coefficient precision - * permitted by the format. - */ + permitted by the format. +*/ #define FLAC__MAX_QLP_COEFF_PRECISION (15u) /** The maximum order of the fixed predictors permitted by the format. */ @@ -154,25 +154,25 @@ extern "C" { #define FLAC__SUBSET_MAX_RICE_PARTITION_ORDER (8u) /** The version string of the release, stamped onto the libraries and binaries. - * - * \note - * This does not correspond to the shared library version number, which - * is used to determine binary compatibility. - */ + + \note + This does not correspond to the shared library version number, which + is used to determine binary compatibility. +*/ extern FLAC_API const char *FLAC__VERSION_STRING; /** The vendor string inserted by the encoder into the VORBIS_COMMENT block. - * This is a NUL-terminated ASCII string; when inserted into the - * VORBIS_COMMENT the trailing null is stripped. - */ + This is a NUL-terminated ASCII string; when inserted into the + VORBIS_COMMENT the trailing null is stripped. +*/ extern FLAC_API const char *FLAC__VENDOR_STRING; /** The byte string representation of the beginning of a FLAC stream. */ extern FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4]; /* = "fLaC" */ /** The 32-bit integer big-endian representation of the beginning of - * a FLAC stream. - */ + a FLAC stream. +*/ extern FLAC_API const uint32_t FLAC__STREAM_SYNC; /* = 0x664C6143 */ /** The length of the FLAC signature in bits. */ @@ -183,60 +183,60 @@ extern FLAC_API const uint32_t FLAC__STREAM_SYNC_LEN; /* = 32 bits */ /***************************************************************************** - * - * Subframe structures - * + + Subframe structures + *****************************************************************************/ /*****************************************************************************/ /** An enumeration of the available entropy coding methods. */ typedef enum { - FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE = 0, - /**< Residual is coded by partitioning into contexts, each with it's own - * 4-bit Rice parameter. */ + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE = 0, + /** < Residual is coded by partitioning into contexts, each with it's own + 4-bit Rice parameter. */ - FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 = 1 - /**< Residual is coded by partitioning into contexts, each with it's own - * 5-bit Rice parameter. */ + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 = 1 + /** < Residual is coded by partitioning into contexts, each with it's own + 5-bit Rice parameter. */ } FLAC__EntropyCodingMethodType; /** Maps a FLAC__EntropyCodingMethodType to a C string. - * - * Using a FLAC__EntropyCodingMethodType as the index to this array will - * give the string equivalent. The contents should not be modified. - */ + + Using a FLAC__EntropyCodingMethodType as the index to this array will + give the string equivalent. The contents should not be modified. +*/ extern FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[]; /** Contents of a Rice partitioned residual - */ +*/ typedef struct { - uint32_t *parameters; - /**< The Rice parameters for each context. */ + uint32_t *parameters; + /**< The Rice parameters for each context. */ - uint32_t *raw_bits; - /**< Widths for escape-coded partitions. Will be non-zero for escaped - * partitions and zero for unescaped partitions. - */ + uint32_t *raw_bits; + /** < Widths for escape-coded partitions. Will be non-zero for escaped + partitions and zero for unescaped partitions. + */ - uint32_t capacity_by_order; - /**< The capacity of the \a parameters and \a raw_bits arrays - * specified as an order, i.e. the number of array elements - * allocated is 2 ^ \a capacity_by_order. - */ + uint32_t capacity_by_order; + /** < The capacity of the \a parameters and \a raw_bits arrays + specified as an order, i.e. the number of array elements + allocated is 2 ^ \a capacity_by_order. + */ } FLAC__EntropyCodingMethod_PartitionedRiceContents; /** Header for a Rice partitioned residual. (c.f. format specification) - */ +*/ typedef struct { - uint32_t order; - /**< The partition order, i.e. # of contexts = 2 ^ \a order. */ + uint32_t order; + /**< The partition order, i.e. # of contexts = 2 ^ \a order. */ - const FLAC__EntropyCodingMethod_PartitionedRiceContents *contents; - /**< The context's Rice parameters and/or raw bits. */ + const FLAC__EntropyCodingMethod_PartitionedRiceContents *contents; + /**< The context's Rice parameters and/or raw bits. */ } FLAC__EntropyCodingMethod_PartitionedRice; @@ -251,12 +251,12 @@ extern FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESC /**< == (1<format specification) - */ +*/ typedef struct { - FLAC__EntropyCodingMethodType type; - union { - FLAC__EntropyCodingMethod_PartitionedRice partitioned_rice; - } data; + FLAC__EntropyCodingMethodType type; + union { + FLAC__EntropyCodingMethod_PartitionedRice partitioned_rice; + } data; } FLAC__EntropyCodingMethod; extern FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_TYPE_LEN; /**< == 2 (bits) */ @@ -265,74 +265,74 @@ extern FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_TYPE_LEN; /**< == 2 ( /** An enumeration of the available subframe types. */ typedef enum { - FLAC__SUBFRAME_TYPE_CONSTANT = 0, /**< constant signal */ - FLAC__SUBFRAME_TYPE_VERBATIM = 1, /**< uncompressed signal */ - FLAC__SUBFRAME_TYPE_FIXED = 2, /**< fixed polynomial prediction */ - FLAC__SUBFRAME_TYPE_LPC = 3 /**< linear prediction */ + FLAC__SUBFRAME_TYPE_CONSTANT = 0, /**< constant signal */ + FLAC__SUBFRAME_TYPE_VERBATIM = 1, /**< uncompressed signal */ + FLAC__SUBFRAME_TYPE_FIXED = 2, /**< fixed polynomial prediction */ + FLAC__SUBFRAME_TYPE_LPC = 3 /**< linear prediction */ } FLAC__SubframeType; /** Maps a FLAC__SubframeType to a C string. - * - * Using a FLAC__SubframeType as the index to this array will - * give the string equivalent. The contents should not be modified. - */ + + Using a FLAC__SubframeType as the index to this array will + give the string equivalent. The contents should not be modified. +*/ extern FLAC_API const char * const FLAC__SubframeTypeString[]; /** CONSTANT subframe. (c.f. format specification) - */ +*/ typedef struct { - FLAC__int32 value; /**< The constant signal value. */ + FLAC__int32 value; /**< The constant signal value. */ } FLAC__Subframe_Constant; /** VERBATIM subframe. (c.f. format specification) - */ +*/ typedef struct { - const FLAC__int32 *data; /**< A pointer to verbatim signal. */ + const FLAC__int32 *data; /**< A pointer to verbatim signal. */ } FLAC__Subframe_Verbatim; /** FIXED subframe. (c.f. format specification) - */ +*/ typedef struct { - FLAC__EntropyCodingMethod entropy_coding_method; - /**< The residual coding method. */ + FLAC__EntropyCodingMethod entropy_coding_method; + /**< The residual coding method. */ - uint32_t order; - /**< The polynomial order. */ + uint32_t order; + /**< The polynomial order. */ - FLAC__int32 warmup[FLAC__MAX_FIXED_ORDER]; - /**< Warmup samples to prime the predictor, length == order. */ + FLAC__int32 warmup[FLAC__MAX_FIXED_ORDER]; + /**< Warmup samples to prime the predictor, length == order. */ - const FLAC__int32 *residual; - /**< The residual signal, length == (blocksize minus order) samples. */ + const FLAC__int32 *residual; + /**< The residual signal, length == (blocksize minus order) samples. */ } FLAC__Subframe_Fixed; /** LPC subframe. (c.f. format specification) - */ +*/ typedef struct { - FLAC__EntropyCodingMethod entropy_coding_method; - /**< The residual coding method. */ + FLAC__EntropyCodingMethod entropy_coding_method; + /**< The residual coding method. */ - uint32_t order; - /**< The FIR order. */ + uint32_t order; + /**< The FIR order. */ - uint32_t qlp_coeff_precision; - /**< Quantized FIR filter coefficient precision in bits. */ + uint32_t qlp_coeff_precision; + /**< Quantized FIR filter coefficient precision in bits. */ - int quantization_level; - /**< The qlp coeff shift needed. */ + int quantization_level; + /**< The qlp coeff shift needed. */ - FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; - /**< FIR filter coefficients. */ + FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; + /**< FIR filter coefficients. */ - FLAC__int32 warmup[FLAC__MAX_LPC_ORDER]; - /**< Warmup samples to prime the predictor, length == order. */ + FLAC__int32 warmup[FLAC__MAX_LPC_ORDER]; + /**< Warmup samples to prime the predictor, length == order. */ - const FLAC__int32 *residual; - /**< The residual signal, length == (blocksize minus order) samples. */ + const FLAC__int32 *residual; + /**< The residual signal, length == (blocksize minus order) samples. */ } FLAC__Subframe_LPC; extern FLAC_API const uint32_t FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN; /**< == 4 (bits) */ @@ -340,25 +340,25 @@ extern FLAC_API const uint32_t FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN; /**< == 5 (bits /** FLAC subframe structure. (c.f. format specification) - */ +*/ typedef struct { - FLAC__SubframeType type; - union { - FLAC__Subframe_Constant constant; - FLAC__Subframe_Fixed fixed; - FLAC__Subframe_LPC lpc; - FLAC__Subframe_Verbatim verbatim; - } data; - uint32_t wasted_bits; + FLAC__SubframeType type; + union { + FLAC__Subframe_Constant constant; + FLAC__Subframe_Fixed fixed; + FLAC__Subframe_LPC lpc; + FLAC__Subframe_Verbatim verbatim; + } data; + uint32_t wasted_bits; } FLAC__Subframe; /** == 1 (bit) - * - * This used to be a zero-padding bit (hence the name - * FLAC__SUBFRAME_ZERO_PAD_LEN) but is now a reserved bit. It still has a - * mandatory value of \c 0 but in the future may take on the value \c 0 or \c 1 - * to mean something else. - */ + + This used to be a zero-padding bit (hence the name + FLAC__SUBFRAME_ZERO_PAD_LEN) but is now a reserved bit. It still has a + mandatory value of \c 0 but in the future may take on the value \c 0 or \c 1 + to mean something else. +*/ extern FLAC_API const uint32_t FLAC__SUBFRAME_ZERO_PAD_LEN; extern FLAC_API const uint32_t FLAC__SUBFRAME_TYPE_LEN; /**< == 6 (bits) */ extern FLAC_API const uint32_t FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN; /**< == 1 (bit) */ @@ -372,75 +372,75 @@ extern FLAC_API const uint32_t FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK; /**< = /***************************************************************************** - * - * Frame structures - * + + Frame structures + *****************************************************************************/ /** An enumeration of the available channel assignments. */ typedef enum { - FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT = 0, /**< independent channels */ - FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE = 1, /**< left+side stereo */ - FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE = 2, /**< right+side stereo */ - FLAC__CHANNEL_ASSIGNMENT_MID_SIDE = 3 /**< mid+side stereo */ + FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT = 0, /**< independent channels */ + FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE = 1, /**< left+side stereo */ + FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE = 2, /**< right+side stereo */ + FLAC__CHANNEL_ASSIGNMENT_MID_SIDE = 3 /**< mid+side stereo */ } FLAC__ChannelAssignment; /** Maps a FLAC__ChannelAssignment to a C string. - * - * Using a FLAC__ChannelAssignment as the index to this array will - * give the string equivalent. The contents should not be modified. - */ + + Using a FLAC__ChannelAssignment as the index to this array will + give the string equivalent. The contents should not be modified. +*/ extern FLAC_API const char * const FLAC__ChannelAssignmentString[]; /** An enumeration of the possible frame numbering methods. */ typedef enum { - FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER, /**< number contains the frame number */ - FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER /**< number contains the sample number of first sample in frame */ + FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER, /**< number contains the frame number */ + FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER /**< number contains the sample number of first sample in frame */ } FLAC__FrameNumberType; /** Maps a FLAC__FrameNumberType to a C string. - * - * Using a FLAC__FrameNumberType as the index to this array will - * give the string equivalent. The contents should not be modified. - */ + + Using a FLAC__FrameNumberType as the index to this array will + give the string equivalent. The contents should not be modified. +*/ extern FLAC_API const char * const FLAC__FrameNumberTypeString[]; /** FLAC frame header structure. (c.f. format specification) - */ +*/ typedef struct { - uint32_t blocksize; - /**< The number of samples per subframe. */ - - uint32_t sample_rate; - /**< The sample rate in Hz. */ - - uint32_t channels; - /**< The number of channels (== number of subframes). */ - - FLAC__ChannelAssignment channel_assignment; - /**< The channel assignment for the frame. */ - - uint32_t bits_per_sample; - /**< The sample resolution. */ - - FLAC__FrameNumberType number_type; - /**< The numbering scheme used for the frame. As a convenience, the - * decoder will always convert a frame number to a sample number because - * the rules are complex. */ - - union { - FLAC__uint32 frame_number; - FLAC__uint64 sample_number; - } number; - /**< The frame number or sample number of first sample in frame; - * use the \a number_type value to determine which to use. */ - - FLAC__uint8 crc; - /**< CRC-8 (polynomial = x^8 + x^2 + x^1 + x^0, initialized with 0) - * of the raw frame header bytes, meaning everything before the CRC byte - * including the sync code. - */ + uint32_t blocksize; + /**< The number of samples per subframe. */ + + uint32_t sample_rate; + /**< The sample rate in Hz. */ + + uint32_t channels; + /**< The number of channels (== number of subframes). */ + + FLAC__ChannelAssignment channel_assignment; + /**< The channel assignment for the frame. */ + + uint32_t bits_per_sample; + /**< The sample resolution. */ + + FLAC__FrameNumberType number_type; + /** < The numbering scheme used for the frame. As a convenience, the + decoder will always convert a frame number to a sample number because + the rules are complex. */ + + union { + FLAC__uint32 frame_number; + FLAC__uint64 sample_number; + } number; + /** < The frame number or sample number of first sample in frame; + use the \a number_type value to determine which to use. */ + + FLAC__uint8 crc; + /** < CRC-8 (polynomial = x^8 + x^2 + x^1 + x^0, initialized with 0) + of the raw frame header bytes, meaning everything before the CRC byte + including the sync code. + */ } FLAC__FrameHeader; extern FLAC_API const uint32_t FLAC__FRAME_HEADER_SYNC; /**< == 0x3ffe; the frame header sync code */ @@ -456,84 +456,84 @@ extern FLAC_API const uint32_t FLAC__FRAME_HEADER_CRC_LEN; /**< == 8 (bits) */ /** FLAC frame footer structure. (c.f. format specification) - */ +*/ typedef struct { - FLAC__uint16 crc; - /**< CRC-16 (polynomial = x^16 + x^15 + x^2 + x^0, initialized with - * 0) of the bytes before the crc, back to and including the frame header - * sync code. - */ + FLAC__uint16 crc; + /** < CRC-16 (polynomial = x^16 + x^15 + x^2 + x^0, initialized with + 0) of the bytes before the crc, back to and including the frame header + sync code. + */ } FLAC__FrameFooter; extern FLAC_API const uint32_t FLAC__FRAME_FOOTER_CRC_LEN; /**< == 16 (bits) */ /** FLAC frame structure. (c.f. format specification) - */ +*/ typedef struct { - FLAC__FrameHeader header; - FLAC__Subframe subframes[FLAC__MAX_CHANNELS]; - FLAC__FrameFooter footer; + FLAC__FrameHeader header; + FLAC__Subframe subframes[FLAC__MAX_CHANNELS]; + FLAC__FrameFooter footer; } FLAC__Frame; /*****************************************************************************/ /***************************************************************************** - * - * Meta-data structures - * + + Meta-data structures + *****************************************************************************/ /** An enumeration of the available metadata block types. */ typedef enum { - FLAC__METADATA_TYPE_STREAMINFO = 0, - /**< STREAMINFO block */ + FLAC__METADATA_TYPE_STREAMINFO = 0, + /**< STREAMINFO block */ - FLAC__METADATA_TYPE_PADDING = 1, - /**< PADDING block */ + FLAC__METADATA_TYPE_PADDING = 1, + /**< PADDING block */ - FLAC__METADATA_TYPE_APPLICATION = 2, - /**< APPLICATION block */ + FLAC__METADATA_TYPE_APPLICATION = 2, + /**< APPLICATION block */ - FLAC__METADATA_TYPE_SEEKTABLE = 3, - /**< SEEKTABLE block */ + FLAC__METADATA_TYPE_SEEKTABLE = 3, + /**< SEEKTABLE block */ - FLAC__METADATA_TYPE_VORBIS_COMMENT = 4, - /**< VORBISCOMMENT block (a.k.a. FLAC tags) */ + FLAC__METADATA_TYPE_VORBIS_COMMENT = 4, + /**< VORBISCOMMENT block (a.k.a. FLAC tags) */ - FLAC__METADATA_TYPE_CUESHEET = 5, - /**< CUESHEET block */ + FLAC__METADATA_TYPE_CUESHEET = 5, + /**< CUESHEET block */ - FLAC__METADATA_TYPE_PICTURE = 6, - /**< PICTURE block */ + FLAC__METADATA_TYPE_PICTURE = 6, + /**< PICTURE block */ - FLAC__METADATA_TYPE_UNDEFINED = 7, - /**< marker to denote beginning of undefined type range; this number will increase as new metadata types are added */ + FLAC__METADATA_TYPE_UNDEFINED = 7, + /**< marker to denote beginning of undefined type range; this number will increase as new metadata types are added */ - FLAC__MAX_METADATA_TYPE = FLAC__MAX_METADATA_TYPE_CODE, - /**< No type will ever be greater than this. There is not enough room in the protocol block. */ + FLAC__MAX_METADATA_TYPE = FLAC__MAX_METADATA_TYPE_CODE, + /**< No type will ever be greater than this. There is not enough room in the protocol block. */ } FLAC__MetadataType; /** Maps a FLAC__MetadataType to a C string. - * - * Using a FLAC__MetadataType as the index to this array will - * give the string equivalent. The contents should not be modified. - */ + + Using a FLAC__MetadataType as the index to this array will + give the string equivalent. The contents should not be modified. +*/ extern FLAC_API const char * const FLAC__MetadataTypeString[]; /** FLAC STREAMINFO structure. (c.f. format specification) - */ +*/ typedef struct { - uint32_t min_blocksize, max_blocksize; - uint32_t min_framesize, max_framesize; - uint32_t sample_rate; - uint32_t channels; - uint32_t bits_per_sample; - FLAC__uint64 total_samples; - FLAC__byte md5sum[16]; + uint32_t min_blocksize, max_blocksize; + uint32_t min_framesize, max_framesize; + uint32_t sample_rate; + uint32_t channels; + uint32_t bits_per_sample; + FLAC__uint64 total_samples; + FLAC__byte md5sum[16]; } FLAC__StreamMetadata_StreamInfo; extern FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN; /**< == 16 (bits) */ @@ -550,37 +550,37 @@ extern FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN; /**< #define FLAC__STREAM_METADATA_STREAMINFO_LENGTH (34u) /** FLAC PADDING structure. (c.f. format specification) - */ +*/ typedef struct { - int dummy; - /**< Conceptually this is an empty struct since we don't store the - * padding bytes. Empty structs are not allowed by some C compilers, - * hence the dummy. - */ + int dummy; + /** < Conceptually this is an empty struct since we don't store the + padding bytes. Empty structs are not allowed by some C compilers, + hence the dummy. + */ } FLAC__StreamMetadata_Padding; /** FLAC APPLICATION structure. (c.f. format specification) - */ +*/ typedef struct { - FLAC__byte id[4]; - FLAC__byte *data; + FLAC__byte id[4]; + FLAC__byte *data; } FLAC__StreamMetadata_Application; extern FLAC_API const uint32_t FLAC__STREAM_METADATA_APPLICATION_ID_LEN; /**< == 32 (bits) */ /** SeekPoint structure used in SEEKTABLE blocks. (c.f. format specification) - */ +*/ typedef struct { - FLAC__uint64 sample_number; - /**< The sample number of the target frame. */ + FLAC__uint64 sample_number; + /**< The sample number of the target frame. */ - FLAC__uint64 stream_offset; - /**< The offset, in bytes, of the target frame with respect to - * beginning of the first frame. */ + FLAC__uint64 stream_offset; + /** < The offset, in bytes, of the target frame with respect to + beginning of the first frame. */ - uint32_t frame_samples; - /**< The number of samples in the target frame. */ + uint32_t frame_samples; + /**< The number of samples in the target frame. */ } FLAC__StreamMetadata_SeekPoint; extern FLAC_API const uint32_t FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN; /**< == 64 (bits) */ @@ -591,67 +591,67 @@ extern FLAC_API const uint32_t FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN #define FLAC__STREAM_METADATA_SEEKPOINT_LENGTH (18u) /** The value used in the \a sample_number field of - * FLAC__StreamMetadataSeekPoint used to indicate a placeholder - * point (== 0xffffffffffffffff). - */ + FLAC__StreamMetadataSeekPoint used to indicate a placeholder + point (== 0xffffffffffffffff). +*/ extern FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; /** FLAC SEEKTABLE structure. (c.f. format specification) - * - * \note From the format specification: - * - The seek points must be sorted by ascending sample number. - * - Each seek point's sample number must be the first sample of the - * target frame. - * - Each seek point's sample number must be unique within the table. - * - Existence of a SEEKTABLE block implies a correct setting of - * total_samples in the stream_info block. - * - Behavior is undefined when more than one SEEKTABLE block is - * present in a stream. - */ + + \note From the format specification: + - The seek points must be sorted by ascending sample number. + - Each seek point's sample number must be the first sample of the + target frame. + - Each seek point's sample number must be unique within the table. + - Existence of a SEEKTABLE block implies a correct setting of + total_samples in the stream_info block. + - Behavior is undefined when more than one SEEKTABLE block is + present in a stream. +*/ typedef struct { - uint32_t num_points; - FLAC__StreamMetadata_SeekPoint *points; + uint32_t num_points; + FLAC__StreamMetadata_SeekPoint *points; } FLAC__StreamMetadata_SeekTable; /** Vorbis comment entry structure used in VORBIS_COMMENT blocks. (c.f. format specification) - * - * For convenience, the APIs maintain a trailing NUL character at the end of - * \a entry which is not counted toward \a length, i.e. - * \code strlen(entry) == length \endcode - */ + + For convenience, the APIs maintain a trailing NUL character at the end of + \a entry which is not counted toward \a length, i.e. + \code strlen(entry) == length \endcode +*/ typedef struct { - FLAC__uint32 length; - FLAC__byte *entry; + FLAC__uint32 length; + FLAC__byte *entry; } FLAC__StreamMetadata_VorbisComment_Entry; extern FLAC_API const uint32_t FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN; /**< == 32 (bits) */ /** FLAC VORBIS_COMMENT structure. (c.f. format specification) - */ +*/ typedef struct { - FLAC__StreamMetadata_VorbisComment_Entry vendor_string; - FLAC__uint32 num_comments; - FLAC__StreamMetadata_VorbisComment_Entry *comments; + FLAC__StreamMetadata_VorbisComment_Entry vendor_string; + FLAC__uint32 num_comments; + FLAC__StreamMetadata_VorbisComment_Entry *comments; } FLAC__StreamMetadata_VorbisComment; extern FLAC_API const uint32_t FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN; /**< == 32 (bits) */ /** FLAC CUESHEET track index structure. (See the - * format specification for - * the full description of each field.) - */ + format specification for + the full description of each field.) +*/ typedef struct { - FLAC__uint64 offset; - /**< Offset in samples, relative to the track offset, of the index - * point. - */ + FLAC__uint64 offset; + /** < Offset in samples, relative to the track offset, of the index + point. + */ - FLAC__byte number; - /**< The index point number. */ + FLAC__byte number; + /**< The index point number. */ } FLAC__StreamMetadata_CueSheet_Index; extern FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN; /**< == 64 (bits) */ @@ -660,30 +660,30 @@ extern FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN /** FLAC CUESHEET track structure. (See the - * format specification for - * the full description of each field.) - */ + format specification for + the full description of each field.) +*/ typedef struct { - FLAC__uint64 offset; - /**< Track offset in samples, relative to the beginning of the FLAC audio stream. */ + FLAC__uint64 offset; + /**< Track offset in samples, relative to the beginning of the FLAC audio stream. */ - FLAC__byte number; - /**< The track number. */ + FLAC__byte number; + /**< The track number. */ - char isrc[13]; - /**< Track ISRC. This is a 12-digit alphanumeric code plus a trailing \c NUL byte */ + char isrc[13]; + /**< Track ISRC. This is a 12-digit alphanumeric code plus a trailing \c NUL byte */ - uint32_t type:1; - /**< The track type: 0 for audio, 1 for non-audio. */ + uint32_t type: 1; + /**< The track type: 0 for audio, 1 for non-audio. */ - uint32_t pre_emphasis:1; - /**< The pre-emphasis flag: 0 for no pre-emphasis, 1 for pre-emphasis. */ + uint32_t pre_emphasis: 1; + /**< The pre-emphasis flag: 0 for no pre-emphasis, 1 for pre-emphasis. */ - FLAC__byte num_indices; - /**< The number of track index points. */ + FLAC__byte num_indices; + /**< The number of track index points. */ - FLAC__StreamMetadata_CueSheet_Index *indices; - /**< NULL if num_indices == 0, else pointer to array of index points. */ + FLAC__StreamMetadata_CueSheet_Index *indices; + /**< NULL if num_indices == 0, else pointer to array of index points. */ } FLAC__StreamMetadata_CueSheet_Track; @@ -697,27 +697,27 @@ extern FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_ /** FLAC CUESHEET structure. (See the - * format specification - * for the full description of each field.) - */ + format specification + for the full description of each field.) +*/ typedef struct { - char media_catalog_number[129]; - /**< Media catalog number, in ASCII printable characters 0x20-0x7e. In - * general, the media catalog number may be 0 to 128 bytes long; any - * unused characters should be right-padded with NUL characters. - */ + char media_catalog_number[129]; + /** < Media catalog number, in ASCII printable characters 0x20-0x7e. In + general, the media catalog number may be 0 to 128 bytes long; any + unused characters should be right-padded with NUL characters. + */ - FLAC__uint64 lead_in; - /**< The number of lead-in samples. */ + FLAC__uint64 lead_in; + /**< The number of lead-in samples. */ - FLAC__bool is_cd; - /**< \c true if CUESHEET corresponds to a Compact Disc, else \c false. */ + FLAC__bool is_cd; + /**< \c true if CUESHEET corresponds to a Compact Disc, else \c false. */ - uint32_t num_tracks; - /**< The number of tracks. */ + uint32_t num_tracks; + /**< The number of tracks. */ - FLAC__StreamMetadata_CueSheet_Track *tracks; - /**< NULL if num_tracks == 0, else pointer to array of tracks. */ + FLAC__StreamMetadata_CueSheet_Track *tracks; + /**< NULL if num_tracks == 0, else pointer to array of tracks. */ } FLAC__StreamMetadata_CueSheet; @@ -730,83 +730,83 @@ extern FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN; /* /** An enumeration of the PICTURE types (see FLAC__StreamMetadataPicture and id3 v2.4 APIC tag). */ typedef enum { - FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER = 0, /**< Other */ - FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD = 1, /**< 32x32 pixels 'file icon' (PNG only) */ - FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON = 2, /**< Other file icon */ - FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER = 3, /**< Cover (front) */ - FLAC__STREAM_METADATA_PICTURE_TYPE_BACK_COVER = 4, /**< Cover (back) */ - FLAC__STREAM_METADATA_PICTURE_TYPE_LEAFLET_PAGE = 5, /**< Leaflet page */ - FLAC__STREAM_METADATA_PICTURE_TYPE_MEDIA = 6, /**< Media (e.g. label side of CD) */ - FLAC__STREAM_METADATA_PICTURE_TYPE_LEAD_ARTIST = 7, /**< Lead artist/lead performer/soloist */ - FLAC__STREAM_METADATA_PICTURE_TYPE_ARTIST = 8, /**< Artist/performer */ - FLAC__STREAM_METADATA_PICTURE_TYPE_CONDUCTOR = 9, /**< Conductor */ - FLAC__STREAM_METADATA_PICTURE_TYPE_BAND = 10, /**< Band/Orchestra */ - FLAC__STREAM_METADATA_PICTURE_TYPE_COMPOSER = 11, /**< Composer */ - FLAC__STREAM_METADATA_PICTURE_TYPE_LYRICIST = 12, /**< Lyricist/text writer */ - FLAC__STREAM_METADATA_PICTURE_TYPE_RECORDING_LOCATION = 13, /**< Recording Location */ - FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_RECORDING = 14, /**< During recording */ - FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_PERFORMANCE = 15, /**< During performance */ - FLAC__STREAM_METADATA_PICTURE_TYPE_VIDEO_SCREEN_CAPTURE = 16, /**< Movie/video screen capture */ - FLAC__STREAM_METADATA_PICTURE_TYPE_FISH = 17, /**< A bright coloured fish */ - FLAC__STREAM_METADATA_PICTURE_TYPE_ILLUSTRATION = 18, /**< Illustration */ - FLAC__STREAM_METADATA_PICTURE_TYPE_BAND_LOGOTYPE = 19, /**< Band/artist logotype */ - FLAC__STREAM_METADATA_PICTURE_TYPE_PUBLISHER_LOGOTYPE = 20, /**< Publisher/Studio logotype */ - FLAC__STREAM_METADATA_PICTURE_TYPE_UNDEFINED + FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER = 0, /**< Other */ + FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD = 1, /**< 32x32 pixels 'file icon' (PNG only) */ + FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON = 2, /**< Other file icon */ + FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER = 3, /**< Cover (front) */ + FLAC__STREAM_METADATA_PICTURE_TYPE_BACK_COVER = 4, /**< Cover (back) */ + FLAC__STREAM_METADATA_PICTURE_TYPE_LEAFLET_PAGE = 5, /**< Leaflet page */ + FLAC__STREAM_METADATA_PICTURE_TYPE_MEDIA = 6, /**< Media (e.g. label side of CD) */ + FLAC__STREAM_METADATA_PICTURE_TYPE_LEAD_ARTIST = 7, /**< Lead artist/lead performer/soloist */ + FLAC__STREAM_METADATA_PICTURE_TYPE_ARTIST = 8, /**< Artist/performer */ + FLAC__STREAM_METADATA_PICTURE_TYPE_CONDUCTOR = 9, /**< Conductor */ + FLAC__STREAM_METADATA_PICTURE_TYPE_BAND = 10, /**< Band/Orchestra */ + FLAC__STREAM_METADATA_PICTURE_TYPE_COMPOSER = 11, /**< Composer */ + FLAC__STREAM_METADATA_PICTURE_TYPE_LYRICIST = 12, /**< Lyricist/text writer */ + FLAC__STREAM_METADATA_PICTURE_TYPE_RECORDING_LOCATION = 13, /**< Recording Location */ + FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_RECORDING = 14, /**< During recording */ + FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_PERFORMANCE = 15, /**< During performance */ + FLAC__STREAM_METADATA_PICTURE_TYPE_VIDEO_SCREEN_CAPTURE = 16, /**< Movie/video screen capture */ + FLAC__STREAM_METADATA_PICTURE_TYPE_FISH = 17, /**< A bright coloured fish */ + FLAC__STREAM_METADATA_PICTURE_TYPE_ILLUSTRATION = 18, /**< Illustration */ + FLAC__STREAM_METADATA_PICTURE_TYPE_BAND_LOGOTYPE = 19, /**< Band/artist logotype */ + FLAC__STREAM_METADATA_PICTURE_TYPE_PUBLISHER_LOGOTYPE = 20, /**< Publisher/Studio logotype */ + FLAC__STREAM_METADATA_PICTURE_TYPE_UNDEFINED } FLAC__StreamMetadata_Picture_Type; /** Maps a FLAC__StreamMetadata_Picture_Type to a C string. - * - * Using a FLAC__StreamMetadata_Picture_Type as the index to this array - * will give the string equivalent. The contents should not be - * modified. - */ + + Using a FLAC__StreamMetadata_Picture_Type as the index to this array + will give the string equivalent. The contents should not be + modified. +*/ extern FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[]; /** FLAC PICTURE structure. (See the - * format specification - * for the full description of each field.) - */ + format specification + for the full description of each field.) +*/ typedef struct { - FLAC__StreamMetadata_Picture_Type type; - /**< The kind of picture stored. */ - - char *mime_type; - /**< Picture data's MIME type, in ASCII printable characters - * 0x20-0x7e, NUL terminated. For best compatibility with players, - * use picture data of MIME type \c image/jpeg or \c image/png. A - * MIME type of '-->' is also allowed, in which case the picture - * data should be a complete URL. In file storage, the MIME type is - * stored as a 32-bit length followed by the ASCII string with no NUL - * terminator, but is converted to a plain C string in this structure - * for convenience. - */ - - FLAC__byte *description; - /**< Picture's description in UTF-8, NUL terminated. In file storage, - * the description is stored as a 32-bit length followed by the UTF-8 - * string with no NUL terminator, but is converted to a plain C string - * in this structure for convenience. - */ - - FLAC__uint32 width; - /**< Picture's width in pixels. */ - - FLAC__uint32 height; - /**< Picture's height in pixels. */ - - FLAC__uint32 depth; - /**< Picture's color depth in bits-per-pixel. */ - - FLAC__uint32 colors; - /**< For indexed palettes (like GIF), picture's number of colors (the - * number of palette entries), or \c 0 for non-indexed (i.e. 2^depth). - */ - - FLAC__uint32 data_length; - /**< Length of binary picture data in bytes. */ - - FLAC__byte *data; - /**< Binary picture data. */ + FLAC__StreamMetadata_Picture_Type type; + /**< The kind of picture stored. */ + + char *mime_type; + /** < Picture data's MIME type, in ASCII printable characters + 0x20-0x7e, NUL terminated. For best compatibility with players, + use picture data of MIME type \c image/jpeg or \c image/png. A + MIME type of '-->' is also allowed, in which case the picture + data should be a complete URL. In file storage, the MIME type is + stored as a 32-bit length followed by the ASCII string with no NUL + terminator, but is converted to a plain C string in this structure + for convenience. + */ + + FLAC__byte *description; + /** < Picture's description in UTF-8, NUL terminated. In file storage, + the description is stored as a 32-bit length followed by the UTF-8 + string with no NUL terminator, but is converted to a plain C string + in this structure for convenience. + */ + + FLAC__uint32 width; + /**< Picture's width in pixels. */ + + FLAC__uint32 height; + /**< Picture's height in pixels. */ + + FLAC__uint32 depth; + /**< Picture's color depth in bits-per-pixel. */ + + FLAC__uint32 colors; + /** < For indexed palettes (like GIF), picture's number of colors (the + number of palette entries), or \c 0 for non-indexed (i.e. 2^depth). + */ + + FLAC__uint32 data_length; + /**< Length of binary picture data in bytes. */ + + FLAC__byte *data; + /**< Binary picture data. */ } FLAC__StreamMetadata_Picture; @@ -821,40 +821,40 @@ extern FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN; /* /** Structure that is used when a metadata block of unknown type is loaded. - * The contents are opaque. The structure is used only internally to - * correctly handle unknown metadata. - */ + The contents are opaque. The structure is used only internally to + correctly handle unknown metadata. +*/ typedef struct { - FLAC__byte *data; + FLAC__byte *data; } FLAC__StreamMetadata_Unknown; /** FLAC metadata block structure. (c.f. format specification) - */ +*/ typedef struct { - FLAC__MetadataType type; - /**< The type of the metadata block; used determine which member of the - * \a data union to dereference. If type >= FLAC__METADATA_TYPE_UNDEFINED - * then \a data.unknown must be used. */ - - FLAC__bool is_last; - /**< \c true if this metadata block is the last, else \a false */ - - uint32_t length; - /**< Length, in bytes, of the block data as it appears in the stream. */ - - union { - FLAC__StreamMetadata_StreamInfo stream_info; - FLAC__StreamMetadata_Padding padding; - FLAC__StreamMetadata_Application application; - FLAC__StreamMetadata_SeekTable seek_table; - FLAC__StreamMetadata_VorbisComment vorbis_comment; - FLAC__StreamMetadata_CueSheet cue_sheet; - FLAC__StreamMetadata_Picture picture; - FLAC__StreamMetadata_Unknown unknown; - } data; - /**< Polymorphic block data; use the \a type value to determine which - * to use. */ + FLAC__MetadataType type; + /** < The type of the metadata block; used determine which member of the + \a data union to dereference. If type >= FLAC__METADATA_TYPE_UNDEFINED + then \a data.unknown must be used. */ + + FLAC__bool is_last; + /**< \c true if this metadata block is the last, else \a false */ + + uint32_t length; + /**< Length, in bytes, of the block data as it appears in the stream. */ + + union { + FLAC__StreamMetadata_StreamInfo stream_info; + FLAC__StreamMetadata_Padding padding; + FLAC__StreamMetadata_Application application; + FLAC__StreamMetadata_SeekTable seek_table; + FLAC__StreamMetadata_VorbisComment vorbis_comment; + FLAC__StreamMetadata_CueSheet cue_sheet; + FLAC__StreamMetadata_Picture picture; + FLAC__StreamMetadata_Unknown unknown; + } data; + /** < Polymorphic block data; use the \a type value to determine which + to use. */ } FLAC__StreamMetadata; extern FLAC_API const uint32_t FLAC__STREAM_METADATA_IS_LAST_LEN; /**< == 1 (bit) */ @@ -868,152 +868,152 @@ extern FLAC_API const uint32_t FLAC__STREAM_METADATA_LENGTH_LEN; /**< == 24 (bit /***************************************************************************** - * - * Utility functions - * + + Utility functions + *****************************************************************************/ /** Tests that a sample rate is valid for FLAC. - * - * \param sample_rate The sample rate to test for compliance. - * \retval FLAC__bool - * \c true if the given sample rate conforms to the specification, else - * \c false. - */ + + \param sample_rate The sample rate to test for compliance. + \retval FLAC__bool + \c true if the given sample rate conforms to the specification, else + \c false. +*/ FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(uint32_t sample_rate); /** Tests that a blocksize at the given sample rate is valid for the FLAC - * subset. - * - * \param blocksize The blocksize to test for compliance. - * \param sample_rate The sample rate is needed, since the valid subset - * blocksize depends on the sample rate. - * \retval FLAC__bool - * \c true if the given blocksize conforms to the specification for the - * subset at the given sample rate, else \c false. - */ + subset. + + \param blocksize The blocksize to test for compliance. + \param sample_rate The sample rate is needed, since the valid subset + blocksize depends on the sample rate. + \retval FLAC__bool + \c true if the given blocksize conforms to the specification for the + subset at the given sample rate, else \c false. +*/ FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(uint32_t blocksize, uint32_t sample_rate); /** Tests that a sample rate is valid for the FLAC subset. The subset rules - * for valid sample rates are slightly more complex since the rate has to - * be expressible completely in the frame header. - * - * \param sample_rate The sample rate to test for compliance. - * \retval FLAC__bool - * \c true if the given sample rate conforms to the specification for the - * subset, else \c false. - */ + for valid sample rates are slightly more complex since the rate has to + be expressible completely in the frame header. + + \param sample_rate The sample rate to test for compliance. + \retval FLAC__bool + \c true if the given sample rate conforms to the specification for the + subset, else \c false. +*/ FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(uint32_t sample_rate); /** Check a Vorbis comment entry name to see if it conforms to the Vorbis - * comment specification. - * - * Vorbis comment names must be composed only of characters from - * [0x20-0x3C,0x3E-0x7D]. - * - * \param name A NUL-terminated string to be checked. - * \assert - * \code name != NULL \endcode - * \retval FLAC__bool - * \c false if entry name is illegal, else \c true. - */ + comment specification. + + Vorbis comment names must be composed only of characters from + [0x20-0x3C,0x3E-0x7D]. + + \param name A NUL-terminated string to be checked. + \assert + \code name != NULL \endcode + \retval FLAC__bool + \c false if entry name is illegal, else \c true. +*/ FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name); /** Check a Vorbis comment entry value to see if it conforms to the Vorbis - * comment specification. - * - * Vorbis comment values must be valid UTF-8 sequences. - * - * \param value A string to be checked. - * \param length A the length of \a value in bytes. May be - * \c (uint32_t)(-1) to indicate that \a value is a plain - * UTF-8 NUL-terminated string. - * \assert - * \code value != NULL \endcode - * \retval FLAC__bool - * \c false if entry name is illegal, else \c true. - */ + comment specification. + + Vorbis comment values must be valid UTF-8 sequences. + + \param value A string to be checked. + \param length A the length of \a value in bytes. May be + \c (uint32_t)(-1) to indicate that \a value is a plain + UTF-8 NUL-terminated string. + \assert + \code value != NULL \endcode + \retval FLAC__bool + \c false if entry name is illegal, else \c true. +*/ FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, uint32_t length); /** Check a Vorbis comment entry to see if it conforms to the Vorbis - * comment specification. - * - * Vorbis comment entries must be of the form 'name=value', and 'name' and - * 'value' must be legal according to - * FLAC__format_vorbiscomment_entry_name_is_legal() and - * FLAC__format_vorbiscomment_entry_value_is_legal() respectively. - * - * \param entry An entry to be checked. - * \param length The length of \a entry in bytes. - * \assert - * \code value != NULL \endcode - * \retval FLAC__bool - * \c false if entry name is illegal, else \c true. - */ + comment specification. + + Vorbis comment entries must be of the form 'name=value', and 'name' and + 'value' must be legal according to + FLAC__format_vorbiscomment_entry_name_is_legal() and + FLAC__format_vorbiscomment_entry_value_is_legal() respectively. + + \param entry An entry to be checked. + \param length The length of \a entry in bytes. + \assert + \code value != NULL \endcode + \retval FLAC__bool + \c false if entry name is illegal, else \c true. +*/ FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, uint32_t length); /** Check a seek table to see if it conforms to the FLAC specification. - * See the format specification for limits on the contents of the - * seek table. - * - * \param seek_table A pointer to a seek table to be checked. - * \assert - * \code seek_table != NULL \endcode - * \retval FLAC__bool - * \c false if seek table is illegal, else \c true. - */ + See the format specification for limits on the contents of the + seek table. + + \param seek_table A pointer to a seek table to be checked. + \assert + \code seek_table != NULL \endcode + \retval FLAC__bool + \c false if seek table is illegal, else \c true. +*/ FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table); /** Sort a seek table's seek points according to the format specification. - * This includes a "unique-ification" step to remove duplicates, i.e. - * seek points with identical \a sample_number values. Duplicate seek - * points are converted into placeholder points and sorted to the end of - * the table. - * - * \param seek_table A pointer to a seek table to be sorted. - * \assert - * \code seek_table != NULL \endcode - * \retval uint32_t - * The number of duplicate seek points converted into placeholders. - */ + This includes a "unique-ification" step to remove duplicates, i.e. + seek points with identical \a sample_number values. Duplicate seek + points are converted into placeholder points and sorted to the end of + the table. + + \param seek_table A pointer to a seek table to be sorted. + \assert + \code seek_table != NULL \endcode + \retval uint32_t + The number of duplicate seek points converted into placeholders. +*/ FLAC_API uint32_t FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table); /** Check a cue sheet to see if it conforms to the FLAC specification. - * See the format specification for limits on the contents of the - * cue sheet. - * - * \param cue_sheet A pointer to an existing cue sheet to be checked. - * \param check_cd_da_subset If \c true, check CUESHEET against more - * stringent requirements for a CD-DA (audio) disc. - * \param violation Address of a pointer to a string. If there is a - * violation, a pointer to a string explanation of the - * violation will be returned here. \a violation may be - * \c NULL if you don't need the returned string. Do not - * free the returned string; it will always point to static - * data. - * \assert - * \code cue_sheet != NULL \endcode - * \retval FLAC__bool - * \c false if cue sheet is illegal, else \c true. - */ + See the format specification for limits on the contents of the + cue sheet. + + \param cue_sheet A pointer to an existing cue sheet to be checked. + \param check_cd_da_subset If \c true, check CUESHEET against more + stringent requirements for a CD-DA (audio) disc. + \param violation Address of a pointer to a string. If there is a + violation, a pointer to a string explanation of the + violation will be returned here. \a violation may be + \c NULL if you don't need the returned string. Do not + free the returned string; it will always point to static + data. + \assert + \code cue_sheet != NULL \endcode + \retval FLAC__bool + \c false if cue sheet is illegal, else \c true. +*/ FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation); /** Check picture data to see if it conforms to the FLAC specification. - * See the format specification for limits on the contents of the - * PICTURE block. - * - * \param picture A pointer to existing picture data to be checked. - * \param violation Address of a pointer to a string. If there is a - * violation, a pointer to a string explanation of the - * violation will be returned here. \a violation may be - * \c NULL if you don't need the returned string. Do not - * free the returned string; it will always point to static - * data. - * \assert - * \code picture != NULL \endcode - * \retval FLAC__bool - * \c false if picture data is illegal, else \c true. - */ + See the format specification for limits on the contents of the + PICTURE block. + + \param picture A pointer to existing picture data to be checked. + \param violation Address of a pointer to a string. If there is a + violation, a pointer to a string explanation of the + violation will be returned here. \a violation may be + \c NULL if you don't need the returned string. Do not + free the returned string; it will always point to static + data. + \assert + \code picture != NULL \endcode + \retval FLAC__bool + \c false if picture data is illegal, else \c true. +*/ FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation); /* \} */ diff --git a/src/libflac/FLAC/metadata.h b/src/libflac/FLAC/metadata.h index 4c67b87f..14fb6ab7 100644 --- a/src/libflac/FLAC/metadata.h +++ b/src/libflac/FLAC/metadata.h @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2001-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__METADATA_H #define FLAC__METADATA_H @@ -38,88 +38,88 @@ #include "callback.h" #include "format.h" -/* -------------------------------------------------------------------- - (For an example of how all these routines are used, see the source - code for the unit tests in src/test_libFLAC/metadata_*.c, or - metaflac in src/metaflac/) - ------------------------------------------------------------------*/ +/* -------------------------------------------------------------------- + (For an example of how all these routines are used, see the source + code for the unit tests in src/test_libFLAC/metadata_*.c, or + metaflac in src/metaflac/) + ------------------------------------------------------------------*/ /** \file include/FLAC/metadata.h - * - * \brief - * This module provides functions for creating and manipulating FLAC - * metadata blocks in memory, and three progressively more powerful - * interfaces for traversing and editing metadata in FLAC files. - * - * See the detailed documentation for each interface in the - * \link flac_metadata metadata \endlink module. - */ + + \brief + This module provides functions for creating and manipulating FLAC + metadata blocks in memory, and three progressively more powerful + interfaces for traversing and editing metadata in FLAC files. + + See the detailed documentation for each interface in the + \link flac_metadata metadata \endlink module. +*/ /** \defgroup flac_metadata FLAC/metadata.h: metadata interfaces - * \ingroup flac - * - * \brief - * This module provides functions for creating and manipulating FLAC - * metadata blocks in memory, and three progressively more powerful - * interfaces for traversing and editing metadata in native FLAC files. - * Note that currently only the Chain interface (level 2) supports Ogg - * FLAC files, and it is read-only i.e. no writing back changed - * metadata to file. - * - * There are three metadata interfaces of increasing complexity: - * - * Level 0: - * Read-only access to the STREAMINFO, VORBIS_COMMENT, CUESHEET, and - * PICTURE blocks. - * - * Level 1: - * Read-write access to all metadata blocks. This level is write- - * efficient in most cases (more on this below), and uses less memory - * than level 2. - * - * Level 2: - * Read-write access to all metadata blocks. This level is write- - * efficient in all cases, but uses more memory since all metadata for - * the whole file is read into memory and manipulated before writing - * out again. - * - * What do we mean by efficient? Since FLAC metadata appears at the - * beginning of the file, when writing metadata back to a FLAC file - * it is possible to grow or shrink the metadata such that the entire - * file must be rewritten. However, if the size remains the same during - * changes or PADDING blocks are utilized, only the metadata needs to be - * overwritten, which is much faster. - * - * Efficient means the whole file is rewritten at most one time, and only - * when necessary. Level 1 is not efficient only in the case that you - * cause more than one metadata block to grow or shrink beyond what can - * be accommodated by padding. In this case you should probably use level - * 2, which allows you to edit all the metadata for a file in memory and - * write it out all at once. - * - * All levels know how to skip over and not disturb an ID3v2 tag at the - * front of the file. - * - * All levels access files via their filenames. In addition, level 2 - * has additional alternative read and write functions that take an I/O - * handle and callbacks, for situations where access by filename is not - * possible. - * - * In addition to the three interfaces, this module defines functions for - * creating and manipulating various metadata objects in memory. As we see - * from the Format module, FLAC metadata blocks in memory are very primitive - * structures for storing information in an efficient way. Reading - * information from the structures is easy but creating or modifying them - * directly is more complex. The metadata object routines here facilitate - * this by taking care of the consistency and memory management drudgery. - * - * Unless you will be using the level 1 or 2 interfaces to modify existing - * metadata however, you will not probably not need these. - * - * From a dependency standpoint, none of the encoders or decoders require - * the metadata module. This is so that embedded users can strip out the - * metadata module from libFLAC to reduce the size and complexity. - */ + \ingroup flac + + \brief + This module provides functions for creating and manipulating FLAC + metadata blocks in memory, and three progressively more powerful + interfaces for traversing and editing metadata in native FLAC files. + Note that currently only the Chain interface (level 2) supports Ogg + FLAC files, and it is read-only i.e. no writing back changed + metadata to file. + + There are three metadata interfaces of increasing complexity: + + Level 0: + Read-only access to the STREAMINFO, VORBIS_COMMENT, CUESHEET, and + PICTURE blocks. + + Level 1: + Read-write access to all metadata blocks. This level is write- + efficient in most cases (more on this below), and uses less memory + than level 2. + + Level 2: + Read-write access to all metadata blocks. This level is write- + efficient in all cases, but uses more memory since all metadata for + the whole file is read into memory and manipulated before writing + out again. + + What do we mean by efficient? Since FLAC metadata appears at the + beginning of the file, when writing metadata back to a FLAC file + it is possible to grow or shrink the metadata such that the entire + file must be rewritten. However, if the size remains the same during + changes or PADDING blocks are utilized, only the metadata needs to be + overwritten, which is much faster. + + Efficient means the whole file is rewritten at most one time, and only + when necessary. Level 1 is not efficient only in the case that you + cause more than one metadata block to grow or shrink beyond what can + be accommodated by padding. In this case you should probably use level + 2, which allows you to edit all the metadata for a file in memory and + write it out all at once. + + All levels know how to skip over and not disturb an ID3v2 tag at the + front of the file. + + All levels access files via their filenames. In addition, level 2 + has additional alternative read and write functions that take an I/O + handle and callbacks, for situations where access by filename is not + possible. + + In addition to the three interfaces, this module defines functions for + creating and manipulating various metadata objects in memory. As we see + from the Format module, FLAC metadata blocks in memory are very primitive + structures for storing information in an efficient way. Reading + information from the structures is easy but creating or modifying them + directly is more complex. The metadata object routines here facilitate + this by taking care of the consistency and memory management drudgery. + + Unless you will be using the level 1 or 2 interfaces to modify existing + metadata however, you will not probably not need these. + + From a dependency standpoint, none of the encoders or decoders require + the metadata module. This is so that embedded users can strip out the + metadata module from libFLAC to reduce the size and complexity. +*/ #ifdef __cplusplus extern "C" { @@ -127,2050 +127,2050 @@ extern "C" { /** \defgroup flac_metadata_level0 FLAC/metadata.h: metadata level 0 interface - * \ingroup flac_metadata - * - * \brief - * The level 0 interface consists of individual routines to read the - * STREAMINFO, VORBIS_COMMENT, CUESHEET, and PICTURE blocks, requiring - * only a filename. - * - * They try to skip any ID3v2 tag at the head of the file. - * - * \{ - */ + \ingroup flac_metadata + + \brief + The level 0 interface consists of individual routines to read the + STREAMINFO, VORBIS_COMMENT, CUESHEET, and PICTURE blocks, requiring + only a filename. + + They try to skip any ID3v2 tag at the head of the file. + + \{ +*/ /** Read the STREAMINFO metadata block of the given FLAC file. This function - * will try to skip any ID3v2 tag at the head of the file. - * - * \param filename The path to the FLAC file to read. - * \param streaminfo A pointer to space for the STREAMINFO block. Since - * FLAC__StreamMetadata is a simple structure with no - * memory allocation involved, you pass the address of - * an existing structure. It need not be initialized. - * \assert - * \code filename != NULL \endcode - * \code streaminfo != NULL \endcode - * \retval FLAC__bool - * \c true if a valid STREAMINFO block was read from \a filename. Returns - * \c false if there was a memory allocation error, a file decoder error, - * or the file contained no STREAMINFO block. (A memory allocation error - * is possible because this function must set up a file decoder.) - */ + will try to skip any ID3v2 tag at the head of the file. + + \param filename The path to the FLAC file to read. + \param streaminfo A pointer to space for the STREAMINFO block. Since + FLAC__StreamMetadata is a simple structure with no + memory allocation involved, you pass the address of + an existing structure. It need not be initialized. + \assert + \code filename != NULL \endcode + \code streaminfo != NULL \endcode + \retval FLAC__bool + \c true if a valid STREAMINFO block was read from \a filename. Returns + \c false if there was a memory allocation error, a file decoder error, + or the file contained no STREAMINFO block. (A memory allocation error + is possible because this function must set up a file decoder.) +*/ FLAC_API FLAC__bool FLAC__metadata_get_streaminfo(const char *filename, FLAC__StreamMetadata *streaminfo); /** Read the VORBIS_COMMENT metadata block of the given FLAC file. This - * function will try to skip any ID3v2 tag at the head of the file. - * - * \param filename The path to the FLAC file to read. - * \param tags The address where the returned pointer will be - * stored. The \a tags object must be deleted by - * the caller using FLAC__metadata_object_delete(). - * \assert - * \code filename != NULL \endcode - * \code tags != NULL \endcode - * \retval FLAC__bool - * \c true if a valid VORBIS_COMMENT block was read from \a filename, - * and \a *tags will be set to the address of the metadata structure. - * Returns \c false if there was a memory allocation error, a file - * decoder error, or the file contained no VORBIS_COMMENT block, and - * \a *tags will be set to \c NULL. - */ + function will try to skip any ID3v2 tag at the head of the file. + + \param filename The path to the FLAC file to read. + \param tags The address where the returned pointer will be + stored. The \a tags object must be deleted by + the caller using FLAC__metadata_object_delete(). + \assert + \code filename != NULL \endcode + \code tags != NULL \endcode + \retval FLAC__bool + \c true if a valid VORBIS_COMMENT block was read from \a filename, + and \a *tags will be set to the address of the metadata structure. + Returns \c false if there was a memory allocation error, a file + decoder error, or the file contained no VORBIS_COMMENT block, and + \a *tags will be set to \c NULL. +*/ FLAC_API FLAC__bool FLAC__metadata_get_tags(const char *filename, FLAC__StreamMetadata **tags); /** Read the CUESHEET metadata block of the given FLAC file. This - * function will try to skip any ID3v2 tag at the head of the file. - * - * \param filename The path to the FLAC file to read. - * \param cuesheet The address where the returned pointer will be - * stored. The \a cuesheet object must be deleted by - * the caller using FLAC__metadata_object_delete(). - * \assert - * \code filename != NULL \endcode - * \code cuesheet != NULL \endcode - * \retval FLAC__bool - * \c true if a valid CUESHEET block was read from \a filename, - * and \a *cuesheet will be set to the address of the metadata - * structure. Returns \c false if there was a memory allocation - * error, a file decoder error, or the file contained no CUESHEET - * block, and \a *cuesheet will be set to \c NULL. - */ + function will try to skip any ID3v2 tag at the head of the file. + + \param filename The path to the FLAC file to read. + \param cuesheet The address where the returned pointer will be + stored. The \a cuesheet object must be deleted by + the caller using FLAC__metadata_object_delete(). + \assert + \code filename != NULL \endcode + \code cuesheet != NULL \endcode + \retval FLAC__bool + \c true if a valid CUESHEET block was read from \a filename, + and \a *cuesheet will be set to the address of the metadata + structure. Returns \c false if there was a memory allocation + error, a file decoder error, or the file contained no CUESHEET + block, and \a *cuesheet will be set to \c NULL. +*/ FLAC_API FLAC__bool FLAC__metadata_get_cuesheet(const char *filename, FLAC__StreamMetadata **cuesheet); /** Read a PICTURE metadata block of the given FLAC file. This - * function will try to skip any ID3v2 tag at the head of the file. - * Since there can be more than one PICTURE block in a file, this - * function takes a number of parameters that act as constraints to - * the search. The PICTURE block with the largest area matching all - * the constraints will be returned, or \a *picture will be set to - * \c NULL if there was no such block. - * - * \param filename The path to the FLAC file to read. - * \param picture The address where the returned pointer will be - * stored. The \a picture object must be deleted by - * the caller using FLAC__metadata_object_delete(). - * \param type The desired picture type. Use \c -1 to mean - * "any type". - * \param mime_type The desired MIME type, e.g. "image/jpeg". The - * string will be matched exactly. Use \c NULL to - * mean "any MIME type". - * \param description The desired description. The string will be - * matched exactly. Use \c NULL to mean "any - * description". - * \param max_width The maximum width in pixels desired. Use - * \c (uint32_t)(-1) to mean "any width". - * \param max_height The maximum height in pixels desired. Use - * \c (uint32_t)(-1) to mean "any height". - * \param max_depth The maximum color depth in bits-per-pixel desired. - * Use \c (uint32_t)(-1) to mean "any depth". - * \param max_colors The maximum number of colors desired. Use - * \c (uint32_t)(-1) to mean "any number of colors". - * \assert - * \code filename != NULL \endcode - * \code picture != NULL \endcode - * \retval FLAC__bool - * \c true if a valid PICTURE block was read from \a filename, - * and \a *picture will be set to the address of the metadata - * structure. Returns \c false if there was a memory allocation - * error, a file decoder error, or the file contained no PICTURE - * block, and \a *picture will be set to \c NULL. - */ + function will try to skip any ID3v2 tag at the head of the file. + Since there can be more than one PICTURE block in a file, this + function takes a number of parameters that act as constraints to + the search. The PICTURE block with the largest area matching all + the constraints will be returned, or \a *picture will be set to + \c NULL if there was no such block. + + \param filename The path to the FLAC file to read. + \param picture The address where the returned pointer will be + stored. The \a picture object must be deleted by + the caller using FLAC__metadata_object_delete(). + \param type The desired picture type. Use \c -1 to mean + "any type". + \param mime_type The desired MIME type, e.g. "image/jpeg". The + string will be matched exactly. Use \c NULL to + mean "any MIME type". + \param description The desired description. The string will be + matched exactly. Use \c NULL to mean "any + description". + \param max_width The maximum width in pixels desired. Use + \c (uint32_t)(-1) to mean "any width". + \param max_height The maximum height in pixels desired. Use + \c (uint32_t)(-1) to mean "any height". + \param max_depth The maximum color depth in bits-per-pixel desired. + Use \c (uint32_t)(-1) to mean "any depth". + \param max_colors The maximum number of colors desired. Use + \c (uint32_t)(-1) to mean "any number of colors". + \assert + \code filename != NULL \endcode + \code picture != NULL \endcode + \retval FLAC__bool + \c true if a valid PICTURE block was read from \a filename, + and \a *picture will be set to the address of the metadata + structure. Returns \c false if there was a memory allocation + error, a file decoder error, or the file contained no PICTURE + block, and \a *picture will be set to \c NULL. +*/ FLAC_API FLAC__bool FLAC__metadata_get_picture(const char *filename, FLAC__StreamMetadata **picture, FLAC__StreamMetadata_Picture_Type type, const char *mime_type, const FLAC__byte *description, uint32_t max_width, uint32_t max_height, uint32_t max_depth, uint32_t max_colors); /* \} */ /** \defgroup flac_metadata_level1 FLAC/metadata.h: metadata level 1 interface - * \ingroup flac_metadata - * - * \brief - * The level 1 interface provides read-write access to FLAC file metadata and - * operates directly on the FLAC file. - * - * The general usage of this interface is: - * - * - Create an iterator using FLAC__metadata_simple_iterator_new() - * - Attach it to a file using FLAC__metadata_simple_iterator_init() and check - * the exit code. Call FLAC__metadata_simple_iterator_is_writable() to - * see if the file is writable, or only read access is allowed. - * - Use FLAC__metadata_simple_iterator_next() and - * FLAC__metadata_simple_iterator_prev() to traverse the blocks. - * This is does not read the actual blocks themselves. - * FLAC__metadata_simple_iterator_next() is relatively fast. - * FLAC__metadata_simple_iterator_prev() is slower since it needs to search - * forward from the front of the file. - * - Use FLAC__metadata_simple_iterator_get_block_type() or - * FLAC__metadata_simple_iterator_get_block() to access the actual data at - * the current iterator position. The returned object is yours to modify - * and free. - * - Use FLAC__metadata_simple_iterator_set_block() to write a modified block - * back. You must have write permission to the original file. Make sure to - * read the whole comment to FLAC__metadata_simple_iterator_set_block() - * below. - * - Use FLAC__metadata_simple_iterator_insert_block_after() to add new blocks. - * Use the object creation functions from - * \link flac_metadata_object here \endlink to generate new objects. - * - Use FLAC__metadata_simple_iterator_delete_block() to remove the block - * currently referred to by the iterator, or replace it with padding. - * - Destroy the iterator with FLAC__metadata_simple_iterator_delete() when - * finished. - * - * \note - * The FLAC file remains open the whole time between - * FLAC__metadata_simple_iterator_init() and - * FLAC__metadata_simple_iterator_delete(), so make sure you are not altering - * the file during this time. - * - * \note - * Do not modify the \a is_last, \a length, or \a type fields of returned - * FLAC__StreamMetadata objects. These are managed automatically. - * - * \note - * If any of the modification functions - * (FLAC__metadata_simple_iterator_set_block(), - * FLAC__metadata_simple_iterator_delete_block(), - * FLAC__metadata_simple_iterator_insert_block_after(), etc.) return \c false, - * you should delete the iterator as it may no longer be valid. - * - * \{ - */ + \ingroup flac_metadata + + \brief + The level 1 interface provides read-write access to FLAC file metadata and + operates directly on the FLAC file. + + The general usage of this interface is: + + - Create an iterator using FLAC__metadata_simple_iterator_new() + - Attach it to a file using FLAC__metadata_simple_iterator_init() and check + the exit code. Call FLAC__metadata_simple_iterator_is_writable() to + see if the file is writable, or only read access is allowed. + - Use FLAC__metadata_simple_iterator_next() and + FLAC__metadata_simple_iterator_prev() to traverse the blocks. + This is does not read the actual blocks themselves. + FLAC__metadata_simple_iterator_next() is relatively fast. + FLAC__metadata_simple_iterator_prev() is slower since it needs to search + forward from the front of the file. + - Use FLAC__metadata_simple_iterator_get_block_type() or + FLAC__metadata_simple_iterator_get_block() to access the actual data at + the current iterator position. The returned object is yours to modify + and free. + - Use FLAC__metadata_simple_iterator_set_block() to write a modified block + back. You must have write permission to the original file. Make sure to + read the whole comment to FLAC__metadata_simple_iterator_set_block() + below. + - Use FLAC__metadata_simple_iterator_insert_block_after() to add new blocks. + Use the object creation functions from + \link flac_metadata_object here \endlink to generate new objects. + - Use FLAC__metadata_simple_iterator_delete_block() to remove the block + currently referred to by the iterator, or replace it with padding. + - Destroy the iterator with FLAC__metadata_simple_iterator_delete() when + finished. + + \note + The FLAC file remains open the whole time between + FLAC__metadata_simple_iterator_init() and + FLAC__metadata_simple_iterator_delete(), so make sure you are not altering + the file during this time. + + \note + Do not modify the \a is_last, \a length, or \a type fields of returned + FLAC__StreamMetadata objects. These are managed automatically. + + \note + If any of the modification functions + (FLAC__metadata_simple_iterator_set_block(), + FLAC__metadata_simple_iterator_delete_block(), + FLAC__metadata_simple_iterator_insert_block_after(), etc.) return \c false, + you should delete the iterator as it may no longer be valid. + + \{ +*/ struct FLAC__Metadata_SimpleIterator; /** The opaque structure definition for the level 1 iterator type. - * See the - * \link flac_metadata_level1 metadata level 1 module \endlink - * for a detailed description. - */ + See the + \link flac_metadata_level1 metadata level 1 module \endlink + for a detailed description. +*/ typedef struct FLAC__Metadata_SimpleIterator FLAC__Metadata_SimpleIterator; /** Status type for FLAC__Metadata_SimpleIterator. - * - * The iterator's current status can be obtained by calling FLAC__metadata_simple_iterator_status(). - */ + + The iterator's current status can be obtained by calling FLAC__metadata_simple_iterator_status(). +*/ typedef enum { - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK = 0, - /**< The iterator is in the normal OK state */ + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK = 0, + /**< The iterator is in the normal OK state */ - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT, - /**< The data passed into a function violated the function's usage criteria */ + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT, + /**< The data passed into a function violated the function's usage criteria */ - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE, - /**< The iterator could not open the target file */ + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE, + /**< The iterator could not open the target file */ - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE, - /**< The iterator could not find the FLAC signature at the start of the file */ + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE, + /**< The iterator could not find the FLAC signature at the start of the file */ - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE, - /**< The iterator tried to write to a file that was not writable */ + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE, + /**< The iterator tried to write to a file that was not writable */ - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA, - /**< The iterator encountered input that does not conform to the FLAC metadata specification */ + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA, + /**< The iterator encountered input that does not conform to the FLAC metadata specification */ - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR, - /**< The iterator encountered an error while reading the FLAC file */ + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR, + /**< The iterator encountered an error while reading the FLAC file */ - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR, - /**< The iterator encountered an error while seeking in the FLAC file */ + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR, + /**< The iterator encountered an error while seeking in the FLAC file */ - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR, - /**< The iterator encountered an error while writing the FLAC file */ + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR, + /**< The iterator encountered an error while writing the FLAC file */ - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR, - /**< The iterator encountered an error renaming the FLAC file */ + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR, + /**< The iterator encountered an error renaming the FLAC file */ - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR, - /**< The iterator encountered an error removing the temporary file */ + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR, + /**< The iterator encountered an error removing the temporary file */ - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR, - /**< Memory allocation failed */ + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR, + /**< Memory allocation failed */ - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR - /**< The caller violated an assertion or an unexpected error occurred */ + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR + /**< The caller violated an assertion or an unexpected error occurred */ } FLAC__Metadata_SimpleIteratorStatus; /** Maps a FLAC__Metadata_SimpleIteratorStatus to a C string. - * - * Using a FLAC__Metadata_SimpleIteratorStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ + + Using a FLAC__Metadata_SimpleIteratorStatus as the index to this array + will give the string equivalent. The contents should not be modified. +*/ extern FLAC_API const char * const FLAC__Metadata_SimpleIteratorStatusString[]; /** Create a new iterator instance. - * - * \retval FLAC__Metadata_SimpleIterator* - * \c NULL if there was an error allocating memory, else the new instance. - */ + + \retval FLAC__Metadata_SimpleIterator + \c NULL if there was an error allocating memory, else the new instance. +*/ FLAC_API FLAC__Metadata_SimpleIterator *FLAC__metadata_simple_iterator_new(void); /** Free an iterator instance. Deletes the object pointed to by \a iterator. - * - * \param iterator A pointer to an existing iterator. - * \assert - * \code iterator != NULL \endcode - */ + + \param iterator A pointer to an existing iterator. + \assert + \code iterator != NULL \endcode +*/ FLAC_API void FLAC__metadata_simple_iterator_delete(FLAC__Metadata_SimpleIterator *iterator); /** Get the current status of the iterator. Call this after a function - * returns \c false to get the reason for the error. Also resets the status - * to FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK. - * - * \param iterator A pointer to an existing iterator. - * \assert - * \code iterator != NULL \endcode - * \retval FLAC__Metadata_SimpleIteratorStatus - * The current status of the iterator. - */ + returns \c false to get the reason for the error. Also resets the status + to FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK. + + \param iterator A pointer to an existing iterator. + \assert + \code iterator != NULL \endcode + \retval FLAC__Metadata_SimpleIteratorStatus + The current status of the iterator. +*/ FLAC_API FLAC__Metadata_SimpleIteratorStatus FLAC__metadata_simple_iterator_status(FLAC__Metadata_SimpleIterator *iterator); /** Initialize the iterator to point to the first metadata block in the - * given FLAC file. - * - * \param iterator A pointer to an existing iterator. - * \param filename The path to the FLAC file. - * \param read_only If \c true, the FLAC file will be opened - * in read-only mode; if \c false, the FLAC - * file will be opened for edit even if no - * edits are performed. - * \param preserve_file_stats If \c true, the owner and modification - * time will be preserved even if the FLAC - * file is written to. - * \assert - * \code iterator != NULL \endcode - * \code filename != NULL \endcode - * \retval FLAC__bool - * \c false if a memory allocation error occurs, the file can't be - * opened, or another error occurs, else \c true. - */ + given FLAC file. + + \param iterator A pointer to an existing iterator. + \param filename The path to the FLAC file. + \param read_only If \c true, the FLAC file will be opened + in read-only mode; if \c false, the FLAC + file will be opened for edit even if no + edits are performed. + \param preserve_file_stats If \c true, the owner and modification + time will be preserved even if the FLAC + file is written to. + \assert + \code iterator != NULL \endcode + \code filename != NULL \endcode + \retval FLAC__bool + \c false if a memory allocation error occurs, the file can't be + opened, or another error occurs, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool read_only, FLAC__bool preserve_file_stats); /** Returns \c true if the FLAC file is writable. If \c false, calls to - * FLAC__metadata_simple_iterator_set_block() and - * FLAC__metadata_simple_iterator_insert_block_after() will fail. - * - * \param iterator A pointer to an existing iterator. - * \assert - * \code iterator != NULL \endcode - * \retval FLAC__bool - * See above. - */ + FLAC__metadata_simple_iterator_set_block() and + FLAC__metadata_simple_iterator_insert_block_after() will fail. + + \param iterator A pointer to an existing iterator. + \assert + \code iterator != NULL \endcode + \retval FLAC__bool + See above. +*/ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_writable(const FLAC__Metadata_SimpleIterator *iterator); /** Moves the iterator forward one metadata block, returning \c false if - * already at the end. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval FLAC__bool - * \c false if already at the last metadata block of the chain, else - * \c true. - */ + already at the end. + + \param iterator A pointer to an existing initialized iterator. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_simple_iterator_init() + \retval FLAC__bool + \c false if already at the last metadata block of the chain, else + \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_next(FLAC__Metadata_SimpleIterator *iterator); /** Moves the iterator backward one metadata block, returning \c false if - * already at the beginning. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval FLAC__bool - * \c false if already at the first metadata block of the chain, else - * \c true. - */ + already at the beginning. + + \param iterator A pointer to an existing initialized iterator. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_simple_iterator_init() + \retval FLAC__bool + \c false if already at the first metadata block of the chain, else + \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator); /** Returns a flag telling if the current metadata block is the last. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval FLAC__bool - * \c true if the current metadata block is the last in the file, - * else \c false. - */ + + \param iterator A pointer to an existing initialized iterator. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_simple_iterator_init() + \retval FLAC__bool + \c true if the current metadata block is the last in the file, + else \c false. +*/ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_last(const FLAC__Metadata_SimpleIterator *iterator); /** Get the offset of the metadata block at the current position. This - * avoids reading the actual block data which can save time for large - * blocks. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval off_t - * The offset of the metadata block at the current iterator position. - * This is the byte offset relative to the beginning of the file of - * the current metadata block's header. - */ + avoids reading the actual block data which can save time for large + blocks. + + \param iterator A pointer to an existing initialized iterator. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_simple_iterator_init() + \retval off_t + The offset of the metadata block at the current iterator position. + This is the byte offset relative to the beginning of the file of + the current metadata block's header. +*/ FLAC_API off_t FLAC__metadata_simple_iterator_get_block_offset(const FLAC__Metadata_SimpleIterator *iterator); /** Get the type of the metadata block at the current position. This - * avoids reading the actual block data which can save time for large - * blocks. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval FLAC__MetadataType - * The type of the metadata block at the current iterator position. - */ + avoids reading the actual block data which can save time for large + blocks. + + \param iterator A pointer to an existing initialized iterator. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_simple_iterator_init() + \retval FLAC__MetadataType + The type of the metadata block at the current iterator position. +*/ FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator); /** Get the length of the metadata block at the current position. This - * avoids reading the actual block data which can save time for large - * blocks. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval uint32_t - * The length of the metadata block at the current iterator position. - * The is same length as that in the - * metadata block header, - * i.e. the length of the metadata body that follows the header. - */ + avoids reading the actual block data which can save time for large + blocks. + + \param iterator A pointer to an existing initialized iterator. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_simple_iterator_init() + \retval uint32_t + The length of the metadata block at the current iterator position. + The is same length as that in the + metadata block header, + i.e. the length of the metadata body that follows the header. +*/ FLAC_API uint32_t FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator); /** Get the application ID of the \c APPLICATION block at the current - * position. This avoids reading the actual block data which can save - * time for large blocks. - * - * \param iterator A pointer to an existing initialized iterator. - * \param id A pointer to a buffer of at least \c 4 bytes where - * the ID will be stored. - * \assert - * \code iterator != NULL \endcode - * \code id != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval FLAC__bool - * \c true if the ID was successfully read, else \c false, in which - * case you should check FLAC__metadata_simple_iterator_status() to - * find out why. If the status is - * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT, then the - * current metadata block is not an \c APPLICATION block. Otherwise - * if the status is - * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR or - * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR, an I/O error - * occurred and the iterator can no longer be used. - */ + position. This avoids reading the actual block data which can save + time for large blocks. + + \param iterator A pointer to an existing initialized iterator. + \param id A pointer to a buffer of at least \c 4 bytes where + the ID will be stored. + \assert + \code iterator != NULL \endcode + \code id != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_simple_iterator_init() + \retval FLAC__bool + \c true if the ID was successfully read, else \c false, in which + case you should check FLAC__metadata_simple_iterator_status() to + find out why. If the status is + \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT, then the + current metadata block is not an \c APPLICATION block. Otherwise + if the status is + \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR or + \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR, an I/O error + occurred and the iterator can no longer be used. +*/ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_get_application_id(FLAC__Metadata_SimpleIterator *iterator, FLAC__byte *id); /** Get the metadata block at the current position. You can modify the - * block but must use FLAC__metadata_simple_iterator_set_block() to - * write it back to the FLAC file. - * - * You must call FLAC__metadata_object_delete() on the returned object - * when you are finished with it. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval FLAC__StreamMetadata* - * The current metadata block, or \c NULL if there was a memory - * allocation error. - */ + block but must use FLAC__metadata_simple_iterator_set_block() to + write it back to the FLAC file. + + You must call FLAC__metadata_object_delete() on the returned object + when you are finished with it. + + \param iterator A pointer to an existing initialized iterator. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_simple_iterator_init() + \retval FLAC__StreamMetadata + The current metadata block, or \c NULL if there was a memory + allocation error. +*/ FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator); /** Write a block back to the FLAC file. This function tries to be - * as efficient as possible; how the block is actually written is - * shown by the following: - * - * Existing block is a STREAMINFO block and the new block is a - * STREAMINFO block: the new block is written in place. Make sure - * you know what you're doing when changing the values of a - * STREAMINFO block. - * - * Existing block is a STREAMINFO block and the new block is a - * not a STREAMINFO block: this is an error since the first block - * must be a STREAMINFO block. Returns \c false without altering the - * file. - * - * Existing block is not a STREAMINFO block and the new block is a - * STREAMINFO block: this is an error since there may be only one - * STREAMINFO block. Returns \c false without altering the file. - * - * Existing block and new block are the same length: the existing - * block will be replaced by the new block, written in place. - * - * Existing block is longer than new block: if use_padding is \c true, - * the existing block will be overwritten in place with the new - * block followed by a PADDING block, if possible, to make the total - * size the same as the existing block. Remember that a padding - * block requires at least four bytes so if the difference in size - * between the new block and existing block is less than that, the - * entire file will have to be rewritten, using the new block's - * exact size. If use_padding is \c false, the entire file will be - * rewritten, replacing the existing block by the new block. - * - * Existing block is shorter than new block: if use_padding is \c true, - * the function will try and expand the new block into the following - * PADDING block, if it exists and doing so won't shrink the PADDING - * block to less than 4 bytes. If there is no following PADDING - * block, or it will shrink to less than 4 bytes, or use_padding is - * \c false, the entire file is rewritten, replacing the existing block - * with the new block. Note that in this case any following PADDING - * block is preserved as is. - * - * After writing the block, the iterator will remain in the same - * place, i.e. pointing to the new block. - * - * \param iterator A pointer to an existing initialized iterator. - * \param block The block to set. - * \param use_padding See above. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \code block != NULL \endcode - * \retval FLAC__bool - * \c true if successful, else \c false. - */ + as efficient as possible; how the block is actually written is + shown by the following: + + Existing block is a STREAMINFO block and the new block is a + STREAMINFO block: the new block is written in place. Make sure + you know what you're doing when changing the values of a + STREAMINFO block. + + Existing block is a STREAMINFO block and the new block is a + not a STREAMINFO block: this is an error since the first block + must be a STREAMINFO block. Returns \c false without altering the + file. + + Existing block is not a STREAMINFO block and the new block is a + STREAMINFO block: this is an error since there may be only one + STREAMINFO block. Returns \c false without altering the file. + + Existing block and new block are the same length: the existing + block will be replaced by the new block, written in place. + + Existing block is longer than new block: if use_padding is \c true, + the existing block will be overwritten in place with the new + block followed by a PADDING block, if possible, to make the total + size the same as the existing block. Remember that a padding + block requires at least four bytes so if the difference in size + between the new block and existing block is less than that, the + entire file will have to be rewritten, using the new block's + exact size. If use_padding is \c false, the entire file will be + rewritten, replacing the existing block by the new block. + + Existing block is shorter than new block: if use_padding is \c true, + the function will try and expand the new block into the following + PADDING block, if it exists and doing so won't shrink the PADDING + block to less than 4 bytes. If there is no following PADDING + block, or it will shrink to less than 4 bytes, or use_padding is + \c false, the entire file is rewritten, replacing the existing block + with the new block. Note that in this case any following PADDING + block is preserved as is. + + After writing the block, the iterator will remain in the same + place, i.e. pointing to the new block. + + \param iterator A pointer to an existing initialized iterator. + \param block The block to set. + \param use_padding See above. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_simple_iterator_init() + \code block != NULL \endcode + \retval FLAC__bool + \c true if successful, else \c false. +*/ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_set_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding); /** This is similar to FLAC__metadata_simple_iterator_set_block() - * except that instead of writing over an existing block, it appends - * a block after the existing block. \a use_padding is again used to - * tell the function to try an expand into following padding in an - * attempt to avoid rewriting the entire file. - * - * This function will fail and return \c false if given a STREAMINFO - * block. - * - * After writing the block, the iterator will be pointing to the - * new block. - * - * \param iterator A pointer to an existing initialized iterator. - * \param block The block to set. - * \param use_padding See above. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \code block != NULL \endcode - * \retval FLAC__bool - * \c true if successful, else \c false. - */ + except that instead of writing over an existing block, it appends + a block after the existing block. \a use_padding is again used to + tell the function to try an expand into following padding in an + attempt to avoid rewriting the entire file. + + This function will fail and return \c false if given a STREAMINFO + block. + + After writing the block, the iterator will be pointing to the + new block. + + \param iterator A pointer to an existing initialized iterator. + \param block The block to set. + \param use_padding See above. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_simple_iterator_init() + \code block != NULL \endcode + \retval FLAC__bool + \c true if successful, else \c false. +*/ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_insert_block_after(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding); /** Deletes the block at the current position. This will cause the - * entire FLAC file to be rewritten, unless \a use_padding is \c true, - * in which case the block will be replaced by an equal-sized PADDING - * block. The iterator will be left pointing to the block before the - * one just deleted. - * - * You may not delete the STREAMINFO block. - * - * \param iterator A pointer to an existing initialized iterator. - * \param use_padding See above. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval FLAC__bool - * \c true if successful, else \c false. - */ + entire FLAC file to be rewritten, unless \a use_padding is \c true, + in which case the block will be replaced by an equal-sized PADDING + block. The iterator will be left pointing to the block before the + one just deleted. + + You may not delete the STREAMINFO block. + + \param iterator A pointer to an existing initialized iterator. + \param use_padding See above. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_simple_iterator_init() + \retval FLAC__bool + \c true if successful, else \c false. +*/ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_delete_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool use_padding); /* \} */ /** \defgroup flac_metadata_level2 FLAC/metadata.h: metadata level 2 interface - * \ingroup flac_metadata - * - * \brief - * The level 2 interface provides read-write access to FLAC file metadata; - * all metadata is read into memory, operated on in memory, and then written - * to file, which is more efficient than level 1 when editing multiple blocks. - * - * Currently Ogg FLAC is supported for read only, via - * FLAC__metadata_chain_read_ogg() but a subsequent - * FLAC__metadata_chain_write() will fail. - * - * The general usage of this interface is: - * - * - Create a new chain using FLAC__metadata_chain_new(). A chain is a - * linked list of FLAC metadata blocks. - * - Read all metadata into the chain from a FLAC file using - * FLAC__metadata_chain_read() or FLAC__metadata_chain_read_ogg() and - * check the status. - * - Optionally, consolidate the padding using - * FLAC__metadata_chain_merge_padding() or - * FLAC__metadata_chain_sort_padding(). - * - Create a new iterator using FLAC__metadata_iterator_new() - * - Initialize the iterator to point to the first element in the chain - * using FLAC__metadata_iterator_init() - * - Traverse the chain using FLAC__metadata_iterator_next and - * FLAC__metadata_iterator_prev(). - * - Get a block for reading or modification using - * FLAC__metadata_iterator_get_block(). The pointer to the object - * inside the chain is returned, so the block is yours to modify. - * Changes will be reflected in the FLAC file when you write the - * chain. You can also add and delete blocks (see functions below). - * - When done, write out the chain using FLAC__metadata_chain_write(). - * Make sure to read the whole comment to the function below. - * - Delete the chain using FLAC__metadata_chain_delete(). - * - * \note - * Even though the FLAC file is not open while the chain is being - * manipulated, you must not alter the file externally during - * this time. The chain assumes the FLAC file will not change - * between the time of FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg() - * and FLAC__metadata_chain_write(). - * - * \note - * Do not modify the is_last, length, or type fields of returned - * FLAC__StreamMetadata objects. These are managed automatically. - * - * \note - * The metadata objects returned by FLAC__metadata_iterator_get_block() - * are owned by the chain; do not FLAC__metadata_object_delete() them. - * In the same way, blocks passed to FLAC__metadata_iterator_set_block() - * become owned by the chain and they will be deleted when the chain is - * deleted. - * - * \{ - */ + \ingroup flac_metadata + + \brief + The level 2 interface provides read-write access to FLAC file metadata; + all metadata is read into memory, operated on in memory, and then written + to file, which is more efficient than level 1 when editing multiple blocks. + + Currently Ogg FLAC is supported for read only, via + FLAC__metadata_chain_read_ogg() but a subsequent + FLAC__metadata_chain_write() will fail. + + The general usage of this interface is: + + - Create a new chain using FLAC__metadata_chain_new(). A chain is a + linked list of FLAC metadata blocks. + - Read all metadata into the chain from a FLAC file using + FLAC__metadata_chain_read() or FLAC__metadata_chain_read_ogg() and + check the status. + - Optionally, consolidate the padding using + FLAC__metadata_chain_merge_padding() or + FLAC__metadata_chain_sort_padding(). + - Create a new iterator using FLAC__metadata_iterator_new() + - Initialize the iterator to point to the first element in the chain + using FLAC__metadata_iterator_init() + - Traverse the chain using FLAC__metadata_iterator_next and + FLAC__metadata_iterator_prev(). + - Get a block for reading or modification using + FLAC__metadata_iterator_get_block(). The pointer to the object + inside the chain is returned, so the block is yours to modify. + Changes will be reflected in the FLAC file when you write the + chain. You can also add and delete blocks (see functions below). + - When done, write out the chain using FLAC__metadata_chain_write(). + Make sure to read the whole comment to the function below. + - Delete the chain using FLAC__metadata_chain_delete(). + + \note + Even though the FLAC file is not open while the chain is being + manipulated, you must not alter the file externally during + this time. The chain assumes the FLAC file will not change + between the time of FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg() + and FLAC__metadata_chain_write(). + + \note + Do not modify the is_last, length, or type fields of returned + FLAC__StreamMetadata objects. These are managed automatically. + + \note + The metadata objects returned by FLAC__metadata_iterator_get_block() + are owned by the chain; do not FLAC__metadata_object_delete() them. + In the same way, blocks passed to FLAC__metadata_iterator_set_block() + become owned by the chain and they will be deleted when the chain is + deleted. + + \{ +*/ struct FLAC__Metadata_Chain; /** The opaque structure definition for the level 2 chain type. - */ +*/ typedef struct FLAC__Metadata_Chain FLAC__Metadata_Chain; struct FLAC__Metadata_Iterator; /** The opaque structure definition for the level 2 iterator type. - */ +*/ typedef struct FLAC__Metadata_Iterator FLAC__Metadata_Iterator; typedef enum { - FLAC__METADATA_CHAIN_STATUS_OK = 0, - /**< The chain is in the normal OK state */ + FLAC__METADATA_CHAIN_STATUS_OK = 0, + /**< The chain is in the normal OK state */ - FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT, - /**< The data passed into a function violated the function's usage criteria */ + FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT, + /**< The data passed into a function violated the function's usage criteria */ - FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE, - /**< The chain could not open the target file */ + FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE, + /**< The chain could not open the target file */ - FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE, - /**< The chain could not find the FLAC signature at the start of the file */ + FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE, + /**< The chain could not find the FLAC signature at the start of the file */ - FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE, - /**< The chain tried to write to a file that was not writable */ + FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE, + /**< The chain tried to write to a file that was not writable */ - FLAC__METADATA_CHAIN_STATUS_BAD_METADATA, - /**< The chain encountered input that does not conform to the FLAC metadata specification */ + FLAC__METADATA_CHAIN_STATUS_BAD_METADATA, + /**< The chain encountered input that does not conform to the FLAC metadata specification */ - FLAC__METADATA_CHAIN_STATUS_READ_ERROR, - /**< The chain encountered an error while reading the FLAC file */ + FLAC__METADATA_CHAIN_STATUS_READ_ERROR, + /**< The chain encountered an error while reading the FLAC file */ - FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR, - /**< The chain encountered an error while seeking in the FLAC file */ + FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR, + /**< The chain encountered an error while seeking in the FLAC file */ - FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR, - /**< The chain encountered an error while writing the FLAC file */ + FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR, + /**< The chain encountered an error while writing the FLAC file */ - FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR, - /**< The chain encountered an error renaming the FLAC file */ + FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR, + /**< The chain encountered an error renaming the FLAC file */ - FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR, - /**< The chain encountered an error removing the temporary file */ + FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR, + /**< The chain encountered an error removing the temporary file */ - FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR, - /**< Memory allocation failed */ + FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR, + /**< Memory allocation failed */ - FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR, - /**< The caller violated an assertion or an unexpected error occurred */ + FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR, + /**< The caller violated an assertion or an unexpected error occurred */ - FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS, - /**< One or more of the required callbacks was NULL */ + FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS, + /**< One or more of the required callbacks was NULL */ - FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH, - /**< FLAC__metadata_chain_write() was called on a chain read by - * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), - * or - * FLAC__metadata_chain_write_with_callbacks()/FLAC__metadata_chain_write_with_callbacks_and_tempfile() - * was called on a chain read by - * FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). - * Matching read/write methods must always be used. */ + FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH, + /** < FLAC__metadata_chain_write() was called on a chain read by + FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), + or + FLAC__metadata_chain_write_with_callbacks()/FLAC__metadata_chain_write_with_callbacks_and_tempfile() + was called on a chain read by + FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). + Matching read/write methods must always be used. */ - FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL - /**< FLAC__metadata_chain_write_with_callbacks() was called when the - * chain write requires a tempfile; use - * FLAC__metadata_chain_write_with_callbacks_and_tempfile() instead. - * Or, FLAC__metadata_chain_write_with_callbacks_and_tempfile() was - * called when the chain write does not require a tempfile; use - * FLAC__metadata_chain_write_with_callbacks() instead. - * Always check FLAC__metadata_chain_check_if_tempfile_needed() - * before writing via callbacks. */ + FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL + /** < FLAC__metadata_chain_write_with_callbacks() was called when the + chain write requires a tempfile; use + FLAC__metadata_chain_write_with_callbacks_and_tempfile() instead. + Or, FLAC__metadata_chain_write_with_callbacks_and_tempfile() was + called when the chain write does not require a tempfile; use + FLAC__metadata_chain_write_with_callbacks() instead. + Always check FLAC__metadata_chain_check_if_tempfile_needed() + before writing via callbacks. */ } FLAC__Metadata_ChainStatus; /** Maps a FLAC__Metadata_ChainStatus to a C string. - * - * Using a FLAC__Metadata_ChainStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ + + Using a FLAC__Metadata_ChainStatus as the index to this array + will give the string equivalent. The contents should not be modified. +*/ extern FLAC_API const char * const FLAC__Metadata_ChainStatusString[]; /*********** FLAC__Metadata_Chain ***********/ /** Create a new chain instance. - * - * \retval FLAC__Metadata_Chain* - * \c NULL if there was an error allocating memory, else the new instance. - */ + + \retval FLAC__Metadata_Chain + \c NULL if there was an error allocating memory, else the new instance. +*/ FLAC_API FLAC__Metadata_Chain *FLAC__metadata_chain_new(void); /** Free a chain instance. Deletes the object pointed to by \a chain. - * - * \param chain A pointer to an existing chain. - * \assert - * \code chain != NULL \endcode - */ + + \param chain A pointer to an existing chain. + \assert + \code chain != NULL \endcode +*/ FLAC_API void FLAC__metadata_chain_delete(FLAC__Metadata_Chain *chain); /** Get the current status of the chain. Call this after a function - * returns \c false to get the reason for the error. Also resets the - * status to FLAC__METADATA_CHAIN_STATUS_OK. - * - * \param chain A pointer to an existing chain. - * \assert - * \code chain != NULL \endcode - * \retval FLAC__Metadata_ChainStatus - * The current status of the chain. - */ + returns \c false to get the reason for the error. Also resets the + status to FLAC__METADATA_CHAIN_STATUS_OK. + + \param chain A pointer to an existing chain. + \assert + \code chain != NULL \endcode + \retval FLAC__Metadata_ChainStatus + The current status of the chain. +*/ FLAC_API FLAC__Metadata_ChainStatus FLAC__metadata_chain_status(FLAC__Metadata_Chain *chain); /** Read all metadata from a FLAC file into the chain. - * - * \param chain A pointer to an existing chain. - * \param filename The path to the FLAC file to read. - * \assert - * \code chain != NULL \endcode - * \code filename != NULL \endcode - * \retval FLAC__bool - * \c true if a valid list of metadata blocks was read from - * \a filename, else \c false. On failure, check the status with - * FLAC__metadata_chain_status(). - */ + + \param chain A pointer to an existing chain. + \param filename The path to the FLAC file to read. + \assert + \code chain != NULL \endcode + \code filename != NULL \endcode + \retval FLAC__bool + \c true if a valid list of metadata blocks was read from + \a filename, else \c false. On failure, check the status with + FLAC__metadata_chain_status(). +*/ FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const char *filename); /** Read all metadata from an Ogg FLAC file into the chain. - * - * \note Ogg FLAC metadata data writing is not supported yet and - * FLAC__metadata_chain_write() will fail. - * - * \param chain A pointer to an existing chain. - * \param filename The path to the Ogg FLAC file to read. - * \assert - * \code chain != NULL \endcode - * \code filename != NULL \endcode - * \retval FLAC__bool - * \c true if a valid list of metadata blocks was read from - * \a filename, else \c false. On failure, check the status with - * FLAC__metadata_chain_status(). - */ + + \note Ogg FLAC metadata data writing is not supported yet and + FLAC__metadata_chain_write() will fail. + + \param chain A pointer to an existing chain. + \param filename The path to the Ogg FLAC file to read. + \assert + \code chain != NULL \endcode + \code filename != NULL \endcode + \retval FLAC__bool + \c true if a valid list of metadata blocks was read from + \a filename, else \c false. On failure, check the status with + FLAC__metadata_chain_status(). +*/ FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg(FLAC__Metadata_Chain *chain, const char *filename); /** Read all metadata from a FLAC stream into the chain via I/O callbacks. - * - * The \a handle need only be open for reading, but must be seekable. - * The equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" - * for Windows). - * - * \param chain A pointer to an existing chain. - * \param handle The I/O handle of the FLAC stream to read. The - * handle will NOT be closed after the metadata is read; - * that is the duty of the caller. - * \param callbacks - * A set of callbacks to use for I/O. The mandatory - * callbacks are \a read, \a seek, and \a tell. - * \assert - * \code chain != NULL \endcode - * \retval FLAC__bool - * \c true if a valid list of metadata blocks was read from - * \a handle, else \c false. On failure, check the status with - * FLAC__metadata_chain_status(). - */ + + The \a handle need only be open for reading, but must be seekable. + The equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" + for Windows). + + \param chain A pointer to an existing chain. + \param handle The I/O handle of the FLAC stream to read. The + handle will NOT be closed after the metadata is read; + that is the duty of the caller. + \param callbacks + A set of callbacks to use for I/O. The mandatory + callbacks are \a read, \a seek, and \a tell. + \assert + \code chain != NULL \endcode + \retval FLAC__bool + \c true if a valid list of metadata blocks was read from + \a handle, else \c false. On failure, check the status with + FLAC__metadata_chain_status(). +*/ FLAC_API FLAC__bool FLAC__metadata_chain_read_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks); /** Read all metadata from an Ogg FLAC stream into the chain via I/O callbacks. - * - * The \a handle need only be open for reading, but must be seekable. - * The equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" - * for Windows). - * - * \note Ogg FLAC metadata data writing is not supported yet and - * FLAC__metadata_chain_write() will fail. - * - * \param chain A pointer to an existing chain. - * \param handle The I/O handle of the Ogg FLAC stream to read. The - * handle will NOT be closed after the metadata is read; - * that is the duty of the caller. - * \param callbacks - * A set of callbacks to use for I/O. The mandatory - * callbacks are \a read, \a seek, and \a tell. - * \assert - * \code chain != NULL \endcode - * \retval FLAC__bool - * \c true if a valid list of metadata blocks was read from - * \a handle, else \c false. On failure, check the status with - * FLAC__metadata_chain_status(). - */ + + The \a handle need only be open for reading, but must be seekable. + The equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" + for Windows). + + \note Ogg FLAC metadata data writing is not supported yet and + FLAC__metadata_chain_write() will fail. + + \param chain A pointer to an existing chain. + \param handle The I/O handle of the Ogg FLAC stream to read. The + handle will NOT be closed after the metadata is read; + that is the duty of the caller. + \param callbacks + A set of callbacks to use for I/O. The mandatory + callbacks are \a read, \a seek, and \a tell. + \assert + \code chain != NULL \endcode + \retval FLAC__bool + \c true if a valid list of metadata blocks was read from + \a handle, else \c false. On failure, check the status with + FLAC__metadata_chain_status(). +*/ FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks); /** Checks if writing the given chain would require the use of a - * temporary file, or if it could be written in place. - * - * Under certain conditions, padding can be utilized so that writing - * edited metadata back to the FLAC file does not require rewriting the - * entire file. If rewriting is required, then a temporary workfile is - * required. When writing metadata using callbacks, you must check - * this function to know whether to call - * FLAC__metadata_chain_write_with_callbacks() or - * FLAC__metadata_chain_write_with_callbacks_and_tempfile(). When - * writing with FLAC__metadata_chain_write(), the temporary file is - * handled internally. - * - * \param chain A pointer to an existing chain. - * \param use_padding - * Whether or not padding will be allowed to be used - * during the write. The value of \a use_padding given - * here must match the value later passed to - * FLAC__metadata_chain_write_with_callbacks() or - * FLAC__metadata_chain_write_with_callbacks_with_tempfile(). - * \assert - * \code chain != NULL \endcode - * \retval FLAC__bool - * \c true if writing the current chain would require a tempfile, or - * \c false if metadata can be written in place. - */ + temporary file, or if it could be written in place. + + Under certain conditions, padding can be utilized so that writing + edited metadata back to the FLAC file does not require rewriting the + entire file. If rewriting is required, then a temporary workfile is + required. When writing metadata using callbacks, you must check + this function to know whether to call + FLAC__metadata_chain_write_with_callbacks() or + FLAC__metadata_chain_write_with_callbacks_and_tempfile(). When + writing with FLAC__metadata_chain_write(), the temporary file is + handled internally. + + \param chain A pointer to an existing chain. + \param use_padding + Whether or not padding will be allowed to be used + during the write. The value of \a use_padding given + here must match the value later passed to + FLAC__metadata_chain_write_with_callbacks() or + FLAC__metadata_chain_write_with_callbacks_with_tempfile(). + \assert + \code chain != NULL \endcode + \retval FLAC__bool + \c true if writing the current chain would require a tempfile, or + \c false if metadata can be written in place. +*/ FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata_Chain *chain, FLAC__bool use_padding); /** Write all metadata out to the FLAC file. This function tries to be as - * efficient as possible; how the metadata is actually written is shown by - * the following: - * - * If the current chain is the same size as the existing metadata, the new - * data is written in place. - * - * If the current chain is longer than the existing metadata, and - * \a use_padding is \c true, and the last block is a PADDING block of - * sufficient length, the function will truncate the final padding block - * so that the overall size of the metadata is the same as the existing - * metadata, and then just rewrite the metadata. Otherwise, if not all of - * the above conditions are met, the entire FLAC file must be rewritten. - * If you want to use padding this way it is a good idea to call - * FLAC__metadata_chain_sort_padding() first so that you have the maximum - * amount of padding to work with, unless you need to preserve ordering - * of the PADDING blocks for some reason. - * - * If the current chain is shorter than the existing metadata, and - * \a use_padding is \c true, and the final block is a PADDING block, the padding - * is extended to make the overall size the same as the existing data. If - * \a use_padding is \c true and the last block is not a PADDING block, a new - * PADDING block is added to the end of the new data to make it the same - * size as the existing data (if possible, see the note to - * FLAC__metadata_simple_iterator_set_block() about the four byte limit) - * and the new data is written in place. If none of the above apply or - * \a use_padding is \c false, the entire FLAC file is rewritten. - * - * If \a preserve_file_stats is \c true, the owner and modification time will - * be preserved even if the FLAC file is written. - * - * For this write function to be used, the chain must have been read with - * FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(), not - * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(). - * - * \param chain A pointer to an existing chain. - * \param use_padding See above. - * \param preserve_file_stats See above. - * \assert - * \code chain != NULL \endcode - * \retval FLAC__bool - * \c true if the write succeeded, else \c false. On failure, - * check the status with FLAC__metadata_chain_status(). - */ + efficient as possible; how the metadata is actually written is shown by + the following: + + If the current chain is the same size as the existing metadata, the new + data is written in place. + + If the current chain is longer than the existing metadata, and + \a use_padding is \c true, and the last block is a PADDING block of + sufficient length, the function will truncate the final padding block + so that the overall size of the metadata is the same as the existing + metadata, and then just rewrite the metadata. Otherwise, if not all of + the above conditions are met, the entire FLAC file must be rewritten. + If you want to use padding this way it is a good idea to call + FLAC__metadata_chain_sort_padding() first so that you have the maximum + amount of padding to work with, unless you need to preserve ordering + of the PADDING blocks for some reason. + + If the current chain is shorter than the existing metadata, and + \a use_padding is \c true, and the final block is a PADDING block, the padding + is extended to make the overall size the same as the existing data. If + \a use_padding is \c true and the last block is not a PADDING block, a new + PADDING block is added to the end of the new data to make it the same + size as the existing data (if possible, see the note to + FLAC__metadata_simple_iterator_set_block() about the four byte limit) + and the new data is written in place. If none of the above apply or + \a use_padding is \c false, the entire FLAC file is rewritten. + + If \a preserve_file_stats is \c true, the owner and modification time will + be preserved even if the FLAC file is written. + + For this write function to be used, the chain must have been read with + FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(), not + FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(). + + \param chain A pointer to an existing chain. + \param use_padding See above. + \param preserve_file_stats See above. + \assert + \code chain != NULL \endcode + \retval FLAC__bool + \c true if the write succeeded, else \c false. On failure, + check the status with FLAC__metadata_chain_status(). +*/ FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__bool preserve_file_stats); /** Write all metadata out to a FLAC stream via callbacks. - * - * (See FLAC__metadata_chain_write() for the details on how padding is - * used to write metadata in place if possible.) - * - * The \a handle must be open for updating and be seekable. The - * equivalent minimum stdio fopen() file mode is \c "r+" (or \c "r+b" - * for Windows). - * - * For this write function to be used, the chain must have been read with - * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), - * not FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). - * Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned - * \c false. - * - * \param chain A pointer to an existing chain. - * \param use_padding See FLAC__metadata_chain_write() - * \param handle The I/O handle of the FLAC stream to write. The - * handle will NOT be closed after the metadata is - * written; that is the duty of the caller. - * \param callbacks A set of callbacks to use for I/O. The mandatory - * callbacks are \a write and \a seek. - * \assert - * \code chain != NULL \endcode - * \retval FLAC__bool - * \c true if the write succeeded, else \c false. On failure, - * check the status with FLAC__metadata_chain_status(). - */ + + (See FLAC__metadata_chain_write() for the details on how padding is + used to write metadata in place if possible.) + + The \a handle must be open for updating and be seekable. The + equivalent minimum stdio fopen() file mode is \c "r+" (or \c "r+b" + for Windows). + + For this write function to be used, the chain must have been read with + FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), + not FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). + Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned + \c false. + + \param chain A pointer to an existing chain. + \param use_padding See FLAC__metadata_chain_write() + \param handle The I/O handle of the FLAC stream to write. The + handle will NOT be closed after the metadata is + written; that is the duty of the caller. + \param callbacks A set of callbacks to use for I/O. The mandatory + callbacks are \a write and \a seek. + \assert + \code chain != NULL \endcode + \retval FLAC__bool + \c true if the write succeeded, else \c false. On failure, + check the status with FLAC__metadata_chain_status(). +*/ FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks); /** Write all metadata out to a FLAC stream via callbacks. - * - * (See FLAC__metadata_chain_write() for the details on how padding is - * used to write metadata in place if possible.) - * - * This version of the write-with-callbacks function must be used when - * FLAC__metadata_chain_check_if_tempfile_needed() returns true. In - * this function, you must supply an I/O handle corresponding to the - * FLAC file to edit, and a temporary handle to which the new FLAC - * file will be written. It is the caller's job to move this temporary - * FLAC file on top of the original FLAC file to complete the metadata - * edit. - * - * The \a handle must be open for reading and be seekable. The - * equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" - * for Windows). - * - * The \a temp_handle must be open for writing. The - * equivalent minimum stdio fopen() file mode is \c "w" (or \c "wb" - * for Windows). It should be an empty stream, or at least positioned - * at the start-of-file (in which case it is the caller's duty to - * truncate it on return). - * - * For this write function to be used, the chain must have been read with - * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), - * not FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). - * Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned - * \c true. - * - * \param chain A pointer to an existing chain. - * \param use_padding See FLAC__metadata_chain_write() - * \param handle The I/O handle of the original FLAC stream to read. - * The handle will NOT be closed after the metadata is - * written; that is the duty of the caller. - * \param callbacks A set of callbacks to use for I/O on \a handle. - * The mandatory callbacks are \a read, \a seek, and - * \a eof. - * \param temp_handle The I/O handle of the FLAC stream to write. The - * handle will NOT be closed after the metadata is - * written; that is the duty of the caller. - * \param temp_callbacks - * A set of callbacks to use for I/O on temp_handle. - * The only mandatory callback is \a write. - * \assert - * \code chain != NULL \endcode - * \retval FLAC__bool - * \c true if the write succeeded, else \c false. On failure, - * check the status with FLAC__metadata_chain_status(). - */ + + (See FLAC__metadata_chain_write() for the details on how padding is + used to write metadata in place if possible.) + + This version of the write-with-callbacks function must be used when + FLAC__metadata_chain_check_if_tempfile_needed() returns true. In + this function, you must supply an I/O handle corresponding to the + FLAC file to edit, and a temporary handle to which the new FLAC + file will be written. It is the caller's job to move this temporary + FLAC file on top of the original FLAC file to complete the metadata + edit. + + The \a handle must be open for reading and be seekable. The + equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" + for Windows). + + The \a temp_handle must be open for writing. The + equivalent minimum stdio fopen() file mode is \c "w" (or \c "wb" + for Windows). It should be an empty stream, or at least positioned + at the start-of-file (in which case it is the caller's duty to + truncate it on return). + + For this write function to be used, the chain must have been read with + FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), + not FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). + Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned + \c true. + + \param chain A pointer to an existing chain. + \param use_padding See FLAC__metadata_chain_write() + \param handle The I/O handle of the original FLAC stream to read. + The handle will NOT be closed after the metadata is + written; that is the duty of the caller. + \param callbacks A set of callbacks to use for I/O on \a handle. + The mandatory callbacks are \a read, \a seek, and + \a eof. + \param temp_handle The I/O handle of the FLAC stream to write. The + handle will NOT be closed after the metadata is + written; that is the duty of the caller. + \param temp_callbacks + A set of callbacks to use for I/O on temp_handle. + The only mandatory callback is \a write. + \assert + \code chain != NULL \endcode + \retval FLAC__bool + \c true if the write succeeded, else \c false. On failure, + check the status with FLAC__metadata_chain_status(). +*/ FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks_and_tempfile(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks, FLAC__IOHandle temp_handle, FLAC__IOCallbacks temp_callbacks); /** Merge adjacent PADDING blocks into a single block. - * - * \note This function does not write to the FLAC file, it only - * modifies the chain. - * - * \warning Any iterator on the current chain will become invalid after this - * call. You should delete the iterator and get a new one. - * - * \param chain A pointer to an existing chain. - * \assert - * \code chain != NULL \endcode - */ + + \note This function does not write to the FLAC file, it only + modifies the chain. + + \warning Any iterator on the current chain will become invalid after this + call. You should delete the iterator and get a new one. + + \param chain A pointer to an existing chain. + \assert + \code chain != NULL \endcode +*/ FLAC_API void FLAC__metadata_chain_merge_padding(FLAC__Metadata_Chain *chain); /** This function will move all PADDING blocks to the end on the metadata, - * then merge them into a single block. - * - * \note This function does not write to the FLAC file, it only - * modifies the chain. - * - * \warning Any iterator on the current chain will become invalid after this - * call. You should delete the iterator and get a new one. - * - * \param chain A pointer to an existing chain. - * \assert - * \code chain != NULL \endcode - */ + then merge them into a single block. + + \note This function does not write to the FLAC file, it only + modifies the chain. + + \warning Any iterator on the current chain will become invalid after this + call. You should delete the iterator and get a new one. + + \param chain A pointer to an existing chain. + \assert + \code chain != NULL \endcode +*/ FLAC_API void FLAC__metadata_chain_sort_padding(FLAC__Metadata_Chain *chain); /*********** FLAC__Metadata_Iterator ***********/ /** Create a new iterator instance. - * - * \retval FLAC__Metadata_Iterator* - * \c NULL if there was an error allocating memory, else the new instance. - */ + + \retval FLAC__Metadata_Iterator + \c NULL if there was an error allocating memory, else the new instance. +*/ FLAC_API FLAC__Metadata_Iterator *FLAC__metadata_iterator_new(void); /** Free an iterator instance. Deletes the object pointed to by \a iterator. - * - * \param iterator A pointer to an existing iterator. - * \assert - * \code iterator != NULL \endcode - */ + + \param iterator A pointer to an existing iterator. + \assert + \code iterator != NULL \endcode +*/ FLAC_API void FLAC__metadata_iterator_delete(FLAC__Metadata_Iterator *iterator); /** Initialize the iterator to point to the first metadata block in the - * given chain. - * - * \param iterator A pointer to an existing iterator. - * \param chain A pointer to an existing and initialized (read) chain. - * \assert - * \code iterator != NULL \endcode - * \code chain != NULL \endcode - */ + given chain. + + \param iterator A pointer to an existing iterator. + \param chain A pointer to an existing and initialized (read) chain. + \assert + \code iterator != NULL \endcode + \code chain != NULL \endcode +*/ FLAC_API void FLAC__metadata_iterator_init(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Chain *chain); /** Moves the iterator forward one metadata block, returning \c false if - * already at the end. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_iterator_init() - * \retval FLAC__bool - * \c false if already at the last metadata block of the chain, else - * \c true. - */ + already at the end. + + \param iterator A pointer to an existing initialized iterator. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_iterator_init() + \retval FLAC__bool + \c false if already at the last metadata block of the chain, else + \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_iterator_next(FLAC__Metadata_Iterator *iterator); /** Moves the iterator backward one metadata block, returning \c false if - * already at the beginning. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_iterator_init() - * \retval FLAC__bool - * \c false if already at the first metadata block of the chain, else - * \c true. - */ + already at the beginning. + + \param iterator A pointer to an existing initialized iterator. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_iterator_init() + \retval FLAC__bool + \c false if already at the first metadata block of the chain, else + \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_iterator_prev(FLAC__Metadata_Iterator *iterator); /** Get the type of the metadata block at the current position. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_iterator_init() - * \retval FLAC__MetadataType - * The type of the metadata block at the current iterator position. - */ + + \param iterator A pointer to an existing initialized iterator. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_iterator_init() + \retval FLAC__MetadataType + The type of the metadata block at the current iterator position. +*/ FLAC_API FLAC__MetadataType FLAC__metadata_iterator_get_block_type(const FLAC__Metadata_Iterator *iterator); /** Get the metadata block at the current position. You can modify - * the block in place but must write the chain before the changes - * are reflected to the FLAC file. You do not need to call - * FLAC__metadata_iterator_set_block() to reflect the changes; - * the pointer returned by FLAC__metadata_iterator_get_block() - * points directly into the chain. - * - * \warning - * Do not call FLAC__metadata_object_delete() on the returned object; - * to delete a block use FLAC__metadata_iterator_delete_block(). - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_iterator_init() - * \retval FLAC__StreamMetadata* - * The current metadata block. - */ + the block in place but must write the chain before the changes + are reflected to the FLAC file. You do not need to call + FLAC__metadata_iterator_set_block() to reflect the changes; + the pointer returned by FLAC__metadata_iterator_get_block() + points directly into the chain. + + \warning + Do not call FLAC__metadata_object_delete() on the returned object; + to delete a block use FLAC__metadata_iterator_delete_block(). + + \param iterator A pointer to an existing initialized iterator. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_iterator_init() + \retval FLAC__StreamMetadata + The current metadata block. +*/ FLAC_API FLAC__StreamMetadata *FLAC__metadata_iterator_get_block(FLAC__Metadata_Iterator *iterator); /** Set the metadata block at the current position, replacing the existing - * block. The new block passed in becomes owned by the chain and it will be - * deleted when the chain is deleted. - * - * \param iterator A pointer to an existing initialized iterator. - * \param block A pointer to a metadata block. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_iterator_init() - * \code block != NULL \endcode - * \retval FLAC__bool - * \c false if the conditions in the above description are not met, or - * a memory allocation error occurs, otherwise \c true. - */ + block. The new block passed in becomes owned by the chain and it will be + deleted when the chain is deleted. + + \param iterator A pointer to an existing initialized iterator. + \param block A pointer to a metadata block. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_iterator_init() + \code block != NULL \endcode + \retval FLAC__bool + \c false if the conditions in the above description are not met, or + a memory allocation error occurs, otherwise \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_iterator_set_block(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); /** Removes the current block from the chain. If \a replace_with_padding is - * \c true, the block will instead be replaced with a padding block of equal - * size. You can not delete the STREAMINFO block. The iterator will be - * left pointing to the block before the one just "deleted", even if - * \a replace_with_padding is \c true. - * - * \param iterator A pointer to an existing initialized iterator. - * \param replace_with_padding See above. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_iterator_init() - * \retval FLAC__bool - * \c false if the conditions in the above description are not met, - * otherwise \c true. - */ + \c true, the block will instead be replaced with a padding block of equal + size. You can not delete the STREAMINFO block. The iterator will be + left pointing to the block before the one just "deleted", even if + \a replace_with_padding is \c true. + + \param iterator A pointer to an existing initialized iterator. + \param replace_with_padding See above. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_iterator_init() + \retval FLAC__bool + \c false if the conditions in the above description are not met, + otherwise \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_iterator_delete_block(FLAC__Metadata_Iterator *iterator, FLAC__bool replace_with_padding); /** Insert a new block before the current block. You cannot insert a block - * before the first STREAMINFO block. You cannot insert a STREAMINFO block - * as there can be only one, the one that already exists at the head when you - * read in a chain. The chain takes ownership of the new block and it will be - * deleted when the chain is deleted. The iterator will be left pointing to - * the new block. - * - * \param iterator A pointer to an existing initialized iterator. - * \param block A pointer to a metadata block to insert. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_iterator_init() - * \retval FLAC__bool - * \c false if the conditions in the above description are not met, or - * a memory allocation error occurs, otherwise \c true. - */ + before the first STREAMINFO block. You cannot insert a STREAMINFO block + as there can be only one, the one that already exists at the head when you + read in a chain. The chain takes ownership of the new block and it will be + deleted when the chain is deleted. The iterator will be left pointing to + the new block. + + \param iterator A pointer to an existing initialized iterator. + \param block A pointer to a metadata block to insert. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_iterator_init() + \retval FLAC__bool + \c false if the conditions in the above description are not met, or + a memory allocation error occurs, otherwise \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_before(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); /** Insert a new block after the current block. You cannot insert a STREAMINFO - * block as there can be only one, the one that already exists at the head when - * you read in a chain. The chain takes ownership of the new block and it will - * be deleted when the chain is deleted. The iterator will be left pointing to - * the new block. - * - * \param iterator A pointer to an existing initialized iterator. - * \param block A pointer to a metadata block to insert. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_iterator_init() - * \retval FLAC__bool - * \c false if the conditions in the above description are not met, or - * a memory allocation error occurs, otherwise \c true. - */ + block as there can be only one, the one that already exists at the head when + you read in a chain. The chain takes ownership of the new block and it will + be deleted when the chain is deleted. The iterator will be left pointing to + the new block. + + \param iterator A pointer to an existing initialized iterator. + \param block A pointer to a metadata block to insert. + \assert + \code iterator != NULL \endcode + \a iterator has been successfully initialized with + FLAC__metadata_iterator_init() + \retval FLAC__bool + \c false if the conditions in the above description are not met, or + a memory allocation error occurs, otherwise \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_after(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); /* \} */ /** \defgroup flac_metadata_object FLAC/metadata.h: metadata object methods - * \ingroup flac_metadata - * - * \brief - * This module contains methods for manipulating FLAC metadata objects. - * - * Since many are variable length we have to be careful about the memory - * management. We decree that all pointers to data in the object are - * owned by the object and memory-managed by the object. - * - * Use the FLAC__metadata_object_new() and FLAC__metadata_object_delete() - * functions to create all instances. When using the - * FLAC__metadata_object_set_*() functions to set pointers to data, set - * \a copy to \c true to have the function make it's own copy of the data, or - * to \c false to give the object ownership of your data. In the latter case - * your pointer must be freeable by free() and will be free()d when the object - * is FLAC__metadata_object_delete()d. It is legal to pass a null pointer as - * the data pointer to a FLAC__metadata_object_set_*() function as long as - * the length argument is 0 and the \a copy argument is \c false. - * - * The FLAC__metadata_object_new() and FLAC__metadata_object_clone() function - * will return \c NULL in the case of a memory allocation error, otherwise a new - * object. The FLAC__metadata_object_set_*() functions return \c false in the - * case of a memory allocation error. - * - * We don't have the convenience of C++ here, so note that the library relies - * on you to keep the types straight. In other words, if you pass, for - * example, a FLAC__StreamMetadata* that represents a STREAMINFO block to - * FLAC__metadata_object_application_set_data(), you will get an assertion - * failure. - * - * For convenience the FLAC__metadata_object_vorbiscomment_*() functions - * maintain a trailing NUL on each Vorbis comment entry. This is not counted - * toward the length or stored in the stream, but it can make working with plain - * comments (those that don't contain embedded-NULs in the value) easier. - * Entries passed into these functions have trailing NULs added if missing, and - * returned entries are guaranteed to have a trailing NUL. - * - * The FLAC__metadata_object_vorbiscomment_*() functions that take a Vorbis - * comment entry/name/value will first validate that it complies with the Vorbis - * comment specification and return false if it does not. - * - * There is no need to recalculate the length field on metadata blocks you - * have modified. They will be calculated automatically before they are - * written back to a file. - * - * \{ - */ + \ingroup flac_metadata + + \brief + This module contains methods for manipulating FLAC metadata objects. + + Since many are variable length we have to be careful about the memory + management. We decree that all pointers to data in the object are + owned by the object and memory-managed by the object. + + Use the FLAC__metadata_object_new() and FLAC__metadata_object_delete() + functions to create all instances. When using the + FLAC__metadata_object_set_*() functions to set pointers to data, set + \a copy to \c true to have the function make it's own copy of the data, or + to \c false to give the object ownership of your data. In the latter case + your pointer must be freeable by free() and will be free()d when the object + is FLAC__metadata_object_delete()d. It is legal to pass a null pointer as + the data pointer to a FLAC__metadata_object_set_*() function as long as + the length argument is 0 and the \a copy argument is \c false. + + The FLAC__metadata_object_new() and FLAC__metadata_object_clone() function + will return \c NULL in the case of a memory allocation error, otherwise a new + object. The FLAC__metadata_object_set_*() functions return \c false in the + case of a memory allocation error. + + We don't have the convenience of C++ here, so note that the library relies + on you to keep the types straight. In other words, if you pass, for + example, a FLAC__StreamMetadata* that represents a STREAMINFO block to + FLAC__metadata_object_application_set_data(), you will get an assertion + failure. + + For convenience the FLAC__metadata_object_vorbiscomment_*() functions + maintain a trailing NUL on each Vorbis comment entry. This is not counted + toward the length or stored in the stream, but it can make working with plain + comments (those that don't contain embedded-NULs in the value) easier. + Entries passed into these functions have trailing NULs added if missing, and + returned entries are guaranteed to have a trailing NUL. + + The FLAC__metadata_object_vorbiscomment_*() functions that take a Vorbis + comment entry/name/value will first validate that it complies with the Vorbis + comment specification and return false if it does not. + + There is no need to recalculate the length field on metadata blocks you + have modified. They will be calculated automatically before they are + written back to a file. + + \{ +*/ /** Create a new metadata object instance of the given type. - * - * The object will be "empty"; i.e. values and data pointers will be \c 0, - * with the exception of FLAC__METADATA_TYPE_VORBIS_COMMENT, which will have - * the vendor string set (but zero comments). - * - * Do not pass in a value greater than or equal to - * \a FLAC__METADATA_TYPE_UNDEFINED unless you really know what you're - * doing. - * - * \param type Type of object to create - * \retval FLAC__StreamMetadata* - * \c NULL if there was an error allocating memory or the type code is - * greater than FLAC__MAX_METADATA_TYPE_CODE, else the new instance. - */ + + The object will be "empty"; i.e. values and data pointers will be \c 0, + with the exception of FLAC__METADATA_TYPE_VORBIS_COMMENT, which will have + the vendor string set (but zero comments). + + Do not pass in a value greater than or equal to + \a FLAC__METADATA_TYPE_UNDEFINED unless you really know what you're + doing. + + \param type Type of object to create + \retval FLAC__StreamMetadata + \c NULL if there was an error allocating memory or the type code is + greater than FLAC__MAX_METADATA_TYPE_CODE, else the new instance. +*/ FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_new(FLAC__MetadataType type); /** Create a copy of an existing metadata object. - * - * The copy is a "deep" copy, i.e. dynamically allocated data within the - * object is also copied. The caller takes ownership of the new block and - * is responsible for freeing it with FLAC__metadata_object_delete(). - * - * \param object Pointer to object to copy. - * \assert - * \code object != NULL \endcode - * \retval FLAC__StreamMetadata* - * \c NULL if there was an error allocating memory, else the new instance. - */ + + The copy is a "deep" copy, i.e. dynamically allocated data within the + object is also copied. The caller takes ownership of the new block and + is responsible for freeing it with FLAC__metadata_object_delete(). + + \param object Pointer to object to copy. + \assert + \code object != NULL \endcode + \retval FLAC__StreamMetadata + \c NULL if there was an error allocating memory, else the new instance. +*/ FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMetadata *object); /** Free a metadata object. Deletes the object pointed to by \a object. - * - * The delete is a "deep" delete, i.e. dynamically allocated data within the - * object is also deleted. - * - * \param object A pointer to an existing object. - * \assert - * \code object != NULL \endcode - */ + + The delete is a "deep" delete, i.e. dynamically allocated data within the + object is also deleted. + + \param object A pointer to an existing object. + \assert + \code object != NULL \endcode +*/ FLAC_API void FLAC__metadata_object_delete(FLAC__StreamMetadata *object); /** Compares two metadata objects. - * - * The compare is "deep", i.e. dynamically allocated data within the - * object is also compared. - * - * \param block1 A pointer to an existing object. - * \param block2 A pointer to an existing object. - * \assert - * \code block1 != NULL \endcode - * \code block2 != NULL \endcode - * \retval FLAC__bool - * \c true if objects are identical, else \c false. - */ + + The compare is "deep", i.e. dynamically allocated data within the + object is also compared. + + \param block1 A pointer to an existing object. + \param block2 A pointer to an existing object. + \assert + \code block1 != NULL \endcode + \code block2 != NULL \endcode + \retval FLAC__bool + \c true if objects are identical, else \c false. +*/ FLAC_API FLAC__bool FLAC__metadata_object_is_equal(const FLAC__StreamMetadata *block1, const FLAC__StreamMetadata *block2); /** Sets the application data of an APPLICATION block. - * - * If \a copy is \c true, a copy of the data is stored; otherwise, the object - * takes ownership of the pointer. The existing data will be freed if this - * function is successful, otherwise the original data will remain if \a copy - * is \c true and malloc() fails. - * - * \note It is safe to pass a const pointer to \a data if \a copy is \c true. - * - * \param object A pointer to an existing APPLICATION object. - * \param data A pointer to the data to set. - * \param length The length of \a data in bytes. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_APPLICATION \endcode - * \code (data != NULL && length > 0) || - * (data == NULL && length == 0 && copy == false) \endcode - * \retval FLAC__bool - * \c false if \a copy is \c true and malloc() fails, else \c true. - */ + + If \a copy is \c true, a copy of the data is stored; otherwise, the object + takes ownership of the pointer. The existing data will be freed if this + function is successful, otherwise the original data will remain if \a copy + is \c true and malloc() fails. + + \note It is safe to pass a const pointer to \a data if \a copy is \c true. + + \param object A pointer to an existing APPLICATION object. + \param data A pointer to the data to set. + \param length The length of \a data in bytes. + \param copy See above. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_APPLICATION \endcode + \code (data != NULL && length > 0) || + (data == NULL && length == 0 && copy == false) \endcode + \retval FLAC__bool + \c false if \a copy is \c true and malloc() fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_application_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, uint32_t length, FLAC__bool copy); /** Resize the seekpoint array. - * - * If the size shrinks, elements will truncated; if it grows, new placeholder - * points will be added to the end. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param new_num_points The desired length of the array; may be \c 0. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \code (object->data.seek_table.points == NULL && object->data.seek_table.num_points == 0) || - * (object->data.seek_table.points != NULL && object->data.seek_table.num_points > 0) \endcode - * \retval FLAC__bool - * \c false if memory allocation error, else \c true. - */ + + If the size shrinks, elements will truncated; if it grows, new placeholder + points will be added to the end. + + \param object A pointer to an existing SEEKTABLE object. + \param new_num_points The desired length of the array; may be \c 0. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + \code (object->data.seek_table.points == NULL && object->data.seek_table.num_points == 0) || + (object->data.seek_table.points != NULL && object->data.seek_table.num_points > 0) \endcode + \retval FLAC__bool + \c false if memory allocation error, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_seektable_resize_points(FLAC__StreamMetadata *object, uint32_t new_num_points); /** Set a seekpoint in a seektable. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param point_num Index into seekpoint array to set. - * \param point The point to set. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \code object->data.seek_table.num_points > point_num \endcode - */ + + \param object A pointer to an existing SEEKTABLE object. + \param point_num Index into seekpoint array to set. + \param point The point to set. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + \code object->data.seek_table.num_points > point_num \endcode +*/ FLAC_API void FLAC__metadata_object_seektable_set_point(FLAC__StreamMetadata *object, uint32_t point_num, FLAC__StreamMetadata_SeekPoint point); /** Insert a seekpoint into a seektable. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param point_num Index into seekpoint array to set. - * \param point The point to set. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \code object->data.seek_table.num_points >= point_num \endcode - * \retval FLAC__bool - * \c false if memory allocation error, else \c true. - */ + + \param object A pointer to an existing SEEKTABLE object. + \param point_num Index into seekpoint array to set. + \param point The point to set. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + \code object->data.seek_table.num_points >= point_num \endcode + \retval FLAC__bool + \c false if memory allocation error, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_seektable_insert_point(FLAC__StreamMetadata *object, uint32_t point_num, FLAC__StreamMetadata_SeekPoint point); /** Delete a seekpoint from a seektable. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param point_num Index into seekpoint array to set. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \code object->data.seek_table.num_points > point_num \endcode - * \retval FLAC__bool - * \c false if memory allocation error, else \c true. - */ + + \param object A pointer to an existing SEEKTABLE object. + \param point_num Index into seekpoint array to set. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + \code object->data.seek_table.num_points > point_num \endcode + \retval FLAC__bool + \c false if memory allocation error, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_seektable_delete_point(FLAC__StreamMetadata *object, uint32_t point_num); /** Check a seektable to see if it conforms to the FLAC specification. - * See the format specification for limits on the contents of the - * seektable. - * - * \param object A pointer to an existing SEEKTABLE object. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \retval FLAC__bool - * \c false if seek table is illegal, else \c true. - */ + See the format specification for limits on the contents of the + seektable. + + \param object A pointer to an existing SEEKTABLE object. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + \retval FLAC__bool + \c false if seek table is illegal, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_seektable_is_legal(const FLAC__StreamMetadata *object); /** Append a number of placeholder points to the end of a seek table. - * - * \note - * As with the other ..._seektable_template_... functions, you should - * call FLAC__metadata_object_seektable_template_sort() when finished - * to make the seek table legal. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param num The number of placeholder points to append. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \retval FLAC__bool - * \c false if memory allocation fails, else \c true. - */ + + \note + As with the other ..._seektable_template_... functions, you should + call FLAC__metadata_object_seektable_template_sort() when finished + to make the seek table legal. + + \param object A pointer to an existing SEEKTABLE object. + \param num The number of placeholder points to append. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + \retval FLAC__bool + \c false if memory allocation fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_placeholders(FLAC__StreamMetadata *object, uint32_t num); /** Append a specific seek point template to the end of a seek table. - * - * \note - * As with the other ..._seektable_template_... functions, you should - * call FLAC__metadata_object_seektable_template_sort() when finished - * to make the seek table legal. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param sample_number The sample number of the seek point template. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \retval FLAC__bool - * \c false if memory allocation fails, else \c true. - */ + + \note + As with the other ..._seektable_template_... functions, you should + call FLAC__metadata_object_seektable_template_sort() when finished + to make the seek table legal. + + \param object A pointer to an existing SEEKTABLE object. + \param sample_number The sample number of the seek point template. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + \retval FLAC__bool + \c false if memory allocation fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_point(FLAC__StreamMetadata *object, FLAC__uint64 sample_number); /** Append specific seek point templates to the end of a seek table. - * - * \note - * As with the other ..._seektable_template_... functions, you should - * call FLAC__metadata_object_seektable_template_sort() when finished - * to make the seek table legal. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param sample_numbers An array of sample numbers for the seek points. - * \param num The number of seek point templates to append. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \retval FLAC__bool - * \c false if memory allocation fails, else \c true. - */ + + \note + As with the other ..._seektable_template_... functions, you should + call FLAC__metadata_object_seektable_template_sort() when finished + to make the seek table legal. + + \param object A pointer to an existing SEEKTABLE object. + \param sample_numbers An array of sample numbers for the seek points. + \param num The number of seek point templates to append. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + \retval FLAC__bool + \c false if memory allocation fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_points(FLAC__StreamMetadata *object, FLAC__uint64 sample_numbers[], uint32_t num); /** Append a set of evenly-spaced seek point templates to the end of a - * seek table. - * - * \note - * As with the other ..._seektable_template_... functions, you should - * call FLAC__metadata_object_seektable_template_sort() when finished - * to make the seek table legal. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param num The number of placeholder points to append. - * \param total_samples The total number of samples to be encoded; - * the seekpoints will be spaced approximately - * \a total_samples / \a num samples apart. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \code total_samples > 0 \endcode - * \retval FLAC__bool - * \c false if memory allocation fails, else \c true. - */ + seek table. + + \note + As with the other ..._seektable_template_... functions, you should + call FLAC__metadata_object_seektable_template_sort() when finished + to make the seek table legal. + + \param object A pointer to an existing SEEKTABLE object. + \param num The number of placeholder points to append. + \param total_samples The total number of samples to be encoded; + the seekpoints will be spaced approximately + \a total_samples / \a num samples apart. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + \code total_samples > 0 \endcode + \retval FLAC__bool + \c false if memory allocation fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points(FLAC__StreamMetadata *object, uint32_t num, FLAC__uint64 total_samples); /** Append a set of evenly-spaced seek point templates to the end of a - * seek table. - * - * \note - * As with the other ..._seektable_template_... functions, you should - * call FLAC__metadata_object_seektable_template_sort() when finished - * to make the seek table legal. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param samples The number of samples apart to space the placeholder - * points. The first point will be at sample \c 0, the - * second at sample \a samples, then 2*\a samples, and - * so on. As long as \a samples and \a total_samples - * are greater than \c 0, there will always be at least - * one seekpoint at sample \c 0. - * \param total_samples The total number of samples to be encoded; - * the seekpoints will be spaced - * \a samples samples apart. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \code samples > 0 \endcode - * \code total_samples > 0 \endcode - * \retval FLAC__bool - * \c false if memory allocation fails, else \c true. - */ + seek table. + + \note + As with the other ..._seektable_template_... functions, you should + call FLAC__metadata_object_seektable_template_sort() when finished + to make the seek table legal. + + \param object A pointer to an existing SEEKTABLE object. + \param samples The number of samples apart to space the placeholder + points. The first point will be at sample \c 0, the + second at sample \a samples, then 2*\a samples, and + so on. As long as \a samples and \a total_samples + are greater than \c 0, there will always be at least + one seekpoint at sample \c 0. + \param total_samples The total number of samples to be encoded; + the seekpoints will be spaced + \a samples samples apart. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + \code samples > 0 \endcode + \code total_samples > 0 \endcode + \retval FLAC__bool + \c false if memory allocation fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(FLAC__StreamMetadata *object, uint32_t samples, FLAC__uint64 total_samples); /** Sort a seek table's seek points according to the format specification, - * removing duplicates. - * - * \param object A pointer to a seek table to be sorted. - * \param compact If \c false, behaves like FLAC__format_seektable_sort(). - * If \c true, duplicates are deleted and the seek table is - * shrunk appropriately; the number of placeholder points - * present in the seek table will be the same after the call - * as before. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \retval FLAC__bool - * \c false if realloc() fails, else \c true. - */ + removing duplicates. + + \param object A pointer to a seek table to be sorted. + \param compact If \c false, behaves like FLAC__format_seektable_sort(). + If \c true, duplicates are deleted and the seek table is + shrunk appropriately; the number of placeholder points + present in the seek table will be the same after the call + as before. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + \retval FLAC__bool + \c false if realloc() fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_sort(FLAC__StreamMetadata *object, FLAC__bool compact); /** Sets the vendor string in a VORBIS_COMMENT block. - * - * For convenience, a trailing NUL is added to the entry if it doesn't have - * one already. - * - * If \a copy is \c true, a copy of the entry is stored; otherwise, the object - * takes ownership of the \c entry.entry pointer. - * - * \note If this function returns \c false, the caller still owns the - * pointer. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param entry The entry to set the vendor string to. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \code (entry.entry != NULL && entry.length > 0) || - * (entry.entry == NULL && entry.length == 0) \endcode - * \retval FLAC__bool - * \c false if memory allocation fails or \a entry does not comply with the - * Vorbis comment specification, else \c true. - */ + + For convenience, a trailing NUL is added to the entry if it doesn't have + one already. + + If \a copy is \c true, a copy of the entry is stored; otherwise, the object + takes ownership of the \c entry.entry pointer. + + \note If this function returns \c false, the caller still owns the + pointer. + + \param object A pointer to an existing VORBIS_COMMENT object. + \param entry The entry to set the vendor string to. + \param copy See above. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + \code (entry.entry != NULL && entry.length > 0) || + (entry.entry == NULL && entry.length == 0) \endcode + \retval FLAC__bool + \c false if memory allocation fails or \a entry does not comply with the + Vorbis comment specification, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_vendor_string(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); /** Resize the comment array. - * - * If the size shrinks, elements will truncated; if it grows, new empty - * fields will be added to the end. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param new_num_comments The desired length of the array; may be \c 0. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \code (object->data.vorbis_comment.comments == NULL && object->data.vorbis_comment.num_comments == 0) || - * (object->data.vorbis_comment.comments != NULL && object->data.vorbis_comment.num_comments > 0) \endcode - * \retval FLAC__bool - * \c false if memory allocation fails, else \c true. - */ + + If the size shrinks, elements will truncated; if it grows, new empty + fields will be added to the end. + + \param object A pointer to an existing VORBIS_COMMENT object. + \param new_num_comments The desired length of the array; may be \c 0. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + \code (object->data.vorbis_comment.comments == NULL && object->data.vorbis_comment.num_comments == 0) || + (object->data.vorbis_comment.comments != NULL && object->data.vorbis_comment.num_comments > 0) \endcode + \retval FLAC__bool + \c false if memory allocation fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_resize_comments(FLAC__StreamMetadata *object, uint32_t new_num_comments); /** Sets a comment in a VORBIS_COMMENT block. - * - * For convenience, a trailing NUL is added to the entry if it doesn't have - * one already. - * - * If \a copy is \c true, a copy of the entry is stored; otherwise, the object - * takes ownership of the \c entry.entry pointer. - * - * \note If this function returns \c false, the caller still owns the - * pointer. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param comment_num Index into comment array to set. - * \param entry The entry to set the comment to. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \code comment_num < object->data.vorbis_comment.num_comments \endcode - * \code (entry.entry != NULL && entry.length > 0) || - * (entry.entry == NULL && entry.length == 0) \endcode - * \retval FLAC__bool - * \c false if memory allocation fails or \a entry does not comply with the - * Vorbis comment specification, else \c true. - */ + + For convenience, a trailing NUL is added to the entry if it doesn't have + one already. + + If \a copy is \c true, a copy of the entry is stored; otherwise, the object + takes ownership of the \c entry.entry pointer. + + \note If this function returns \c false, the caller still owns the + pointer. + + \param object A pointer to an existing VORBIS_COMMENT object. + \param comment_num Index into comment array to set. + \param entry The entry to set the comment to. + \param copy See above. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + \code comment_num < object->data.vorbis_comment.num_comments \endcode + \code (entry.entry != NULL && entry.length > 0) || + (entry.entry == NULL && entry.length == 0) \endcode + \retval FLAC__bool + \c false if memory allocation fails or \a entry does not comply with the + Vorbis comment specification, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_comment(FLAC__StreamMetadata *object, uint32_t comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); /** Insert a comment in a VORBIS_COMMENT block at the given index. - * - * For convenience, a trailing NUL is added to the entry if it doesn't have - * one already. - * - * If \a copy is \c true, a copy of the entry is stored; otherwise, the object - * takes ownership of the \c entry.entry pointer. - * - * \note If this function returns \c false, the caller still owns the - * pointer. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param comment_num The index at which to insert the comment. The comments - * at and after \a comment_num move right one position. - * To append a comment to the end, set \a comment_num to - * \c object->data.vorbis_comment.num_comments . - * \param entry The comment to insert. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \code object->data.vorbis_comment.num_comments >= comment_num \endcode - * \code (entry.entry != NULL && entry.length > 0) || - * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode - * \retval FLAC__bool - * \c false if memory allocation fails or \a entry does not comply with the - * Vorbis comment specification, else \c true. - */ + + For convenience, a trailing NUL is added to the entry if it doesn't have + one already. + + If \a copy is \c true, a copy of the entry is stored; otherwise, the object + takes ownership of the \c entry.entry pointer. + + \note If this function returns \c false, the caller still owns the + pointer. + + \param object A pointer to an existing VORBIS_COMMENT object. + \param comment_num The index at which to insert the comment. The comments + at and after \a comment_num move right one position. + To append a comment to the end, set \a comment_num to + \c object->data.vorbis_comment.num_comments . + \param entry The comment to insert. + \param copy See above. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + \code object->data.vorbis_comment.num_comments >= comment_num \endcode + \code (entry.entry != NULL && entry.length > 0) || + (entry.entry == NULL && entry.length == 0 && copy == false) \endcode + \retval FLAC__bool + \c false if memory allocation fails or \a entry does not comply with the + Vorbis comment specification, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_insert_comment(FLAC__StreamMetadata *object, uint32_t comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); /** Appends a comment to a VORBIS_COMMENT block. - * - * For convenience, a trailing NUL is added to the entry if it doesn't have - * one already. - * - * If \a copy is \c true, a copy of the entry is stored; otherwise, the object - * takes ownership of the \c entry.entry pointer. - * - * \note If this function returns \c false, the caller still owns the - * pointer. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param entry The comment to insert. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \code (entry.entry != NULL && entry.length > 0) || - * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode - * \retval FLAC__bool - * \c false if memory allocation fails or \a entry does not comply with the - * Vorbis comment specification, else \c true. - */ + + For convenience, a trailing NUL is added to the entry if it doesn't have + one already. + + If \a copy is \c true, a copy of the entry is stored; otherwise, the object + takes ownership of the \c entry.entry pointer. + + \note If this function returns \c false, the caller still owns the + pointer. + + \param object A pointer to an existing VORBIS_COMMENT object. + \param entry The comment to insert. + \param copy See above. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + \code (entry.entry != NULL && entry.length > 0) || + (entry.entry == NULL && entry.length == 0 && copy == false) \endcode + \retval FLAC__bool + \c false if memory allocation fails or \a entry does not comply with the + Vorbis comment specification, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_append_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); /** Replaces comments in a VORBIS_COMMENT block with a new one. - * - * For convenience, a trailing NUL is added to the entry if it doesn't have - * one already. - * - * Depending on the value of \a all, either all or just the first comment - * whose field name(s) match the given entry's name will be replaced by the - * given entry. If no comments match, \a entry will simply be appended. - * - * If \a copy is \c true, a copy of the entry is stored; otherwise, the object - * takes ownership of the \c entry.entry pointer. - * - * \note If this function returns \c false, the caller still owns the - * pointer. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param entry The comment to insert. - * \param all If \c true, all comments whose field name matches - * \a entry's field name will be removed, and \a entry will - * be inserted at the position of the first matching - * comment. If \c false, only the first comment whose - * field name matches \a entry's field name will be - * replaced with \a entry. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \code (entry.entry != NULL && entry.length > 0) || - * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode - * \retval FLAC__bool - * \c false if memory allocation fails or \a entry does not comply with the - * Vorbis comment specification, else \c true. - */ + + For convenience, a trailing NUL is added to the entry if it doesn't have + one already. + + Depending on the value of \a all, either all or just the first comment + whose field name(s) match the given entry's name will be replaced by the + given entry. If no comments match, \a entry will simply be appended. + + If \a copy is \c true, a copy of the entry is stored; otherwise, the object + takes ownership of the \c entry.entry pointer. + + \note If this function returns \c false, the caller still owns the + pointer. + + \param object A pointer to an existing VORBIS_COMMENT object. + \param entry The comment to insert. + \param all If \c true, all comments whose field name matches + \a entry's field name will be removed, and \a entry will + be inserted at the position of the first matching + comment. If \c false, only the first comment whose + field name matches \a entry's field name will be + replaced with \a entry. + \param copy See above. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + \code (entry.entry != NULL && entry.length > 0) || + (entry.entry == NULL && entry.length == 0 && copy == false) \endcode + \retval FLAC__bool + \c false if memory allocation fails or \a entry does not comply with the + Vorbis comment specification, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_replace_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool all, FLAC__bool copy); /** Delete a comment in a VORBIS_COMMENT block at the given index. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param comment_num The index of the comment to delete. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \code object->data.vorbis_comment.num_comments > comment_num \endcode - * \retval FLAC__bool - * \c false if realloc() fails, else \c true. - */ + + \param object A pointer to an existing VORBIS_COMMENT object. + \param comment_num The index of the comment to delete. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + \code object->data.vorbis_comment.num_comments > comment_num \endcode + \retval FLAC__bool + \c false if realloc() fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_delete_comment(FLAC__StreamMetadata *object, uint32_t comment_num); /** Creates a Vorbis comment entry from NUL-terminated name and value strings. - * - * On return, the filled-in \a entry->entry pointer will point to malloc()ed - * memory and shall be owned by the caller. For convenience the entry will - * have a terminating NUL. - * - * \param entry A pointer to a Vorbis comment entry. The entry's - * \c entry pointer should not point to allocated - * memory as it will be overwritten. - * \param field_name The field name in ASCII, \c NUL terminated. - * \param field_value The field value in UTF-8, \c NUL terminated. - * \assert - * \code entry != NULL \endcode - * \code field_name != NULL \endcode - * \code field_value != NULL \endcode - * \retval FLAC__bool - * \c false if malloc() fails, or if \a field_name or \a field_value does - * not comply with the Vorbis comment specification, else \c true. - */ + + On return, the filled-in \a entry->entry pointer will point to malloc()ed + memory and shall be owned by the caller. For convenience the entry will + have a terminating NUL. + + \param entry A pointer to a Vorbis comment entry. The entry's + \c entry pointer should not point to allocated + memory as it will be overwritten. + \param field_name The field name in ASCII, \c NUL terminated. + \param field_value The field value in UTF-8, \c NUL terminated. + \assert + \code entry != NULL \endcode + \code field_name != NULL \endcode + \code field_value != NULL \endcode + \retval FLAC__bool + \c false if malloc() fails, or if \a field_name or \a field_value does + not comply with the Vorbis comment specification, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(FLAC__StreamMetadata_VorbisComment_Entry *entry, const char *field_name, const char *field_value); /** Splits a Vorbis comment entry into NUL-terminated name and value strings. - * - * The returned pointers to name and value will be allocated by malloc() - * and shall be owned by the caller. - * - * \param entry An existing Vorbis comment entry. - * \param field_name The address of where the returned pointer to the - * field name will be stored. - * \param field_value The address of where the returned pointer to the - * field value will be stored. - * \assert - * \code (entry.entry != NULL && entry.length > 0) \endcode - * \code memchr(entry.entry, '=', entry.length) != NULL \endcode - * \code field_name != NULL \endcode - * \code field_value != NULL \endcode - * \retval FLAC__bool - * \c false if memory allocation fails or \a entry does not comply with the - * Vorbis comment specification, else \c true. - */ + + The returned pointers to name and value will be allocated by malloc() + and shall be owned by the caller. + + \param entry An existing Vorbis comment entry. + \param field_name The address of where the returned pointer to the + field name will be stored. + \param field_value The address of where the returned pointer to the + field value will be stored. + \assert + \code (entry.entry != NULL && entry.length > 0) \endcode + \code memchr(entry.entry, '=', entry.length) != NULL \endcode + \code field_name != NULL \endcode + \code field_value != NULL \endcode + \retval FLAC__bool + \c false if memory allocation fails or \a entry does not comply with the + Vorbis comment specification, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(const FLAC__StreamMetadata_VorbisComment_Entry entry, char **field_name, char **field_value); /** Check if the given Vorbis comment entry's field name matches the given - * field name. - * - * \param entry An existing Vorbis comment entry. - * \param field_name The field name to check. - * \param field_name_length The length of \a field_name, not including the - * terminating \c NUL. - * \assert - * \code (entry.entry != NULL && entry.length > 0) \endcode - * \retval FLAC__bool - * \c true if the field names match, else \c false - */ + field name. + + \param entry An existing Vorbis comment entry. + \param field_name The field name to check. + \param field_name_length The length of \a field_name, not including the + terminating \c NUL. + \assert + \code (entry.entry != NULL && entry.length > 0) \endcode + \retval FLAC__bool + \c true if the field names match, else \c false +*/ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_matches(const FLAC__StreamMetadata_VorbisComment_Entry entry, const char *field_name, uint32_t field_name_length); /** Find a Vorbis comment with the given field name. - * - * The search begins at entry number \a offset; use an offset of 0 to - * search from the beginning of the comment array. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param offset The offset into the comment array from where to start - * the search. - * \param field_name The field name of the comment to find. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \code field_name != NULL \endcode - * \retval int - * The offset in the comment array of the first comment whose field - * name matches \a field_name, or \c -1 if no match was found. - */ + + The search begins at entry number \a offset; use an offset of 0 to + search from the beginning of the comment array. + + \param object A pointer to an existing VORBIS_COMMENT object. + \param offset The offset into the comment array from where to start + the search. + \param field_name The field name of the comment to find. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + \code field_name != NULL \endcode + \retval int + The offset in the comment array of the first comment whose field + name matches \a field_name, or \c -1 if no match was found. +*/ FLAC_API int FLAC__metadata_object_vorbiscomment_find_entry_from(const FLAC__StreamMetadata *object, uint32_t offset, const char *field_name); /** Remove first Vorbis comment matching the given field name. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param field_name The field name of comment to delete. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \retval int - * \c -1 for memory allocation error, \c 0 for no matching entries, - * \c 1 for one matching entry deleted. - */ + + \param object A pointer to an existing VORBIS_COMMENT object. + \param field_name The field name of comment to delete. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + \retval int + \c -1 for memory allocation error, \c 0 for no matching entries, + \c 1 for one matching entry deleted. +*/ FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entry_matching(FLAC__StreamMetadata *object, const char *field_name); /** Remove all Vorbis comments matching the given field name. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param field_name The field name of comments to delete. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \retval int - * \c -1 for memory allocation error, \c 0 for no matching entries, - * else the number of matching entries deleted. - */ + + \param object A pointer to an existing VORBIS_COMMENT object. + \param field_name The field name of comments to delete. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + \retval int + \c -1 for memory allocation error, \c 0 for no matching entries, + else the number of matching entries deleted. +*/ FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entries_matching(FLAC__StreamMetadata *object, const char *field_name); /** Create a new CUESHEET track instance. - * - * The object will be "empty"; i.e. values and data pointers will be \c 0. - * - * \retval FLAC__StreamMetadata_CueSheet_Track* - * \c NULL if there was an error allocating memory, else the new instance. - */ + + The object will be "empty"; i.e. values and data pointers will be \c 0. + + \retval FLAC__StreamMetadata_CueSheet_Track + \c NULL if there was an error allocating memory, else the new instance. +*/ FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_new(void); /** Create a copy of an existing CUESHEET track object. - * - * The copy is a "deep" copy, i.e. dynamically allocated data within the - * object is also copied. The caller takes ownership of the new object and - * is responsible for freeing it with - * FLAC__metadata_object_cuesheet_track_delete(). - * - * \param object Pointer to object to copy. - * \assert - * \code object != NULL \endcode - * \retval FLAC__StreamMetadata_CueSheet_Track* - * \c NULL if there was an error allocating memory, else the new instance. - */ + + The copy is a "deep" copy, i.e. dynamically allocated data within the + object is also copied. The caller takes ownership of the new object and + is responsible for freeing it with + FLAC__metadata_object_cuesheet_track_delete(). + + \param object Pointer to object to copy. + \assert + \code object != NULL \endcode + \retval FLAC__StreamMetadata_CueSheet_Track + \c NULL if there was an error allocating memory, else the new instance. +*/ FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_clone(const FLAC__StreamMetadata_CueSheet_Track *object); /** Delete a CUESHEET track object - * - * \param object A pointer to an existing CUESHEET track object. - * \assert - * \code object != NULL \endcode - */ + + \param object A pointer to an existing CUESHEET track object. + \assert + \code object != NULL \endcode +*/ FLAC_API void FLAC__metadata_object_cuesheet_track_delete(FLAC__StreamMetadata_CueSheet_Track *object); /** Resize a track's index point array. - * - * If the size shrinks, elements will truncated; if it grows, new blank - * indices will be added to the end. - * - * \param object A pointer to an existing CUESHEET object. - * \param track_num The index of the track to modify. NOTE: this is not - * necessarily the same as the track's \a number field. - * \param new_num_indices The desired length of the array; may be \c 0. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code object->data.cue_sheet.num_tracks > track_num \endcode - * \code (object->data.cue_sheet.tracks[track_num].indices == NULL && object->data.cue_sheet.tracks[track_num].num_indices == 0) || - * (object->data.cue_sheet.tracks[track_num].indices != NULL && object->data.cue_sheet.tracks[track_num].num_indices > 0) \endcode - * \retval FLAC__bool - * \c false if memory allocation error, else \c true. - */ + + If the size shrinks, elements will truncated; if it grows, new blank + indices will be added to the end. + + \param object A pointer to an existing CUESHEET object. + \param track_num The index of the track to modify. NOTE: this is not + necessarily the same as the track's \a number field. + \param new_num_indices The desired length of the array; may be \c 0. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + \code object->data.cue_sheet.num_tracks > track_num \endcode + \code (object->data.cue_sheet.tracks[track_num].indices == NULL && object->data.cue_sheet.tracks[track_num].num_indices == 0) || + (object->data.cue_sheet.tracks[track_num].indices != NULL && object->data.cue_sheet.tracks[track_num].num_indices > 0) \endcode + \retval FLAC__bool + \c false if memory allocation error, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_resize_indices(FLAC__StreamMetadata *object, uint32_t track_num, uint32_t new_num_indices); /** Insert an index point in a CUESHEET track at the given index. - * - * \param object A pointer to an existing CUESHEET object. - * \param track_num The index of the track to modify. NOTE: this is not - * necessarily the same as the track's \a number field. - * \param index_num The index into the track's index array at which to - * insert the index point. NOTE: this is not necessarily - * the same as the index point's \a number field. The - * indices at and after \a index_num move right one - * position. To append an index point to the end, set - * \a index_num to - * \c object->data.cue_sheet.tracks[track_num].num_indices . - * \param index The index point to insert. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code object->data.cue_sheet.num_tracks > track_num \endcode - * \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode - * \retval FLAC__bool - * \c false if realloc() fails, else \c true. - */ + + \param object A pointer to an existing CUESHEET object. + \param track_num The index of the track to modify. NOTE: this is not + necessarily the same as the track's \a number field. + \param index_num The index into the track's index array at which to + insert the index point. NOTE: this is not necessarily + the same as the index point's \a number field. The + indices at and after \a index_num move right one + position. To append an index point to the end, set + \a index_num to + \c object->data.cue_sheet.tracks[track_num].num_indices . + \param index The index point to insert. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + \code object->data.cue_sheet.num_tracks > track_num \endcode + \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode + \retval FLAC__bool + \c false if realloc() fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_index(FLAC__StreamMetadata *object, uint32_t track_num, uint32_t index_num, FLAC__StreamMetadata_CueSheet_Index index); /** Insert a blank index point in a CUESHEET track at the given index. - * - * A blank index point is one in which all field values are zero. - * - * \param object A pointer to an existing CUESHEET object. - * \param track_num The index of the track to modify. NOTE: this is not - * necessarily the same as the track's \a number field. - * \param index_num The index into the track's index array at which to - * insert the index point. NOTE: this is not necessarily - * the same as the index point's \a number field. The - * indices at and after \a index_num move right one - * position. To append an index point to the end, set - * \a index_num to - * \c object->data.cue_sheet.tracks[track_num].num_indices . - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code object->data.cue_sheet.num_tracks > track_num \endcode - * \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode - * \retval FLAC__bool - * \c false if realloc() fails, else \c true. - */ + + A blank index point is one in which all field values are zero. + + \param object A pointer to an existing CUESHEET object. + \param track_num The index of the track to modify. NOTE: this is not + necessarily the same as the track's \a number field. + \param index_num The index into the track's index array at which to + insert the index point. NOTE: this is not necessarily + the same as the index point's \a number field. The + indices at and after \a index_num move right one + position. To append an index point to the end, set + \a index_num to + \c object->data.cue_sheet.tracks[track_num].num_indices . + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + \code object->data.cue_sheet.num_tracks > track_num \endcode + \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode + \retval FLAC__bool + \c false if realloc() fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_blank_index(FLAC__StreamMetadata *object, uint32_t track_num, uint32_t index_num); /** Delete an index point in a CUESHEET track at the given index. - * - * \param object A pointer to an existing CUESHEET object. - * \param track_num The index into the track array of the track to - * modify. NOTE: this is not necessarily the same - * as the track's \a number field. - * \param index_num The index into the track's index array of the index - * to delete. NOTE: this is not necessarily the same - * as the index's \a number field. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code object->data.cue_sheet.num_tracks > track_num \endcode - * \code object->data.cue_sheet.tracks[track_num].num_indices > index_num \endcode - * \retval FLAC__bool - * \c false if realloc() fails, else \c true. - */ + + \param object A pointer to an existing CUESHEET object. + \param track_num The index into the track array of the track to + modify. NOTE: this is not necessarily the same + as the track's \a number field. + \param index_num The index into the track's index array of the index + to delete. NOTE: this is not necessarily the same + as the index's \a number field. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + \code object->data.cue_sheet.num_tracks > track_num \endcode + \code object->data.cue_sheet.tracks[track_num].num_indices > index_num \endcode + \retval FLAC__bool + \c false if realloc() fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_delete_index(FLAC__StreamMetadata *object, uint32_t track_num, uint32_t index_num); /** Resize the track array. - * - * If the size shrinks, elements will truncated; if it grows, new blank - * tracks will be added to the end. - * - * \param object A pointer to an existing CUESHEET object. - * \param new_num_tracks The desired length of the array; may be \c 0. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code (object->data.cue_sheet.tracks == NULL && object->data.cue_sheet.num_tracks == 0) || - * (object->data.cue_sheet.tracks != NULL && object->data.cue_sheet.num_tracks > 0) \endcode - * \retval FLAC__bool - * \c false if memory allocation error, else \c true. - */ + + If the size shrinks, elements will truncated; if it grows, new blank + tracks will be added to the end. + + \param object A pointer to an existing CUESHEET object. + \param new_num_tracks The desired length of the array; may be \c 0. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + \code (object->data.cue_sheet.tracks == NULL && object->data.cue_sheet.num_tracks == 0) || + (object->data.cue_sheet.tracks != NULL && object->data.cue_sheet.num_tracks > 0) \endcode + \retval FLAC__bool + \c false if memory allocation error, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_resize_tracks(FLAC__StreamMetadata *object, uint32_t new_num_tracks); /** Sets a track in a CUESHEET block. - * - * If \a copy is \c true, a copy of the track is stored; otherwise, the object - * takes ownership of the \a track pointer. - * - * \param object A pointer to an existing CUESHEET object. - * \param track_num Index into track array to set. NOTE: this is not - * necessarily the same as the track's \a number field. - * \param track The track to set the track to. You may safely pass in - * a const pointer if \a copy is \c true. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code track_num < object->data.cue_sheet.num_tracks \endcode - * \code (track->indices != NULL && track->num_indices > 0) || - * (track->indices == NULL && track->num_indices == 0) \endcode - * \retval FLAC__bool - * \c false if \a copy is \c true and malloc() fails, else \c true. - */ + + If \a copy is \c true, a copy of the track is stored; otherwise, the object + takes ownership of the \a track pointer. + + \param object A pointer to an existing CUESHEET object. + \param track_num Index into track array to set. NOTE: this is not + necessarily the same as the track's \a number field. + \param track The track to set the track to. You may safely pass in + a const pointer if \a copy is \c true. + \param copy See above. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + \code track_num < object->data.cue_sheet.num_tracks \endcode + \code (track->indices != NULL && track->num_indices > 0) || + (track->indices == NULL && track->num_indices == 0) \endcode + \retval FLAC__bool + \c false if \a copy is \c true and malloc() fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_set_track(FLAC__StreamMetadata *object, uint32_t track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy); /** Insert a track in a CUESHEET block at the given index. - * - * If \a copy is \c true, a copy of the track is stored; otherwise, the object - * takes ownership of the \a track pointer. - * - * \param object A pointer to an existing CUESHEET object. - * \param track_num The index at which to insert the track. NOTE: this - * is not necessarily the same as the track's \a number - * field. The tracks at and after \a track_num move right - * one position. To append a track to the end, set - * \a track_num to \c object->data.cue_sheet.num_tracks . - * \param track The track to insert. You may safely pass in a const - * pointer if \a copy is \c true. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code object->data.cue_sheet.num_tracks >= track_num \endcode - * \retval FLAC__bool - * \c false if \a copy is \c true and malloc() fails, else \c true. - */ + + If \a copy is \c true, a copy of the track is stored; otherwise, the object + takes ownership of the \a track pointer. + + \param object A pointer to an existing CUESHEET object. + \param track_num The index at which to insert the track. NOTE: this + is not necessarily the same as the track's \a number + field. The tracks at and after \a track_num move right + one position. To append a track to the end, set + \a track_num to \c object->data.cue_sheet.num_tracks . + \param track The track to insert. You may safely pass in a const + pointer if \a copy is \c true. + \param copy See above. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + \code object->data.cue_sheet.num_tracks >= track_num \endcode + \retval FLAC__bool + \c false if \a copy is \c true and malloc() fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_track(FLAC__StreamMetadata *object, uint32_t track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy); /** Insert a blank track in a CUESHEET block at the given index. - * - * A blank track is one in which all field values are zero. - * - * \param object A pointer to an existing CUESHEET object. - * \param track_num The index at which to insert the track. NOTE: this - * is not necessarily the same as the track's \a number - * field. The tracks at and after \a track_num move right - * one position. To append a track to the end, set - * \a track_num to \c object->data.cue_sheet.num_tracks . - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code object->data.cue_sheet.num_tracks >= track_num \endcode - * \retval FLAC__bool - * \c false if \a copy is \c true and malloc() fails, else \c true. - */ + + A blank track is one in which all field values are zero. + + \param object A pointer to an existing CUESHEET object. + \param track_num The index at which to insert the track. NOTE: this + is not necessarily the same as the track's \a number + field. The tracks at and after \a track_num move right + one position. To append a track to the end, set + \a track_num to \c object->data.cue_sheet.num_tracks . + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + \code object->data.cue_sheet.num_tracks >= track_num \endcode + \retval FLAC__bool + \c false if \a copy is \c true and malloc() fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_blank_track(FLAC__StreamMetadata *object, uint32_t track_num); /** Delete a track in a CUESHEET block at the given index. - * - * \param object A pointer to an existing CUESHEET object. - * \param track_num The index into the track array of the track to - * delete. NOTE: this is not necessarily the same - * as the track's \a number field. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code object->data.cue_sheet.num_tracks > track_num \endcode - * \retval FLAC__bool - * \c false if realloc() fails, else \c true. - */ + + \param object A pointer to an existing CUESHEET object. + \param track_num The index into the track array of the track to + delete. NOTE: this is not necessarily the same + as the track's \a number field. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + \code object->data.cue_sheet.num_tracks > track_num \endcode + \retval FLAC__bool + \c false if realloc() fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_delete_track(FLAC__StreamMetadata *object, uint32_t track_num); /** Check a cue sheet to see if it conforms to the FLAC specification. - * See the format specification for limits on the contents of the - * cue sheet. - * - * \param object A pointer to an existing CUESHEET object. - * \param check_cd_da_subset If \c true, check CUESHEET against more - * stringent requirements for a CD-DA (audio) disc. - * \param violation Address of a pointer to a string. If there is a - * violation, a pointer to a string explanation of the - * violation will be returned here. \a violation may be - * \c NULL if you don't need the returned string. Do not - * free the returned string; it will always point to static - * data. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \retval FLAC__bool - * \c false if cue sheet is illegal, else \c true. - */ + See the format specification for limits on the contents of the + cue sheet. + + \param object A pointer to an existing CUESHEET object. + \param check_cd_da_subset If \c true, check CUESHEET against more + stringent requirements for a CD-DA (audio) disc. + \param violation Address of a pointer to a string. If there is a + violation, a pointer to a string explanation of the + violation will be returned here. \a violation may be + \c NULL if you don't need the returned string. Do not + free the returned string; it will always point to static + data. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + \retval FLAC__bool + \c false if cue sheet is illegal, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_is_legal(const FLAC__StreamMetadata *object, FLAC__bool check_cd_da_subset, const char **violation); /** Calculate and return the CDDB/freedb ID for a cue sheet. The function - * assumes the cue sheet corresponds to a CD; the result is undefined - * if the cuesheet's is_cd bit is not set. - * - * \param object A pointer to an existing CUESHEET object. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \retval FLAC__uint32 - * The unsigned integer representation of the CDDB/freedb ID - */ + assumes the cue sheet corresponds to a CD; the result is undefined + if the cuesheet's is_cd bit is not set. + + \param object A pointer to an existing CUESHEET object. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + \retval FLAC__uint32 + The unsigned integer representation of the CDDB/freedb ID +*/ FLAC_API FLAC__uint32 FLAC__metadata_object_cuesheet_calculate_cddb_id(const FLAC__StreamMetadata *object); /** Sets the MIME type of a PICTURE block. - * - * If \a copy is \c true, a copy of the string is stored; otherwise, the object - * takes ownership of the pointer. The existing string will be freed if this - * function is successful, otherwise the original string will remain if \a copy - * is \c true and malloc() fails. - * - * \note It is safe to pass a const pointer to \a mime_type if \a copy is \c true. - * - * \param object A pointer to an existing PICTURE object. - * \param mime_type A pointer to the MIME type string. The string must be - * ASCII characters 0x20-0x7e, NUL-terminated. No validation - * is done. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode - * \code (mime_type != NULL) \endcode - * \retval FLAC__bool - * \c false if \a copy is \c true and malloc() fails, else \c true. - */ + + If \a copy is \c true, a copy of the string is stored; otherwise, the object + takes ownership of the pointer. The existing string will be freed if this + function is successful, otherwise the original string will remain if \a copy + is \c true and malloc() fails. + + \note It is safe to pass a const pointer to \a mime_type if \a copy is \c true. + + \param object A pointer to an existing PICTURE object. + \param mime_type A pointer to the MIME type string. The string must be + ASCII characters 0x20-0x7e, NUL-terminated. No validation + is done. + \param copy See above. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode + \code (mime_type != NULL) \endcode + \retval FLAC__bool + \c false if \a copy is \c true and malloc() fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_picture_set_mime_type(FLAC__StreamMetadata *object, char *mime_type, FLAC__bool copy); /** Sets the description of a PICTURE block. - * - * If \a copy is \c true, a copy of the string is stored; otherwise, the object - * takes ownership of the pointer. The existing string will be freed if this - * function is successful, otherwise the original string will remain if \a copy - * is \c true and malloc() fails. - * - * \note It is safe to pass a const pointer to \a description if \a copy is \c true. - * - * \param object A pointer to an existing PICTURE object. - * \param description A pointer to the description string. The string must be - * valid UTF-8, NUL-terminated. No validation is done. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode - * \code (description != NULL) \endcode - * \retval FLAC__bool - * \c false if \a copy is \c true and malloc() fails, else \c true. - */ + + If \a copy is \c true, a copy of the string is stored; otherwise, the object + takes ownership of the pointer. The existing string will be freed if this + function is successful, otherwise the original string will remain if \a copy + is \c true and malloc() fails. + + \note It is safe to pass a const pointer to \a description if \a copy is \c true. + + \param object A pointer to an existing PICTURE object. + \param description A pointer to the description string. The string must be + valid UTF-8, NUL-terminated. No validation is done. + \param copy See above. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode + \code (description != NULL) \endcode + \retval FLAC__bool + \c false if \a copy is \c true and malloc() fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_picture_set_description(FLAC__StreamMetadata *object, FLAC__byte *description, FLAC__bool copy); /** Sets the picture data of a PICTURE block. - * - * If \a copy is \c true, a copy of the data is stored; otherwise, the object - * takes ownership of the pointer. Also sets the \a data_length field of the - * metadata object to what is passed in as the \a length parameter. The - * existing data will be freed if this function is successful, otherwise the - * original data and data_length will remain if \a copy is \c true and - * malloc() fails. - * - * \note It is safe to pass a const pointer to \a data if \a copy is \c true. - * - * \param object A pointer to an existing PICTURE object. - * \param data A pointer to the data to set. - * \param length The length of \a data in bytes. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode - * \code (data != NULL && length > 0) || - * (data == NULL && length == 0 && copy == false) \endcode - * \retval FLAC__bool - * \c false if \a copy is \c true and malloc() fails, else \c true. - */ + + If \a copy is \c true, a copy of the data is stored; otherwise, the object + takes ownership of the pointer. Also sets the \a data_length field of the + metadata object to what is passed in as the \a length parameter. The + existing data will be freed if this function is successful, otherwise the + original data and data_length will remain if \a copy is \c true and + malloc() fails. + + \note It is safe to pass a const pointer to \a data if \a copy is \c true. + + \param object A pointer to an existing PICTURE object. + \param data A pointer to the data to set. + \param length The length of \a data in bytes. + \param copy See above. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode + \code (data != NULL && length > 0) || + (data == NULL && length == 0 && copy == false) \endcode + \retval FLAC__bool + \c false if \a copy is \c true and malloc() fails, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_picture_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, FLAC__uint32 length, FLAC__bool copy); /** Check a PICTURE block to see if it conforms to the FLAC specification. - * See the format specification for limits on the contents of the - * PICTURE block. - * - * \param object A pointer to existing PICTURE block to be checked. - * \param violation Address of a pointer to a string. If there is a - * violation, a pointer to a string explanation of the - * violation will be returned here. \a violation may be - * \c NULL if you don't need the returned string. Do not - * free the returned string; it will always point to static - * data. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode - * \retval FLAC__bool - * \c false if PICTURE block is illegal, else \c true. - */ + See the format specification for limits on the contents of the + PICTURE block. + + \param object A pointer to existing PICTURE block to be checked. + \param violation Address of a pointer to a string. If there is a + violation, a pointer to a string explanation of the + violation will be returned here. \a violation may be + \c NULL if you don't need the returned string. Do not + free the returned string; it will always point to static + data. + \assert + \code object != NULL \endcode + \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode + \retval FLAC__bool + \c false if PICTURE block is illegal, else \c true. +*/ FLAC_API FLAC__bool FLAC__metadata_object_picture_is_legal(const FLAC__StreamMetadata *object, const char **violation); /* \} */ diff --git a/src/libflac/FLAC/ordinals.h b/src/libflac/FLAC/ordinals.h index 75b830d6..efc1dac0 100644 --- a/src/libflac/FLAC/ordinals.h +++ b/src/libflac/FLAC/ordinals.h @@ -1,43 +1,43 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2000-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__ORDINALS_H #define FLAC__ORDINALS_H #if defined(_MSC_VER) && _MSC_VER < 1600 -/* Microsoft Visual Studio earlier than the 2010 version did not provide - * the 1999 ISO C Standard header file . - */ +/* Microsoft Visual Studio earlier than the 2010 version did not provide + the 1999 ISO C Standard header file . +*/ typedef signed __int8 FLAC__int8; typedef signed __int16 FLAC__int16; diff --git a/src/libflac/FLAC/stream_decoder.h b/src/libflac/FLAC/stream_decoder.h index 978c42d4..e05c3049 100644 --- a/src/libflac/FLAC/stream_decoder.h +++ b/src/libflac/FLAC/stream_decoder.h @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2000-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__STREAM_DECODER_H #define FLAC__STREAM_DECODER_H @@ -43,1525 +43,1525 @@ extern "C" { /** \file include/FLAC/stream_decoder.h - * - * \brief - * This module contains the functions which implement the stream - * decoder. - * - * See the detailed documentation in the - * \link flac_stream_decoder stream decoder \endlink module. - */ + + \brief + This module contains the functions which implement the stream + decoder. + + See the detailed documentation in the + \link flac_stream_decoder stream decoder \endlink module. +*/ /** \defgroup flac_decoder FLAC/ \*_decoder.h: decoder interfaces - * \ingroup flac - * - * \brief - * This module describes the decoder layers provided by libFLAC. - * - * The stream decoder can be used to decode complete streams either from - * the client via callbacks, or directly from a file, depending on how - * it is initialized. When decoding via callbacks, the client provides - * callbacks for reading FLAC data and writing decoded samples, and - * handling metadata and errors. If the client also supplies seek-related - * callback, the decoder function for sample-accurate seeking within the - * FLAC input is also available. When decoding from a file, the client - * needs only supply a filename or open \c FILE* and write/metadata/error - * callbacks; the rest of the callbacks are supplied internally. For more - * info see the \link flac_stream_decoder stream decoder \endlink module. - */ + \ingroup flac + + \brief + This module describes the decoder layers provided by libFLAC. + + The stream decoder can be used to decode complete streams either from + the client via callbacks, or directly from a file, depending on how + it is initialized. When decoding via callbacks, the client provides + callbacks for reading FLAC data and writing decoded samples, and + handling metadata and errors. If the client also supplies seek-related + callback, the decoder function for sample-accurate seeking within the + FLAC input is also available. When decoding from a file, the client + needs only supply a filename or open \c FILE* and write/metadata/error + callbacks; the rest of the callbacks are supplied internally. For more + info see the \link flac_stream_decoder stream decoder \endlink module. +*/ /** \defgroup flac_stream_decoder FLAC/stream_decoder.h: stream decoder interface - * \ingroup flac_decoder - * - * \brief - * This module contains the functions which implement the stream - * decoder. - * - * The stream decoder can decode native FLAC, and optionally Ogg FLAC - * (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files. - * - * The basic usage of this decoder is as follows: - * - The program creates an instance of a decoder using - * FLAC__stream_decoder_new(). - * - The program overrides the default settings using - * FLAC__stream_decoder_set_*() functions. - * - The program initializes the instance to validate the settings and - * prepare for decoding using - * - FLAC__stream_decoder_init_stream() or FLAC__stream_decoder_init_FILE() - * or FLAC__stream_decoder_init_file() for native FLAC, - * - FLAC__stream_decoder_init_ogg_stream() or FLAC__stream_decoder_init_ogg_FILE() - * or FLAC__stream_decoder_init_ogg_file() for Ogg FLAC - * - The program calls the FLAC__stream_decoder_process_*() functions - * to decode data, which subsequently calls the callbacks. - * - The program finishes the decoding with FLAC__stream_decoder_finish(), - * which flushes the input and output and resets the decoder to the - * uninitialized state. - * - The instance may be used again or deleted with - * FLAC__stream_decoder_delete(). - * - * In more detail, the program will create a new instance by calling - * FLAC__stream_decoder_new(), then call FLAC__stream_decoder_set_*() - * functions to override the default decoder options, and call - * one of the FLAC__stream_decoder_init_*() functions. - * - * There are three initialization functions for native FLAC, one for - * setting up the decoder to decode FLAC data from the client via - * callbacks, and two for decoding directly from a FLAC file. - * - * For decoding via callbacks, use FLAC__stream_decoder_init_stream(). - * You must also supply several callbacks for handling I/O. Some (like - * seeking) are optional, depending on the capabilities of the input. - * - * For decoding directly from a file, use FLAC__stream_decoder_init_FILE() - * or FLAC__stream_decoder_init_file(). Then you must only supply an open - * \c FILE* or filename and fewer callbacks; the decoder will handle - * the other callbacks internally. - * - * There are three similarly-named init functions for decoding from Ogg - * FLAC streams. Check \c FLAC_API_SUPPORTS_OGG_FLAC to find out if the - * library has been built with Ogg support. - * - * Once the decoder is initialized, your program will call one of several - * functions to start the decoding process: - * - * - FLAC__stream_decoder_process_single() - Tells the decoder to process at - * most one metadata block or audio frame and return, calling either the - * metadata callback or write callback, respectively, once. If the decoder - * loses sync it will return with only the error callback being called. - * - FLAC__stream_decoder_process_until_end_of_metadata() - Tells the decoder - * to process the stream from the current location and stop upon reaching - * the first audio frame. The client will get one metadata, write, or error - * callback per metadata block, audio frame, or sync error, respectively. - * - FLAC__stream_decoder_process_until_end_of_stream() - Tells the decoder - * to process the stream from the current location until the read callback - * returns FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM or - * FLAC__STREAM_DECODER_READ_STATUS_ABORT. The client will get one metadata, - * write, or error callback per metadata block, audio frame, or sync error, - * respectively. - * - * When the decoder has finished decoding (normally or through an abort), - * the instance is finished by calling FLAC__stream_decoder_finish(), which - * ensures the decoder is in the correct state and frees memory. Then the - * instance may be deleted with FLAC__stream_decoder_delete() or initialized - * again to decode another stream. - * - * Seeking is exposed through the FLAC__stream_decoder_seek_absolute() method. - * At any point after the stream decoder has been initialized, the client can - * call this function to seek to an exact sample within the stream. - * Subsequently, the first time the write callback is called it will be - * passed a (possibly partial) block starting at that sample. - * - * If the client cannot seek via the callback interface provided, but still - * has another way of seeking, it can flush the decoder using - * FLAC__stream_decoder_flush() and start feeding data from the new position - * through the read callback. - * - * The stream decoder also provides MD5 signature checking. If this is - * turned on before initialization, FLAC__stream_decoder_finish() will - * report when the decoded MD5 signature does not match the one stored - * in the STREAMINFO block. MD5 checking is automatically turned off - * (until the next FLAC__stream_decoder_reset()) if there is no signature - * in the STREAMINFO block or when a seek is attempted. - * - * The FLAC__stream_decoder_set_metadata_*() functions deserve special - * attention. By default, the decoder only calls the metadata_callback for - * the STREAMINFO block. These functions allow you to tell the decoder - * explicitly which blocks to parse and return via the metadata_callback - * and/or which to skip. Use a FLAC__stream_decoder_set_metadata_respond_all(), - * FLAC__stream_decoder_set_metadata_ignore() ... or FLAC__stream_decoder_set_metadata_ignore_all(), - * FLAC__stream_decoder_set_metadata_respond() ... sequence to exactly specify - * which blocks to return. Remember that metadata blocks can potentially - * be big (for example, cover art) so filtering out the ones you don't - * use can reduce the memory requirements of the decoder. Also note the - * special forms FLAC__stream_decoder_set_metadata_respond_application(id) - * and FLAC__stream_decoder_set_metadata_ignore_application(id) for - * filtering APPLICATION blocks based on the application ID. - * - * STREAMINFO and SEEKTABLE blocks are always parsed and used internally, but - * they still can legally be filtered from the metadata_callback. - * - * \note - * The "set" functions may only be called when the decoder is in the - * state FLAC__STREAM_DECODER_UNINITIALIZED, i.e. after - * FLAC__stream_decoder_new() or FLAC__stream_decoder_finish(), but - * before FLAC__stream_decoder_init_*(). If this is the case they will - * return \c true, otherwise \c false. - * - * \note - * FLAC__stream_decoder_finish() resets all settings to the constructor - * defaults, including the callbacks. - * - * \{ - */ + \ingroup flac_decoder + + \brief + This module contains the functions which implement the stream + decoder. + + The stream decoder can decode native FLAC, and optionally Ogg FLAC + (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files. + + The basic usage of this decoder is as follows: + - The program creates an instance of a decoder using + FLAC__stream_decoder_new(). + - The program overrides the default settings using + FLAC__stream_decoder_set_*() functions. + - The program initializes the instance to validate the settings and + prepare for decoding using + - FLAC__stream_decoder_init_stream() or FLAC__stream_decoder_init_FILE() + or FLAC__stream_decoder_init_file() for native FLAC, + - FLAC__stream_decoder_init_ogg_stream() or FLAC__stream_decoder_init_ogg_FILE() + or FLAC__stream_decoder_init_ogg_file() for Ogg FLAC + - The program calls the FLAC__stream_decoder_process_*() functions + to decode data, which subsequently calls the callbacks. + - The program finishes the decoding with FLAC__stream_decoder_finish(), + which flushes the input and output and resets the decoder to the + uninitialized state. + - The instance may be used again or deleted with + FLAC__stream_decoder_delete(). + + In more detail, the program will create a new instance by calling + FLAC__stream_decoder_new(), then call FLAC__stream_decoder_set_*() + functions to override the default decoder options, and call + one of the FLAC__stream_decoder_init_*() functions. + + There are three initialization functions for native FLAC, one for + setting up the decoder to decode FLAC data from the client via + callbacks, and two for decoding directly from a FLAC file. + + For decoding via callbacks, use FLAC__stream_decoder_init_stream(). + You must also supply several callbacks for handling I/O. Some (like + seeking) are optional, depending on the capabilities of the input. + + For decoding directly from a file, use FLAC__stream_decoder_init_FILE() + or FLAC__stream_decoder_init_file(). Then you must only supply an open + \c FILE* or filename and fewer callbacks; the decoder will handle + the other callbacks internally. + + There are three similarly-named init functions for decoding from Ogg + FLAC streams. Check \c FLAC_API_SUPPORTS_OGG_FLAC to find out if the + library has been built with Ogg support. + + Once the decoder is initialized, your program will call one of several + functions to start the decoding process: + + - FLAC__stream_decoder_process_single() - Tells the decoder to process at + most one metadata block or audio frame and return, calling either the + metadata callback or write callback, respectively, once. If the decoder + loses sync it will return with only the error callback being called. + - FLAC__stream_decoder_process_until_end_of_metadata() - Tells the decoder + to process the stream from the current location and stop upon reaching + the first audio frame. The client will get one metadata, write, or error + callback per metadata block, audio frame, or sync error, respectively. + - FLAC__stream_decoder_process_until_end_of_stream() - Tells the decoder + to process the stream from the current location until the read callback + returns FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM or + FLAC__STREAM_DECODER_READ_STATUS_ABORT. The client will get one metadata, + write, or error callback per metadata block, audio frame, or sync error, + respectively. + + When the decoder has finished decoding (normally or through an abort), + the instance is finished by calling FLAC__stream_decoder_finish(), which + ensures the decoder is in the correct state and frees memory. Then the + instance may be deleted with FLAC__stream_decoder_delete() or initialized + again to decode another stream. + + Seeking is exposed through the FLAC__stream_decoder_seek_absolute() method. + At any point after the stream decoder has been initialized, the client can + call this function to seek to an exact sample within the stream. + Subsequently, the first time the write callback is called it will be + passed a (possibly partial) block starting at that sample. + + If the client cannot seek via the callback interface provided, but still + has another way of seeking, it can flush the decoder using + FLAC__stream_decoder_flush() and start feeding data from the new position + through the read callback. + + The stream decoder also provides MD5 signature checking. If this is + turned on before initialization, FLAC__stream_decoder_finish() will + report when the decoded MD5 signature does not match the one stored + in the STREAMINFO block. MD5 checking is automatically turned off + (until the next FLAC__stream_decoder_reset()) if there is no signature + in the STREAMINFO block or when a seek is attempted. + + The FLAC__stream_decoder_set_metadata_*() functions deserve special + attention. By default, the decoder only calls the metadata_callback for + the STREAMINFO block. These functions allow you to tell the decoder + explicitly which blocks to parse and return via the metadata_callback + and/or which to skip. Use a FLAC__stream_decoder_set_metadata_respond_all(), + FLAC__stream_decoder_set_metadata_ignore() ... or FLAC__stream_decoder_set_metadata_ignore_all(), + FLAC__stream_decoder_set_metadata_respond() ... sequence to exactly specify + which blocks to return. Remember that metadata blocks can potentially + be big (for example, cover art) so filtering out the ones you don't + use can reduce the memory requirements of the decoder. Also note the + special forms FLAC__stream_decoder_set_metadata_respond_application(id) + and FLAC__stream_decoder_set_metadata_ignore_application(id) for + filtering APPLICATION blocks based on the application ID. + + STREAMINFO and SEEKTABLE blocks are always parsed and used internally, but + they still can legally be filtered from the metadata_callback. + + \note + The "set" functions may only be called when the decoder is in the + state FLAC__STREAM_DECODER_UNINITIALIZED, i.e. after + FLAC__stream_decoder_new() or FLAC__stream_decoder_finish(), but + before FLAC__stream_decoder_init_*(). If this is the case they will + return \c true, otherwise \c false. + + \note + FLAC__stream_decoder_finish() resets all settings to the constructor + defaults, including the callbacks. + + \{ +*/ /** State values for a FLAC__StreamDecoder - * - * The decoder's state can be obtained by calling FLAC__stream_decoder_get_state(). - */ + + The decoder's state can be obtained by calling FLAC__stream_decoder_get_state(). +*/ typedef enum { - FLAC__STREAM_DECODER_SEARCH_FOR_METADATA = 0, - /**< The decoder is ready to search for metadata. */ + FLAC__STREAM_DECODER_SEARCH_FOR_METADATA = 0, + /**< The decoder is ready to search for metadata. */ - FLAC__STREAM_DECODER_READ_METADATA, - /**< The decoder is ready to or is in the process of reading metadata. */ + FLAC__STREAM_DECODER_READ_METADATA, + /**< The decoder is ready to or is in the process of reading metadata. */ - FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC, - /**< The decoder is ready to or is in the process of searching for the - * frame sync code. - */ + FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC, + /** < The decoder is ready to or is in the process of searching for the + frame sync code. + */ - FLAC__STREAM_DECODER_READ_FRAME, - /**< The decoder is ready to or is in the process of reading a frame. */ + FLAC__STREAM_DECODER_READ_FRAME, + /**< The decoder is ready to or is in the process of reading a frame. */ - FLAC__STREAM_DECODER_END_OF_STREAM, - /**< The decoder has reached the end of the stream. */ + FLAC__STREAM_DECODER_END_OF_STREAM, + /**< The decoder has reached the end of the stream. */ - FLAC__STREAM_DECODER_OGG_ERROR, - /**< An error occurred in the underlying Ogg layer. */ + FLAC__STREAM_DECODER_OGG_ERROR, + /**< An error occurred in the underlying Ogg layer. */ - FLAC__STREAM_DECODER_SEEK_ERROR, - /**< An error occurred while seeking. The decoder must be flushed - * with FLAC__stream_decoder_flush() or reset with - * FLAC__stream_decoder_reset() before decoding can continue. - */ + FLAC__STREAM_DECODER_SEEK_ERROR, + /** < An error occurred while seeking. The decoder must be flushed + with FLAC__stream_decoder_flush() or reset with + FLAC__stream_decoder_reset() before decoding can continue. + */ - FLAC__STREAM_DECODER_ABORTED, - /**< The decoder was aborted by the read or write callback. */ + FLAC__STREAM_DECODER_ABORTED, + /**< The decoder was aborted by the read or write callback. */ - FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR, - /**< An error occurred allocating memory. The decoder is in an invalid - * state and can no longer be used. - */ + FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR, + /** < An error occurred allocating memory. The decoder is in an invalid + state and can no longer be used. + */ - FLAC__STREAM_DECODER_UNINITIALIZED - /**< The decoder is in the uninitialized state; one of the - * FLAC__stream_decoder_init_*() functions must be called before samples - * can be processed. - */ + FLAC__STREAM_DECODER_UNINITIALIZED + /** < The decoder is in the uninitialized state; one of the + FLAC__stream_decoder_init_*() functions must be called before samples + can be processed. + */ } FLAC__StreamDecoderState; /** Maps a FLAC__StreamDecoderState to a C string. - * - * Using a FLAC__StreamDecoderState as the index to this array - * will give the string equivalent. The contents should not be modified. - */ + + Using a FLAC__StreamDecoderState as the index to this array + will give the string equivalent. The contents should not be modified. +*/ extern FLAC_API const char * const FLAC__StreamDecoderStateString[]; /** Possible return values for the FLAC__stream_decoder_init_*() functions. - */ +*/ typedef enum { - FLAC__STREAM_DECODER_INIT_STATUS_OK = 0, - /**< Initialization was successful. */ + FLAC__STREAM_DECODER_INIT_STATUS_OK = 0, + /**< Initialization was successful. */ - FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER, - /**< The library was not compiled with support for the given container - * format. - */ + FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER, + /** < The library was not compiled with support for the given container + format. + */ - FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS, - /**< A required callback was not supplied. */ + FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS, + /**< A required callback was not supplied. */ - FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR, - /**< An error occurred allocating memory. */ + FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR, + /**< An error occurred allocating memory. */ - FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE, - /**< fopen() failed in FLAC__stream_decoder_init_file() or - * FLAC__stream_decoder_init_ogg_file(). */ + FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE, + /** < fopen() failed in FLAC__stream_decoder_init_file() or + FLAC__stream_decoder_init_ogg_file(). */ - FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED - /**< FLAC__stream_decoder_init_*() was called when the decoder was - * already initialized, usually because - * FLAC__stream_decoder_finish() was not called. - */ + FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED + /** < FLAC__stream_decoder_init_*() was called when the decoder was + already initialized, usually because + FLAC__stream_decoder_finish() was not called. + */ } FLAC__StreamDecoderInitStatus; /** Maps a FLAC__StreamDecoderInitStatus to a C string. - * - * Using a FLAC__StreamDecoderInitStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ + + Using a FLAC__StreamDecoderInitStatus as the index to this array + will give the string equivalent. The contents should not be modified. +*/ extern FLAC_API const char * const FLAC__StreamDecoderInitStatusString[]; /** Return values for the FLAC__StreamDecoder read callback. - */ +*/ typedef enum { - FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, - /**< The read was OK and decoding can continue. */ + FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, + /**< The read was OK and decoding can continue. */ - FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM, - /**< The read was attempted while at the end of the stream. Note that - * the client must only return this value when the read callback was - * called when already at the end of the stream. Otherwise, if the read - * itself moves to the end of the stream, the client should still return - * the data and \c FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, and then on - * the next read callback it should return - * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM with a byte count - * of \c 0. - */ + FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM, + /** < The read was attempted while at the end of the stream. Note that + the client must only return this value when the read callback was + called when already at the end of the stream. Otherwise, if the read + itself moves to the end of the stream, the client should still return + the data and \c FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, and then on + the next read callback it should return + \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM with a byte count + of \c 0. + */ - FLAC__STREAM_DECODER_READ_STATUS_ABORT - /**< An unrecoverable error occurred. The decoder will return from the process call. */ + FLAC__STREAM_DECODER_READ_STATUS_ABORT + /**< An unrecoverable error occurred. The decoder will return from the process call. */ } FLAC__StreamDecoderReadStatus; /** Maps a FLAC__StreamDecoderReadStatus to a C string. - * - * Using a FLAC__StreamDecoderReadStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ + + Using a FLAC__StreamDecoderReadStatus as the index to this array + will give the string equivalent. The contents should not be modified. +*/ extern FLAC_API const char * const FLAC__StreamDecoderReadStatusString[]; /** Return values for the FLAC__StreamDecoder seek callback. - */ +*/ typedef enum { - FLAC__STREAM_DECODER_SEEK_STATUS_OK, - /**< The seek was OK and decoding can continue. */ + FLAC__STREAM_DECODER_SEEK_STATUS_OK, + /**< The seek was OK and decoding can continue. */ - FLAC__STREAM_DECODER_SEEK_STATUS_ERROR, - /**< An unrecoverable error occurred. The decoder will return from the process call. */ + FLAC__STREAM_DECODER_SEEK_STATUS_ERROR, + /**< An unrecoverable error occurred. The decoder will return from the process call. */ - FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED - /**< Client does not support seeking. */ + FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED + /**< Client does not support seeking. */ } FLAC__StreamDecoderSeekStatus; /** Maps a FLAC__StreamDecoderSeekStatus to a C string. - * - * Using a FLAC__StreamDecoderSeekStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ + + Using a FLAC__StreamDecoderSeekStatus as the index to this array + will give the string equivalent. The contents should not be modified. +*/ extern FLAC_API const char * const FLAC__StreamDecoderSeekStatusString[]; /** Return values for the FLAC__StreamDecoder tell callback. - */ +*/ typedef enum { - FLAC__STREAM_DECODER_TELL_STATUS_OK, - /**< The tell was OK and decoding can continue. */ + FLAC__STREAM_DECODER_TELL_STATUS_OK, + /**< The tell was OK and decoding can continue. */ - FLAC__STREAM_DECODER_TELL_STATUS_ERROR, - /**< An unrecoverable error occurred. The decoder will return from the process call. */ + FLAC__STREAM_DECODER_TELL_STATUS_ERROR, + /**< An unrecoverable error occurred. The decoder will return from the process call. */ - FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED - /**< Client does not support telling the position. */ + FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED + /**< Client does not support telling the position. */ } FLAC__StreamDecoderTellStatus; /** Maps a FLAC__StreamDecoderTellStatus to a C string. - * - * Using a FLAC__StreamDecoderTellStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ + + Using a FLAC__StreamDecoderTellStatus as the index to this array + will give the string equivalent. The contents should not be modified. +*/ extern FLAC_API const char * const FLAC__StreamDecoderTellStatusString[]; /** Return values for the FLAC__StreamDecoder length callback. - */ +*/ typedef enum { - FLAC__STREAM_DECODER_LENGTH_STATUS_OK, - /**< The length call was OK and decoding can continue. */ + FLAC__STREAM_DECODER_LENGTH_STATUS_OK, + /**< The length call was OK and decoding can continue. */ - FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR, - /**< An unrecoverable error occurred. The decoder will return from the process call. */ + FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR, + /**< An unrecoverable error occurred. The decoder will return from the process call. */ - FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED - /**< Client does not support reporting the length. */ + FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED + /**< Client does not support reporting the length. */ } FLAC__StreamDecoderLengthStatus; /** Maps a FLAC__StreamDecoderLengthStatus to a C string. - * - * Using a FLAC__StreamDecoderLengthStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ + + Using a FLAC__StreamDecoderLengthStatus as the index to this array + will give the string equivalent. The contents should not be modified. +*/ extern FLAC_API const char * const FLAC__StreamDecoderLengthStatusString[]; /** Return values for the FLAC__StreamDecoder write callback. - */ +*/ typedef enum { - FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE, - /**< The write was OK and decoding can continue. */ + FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE, + /**< The write was OK and decoding can continue. */ - FLAC__STREAM_DECODER_WRITE_STATUS_ABORT - /**< An unrecoverable error occurred. The decoder will return from the process call. */ + FLAC__STREAM_DECODER_WRITE_STATUS_ABORT + /**< An unrecoverable error occurred. The decoder will return from the process call. */ } FLAC__StreamDecoderWriteStatus; /** Maps a FLAC__StreamDecoderWriteStatus to a C string. - * - * Using a FLAC__StreamDecoderWriteStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ + + Using a FLAC__StreamDecoderWriteStatus as the index to this array + will give the string equivalent. The contents should not be modified. +*/ extern FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[]; /** Possible values passed back to the FLAC__StreamDecoder error callback. - * \c FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC is the generic catch- - * all. The rest could be caused by bad sync (false synchronization on - * data that is not the start of a frame) or corrupted data. The error - * itself is the decoder's best guess at what happened assuming a correct - * sync. For example \c FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER - * could be caused by a correct sync on the start of a frame, but some - * data in the frame header was corrupted. Or it could be the result of - * syncing on a point the stream that looked like the starting of a frame - * but was not. \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM - * could be because the decoder encountered a valid frame made by a future - * version of the encoder which it cannot parse, or because of a false - * sync making it appear as though an encountered frame was generated by - * a future encoder. - */ + \c FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC is the generic catch- + all. The rest could be caused by bad sync (false synchronization on + data that is not the start of a frame) or corrupted data. The error + itself is the decoder's best guess at what happened assuming a correct + sync. For example \c FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER + could be caused by a correct sync on the start of a frame, but some + data in the frame header was corrupted. Or it could be the result of + syncing on a point the stream that looked like the starting of a frame + but was not. \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM + could be because the decoder encountered a valid frame made by a future + version of the encoder which it cannot parse, or because of a false + sync making it appear as though an encountered frame was generated by + a future encoder. +*/ typedef enum { - FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, - /**< An error in the stream caused the decoder to lose synchronization. */ + FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, + /**< An error in the stream caused the decoder to lose synchronization. */ - FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, - /**< The decoder encountered a corrupted frame header. */ + FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, + /**< The decoder encountered a corrupted frame header. */ - FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH, - /**< The frame's data did not match the CRC in the footer. */ + FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH, + /**< The frame's data did not match the CRC in the footer. */ - FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM - /**< The decoder encountered reserved fields in use in the stream. */ + FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM + /**< The decoder encountered reserved fields in use in the stream. */ } FLAC__StreamDecoderErrorStatus; /** Maps a FLAC__StreamDecoderErrorStatus to a C string. - * - * Using a FLAC__StreamDecoderErrorStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ + + Using a FLAC__StreamDecoderErrorStatus as the index to this array + will give the string equivalent. The contents should not be modified. +*/ extern FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[]; /*********************************************************************** - * - * class FLAC__StreamDecoder - * + + class FLAC__StreamDecoder + ***********************************************************************/ struct FLAC__StreamDecoderProtected; struct FLAC__StreamDecoderPrivate; /** The opaque structure definition for the stream decoder type. - * See the \link flac_stream_decoder stream decoder module \endlink - * for a detailed description. - */ + See the \link flac_stream_decoder stream decoder module \endlink + for a detailed description. +*/ typedef struct { - struct FLAC__StreamDecoderProtected *protected_; /* avoid the C++ keyword 'protected' */ - struct FLAC__StreamDecoderPrivate *private_; /* avoid the C++ keyword 'private' */ + struct FLAC__StreamDecoderProtected *protected_; /* avoid the C++ keyword 'protected' */ + struct FLAC__StreamDecoderPrivate *private_; /* avoid the C++ keyword 'private' */ } FLAC__StreamDecoder; /** Signature for the read callback. - * - * A function pointer matching this signature must be passed to - * FLAC__stream_decoder_init*_stream(). The supplied function will be - * called when the decoder needs more input data. The address of the - * buffer to be filled is supplied, along with the number of bytes the - * buffer can hold. The callback may choose to supply less data and - * modify the byte count but must be careful not to overflow the buffer. - * The callback then returns a status code chosen from - * FLAC__StreamDecoderReadStatus. - * - * Here is an example of a read callback for stdio streams: - * \code - * FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) - * { - * FILE *file = ((MyClientData*)client_data)->file; - * if(*bytes > 0) { + + A function pointer matching this signature must be passed to + FLAC__stream_decoder_init*_stream(). The supplied function will be + called when the decoder needs more input data. The address of the + buffer to be filled is supplied, along with the number of bytes the + buffer can hold. The callback may choose to supply less data and + modify the byte count but must be careful not to overflow the buffer. + The callback then returns a status code chosen from + FLAC__StreamDecoderReadStatus. + + Here is an example of a read callback for stdio streams: + \code + FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) + { + FILE *file = ((MyClientData*)client_data)->file; + if(*bytes > 0) { * *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, file); - * if(ferror(file)) - * return FLAC__STREAM_DECODER_READ_STATUS_ABORT; - * else if(*bytes == 0) - * return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; - * else - * return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; - * } - * else - * return FLAC__STREAM_DECODER_READ_STATUS_ABORT; - * } - * \endcode - * - * \note In general, FLAC__StreamDecoder functions which change the - * state should not be called on the \a decoder while in the callback. - * - * \param decoder The decoder instance calling the callback. - * \param buffer A pointer to a location for the callee to store - * data to be decoded. - * \param bytes A pointer to the size of the buffer. On entry - * to the callback, it contains the maximum number - * of bytes that may be stored in \a buffer. The - * callee must set it to the actual number of bytes - * stored (0 in case of error or end-of-stream) before - * returning. - * \param client_data The callee's client data set through - * FLAC__stream_decoder_init_*(). - * \retval FLAC__StreamDecoderReadStatus - * The callee's return status. Note that the callback should return - * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM if and only if - * zero bytes were read and there is no more data to be read. - */ -typedef FLAC__StreamDecoderReadStatus (*FLAC__StreamDecoderReadCallback)(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); + if(ferror(file)) + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + else if(*bytes == 0) + return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; + else + return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + } + else + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + } + \endcode + + \note In general, FLAC__StreamDecoder functions which change the + state should not be called on the \a decoder while in the callback. + + \param decoder The decoder instance calling the callback. + \param buffer A pointer to a location for the callee to store + data to be decoded. + \param bytes A pointer to the size of the buffer. On entry + to the callback, it contains the maximum number + of bytes that may be stored in \a buffer. The + callee must set it to the actual number of bytes + stored (0 in case of error or end-of-stream) before + returning. + \param client_data The callee's client data set through + FLAC__stream_decoder_init_*(). + \retval FLAC__StreamDecoderReadStatus + The callee's return status. Note that the callback should return + \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM if and only if + zero bytes were read and there is no more data to be read. +*/ +typedef FLAC__StreamDecoderReadStatus(*FLAC__StreamDecoderReadCallback)(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); /** Signature for the seek callback. - * - * A function pointer matching this signature may be passed to - * FLAC__stream_decoder_init*_stream(). The supplied function will be - * called when the decoder needs to seek the input stream. The decoder - * will pass the absolute byte offset to seek to, 0 meaning the - * beginning of the stream. - * - * Here is an example of a seek callback for stdio streams: - * \code - * FLAC__StreamDecoderSeekStatus seek_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) - * { - * FILE *file = ((MyClientData*)client_data)->file; - * if(file == stdin) - * return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; - * else if(fseeko(file, (off_t)absolute_byte_offset, SEEK_SET) < 0) - * return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; - * else - * return FLAC__STREAM_DECODER_SEEK_STATUS_OK; - * } - * \endcode - * - * \note In general, FLAC__StreamDecoder functions which change the - * state should not be called on the \a decoder while in the callback. - * - * \param decoder The decoder instance calling the callback. - * \param absolute_byte_offset The offset from the beginning of the stream - * to seek to. - * \param client_data The callee's client data set through - * FLAC__stream_decoder_init_*(). - * \retval FLAC__StreamDecoderSeekStatus - * The callee's return status. - */ -typedef FLAC__StreamDecoderSeekStatus (*FLAC__StreamDecoderSeekCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data); + + A function pointer matching this signature may be passed to + FLAC__stream_decoder_init*_stream(). The supplied function will be + called when the decoder needs to seek the input stream. The decoder + will pass the absolute byte offset to seek to, 0 meaning the + beginning of the stream. + + Here is an example of a seek callback for stdio streams: + \code + FLAC__StreamDecoderSeekStatus seek_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) + { + FILE *file = ((MyClientData*)client_data)->file; + if(file == stdin) + return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; + else if(fseeko(file, (off_t)absolute_byte_offset, SEEK_SET) < 0) + return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; + else + return FLAC__STREAM_DECODER_SEEK_STATUS_OK; + } + \endcode + + \note In general, FLAC__StreamDecoder functions which change the + state should not be called on the \a decoder while in the callback. + + \param decoder The decoder instance calling the callback. + \param absolute_byte_offset The offset from the beginning of the stream + to seek to. + \param client_data The callee's client data set through + FLAC__stream_decoder_init_*(). + \retval FLAC__StreamDecoderSeekStatus + The callee's return status. +*/ +typedef FLAC__StreamDecoderSeekStatus(*FLAC__StreamDecoderSeekCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data); /** Signature for the tell callback. - * - * A function pointer matching this signature may be passed to - * FLAC__stream_decoder_init*_stream(). The supplied function will be - * called when the decoder wants to know the current position of the - * stream. The callback should return the byte offset from the - * beginning of the stream. - * - * Here is an example of a tell callback for stdio streams: - * \code - * FLAC__StreamDecoderTellStatus tell_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) - * { - * FILE *file = ((MyClientData*)client_data)->file; - * off_t pos; - * if(file == stdin) - * return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED; - * else if((pos = ftello(file)) < 0) - * return FLAC__STREAM_DECODER_TELL_STATUS_ERROR; - * else { + + A function pointer matching this signature may be passed to + FLAC__stream_decoder_init*_stream(). The supplied function will be + called when the decoder wants to know the current position of the + stream. The callback should return the byte offset from the + beginning of the stream. + + Here is an example of a tell callback for stdio streams: + \code + FLAC__StreamDecoderTellStatus tell_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) + { + FILE *file = ((MyClientData*)client_data)->file; + off_t pos; + if(file == stdin) + return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED; + else if((pos = ftello(file)) < 0) + return FLAC__STREAM_DECODER_TELL_STATUS_ERROR; + else { * *absolute_byte_offset = (FLAC__uint64)pos; - * return FLAC__STREAM_DECODER_TELL_STATUS_OK; - * } - * } - * \endcode - * - * \note In general, FLAC__StreamDecoder functions which change the - * state should not be called on the \a decoder while in the callback. - * - * \param decoder The decoder instance calling the callback. - * \param absolute_byte_offset A pointer to storage for the current offset - * from the beginning of the stream. - * \param client_data The callee's client data set through - * FLAC__stream_decoder_init_*(). - * \retval FLAC__StreamDecoderTellStatus - * The callee's return status. - */ -typedef FLAC__StreamDecoderTellStatus (*FLAC__StreamDecoderTellCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); + return FLAC__STREAM_DECODER_TELL_STATUS_OK; + } + } + \endcode + + \note In general, FLAC__StreamDecoder functions which change the + state should not be called on the \a decoder while in the callback. + + \param decoder The decoder instance calling the callback. + \param absolute_byte_offset A pointer to storage for the current offset + from the beginning of the stream. + \param client_data The callee's client data set through + FLAC__stream_decoder_init_*(). + \retval FLAC__StreamDecoderTellStatus + The callee's return status. +*/ +typedef FLAC__StreamDecoderTellStatus(*FLAC__StreamDecoderTellCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); /** Signature for the length callback. - * - * A function pointer matching this signature may be passed to - * FLAC__stream_decoder_init*_stream(). The supplied function will be - * called when the decoder wants to know the total length of the stream - * in bytes. - * - * Here is an example of a length callback for stdio streams: - * \code - * FLAC__StreamDecoderLengthStatus length_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) - * { - * FILE *file = ((MyClientData*)client_data)->file; - * struct stat filestats; - * - * if(file == stdin) - * return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED; - * else if(fstat(fileno(file), &filestats) != 0) - * return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR; - * else { + + A function pointer matching this signature may be passed to + FLAC__stream_decoder_init*_stream(). The supplied function will be + called when the decoder wants to know the total length of the stream + in bytes. + + Here is an example of a length callback for stdio streams: + \code + FLAC__StreamDecoderLengthStatus length_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) + { + FILE *file = ((MyClientData*)client_data)->file; + struct stat filestats; + + if(file == stdin) + return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED; + else if(fstat(fileno(file), &filestats) != 0) + return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR; + else { * *stream_length = (FLAC__uint64)filestats.st_size; - * return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; - * } - * } - * \endcode - * - * \note In general, FLAC__StreamDecoder functions which change the - * state should not be called on the \a decoder while in the callback. - * - * \param decoder The decoder instance calling the callback. - * \param stream_length A pointer to storage for the length of the stream - * in bytes. - * \param client_data The callee's client data set through - * FLAC__stream_decoder_init_*(). - * \retval FLAC__StreamDecoderLengthStatus - * The callee's return status. - */ -typedef FLAC__StreamDecoderLengthStatus (*FLAC__StreamDecoderLengthCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); + return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; + } + } + \endcode + + \note In general, FLAC__StreamDecoder functions which change the + state should not be called on the \a decoder while in the callback. + + \param decoder The decoder instance calling the callback. + \param stream_length A pointer to storage for the length of the stream + in bytes. + \param client_data The callee's client data set through + FLAC__stream_decoder_init_*(). + \retval FLAC__StreamDecoderLengthStatus + The callee's return status. +*/ +typedef FLAC__StreamDecoderLengthStatus(*FLAC__StreamDecoderLengthCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); /** Signature for the EOF callback. - * - * A function pointer matching this signature may be passed to - * FLAC__stream_decoder_init*_stream(). The supplied function will be - * called when the decoder needs to know if the end of the stream has - * been reached. - * - * Here is an example of a EOF callback for stdio streams: - * FLAC__bool eof_cb(const FLAC__StreamDecoder *decoder, void *client_data) - * \code - * { - * FILE *file = ((MyClientData*)client_data)->file; - * return feof(file)? true : false; - * } - * \endcode - * - * \note In general, FLAC__StreamDecoder functions which change the - * state should not be called on the \a decoder while in the callback. - * - * \param decoder The decoder instance calling the callback. - * \param client_data The callee's client data set through - * FLAC__stream_decoder_init_*(). - * \retval FLAC__bool - * \c true if the currently at the end of the stream, else \c false. - */ -typedef FLAC__bool (*FLAC__StreamDecoderEofCallback)(const FLAC__StreamDecoder *decoder, void *client_data); + + A function pointer matching this signature may be passed to + FLAC__stream_decoder_init*_stream(). The supplied function will be + called when the decoder needs to know if the end of the stream has + been reached. + + Here is an example of a EOF callback for stdio streams: + FLAC__bool eof_cb(const FLAC__StreamDecoder *decoder, void *client_data) + \code + { + FILE *file = ((MyClientData*)client_data)->file; + return feof(file)? true : false; + } + \endcode + + \note In general, FLAC__StreamDecoder functions which change the + state should not be called on the \a decoder while in the callback. + + \param decoder The decoder instance calling the callback. + \param client_data The callee's client data set through + FLAC__stream_decoder_init_*(). + \retval FLAC__bool + \c true if the currently at the end of the stream, else \c false. +*/ +typedef FLAC__bool(*FLAC__StreamDecoderEofCallback)(const FLAC__StreamDecoder *decoder, void *client_data); /** Signature for the write callback. - * - * A function pointer matching this signature must be passed to one of - * the FLAC__stream_decoder_init_*() functions. - * The supplied function will be called when the decoder has decoded a - * single audio frame. The decoder will pass the frame metadata as well - * as an array of pointers (one for each channel) pointing to the - * decoded audio. - * - * \note In general, FLAC__StreamDecoder functions which change the - * state should not be called on the \a decoder while in the callback. - * - * \param decoder The decoder instance calling the callback. - * \param frame The description of the decoded frame. See - * FLAC__Frame. - * \param buffer An array of pointers to decoded channels of data. - * Each pointer will point to an array of signed - * samples of length \a frame->header.blocksize. - * Channels will be ordered according to the FLAC - * specification; see the documentation for the - * frame header. - * \param client_data The callee's client data set through - * FLAC__stream_decoder_init_*(). - * \retval FLAC__StreamDecoderWriteStatus - * The callee's return status. - */ -typedef FLAC__StreamDecoderWriteStatus (*FLAC__StreamDecoderWriteCallback)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); + + A function pointer matching this signature must be passed to one of + the FLAC__stream_decoder_init_*() functions. + The supplied function will be called when the decoder has decoded a + single audio frame. The decoder will pass the frame metadata as well + as an array of pointers (one for each channel) pointing to the + decoded audio. + + \note In general, FLAC__StreamDecoder functions which change the + state should not be called on the \a decoder while in the callback. + + \param decoder The decoder instance calling the callback. + \param frame The description of the decoded frame. See + FLAC__Frame. + \param buffer An array of pointers to decoded channels of data. + Each pointer will point to an array of signed + samples of length \a frame->header.blocksize. + Channels will be ordered according to the FLAC + specification; see the documentation for the + frame header. + \param client_data The callee's client data set through + FLAC__stream_decoder_init_*(). + \retval FLAC__StreamDecoderWriteStatus + The callee's return status. +*/ +typedef FLAC__StreamDecoderWriteStatus(*FLAC__StreamDecoderWriteCallback)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); /** Signature for the metadata callback. - * - * A function pointer matching this signature must be passed to one of - * the FLAC__stream_decoder_init_*() functions. - * The supplied function will be called when the decoder has decoded a - * metadata block. In a valid FLAC file there will always be one - * \c STREAMINFO block, followed by zero or more other metadata blocks. - * These will be supplied by the decoder in the same order as they - * appear in the stream and always before the first audio frame (i.e. - * write callback). The metadata block that is passed in must not be - * modified, and it doesn't live beyond the callback, so you should make - * a copy of it with FLAC__metadata_object_clone() if you will need it - * elsewhere. Since metadata blocks can potentially be large, by - * default the decoder only calls the metadata callback for the - * \c STREAMINFO block; you can instruct the decoder to pass or filter - * other blocks with FLAC__stream_decoder_set_metadata_*() calls. - * - * \note In general, FLAC__StreamDecoder functions which change the - * state should not be called on the \a decoder while in the callback. - * - * \param decoder The decoder instance calling the callback. - * \param metadata The decoded metadata block. - * \param client_data The callee's client data set through - * FLAC__stream_decoder_init_*(). - */ + + A function pointer matching this signature must be passed to one of + the FLAC__stream_decoder_init_*() functions. + The supplied function will be called when the decoder has decoded a + metadata block. In a valid FLAC file there will always be one + \c STREAMINFO block, followed by zero or more other metadata blocks. + These will be supplied by the decoder in the same order as they + appear in the stream and always before the first audio frame (i.e. + write callback). The metadata block that is passed in must not be + modified, and it doesn't live beyond the callback, so you should make + a copy of it with FLAC__metadata_object_clone() if you will need it + elsewhere. Since metadata blocks can potentially be large, by + default the decoder only calls the metadata callback for the + \c STREAMINFO block; you can instruct the decoder to pass or filter + other blocks with FLAC__stream_decoder_set_metadata_*() calls. + + \note In general, FLAC__StreamDecoder functions which change the + state should not be called on the \a decoder while in the callback. + + \param decoder The decoder instance calling the callback. + \param metadata The decoded metadata block. + \param client_data The callee's client data set through + FLAC__stream_decoder_init_*(). +*/ typedef void (*FLAC__StreamDecoderMetadataCallback)(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); /** Signature for the error callback. - * - * A function pointer matching this signature must be passed to one of - * the FLAC__stream_decoder_init_*() functions. - * The supplied function will be called whenever an error occurs during - * decoding. - * - * \note In general, FLAC__StreamDecoder functions which change the - * state should not be called on the \a decoder while in the callback. - * - * \param decoder The decoder instance calling the callback. - * \param status The error encountered by the decoder. - * \param client_data The callee's client data set through - * FLAC__stream_decoder_init_*(). - */ + + A function pointer matching this signature must be passed to one of + the FLAC__stream_decoder_init_*() functions. + The supplied function will be called whenever an error occurs during + decoding. + + \note In general, FLAC__StreamDecoder functions which change the + state should not be called on the \a decoder while in the callback. + + \param decoder The decoder instance calling the callback. + \param status The error encountered by the decoder. + \param client_data The callee's client data set through + FLAC__stream_decoder_init_*(). +*/ typedef void (*FLAC__StreamDecoderErrorCallback)(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); /*********************************************************************** - * - * Class constructor/destructor - * + + Class constructor/destructor + ***********************************************************************/ /** Create a new stream decoder instance. The instance is created with - * default settings; see the individual FLAC__stream_decoder_set_*() - * functions for each setting's default. - * - * \retval FLAC__StreamDecoder* - * \c NULL if there was an error allocating memory, else the new instance. - */ + default settings; see the individual FLAC__stream_decoder_set_*() + functions for each setting's default. + + \retval FLAC__StreamDecoder + \c NULL if there was an error allocating memory, else the new instance. +*/ FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void); /** Free a decoder instance. Deletes the object pointed to by \a decoder. - * - * \param decoder A pointer to an existing decoder. - * \assert - * \code decoder != NULL \endcode - */ + + \param decoder A pointer to an existing decoder. + \assert + \code decoder != NULL \endcode +*/ FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder); /*********************************************************************** - * - * Public class method prototypes - * + + Public class method prototypes + ***********************************************************************/ /** Set the serial number for the FLAC stream within the Ogg container. - * The default behavior is to use the serial number of the first Ogg - * page. Setting a serial number here will explicitly specify which - * stream is to be decoded. - * - * \note - * This does not need to be set for native FLAC decoding. - * - * \default \c use serial number of first page - * \param decoder A decoder instance to set. - * \param serial_number See above. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if the decoder is already initialized, else \c true. - */ + The default behavior is to use the serial number of the first Ogg + page. Setting a serial number here will explicitly specify which + stream is to be decoded. + + \note + This does not need to be set for native FLAC decoding. + + \default \c use serial number of first page + \param decoder A decoder instance to set. + \param serial_number See above. + \assert + \code decoder != NULL \endcode + \retval FLAC__bool + \c false if the decoder is already initialized, else \c true. +*/ FLAC_API FLAC__bool FLAC__stream_decoder_set_ogg_serial_number(FLAC__StreamDecoder *decoder, long serial_number); /** Set the "MD5 signature checking" flag. If \c true, the decoder will - * compute the MD5 signature of the unencoded audio data while decoding - * and compare it to the signature from the STREAMINFO block, if it - * exists, during FLAC__stream_decoder_finish(). - * - * MD5 signature checking will be turned off (until the next - * FLAC__stream_decoder_reset()) if there is no signature in the - * STREAMINFO block or when a seek is attempted. - * - * Clients that do not use the MD5 check should leave this off to speed - * up decoding. - * - * \default \c false - * \param decoder A decoder instance to set. - * \param value Flag value (see above). - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if the decoder is already initialized, else \c true. - */ + compute the MD5 signature of the unencoded audio data while decoding + and compare it to the signature from the STREAMINFO block, if it + exists, during FLAC__stream_decoder_finish(). + + MD5 signature checking will be turned off (until the next + FLAC__stream_decoder_reset()) if there is no signature in the + STREAMINFO block or when a seek is attempted. + + Clients that do not use the MD5 check should leave this off to speed + up decoding. + + \default \c false + \param decoder A decoder instance to set. + \param value Flag value (see above). + \assert + \code decoder != NULL \endcode + \retval FLAC__bool + \c false if the decoder is already initialized, else \c true. +*/ FLAC_API FLAC__bool FLAC__stream_decoder_set_md5_checking(FLAC__StreamDecoder *decoder, FLAC__bool value); /** Direct the decoder to pass on all metadata blocks of type \a type. - * - * \default By default, only the \c STREAMINFO block is returned via the - * metadata callback. - * \param decoder A decoder instance to set. - * \param type See above. - * \assert - * \code decoder != NULL \endcode - * \a type is valid - * \retval FLAC__bool - * \c false if the decoder is already initialized, else \c true. - */ + + \default By default, only the \c STREAMINFO block is returned via the + metadata callback. + \param decoder A decoder instance to set. + \param type See above. + \assert + \code decoder != NULL \endcode + \a type is valid + \retval FLAC__bool + \c false if the decoder is already initialized, else \c true. +*/ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type); /** Direct the decoder to pass on all APPLICATION metadata blocks of the - * given \a id. - * - * \default By default, only the \c STREAMINFO block is returned via the - * metadata callback. - * \param decoder A decoder instance to set. - * \param id See above. - * \assert - * \code decoder != NULL \endcode - * \code id != NULL \endcode - * \retval FLAC__bool - * \c false if the decoder is already initialized, else \c true. - */ + given \a id. + + \default By default, only the \c STREAMINFO block is returned via the + metadata callback. + \param decoder A decoder instance to set. + \param id See above. + \assert + \code decoder != NULL \endcode + \code id != NULL \endcode + \retval FLAC__bool + \c false if the decoder is already initialized, else \c true. +*/ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]); /** Direct the decoder to pass on all metadata blocks of any type. - * - * \default By default, only the \c STREAMINFO block is returned via the - * metadata callback. - * \param decoder A decoder instance to set. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if the decoder is already initialized, else \c true. - */ + + \default By default, only the \c STREAMINFO block is returned via the + metadata callback. + \param decoder A decoder instance to set. + \assert + \code decoder != NULL \endcode + \retval FLAC__bool + \c false if the decoder is already initialized, else \c true. +*/ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder); /** Direct the decoder to filter out all metadata blocks of type \a type. - * - * \default By default, only the \c STREAMINFO block is returned via the - * metadata callback. - * \param decoder A decoder instance to set. - * \param type See above. - * \assert - * \code decoder != NULL \endcode - * \a type is valid - * \retval FLAC__bool - * \c false if the decoder is already initialized, else \c true. - */ + + \default By default, only the \c STREAMINFO block is returned via the + metadata callback. + \param decoder A decoder instance to set. + \param type See above. + \assert + \code decoder != NULL \endcode + \a type is valid + \retval FLAC__bool + \c false if the decoder is already initialized, else \c true. +*/ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type); /** Direct the decoder to filter out all APPLICATION metadata blocks of - * the given \a id. - * - * \default By default, only the \c STREAMINFO block is returned via the - * metadata callback. - * \param decoder A decoder instance to set. - * \param id See above. - * \assert - * \code decoder != NULL \endcode - * \code id != NULL \endcode - * \retval FLAC__bool - * \c false if the decoder is already initialized, else \c true. - */ + the given \a id. + + \default By default, only the \c STREAMINFO block is returned via the + metadata callback. + \param decoder A decoder instance to set. + \param id See above. + \assert + \code decoder != NULL \endcode + \code id != NULL \endcode + \retval FLAC__bool + \c false if the decoder is already initialized, else \c true. +*/ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]); /** Direct the decoder to filter out all metadata blocks of any type. - * - * \default By default, only the \c STREAMINFO block is returned via the - * metadata callback. - * \param decoder A decoder instance to set. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if the decoder is already initialized, else \c true. - */ + + \default By default, only the \c STREAMINFO block is returned via the + metadata callback. + \param decoder A decoder instance to set. + \assert + \code decoder != NULL \endcode + \retval FLAC__bool + \c false if the decoder is already initialized, else \c true. +*/ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder); /** Get the current decoder state. - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__StreamDecoderState - * The current decoder state. - */ + + \param decoder A decoder instance to query. + \assert + \code decoder != NULL \endcode + \retval FLAC__StreamDecoderState + The current decoder state. +*/ FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder); /** Get the current decoder state as a C string. - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval const char * - * The decoder state as a C string. Do not modify the contents. - */ + + \param decoder A decoder instance to query. + \assert + \code decoder != NULL \endcode + \retval const char + The decoder state as a C string. Do not modify the contents. +*/ FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string(const FLAC__StreamDecoder *decoder); /** Get the "MD5 signature checking" flag. - * This is the value of the setting, not whether or not the decoder is - * currently checking the MD5 (remember, it can be turned off automatically - * by a seek). When the decoder is reset the flag will be restored to the - * value returned by this function. - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * See above. - */ + This is the value of the setting, not whether or not the decoder is + currently checking the MD5 (remember, it can be turned off automatically + by a seek). When the decoder is reset the flag will be restored to the + value returned by this function. + + \param decoder A decoder instance to query. + \assert + \code decoder != NULL \endcode + \retval FLAC__bool + See above. +*/ FLAC_API FLAC__bool FLAC__stream_decoder_get_md5_checking(const FLAC__StreamDecoder *decoder); /** Get the total number of samples in the stream being decoded. - * Will only be valid after decoding has started and will contain the - * value from the \c STREAMINFO block. A value of \c 0 means "unknown". - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval uint32_t - * See above. - */ + Will only be valid after decoding has started and will contain the + value from the \c STREAMINFO block. A value of \c 0 means "unknown". + + \param decoder A decoder instance to query. + \assert + \code decoder != NULL \endcode + \retval uint32_t + See above. +*/ FLAC_API FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder); /** Get the current number of channels in the stream being decoded. - * Will only be valid after decoding has started and will contain the - * value from the most recently decoded frame header. - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval uint32_t - * See above. - */ + Will only be valid after decoding has started and will contain the + value from the most recently decoded frame header. + + \param decoder A decoder instance to query. + \assert + \code decoder != NULL \endcode + \retval uint32_t + See above. +*/ FLAC_API uint32_t FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder); /** Get the current channel assignment in the stream being decoded. - * Will only be valid after decoding has started and will contain the - * value from the most recently decoded frame header. - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__ChannelAssignment - * See above. - */ + Will only be valid after decoding has started and will contain the + value from the most recently decoded frame header. + + \param decoder A decoder instance to query. + \assert + \code decoder != NULL \endcode + \retval FLAC__ChannelAssignment + See above. +*/ FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder); /** Get the current sample resolution in the stream being decoded. - * Will only be valid after decoding has started and will contain the - * value from the most recently decoded frame header. - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval uint32_t - * See above. - */ + Will only be valid after decoding has started and will contain the + value from the most recently decoded frame header. + + \param decoder A decoder instance to query. + \assert + \code decoder != NULL \endcode + \retval uint32_t + See above. +*/ FLAC_API uint32_t FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder); /** Get the current sample rate in Hz of the stream being decoded. - * Will only be valid after decoding has started and will contain the - * value from the most recently decoded frame header. - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval uint32_t - * See above. - */ + Will only be valid after decoding has started and will contain the + value from the most recently decoded frame header. + + \param decoder A decoder instance to query. + \assert + \code decoder != NULL \endcode + \retval uint32_t + See above. +*/ FLAC_API uint32_t FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder); /** Get the current blocksize of the stream being decoded. - * Will only be valid after decoding has started and will contain the - * value from the most recently decoded frame header. - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval uint32_t - * See above. - */ + Will only be valid after decoding has started and will contain the + value from the most recently decoded frame header. + + \param decoder A decoder instance to query. + \assert + \code decoder != NULL \endcode + \retval uint32_t + See above. +*/ FLAC_API uint32_t FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder); /** Returns the decoder's current read position within the stream. - * The position is the byte offset from the start of the stream. - * Bytes before this position have been fully decoded. Note that - * there may still be undecoded bytes in the decoder's read FIFO. - * The returned position is correct even after a seek. - * - * \warning This function currently only works for native FLAC, - * not Ogg FLAC streams. - * - * \param decoder A decoder instance to query. - * \param position Address at which to return the desired position. - * \assert - * \code decoder != NULL \endcode - * \code position != NULL \endcode - * \retval FLAC__bool - * \c true if successful, \c false if the stream is not native FLAC, - * or there was an error from the 'tell' callback or it returned - * \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED. - */ + The position is the byte offset from the start of the stream. + Bytes before this position have been fully decoded. Note that + there may still be undecoded bytes in the decoder's read FIFO. + The returned position is correct even after a seek. + + \warning This function currently only works for native FLAC, + not Ogg FLAC streams. + + \param decoder A decoder instance to query. + \param position Address at which to return the desired position. + \assert + \code decoder != NULL \endcode + \code position != NULL \endcode + \retval FLAC__bool + \c true if successful, \c false if the stream is not native FLAC, + or there was an error from the 'tell' callback or it returned + \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED. +*/ FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamDecoder *decoder, FLAC__uint64 *position); /** Initialize the decoder instance to decode native FLAC streams. - * - * This flavor of initialization sets up the decoder to decode from a - * native FLAC stream. I/O is performed via callbacks to the client. - * For decoding from a plain file via filename or open FILE*, - * FLAC__stream_decoder_init_file() and FLAC__stream_decoder_init_FILE() - * provide a simpler interface. - * - * This function should be called after FLAC__stream_decoder_new() and - * FLAC__stream_decoder_set_*() but before any of the - * FLAC__stream_decoder_process_*() functions. Will set and return the - * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA - * if initialization succeeded. - * - * \param decoder An uninitialized decoder instance. - * \param read_callback See FLAC__StreamDecoderReadCallback. This - * pointer must not be \c NULL. - * \param seek_callback See FLAC__StreamDecoderSeekCallback. This - * pointer may be \c NULL if seeking is not - * supported. If \a seek_callback is not \c NULL then a - * \a tell_callback, \a length_callback, and \a eof_callback must also be supplied. - * Alternatively, a dummy seek callback that just - * returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param tell_callback See FLAC__StreamDecoderTellCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a tell_callback must also be supplied. - * Alternatively, a dummy tell callback that just - * returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param length_callback See FLAC__StreamDecoderLengthCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a length_callback must also be supplied. - * Alternatively, a dummy length callback that just - * returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param eof_callback See FLAC__StreamDecoderEofCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a eof_callback must also be supplied. - * Alternatively, a dummy length callback that just - * returns \c false - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param write_callback See FLAC__StreamDecoderWriteCallback. This - * pointer must not be \c NULL. - * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This - * pointer may be \c NULL if the callback is not - * desired. - * \param error_callback See FLAC__StreamDecoderErrorCallback. This - * pointer must not be \c NULL. - * \param client_data This value will be supplied to callbacks in their - * \a client_data argument. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__StreamDecoderInitStatus - * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; - * see FLAC__StreamDecoderInitStatus for the meanings of other return values. - */ + + This flavor of initialization sets up the decoder to decode from a + native FLAC stream. I/O is performed via callbacks to the client. + For decoding from a plain file via filename or open FILE*, + FLAC__stream_decoder_init_file() and FLAC__stream_decoder_init_FILE() + provide a simpler interface. + + This function should be called after FLAC__stream_decoder_new() and + FLAC__stream_decoder_set_*() but before any of the + FLAC__stream_decoder_process_*() functions. Will set and return the + decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + if initialization succeeded. + + \param decoder An uninitialized decoder instance. + \param read_callback See FLAC__StreamDecoderReadCallback. This + pointer must not be \c NULL. + \param seek_callback See FLAC__StreamDecoderSeekCallback. This + pointer may be \c NULL if seeking is not + supported. If \a seek_callback is not \c NULL then a + \a tell_callback, \a length_callback, and \a eof_callback must also be supplied. + Alternatively, a dummy seek callback that just + returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED + may also be supplied, all though this is slightly + less efficient for the decoder. + \param tell_callback See FLAC__StreamDecoderTellCallback. This + pointer may be \c NULL if not supported by the client. If + \a seek_callback is not \c NULL then a + \a tell_callback must also be supplied. + Alternatively, a dummy tell callback that just + returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED + may also be supplied, all though this is slightly + less efficient for the decoder. + \param length_callback See FLAC__StreamDecoderLengthCallback. This + pointer may be \c NULL if not supported by the client. If + \a seek_callback is not \c NULL then a + \a length_callback must also be supplied. + Alternatively, a dummy length callback that just + returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED + may also be supplied, all though this is slightly + less efficient for the decoder. + \param eof_callback See FLAC__StreamDecoderEofCallback. This + pointer may be \c NULL if not supported by the client. If + \a seek_callback is not \c NULL then a + \a eof_callback must also be supplied. + Alternatively, a dummy length callback that just + returns \c false + may also be supplied, all though this is slightly + less efficient for the decoder. + \param write_callback See FLAC__StreamDecoderWriteCallback. This + pointer must not be \c NULL. + \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + pointer may be \c NULL if the callback is not + desired. + \param error_callback See FLAC__StreamDecoderErrorCallback. This + pointer must not be \c NULL. + \param client_data This value will be supplied to callbacks in their + \a client_data argument. + \assert + \code decoder != NULL \endcode + \retval FLAC__StreamDecoderInitStatus + \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + see FLAC__StreamDecoderInitStatus for the meanings of other return values. +*/ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream( - FLAC__StreamDecoder *decoder, - FLAC__StreamDecoderReadCallback read_callback, - FLAC__StreamDecoderSeekCallback seek_callback, - FLAC__StreamDecoderTellCallback tell_callback, - FLAC__StreamDecoderLengthCallback length_callback, - FLAC__StreamDecoderEofCallback eof_callback, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data + FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderReadCallback read_callback, + FLAC__StreamDecoderSeekCallback seek_callback, + FLAC__StreamDecoderTellCallback tell_callback, + FLAC__StreamDecoderLengthCallback length_callback, + FLAC__StreamDecoderEofCallback eof_callback, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data ); /** Initialize the decoder instance to decode Ogg FLAC streams. - * - * This flavor of initialization sets up the decoder to decode from a - * FLAC stream in an Ogg container. I/O is performed via callbacks to the - * client. For decoding from a plain file via filename or open FILE*, - * FLAC__stream_decoder_init_ogg_file() and FLAC__stream_decoder_init_ogg_FILE() - * provide a simpler interface. - * - * This function should be called after FLAC__stream_decoder_new() and - * FLAC__stream_decoder_set_*() but before any of the - * FLAC__stream_decoder_process_*() functions. Will set and return the - * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA - * if initialization succeeded. - * - * \note Support for Ogg FLAC in the library is optional. If this - * library has been built without support for Ogg FLAC, this function - * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. - * - * \param decoder An uninitialized decoder instance. - * \param read_callback See FLAC__StreamDecoderReadCallback. This - * pointer must not be \c NULL. - * \param seek_callback See FLAC__StreamDecoderSeekCallback. This - * pointer may be \c NULL if seeking is not - * supported. If \a seek_callback is not \c NULL then a - * \a tell_callback, \a length_callback, and \a eof_callback must also be supplied. - * Alternatively, a dummy seek callback that just - * returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param tell_callback See FLAC__StreamDecoderTellCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a tell_callback must also be supplied. - * Alternatively, a dummy tell callback that just - * returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param length_callback See FLAC__StreamDecoderLengthCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a length_callback must also be supplied. - * Alternatively, a dummy length callback that just - * returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param eof_callback See FLAC__StreamDecoderEofCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a eof_callback must also be supplied. - * Alternatively, a dummy length callback that just - * returns \c false - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param write_callback See FLAC__StreamDecoderWriteCallback. This - * pointer must not be \c NULL. - * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This - * pointer may be \c NULL if the callback is not - * desired. - * \param error_callback See FLAC__StreamDecoderErrorCallback. This - * pointer must not be \c NULL. - * \param client_data This value will be supplied to callbacks in their - * \a client_data argument. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__StreamDecoderInitStatus - * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; - * see FLAC__StreamDecoderInitStatus for the meanings of other return values. - */ + + This flavor of initialization sets up the decoder to decode from a + FLAC stream in an Ogg container. I/O is performed via callbacks to the + client. For decoding from a plain file via filename or open FILE*, + FLAC__stream_decoder_init_ogg_file() and FLAC__stream_decoder_init_ogg_FILE() + provide a simpler interface. + + This function should be called after FLAC__stream_decoder_new() and + FLAC__stream_decoder_set_*() but before any of the + FLAC__stream_decoder_process_*() functions. Will set and return the + decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + if initialization succeeded. + + \note Support for Ogg FLAC in the library is optional. If this + library has been built without support for Ogg FLAC, this function + will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. + + \param decoder An uninitialized decoder instance. + \param read_callback See FLAC__StreamDecoderReadCallback. This + pointer must not be \c NULL. + \param seek_callback See FLAC__StreamDecoderSeekCallback. This + pointer may be \c NULL if seeking is not + supported. If \a seek_callback is not \c NULL then a + \a tell_callback, \a length_callback, and \a eof_callback must also be supplied. + Alternatively, a dummy seek callback that just + returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED + may also be supplied, all though this is slightly + less efficient for the decoder. + \param tell_callback See FLAC__StreamDecoderTellCallback. This + pointer may be \c NULL if not supported by the client. If + \a seek_callback is not \c NULL then a + \a tell_callback must also be supplied. + Alternatively, a dummy tell callback that just + returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED + may also be supplied, all though this is slightly + less efficient for the decoder. + \param length_callback See FLAC__StreamDecoderLengthCallback. This + pointer may be \c NULL if not supported by the client. If + \a seek_callback is not \c NULL then a + \a length_callback must also be supplied. + Alternatively, a dummy length callback that just + returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED + may also be supplied, all though this is slightly + less efficient for the decoder. + \param eof_callback See FLAC__StreamDecoderEofCallback. This + pointer may be \c NULL if not supported by the client. If + \a seek_callback is not \c NULL then a + \a eof_callback must also be supplied. + Alternatively, a dummy length callback that just + returns \c false + may also be supplied, all though this is slightly + less efficient for the decoder. + \param write_callback See FLAC__StreamDecoderWriteCallback. This + pointer must not be \c NULL. + \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + pointer may be \c NULL if the callback is not + desired. + \param error_callback See FLAC__StreamDecoderErrorCallback. This + pointer must not be \c NULL. + \param client_data This value will be supplied to callbacks in their + \a client_data argument. + \assert + \code decoder != NULL \endcode + \retval FLAC__StreamDecoderInitStatus + \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + see FLAC__StreamDecoderInitStatus for the meanings of other return values. +*/ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_stream( - FLAC__StreamDecoder *decoder, - FLAC__StreamDecoderReadCallback read_callback, - FLAC__StreamDecoderSeekCallback seek_callback, - FLAC__StreamDecoderTellCallback tell_callback, - FLAC__StreamDecoderLengthCallback length_callback, - FLAC__StreamDecoderEofCallback eof_callback, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data + FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderReadCallback read_callback, + FLAC__StreamDecoderSeekCallback seek_callback, + FLAC__StreamDecoderTellCallback tell_callback, + FLAC__StreamDecoderLengthCallback length_callback, + FLAC__StreamDecoderEofCallback eof_callback, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data ); /** Initialize the decoder instance to decode native FLAC files. - * - * This flavor of initialization sets up the decoder to decode from a - * plain native FLAC file. For non-stdio streams, you must use - * FLAC__stream_decoder_init_stream() and provide callbacks for the I/O. - * - * This function should be called after FLAC__stream_decoder_new() and - * FLAC__stream_decoder_set_*() but before any of the - * FLAC__stream_decoder_process_*() functions. Will set and return the - * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA - * if initialization succeeded. - * - * \param decoder An uninitialized decoder instance. - * \param file An open FLAC file. The file should have been - * opened with mode \c "rb" and rewound. The file - * becomes owned by the decoder and should not be - * manipulated by the client while decoding. - * Unless \a file is \c stdin, it will be closed - * when FLAC__stream_decoder_finish() is called. - * Note however that seeking will not work when - * decoding from \c stdin since it is not seekable. - * \param write_callback See FLAC__StreamDecoderWriteCallback. This - * pointer must not be \c NULL. - * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This - * pointer may be \c NULL if the callback is not - * desired. - * \param error_callback See FLAC__StreamDecoderErrorCallback. This - * pointer must not be \c NULL. - * \param client_data This value will be supplied to callbacks in their - * \a client_data argument. - * \assert - * \code decoder != NULL \endcode - * \code file != NULL \endcode - * \retval FLAC__StreamDecoderInitStatus - * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; - * see FLAC__StreamDecoderInitStatus for the meanings of other return values. - */ + + This flavor of initialization sets up the decoder to decode from a + plain native FLAC file. For non-stdio streams, you must use + FLAC__stream_decoder_init_stream() and provide callbacks for the I/O. + + This function should be called after FLAC__stream_decoder_new() and + FLAC__stream_decoder_set_*() but before any of the + FLAC__stream_decoder_process_*() functions. Will set and return the + decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + if initialization succeeded. + + \param decoder An uninitialized decoder instance. + \param file An open FLAC file. The file should have been + opened with mode \c "rb" and rewound. The file + becomes owned by the decoder and should not be + manipulated by the client while decoding. + Unless \a file is \c stdin, it will be closed + when FLAC__stream_decoder_finish() is called. + Note however that seeking will not work when + decoding from \c stdin since it is not seekable. + \param write_callback See FLAC__StreamDecoderWriteCallback. This + pointer must not be \c NULL. + \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + pointer may be \c NULL if the callback is not + desired. + \param error_callback See FLAC__StreamDecoderErrorCallback. This + pointer must not be \c NULL. + \param client_data This value will be supplied to callbacks in their + \a client_data argument. + \assert + \code decoder != NULL \endcode + \code file != NULL \endcode + \retval FLAC__StreamDecoderInitStatus + \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + see FLAC__StreamDecoderInitStatus for the meanings of other return values. +*/ #if 0 FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_FILE( - FLAC__StreamDecoder *decoder, - FILE *file, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data + FLAC__StreamDecoder *decoder, + FILE *file, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data ); #endif /** Initialize the decoder instance to decode Ogg FLAC files. - * - * This flavor of initialization sets up the decoder to decode from a - * plain Ogg FLAC file. For non-stdio streams, you must use - * FLAC__stream_decoder_init_ogg_stream() and provide callbacks for the I/O. - * - * This function should be called after FLAC__stream_decoder_new() and - * FLAC__stream_decoder_set_*() but before any of the - * FLAC__stream_decoder_process_*() functions. Will set and return the - * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA - * if initialization succeeded. - * - * \note Support for Ogg FLAC in the library is optional. If this - * library has been built without support for Ogg FLAC, this function - * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. - * - * \param decoder An uninitialized decoder instance. - * \param file An open FLAC file. The file should have been - * opened with mode \c "rb" and rewound. The file - * becomes owned by the decoder and should not be - * manipulated by the client while decoding. - * Unless \a file is \c stdin, it will be closed - * when FLAC__stream_decoder_finish() is called. - * Note however that seeking will not work when - * decoding from \c stdin since it is not seekable. - * \param write_callback See FLAC__StreamDecoderWriteCallback. This - * pointer must not be \c NULL. - * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This - * pointer may be \c NULL if the callback is not - * desired. - * \param error_callback See FLAC__StreamDecoderErrorCallback. This - * pointer must not be \c NULL. - * \param client_data This value will be supplied to callbacks in their - * \a client_data argument. - * \assert - * \code decoder != NULL \endcode - * \code file != NULL \endcode - * \retval FLAC__StreamDecoderInitStatus - * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; - * see FLAC__StreamDecoderInitStatus for the meanings of other return values. - */ + + This flavor of initialization sets up the decoder to decode from a + plain Ogg FLAC file. For non-stdio streams, you must use + FLAC__stream_decoder_init_ogg_stream() and provide callbacks for the I/O. + + This function should be called after FLAC__stream_decoder_new() and + FLAC__stream_decoder_set_*() but before any of the + FLAC__stream_decoder_process_*() functions. Will set and return the + decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + if initialization succeeded. + + \note Support for Ogg FLAC in the library is optional. If this + library has been built without support for Ogg FLAC, this function + will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. + + \param decoder An uninitialized decoder instance. + \param file An open FLAC file. The file should have been + opened with mode \c "rb" and rewound. The file + becomes owned by the decoder and should not be + manipulated by the client while decoding. + Unless \a file is \c stdin, it will be closed + when FLAC__stream_decoder_finish() is called. + Note however that seeking will not work when + decoding from \c stdin since it is not seekable. + \param write_callback See FLAC__StreamDecoderWriteCallback. This + pointer must not be \c NULL. + \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + pointer may be \c NULL if the callback is not + desired. + \param error_callback See FLAC__StreamDecoderErrorCallback. This + pointer must not be \c NULL. + \param client_data This value will be supplied to callbacks in their + \a client_data argument. + \assert + \code decoder != NULL \endcode + \code file != NULL \endcode + \retval FLAC__StreamDecoderInitStatus + \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + see FLAC__StreamDecoderInitStatus for the meanings of other return values. +*/ #if 0 FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_FILE( - FLAC__StreamDecoder *decoder, - FILE *file, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data + FLAC__StreamDecoder *decoder, + FILE *file, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data ); #endif /** Initialize the decoder instance to decode native FLAC files. - * - * This flavor of initialization sets up the decoder to decode from a plain - * native FLAC file. If POSIX fopen() semantics are not sufficient, (for - * example, with Unicode filenames on Windows), you must use - * FLAC__stream_decoder_init_FILE(), or FLAC__stream_decoder_init_stream() - * and provide callbacks for the I/O. - * - * This function should be called after FLAC__stream_decoder_new() and - * FLAC__stream_decoder_set_*() but before any of the - * FLAC__stream_decoder_process_*() functions. Will set and return the - * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA - * if initialization succeeded. - * - * \param decoder An uninitialized decoder instance. - * \param filename The name of the file to decode from. The file will - * be opened with fopen(). Use \c NULL to decode from - * \c stdin. Note that \c stdin is not seekable. - * \param write_callback See FLAC__StreamDecoderWriteCallback. This - * pointer must not be \c NULL. - * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This - * pointer may be \c NULL if the callback is not - * desired. - * \param error_callback See FLAC__StreamDecoderErrorCallback. This - * pointer must not be \c NULL. - * \param client_data This value will be supplied to callbacks in their - * \a client_data argument. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__StreamDecoderInitStatus - * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; - * see FLAC__StreamDecoderInitStatus for the meanings of other return values. - */ + + This flavor of initialization sets up the decoder to decode from a plain + native FLAC file. If POSIX fopen() semantics are not sufficient, (for + example, with Unicode filenames on Windows), you must use + FLAC__stream_decoder_init_FILE(), or FLAC__stream_decoder_init_stream() + and provide callbacks for the I/O. + + This function should be called after FLAC__stream_decoder_new() and + FLAC__stream_decoder_set_*() but before any of the + FLAC__stream_decoder_process_*() functions. Will set and return the + decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + if initialization succeeded. + + \param decoder An uninitialized decoder instance. + \param filename The name of the file to decode from. The file will + be opened with fopen(). Use \c NULL to decode from + \c stdin. Note that \c stdin is not seekable. + \param write_callback See FLAC__StreamDecoderWriteCallback. This + pointer must not be \c NULL. + \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + pointer may be \c NULL if the callback is not + desired. + \param error_callback See FLAC__StreamDecoderErrorCallback. This + pointer must not be \c NULL. + \param client_data This value will be supplied to callbacks in their + \a client_data argument. + \assert + \code decoder != NULL \endcode + \retval FLAC__StreamDecoderInitStatus + \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + see FLAC__StreamDecoderInitStatus for the meanings of other return values. +*/ #if 0 FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file( - FLAC__StreamDecoder *decoder, - const char *filename, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data + FLAC__StreamDecoder *decoder, + const char *filename, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data ); #endif /** Initialize the decoder instance to decode Ogg FLAC files. - * - * This flavor of initialization sets up the decoder to decode from a plain - * Ogg FLAC file. If POSIX fopen() semantics are not sufficient, (for - * example, with Unicode filenames on Windows), you must use - * FLAC__stream_decoder_init_ogg_FILE(), or FLAC__stream_decoder_init_ogg_stream() - * and provide callbacks for the I/O. - * - * This function should be called after FLAC__stream_decoder_new() and - * FLAC__stream_decoder_set_*() but before any of the - * FLAC__stream_decoder_process_*() functions. Will set and return the - * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA - * if initialization succeeded. - * - * \note Support for Ogg FLAC in the library is optional. If this - * library has been built without support for Ogg FLAC, this function - * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. - * - * \param decoder An uninitialized decoder instance. - * \param filename The name of the file to decode from. The file will - * be opened with fopen(). Use \c NULL to decode from - * \c stdin. Note that \c stdin is not seekable. - * \param write_callback See FLAC__StreamDecoderWriteCallback. This - * pointer must not be \c NULL. - * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This - * pointer may be \c NULL if the callback is not - * desired. - * \param error_callback See FLAC__StreamDecoderErrorCallback. This - * pointer must not be \c NULL. - * \param client_data This value will be supplied to callbacks in their - * \a client_data argument. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__StreamDecoderInitStatus - * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; - * see FLAC__StreamDecoderInitStatus for the meanings of other return values. - */ + + This flavor of initialization sets up the decoder to decode from a plain + Ogg FLAC file. If POSIX fopen() semantics are not sufficient, (for + example, with Unicode filenames on Windows), you must use + FLAC__stream_decoder_init_ogg_FILE(), or FLAC__stream_decoder_init_ogg_stream() + and provide callbacks for the I/O. + + This function should be called after FLAC__stream_decoder_new() and + FLAC__stream_decoder_set_*() but before any of the + FLAC__stream_decoder_process_*() functions. Will set and return the + decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + if initialization succeeded. + + \note Support for Ogg FLAC in the library is optional. If this + library has been built without support for Ogg FLAC, this function + will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. + + \param decoder An uninitialized decoder instance. + \param filename The name of the file to decode from. The file will + be opened with fopen(). Use \c NULL to decode from + \c stdin. Note that \c stdin is not seekable. + \param write_callback See FLAC__StreamDecoderWriteCallback. This + pointer must not be \c NULL. + \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + pointer may be \c NULL if the callback is not + desired. + \param error_callback See FLAC__StreamDecoderErrorCallback. This + pointer must not be \c NULL. + \param client_data This value will be supplied to callbacks in their + \a client_data argument. + \assert + \code decoder != NULL \endcode + \retval FLAC__StreamDecoderInitStatus + \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + see FLAC__StreamDecoderInitStatus for the meanings of other return values. +*/ #if 0 FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_file( - FLAC__StreamDecoder *decoder, - const char *filename, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data + FLAC__StreamDecoder *decoder, + const char *filename, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data ); #endif /** Finish the decoding process. - * Flushes the decoding buffer, releases resources, resets the decoder - * settings to their defaults, and returns the decoder state to - * FLAC__STREAM_DECODER_UNINITIALIZED. - * - * In the event of a prematurely-terminated decode, it is not strictly - * necessary to call this immediately before FLAC__stream_decoder_delete() - * but it is good practice to match every FLAC__stream_decoder_init_*() - * with a FLAC__stream_decoder_finish(). - * - * \param decoder An uninitialized decoder instance. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if MD5 checking is on AND a STREAMINFO block was available - * AND the MD5 signature in the STREAMINFO block was non-zero AND the - * signature does not match the one computed by the decoder; else - * \c true. - */ + Flushes the decoding buffer, releases resources, resets the decoder + settings to their defaults, and returns the decoder state to + FLAC__STREAM_DECODER_UNINITIALIZED. + + In the event of a prematurely-terminated decode, it is not strictly + necessary to call this immediately before FLAC__stream_decoder_delete() + but it is good practice to match every FLAC__stream_decoder_init_*() + with a FLAC__stream_decoder_finish(). + + \param decoder An uninitialized decoder instance. + \assert + \code decoder != NULL \endcode + \retval FLAC__bool + \c false if MD5 checking is on AND a STREAMINFO block was available + AND the MD5 signature in the STREAMINFO block was non-zero AND the + signature does not match the one computed by the decoder; else + \c true. +*/ FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder); /** Flush the stream input. - * The decoder's input buffer will be cleared and the state set to - * \c FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC. This will also turn - * off MD5 checking. - * - * \param decoder A decoder instance. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c true if successful, else \c false if a memory allocation - * error occurs (in which case the state will be set to - * \c FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR). - */ + The decoder's input buffer will be cleared and the state set to + \c FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC. This will also turn + off MD5 checking. + + \param decoder A decoder instance. + \assert + \code decoder != NULL \endcode + \retval FLAC__bool + \c true if successful, else \c false if a memory allocation + error occurs (in which case the state will be set to + \c FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR). +*/ FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder); /** Reset the decoding process. - * The decoder's input buffer will be cleared and the state set to - * \c FLAC__STREAM_DECODER_SEARCH_FOR_METADATA. This is similar to - * FLAC__stream_decoder_finish() except that the settings are - * preserved; there is no need to call FLAC__stream_decoder_init_*() - * before decoding again. MD5 checking will be restored to its original - * setting. - * - * If the decoder is seekable, or was initialized with - * FLAC__stream_decoder_init*_FILE() or FLAC__stream_decoder_init*_file(), - * the decoder will also attempt to seek to the beginning of the file. - * If this rewind fails, this function will return \c false. It follows - * that FLAC__stream_decoder_reset() cannot be used when decoding from - * \c stdin. - * - * If the decoder was initialized with FLAC__stream_encoder_init*_stream() - * and is not seekable (i.e. no seek callback was provided or the seek - * callback returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED), it - * is the duty of the client to start feeding data from the beginning of - * the stream on the next FLAC__stream_decoder_process_*() call. - * - * \param decoder A decoder instance. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c true if successful, else \c false if a memory allocation occurs - * (in which case the state will be set to - * \c FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR) or a seek error - * occurs (the state will be unchanged). - */ + The decoder's input buffer will be cleared and the state set to + \c FLAC__STREAM_DECODER_SEARCH_FOR_METADATA. This is similar to + FLAC__stream_decoder_finish() except that the settings are + preserved; there is no need to call FLAC__stream_decoder_init_*() + before decoding again. MD5 checking will be restored to its original + setting. + + If the decoder is seekable, or was initialized with + FLAC__stream_decoder_init*_FILE() or FLAC__stream_decoder_init*_file(), + the decoder will also attempt to seek to the beginning of the file. + If this rewind fails, this function will return \c false. It follows + that FLAC__stream_decoder_reset() cannot be used when decoding from + \c stdin. + + If the decoder was initialized with FLAC__stream_encoder_init*_stream() + and is not seekable (i.e. no seek callback was provided or the seek + callback returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED), it + is the duty of the client to start feeding data from the beginning of + the stream on the next FLAC__stream_decoder_process_*() call. + + \param decoder A decoder instance. + \assert + \code decoder != NULL \endcode + \retval FLAC__bool + \c true if successful, else \c false if a memory allocation occurs + (in which case the state will be set to + \c FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR) or a seek error + occurs (the state will be unchanged). +*/ FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder); /** Decode one metadata block or audio frame. - * This version instructs the decoder to decode a either a single metadata - * block or a single frame and stop, unless the callbacks return a fatal - * error or the read callback returns - * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. - * - * As the decoder needs more input it will call the read callback. - * Depending on what was decoded, the metadata or write callback will be - * called with the decoded metadata block or audio frame. - * - * Unless there is a fatal read error or end of stream, this function - * will return once one whole frame is decoded. In other words, if the - * stream is not synchronized or points to a corrupt frame header, the - * decoder will continue to try and resync until it gets to a valid - * frame, then decode one frame, then return. If the decoder points to - * a frame whose frame CRC in the frame footer does not match the - * computed frame CRC, this function will issue a - * FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH error to the - * error callback, and return, having decoded one complete, although - * corrupt, frame. (Such corrupted frames are sent as silence of the - * correct length to the write callback.) - * - * \param decoder An initialized decoder instance. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if any fatal read, write, or memory allocation error - * occurred (meaning decoding must stop), else \c true; for more - * information about the decoder, check the decoder state with - * FLAC__stream_decoder_get_state(). - */ + This version instructs the decoder to decode a either a single metadata + block or a single frame and stop, unless the callbacks return a fatal + error or the read callback returns + \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. + + As the decoder needs more input it will call the read callback. + Depending on what was decoded, the metadata or write callback will be + called with the decoded metadata block or audio frame. + + Unless there is a fatal read error or end of stream, this function + will return once one whole frame is decoded. In other words, if the + stream is not synchronized or points to a corrupt frame header, the + decoder will continue to try and resync until it gets to a valid + frame, then decode one frame, then return. If the decoder points to + a frame whose frame CRC in the frame footer does not match the + computed frame CRC, this function will issue a + FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH error to the + error callback, and return, having decoded one complete, although + corrupt, frame. (Such corrupted frames are sent as silence of the + correct length to the write callback.) + + \param decoder An initialized decoder instance. + \assert + \code decoder != NULL \endcode + \retval FLAC__bool + \c false if any fatal read, write, or memory allocation error + occurred (meaning decoding must stop), else \c true; for more + information about the decoder, check the decoder state with + FLAC__stream_decoder_get_state(). +*/ FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder); /** Decode until the end of the metadata. - * This version instructs the decoder to decode from the current position - * and continue until all the metadata has been read, or until the - * callbacks return a fatal error or the read callback returns - * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. - * - * As the decoder needs more input it will call the read callback. - * As each metadata block is decoded, the metadata callback will be called - * with the decoded metadata. - * - * \param decoder An initialized decoder instance. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if any fatal read, write, or memory allocation error - * occurred (meaning decoding must stop), else \c true; for more - * information about the decoder, check the decoder state with - * FLAC__stream_decoder_get_state(). - */ + This version instructs the decoder to decode from the current position + and continue until all the metadata has been read, or until the + callbacks return a fatal error or the read callback returns + \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. + + As the decoder needs more input it will call the read callback. + As each metadata block is decoded, the metadata callback will be called + with the decoded metadata. + + \param decoder An initialized decoder instance. + \assert + \code decoder != NULL \endcode + \retval FLAC__bool + \c false if any fatal read, write, or memory allocation error + occurred (meaning decoding must stop), else \c true; for more + information about the decoder, check the decoder state with + FLAC__stream_decoder_get_state(). +*/ FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder); /** Decode until the end of the stream. - * This version instructs the decoder to decode from the current position - * and continue until the end of stream (the read callback returns - * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM), or until the - * callbacks return a fatal error. - * - * As the decoder needs more input it will call the read callback. - * As each metadata block and frame is decoded, the metadata or write - * callback will be called with the decoded metadata or frame. - * - * \param decoder An initialized decoder instance. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if any fatal read, write, or memory allocation error - * occurred (meaning decoding must stop), else \c true; for more - * information about the decoder, check the decoder state with - * FLAC__stream_decoder_get_state(). - */ + This version instructs the decoder to decode from the current position + and continue until the end of stream (the read callback returns + \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM), or until the + callbacks return a fatal error. + + As the decoder needs more input it will call the read callback. + As each metadata block and frame is decoded, the metadata or write + callback will be called with the decoded metadata or frame. + + \param decoder An initialized decoder instance. + \assert + \code decoder != NULL \endcode + \retval FLAC__bool + \c false if any fatal read, write, or memory allocation error + occurred (meaning decoding must stop), else \c true; for more + information about the decoder, check the decoder state with + FLAC__stream_decoder_get_state(). +*/ FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder); /** Skip one audio frame. - * This version instructs the decoder to 'skip' a single frame and stop, - * unless the callbacks return a fatal error or the read callback returns - * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. - * - * The decoding flow is the same as what occurs when - * FLAC__stream_decoder_process_single() is called to process an audio - * frame, except that this function does not decode the parsed data into - * PCM or call the write callback. The integrity of the frame is still - * checked the same way as in the other process functions. - * - * This function will return once one whole frame is skipped, in the - * same way that FLAC__stream_decoder_process_single() will return once - * one whole frame is decoded. - * - * This function can be used in more quickly determining FLAC frame - * boundaries when decoding of the actual data is not needed, for - * example when an application is separating a FLAC stream into frames - * for editing or storing in a container. To do this, the application - * can use FLAC__stream_decoder_skip_single_frame() to quickly advance - * to the next frame, then use - * FLAC__stream_decoder_get_decode_position() to find the new frame - * boundary. - * - * This function should only be called when the stream has advanced - * past all the metadata, otherwise it will return \c false. - * - * \param decoder An initialized decoder instance not in a metadata - * state. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if any fatal read, write, or memory allocation error - * occurred (meaning decoding must stop), or if the decoder - * is in the FLAC__STREAM_DECODER_SEARCH_FOR_METADATA or - * FLAC__STREAM_DECODER_READ_METADATA state, else \c true; for more - * information about the decoder, check the decoder state with - * FLAC__stream_decoder_get_state(). - */ + This version instructs the decoder to 'skip' a single frame and stop, + unless the callbacks return a fatal error or the read callback returns + \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. + + The decoding flow is the same as what occurs when + FLAC__stream_decoder_process_single() is called to process an audio + frame, except that this function does not decode the parsed data into + PCM or call the write callback. The integrity of the frame is still + checked the same way as in the other process functions. + + This function will return once one whole frame is skipped, in the + same way that FLAC__stream_decoder_process_single() will return once + one whole frame is decoded. + + This function can be used in more quickly determining FLAC frame + boundaries when decoding of the actual data is not needed, for + example when an application is separating a FLAC stream into frames + for editing or storing in a container. To do this, the application + can use FLAC__stream_decoder_skip_single_frame() to quickly advance + to the next frame, then use + FLAC__stream_decoder_get_decode_position() to find the new frame + boundary. + + This function should only be called when the stream has advanced + past all the metadata, otherwise it will return \c false. + + \param decoder An initialized decoder instance not in a metadata + state. + \assert + \code decoder != NULL \endcode + \retval FLAC__bool + \c false if any fatal read, write, or memory allocation error + occurred (meaning decoding must stop), or if the decoder + is in the FLAC__STREAM_DECODER_SEARCH_FOR_METADATA or + FLAC__STREAM_DECODER_READ_METADATA state, else \c true; for more + information about the decoder, check the decoder state with + FLAC__stream_decoder_get_state(). +*/ FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder); /** Flush the input and seek to an absolute sample. - * Decoding will resume at the given sample. Note that because of - * this, the next write callback may contain a partial block. The - * client must support seeking the input or this function will fail - * and return \c false. Furthermore, if the decoder state is - * \c FLAC__STREAM_DECODER_SEEK_ERROR, then the decoder must be flushed - * with FLAC__stream_decoder_flush() or reset with - * FLAC__stream_decoder_reset() before decoding can continue. - * - * \param decoder A decoder instance. - * \param sample The target sample number to seek to. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c true if successful, else \c false. - */ + Decoding will resume at the given sample. Note that because of + this, the next write callback may contain a partial block. The + client must support seeking the input or this function will fail + and return \c false. Furthermore, if the decoder state is + \c FLAC__STREAM_DECODER_SEEK_ERROR, then the decoder must be flushed + with FLAC__stream_decoder_flush() or reset with + FLAC__stream_decoder_reset() before decoding can continue. + + \param decoder A decoder instance. + \param sample The target sample number to seek to. + \assert + \code decoder != NULL \endcode + \retval FLAC__bool + \c true if successful, else \c false. +*/ FLAC_API FLAC__bool FLAC__stream_decoder_seek_absolute(FLAC__StreamDecoder *decoder, FLAC__uint64 sample); /** Return client_data from decoder. - * The data pointed to by the pointer should not be modified. - * - * \param decoder A decoder instance. - * \retval const void * - * The callee's client data set through FLAC__stream_decoder_init_*(). - * Do not modify the contents. - */ + The data pointed to by the pointer should not be modified. + + \param decoder A decoder instance. + \retval const void + The callee's client data set through FLAC__stream_decoder_init_*(). + Do not modify the contents. +*/ FLAC_API const void *FLAC__get_decoder_client_data(FLAC__StreamDecoder *decoder); /* \} */ diff --git a/src/libflac/bitmath.c b/src/libflac/bitmath.c index c8853055..0a1c8efa 100644 --- a/src/libflac/bitmath.c +++ b/src/libflac/bitmath.c @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2001-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ //#ifdef HAVE_CONFIG_H # include "config.h" @@ -38,38 +38,39 @@ #include "private/bitmath.h" -/* An example of what FLAC__bitmath_silog2() computes: - * - * silog2(-10) = 5 - * silog2(- 9) = 5 - * silog2(- 8) = 4 - * silog2(- 7) = 4 - * silog2(- 6) = 4 - * silog2(- 5) = 4 - * silog2(- 4) = 3 - * silog2(- 3) = 3 - * silog2(- 2) = 2 - * silog2(- 1) = 2 - * silog2( 0) = 0 - * silog2( 1) = 2 - * silog2( 2) = 3 - * silog2( 3) = 3 - * silog2( 4) = 4 - * silog2( 5) = 4 - * silog2( 6) = 4 - * silog2( 7) = 4 - * silog2( 8) = 5 - * silog2( 9) = 5 - * silog2( 10) = 5 - */ -uint32_t FLAC__bitmath_silog2(FLAC__int64 v) -{ - if(v == 0) - return 0; +/* An example of what FLAC__bitmath_silog2() computes: + + silog2(-10) = 5 + silog2(- 9) = 5 + silog2(- 8) = 4 + silog2(- 7) = 4 + silog2(- 6) = 4 + silog2(- 5) = 4 + silog2(- 4) = 3 + silog2(- 3) = 3 + silog2(- 2) = 2 + silog2(- 1) = 2 + silog2( 0) = 0 + silog2( 1) = 2 + silog2( 2) = 3 + silog2( 3) = 3 + silog2( 4) = 4 + silog2( 5) = 4 + silog2( 6) = 4 + silog2( 7) = 4 + silog2( 8) = 5 + silog2( 9) = 5 + silog2( 10) = 5 +*/ +uint32_t FLAC__bitmath_silog2(FLAC__int64 v) { + if (v == 0) { + return 0; + } - if(v == -1) - return 2; + if (v == -1) { + return 2; + } - v = (v < 0) ? (-(v+1)) : v; - return FLAC__bitmath_ilog2_wide(v)+2; + v = (v < 0) ? (-(v + 1)) : v; + return FLAC__bitmath_ilog2_wide(v) + 2; } diff --git a/src/libflac/bitreader.c b/src/libflac/bitreader.c index a64c1ce5..c3756b1e 100644 --- a/src/libflac/bitreader.c +++ b/src/libflac/bitreader.c @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2000-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ //#ifdef HAVE_CONFIG_H # include "config.h" @@ -86,19 +86,19 @@ typedef FLAC__uint64 brword; #endif /* - * This should be at least twice as large as the largest number of words - * required to represent any 'number' (in any encoding) you are going to - * read. With FLAC this is on the order of maybe a few hundred bits. - * If the buffer is smaller than that, the decoder won't be able to read - * in a whole number that is in a variable length encoding (e.g. Rice). - * But to be practical it should be at least 1K bytes. - * - * Increase this number to decrease the number of read callbacks, at the - * expense of using more memory. Or decrease for the reverse effect, - * keeping in mind the limit from the first paragraph. The optimal size - * also depends on the CPU cache size and other factors; some twiddling - * may be necessary to squeeze out the best performance. - */ + This should be at least twice as large as the largest number of words + required to represent any 'number' (in any encoding) you are going to + read. With FLAC this is on the order of maybe a few hundred bits. + If the buffer is smaller than that, the decoder won't be able to read + in a whole number that is in a variable length encoding (e.g. Rice). + But to be practical it should be at least 1K bytes. + + Increase this number to decrease the number of read callbacks, at the + expense of using more memory. Or decrease for the reverse effect, + keeping in mind the limit from the first paragraph. The optimal size + also depends on the CPU cache size and other factors; some twiddling + may be necessary to squeeze out the best performance. +*/ #if defined(ESP8266) /* Reduced bitreader buffer, saves some RAM */ static const uint32_t FLAC__BITREADER_DEFAULT_CAPACITY = 8192u / FLAC__BITS_PER_WORD; /* in words */ @@ -107,987 +107,1000 @@ static const uint32_t FLAC__BITREADER_DEFAULT_CAPACITY = 65536u / FLAC__BITS_PER #endif struct FLAC__BitReader { - /* any partially-consumed word at the head will stay right-justified as bits are consumed from the left */ - /* any incomplete word at the tail will be left-justified, and bytes from the read callback are added on the right */ - brword *buffer; - uint32_t capacity; /* in words */ - uint32_t words; /* # of completed words in buffer */ - uint32_t bytes; /* # of bytes in incomplete word at buffer[words] */ - uint32_t consumed_words; /* #words ... */ - uint32_t consumed_bits; /* ... + (#bits of head word) already consumed from the front of buffer */ - uint32_t read_crc16; /* the running frame CRC */ - uint32_t crc16_align; /* the number of bits in the current consumed word that should not be CRC'd */ - FLAC__BitReaderReadCallback read_callback; - void *client_data; + /* any partially-consumed word at the head will stay right-justified as bits are consumed from the left */ + /* any incomplete word at the tail will be left-justified, and bytes from the read callback are added on the right */ + brword *buffer; + uint32_t capacity; /* in words */ + uint32_t words; /* # of completed words in buffer */ + uint32_t bytes; /* # of bytes in incomplete word at buffer[words] */ + uint32_t consumed_words; /* #words ... */ + uint32_t consumed_bits; /* ... + (#bits of head word) already consumed from the front of buffer */ + uint32_t read_crc16; /* the running frame CRC */ + uint32_t crc16_align; /* the number of bits in the current consumed word that should not be CRC'd */ + FLAC__BitReaderReadCallback read_callback; + void *client_data; }; -static inline void crc16_update_word_(FLAC__BitReader *br, brword word) -{ - unsigned crc = br->read_crc16; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +static inline void crc16_update_word_(FLAC__BitReader *br, brword word) { + unsigned crc = br->read_crc16; #if FLAC__BYTES_PER_WORD == 4 - switch(br->crc16_align) { - case 0: crc = FLAC__CRC16_UPDATE((uint32_t)(word >> 24), crc); /* Falls Through. */ - case 8: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 16) & 0xff), crc); /* Falls Through. */ - case 16: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 8) & 0xff), crc); /* Falls Through. */ - case 24: br->read_crc16 = FLAC__CRC16_UPDATE((uint32_t)(word & 0xff), crc); - } + switch (br->crc16_align) { + case 0: crc = FLAC__CRC16_UPDATE((uint32_t)(word >> 24), crc); /* Falls Through. */ + case 8: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 16) & 0xff), crc); /* Falls Through. */ + case 16: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 8) & 0xff), crc); /* Falls Through. */ + case 24: br->read_crc16 = FLAC__CRC16_UPDATE((uint32_t)(word & 0xff), crc); + } #elif FLAC__BYTES_PER_WORD == 8 - switch(br->crc16_align) { - case 0: crc = FLAC__CRC16_UPDATE((uint32_t)(word >> 56), crc); /* Falls Through. */ - case 8: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 48) & 0xff), crc); /* Falls Through. */ - case 16: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 40) & 0xff), crc); /* Falls Through. */ - case 24: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 32) & 0xff), crc); /* Falls Through. */ - case 32: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 24) & 0xff), crc); /* Falls Through. */ - case 40: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 16) & 0xff), crc); /* Falls Through. */ - case 48: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 8) & 0xff), crc); /* Falls Through. */ - case 56: br->read_crc16 = FLAC__CRC16_UPDATE((uint32_t)(word & 0xff), crc); - } + switch (br->crc16_align) { + case 0: crc = FLAC__CRC16_UPDATE((uint32_t)(word >> 56), crc); /* Falls Through. */ + case 8: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 48) & 0xff), crc); /* Falls Through. */ + case 16: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 40) & 0xff), crc); /* Falls Through. */ + case 24: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 32) & 0xff), crc); /* Falls Through. */ + case 32: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 24) & 0xff), crc); /* Falls Through. */ + case 40: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 16) & 0xff), crc); /* Falls Through. */ + case 48: crc = FLAC__CRC16_UPDATE((uint32_t)((word >> 8) & 0xff), crc); /* Falls Through. */ + case 56: br->read_crc16 = FLAC__CRC16_UPDATE((uint32_t)(word & 0xff), crc); + } #else - for( ; br->crc16_align < FLAC__BITS_PER_WORD; br->crc16_align += 8) - crc = FLAC__CRC16_UPDATE((uint32_t)((word >> (FLAC__BITS_PER_WORD-8-br->crc16_align)) & 0xff), crc); - br->read_crc16 = crc; + for (; br->crc16_align < FLAC__BITS_PER_WORD; br->crc16_align += 8) { + crc = FLAC__CRC16_UPDATE((uint32_t)((word >> (FLAC__BITS_PER_WORD - 8 - br->crc16_align)) & 0xff), crc); + } + br->read_crc16 = crc; #endif - br->crc16_align = 0; + br->crc16_align = 0; } - -static FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br) -{ - uint32_t start, end; - size_t bytes; - FLAC__byte *target; - - /* first shift the unconsumed buffer data toward the front as much as possible */ - if(br->consumed_words > 0) { - start = br->consumed_words; - end = br->words + (br->bytes? 1:0); - memmove(br->buffer, br->buffer+start, FLAC__BYTES_PER_WORD * (end - start)); - - br->words -= start; - br->consumed_words = 0; - } - - /* - * set the target for reading, taking into account word alignment and endianness - */ - bytes = (br->capacity - br->words) * FLAC__BYTES_PER_WORD - br->bytes; - if(bytes == 0) - return false; /* no space left, buffer is too small; see note for FLAC__BITREADER_DEFAULT_CAPACITY */ - target = ((FLAC__byte*)(br->buffer+br->words)) + br->bytes; - - /* before reading, if the existing reader looks like this (say brword is 32 bits wide) - * bitstream : 11 22 33 44 55 br->words=1 br->bytes=1 (partial tail word is left-justified) - * buffer[BE]: 11 22 33 44 55 ?? ?? ?? (shown laid out as bytes sequentially in memory) - * buffer[LE]: 44 33 22 11 ?? ?? ?? 55 (?? being don't-care) - * ^^-------target, bytes=3 - * on LE machines, have to byteswap the odd tail word so nothing is - * overwritten: - */ +#pragma GCC diagnostic pop + +static FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br) { + uint32_t start, end; + size_t bytes; + FLAC__byte *target; + + /* first shift the unconsumed buffer data toward the front as much as possible */ + if (br->consumed_words > 0) { + start = br->consumed_words; + end = br->words + (br->bytes ? 1 : 0); + memmove(br->buffer, br->buffer + start, FLAC__BYTES_PER_WORD * (end - start)); + + br->words -= start; + br->consumed_words = 0; + } + + /* + set the target for reading, taking into account word alignment and endianness + */ + bytes = (br->capacity - br->words) * FLAC__BYTES_PER_WORD - br->bytes; + if (bytes == 0) { + return false; /* no space left, buffer is too small; see note for FLAC__BITREADER_DEFAULT_CAPACITY */ + } + target = ((FLAC__byte*)(br->buffer + br->words)) + br->bytes; + + /* before reading, if the existing reader looks like this (say brword is 32 bits wide) + bitstream : 11 22 33 44 55 br->words=1 br->bytes=1 (partial tail word is left-justified) + buffer[BE]: 11 22 33 44 55 ?? ?? ?? (shown laid out as bytes sequentially in memory) + buffer[LE]: 44 33 22 11 ?? ?? ?? 55 (?? being don't-care) + ^^-------target, bytes=3 + on LE machines, have to byteswap the odd tail word so nothing is + overwritten: + */ #if WORDS_BIGENDIAN #else - if(br->bytes) - br->buffer[br->words] = SWAP_BE_WORD_TO_HOST(br->buffer[br->words]); + if (br->bytes) { + br->buffer[br->words] = SWAP_BE_WORD_TO_HOST(br->buffer[br->words]); + } #endif - /* now it looks like: - * bitstream : 11 22 33 44 55 br->words=1 br->bytes=1 - * buffer[BE]: 11 22 33 44 55 ?? ?? ?? - * buffer[LE]: 44 33 22 11 55 ?? ?? ?? - * ^^-------target, bytes=3 - */ - - /* read in the data; note that the callback may return a smaller number of bytes */ - if(!br->read_callback(target, &bytes, br->client_data)) - return false; - - /* after reading bytes 66 77 88 99 AA BB CC DD EE FF from the client: - * bitstream : 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF - * buffer[BE]: 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF ?? - * buffer[LE]: 44 33 22 11 55 66 77 88 99 AA BB CC DD EE FF ?? - * now have to byteswap on LE machines: - */ + /* now it looks like: + bitstream : 11 22 33 44 55 br->words=1 br->bytes=1 + buffer[BE]: 11 22 33 44 55 ?? ?? ?? + buffer[LE]: 44 33 22 11 55 ?? ?? ?? + ^^-------target, bytes=3 + */ + + /* read in the data; note that the callback may return a smaller number of bytes */ + if (!br->read_callback(target, &bytes, br->client_data)) { + return false; + } + + /* after reading bytes 66 77 88 99 AA BB CC DD EE FF from the client: + bitstream : 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF + buffer[BE]: 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF ?? + buffer[LE]: 44 33 22 11 55 66 77 88 99 AA BB CC DD EE FF ?? + now have to byteswap on LE machines: + */ #if WORDS_BIGENDIAN #else - end = (br->words*FLAC__BYTES_PER_WORD + br->bytes + (uint32_t)bytes + (FLAC__BYTES_PER_WORD-1)) / FLAC__BYTES_PER_WORD; - for(start = br->words; start < end; start++) - br->buffer[start] = SWAP_BE_WORD_TO_HOST(br->buffer[start]); + end = (br->words * FLAC__BYTES_PER_WORD + br->bytes + (uint32_t)bytes + (FLAC__BYTES_PER_WORD - 1)) / FLAC__BYTES_PER_WORD; + for (start = br->words; start < end; start++) { + br->buffer[start] = SWAP_BE_WORD_TO_HOST(br->buffer[start]); + } #endif - /* now it looks like: - * bitstream : 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF - * buffer[BE]: 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF ?? - * buffer[LE]: 44 33 22 11 88 77 66 55 CC BB AA 99 ?? FF EE DD - * finally we'll update the reader values: - */ - end = br->words*FLAC__BYTES_PER_WORD + br->bytes + (uint32_t)bytes; - br->words = end / FLAC__BYTES_PER_WORD; - br->bytes = end % FLAC__BYTES_PER_WORD; - - return true; + /* now it looks like: + bitstream : 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF + buffer[BE]: 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF ?? + buffer[LE]: 44 33 22 11 88 77 66 55 CC BB AA 99 ?? FF EE DD + finally we'll update the reader values: + */ + end = br->words * FLAC__BYTES_PER_WORD + br->bytes + (uint32_t)bytes; + br->words = end / FLAC__BYTES_PER_WORD; + br->bytes = end % FLAC__BYTES_PER_WORD; + + return true; } /*********************************************************************** - * - * Class constructor/destructor - * + + Class constructor/destructor + ***********************************************************************/ -FLAC__BitReader *FLAC__bitreader_new(void) -{ - FLAC__BitReader *br = (FLAC__BitReader*)calloc(1, sizeof(FLAC__BitReader)); - - /* calloc() implies: - memset(br, 0, sizeof(FLAC__BitReader)); - br->buffer = 0; - br->capacity = 0; - br->words = br->bytes = 0; - br->consumed_words = br->consumed_bits = 0; - br->read_callback = 0; - br->client_data = 0; - */ - return br; +FLAC__BitReader *FLAC__bitreader_new(void) { + FLAC__BitReader *br = (FLAC__BitReader*)calloc(1, sizeof(FLAC__BitReader)); + + /* calloc() implies: + memset(br, 0, sizeof(FLAC__BitReader)); + br->buffer = 0; + br->capacity = 0; + br->words = br->bytes = 0; + br->consumed_words = br->consumed_bits = 0; + br->read_callback = 0; + br->client_data = 0; + */ + return br; } -void FLAC__bitreader_delete(FLAC__BitReader *br) -{ - FLAC__ASSERT(0 != br); +void FLAC__bitreader_delete(FLAC__BitReader *br) { + FLAC__ASSERT(0 != br); - FLAC__bitreader_free(br); - free(br); + FLAC__bitreader_free(br); + free(br); } /*********************************************************************** - * - * Public class methods - * + + Public class methods + ***********************************************************************/ -FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd) -{ - FLAC__ASSERT(0 != br); - - br->words = br->bytes = 0; - br->consumed_words = br->consumed_bits = 0; - br->capacity = FLAC__BITREADER_DEFAULT_CAPACITY; - br->buffer = (brword*)malloc(sizeof(brword) * br->capacity); - if(br->buffer == 0) - return false; - br->read_callback = rcb; - br->client_data = cd; - - return true; +FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd) { + FLAC__ASSERT(0 != br); + + br->words = br->bytes = 0; + br->consumed_words = br->consumed_bits = 0; + br->capacity = FLAC__BITREADER_DEFAULT_CAPACITY; + br->buffer = (brword*)malloc(sizeof(brword) * br->capacity); + if (br->buffer == 0) { + return false; + } + br->read_callback = rcb; + br->client_data = cd; + + return true; } -void FLAC__bitreader_free(FLAC__BitReader *br) -{ - FLAC__ASSERT(0 != br); - - if(0 != br->buffer) - free(br->buffer); - br->buffer = 0; - br->capacity = 0; - br->words = br->bytes = 0; - br->consumed_words = br->consumed_bits = 0; - br->read_callback = 0; - br->client_data = 0; +void FLAC__bitreader_free(FLAC__BitReader *br) { + FLAC__ASSERT(0 != br); + + if (0 != br->buffer) { + free(br->buffer); + } + br->buffer = 0; + br->capacity = 0; + br->words = br->bytes = 0; + br->consumed_words = br->consumed_bits = 0; + br->read_callback = 0; + br->client_data = 0; } -FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br) -{ - br->words = br->bytes = 0; - br->consumed_words = br->consumed_bits = 0; - return true; +FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br) { + br->words = br->bytes = 0; + br->consumed_words = br->consumed_bits = 0; + return true; } #if 0 -void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out) -{ - uint32_t i, j; - if(br == 0) { - fprintf(out, "bitreader is NULL\n"); - } - else { - fprintf(out, "bitreader: capacity=%u words=%u bytes=%u consumed: words=%u, bits=%u\n", br->capacity, br->words, br->bytes, br->consumed_words, br->consumed_bits); - - for(i = 0; i < br->words; i++) { - fprintf(out, "%08X: ", i); - for(j = 0; j < FLAC__BITS_PER_WORD; j++) - if(i < br->consumed_words || (i == br->consumed_words && j < br->consumed_bits)) - fprintf(out, "."); - else - fprintf(out, "%01d", br->buffer[i] & ((brword)1 << (FLAC__BITS_PER_WORD-j-1)) ? 1:0); - fprintf(out, "\n"); - } - if(br->bytes > 0) { - fprintf(out, "%08X: ", i); - for(j = 0; j < br->bytes*8; j++) - if(i < br->consumed_words || (i == br->consumed_words && j < br->consumed_bits)) - fprintf(out, "."); - else - fprintf(out, "%01d", br->buffer[i] & ((brword)1 << (br->bytes*8-j-1)) ? 1:0); - fprintf(out, "\n"); - } - } +void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out) { + uint32_t i, j; + if (br == 0) { + fprintf(out, "bitreader is NULL\n"); + } else { + fprintf(out, "bitreader: capacity=%u words=%u bytes=%u consumed: words=%u, bits=%u\n", br->capacity, br->words, br->bytes, br->consumed_words, br->consumed_bits); + + for (i = 0; i < br->words; i++) { + fprintf(out, "%08X: ", i); + for (j = 0; j < FLAC__BITS_PER_WORD; j++) + if (i < br->consumed_words || (i == br->consumed_words && j < br->consumed_bits)) { + fprintf(out, "."); + } else { + fprintf(out, "%01d", br->buffer[i] & ((brword)1 << (FLAC__BITS_PER_WORD - j - 1)) ? 1 : 0); + } + fprintf(out, "\n"); + } + if (br->bytes > 0) { + fprintf(out, "%08X: ", i); + for (j = 0; j < br->bytes * 8; j++) + if (i < br->consumed_words || (i == br->consumed_words && j < br->consumed_bits)) { + fprintf(out, "."); + } else { + fprintf(out, "%01d", br->buffer[i] & ((brword)1 << (br->bytes * 8 - j - 1)) ? 1 : 0); + } + fprintf(out, "\n"); + } + } } #endif -void FLAC__bitreader_reset_read_crc16(FLAC__BitReader *br, FLAC__uint16 seed) -{ +void FLAC__bitreader_reset_read_crc16(FLAC__BitReader *br, FLAC__uint16 seed) { FLAC__ASSERT(0 != br); - FLAC__ASSERT(0 != br->buffer); - FLAC__ASSERT((br->consumed_bits & 7) == 0); + FLAC__ASSERT(0 != br->buffer); + FLAC__ASSERT((br->consumed_bits & 7) == 0); - br->read_crc16 = (uint32_t)seed; - br->crc16_align = br->consumed_bits; + br->read_crc16 = (uint32_t)seed; + br->crc16_align = br->consumed_bits; } -FLAC__uint16 FLAC__bitreader_get_read_crc16(FLAC__BitReader *br) -{ - FLAC__ASSERT(0 != br); - FLAC__ASSERT(0 != br->buffer); - FLAC__ASSERT((br->consumed_bits & 7) == 0); - FLAC__ASSERT(br->crc16_align <= br->consumed_bits); - - /* CRC any tail bytes in a partially-consumed word */ - if(br->consumed_bits) { - const brword tail = br->buffer[br->consumed_words]; - for( ; br->crc16_align < br->consumed_bits; br->crc16_align += 8) - br->read_crc16 = FLAC__CRC16_UPDATE((uint32_t)((tail >> (FLAC__BITS_PER_WORD-8-br->crc16_align)) & 0xff), br->read_crc16); - } - return br->read_crc16; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +FLAC__uint16 FLAC__bitreader_get_read_crc16(FLAC__BitReader *br) { + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + FLAC__ASSERT((br->consumed_bits & 7) == 0); + FLAC__ASSERT(br->crc16_align <= br->consumed_bits); + + /* CRC any tail bytes in a partially-consumed word */ + if (br->consumed_bits) { + const brword tail = br->buffer[br->consumed_words]; + for (; br->crc16_align < br->consumed_bits; br->crc16_align += 8) { + br->read_crc16 = FLAC__CRC16_UPDATE((uint32_t)((tail >> (FLAC__BITS_PER_WORD - 8 - br->crc16_align)) & 0xff), br->read_crc16); + } + } + return br->read_crc16; } +#pragma GCC diagnostic pop -inline FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br) -{ - return ((br->consumed_bits & 7) == 0); +inline FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br) { + return ((br->consumed_bits & 7) == 0); } -inline uint32_t FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br) -{ - return 8 - (br->consumed_bits & 7); +inline uint32_t FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br) { + return 8 - (br->consumed_bits & 7); } -inline uint32_t FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br) -{ - return (br->words-br->consumed_words)*FLAC__BITS_PER_WORD + br->bytes*8 - br->consumed_bits; +inline uint32_t FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br) { + return (br->words - br->consumed_words) * FLAC__BITS_PER_WORD + br->bytes * 8 - br->consumed_bits; } -FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, uint32_t bits) -{ - FLAC__ASSERT(0 != br); - FLAC__ASSERT(0 != br->buffer); - - FLAC__ASSERT(bits <= 32); - FLAC__ASSERT((br->capacity*FLAC__BITS_PER_WORD) * 2 >= bits); - FLAC__ASSERT(br->consumed_words <= br->words); - - /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ - FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); - - if(bits == 0) { /* OPT: investigate if this can ever happen, maybe change to assertion */ - *val = 0; - return true; - } - - while((br->words-br->consumed_words)*FLAC__BITS_PER_WORD + br->bytes*8 - br->consumed_bits < bits) { - if(!bitreader_read_from_client_(br)) - return false; - } - if(br->consumed_words < br->words) { /* if we've not consumed up to a partial tail word... */ - /* OPT: taking out the consumed_bits==0 "else" case below might make things faster if less code allows the compiler to inline this function */ - if(br->consumed_bits) { - /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */ - const uint32_t n = FLAC__BITS_PER_WORD - br->consumed_bits; - const brword word = br->buffer[br->consumed_words]; - if(bits < n) { - *val = (FLAC__uint32)((word & (FLAC__WORD_ALL_ONES >> br->consumed_bits)) >> (n-bits)); /* The result has <= 32 non-zero bits */ - br->consumed_bits += bits; - return true; - } - /* (FLAC__BITS_PER_WORD - br->consumed_bits <= bits) ==> (FLAC__WORD_ALL_ONES >> br->consumed_bits) has no more than 'bits' non-zero bits */ - *val = (FLAC__uint32)(word & (FLAC__WORD_ALL_ONES >> br->consumed_bits)); - bits -= n; - crc16_update_word_(br, word); - br->consumed_words++; - br->consumed_bits = 0; - if(bits) { /* if there are still bits left to read, there have to be less than 32 so they will all be in the next word */ - *val <<= bits; - *val |= (FLAC__uint32)(br->buffer[br->consumed_words] >> (FLAC__BITS_PER_WORD-bits)); - br->consumed_bits = bits; - } - return true; - } - else { /* br->consumed_bits == 0 */ - const brword word = br->buffer[br->consumed_words]; - if(bits < FLAC__BITS_PER_WORD) { - *val = (FLAC__uint32)(word >> (FLAC__BITS_PER_WORD-bits)); - br->consumed_bits = bits; - return true; - } - /* at this point bits == FLAC__BITS_PER_WORD == 32; because of previous assertions, it can't be larger */ - *val = (FLAC__uint32)word; - crc16_update_word_(br, word); - br->consumed_words++; - return true; - } - } - else { - /* in this case we're starting our read at a partial tail word; - * the reader has guaranteed that we have at least 'bits' bits - * available to read, which makes this case simpler. - */ - /* OPT: taking out the consumed_bits==0 "else" case below might make things faster if less code allows the compiler to inline this function */ - if(br->consumed_bits) { - /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */ - FLAC__ASSERT(br->consumed_bits + bits <= br->bytes*8); - *val = (FLAC__uint32)((br->buffer[br->consumed_words] & (FLAC__WORD_ALL_ONES >> br->consumed_bits)) >> (FLAC__BITS_PER_WORD-br->consumed_bits-bits)); - br->consumed_bits += bits; - return true; - } - else { - *val = (FLAC__uint32)(br->buffer[br->consumed_words] >> (FLAC__BITS_PER_WORD-bits)); - br->consumed_bits += bits; - return true; - } - } +FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, uint32_t bits) { + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + + FLAC__ASSERT(bits <= 32); + FLAC__ASSERT((br->capacity * FLAC__BITS_PER_WORD) * 2 >= bits); + FLAC__ASSERT(br->consumed_words <= br->words); + + /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ + FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); + + if (bits == 0) { /* OPT: investigate if this can ever happen, maybe change to assertion */ + *val = 0; + return true; + } + + while ((br->words - br->consumed_words)*FLAC__BITS_PER_WORD + br->bytes * 8 - br->consumed_bits < bits) { + if (!bitreader_read_from_client_(br)) { + return false; + } + } + if (br->consumed_words < br->words) { /* if we've not consumed up to a partial tail word... */ + /* OPT: taking out the consumed_bits==0 "else" case below might make things faster if less code allows the compiler to inline this function */ + if (br->consumed_bits) { + /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */ + const uint32_t n = FLAC__BITS_PER_WORD - br->consumed_bits; + const brword word = br->buffer[br->consumed_words]; + if (bits < n) { + *val = (FLAC__uint32)((word & (FLAC__WORD_ALL_ONES >> br->consumed_bits)) >> (n - bits)); /* The result has <= 32 non-zero bits */ + br->consumed_bits += bits; + return true; + } + /* (FLAC__BITS_PER_WORD - br->consumed_bits <= bits) ==> (FLAC__WORD_ALL_ONES >> br->consumed_bits) has no more than 'bits' non-zero bits */ + *val = (FLAC__uint32)(word & (FLAC__WORD_ALL_ONES >> br->consumed_bits)); + bits -= n; + crc16_update_word_(br, word); + br->consumed_words++; + br->consumed_bits = 0; + if (bits) { /* if there are still bits left to read, there have to be less than 32 so they will all be in the next word */ + *val <<= bits; + *val |= (FLAC__uint32)(br->buffer[br->consumed_words] >> (FLAC__BITS_PER_WORD - bits)); + br->consumed_bits = bits; + } + return true; + } else { /* br->consumed_bits == 0 */ + const brword word = br->buffer[br->consumed_words]; + if (bits < FLAC__BITS_PER_WORD) { + *val = (FLAC__uint32)(word >> (FLAC__BITS_PER_WORD - bits)); + br->consumed_bits = bits; + return true; + } + /* at this point bits == FLAC__BITS_PER_WORD == 32; because of previous assertions, it can't be larger */ + *val = (FLAC__uint32)word; + crc16_update_word_(br, word); + br->consumed_words++; + return true; + } + } else { + /* in this case we're starting our read at a partial tail word; + the reader has guaranteed that we have at least 'bits' bits + available to read, which makes this case simpler. + */ + /* OPT: taking out the consumed_bits==0 "else" case below might make things faster if less code allows the compiler to inline this function */ + if (br->consumed_bits) { + /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */ + FLAC__ASSERT(br->consumed_bits + bits <= br->bytes * 8); + *val = (FLAC__uint32)((br->buffer[br->consumed_words] & (FLAC__WORD_ALL_ONES >> br->consumed_bits)) >> (FLAC__BITS_PER_WORD - br->consumed_bits - bits)); + br->consumed_bits += bits; + return true; + } else { + *val = (FLAC__uint32)(br->buffer[br->consumed_words] >> (FLAC__BITS_PER_WORD - bits)); + br->consumed_bits += bits; + return true; + } + } } -FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, uint32_t bits) -{ - FLAC__uint32 uval, mask; - /* OPT: inline raw uint32 code here, or make into a macro if possible in the .h file */ - if(!FLAC__bitreader_read_raw_uint32(br, &uval, bits)) - return false; - /* sign-extend *val assuming it is currently bits wide. */ - /* From: https://graphics.stanford.edu/~seander/bithacks.html#FixedSignExtend */ - mask = 1u << (bits - 1); - *val = (uval ^ mask) - mask; - return true; +FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, uint32_t bits) { + FLAC__uint32 uval, mask; + /* OPT: inline raw uint32 code here, or make into a macro if possible in the .h file */ + if (!FLAC__bitreader_read_raw_uint32(br, &uval, bits)) { + return false; + } + /* sign-extend *val assuming it is currently bits wide. */ + /* From: https://graphics.stanford.edu/~seander/bithacks.html#FixedSignExtend */ + mask = 1u << (bits - 1); + *val = (uval ^ mask) - mask; + return true; } -FLAC__bool FLAC__bitreader_read_raw_uint64(FLAC__BitReader *br, FLAC__uint64 *val, uint32_t bits) -{ - FLAC__uint32 hi, lo; - - if(bits > 32) { - if(!FLAC__bitreader_read_raw_uint32(br, &hi, bits-32)) - return false; - if(!FLAC__bitreader_read_raw_uint32(br, &lo, 32)) - return false; - *val = hi; - *val <<= 32; - *val |= lo; - } - else { - if(!FLAC__bitreader_read_raw_uint32(br, &lo, bits)) - return false; - *val = lo; - } - return true; +FLAC__bool FLAC__bitreader_read_raw_uint64(FLAC__BitReader *br, FLAC__uint64 *val, uint32_t bits) { + FLAC__uint32 hi, lo; + + if (bits > 32) { + if (!FLAC__bitreader_read_raw_uint32(br, &hi, bits - 32)) { + return false; + } + if (!FLAC__bitreader_read_raw_uint32(br, &lo, 32)) { + return false; + } + *val = hi; + *val <<= 32; + *val |= lo; + } else { + if (!FLAC__bitreader_read_raw_uint32(br, &lo, bits)) { + return false; + } + *val = lo; + } + return true; } -inline FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val) -{ - FLAC__uint32 x8, x32 = 0; +inline FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val) { + FLAC__uint32 x8, x32 = 0; - /* this doesn't need to be that fast as currently it is only used for vorbis comments */ + /* this doesn't need to be that fast as currently it is only used for vorbis comments */ - if(!FLAC__bitreader_read_raw_uint32(br, &x32, 8)) - return false; + if (!FLAC__bitreader_read_raw_uint32(br, &x32, 8)) { + return false; + } - if(!FLAC__bitreader_read_raw_uint32(br, &x8, 8)) - return false; - x32 |= (x8 << 8); + if (!FLAC__bitreader_read_raw_uint32(br, &x8, 8)) { + return false; + } + x32 |= (x8 << 8); - if(!FLAC__bitreader_read_raw_uint32(br, &x8, 8)) - return false; - x32 |= (x8 << 16); + if (!FLAC__bitreader_read_raw_uint32(br, &x8, 8)) { + return false; + } + x32 |= (x8 << 16); - if(!FLAC__bitreader_read_raw_uint32(br, &x8, 8)) - return false; - x32 |= (x8 << 24); + if (!FLAC__bitreader_read_raw_uint32(br, &x8, 8)) { + return false; + } + x32 |= (x8 << 24); - *val = x32; - return true; + *val = x32; + return true; } -FLAC__bool FLAC__bitreader_skip_bits_no_crc(FLAC__BitReader *br, uint32_t bits) -{ - /* - * OPT: a faster implementation is possible but probably not that useful - * since this is only called a couple of times in the metadata readers. - */ - FLAC__ASSERT(0 != br); - FLAC__ASSERT(0 != br->buffer); - - if(bits > 0) { - const uint32_t n = br->consumed_bits & 7; - uint32_t m; - FLAC__uint32 x; - - if(n != 0) { - m = flac_min(8-n, bits); - if(!FLAC__bitreader_read_raw_uint32(br, &x, m)) - return false; - bits -= m; - } - m = bits / 8; - if(m > 0) { - if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(br, m)) - return false; - bits %= 8; - } - if(bits > 0) { - if(!FLAC__bitreader_read_raw_uint32(br, &x, bits)) - return false; - } - } - - return true; +FLAC__bool FLAC__bitreader_skip_bits_no_crc(FLAC__BitReader *br, uint32_t bits) { + /* + OPT: a faster implementation is possible but probably not that useful + since this is only called a couple of times in the metadata readers. + */ + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + + if (bits > 0) { + const uint32_t n = br->consumed_bits & 7; + uint32_t m; + FLAC__uint32 x; + + if (n != 0) { + m = flac_min(8 - n, bits); + if (!FLAC__bitreader_read_raw_uint32(br, &x, m)) { + return false; + } + bits -= m; + } + m = bits / 8; + if (m > 0) { + if (!FLAC__bitreader_skip_byte_block_aligned_no_crc(br, m)) { + return false; + } + bits %= 8; + } + if (bits > 0) { + if (!FLAC__bitreader_read_raw_uint32(br, &x, bits)) { + return false; + } + } + } + + return true; } -FLAC__bool FLAC__bitreader_skip_byte_block_aligned_no_crc(FLAC__BitReader *br, uint32_t nvals) -{ - FLAC__uint32 x; - - FLAC__ASSERT(0 != br); - FLAC__ASSERT(0 != br->buffer); - FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(br)); - - /* step 1: skip over partial head word to get word aligned */ - while(nvals && br->consumed_bits) { /* i.e. run until we read 'nvals' bytes or we hit the end of the head word */ - if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) - return false; - nvals--; - } - if(0 == nvals) - return true; - /* step 2: skip whole words in chunks */ - while(nvals >= FLAC__BYTES_PER_WORD) { - if(br->consumed_words < br->words) { - br->consumed_words++; - nvals -= FLAC__BYTES_PER_WORD; - } - else if(!bitreader_read_from_client_(br)) - return false; - } - /* step 3: skip any remainder from partial tail bytes */ - while(nvals) { - if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) - return false; - nvals--; - } - - return true; +FLAC__bool FLAC__bitreader_skip_byte_block_aligned_no_crc(FLAC__BitReader *br, uint32_t nvals) { + FLAC__uint32 x; + + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(br)); + + /* step 1: skip over partial head word to get word aligned */ + while (nvals && br->consumed_bits) { /* i.e. run until we read 'nvals' bytes or we hit the end of the head word */ + if (!FLAC__bitreader_read_raw_uint32(br, &x, 8)) { + return false; + } + nvals--; + } + if (0 == nvals) { + return true; + } + /* step 2: skip whole words in chunks */ + while (nvals >= FLAC__BYTES_PER_WORD) { + if (br->consumed_words < br->words) { + br->consumed_words++; + nvals -= FLAC__BYTES_PER_WORD; + } else if (!bitreader_read_from_client_(br)) { + return false; + } + } + /* step 3: skip any remainder from partial tail bytes */ + while (nvals) { + if (!FLAC__bitreader_read_raw_uint32(br, &x, 8)) { + return false; + } + nvals--; + } + + return true; } -FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, FLAC__byte *val, uint32_t nvals) -{ - FLAC__uint32 x; - - FLAC__ASSERT(0 != br); - FLAC__ASSERT(0 != br->buffer); - FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(br)); - - /* step 1: read from partial head word to get word aligned */ - while(nvals && br->consumed_bits) { /* i.e. run until we read 'nvals' bytes or we hit the end of the head word */ - if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) - return false; - *val++ = (FLAC__byte)x; - nvals--; - } - if(0 == nvals) - return true; - /* step 2: read whole words in chunks */ - while(nvals >= FLAC__BYTES_PER_WORD) { - if(br->consumed_words < br->words) { - const brword word = br->buffer[br->consumed_words++]; +FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, FLAC__byte *val, uint32_t nvals) { + FLAC__uint32 x; + + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(br)); + + /* step 1: read from partial head word to get word aligned */ + while (nvals && br->consumed_bits) { /* i.e. run until we read 'nvals' bytes or we hit the end of the head word */ + if (!FLAC__bitreader_read_raw_uint32(br, &x, 8)) { + return false; + } + *val++ = (FLAC__byte)x; + nvals--; + } + if (0 == nvals) { + return true; + } + /* step 2: read whole words in chunks */ + while (nvals >= FLAC__BYTES_PER_WORD) { + if (br->consumed_words < br->words) { + const brword word = br->buffer[br->consumed_words++]; #if FLAC__BYTES_PER_WORD == 4 - val[0] = (FLAC__byte)(word >> 24); - val[1] = (FLAC__byte)(word >> 16); - val[2] = (FLAC__byte)(word >> 8); - val[3] = (FLAC__byte)word; + val[0] = (FLAC__byte)(word >> 24); + val[1] = (FLAC__byte)(word >> 16); + val[2] = (FLAC__byte)(word >> 8); + val[3] = (FLAC__byte)word; #elif FLAC__BYTES_PER_WORD == 8 - val[0] = (FLAC__byte)(word >> 56); - val[1] = (FLAC__byte)(word >> 48); - val[2] = (FLAC__byte)(word >> 40); - val[3] = (FLAC__byte)(word >> 32); - val[4] = (FLAC__byte)(word >> 24); - val[5] = (FLAC__byte)(word >> 16); - val[6] = (FLAC__byte)(word >> 8); - val[7] = (FLAC__byte)word; + val[0] = (FLAC__byte)(word >> 56); + val[1] = (FLAC__byte)(word >> 48); + val[2] = (FLAC__byte)(word >> 40); + val[3] = (FLAC__byte)(word >> 32); + val[4] = (FLAC__byte)(word >> 24); + val[5] = (FLAC__byte)(word >> 16); + val[6] = (FLAC__byte)(word >> 8); + val[7] = (FLAC__byte)word; #else - for(x = 0; x < FLAC__BYTES_PER_WORD; x++) - val[x] = (FLAC__byte)(word >> (8*(FLAC__BYTES_PER_WORD-x-1))); + for (x = 0; x < FLAC__BYTES_PER_WORD; x++) { + val[x] = (FLAC__byte)(word >> (8 * (FLAC__BYTES_PER_WORD - x - 1))); + } #endif - val += FLAC__BYTES_PER_WORD; - nvals -= FLAC__BYTES_PER_WORD; - } - else if(!bitreader_read_from_client_(br)) - return false; - } - /* step 3: read any remainder from partial tail bytes */ - while(nvals) { - if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) - return false; - *val++ = (FLAC__byte)x; - nvals--; - } - - return true; + val += FLAC__BYTES_PER_WORD; + nvals -= FLAC__BYTES_PER_WORD; + } else if (!bitreader_read_from_client_(br)) { + return false; + } + } + /* step 3: read any remainder from partial tail bytes */ + while (nvals) { + if (!FLAC__bitreader_read_raw_uint32(br, &x, 8)) { + return false; + } + *val++ = (FLAC__byte)x; + nvals--; + } + + return true; } FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, uint32_t *val) #if 0 /* slow but readable version */ { - uint32_t bit; - - FLAC__ASSERT(0 != br); - FLAC__ASSERT(0 != br->buffer); - - *val = 0; - while(1) { - if(!FLAC__bitreader_read_bit(br, &bit)) - return false; - if(bit) - break; - else - *val++; - } - return true; + uint32_t bit; + + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + + *val = 0; + while (1) { + if (!FLAC__bitreader_read_bit(br, &bit)) { + return false; + } + if (bit) { + break; + } else { + *val++; + } + } + return true; } #else { - uint32_t i; - - FLAC__ASSERT(0 != br); - FLAC__ASSERT(0 != br->buffer); - - *val = 0; - while(1) { - while(br->consumed_words < br->words) { /* if we've not consumed up to a partial tail word... */ - brword b = br->buffer[br->consumed_words] << br->consumed_bits; - if(b) { - i = COUNT_ZERO_MSBS(b); - *val += i; - i++; - br->consumed_bits += i; - if(br->consumed_bits >= FLAC__BITS_PER_WORD) { /* faster way of testing if(br->consumed_bits == FLAC__BITS_PER_WORD) */ - crc16_update_word_(br, br->buffer[br->consumed_words]); - br->consumed_words++; - br->consumed_bits = 0; - } - return true; - } - else { - *val += FLAC__BITS_PER_WORD - br->consumed_bits; - crc16_update_word_(br, br->buffer[br->consumed_words]); - br->consumed_words++; - br->consumed_bits = 0; - /* didn't find stop bit yet, have to keep going... */ - } - } - /* at this point we've eaten up all the whole words; have to try - * reading through any tail bytes before calling the read callback. - * this is a repeat of the above logic adjusted for the fact we - * don't have a whole word. note though if the client is feeding - * us data a byte at a time (unlikely), br->consumed_bits may not - * be zero. - */ - if(br->bytes*8 > br->consumed_bits) { - const uint32_t end = br->bytes * 8; - brword b = (br->buffer[br->consumed_words] & (FLAC__WORD_ALL_ONES << (FLAC__BITS_PER_WORD-end))) << br->consumed_bits; - if(b) { - i = COUNT_ZERO_MSBS(b); - *val += i; - i++; - br->consumed_bits += i; - FLAC__ASSERT(br->consumed_bits < FLAC__BITS_PER_WORD); - return true; - } - else { - *val += end - br->consumed_bits; - br->consumed_bits = end; - FLAC__ASSERT(br->consumed_bits < FLAC__BITS_PER_WORD); - /* didn't find stop bit yet, have to keep going... */ - } - } - if(!bitreader_read_from_client_(br)) - return false; - } + uint32_t i; + + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + + *val = 0; + while (1) { + while (br->consumed_words < br->words) { /* if we've not consumed up to a partial tail word... */ + brword b = br->buffer[br->consumed_words] << br->consumed_bits; + if (b) { + i = COUNT_ZERO_MSBS(b); + *val += i; + i++; + br->consumed_bits += i; + if (br->consumed_bits >= FLAC__BITS_PER_WORD) { /* faster way of testing if(br->consumed_bits == FLAC__BITS_PER_WORD) */ + crc16_update_word_(br, br->buffer[br->consumed_words]); + br->consumed_words++; + br->consumed_bits = 0; + } + return true; + } else { + *val += FLAC__BITS_PER_WORD - br->consumed_bits; + crc16_update_word_(br, br->buffer[br->consumed_words]); + br->consumed_words++; + br->consumed_bits = 0; + /* didn't find stop bit yet, have to keep going... */ + } + } + /* at this point we've eaten up all the whole words; have to try + reading through any tail bytes before calling the read callback. + this is a repeat of the above logic adjusted for the fact we + don't have a whole word. note though if the client is feeding + us data a byte at a time (unlikely), br->consumed_bits may not + be zero. + */ + if (br->bytes * 8 > br->consumed_bits) { + const uint32_t end = br->bytes * 8; + brword b = (br->buffer[br->consumed_words] & (FLAC__WORD_ALL_ONES << (FLAC__BITS_PER_WORD - end))) << br->consumed_bits; + if (b) { + i = COUNT_ZERO_MSBS(b); + *val += i; + i++; + br->consumed_bits += i; + FLAC__ASSERT(br->consumed_bits < FLAC__BITS_PER_WORD); + return true; + } else { + *val += end - br->consumed_bits; + br->consumed_bits = end; + FLAC__ASSERT(br->consumed_bits < FLAC__BITS_PER_WORD); + /* didn't find stop bit yet, have to keep going... */ + } + } + if (!bitreader_read_from_client_(br)) { + return false; + } + } } #endif -FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, uint32_t parameter) -{ - FLAC__uint32 lsbs = 0, msbs = 0; - uint32_t uval; - - FLAC__ASSERT(0 != br); - FLAC__ASSERT(0 != br->buffer); - FLAC__ASSERT(parameter <= 31); - - /* read the unary MSBs and end bit */ - if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) - return false; - - /* read the binary LSBs */ - if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, parameter)) - return false; +FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, uint32_t parameter) { + FLAC__uint32 lsbs = 0, msbs = 0; + uint32_t uval; - /* compose the value */ - uval = (msbs << parameter) | lsbs; - if(uval & 1) - *val = -((int)(uval >> 1)) - 1; - else - *val = (int)(uval >> 1); - - return true; + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + FLAC__ASSERT(parameter <= 31); + + /* read the unary MSBs and end bit */ + if (!FLAC__bitreader_read_unary_unsigned(br, &msbs)) { + return false; + } + + /* read the binary LSBs */ + if (!FLAC__bitreader_read_raw_uint32(br, &lsbs, parameter)) { + return false; + } + + /* compose the value */ + uval = (msbs << parameter) | lsbs; + if (uval & 1) { + *val = -((int)(uval >> 1)) - 1; + } else { + *val = (int)(uval >> 1); + } + + return true; } /* this is by far the most heavily used reader call. it ain't pretty but it's fast */ -FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], uint32_t nvals, uint32_t parameter) -{ - /* try and get br->consumed_words and br->consumed_bits into register; - * must remember to flush them back to *br before calling other - * bitreader functions that use them, and before returning */ - uint32_t cwords, words, lsbs, msbs, x, y; - uint32_t ucbits; /* keep track of the number of unconsumed bits in word */ - brword b; - int *val, *end; - - FLAC__ASSERT(0 != br); - FLAC__ASSERT(0 != br->buffer); - /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ - FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); - FLAC__ASSERT(parameter < 32); - /* the above two asserts also guarantee that the binary part never straddles more than 2 words, so we don't have to loop to read it */ - - val = vals; - end = vals + nvals; - - if(parameter == 0) { - while(val < end) { - /* read the unary MSBs and end bit */ - if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) - return false; - - *val++ = (int)(msbs >> 1) ^ -(int)(msbs & 1); - } - - return true; - } - - FLAC__ASSERT(parameter > 0); - - cwords = br->consumed_words; - words = br->words; - - /* if we've not consumed up to a partial tail word... */ - if(cwords >= words) { - x = 0; - goto process_tail; - } - - ucbits = FLAC__BITS_PER_WORD - br->consumed_bits; - b = br->buffer[cwords] << br->consumed_bits; /* keep unconsumed bits aligned to left */ - - while(val < end) { - /* read the unary MSBs and end bit */ - x = y = COUNT_ZERO_MSBS2(b); - if(x == FLAC__BITS_PER_WORD) { - x = ucbits; - do { - /* didn't find stop bit yet, have to keep going... */ - crc16_update_word_(br, br->buffer[cwords++]); - if (cwords >= words) - goto incomplete_msbs; - b = br->buffer[cwords]; - y = COUNT_ZERO_MSBS2(b); - x += y; - } while(y == FLAC__BITS_PER_WORD); - } - b <<= y; - b <<= 1; /* account for stop bit */ - ucbits = (ucbits - x - 1) % FLAC__BITS_PER_WORD; - msbs = x; - - /* read the binary LSBs */ - x = (FLAC__uint32)(b >> (FLAC__BITS_PER_WORD - parameter)); /* parameter < 32, so we can cast to 32-bit uint32_t */ - if(parameter <= ucbits) { - ucbits -= parameter; - b <<= parameter; - } else { - /* there are still bits left to read, they will all be in the next word */ - crc16_update_word_(br, br->buffer[cwords++]); - if (cwords >= words) - goto incomplete_lsbs; - b = br->buffer[cwords]; - ucbits += FLAC__BITS_PER_WORD - parameter; - x |= (FLAC__uint32)(b >> ucbits); - b <<= FLAC__BITS_PER_WORD - ucbits; - } - lsbs = x; - - /* compose the value */ - x = (msbs << parameter) | lsbs; - *val++ = (int)(x >> 1) ^ -(int)(x & 1); - - continue; - - /* at this point we've eaten up all the whole words */ +FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], uint32_t nvals, uint32_t parameter) { + /* try and get br->consumed_words and br->consumed_bits into register; + must remember to flush them back to *br before calling other + bitreader functions that use them, and before returning */ + uint32_t cwords, words, lsbs, msbs, x, y; + uint32_t ucbits; /* keep track of the number of unconsumed bits in word */ + brword b; + int *val, *end; + + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ + FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); + FLAC__ASSERT(parameter < 32); + /* the above two asserts also guarantee that the binary part never straddles more than 2 words, so we don't have to loop to read it */ + + val = vals; + end = vals + nvals; + + if (parameter == 0) { + while (val < end) { + /* read the unary MSBs and end bit */ + if (!FLAC__bitreader_read_unary_unsigned(br, &msbs)) { + return false; + } + + *val++ = (int)(msbs >> 1) ^ -(int)(msbs & 1); + } + + return true; + } + + FLAC__ASSERT(parameter > 0); + + cwords = br->consumed_words; + words = br->words; + + /* if we've not consumed up to a partial tail word... */ + if (cwords >= words) { + x = 0; + goto process_tail; + } + + ucbits = FLAC__BITS_PER_WORD - br->consumed_bits; + b = br->buffer[cwords] << br->consumed_bits; /* keep unconsumed bits aligned to left */ + + while (val < end) { + /* read the unary MSBs and end bit */ + x = y = COUNT_ZERO_MSBS2(b); + if (x == FLAC__BITS_PER_WORD) { + x = ucbits; + do { + /* didn't find stop bit yet, have to keep going... */ + crc16_update_word_(br, br->buffer[cwords++]); + if (cwords >= words) { + goto incomplete_msbs; + } + b = br->buffer[cwords]; + y = COUNT_ZERO_MSBS2(b); + x += y; + } while (y == FLAC__BITS_PER_WORD); + } + b <<= y; + b <<= 1; /* account for stop bit */ + ucbits = (ucbits - x - 1) % FLAC__BITS_PER_WORD; + msbs = x; + + /* read the binary LSBs */ + x = (FLAC__uint32)(b >> (FLAC__BITS_PER_WORD - parameter)); /* parameter < 32, so we can cast to 32-bit uint32_t */ + if (parameter <= ucbits) { + ucbits -= parameter; + b <<= parameter; + } else { + /* there are still bits left to read, they will all be in the next word */ + crc16_update_word_(br, br->buffer[cwords++]); + if (cwords >= words) { + goto incomplete_lsbs; + } + b = br->buffer[cwords]; + ucbits += FLAC__BITS_PER_WORD - parameter; + x |= (FLAC__uint32)(b >> ucbits); + b <<= FLAC__BITS_PER_WORD - ucbits; + } + lsbs = x; + + /* compose the value */ + x = (msbs << parameter) | lsbs; + *val++ = (int)(x >> 1) ^ -(int)(x & 1); + + continue; + + /* at this point we've eaten up all the whole words */ process_tail: - do { - if(0) { + do { + if (0) { incomplete_msbs: - br->consumed_bits = 0; - br->consumed_words = cwords; - } - - /* read the unary MSBs and end bit */ - if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) - return false; - msbs += x; - x = ucbits = 0; - - if(0) { + br->consumed_bits = 0; + br->consumed_words = cwords; + } + + /* read the unary MSBs and end bit */ + if (!FLAC__bitreader_read_unary_unsigned(br, &msbs)) { + return false; + } + msbs += x; + x = ucbits = 0; + + if (0) { incomplete_lsbs: - br->consumed_bits = 0; - br->consumed_words = cwords; - } - - /* read the binary LSBs */ - if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, parameter - ucbits)) - return false; - lsbs = x | lsbs; - - /* compose the value */ - x = (msbs << parameter) | lsbs; - *val++ = (int)(x >> 1) ^ -(int)(x & 1); - x = 0; - - cwords = br->consumed_words; - words = br->words; - ucbits = FLAC__BITS_PER_WORD - br->consumed_bits; - b = br->buffer[cwords] << br->consumed_bits; - } while(cwords >= words && val < end); - } - - if(ucbits == 0 && cwords < words) { - /* don't leave the head word with no unconsumed bits */ - crc16_update_word_(br, br->buffer[cwords++]); - ucbits = FLAC__BITS_PER_WORD; - } - - br->consumed_bits = FLAC__BITS_PER_WORD - ucbits; - br->consumed_words = cwords; - - return true; + br->consumed_bits = 0; + br->consumed_words = cwords; + } + + /* read the binary LSBs */ + if (!FLAC__bitreader_read_raw_uint32(br, &lsbs, parameter - ucbits)) { + return false; + } + lsbs = x | lsbs; + + /* compose the value */ + x = (msbs << parameter) | lsbs; + *val++ = (int)(x >> 1) ^ -(int)(x & 1); + x = 0; + + cwords = br->consumed_words; + words = br->words; + ucbits = FLAC__BITS_PER_WORD - br->consumed_bits; + b = br->buffer[cwords] << br->consumed_bits; + } while (cwords >= words && val < end); + } + + if (ucbits == 0 && cwords < words) { + /* don't leave the head word with no unconsumed bits */ + crc16_update_word_(br, br->buffer[cwords++]); + ucbits = FLAC__BITS_PER_WORD; + } + + br->consumed_bits = FLAC__BITS_PER_WORD - ucbits; + br->consumed_words = cwords; + + return true; } #if 0 /* UNUSED */ -FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, uint32_t parameter) -{ - FLAC__uint32 lsbs = 0, msbs = 0; - uint32_t bit, uval, k; - - FLAC__ASSERT(0 != br); - FLAC__ASSERT(0 != br->buffer); - - k = FLAC__bitmath_ilog2(parameter); - - /* read the unary MSBs and end bit */ - if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) - return false; - - /* read the binary LSBs */ - if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, k)) - return false; - - if(parameter == 1u<= d) { - if(!FLAC__bitreader_read_bit(br, &bit)) - return false; - lsbs <<= 1; - lsbs |= bit; - lsbs -= d; - } - /* compose the value */ - uval = msbs * parameter + lsbs; - } - - /* unfold uint32_t to signed */ - if(uval & 1) - *val = -((int)(uval >> 1)) - 1; - else - *val = (int)(uval >> 1); - - return true; +FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, uint32_t parameter) { + FLAC__uint32 lsbs = 0, msbs = 0; + uint32_t bit, uval, k; + + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + + k = FLAC__bitmath_ilog2(parameter); + + /* read the unary MSBs and end bit */ + if (!FLAC__bitreader_read_unary_unsigned(br, &msbs)) { + return false; + } + + /* read the binary LSBs */ + if (!FLAC__bitreader_read_raw_uint32(br, &lsbs, k)) { + return false; + } + + if (parameter == 1u << k) { + /* compose the value */ + uval = (msbs << k) | lsbs; + } else { + uint32_t d = (1 << (k + 1)) - parameter; + if (lsbs >= d) { + if (!FLAC__bitreader_read_bit(br, &bit)) { + return false; + } + lsbs <<= 1; + lsbs |= bit; + lsbs -= d; + } + /* compose the value */ + uval = msbs * parameter + lsbs; + } + + /* unfold uint32_t to signed */ + if (uval & 1) { + *val = -((int)(uval >> 1)) - 1; + } else { + *val = (int)(uval >> 1); + } + + return true; } -FLAC__bool FLAC__bitreader_read_golomb_unsigned(FLAC__BitReader *br, uint32_t *val, uint32_t parameter) -{ - FLAC__uint32 lsbs, msbs = 0; - uint32_t bit, k; - - FLAC__ASSERT(0 != br); - FLAC__ASSERT(0 != br->buffer); - - k = FLAC__bitmath_ilog2(parameter); - - /* read the unary MSBs and end bit */ - if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) - return false; - - /* read the binary LSBs */ - if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, k)) - return false; - - if(parameter == 1u<= d) { - if(!FLAC__bitreader_read_bit(br, &bit)) - return false; - lsbs <<= 1; - lsbs |= bit; - lsbs -= d; - } - /* compose the value */ - *val = msbs * parameter + lsbs; - } - - return true; +FLAC__bool FLAC__bitreader_read_golomb_unsigned(FLAC__BitReader *br, uint32_t *val, uint32_t parameter) { + FLAC__uint32 lsbs, msbs = 0; + uint32_t bit, k; + + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + + k = FLAC__bitmath_ilog2(parameter); + + /* read the unary MSBs and end bit */ + if (!FLAC__bitreader_read_unary_unsigned(br, &msbs)) { + return false; + } + + /* read the binary LSBs */ + if (!FLAC__bitreader_read_raw_uint32(br, &lsbs, k)) { + return false; + } + + if (parameter == 1u << k) { + /* compose the value */ + *val = (msbs << k) | lsbs; + } else { + uint32_t d = (1 << (k + 1)) - parameter; + if (lsbs >= d) { + if (!FLAC__bitreader_read_bit(br, &bit)) { + return false; + } + lsbs <<= 1; + lsbs |= bit; + lsbs -= d; + } + /* compose the value */ + *val = msbs * parameter + lsbs; + } + + return true; } #endif /* UNUSED */ /* on return, if *val == 0xffffffff then the utf-8 sequence was invalid, but the return value will be true */ -FLAC__bool FLAC__bitreader_read_utf8_uint32(FLAC__BitReader *br, FLAC__uint32 *val, FLAC__byte *raw, uint32_t *rawlen) -{ - FLAC__uint32 v = 0; - FLAC__uint32 x; - uint32_t i; - - if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) - return false; - if(raw) - raw[(*rawlen)++] = (FLAC__byte)x; - if(!(x & 0x80)) { /* 0xxxxxxx */ - v = x; - i = 0; - } - else if(x & 0xC0 && !(x & 0x20)) { /* 110xxxxx */ - v = x & 0x1F; - i = 1; - } - else if(x & 0xE0 && !(x & 0x10)) { /* 1110xxxx */ - v = x & 0x0F; - i = 2; - } - else if(x & 0xF0 && !(x & 0x08)) { /* 11110xxx */ - v = x & 0x07; - i = 3; - } - else if(x & 0xF8 && !(x & 0x04)) { /* 111110xx */ - v = x & 0x03; - i = 4; - } - else if(x & 0xFC && !(x & 0x02)) { /* 1111110x */ - v = x & 0x01; - i = 5; - } - else { - *val = 0xffffffff; - return true; - } - for( ; i; i--) { - if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) - return false; - if(raw) - raw[(*rawlen)++] = (FLAC__byte)x; - if(!(x & 0x80) || (x & 0x40)) { /* 10xxxxxx */ - *val = 0xffffffff; - return true; - } - v <<= 6; - v |= (x & 0x3F); - } - *val = v; - return true; +FLAC__bool FLAC__bitreader_read_utf8_uint32(FLAC__BitReader *br, FLAC__uint32 *val, FLAC__byte *raw, uint32_t *rawlen) { + FLAC__uint32 v = 0; + FLAC__uint32 x; + uint32_t i; + + if (!FLAC__bitreader_read_raw_uint32(br, &x, 8)) { + return false; + } + if (raw) { + raw[(*rawlen)++] = (FLAC__byte)x; + } + if (!(x & 0x80)) { /* 0xxxxxxx */ + v = x; + i = 0; + } else if (x & 0xC0 && !(x & 0x20)) { /* 110xxxxx */ + v = x & 0x1F; + i = 1; + } else if (x & 0xE0 && !(x & 0x10)) { /* 1110xxxx */ + v = x & 0x0F; + i = 2; + } else if (x & 0xF0 && !(x & 0x08)) { /* 11110xxx */ + v = x & 0x07; + i = 3; + } else if (x & 0xF8 && !(x & 0x04)) { /* 111110xx */ + v = x & 0x03; + i = 4; + } else if (x & 0xFC && !(x & 0x02)) { /* 1111110x */ + v = x & 0x01; + i = 5; + } else { + *val = 0xffffffff; + return true; + } + for (; i; i--) { + if (!FLAC__bitreader_read_raw_uint32(br, &x, 8)) { + return false; + } + if (raw) { + raw[(*rawlen)++] = (FLAC__byte)x; + } + if (!(x & 0x80) || (x & 0x40)) { /* 10xxxxxx */ + *val = 0xffffffff; + return true; + } + v <<= 6; + v |= (x & 0x3F); + } + *val = v; + return true; } /* on return, if *val == 0xffffffffffffffff then the utf-8 sequence was invalid, but the return value will be true */ -FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *val, FLAC__byte *raw, uint32_t *rawlen) -{ - FLAC__uint64 v = 0; - FLAC__uint32 x; - uint32_t i; - - if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) - return false; - if(raw) - raw[(*rawlen)++] = (FLAC__byte)x; - if(!(x & 0x80)) { /* 0xxxxxxx */ - v = x; - i = 0; - } - else if(x & 0xC0 && !(x & 0x20)) { /* 110xxxxx */ - v = x & 0x1F; - i = 1; - } - else if(x & 0xE0 && !(x & 0x10)) { /* 1110xxxx */ - v = x & 0x0F; - i = 2; - } - else if(x & 0xF0 && !(x & 0x08)) { /* 11110xxx */ - v = x & 0x07; - i = 3; - } - else if(x & 0xF8 && !(x & 0x04)) { /* 111110xx */ - v = x & 0x03; - i = 4; - } - else if(x & 0xFC && !(x & 0x02)) { /* 1111110x */ - v = x & 0x01; - i = 5; - } - else if(x & 0xFE && !(x & 0x01)) { /* 11111110 */ - v = 0; - i = 6; - } - else { - *val = FLAC__U64L(0xffffffffffffffff); - return true; - } - for( ; i; i--) { - if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) - return false; - if(raw) - raw[(*rawlen)++] = (FLAC__byte)x; - if(!(x & 0x80) || (x & 0x40)) { /* 10xxxxxx */ - *val = FLAC__U64L(0xffffffffffffffff); - return true; - } - v <<= 6; - v |= (x & 0x3F); - } - *val = v; - return true; +FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *val, FLAC__byte *raw, uint32_t *rawlen) { + FLAC__uint64 v = 0; + FLAC__uint32 x; + uint32_t i; + + if (!FLAC__bitreader_read_raw_uint32(br, &x, 8)) { + return false; + } + if (raw) { + raw[(*rawlen)++] = (FLAC__byte)x; + } + if (!(x & 0x80)) { /* 0xxxxxxx */ + v = x; + i = 0; + } else if (x & 0xC0 && !(x & 0x20)) { /* 110xxxxx */ + v = x & 0x1F; + i = 1; + } else if (x & 0xE0 && !(x & 0x10)) { /* 1110xxxx */ + v = x & 0x0F; + i = 2; + } else if (x & 0xF0 && !(x & 0x08)) { /* 11110xxx */ + v = x & 0x07; + i = 3; + } else if (x & 0xF8 && !(x & 0x04)) { /* 111110xx */ + v = x & 0x03; + i = 4; + } else if (x & 0xFC && !(x & 0x02)) { /* 1111110x */ + v = x & 0x01; + i = 5; + } else if (x & 0xFE && !(x & 0x01)) { /* 11111110 */ + v = 0; + i = 6; + } else { + *val = FLAC__U64L(0xffffffffffffffff); + return true; + } + for (; i; i--) { + if (!FLAC__bitreader_read_raw_uint32(br, &x, 8)) { + return false; + } + if (raw) { + raw[(*rawlen)++] = (FLAC__byte)x; + } + if (!(x & 0x80) || (x & 0x40)) { /* 10xxxxxx */ + *val = FLAC__U64L(0xffffffffffffffff); + return true; + } + v <<= 6; + v |= (x & 0x3F); + } + *val = v; + return true; } -/* These functions are declared inline in this file but are also callable as - * externs from elsewhere. - * According to the C99 spec, section 6.7.4, simply providing a function - * prototype in a header file without 'inline' and making the function inline - * in this file should be sufficient. - * Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To - * fix that we add extern declarations here. - */ +/* These functions are declared inline in this file but are also callable as + externs from elsewhere. + According to the C99 spec, section 6.7.4, simply providing a function + prototype in a header file without 'inline' and making the function inline + in this file should be sufficient. + Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To + fix that we add extern declarations here. +*/ extern FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br); extern uint32_t FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br); extern uint32_t FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br); diff --git a/src/libflac/config.h b/src/libflac/config.h index cf6c07df..edcb23e3 100644 --- a/src/libflac/config.h +++ b/src/libflac/config.h @@ -1,9 +1,11 @@ #define PGM_READ_UNALIGNED 0 #ifdef DEBUG - #undef NDEBUG +#undef NDEBUG #else - #define NDEBUG +#ifndef NDEBUG +#define NDEBUG +#endif #endif /* config.h. Generated from config.h.in by configure. */ @@ -151,7 +153,7 @@ #undef HAVE_X86INTRIN_H /* Define as const if the declaration of iconv() needs const. */ -#define ICONV_CONST +#define ICONV_CONST /* Define to the sub-directory where libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" @@ -231,15 +233,15 @@ /* Define to 1 if on MINIX. */ /* #undef _MINIX */ -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ /* #undef _POSIX_1_SOURCE */ /* Define to 1 if you need to in order for `stat' and other things to work. */ /* #undef _POSIX_SOURCE */ -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus /* #undef inline */ #endif diff --git a/src/libflac/cpu.c b/src/libflac/cpu.c index efed11b7..37e76aa3 100644 --- a/src/libflac/cpu.c +++ b/src/libflac/cpu.c @@ -1,37 +1,37 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2001-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ //#ifdef HAVE_CONFIG_H -# include +# include "config.h" //#endif #include "private/cpu.h" @@ -79,164 +79,162 @@ static const uint32_t FLAC__CPUINFO_X86_CPUID_FMA = 0x00001000; static const uint32_t FLAC__CPUINFO_X86_CPUID_AVX2 = 0x00000020; static uint32_t -cpu_xgetbv_x86(void) -{ +cpu_xgetbv_x86(void) { #if (defined _MSC_VER || defined __INTEL_COMPILER) && FLAC__AVX_SUPPORTED - return (uint32_t)_xgetbv(0); + return (uint32_t)_xgetbv(0); #elif defined __GNUC__ - uint32_t lo, hi; - __asm__ volatile (".byte 0x0f, 0x01, 0xd0" : "=a"(lo), "=d"(hi) : "c" (0)); - return lo; + uint32_t lo, hi; + __asm__ volatile(".byte 0x0f, 0x01, 0xd0" : "=a"(lo), "=d"(hi) : "c"(0)); + return lo; #else - return 0; + return 0; #endif } static uint32_t -cpu_have_cpuid(void) -{ +cpu_have_cpuid(void) { #if defined FLAC__CPU_X86_64 || defined __i686__ || defined __SSE__ || (defined _M_IX86_FP && _M_IX86_FP > 0) - /* target CPU does have CPUID instruction */ - return 1; + /* target CPU does have CPUID instruction */ + return 1; #elif defined FLAC__HAS_NASM - return FLAC__cpu_have_cpuid_asm_ia32(); + return FLAC__cpu_have_cpuid_asm_ia32(); #elif defined __GNUC__ && defined HAVE_CPUID_H - if (__get_cpuid_max(0, 0) != 0) - return 1; - else - return 0; + if (__get_cpuid_max(0, 0) != 0) { + return 1; + } else { + return 0; + } #elif defined _MSC_VER - FLAC__uint32 flags1, flags2; - __asm { - pushfd - pushfd - pop eax - mov flags1, eax - xor eax, 0x200000 - push eax - popfd - pushfd - pop eax - mov flags2, eax - popfd - } - if (((flags1^flags2) & 0x200000) != 0) - return 1; - else - return 0; + FLAC__uint32 flags1, flags2; + __asm { + pushfd + pushfd + pop eax + mov flags1, eax + xor eax, 0x200000 + push eax + popfd + pushfd + pop eax + mov flags2, eax + popfd + } + if (((flags1^flags2) & 0x200000) != 0) { + return 1; + } else { + return 0; + } #else - return 0; + return 0; #endif } static void -cpuinfo_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx) -{ +cpuinfo_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx) { #if defined _MSC_VER - int cpuinfo[4]; - int ext = level & 0x80000000; - __cpuid(cpuinfo, ext); - if ((uint32_t)cpuinfo[0] >= level) { + int cpuinfo[4]; + int ext = level & 0x80000000; + __cpuid(cpuinfo, ext); + if ((uint32_t)cpuinfo[0] >= level) { #if FLAC__AVX_SUPPORTED - __cpuidex(cpuinfo, level, 0); /* for AVX2 detection */ + __cpuidex(cpuinfo, level, 0); /* for AVX2 detection */ #else - __cpuid(cpuinfo, level); /* some old compilers don't support __cpuidex */ + __cpuid(cpuinfo, level); /* some old compilers don't support __cpuidex */ #endif - *eax = cpuinfo[0]; *ebx = cpuinfo[1]; *ecx = cpuinfo[2]; *edx = cpuinfo[3]; - return; - } + *eax = cpuinfo[0]; *ebx = cpuinfo[1]; *ecx = cpuinfo[2]; *edx = cpuinfo[3]; + return; + } #elif defined __GNUC__ && defined HAVE_CPUID_H - FLAC__uint32 ext = level & 0x80000000; - __cpuid(ext, *eax, *ebx, *ecx, *edx); - if (*eax >= level) { - __cpuid_count(level, 0, *eax, *ebx, *ecx, *edx); - return; - } + FLAC__uint32 ext = level & 0x80000000; + __cpuid(ext, *eax, *ebx, *ecx, *edx); + if (*eax >= level) { + __cpuid_count(level, 0, *eax, *ebx, *ecx, *edx); + return; + } #elif defined FLAC__HAS_NASM && defined FLAC__CPU_IA32 - FLAC__cpu_info_asm_ia32(level, eax, ebx, ecx, edx); - return; + FLAC__cpu_info_asm_ia32(level, eax, ebx, ecx, edx); + return; #endif - *eax = *ebx = *ecx = *edx = 0; + *eax = *ebx = *ecx = *edx = 0; } #endif static void -x86_cpu_info (FLAC__CPUInfo *info) -{ +x86_cpu_info(FLAC__CPUInfo *info) { #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && (defined FLAC__HAS_NASM || FLAC__HAS_X86INTRIN) && !defined FLAC__NO_ASM - FLAC__bool x86_osxsave = false; - FLAC__bool os_avx = false; - FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx; - - info->use_asm = true; /* we assume a minimum of 80386 */ - if (!cpu_have_cpuid()) - return; - - cpuinfo_x86(0, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); - info->x86.intel = (flags_ebx == 0x756E6547 && flags_edx == 0x49656E69 && flags_ecx == 0x6C65746E) ? true : false; /* GenuineIntel */ - cpuinfo_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); - - info->x86.cmov = (flags_edx & FLAC__CPUINFO_X86_CPUID_CMOV ) ? true : false; - info->x86.mmx = (flags_edx & FLAC__CPUINFO_X86_CPUID_MMX ) ? true : false; - info->x86.sse = (flags_edx & FLAC__CPUINFO_X86_CPUID_SSE ) ? true : false; - info->x86.sse2 = (flags_edx & FLAC__CPUINFO_X86_CPUID_SSE2 ) ? true : false; - info->x86.sse3 = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSE3 ) ? true : false; - info->x86.ssse3 = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSSE3) ? true : false; - info->x86.sse41 = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSE41) ? true : false; - info->x86.sse42 = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSE42) ? true : false; - - if (FLAC__AVX_SUPPORTED) { - x86_osxsave = (flags_ecx & FLAC__CPUINFO_X86_CPUID_OSXSAVE) ? true : false; - info->x86.avx = (flags_ecx & FLAC__CPUINFO_X86_CPUID_AVX ) ? true : false; - info->x86.fma = (flags_ecx & FLAC__CPUINFO_X86_CPUID_FMA ) ? true : false; - cpuinfo_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); - info->x86.avx2 = (flags_ebx & FLAC__CPUINFO_X86_CPUID_AVX2 ) ? true : false; - } + FLAC__bool x86_osxsave = false; + FLAC__bool os_avx = false; + FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx; + + info->use_asm = true; /* we assume a minimum of 80386 */ + if (!cpu_have_cpuid()) { + return; + } + + cpuinfo_x86(0, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); + info->x86.intel = (flags_ebx == 0x756E6547 && flags_edx == 0x49656E69 && flags_ecx == 0x6C65746E) ? true : false; /* GenuineIntel */ + cpuinfo_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); + + info->x86.cmov = (flags_edx & FLAC__CPUINFO_X86_CPUID_CMOV) ? true : false; + info->x86.mmx = (flags_edx & FLAC__CPUINFO_X86_CPUID_MMX) ? true : false; + info->x86.sse = (flags_edx & FLAC__CPUINFO_X86_CPUID_SSE) ? true : false; + info->x86.sse2 = (flags_edx & FLAC__CPUINFO_X86_CPUID_SSE2) ? true : false; + info->x86.sse3 = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSE3) ? true : false; + info->x86.ssse3 = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSSE3) ? true : false; + info->x86.sse41 = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSE41) ? true : false; + info->x86.sse42 = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSE42) ? true : false; + + if (FLAC__AVX_SUPPORTED) { + x86_osxsave = (flags_ecx & FLAC__CPUINFO_X86_CPUID_OSXSAVE) ? true : false; + info->x86.avx = (flags_ecx & FLAC__CPUINFO_X86_CPUID_AVX) ? true : false; + info->x86.fma = (flags_ecx & FLAC__CPUINFO_X86_CPUID_FMA) ? true : false; + cpuinfo_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); + info->x86.avx2 = (flags_ebx & FLAC__CPUINFO_X86_CPUID_AVX2) ? true : false; + } #if defined FLAC__CPU_IA32 - dfprintf(stderr, "CPU info (IA-32):\n"); + dfprintf(stderr, "CPU info (IA-32):\n"); #else - dfprintf(stderr, "CPU info (x86-64):\n"); + dfprintf(stderr, "CPU info (x86-64):\n"); #endif - dfprintf(stderr, " CMOV ....... %c\n", info->x86.cmov ? 'Y' : 'n'); - dfprintf(stderr, " MMX ........ %c\n", info->x86.mmx ? 'Y' : 'n'); - dfprintf(stderr, " SSE ........ %c\n", info->x86.sse ? 'Y' : 'n'); - dfprintf(stderr, " SSE2 ....... %c\n", info->x86.sse2 ? 'Y' : 'n'); - dfprintf(stderr, " SSE3 ....... %c\n", info->x86.sse3 ? 'Y' : 'n'); - dfprintf(stderr, " SSSE3 ...... %c\n", info->x86.ssse3 ? 'Y' : 'n'); - dfprintf(stderr, " SSE41 ...... %c\n", info->x86.sse41 ? 'Y' : 'n'); - dfprintf(stderr, " SSE42 ...... %c\n", info->x86.sse42 ? 'Y' : 'n'); - - if (FLAC__AVX_SUPPORTED) { - dfprintf(stderr, " AVX ........ %c\n", info->x86.avx ? 'Y' : 'n'); - dfprintf(stderr, " FMA ........ %c\n", info->x86.fma ? 'Y' : 'n'); - dfprintf(stderr, " AVX2 ....... %c\n", info->x86.avx2 ? 'Y' : 'n'); - } - - /* - * now have to check for OS support of AVX instructions - */ - if (FLAC__AVX_SUPPORTED && info->x86.avx && x86_osxsave && (cpu_xgetbv_x86() & 0x6) == 0x6) { - os_avx = true; - } - if (os_avx) { - dfprintf(stderr, " AVX OS sup . %c\n", info->x86.avx ? 'Y' : 'n'); - } - if (!os_avx) { - /* no OS AVX support */ - info->x86.avx = false; - info->x86.avx2 = false; - info->x86.fma = false; - } + dfprintf(stderr, " CMOV ....... %c\n", info->x86.cmov ? 'Y' : 'n'); + dfprintf(stderr, " MMX ........ %c\n", info->x86.mmx ? 'Y' : 'n'); + dfprintf(stderr, " SSE ........ %c\n", info->x86.sse ? 'Y' : 'n'); + dfprintf(stderr, " SSE2 ....... %c\n", info->x86.sse2 ? 'Y' : 'n'); + dfprintf(stderr, " SSE3 ....... %c\n", info->x86.sse3 ? 'Y' : 'n'); + dfprintf(stderr, " SSSE3 ...... %c\n", info->x86.ssse3 ? 'Y' : 'n'); + dfprintf(stderr, " SSE41 ...... %c\n", info->x86.sse41 ? 'Y' : 'n'); + dfprintf(stderr, " SSE42 ...... %c\n", info->x86.sse42 ? 'Y' : 'n'); + + if (FLAC__AVX_SUPPORTED) { + dfprintf(stderr, " AVX ........ %c\n", info->x86.avx ? 'Y' : 'n'); + dfprintf(stderr, " FMA ........ %c\n", info->x86.fma ? 'Y' : 'n'); + dfprintf(stderr, " AVX2 ....... %c\n", info->x86.avx2 ? 'Y' : 'n'); + } + + /* + now have to check for OS support of AVX instructions + */ + if (FLAC__AVX_SUPPORTED && info->x86.avx && x86_osxsave && (cpu_xgetbv_x86() & 0x6) == 0x6) { + os_avx = true; + } + if (os_avx) { + dfprintf(stderr, " AVX OS sup . %c\n", info->x86.avx ? 'Y' : 'n'); + } + if (!os_avx) { + /* no OS AVX support */ + info->x86.avx = false; + info->x86.avx2 = false; + info->x86.fma = false; + } #else - info->use_asm = false; + info->use_asm = false; #endif } static void -ppc_cpu_info (FLAC__CPUInfo *info) -{ +ppc_cpu_info(FLAC__CPUInfo *info) { #if defined FLAC__CPU_PPC #ifndef PPC_FEATURE2_ARCH_3_00 #define PPC_FEATURE2_ARCH_3_00 0x00800000 @@ -247,53 +245,52 @@ ppc_cpu_info (FLAC__CPUInfo *info) #endif #ifdef __linux__ - if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00) { - info->ppc.arch_3_00 = true; - } else if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) { - info->ppc.arch_2_07 = true; - } + if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00) { + info->ppc.arch_3_00 = true; + } else if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) { + info->ppc.arch_2_07 = true; + } #elif defined(__FreeBSD__) - long hwcaps; - elf_aux_info(AT_HWCAP2, &hwcaps, sizeof(hwcaps)); + long hwcaps; + elf_aux_info(AT_HWCAP2, &hwcaps, sizeof(hwcaps)); #else #error Unsupported platform! Please add support for reading ppc hwcaps. #endif - if (hwcaps & PPC_FEATURE2_ARCH_3_00) { - info->ppc.arch_3_00 = true; - } else if (hwcaps & PPC_FEATURE2_ARCH_2_07) { - info->ppc.arch_2_07 = true; - } + if (hwcaps & PPC_FEATURE2_ARCH_3_00) { + info->ppc.arch_3_00 = true; + } else if (hwcaps & PPC_FEATURE2_ARCH_2_07) { + info->ppc.arch_2_07 = true; + } #else - info->ppc.arch_2_07 = false; - info->ppc.arch_3_00 = false; + info->ppc.arch_2_07 = false; + info->ppc.arch_3_00 = false; #endif } -void FLAC__cpu_info (FLAC__CPUInfo *info) -{ - memset(info, 0, sizeof(*info)); +void FLAC__cpu_info(FLAC__CPUInfo *info) { + memset(info, 0, sizeof(*info)); #ifdef FLAC__CPU_IA32 - info->type = FLAC__CPUINFO_TYPE_IA32; + info->type = FLAC__CPUINFO_TYPE_IA32; #elif defined FLAC__CPU_X86_64 - info->type = FLAC__CPUINFO_TYPE_X86_64; + info->type = FLAC__CPUINFO_TYPE_X86_64; #elif defined FLAC__CPU_PPC - info->type = FLAC__CPUINFO_TYPE_PPC; + info->type = FLAC__CPUINFO_TYPE_PPC; #else - info->type = FLAC__CPUINFO_TYPE_UNKNOWN; + info->type = FLAC__CPUINFO_TYPE_UNKNOWN; #endif - switch (info->type) { - case FLAC__CPUINFO_TYPE_IA32: /* fallthrough */ - case FLAC__CPUINFO_TYPE_X86_64: - x86_cpu_info (info); - break; - case FLAC__CPUINFO_TYPE_PPC: - ppc_cpu_info (info); - break; - default: - info->use_asm = false; - break; - } + switch (info->type) { + case FLAC__CPUINFO_TYPE_IA32: /* fallthrough */ + case FLAC__CPUINFO_TYPE_X86_64: + x86_cpu_info(info); + break; + case FLAC__CPUINFO_TYPE_PPC: + ppc_cpu_info(info); + break; + default: + info->use_asm = false; + break; + } } diff --git a/src/libflac/crc.c b/src/libflac/crc.c index 1b531e3d..2ba9b56e 100644 --- a/src/libflac/crc.c +++ b/src/libflac/crc.c @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2000-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ //#ifdef HAVE_CONFIG_H # include "config.h" @@ -44,105 +44,106 @@ /* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */ FLAC__byte const FLAC__crc8_table[256] PROGMEM = { - 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, - 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D, - 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, - 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, - 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, - 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, - 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, - 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD, - 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, - 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, - 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, - 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, - 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, - 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A, - 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, - 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, - 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, - 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, - 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, - 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4, - 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, - 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, - 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, - 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, - 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, - 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63, - 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, - 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, - 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, - 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, - 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, - 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3 + 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, + 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D, + 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, + 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, + 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, + 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, + 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, + 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD, + 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, + 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, + 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, + 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, + 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, + 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A, + 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, + 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, + 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, + 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, + 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, + 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4, + 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, + 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, + 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, + 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, + 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, + 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63, + 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, + 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, + 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, + 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, + 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, + 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3 }; /* CRC-16, poly = x^16 + x^15 + x^2 + x^0, init = 0 */ unsigned const FLAC__crc16_table[256] PROGMEM = { - 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, - 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, - 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, - 0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041, - 0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2, - 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1, - 0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1, - 0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082, - 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192, - 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1, - 0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1, - 0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2, - 0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151, - 0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162, - 0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132, - 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101, - 0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312, - 0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321, - 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371, - 0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342, - 0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1, - 0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2, - 0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2, - 0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381, - 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291, - 0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2, - 0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2, - 0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1, - 0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252, - 0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261, - 0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231, - 0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202 + 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, + 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, + 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, + 0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041, + 0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2, + 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1, + 0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1, + 0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082, + 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192, + 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1, + 0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1, + 0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2, + 0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151, + 0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162, + 0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132, + 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101, + 0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312, + 0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321, + 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371, + 0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342, + 0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1, + 0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2, + 0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2, + 0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381, + 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291, + 0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2, + 0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2, + 0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1, + 0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252, + 0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261, + 0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231, + 0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202 }; -void FLAC__crc8_update(const FLAC__byte data, FLAC__uint8 *crc) -{ - *crc = pgm_read_byte(&FLAC__crc8_table[*crc ^ data]); +void FLAC__crc8_update(const FLAC__byte data, FLAC__uint8 *crc) { + *crc = pgm_read_byte(&FLAC__crc8_table[*crc ^ data]); } -void FLAC__crc8_update_block(const FLAC__byte *data, unsigned len, FLAC__uint8 *crc) -{ - while(len--) - *crc = pgm_read_byte(&FLAC__crc8_table[*crc ^ *data++]); +void FLAC__crc8_update_block(const FLAC__byte *data, unsigned len, FLAC__uint8 *crc) { + while (len--) { + *crc = pgm_read_byte(&FLAC__crc8_table[*crc ^ *data++]); + } } -FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len) -{ - FLAC__uint8 crc = 0; +FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len) { + FLAC__uint8 crc = 0; - while(len--) - crc = pgm_read_byte(&FLAC__crc8_table[crc ^ *data++]); + while (len--) { + crc = pgm_read_byte(&FLAC__crc8_table[crc ^ *data++]); + } - return crc; + return crc; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +unsigned FLAC__crc16(const FLAC__byte *data, unsigned len) { + unsigned crc = 0; -unsigned FLAC__crc16(const FLAC__byte *data, unsigned len) -{ - unsigned crc = 0; + while (len--) { + crc = ((crc << 8) ^ pgm_read_word(&FLAC__crc16_table[(crc >> 8) ^ *data++])) & 0xffff; + } - while(len--) - crc = ((crc<<8) ^ pgm_read_word(&FLAC__crc16_table[(crc>>8) ^ *data++])) & 0xffff; - - return crc; + return crc; } +#pragma GCC diagnostic pop diff --git a/src/libflac/fixed.c b/src/libflac/fixed.c index 567ae1ae..21cf2c75 100644 --- a/src/libflac/fixed.c +++ b/src/libflac/fixed.c @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2000-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ //#ifdef HAVE_CONFIG_H # include "config.h" @@ -50,348 +50,360 @@ #pragma GCC optimize ("O3") #ifdef FLAC__INTEGER_ONLY_LIBRARY -/* rbps stands for residual bits per sample - * - * (ln(2) * err) - * rbps = log (-----------) - * 2 ( n ) - */ -static FLAC__fixedpoint local__compute_rbps_integerized(FLAC__uint32 err, FLAC__uint32 n) -{ - FLAC__uint32 rbps; - uint32_t bits; /* the number of bits required to represent a number */ - int fracbits; /* the number of bits of rbps that comprise the fractional part */ - - FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint)); - FLAC__ASSERT(err > 0); - FLAC__ASSERT(n > 0); - - FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE); - if(err <= n) - return 0; - /* - * The above two things tell us 1) n fits in 16 bits; 2) err/n > 1. - * These allow us later to know we won't lose too much precision in the - * fixed-point division (err< 0); - bits = FLAC__bitmath_ilog2(err)+1; - if(bits > 16) { - err >>= (bits-16); - fracbits -= (bits-16); - } - rbps = (FLAC__uint32)err; - - /* Multiply by fixed-point version of ln(2), with 16 fractional bits */ - rbps *= FLAC__FP_LN2; - fracbits += 16; - FLAC__ASSERT(fracbits >= 0); - - /* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */ - { - const int f = fracbits & 3; - if(f) { - rbps >>= f; - fracbits -= f; - } - } - - rbps = FLAC__fixedpoint_log2(rbps, fracbits, (uint32_t)(-1)); - - if(rbps == 0) - return 0; - - /* - * The return value must have 16 fractional bits. Since the whole part - * of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits - * must be >= -3, these assertion allows us to be able to shift rbps - * left if necessary to get 16 fracbits without losing any bits of the - * whole part of rbps. - * - * There is a slight chance due to accumulated error that the whole part - * will require 6 bits, so we use 6 in the assertion. Really though as - * long as it fits in 13 bits (32 - (16 - (-3))) we are fine. - */ - FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6); - FLAC__ASSERT(fracbits >= -3); - - /* now shift the decimal point into place */ - if(fracbits < 16) - return rbps << (16-fracbits); - else if(fracbits > 16) - return rbps >> (fracbits-16); - else - return rbps; +/* rbps stands for residual bits per sample + + (ln(2) * err) + rbps = log (-----------) + 2 ( n ) +*/ +static FLAC__fixedpoint local__compute_rbps_integerized(FLAC__uint32 err, FLAC__uint32 n) { + FLAC__uint32 rbps; + uint32_t bits; /* the number of bits required to represent a number */ + int fracbits; /* the number of bits of rbps that comprise the fractional part */ + + FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint)); + FLAC__ASSERT(err > 0); + FLAC__ASSERT(n > 0); + + FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE); + if (err <= n) { + return 0; + } + /* + The above two things tell us 1) n fits in 16 bits; 2) err/n > 1. + These allow us later to know we won't lose too much precision in the + fixed-point division (err< 0); + bits = FLAC__bitmath_ilog2(err) + 1; + if (bits > 16) { + err >>= (bits - 16); + fracbits -= (bits - 16); + } + rbps = (FLAC__uint32)err; + + /* Multiply by fixed-point version of ln(2), with 16 fractional bits */ + rbps *= FLAC__FP_LN2; + fracbits += 16; + FLAC__ASSERT(fracbits >= 0); + + /* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */ + { + const int f = fracbits & 3; + if (f) { + rbps >>= f; + fracbits -= f; + } + } + + rbps = FLAC__fixedpoint_log2(rbps, fracbits, (uint32_t)(-1)); + + if (rbps == 0) { + return 0; + } + + /* + The return value must have 16 fractional bits. Since the whole part + of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits + must be >= -3, these assertion allows us to be able to shift rbps + left if necessary to get 16 fracbits without losing any bits of the + whole part of rbps. + + There is a slight chance due to accumulated error that the whole part + will require 6 bits, so we use 6 in the assertion. Really though as + long as it fits in 13 bits (32 - (16 - (-3))) we are fine. + */ + FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps) + 1 <= fracbits + 6); + FLAC__ASSERT(fracbits >= -3); + + /* now shift the decimal point into place */ + if (fracbits < 16) { + return rbps << (16 - fracbits); + } else if (fracbits > 16) { + return rbps >> (fracbits - 16); + } else { + return rbps; + } } -static FLAC__fixedpoint local__compute_rbps_wide_integerized(FLAC__uint64 err, FLAC__uint32 n) -{ - FLAC__uint32 rbps; - uint32_t bits; /* the number of bits required to represent a number */ - int fracbits; /* the number of bits of rbps that comprise the fractional part */ - - FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint)); - FLAC__ASSERT(err > 0); - FLAC__ASSERT(n > 0); - - FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE); - if(err <= n) - return 0; - /* - * The above two things tell us 1) n fits in 16 bits; 2) err/n > 1. - * These allow us later to know we won't lose too much precision in the - * fixed-point division (err< 0); - bits = FLAC__bitmath_ilog2_wide(err)+1; - if(bits > 16) { - err >>= (bits-16); - fracbits -= (bits-16); - } - rbps = (FLAC__uint32)err; - - /* Multiply by fixed-point version of ln(2), with 16 fractional bits */ - rbps *= FLAC__FP_LN2; - fracbits += 16; - FLAC__ASSERT(fracbits >= 0); - - /* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */ - { - const int f = fracbits & 3; - if(f) { - rbps >>= f; - fracbits -= f; - } - } - - rbps = FLAC__fixedpoint_log2(rbps, fracbits, (uint32_t)(-1)); - - if(rbps == 0) - return 0; - - /* - * The return value must have 16 fractional bits. Since the whole part - * of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits - * must be >= -3, these assertion allows us to be able to shift rbps - * left if necessary to get 16 fracbits without losing any bits of the - * whole part of rbps. - * - * There is a slight chance due to accumulated error that the whole part - * will require 6 bits, so we use 6 in the assertion. Really though as - * long as it fits in 13 bits (32 - (16 - (-3))) we are fine. - */ - FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6); - FLAC__ASSERT(fracbits >= -3); - - /* now shift the decimal point into place */ - if(fracbits < 16) - return rbps << (16-fracbits); - else if(fracbits > 16) - return rbps >> (fracbits-16); - else - return rbps; +static FLAC__fixedpoint local__compute_rbps_wide_integerized(FLAC__uint64 err, FLAC__uint32 n) { + FLAC__uint32 rbps; + uint32_t bits; /* the number of bits required to represent a number */ + int fracbits; /* the number of bits of rbps that comprise the fractional part */ + + FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint)); + FLAC__ASSERT(err > 0); + FLAC__ASSERT(n > 0); + + FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE); + if (err <= n) { + return 0; + } + /* + The above two things tell us 1) n fits in 16 bits; 2) err/n > 1. + These allow us later to know we won't lose too much precision in the + fixed-point division (err< 0); + bits = FLAC__bitmath_ilog2_wide(err) + 1; + if (bits > 16) { + err >>= (bits - 16); + fracbits -= (bits - 16); + } + rbps = (FLAC__uint32)err; + + /* Multiply by fixed-point version of ln(2), with 16 fractional bits */ + rbps *= FLAC__FP_LN2; + fracbits += 16; + FLAC__ASSERT(fracbits >= 0); + + /* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */ + { + const int f = fracbits & 3; + if (f) { + rbps >>= f; + fracbits -= f; + } + } + + rbps = FLAC__fixedpoint_log2(rbps, fracbits, (uint32_t)(-1)); + + if (rbps == 0) { + return 0; + } + + /* + The return value must have 16 fractional bits. Since the whole part + of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits + must be >= -3, these assertion allows us to be able to shift rbps + left if necessary to get 16 fracbits without losing any bits of the + whole part of rbps. + + There is a slight chance due to accumulated error that the whole part + will require 6 bits, so we use 6 in the assertion. Really though as + long as it fits in 13 bits (32 - (16 - (-3))) we are fine. + */ + FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps) + 1 <= fracbits + 6); + FLAC__ASSERT(fracbits >= -3); + + /* now shift the decimal point into place */ + if (fracbits < 16) { + return rbps << (16 - fracbits); + } else if (fracbits > 16) { + return rbps >> (fracbits - 16); + } else { + return rbps; + } } #endif #ifndef FLAC__INTEGER_ONLY_LIBRARY -uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) +uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]) #else -uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) +uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]) #endif { - FLAC__int32 last_error_0 = data[-1]; - FLAC__int32 last_error_1 = data[-1] - data[-2]; - FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]); - FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]); - FLAC__int32 error, save; - FLAC__uint32 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0; - uint32_t i, order; - - for(i = 0; i < data_len; i++) { - error = data[i] ; total_error_0 += local_abs(error); save = error; - error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error; - error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error; - error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error; - error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; - } - - if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) - order = 0; - else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) - order = 1; - else if(total_error_2 < flac_min(total_error_3, total_error_4)) - order = 2; - else if(total_error_3 < total_error_4) - order = 3; - else - order = 4; - - /* Estimate the expected number of bits per residual signal sample. */ - /* 'total_error*' is linearly related to the variance of the residual */ - /* signal, so we use it directly to compute E(|x|) */ - FLAC__ASSERT(data_len > 0 || total_error_0 == 0); - FLAC__ASSERT(data_len > 0 || total_error_1 == 0); - FLAC__ASSERT(data_len > 0 || total_error_2 == 0); - FLAC__ASSERT(data_len > 0 || total_error_3 == 0); - FLAC__ASSERT(data_len > 0 || total_error_4 == 0); + FLAC__int32 last_error_0 = data[-1]; + FLAC__int32 last_error_1 = data[-1] - data[-2]; + FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]); + FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2 * data[-3] + data[-4]); + FLAC__int32 error, save; + FLAC__uint32 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0; + uint32_t i, order; + + for (i = 0; i < data_len; i++) { + error = data[i] ; total_error_0 += local_abs(error); save = error; + error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error; + error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error; + error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error; + error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; + } + + if (total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) { + order = 0; + } else if (total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) { + order = 1; + } else if (total_error_2 < flac_min(total_error_3, total_error_4)) { + order = 2; + } else if (total_error_3 < total_error_4) { + order = 3; + } else { + order = 4; + } + + /* Estimate the expected number of bits per residual signal sample. */ + /* 'total_error*' is linearly related to the variance of the residual */ + /* signal, so we use it directly to compute E(|x|) */ + FLAC__ASSERT(data_len > 0 || total_error_0 == 0); + FLAC__ASSERT(data_len > 0 || total_error_1 == 0); + FLAC__ASSERT(data_len > 0 || total_error_2 == 0); + FLAC__ASSERT(data_len > 0 || total_error_3 == 0); + FLAC__ASSERT(data_len > 0 || total_error_4 == 0); #ifndef FLAC__INTEGER_ONLY_LIBRARY - residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); - residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); - residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); - residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); - residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); #else - residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_integerized(total_error_0, data_len) : 0; - residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_integerized(total_error_1, data_len) : 0; - residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_integerized(total_error_2, data_len) : 0; - residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_integerized(total_error_3, data_len) : 0; - residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_integerized(total_error_4, data_len) : 0; + residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_integerized(total_error_0, data_len) : 0; + residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_integerized(total_error_1, data_len) : 0; + residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_integerized(total_error_2, data_len) : 0; + residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_integerized(total_error_3, data_len) : 0; + residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_integerized(total_error_4, data_len) : 0; #endif - return order; + return order; } #ifndef FLAC__INTEGER_ONLY_LIBRARY -uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) +uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]) #else -uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) +uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]) #endif { - FLAC__int32 last_error_0 = data[-1]; - FLAC__int32 last_error_1 = data[-1] - data[-2]; - FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]); - FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]); - FLAC__int32 error, save; - /* total_error_* are 64-bits to avoid overflow when encoding - * erratic signals when the bits-per-sample and blocksize are - * large. - */ - FLAC__uint64 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0; - uint32_t i, order; - - for(i = 0; i < data_len; i++) { - error = data[i] ; total_error_0 += local_abs(error); save = error; - error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error; - error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error; - error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error; - error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; - } - - if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) - order = 0; - else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) - order = 1; - else if(total_error_2 < flac_min(total_error_3, total_error_4)) - order = 2; - else if(total_error_3 < total_error_4) - order = 3; - else - order = 4; - - /* Estimate the expected number of bits per residual signal sample. */ - /* 'total_error*' is linearly related to the variance of the residual */ - /* signal, so we use it directly to compute E(|x|) */ - FLAC__ASSERT(data_len > 0 || total_error_0 == 0); - FLAC__ASSERT(data_len > 0 || total_error_1 == 0); - FLAC__ASSERT(data_len > 0 || total_error_2 == 0); - FLAC__ASSERT(data_len > 0 || total_error_3 == 0); - FLAC__ASSERT(data_len > 0 || total_error_4 == 0); + FLAC__int32 last_error_0 = data[-1]; + FLAC__int32 last_error_1 = data[-1] - data[-2]; + FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]); + FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2 * data[-3] + data[-4]); + FLAC__int32 error, save; + /* total_error_* are 64-bits to avoid overflow when encoding + erratic signals when the bits-per-sample and blocksize are + large. + */ + FLAC__uint64 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0; + uint32_t i, order; + + for (i = 0; i < data_len; i++) { + error = data[i] ; total_error_0 += local_abs(error); save = error; + error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error; + error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error; + error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error; + error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; + } + + if (total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) { + order = 0; + } else if (total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) { + order = 1; + } else if (total_error_2 < flac_min(total_error_3, total_error_4)) { + order = 2; + } else if (total_error_3 < total_error_4) { + order = 3; + } else { + order = 4; + } + + /* Estimate the expected number of bits per residual signal sample. */ + /* 'total_error*' is linearly related to the variance of the residual */ + /* signal, so we use it directly to compute E(|x|) */ + FLAC__ASSERT(data_len > 0 || total_error_0 == 0); + FLAC__ASSERT(data_len > 0 || total_error_1 == 0); + FLAC__ASSERT(data_len > 0 || total_error_2 == 0); + FLAC__ASSERT(data_len > 0 || total_error_3 == 0); + FLAC__ASSERT(data_len > 0 || total_error_4 == 0); #ifndef FLAC__INTEGER_ONLY_LIBRARY - residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); - residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); - residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); - residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); - residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); + residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); #else - residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_wide_integerized(total_error_0, data_len) : 0; - residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_wide_integerized(total_error_1, data_len) : 0; - residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_wide_integerized(total_error_2, data_len) : 0; - residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_wide_integerized(total_error_3, data_len) : 0; - residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_wide_integerized(total_error_4, data_len) : 0; + residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_wide_integerized(total_error_0, data_len) : 0; + residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_wide_integerized(total_error_1, data_len) : 0; + residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_wide_integerized(total_error_2, data_len) : 0; + residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_wide_integerized(total_error_3, data_len) : 0; + residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_wide_integerized(total_error_4, data_len) : 0; #endif - return order; + return order; } -void FLAC__fixed_compute_residual(const FLAC__int32 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[]) -{ - const int idata_len = (int)data_len; - int i; - - switch(order) { - case 0: - FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0])); - memcpy(residual, data, sizeof(residual[0])*data_len); - break; - case 1: - for(i = 0; i < idata_len; i++) - residual[i] = data[i] - data[i-1]; - break; - case 2: - for(i = 0; i < idata_len; i++) - residual[i] = data[i] - 2*data[i-1] + data[i-2]; - break; - case 3: - for(i = 0; i < idata_len; i++) - residual[i] = data[i] - 3*data[i-1] + 3*data[i-2] - data[i-3]; - break; - case 4: - for(i = 0; i < idata_len; i++) - residual[i] = data[i] - 4*data[i-1] + 6*data[i-2] - 4*data[i-3] + data[i-4]; - break; - default: - FLAC__ASSERT(0); - } +void FLAC__fixed_compute_residual(const FLAC__int32 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[]) { + const int idata_len = (int)data_len; + int i; + + switch (order) { + case 0: + FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0])); + memcpy(residual, data, sizeof(residual[0])*data_len); + break; + case 1: + for (i = 0; i < idata_len; i++) { + residual[i] = data[i] - data[i - 1]; + } + break; + case 2: + for (i = 0; i < idata_len; i++) { + residual[i] = data[i] - 2 * data[i - 1] + data[i - 2]; + } + break; + case 3: + for (i = 0; i < idata_len; i++) { + residual[i] = data[i] - 3 * data[i - 1] + 3 * data[i - 2] - data[i - 3]; + } + break; + case 4: + for (i = 0; i < idata_len; i++) { + residual[i] = data[i] - 4 * data[i - 1] + 6 * data[i - 2] - 4 * data[i - 3] + data[i - 4]; + } + break; + default: + FLAC__ASSERT(0); + } } -void FLAC__fixed_restore_signal(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int32 data[]) -{ - int i, idata_len = (int)data_len; - - switch(order) { - case 0: - FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0])); - memcpy(data, residual, sizeof(residual[0])*data_len); - break; - case 1: - for(i = 0; i < idata_len; i++) - data[i] = residual[i] + data[i-1]; - break; - case 2: - for(i = 0; i < idata_len; i++) - data[i] = residual[i] + 2*data[i-1] - data[i-2]; - break; - case 3: - for(i = 0; i < idata_len; i++) - data[i] = residual[i] + 3*data[i-1] - 3*data[i-2] + data[i-3]; - break; - case 4: - for(i = 0; i < idata_len; i++) - data[i] = residual[i] + 4*data[i-1] - 6*data[i-2] + 4*data[i-3] - data[i-4]; - break; - default: - FLAC__ASSERT(0); - } +void FLAC__fixed_restore_signal(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int32 data[]) { + int i, idata_len = (int)data_len; + + switch (order) { + case 0: + FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0])); + memcpy(data, residual, sizeof(residual[0])*data_len); + break; + case 1: + for (i = 0; i < idata_len; i++) { + data[i] = residual[i] + data[i - 1]; + } + break; + case 2: + for (i = 0; i < idata_len; i++) { + data[i] = residual[i] + 2 * data[i - 1] - data[i - 2]; + } + break; + case 3: + for (i = 0; i < idata_len; i++) { + data[i] = residual[i] + 3 * data[i - 1] - 3 * data[i - 2] + data[i - 3]; + } + break; + case 4: + for (i = 0; i < idata_len; i++) { + data[i] = residual[i] + 4 * data[i - 1] - 6 * data[i - 2] + 4 * data[i - 3] - data[i - 4]; + } + break; + default: + FLAC__ASSERT(0); + } } diff --git a/src/libflac/float.c b/src/libflac/float.c index 48b79133..bbba59e5 100644 --- a/src/libflac/float.c +++ b/src/libflac/float.c @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2004-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2004-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ //#ifdef HAVE_CONFIG_H # include "config.h" @@ -51,254 +51,254 @@ const FLAC__fixedpoint FLAC__FP_E = 178145; /* Lookup tables for Knuth's logarithm algorithm */ #define LOG2_LOOKUP_PRECISION 16 static const FLAC__uint32 log2_lookup[][LOG2_LOOKUP_PRECISION] PROGMEM = { - { - /* - * 0 fraction bits - */ - /* undefined */ 0x00000000, - /* lg(2/1) = */ 0x00000001, - /* lg(4/3) = */ 0x00000000, - /* lg(8/7) = */ 0x00000000, - /* lg(16/15) = */ 0x00000000, - /* lg(32/31) = */ 0x00000000, - /* lg(64/63) = */ 0x00000000, - /* lg(128/127) = */ 0x00000000, - /* lg(256/255) = */ 0x00000000, - /* lg(512/511) = */ 0x00000000, - /* lg(1024/1023) = */ 0x00000000, - /* lg(2048/2047) = */ 0x00000000, - /* lg(4096/4095) = */ 0x00000000, - /* lg(8192/8191) = */ 0x00000000, - /* lg(16384/16383) = */ 0x00000000, - /* lg(32768/32767) = */ 0x00000000 - }, - { - /* - * 4 fraction bits - */ - /* undefined */ 0x00000000, - /* lg(2/1) = */ 0x00000010, - /* lg(4/3) = */ 0x00000007, - /* lg(8/7) = */ 0x00000003, - /* lg(16/15) = */ 0x00000001, - /* lg(32/31) = */ 0x00000001, - /* lg(64/63) = */ 0x00000000, - /* lg(128/127) = */ 0x00000000, - /* lg(256/255) = */ 0x00000000, - /* lg(512/511) = */ 0x00000000, - /* lg(1024/1023) = */ 0x00000000, - /* lg(2048/2047) = */ 0x00000000, - /* lg(4096/4095) = */ 0x00000000, - /* lg(8192/8191) = */ 0x00000000, - /* lg(16384/16383) = */ 0x00000000, - /* lg(32768/32767) = */ 0x00000000 - }, - { - /* - * 8 fraction bits - */ - /* undefined */ 0x00000000, - /* lg(2/1) = */ 0x00000100, - /* lg(4/3) = */ 0x0000006a, - /* lg(8/7) = */ 0x00000031, - /* lg(16/15) = */ 0x00000018, - /* lg(32/31) = */ 0x0000000c, - /* lg(64/63) = */ 0x00000006, - /* lg(128/127) = */ 0x00000003, - /* lg(256/255) = */ 0x00000001, - /* lg(512/511) = */ 0x00000001, - /* lg(1024/1023) = */ 0x00000000, - /* lg(2048/2047) = */ 0x00000000, - /* lg(4096/4095) = */ 0x00000000, - /* lg(8192/8191) = */ 0x00000000, - /* lg(16384/16383) = */ 0x00000000, - /* lg(32768/32767) = */ 0x00000000 - }, - { - /* - * 12 fraction bits - */ - /* undefined */ 0x00000000, - /* lg(2/1) = */ 0x00001000, - /* lg(4/3) = */ 0x000006a4, - /* lg(8/7) = */ 0x00000315, - /* lg(16/15) = */ 0x0000017d, - /* lg(32/31) = */ 0x000000bc, - /* lg(64/63) = */ 0x0000005d, - /* lg(128/127) = */ 0x0000002e, - /* lg(256/255) = */ 0x00000017, - /* lg(512/511) = */ 0x0000000c, - /* lg(1024/1023) = */ 0x00000006, - /* lg(2048/2047) = */ 0x00000003, - /* lg(4096/4095) = */ 0x00000001, - /* lg(8192/8191) = */ 0x00000001, - /* lg(16384/16383) = */ 0x00000000, - /* lg(32768/32767) = */ 0x00000000 - }, - { - /* - * 16 fraction bits - */ - /* undefined */ 0x00000000, - /* lg(2/1) = */ 0x00010000, - /* lg(4/3) = */ 0x00006a40, - /* lg(8/7) = */ 0x00003151, - /* lg(16/15) = */ 0x000017d6, - /* lg(32/31) = */ 0x00000bba, - /* lg(64/63) = */ 0x000005d1, - /* lg(128/127) = */ 0x000002e6, - /* lg(256/255) = */ 0x00000172, - /* lg(512/511) = */ 0x000000b9, - /* lg(1024/1023) = */ 0x0000005c, - /* lg(2048/2047) = */ 0x0000002e, - /* lg(4096/4095) = */ 0x00000017, - /* lg(8192/8191) = */ 0x0000000c, - /* lg(16384/16383) = */ 0x00000006, - /* lg(32768/32767) = */ 0x00000003 - }, - { - /* - * 20 fraction bits - */ - /* undefined */ 0x00000000, - /* lg(2/1) = */ 0x00100000, - /* lg(4/3) = */ 0x0006a3fe, - /* lg(8/7) = */ 0x00031513, - /* lg(16/15) = */ 0x00017d60, - /* lg(32/31) = */ 0x0000bb9d, - /* lg(64/63) = */ 0x00005d10, - /* lg(128/127) = */ 0x00002e59, - /* lg(256/255) = */ 0x00001721, - /* lg(512/511) = */ 0x00000b8e, - /* lg(1024/1023) = */ 0x000005c6, - /* lg(2048/2047) = */ 0x000002e3, - /* lg(4096/4095) = */ 0x00000171, - /* lg(8192/8191) = */ 0x000000b9, - /* lg(16384/16383) = */ 0x0000005c, - /* lg(32768/32767) = */ 0x0000002e - }, - { - /* - * 24 fraction bits - */ - /* undefined */ 0x00000000, - /* lg(2/1) = */ 0x01000000, - /* lg(4/3) = */ 0x006a3fe6, - /* lg(8/7) = */ 0x00315130, - /* lg(16/15) = */ 0x0017d605, - /* lg(32/31) = */ 0x000bb9ca, - /* lg(64/63) = */ 0x0005d0fc, - /* lg(128/127) = */ 0x0002e58f, - /* lg(256/255) = */ 0x0001720e, - /* lg(512/511) = */ 0x0000b8d8, - /* lg(1024/1023) = */ 0x00005c61, - /* lg(2048/2047) = */ 0x00002e2d, - /* lg(4096/4095) = */ 0x00001716, - /* lg(8192/8191) = */ 0x00000b8b, - /* lg(16384/16383) = */ 0x000005c5, - /* lg(32768/32767) = */ 0x000002e3 - }, - { - /* - * 28 fraction bits - */ - /* undefined */ 0x00000000, - /* lg(2/1) = */ 0x10000000, - /* lg(4/3) = */ 0x06a3fe5c, - /* lg(8/7) = */ 0x03151301, - /* lg(16/15) = */ 0x017d6049, - /* lg(32/31) = */ 0x00bb9ca6, - /* lg(64/63) = */ 0x005d0fba, - /* lg(128/127) = */ 0x002e58f7, - /* lg(256/255) = */ 0x001720da, - /* lg(512/511) = */ 0x000b8d87, - /* lg(1024/1023) = */ 0x0005c60b, - /* lg(2048/2047) = */ 0x0002e2d7, - /* lg(4096/4095) = */ 0x00017160, - /* lg(8192/8191) = */ 0x0000b8ad, - /* lg(16384/16383) = */ 0x00005c56, - /* lg(32768/32767) = */ 0x00002e2b - } + { + /* + 0 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ 0x00000001, + /* lg(4/3) = */ 0x00000000, + /* lg(8/7) = */ 0x00000000, + /* lg(16/15) = */ 0x00000000, + /* lg(32/31) = */ 0x00000000, + /* lg(64/63) = */ 0x00000000, + /* lg(128/127) = */ 0x00000000, + /* lg(256/255) = */ 0x00000000, + /* lg(512/511) = */ 0x00000000, + /* lg(1024/1023) = */ 0x00000000, + /* lg(2048/2047) = */ 0x00000000, + /* lg(4096/4095) = */ 0x00000000, + /* lg(8192/8191) = */ 0x00000000, + /* lg(16384/16383) = */ 0x00000000, + /* lg(32768/32767) = */ 0x00000000 + }, + { + /* + 4 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ 0x00000010, + /* lg(4/3) = */ 0x00000007, + /* lg(8/7) = */ 0x00000003, + /* lg(16/15) = */ 0x00000001, + /* lg(32/31) = */ 0x00000001, + /* lg(64/63) = */ 0x00000000, + /* lg(128/127) = */ 0x00000000, + /* lg(256/255) = */ 0x00000000, + /* lg(512/511) = */ 0x00000000, + /* lg(1024/1023) = */ 0x00000000, + /* lg(2048/2047) = */ 0x00000000, + /* lg(4096/4095) = */ 0x00000000, + /* lg(8192/8191) = */ 0x00000000, + /* lg(16384/16383) = */ 0x00000000, + /* lg(32768/32767) = */ 0x00000000 + }, + { + /* + 8 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ 0x00000100, + /* lg(4/3) = */ 0x0000006a, + /* lg(8/7) = */ 0x00000031, + /* lg(16/15) = */ 0x00000018, + /* lg(32/31) = */ 0x0000000c, + /* lg(64/63) = */ 0x00000006, + /* lg(128/127) = */ 0x00000003, + /* lg(256/255) = */ 0x00000001, + /* lg(512/511) = */ 0x00000001, + /* lg(1024/1023) = */ 0x00000000, + /* lg(2048/2047) = */ 0x00000000, + /* lg(4096/4095) = */ 0x00000000, + /* lg(8192/8191) = */ 0x00000000, + /* lg(16384/16383) = */ 0x00000000, + /* lg(32768/32767) = */ 0x00000000 + }, + { + /* + 12 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ 0x00001000, + /* lg(4/3) = */ 0x000006a4, + /* lg(8/7) = */ 0x00000315, + /* lg(16/15) = */ 0x0000017d, + /* lg(32/31) = */ 0x000000bc, + /* lg(64/63) = */ 0x0000005d, + /* lg(128/127) = */ 0x0000002e, + /* lg(256/255) = */ 0x00000017, + /* lg(512/511) = */ 0x0000000c, + /* lg(1024/1023) = */ 0x00000006, + /* lg(2048/2047) = */ 0x00000003, + /* lg(4096/4095) = */ 0x00000001, + /* lg(8192/8191) = */ 0x00000001, + /* lg(16384/16383) = */ 0x00000000, + /* lg(32768/32767) = */ 0x00000000 + }, + { + /* + 16 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ 0x00010000, + /* lg(4/3) = */ 0x00006a40, + /* lg(8/7) = */ 0x00003151, + /* lg(16/15) = */ 0x000017d6, + /* lg(32/31) = */ 0x00000bba, + /* lg(64/63) = */ 0x000005d1, + /* lg(128/127) = */ 0x000002e6, + /* lg(256/255) = */ 0x00000172, + /* lg(512/511) = */ 0x000000b9, + /* lg(1024/1023) = */ 0x0000005c, + /* lg(2048/2047) = */ 0x0000002e, + /* lg(4096/4095) = */ 0x00000017, + /* lg(8192/8191) = */ 0x0000000c, + /* lg(16384/16383) = */ 0x00000006, + /* lg(32768/32767) = */ 0x00000003 + }, + { + /* + 20 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ 0x00100000, + /* lg(4/3) = */ 0x0006a3fe, + /* lg(8/7) = */ 0x00031513, + /* lg(16/15) = */ 0x00017d60, + /* lg(32/31) = */ 0x0000bb9d, + /* lg(64/63) = */ 0x00005d10, + /* lg(128/127) = */ 0x00002e59, + /* lg(256/255) = */ 0x00001721, + /* lg(512/511) = */ 0x00000b8e, + /* lg(1024/1023) = */ 0x000005c6, + /* lg(2048/2047) = */ 0x000002e3, + /* lg(4096/4095) = */ 0x00000171, + /* lg(8192/8191) = */ 0x000000b9, + /* lg(16384/16383) = */ 0x0000005c, + /* lg(32768/32767) = */ 0x0000002e + }, + { + /* + 24 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ 0x01000000, + /* lg(4/3) = */ 0x006a3fe6, + /* lg(8/7) = */ 0x00315130, + /* lg(16/15) = */ 0x0017d605, + /* lg(32/31) = */ 0x000bb9ca, + /* lg(64/63) = */ 0x0005d0fc, + /* lg(128/127) = */ 0x0002e58f, + /* lg(256/255) = */ 0x0001720e, + /* lg(512/511) = */ 0x0000b8d8, + /* lg(1024/1023) = */ 0x00005c61, + /* lg(2048/2047) = */ 0x00002e2d, + /* lg(4096/4095) = */ 0x00001716, + /* lg(8192/8191) = */ 0x00000b8b, + /* lg(16384/16383) = */ 0x000005c5, + /* lg(32768/32767) = */ 0x000002e3 + }, + { + /* + 28 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ 0x10000000, + /* lg(4/3) = */ 0x06a3fe5c, + /* lg(8/7) = */ 0x03151301, + /* lg(16/15) = */ 0x017d6049, + /* lg(32/31) = */ 0x00bb9ca6, + /* lg(64/63) = */ 0x005d0fba, + /* lg(128/127) = */ 0x002e58f7, + /* lg(256/255) = */ 0x001720da, + /* lg(512/511) = */ 0x000b8d87, + /* lg(1024/1023) = */ 0x0005c60b, + /* lg(2048/2047) = */ 0x0002e2d7, + /* lg(4096/4095) = */ 0x00017160, + /* lg(8192/8191) = */ 0x0000b8ad, + /* lg(16384/16383) = */ 0x00005c56, + /* lg(32768/32767) = */ 0x00002e2b + } }; #if 0 static const FLAC__uint64 log2_lookup_wide[] = { - { - /* - * 32 fraction bits - */ - /* undefined */ 0x00000000, - /* lg(2/1) = */ FLAC__U64L(0x100000000), - /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c6), - /* lg(8/7) = */ FLAC__U64L(0x31513015), - /* lg(16/15) = */ FLAC__U64L(0x17d60497), - /* lg(32/31) = */ FLAC__U64L(0x0bb9ca65), - /* lg(64/63) = */ FLAC__U64L(0x05d0fba2), - /* lg(128/127) = */ FLAC__U64L(0x02e58f74), - /* lg(256/255) = */ FLAC__U64L(0x01720d9c), - /* lg(512/511) = */ FLAC__U64L(0x00b8d875), - /* lg(1024/1023) = */ FLAC__U64L(0x005c60aa), - /* lg(2048/2047) = */ FLAC__U64L(0x002e2d72), - /* lg(4096/4095) = */ FLAC__U64L(0x00171600), - /* lg(8192/8191) = */ FLAC__U64L(0x000b8ad2), - /* lg(16384/16383) = */ FLAC__U64L(0x0005c55d), - /* lg(32768/32767) = */ FLAC__U64L(0x0002e2ac) - }, - { - /* - * 48 fraction bits - */ - /* undefined */ 0x00000000, - /* lg(2/1) = */ FLAC__U64L(0x1000000000000), - /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c60429), - /* lg(8/7) = */ FLAC__U64L(0x315130157f7a), - /* lg(16/15) = */ FLAC__U64L(0x17d60496cfbb), - /* lg(32/31) = */ FLAC__U64L(0xbb9ca64ecac), - /* lg(64/63) = */ FLAC__U64L(0x5d0fba187cd), - /* lg(128/127) = */ FLAC__U64L(0x2e58f7441ee), - /* lg(256/255) = */ FLAC__U64L(0x1720d9c06a8), - /* lg(512/511) = */ FLAC__U64L(0xb8d8752173), - /* lg(1024/1023) = */ FLAC__U64L(0x5c60aa252e), - /* lg(2048/2047) = */ FLAC__U64L(0x2e2d71b0d8), - /* lg(4096/4095) = */ FLAC__U64L(0x1716001719), - /* lg(8192/8191) = */ FLAC__U64L(0xb8ad1de1b), - /* lg(16384/16383) = */ FLAC__U64L(0x5c55d640d), - /* lg(32768/32767) = */ FLAC__U64L(0x2e2abcf52) - } + { + /* + 32 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ FLAC__U64L(0x100000000), + /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c6), + /* lg(8/7) = */ FLAC__U64L(0x31513015), + /* lg(16/15) = */ FLAC__U64L(0x17d60497), + /* lg(32/31) = */ FLAC__U64L(0x0bb9ca65), + /* lg(64/63) = */ FLAC__U64L(0x05d0fba2), + /* lg(128/127) = */ FLAC__U64L(0x02e58f74), + /* lg(256/255) = */ FLAC__U64L(0x01720d9c), + /* lg(512/511) = */ FLAC__U64L(0x00b8d875), + /* lg(1024/1023) = */ FLAC__U64L(0x005c60aa), + /* lg(2048/2047) = */ FLAC__U64L(0x002e2d72), + /* lg(4096/4095) = */ FLAC__U64L(0x00171600), + /* lg(8192/8191) = */ FLAC__U64L(0x000b8ad2), + /* lg(16384/16383) = */ FLAC__U64L(0x0005c55d), + /* lg(32768/32767) = */ FLAC__U64L(0x0002e2ac) + }, + { + /* + 48 fraction bits + */ + /* undefined */ 0x00000000, + /* lg(2/1) = */ FLAC__U64L(0x1000000000000), + /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c60429), + /* lg(8/7) = */ FLAC__U64L(0x315130157f7a), + /* lg(16/15) = */ FLAC__U64L(0x17d60496cfbb), + /* lg(32/31) = */ FLAC__U64L(0xbb9ca64ecac), + /* lg(64/63) = */ FLAC__U64L(0x5d0fba187cd), + /* lg(128/127) = */ FLAC__U64L(0x2e58f7441ee), + /* lg(256/255) = */ FLAC__U64L(0x1720d9c06a8), + /* lg(512/511) = */ FLAC__U64L(0xb8d8752173), + /* lg(1024/1023) = */ FLAC__U64L(0x5c60aa252e), + /* lg(2048/2047) = */ FLAC__U64L(0x2e2d71b0d8), + /* lg(4096/4095) = */ FLAC__U64L(0x1716001719), + /* lg(8192/8191) = */ FLAC__U64L(0xb8ad1de1b), + /* lg(16384/16383) = */ FLAC__U64L(0x5c55d640d), + /* lg(32768/32767) = */ FLAC__U64L(0x2e2abcf52) + } }; #endif -FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, uint32_t fracbits, uint32_t precision) -{ - const FLAC__uint32 ONE = (1u << fracbits); - const FLAC__uint32 *table = log2_lookup[fracbits >> 2]; +FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, uint32_t fracbits, uint32_t precision) { + const FLAC__uint32 ONE = (1u << fracbits); + const FLAC__uint32 *table = log2_lookup[fracbits >> 2]; - FLAC__ASSERT(fracbits < 32); - FLAC__ASSERT((fracbits & 0x3) == 0); + FLAC__ASSERT(fracbits < 32); + FLAC__ASSERT((fracbits & 0x3) == 0); - if(x < ONE) - return 0; + if (x < ONE) { + return 0; + } - if(precision > LOG2_LOOKUP_PRECISION) - precision = LOG2_LOOKUP_PRECISION; + if (precision > LOG2_LOOKUP_PRECISION) { + precision = LOG2_LOOKUP_PRECISION; + } - /* Knuth's algorithm for computing logarithms, optimized for base-2 with lookup tables */ - { - FLAC__uint32 y = 0; - FLAC__uint32 z = x >> 1, k = 1; - while (x > ONE && k < precision) { - if (x - z >= ONE) { - x -= z; - z = x >> k; - y += table[k]; - } - else { - z >>= 1; - k++; - } - } - return y; - } + /* Knuth's algorithm for computing logarithms, optimized for base-2 with lookup tables */ + { + FLAC__uint32 y = 0; + FLAC__uint32 z = x >> 1, k = 1; + while (x > ONE && k < precision) { + if (x - z >= ONE) { + x -= z; + z = x >> k; + y += table[k]; + } else { + z >>= 1; + k++; + } + } + return y; + } } #endif /* defined FLAC__INTEGER_ONLY_LIBRARY */ diff --git a/src/libflac/format.c b/src/libflac/format.c index 5578bbec..e5d40ab1 100644 --- a/src/libflac/format.c +++ b/src/libflac/format.c @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2000-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ //#ifdef HAVE_CONFIG_H # include "config.h" @@ -51,7 +51,7 @@ FLAC_API const char *FLAC__VERSION_STRING = PACKAGE_VERSION; FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " PACKAGE_VERSION " 20190804"; -FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' }; +FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f', 'L', 'a', 'C' }; FLAC_API const uint32_t FLAC__STREAM_SYNC = 0x664C6143; FLAC_API const uint32_t FLAC__STREAM_SYNC_LEN = 32; /* bits */ @@ -78,20 +78,20 @@ FLAC_API const uint32_t FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN = FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN = 64; /* bits */ FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN = 8; /* bits */ -FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = 3*8; /* bits */ +FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = 3 * 8; /* bits */ FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN = 64; /* bits */ FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN = 8; /* bits */ -FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = 12*8; /* bits */ +FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = 12 * 8; /* bits */ FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN = 1; /* bit */ FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN = 1; /* bit */ -FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN = 6+13*8; /* bits */ +FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN = 6 + 13 * 8; /* bits */ FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN = 8; /* bits */ -FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN = 128*8; /* bits */ +FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN = 128 * 8; /* bits */ FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN = 64; /* bits */ FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN = 1; /* bit */ -FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN = 7+258*8; /* bits */ +FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN = 7 + 258 * 8; /* bits */ FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN = 8; /* bits */ FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_TYPE_LEN = 32; /* bits */ @@ -130,8 +130,8 @@ FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARA FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER = 31; /* == (1< FLAC__MAX_SAMPLE_RATE) { - return false; - } - else - return true; +FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(uint32_t sample_rate) { + if (sample_rate == 0 || sample_rate > FLAC__MAX_SAMPLE_RATE) { + return false; + } else { + return true; + } } -FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(uint32_t blocksize, uint32_t sample_rate) -{ - if(blocksize > 16384) - return false; - else if(sample_rate <= 48000 && blocksize > 4608) - return false; - else - return true; +FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(uint32_t blocksize, uint32_t sample_rate) { + if (blocksize > 16384) { + return false; + } else if (sample_rate <= 48000 && blocksize > 4608) { + return false; + } else { + return true; + } } -FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(uint32_t sample_rate) -{ - if( - !FLAC__format_sample_rate_is_valid(sample_rate) || - ( - sample_rate >= (1u << 16) && - !(sample_rate % 1000 == 0 || sample_rate % 10 == 0) - ) - ) { - return false; - } - else - return true; +FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(uint32_t sample_rate) { + if ( + !FLAC__format_sample_rate_is_valid(sample_rate) || + ( + sample_rate >= (1u << 16) && + !(sample_rate % 1000 == 0 || sample_rate % 10 == 0) + ) + ) { + return false; + } else { + return true; + } } /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ -FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table) -{ - uint32_t i; - FLAC__uint64 prev_sample_number = 0; - FLAC__bool got_prev = false; - - FLAC__ASSERT(0 != seek_table); - - for(i = 0; i < seek_table->num_points; i++) { - if(got_prev) { - if( - seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && - seek_table->points[i].sample_number <= prev_sample_number - ) - return false; - } - prev_sample_number = seek_table->points[i].sample_number; - got_prev = true; - } - - return true; +FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table) { + uint32_t i; + FLAC__uint64 prev_sample_number = 0; + FLAC__bool got_prev = false; + + FLAC__ASSERT(0 != seek_table); + + for (i = 0; i < seek_table->num_points; i++) { + if (got_prev) { + if ( + seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && + seek_table->points[i].sample_number <= prev_sample_number + ) { + return false; + } + } + prev_sample_number = seek_table->points[i].sample_number; + got_prev = true; + } + + return true; } /* used as the sort predicate for qsort() */ -static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r) -{ - /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */ - if(l->sample_number == r->sample_number) - return 0; - else if(l->sample_number < r->sample_number) - return -1; - else - return 1; +static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r) { + /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */ + if (l->sample_number == r->sample_number) { + return 0; + } else if (l->sample_number < r->sample_number) { + return -1; + } else { + return 1; + } } /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ -FLAC_API uint32_t FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table) -{ - uint32_t i, j; - FLAC__bool first; - - FLAC__ASSERT(0 != seek_table); - - if (seek_table->num_points == 0) - return 0; - - /* sort the seekpoints */ - qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare_); - - /* uniquify the seekpoints */ - first = true; - for(i = j = 0; i < seek_table->num_points; i++) { - if(seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) { - if(!first) { - if(seek_table->points[i].sample_number == seek_table->points[j-1].sample_number) - continue; - } - } - first = false; - seek_table->points[j++] = seek_table->points[i]; - } - - for(i = j; i < seek_table->num_points; i++) { - seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; - seek_table->points[i].stream_offset = 0; - seek_table->points[i].frame_samples = 0; - } - - return j; +FLAC_API uint32_t FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table) { + uint32_t i, j; + FLAC__bool first; + + FLAC__ASSERT(0 != seek_table); + + if (seek_table->num_points == 0) { + return 0; + } + + /* sort the seekpoints */ + qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare_); + + /* uniquify the seekpoints */ + first = true; + for (i = j = 0; i < seek_table->num_points; i++) { + if (seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) { + if (!first) { + if (seek_table->points[i].sample_number == seek_table->points[j - 1].sample_number) { + continue; + } + } + } + first = false; + seek_table->points[j++] = seek_table->points[i]; + } + + for (i = j; i < seek_table->num_points; i++) { + seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; + seek_table->points[i].stream_offset = 0; + seek_table->points[i].frame_samples = 0; + } + + return j; } /* - * also disallows non-shortest-form encodings, c.f. - * http://www.unicode.org/versions/corrigendum1.html - * and a more clear explanation at the end of this section: - * http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - */ -static uint32_t utf8len_(const FLAC__byte *utf8) -{ - FLAC__ASSERT(0 != utf8); - if ((utf8[0] & 0x80) == 0) { - return 1; - } - else if ((utf8[0] & 0xE0) == 0xC0 && (utf8[1] & 0xC0) == 0x80) { - if ((utf8[0] & 0xFE) == 0xC0) /* overlong sequence check */ - return 0; - return 2; - } - else if ((utf8[0] & 0xF0) == 0xE0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80) { - if (utf8[0] == 0xE0 && (utf8[1] & 0xE0) == 0x80) /* overlong sequence check */ - return 0; - /* illegal surrogates check (U+D800...U+DFFF and U+FFFE...U+FFFF) */ - if (utf8[0] == 0xED && (utf8[1] & 0xE0) == 0xA0) /* D800-DFFF */ - return 0; - if (utf8[0] == 0xEF && utf8[1] == 0xBF && (utf8[2] & 0xFE) == 0xBE) /* FFFE-FFFF */ - return 0; - return 3; - } - else if ((utf8[0] & 0xF8) == 0xF0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80) { - if (utf8[0] == 0xF0 && (utf8[1] & 0xF0) == 0x80) /* overlong sequence check */ - return 0; - return 4; - } - else if ((utf8[0] & 0xFC) == 0xF8 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80) { - if (utf8[0] == 0xF8 && (utf8[1] & 0xF8) == 0x80) /* overlong sequence check */ - return 0; - return 5; - } - else if ((utf8[0] & 0xFE) == 0xFC && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80 && (utf8[5] & 0xC0) == 0x80) { - if (utf8[0] == 0xFC && (utf8[1] & 0xFC) == 0x80) /* overlong sequence check */ - return 0; - return 6; - } - else { - return 0; - } + also disallows non-shortest-form encodings, c.f. + http://www.unicode.org/versions/corrigendum1.html + and a more clear explanation at the end of this section: + http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 +*/ +static uint32_t utf8len_(const FLAC__byte *utf8) { + FLAC__ASSERT(0 != utf8); + if ((utf8[0] & 0x80) == 0) { + return 1; + } else if ((utf8[0] & 0xE0) == 0xC0 && (utf8[1] & 0xC0) == 0x80) { + if ((utf8[0] & 0xFE) == 0xC0) { /* overlong sequence check */ + return 0; + } + return 2; + } else if ((utf8[0] & 0xF0) == 0xE0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80) { + if (utf8[0] == 0xE0 && (utf8[1] & 0xE0) == 0x80) { /* overlong sequence check */ + return 0; + } + /* illegal surrogates check (U+D800...U+DFFF and U+FFFE...U+FFFF) */ + if (utf8[0] == 0xED && (utf8[1] & 0xE0) == 0xA0) { /* D800-DFFF */ + return 0; + } + if (utf8[0] == 0xEF && utf8[1] == 0xBF && (utf8[2] & 0xFE) == 0xBE) { /* FFFE-FFFF */ + return 0; + } + return 3; + } else if ((utf8[0] & 0xF8) == 0xF0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80) { + if (utf8[0] == 0xF0 && (utf8[1] & 0xF0) == 0x80) { /* overlong sequence check */ + return 0; + } + return 4; + } else if ((utf8[0] & 0xFC) == 0xF8 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80) { + if (utf8[0] == 0xF8 && (utf8[1] & 0xF8) == 0x80) { /* overlong sequence check */ + return 0; + } + return 5; + } else if ((utf8[0] & 0xFE) == 0xFC && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80 && (utf8[5] & 0xC0) == 0x80) { + if (utf8[0] == 0xFC && (utf8[1] & 0xFC) == 0x80) { /* overlong sequence check */ + return 0; + } + return 6; + } else { + return 0; + } } -FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name) -{ - char c; - for(c = *name; c; c = *(++name)) - if(c < 0x20 || c == 0x3d || c > 0x7d) - return false; - return true; +FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name) { + char c; + for (c = *name; c; c = *(++name)) + if (c < 0x20 || c == 0x3d || c > 0x7d) { + return false; + } + return true; } -FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, uint32_t length) -{ - if(length == (uint32_t)(-1)) { - while(*value) { - uint32_t n = utf8len_(value); - if(n == 0) - return false; - value += n; - } - } - else { - const FLAC__byte *end = value + length; - while(value < end) { - uint32_t n = utf8len_(value); - if(n == 0) - return false; - value += n; - } - if(value != end) - return false; - } - return true; +FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, uint32_t length) { + if (length == (uint32_t)(-1)) { + while (*value) { + uint32_t n = utf8len_(value); + if (n == 0) { + return false; + } + value += n; + } + } else { + const FLAC__byte *end = value + length; + while (value < end) { + uint32_t n = utf8len_(value); + if (n == 0) { + return false; + } + value += n; + } + if (value != end) { + return false; + } + } + return true; } -FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, uint32_t length) -{ - const FLAC__byte *s, *end; - - for(s = entry, end = s + length; s < end && *s != '='; s++) { - if(*s < 0x20 || *s > 0x7D) - return false; - } - if(s == end) - return false; - - s++; /* skip '=' */ - - while(s < end) { - uint32_t n = utf8len_(s); - if(n == 0) - return false; - s += n; - } - if(s != end) - return false; - - return true; +FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, uint32_t length) { + const FLAC__byte *s, *end; + + for (s = entry, end = s + length; s < end && *s != '='; s++) { + if (*s < 0x20 || *s > 0x7D) { + return false; + } + } + if (s == end) { + return false; + } + + s++; /* skip '=' */ + + while (s < end) { + uint32_t n = utf8len_(s); + if (n == 0) { + return false; + } + s += n; + } + if (s != end) { + return false; + } + + return true; } /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ -FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation) -{ - uint32_t i, j; - - if(check_cd_da_subset) { - if(cue_sheet->lead_in < 2 * 44100) { - if(violation) *violation = "CD-DA cue sheet must have a lead-in length of at least 2 seconds"; - return false; - } - if(cue_sheet->lead_in % 588 != 0) { - if(violation) *violation = "CD-DA cue sheet lead-in length must be evenly divisible by 588 samples"; - return false; - } - } - - if(cue_sheet->num_tracks == 0) { - if(violation) *violation = "cue sheet must have at least one track (the lead-out)"; - return false; - } - - if(check_cd_da_subset && cue_sheet->tracks[cue_sheet->num_tracks-1].number != 170) { - if(violation) *violation = "CD-DA cue sheet must have a lead-out track number 170 (0xAA)"; - return false; - } - - for(i = 0; i < cue_sheet->num_tracks; i++) { - if(cue_sheet->tracks[i].number == 0) { - if(violation) *violation = "cue sheet may not have a track number 0"; - return false; - } - - if(check_cd_da_subset) { - if(!((cue_sheet->tracks[i].number >= 1 && cue_sheet->tracks[i].number <= 99) || cue_sheet->tracks[i].number == 170)) { - if(violation) *violation = "CD-DA cue sheet track number must be 1-99 or 170"; - return false; - } - } - - if(check_cd_da_subset && cue_sheet->tracks[i].offset % 588 != 0) { - if(violation) { - if(i == cue_sheet->num_tracks-1) /* the lead-out track... */ - *violation = "CD-DA cue sheet lead-out offset must be evenly divisible by 588 samples"; - else - *violation = "CD-DA cue sheet track offset must be evenly divisible by 588 samples"; - } - return false; - } - - if(i < cue_sheet->num_tracks - 1) { - if(cue_sheet->tracks[i].num_indices == 0) { - if(violation) *violation = "cue sheet track must have at least one index point"; - return false; - } - - if(cue_sheet->tracks[i].indices[0].number > 1) { - if(violation) *violation = "cue sheet track's first index number must be 0 or 1"; - return false; - } - } - - for(j = 0; j < cue_sheet->tracks[i].num_indices; j++) { - if(check_cd_da_subset && cue_sheet->tracks[i].indices[j].offset % 588 != 0) { - if(violation) *violation = "CD-DA cue sheet track index offset must be evenly divisible by 588 samples"; - return false; - } - - if(j > 0) { - if(cue_sheet->tracks[i].indices[j].number != cue_sheet->tracks[i].indices[j-1].number + 1) { - if(violation) *violation = "cue sheet track index numbers must increase by 1"; - return false; - } - } - } - } - - return true; +FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation) { + uint32_t i, j; + + if (check_cd_da_subset) { + if (cue_sheet->lead_in < 2 * 44100) { + if (violation) { + *violation = "CD-DA cue sheet must have a lead-in length of at least 2 seconds"; + } + return false; + } + if (cue_sheet->lead_in % 588 != 0) { + if (violation) { + *violation = "CD-DA cue sheet lead-in length must be evenly divisible by 588 samples"; + } + return false; + } + } + + if (cue_sheet->num_tracks == 0) { + if (violation) { + *violation = "cue sheet must have at least one track (the lead-out)"; + } + return false; + } + + if (check_cd_da_subset && cue_sheet->tracks[cue_sheet->num_tracks - 1].number != 170) { + if (violation) { + *violation = "CD-DA cue sheet must have a lead-out track number 170 (0xAA)"; + } + return false; + } + + for (i = 0; i < cue_sheet->num_tracks; i++) { + if (cue_sheet->tracks[i].number == 0) { + if (violation) { + *violation = "cue sheet may not have a track number 0"; + } + return false; + } + + if (check_cd_da_subset) { + if (!((cue_sheet->tracks[i].number >= 1 && cue_sheet->tracks[i].number <= 99) || cue_sheet->tracks[i].number == 170)) { + if (violation) { + *violation = "CD-DA cue sheet track number must be 1-99 or 170"; + } + return false; + } + } + + if (check_cd_da_subset && cue_sheet->tracks[i].offset % 588 != 0) { + if (violation) { + if (i == cue_sheet->num_tracks - 1) { /* the lead-out track... */ + *violation = "CD-DA cue sheet lead-out offset must be evenly divisible by 588 samples"; + } else { + *violation = "CD-DA cue sheet track offset must be evenly divisible by 588 samples"; + } + } + return false; + } + + if (i < cue_sheet->num_tracks - 1) { + if (cue_sheet->tracks[i].num_indices == 0) { + if (violation) { + *violation = "cue sheet track must have at least one index point"; + } + return false; + } + + if (cue_sheet->tracks[i].indices[0].number > 1) { + if (violation) { + *violation = "cue sheet track's first index number must be 0 or 1"; + } + return false; + } + } + + for (j = 0; j < cue_sheet->tracks[i].num_indices; j++) { + if (check_cd_da_subset && cue_sheet->tracks[i].indices[j].offset % 588 != 0) { + if (violation) { + *violation = "CD-DA cue sheet track index offset must be evenly divisible by 588 samples"; + } + return false; + } + + if (j > 0) { + if (cue_sheet->tracks[i].indices[j].number != cue_sheet->tracks[i].indices[j - 1].number + 1) { + if (violation) { + *violation = "cue sheet track index numbers must increase by 1"; + } + return false; + } + } + } + } + + return true; } /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ -FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation) -{ - char *p; - FLAC__byte *b; - - for(p = picture->mime_type; *p; p++) { - if(*p < 0x20 || *p > 0x7e) { - if(violation) *violation = "MIME type string must contain only printable ASCII characters (0x20-0x7e)"; - return false; - } - } - - for(b = picture->description; *b; ) { - uint32_t n = utf8len_(b); - if(n == 0) { - if(violation) *violation = "description string must be valid UTF-8"; - return false; - } - b += n; - } - - return true; +FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation) { + char *p; + FLAC__byte *b; + + for (p = picture->mime_type; *p; p++) { + if (*p < 0x20 || *p > 0x7e) { + if (violation) { + *violation = "MIME type string must contain only printable ASCII characters (0x20-0x7e)"; + } + return false; + } + } + + for (b = picture->description; *b;) { + uint32_t n = utf8len_(b); + if (n == 0) { + if (violation) { + *violation = "description string must be valid UTF-8"; + } + return false; + } + b += n; + } + + return true; } /* - * These routines are private to libFLAC - */ -uint32_t FLAC__format_get_max_rice_partition_order(uint32_t blocksize, uint32_t predictor_order) -{ - return - FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order( - FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize), - blocksize, - predictor_order - ); + These routines are private to libFLAC +*/ +uint32_t FLAC__format_get_max_rice_partition_order(uint32_t blocksize, uint32_t predictor_order) { + return + FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order( + FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize), + blocksize, + predictor_order + ); } -uint32_t FLAC__format_get_max_rice_partition_order_from_blocksize(uint32_t blocksize) -{ - uint32_t max_rice_partition_order = 0; - while(!(blocksize & 1)) { - max_rice_partition_order++; - blocksize >>= 1; - } - return flac_min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order); +uint32_t FLAC__format_get_max_rice_partition_order_from_blocksize(uint32_t blocksize) { + uint32_t max_rice_partition_order = 0; + while (!(blocksize & 1)) { + max_rice_partition_order++; + blocksize >>= 1; + } + return flac_min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order); } -uint32_t FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(uint32_t limit, uint32_t blocksize, uint32_t predictor_order) -{ - uint32_t max_rice_partition_order = limit; +uint32_t FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(uint32_t limit, uint32_t blocksize, uint32_t predictor_order) { + uint32_t max_rice_partition_order = limit; - while(max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order) - max_rice_partition_order--; + while (max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order) { + max_rice_partition_order--; + } - FLAC__ASSERT( - (max_rice_partition_order == 0 && blocksize >= predictor_order) || - (max_rice_partition_order > 0 && blocksize >> max_rice_partition_order > predictor_order) - ); + FLAC__ASSERT( + (max_rice_partition_order == 0 && blocksize >= predictor_order) || + (max_rice_partition_order > 0 && blocksize >> max_rice_partition_order > predictor_order) + ); - return max_rice_partition_order; + return max_rice_partition_order; } -void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object) -{ - FLAC__ASSERT(0 != object); +void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object) { + FLAC__ASSERT(0 != object); - object->parameters = 0; - object->raw_bits = 0; - object->capacity_by_order = 0; + object->parameters = 0; + object->raw_bits = 0; + object->capacity_by_order = 0; } -void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object) -{ - FLAC__ASSERT(0 != object); +void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object) { + FLAC__ASSERT(0 != object); - if(0 != object->parameters) - free(object->parameters); - if(0 != object->raw_bits) - free(object->raw_bits); - FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object); + if (0 != object->parameters) { + free(object->parameters); + } + if (0 != object->raw_bits) { + free(object->raw_bits); + } + FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object); } -FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, uint32_t max_partition_order) -{ - FLAC__ASSERT(0 != object); +FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, uint32_t max_partition_order) { + FLAC__ASSERT(0 != object); - FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits)); + FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits)); - if(object->capacity_by_order < max_partition_order) { - if(0 == (object->parameters = safe_realloc_(object->parameters, sizeof(uint32_t)*(1 << max_partition_order)))) - return false; - if(0 == (object->raw_bits = safe_realloc_(object->raw_bits, sizeof(uint32_t)*(1 << max_partition_order)))) - return false; - memset(object->raw_bits, 0, sizeof(uint32_t)*(1 << max_partition_order)); - object->capacity_by_order = max_partition_order; - } + if (object->capacity_by_order < max_partition_order) { + if (0 == (object->parameters = safe_realloc_(object->parameters, sizeof(uint32_t) * (1 << max_partition_order)))) { + return false; + } + if (0 == (object->raw_bits = safe_realloc_(object->raw_bits, sizeof(uint32_t) * (1 << max_partition_order)))) { + return false; + } + memset(object->raw_bits, 0, sizeof(uint32_t) * (1 << max_partition_order)); + object->capacity_by_order = max_partition_order; + } - return true; + return true; } diff --git a/src/libflac/lpc.c b/src/libflac/lpc.c index c2a489f4..407bd704 100644 --- a/src/libflac/lpc.c +++ b/src/libflac/lpc.c @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2000-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ //#ifdef HAVE_CONFIG_H # include "config.h" @@ -56,209 +56,218 @@ #if defined(_MSC_VER) && (_MSC_VER < 1800) #include static inline long int lround(double x) { - return (long)(x + _copysign(0.5, x)); + return (long)(x + _copysign(0.5, x)); } #elif !defined(HAVE_LROUND) && defined(__GNUC__) static inline long int lround(double x) { - return (long)(x + __builtin_copysign(0.5, x)); + return (long)(x + __builtin_copysign(0.5, x)); } /* If this fails, we are in the presence of a mid 90's compiler, move along... */ #endif -void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len) -{ - uint32_t i; - for(i = 0; i < data_len; i++) - out[i] = in[i] * window[i]; +void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len) { + uint32_t i; + for (i = 0; i < data_len; i++) { + out[i] = in[i] * window[i]; + } } -void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) -{ - /* a readable, but slower, version */ +void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) { + /* a readable, but slower, version */ #if 0 - FLAC__real d; - uint32_t i; - - FLAC__ASSERT(lag > 0); - FLAC__ASSERT(lag <= data_len); - - /* - * Technically we should subtract the mean first like so: - * for(i = 0; i < data_len; i++) - * data[i] -= mean; - * but it appears not to make enough of a difference to matter, and - * most signals are already closely centered around zero - */ - while(lag--) { - for(i = lag, d = 0.0; i < data_len; i++) - d += data[i] * data[i - lag]; - autoc[lag] = d; - } + FLAC__real d; + uint32_t i; + + FLAC__ASSERT(lag > 0); + FLAC__ASSERT(lag <= data_len); + + /* + Technically we should subtract the mean first like so: + for(i = 0; i < data_len; i++) + data[i] -= mean; + but it appears not to make enough of a difference to matter, and + most signals are already closely centered around zero + */ + while (lag--) { + for (i = lag, d = 0.0; i < data_len; i++) { + d += data[i] * data[i - lag]; + } + autoc[lag] = d; + } #endif - /* - * this version tends to run faster because of better data locality - * ('data_len' is usually much larger than 'lag') - */ - FLAC__real d; - uint32_t sample, coeff; - const uint32_t limit = data_len - lag; - - FLAC__ASSERT(lag > 0); - FLAC__ASSERT(lag <= data_len); - - for(coeff = 0; coeff < lag; coeff++) - autoc[coeff] = 0.0; - for(sample = 0; sample <= limit; sample++) { - d = data[sample]; - for(coeff = 0; coeff < lag; coeff++) - autoc[coeff] += d * data[sample+coeff]; - } - for(; sample < data_len; sample++) { - d = data[sample]; - for(coeff = 0; coeff < data_len - sample; coeff++) - autoc[coeff] += d * data[sample+coeff]; - } + /* + this version tends to run faster because of better data locality + ('data_len' is usually much larger than 'lag') + */ + FLAC__real d; + uint32_t sample, coeff; + const uint32_t limit = data_len - lag; + + FLAC__ASSERT(lag > 0); + FLAC__ASSERT(lag <= data_len); + + for (coeff = 0; coeff < lag; coeff++) { + autoc[coeff] = 0.0; + } + for (sample = 0; sample <= limit; sample++) { + d = data[sample]; + for (coeff = 0; coeff < lag; coeff++) { + autoc[coeff] += d * data[sample + coeff]; + } + } + for (; sample < data_len; sample++) { + d = data[sample]; + for (coeff = 0; coeff < data_len - sample; coeff++) { + autoc[coeff] += d * data[sample + coeff]; + } + } } -void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], uint32_t *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], double error[]) -{ - uint32_t i, j; - double r, err, lpc[FLAC__MAX_LPC_ORDER]; - - FLAC__ASSERT(0 != max_order); - FLAC__ASSERT(0 < *max_order); - FLAC__ASSERT(*max_order <= FLAC__MAX_LPC_ORDER); - FLAC__ASSERT(autoc[0] != 0.0); - - err = autoc[0]; - - for(i = 0; i < *max_order; i++) { - /* Sum up this iteration's reflection coefficient. */ - r = -autoc[i+1]; - for(j = 0; j < i; j++) - r -= lpc[j] * autoc[i-j]; - r /= err; - - /* Update LPC coefficients and total error. */ - lpc[i]=r; - for(j = 0; j < (i>>1); j++) { - double tmp = lpc[j]; - lpc[j] += r * lpc[i-1-j]; - lpc[i-1-j] += r * tmp; - } - if(i & 1) - lpc[j] += lpc[j] * r; - - err *= (1.0 - r * r); - - /* save this order */ - for(j = 0; j <= i; j++) - lp_coeff[i][j] = (FLAC__real)(-lpc[j]); /* negate FIR filter coeff to get predictor coeff */ - error[i] = err; - - /* see SF bug https://sourceforge.net/p/flac/bugs/234/ */ - if(err == 0.0) { - *max_order = i+1; - return; - } - } +void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], uint32_t *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], double error[]) { + uint32_t i, j; + double r, err, lpc[FLAC__MAX_LPC_ORDER]; + + FLAC__ASSERT(0 != max_order); + FLAC__ASSERT(0 < *max_order); + FLAC__ASSERT(*max_order <= FLAC__MAX_LPC_ORDER); + FLAC__ASSERT(autoc[0] != 0.0); + + err = autoc[0]; + + for (i = 0; i < *max_order; i++) { + /* Sum up this iteration's reflection coefficient. */ + r = -autoc[i + 1]; + for (j = 0; j < i; j++) { + r -= lpc[j] * autoc[i - j]; + } + r /= err; + + /* Update LPC coefficients and total error. */ + lpc[i] = r; + for (j = 0; j < (i >> 1); j++) { + double tmp = lpc[j]; + lpc[j] += r * lpc[i - 1 - j]; + lpc[i - 1 - j] += r * tmp; + } + if (i & 1) { + lpc[j] += lpc[j] * r; + } + + err *= (1.0 - r * r); + + /* save this order */ + for (j = 0; j <= i; j++) { + lp_coeff[i][j] = (FLAC__real)(-lpc[j]); /* negate FIR filter coeff to get predictor coeff */ + } + error[i] = err; + + /* see SF bug https://sourceforge.net/p/flac/bugs/234/ */ + if (err == 0.0) { + *max_order = i + 1; + return; + } + } } -int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], uint32_t order, uint32_t precision, FLAC__int32 qlp_coeff[], int *shift) -{ - uint32_t i; - double cmax; - FLAC__int32 qmax, qmin; - - FLAC__ASSERT(precision > 0); - FLAC__ASSERT(precision >= FLAC__MIN_QLP_COEFF_PRECISION); - - /* drop one bit for the sign; from here on out we consider only |lp_coeff[i]| */ - precision--; - qmax = 1 << precision; - qmin = -qmax; - qmax--; - - /* calc cmax = max( |lp_coeff[i]| ) */ - cmax = 0.0; - for(i = 0; i < order; i++) { - const double d = fabs(lp_coeff[i]); - if(d > cmax) - cmax = d; - } - - if(cmax <= 0.0) { - /* => coefficients are all 0, which means our constant-detect didn't work */ - return 2; - } - else { - const int max_shiftlimit = (1 << (FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN-1)) - 1; - const int min_shiftlimit = -max_shiftlimit - 1; - int log2cmax; - - (void)frexp(cmax, &log2cmax); - log2cmax--; - *shift = (int)precision - log2cmax - 1; - - if(*shift > max_shiftlimit) - *shift = max_shiftlimit; - else if(*shift < min_shiftlimit) - return 1; - } - - if(*shift >= 0) { - double error = 0.0; - FLAC__int32 q; - for(i = 0; i < order; i++) { - error += lp_coeff[i] * (1 << *shift); - q = lround(error); +int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], uint32_t order, uint32_t precision, FLAC__int32 qlp_coeff[], int *shift) { + uint32_t i; + double cmax; + FLAC__int32 qmax, qmin; + + FLAC__ASSERT(precision > 0); + FLAC__ASSERT(precision >= FLAC__MIN_QLP_COEFF_PRECISION); + + /* drop one bit for the sign; from here on out we consider only |lp_coeff[i]| */ + precision--; + qmax = 1 << precision; + qmin = -qmax; + qmax--; + + /* calc cmax = max( |lp_coeff[i]| ) */ + cmax = 0.0; + for (i = 0; i < order; i++) { + const double d = fabs(lp_coeff[i]); + if (d > cmax) { + cmax = d; + } + } + + if (cmax <= 0.0) { + /* => coefficients are all 0, which means our constant-detect didn't work */ + return 2; + } else { + const int max_shiftlimit = (1 << (FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN - 1)) - 1; + const int min_shiftlimit = -max_shiftlimit - 1; + int log2cmax; + + (void)frexp(cmax, &log2cmax); + log2cmax--; + *shift = (int)precision - log2cmax - 1; + + if (*shift > max_shiftlimit) { + *shift = max_shiftlimit; + } else if (*shift < min_shiftlimit) { + return 1; + } + } + + if (*shift >= 0) { + double error = 0.0; + FLAC__int32 q; + for (i = 0; i < order; i++) { + error += lp_coeff[i] * (1 << *shift); + q = lround(error); #ifdef FLAC__OVERFLOW_DETECT - if(q > qmax+1) /* we expect q==qmax+1 occasionally due to rounding */ - fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmax,*shift,cmax,precision+1,i,lp_coeff[i]); - else if(q < qmin) - fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q qmax + 1) { /* we expect q==qmax+1 occasionally due to rounding */ + fprintf(stderr, "FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n", q, qmax, *shift, cmax, precision + 1, i, lp_coeff[i]); + } else if (q < qmin) { + fprintf(stderr, "FLAC__lpc_quantize_coefficients: quantizer overflow: q qmax) - q = qmax; - else if(q < qmin) - q = qmin; - error -= q; - qlp_coeff[i] = q; - } - } - /* negative shift is very rare but due to design flaw, negative shift is - * not allowed in the decoder, so it must be handled specially by scaling - * down coeffs - */ - else { - const int nshift = -(*shift); - double error = 0.0; - FLAC__int32 q; + if (q > qmax) { + q = qmax; + } else if (q < qmin) { + q = qmin; + } + error -= q; + qlp_coeff[i] = q; + } + } + /* negative shift is very rare but due to design flaw, negative shift is + not allowed in the decoder, so it must be handled specially by scaling + down coeffs + */ + else { + const int nshift = -(*shift); + double error = 0.0; + FLAC__int32 q; #ifndef NDEBUG - fprintf(stderr,"FLAC__lpc_quantize_coefficients: negative shift=%d order=%u cmax=%f\n", *shift, order, cmax); + fprintf(stderr, "FLAC__lpc_quantize_coefficients: negative shift=%d order=%u cmax=%f\n", *shift, order, cmax); #endif - for(i = 0; i < order; i++) { - error += lp_coeff[i] / (1 << nshift); - q = lround(error); + for (i = 0; i < order; i++) { + error += lp_coeff[i] / (1 << nshift); + q = lround(error); #ifdef FLAC__OVERFLOW_DETECT - if(q > qmax+1) /* we expect q==qmax+1 occasionally due to rounding */ - fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmax,*shift,cmax,precision+1,i,lp_coeff[i]); - else if(q < qmin) - fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q qmax + 1) { /* we expect q==qmax+1 occasionally due to rounding */ + fprintf(stderr, "FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n", q, qmax, *shift, cmax, precision + 1, i, lp_coeff[i]); + } else if (q < qmin) { + fprintf(stderr, "FLAC__lpc_quantize_coefficients: quantizer overflow: q qmax) - q = qmax; - else if(q < qmin) - q = qmin; - error -= q; - qlp_coeff[i] = q; - } - *shift = 0; - } - - return 0; + if (q > qmax) { + q = qmax; + } else if (q < qmin) { + q = qmin; + } + error -= q; + qlp_coeff[i] = q; + } + *shift = 0; + } + + return 0; } #if defined(_MSC_VER) @@ -269,515 +278,497 @@ int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], uint32_t order, void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 * flac_restrict data, uint32_t data_len, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization, FLAC__int32 * flac_restrict residual) #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) { - FLAC__int64 sumo; - uint32_t i, j; - FLAC__int32 sum; - const FLAC__int32 *history; + FLAC__int64 sumo; + uint32_t i, j; + FLAC__int32 sum; + const FLAC__int32 *history; #ifdef FLAC__OVERFLOW_DETECT_VERBOSE - fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization); - for(i=0;i 0); - - for(i = 0; i < data_len; i++) { - sumo = 0; - sum = 0; - history = data; - for(j = 0; j < order; j++) { - sum += qlp_coeff[j] * (*(--history)); - sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history); - if(sumo > 2147483647ll || sumo < -2147483648ll) - fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%" PRId64 "\n",i,j,qlp_coeff[j],*history,sumo); - } - *(residual++) = *(data++) - (sum >> lp_quantization); - } - - /* Here's a slower but clearer version: - for(i = 0; i < data_len; i++) { - sum = 0; - for(j = 0; j < order; j++) - sum += qlp_coeff[j] * data[i-j-1]; - residual[i] = data[i] - (sum >> lp_quantization); - } - */ + FLAC__ASSERT(order > 0); + + for (i = 0; i < data_len; i++) { + sumo = 0; + sum = 0; + history = data; + for (j = 0; j < order; j++) { + sum += qlp_coeff[j] * (*(--history)); + sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history); + if (sumo > 2147483647ll || sumo < -2147483648ll) { + fprintf(stderr, "FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%" PRId64 "\n", i, j, qlp_coeff[j], *history, sumo); + } + } + *(residual++) = *(data++) - (sum >> lp_quantization); + } + + /* Here's a slower but clearer version: + for(i = 0; i < data_len; i++) { + sum = 0; + for(j = 0; j < order; j++) + sum += qlp_coeff[j] * data[i-j-1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + */ } #else /* fully unrolled version for normal use */ { - int i; - FLAC__int32 sum; - - FLAC__ASSERT(order > 0); - FLAC__ASSERT(order <= 32); - - /* - * We do unique versions up to 12th order since that's the subset limit. - * Also they are roughly ordered to match frequency of occurrence to - * minimize branching. - */ - if(order <= 12) { - if(order > 8) { - if(order > 10) { - if(order == 12) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[11] * data[i-12]; - sum += qlp_coeff[10] * data[i-11]; - sum += qlp_coeff[9] * data[i-10]; - sum += qlp_coeff[8] * data[i-9]; - sum += qlp_coeff[7] * data[i-8]; - sum += qlp_coeff[6] * data[i-7]; - sum += qlp_coeff[5] * data[i-6]; - sum += qlp_coeff[4] * data[i-5]; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - residual[i] = data[i] - (sum >> lp_quantization); - } - } - else { /* order == 11 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[10] * data[i-11]; - sum += qlp_coeff[9] * data[i-10]; - sum += qlp_coeff[8] * data[i-9]; - sum += qlp_coeff[7] * data[i-8]; - sum += qlp_coeff[6] * data[i-7]; - sum += qlp_coeff[5] * data[i-6]; - sum += qlp_coeff[4] * data[i-5]; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - residual[i] = data[i] - (sum >> lp_quantization); - } - } - } - else { - if(order == 10) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[9] * data[i-10]; - sum += qlp_coeff[8] * data[i-9]; - sum += qlp_coeff[7] * data[i-8]; - sum += qlp_coeff[6] * data[i-7]; - sum += qlp_coeff[5] * data[i-6]; - sum += qlp_coeff[4] * data[i-5]; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - residual[i] = data[i] - (sum >> lp_quantization); - } - } - else { /* order == 9 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[8] * data[i-9]; - sum += qlp_coeff[7] * data[i-8]; - sum += qlp_coeff[6] * data[i-7]; - sum += qlp_coeff[5] * data[i-6]; - sum += qlp_coeff[4] * data[i-5]; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - residual[i] = data[i] - (sum >> lp_quantization); - } - } - } - } - else if(order > 4) { - if(order > 6) { - if(order == 8) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[7] * data[i-8]; - sum += qlp_coeff[6] * data[i-7]; - sum += qlp_coeff[5] * data[i-6]; - sum += qlp_coeff[4] * data[i-5]; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - residual[i] = data[i] - (sum >> lp_quantization); - } - } - else { /* order == 7 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[6] * data[i-7]; - sum += qlp_coeff[5] * data[i-6]; - sum += qlp_coeff[4] * data[i-5]; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - residual[i] = data[i] - (sum >> lp_quantization); - } - } - } - else { - if(order == 6) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[5] * data[i-6]; - sum += qlp_coeff[4] * data[i-5]; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - residual[i] = data[i] - (sum >> lp_quantization); - } - } - else { /* order == 5 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[4] * data[i-5]; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - residual[i] = data[i] - (sum >> lp_quantization); - } - } - } - } - else { - if(order > 2) { - if(order == 4) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - residual[i] = data[i] - (sum >> lp_quantization); - } - } - else { /* order == 3 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - residual[i] = data[i] - (sum >> lp_quantization); - } - } - } - else { - if(order == 2) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - residual[i] = data[i] - (sum >> lp_quantization); - } - } - else { /* order == 1 */ - for(i = 0; i < (int)data_len; i++) - residual[i] = data[i] - ((qlp_coeff[0] * data[i-1]) >> lp_quantization); - } - } - } - } - else { /* order > 12 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - switch(order) { - case 32: sum += qlp_coeff[31] * data[i-32]; /* Falls through. */ - case 31: sum += qlp_coeff[30] * data[i-31]; /* Falls through. */ - case 30: sum += qlp_coeff[29] * data[i-30]; /* Falls through. */ - case 29: sum += qlp_coeff[28] * data[i-29]; /* Falls through. */ - case 28: sum += qlp_coeff[27] * data[i-28]; /* Falls through. */ - case 27: sum += qlp_coeff[26] * data[i-27]; /* Falls through. */ - case 26: sum += qlp_coeff[25] * data[i-26]; /* Falls through. */ - case 25: sum += qlp_coeff[24] * data[i-25]; /* Falls through. */ - case 24: sum += qlp_coeff[23] * data[i-24]; /* Falls through. */ - case 23: sum += qlp_coeff[22] * data[i-23]; /* Falls through. */ - case 22: sum += qlp_coeff[21] * data[i-22]; /* Falls through. */ - case 21: sum += qlp_coeff[20] * data[i-21]; /* Falls through. */ - case 20: sum += qlp_coeff[19] * data[i-20]; /* Falls through. */ - case 19: sum += qlp_coeff[18] * data[i-19]; /* Falls through. */ - case 18: sum += qlp_coeff[17] * data[i-18]; /* Falls through. */ - case 17: sum += qlp_coeff[16] * data[i-17]; /* Falls through. */ - case 16: sum += qlp_coeff[15] * data[i-16]; /* Falls through. */ - case 15: sum += qlp_coeff[14] * data[i-15]; /* Falls through. */ - case 14: sum += qlp_coeff[13] * data[i-14]; /* Falls through. */ - case 13: sum += qlp_coeff[12] * data[i-13]; - sum += qlp_coeff[11] * data[i-12]; - sum += qlp_coeff[10] * data[i-11]; - sum += qlp_coeff[ 9] * data[i-10]; - sum += qlp_coeff[ 8] * data[i- 9]; - sum += qlp_coeff[ 7] * data[i- 8]; - sum += qlp_coeff[ 6] * data[i- 7]; - sum += qlp_coeff[ 5] * data[i- 6]; - sum += qlp_coeff[ 4] * data[i- 5]; - sum += qlp_coeff[ 3] * data[i- 4]; - sum += qlp_coeff[ 2] * data[i- 3]; - sum += qlp_coeff[ 1] * data[i- 2]; - sum += qlp_coeff[ 0] * data[i- 1]; - } - residual[i] = data[i] - (sum >> lp_quantization); - } - } + int i; + FLAC__int32 sum; + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + /* + We do unique versions up to 12th order since that's the subset limit. + Also they are roughly ordered to match frequency of occurrence to + minimize branching. + */ + if (order <= 12) { + if (order > 8) { + if (order > 10) { + if (order == 12) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[11] * data[i - 12]; + sum += qlp_coeff[10] * data[i - 11]; + sum += qlp_coeff[9] * data[i - 10]; + sum += qlp_coeff[8] * data[i - 9]; + sum += qlp_coeff[7] * data[i - 8]; + sum += qlp_coeff[6] * data[i - 7]; + sum += qlp_coeff[5] * data[i - 6]; + sum += qlp_coeff[4] * data[i - 5]; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } else { /* order == 11 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[10] * data[i - 11]; + sum += qlp_coeff[9] * data[i - 10]; + sum += qlp_coeff[8] * data[i - 9]; + sum += qlp_coeff[7] * data[i - 8]; + sum += qlp_coeff[6] * data[i - 7]; + sum += qlp_coeff[5] * data[i - 6]; + sum += qlp_coeff[4] * data[i - 5]; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } + } else { + if (order == 10) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[9] * data[i - 10]; + sum += qlp_coeff[8] * data[i - 9]; + sum += qlp_coeff[7] * data[i - 8]; + sum += qlp_coeff[6] * data[i - 7]; + sum += qlp_coeff[5] * data[i - 6]; + sum += qlp_coeff[4] * data[i - 5]; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } else { /* order == 9 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[8] * data[i - 9]; + sum += qlp_coeff[7] * data[i - 8]; + sum += qlp_coeff[6] * data[i - 7]; + sum += qlp_coeff[5] * data[i - 6]; + sum += qlp_coeff[4] * data[i - 5]; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } + } + } else if (order > 4) { + if (order > 6) { + if (order == 8) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[7] * data[i - 8]; + sum += qlp_coeff[6] * data[i - 7]; + sum += qlp_coeff[5] * data[i - 6]; + sum += qlp_coeff[4] * data[i - 5]; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } else { /* order == 7 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[6] * data[i - 7]; + sum += qlp_coeff[5] * data[i - 6]; + sum += qlp_coeff[4] * data[i - 5]; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } + } else { + if (order == 6) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[5] * data[i - 6]; + sum += qlp_coeff[4] * data[i - 5]; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } else { /* order == 5 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[4] * data[i - 5]; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } + } + } else { + if (order > 2) { + if (order == 4) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } else { /* order == 3 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } + } else { + if (order == 2) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + residual[i] = data[i] - (sum >> lp_quantization); + } + } else { /* order == 1 */ + for (i = 0; i < (int)data_len; i++) { + residual[i] = data[i] - ((qlp_coeff[0] * data[i - 1]) >> lp_quantization); + } + } + } + } + } else { /* order > 12 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + switch (order) { + case 32: sum += qlp_coeff[31] * data[i - 32]; /* Falls through. */ + case 31: sum += qlp_coeff[30] * data[i - 31]; /* Falls through. */ + case 30: sum += qlp_coeff[29] * data[i - 30]; /* Falls through. */ + case 29: sum += qlp_coeff[28] * data[i - 29]; /* Falls through. */ + case 28: sum += qlp_coeff[27] * data[i - 28]; /* Falls through. */ + case 27: sum += qlp_coeff[26] * data[i - 27]; /* Falls through. */ + case 26: sum += qlp_coeff[25] * data[i - 26]; /* Falls through. */ + case 25: sum += qlp_coeff[24] * data[i - 25]; /* Falls through. */ + case 24: sum += qlp_coeff[23] * data[i - 24]; /* Falls through. */ + case 23: sum += qlp_coeff[22] * data[i - 23]; /* Falls through. */ + case 22: sum += qlp_coeff[21] * data[i - 22]; /* Falls through. */ + case 21: sum += qlp_coeff[20] * data[i - 21]; /* Falls through. */ + case 20: sum += qlp_coeff[19] * data[i - 20]; /* Falls through. */ + case 19: sum += qlp_coeff[18] * data[i - 19]; /* Falls through. */ + case 18: sum += qlp_coeff[17] * data[i - 18]; /* Falls through. */ + case 17: sum += qlp_coeff[16] * data[i - 17]; /* Falls through. */ + case 16: sum += qlp_coeff[15] * data[i - 16]; /* Falls through. */ + case 15: sum += qlp_coeff[14] * data[i - 15]; /* Falls through. */ + case 14: sum += qlp_coeff[13] * data[i - 14]; /* Falls through. */ + case 13: sum += qlp_coeff[12] * data[i - 13]; + sum += qlp_coeff[11] * data[i - 12]; + sum += qlp_coeff[10] * data[i - 11]; + sum += qlp_coeff[ 9] * data[i - 10]; + sum += qlp_coeff[ 8] * data[i - 9]; + sum += qlp_coeff[ 7] * data[i - 8]; + sum += qlp_coeff[ 6] * data[i - 7]; + sum += qlp_coeff[ 5] * data[i - 6]; + sum += qlp_coeff[ 4] * data[i - 5]; + sum += qlp_coeff[ 3] * data[i - 4]; + sum += qlp_coeff[ 2] * data[i - 3]; + sum += qlp_coeff[ 1] * data[i - 2]; + sum += qlp_coeff[ 0] * data[i - 1]; + } + residual[i] = data[i] - (sum >> lp_quantization); + } + } } #endif void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * flac_restrict data, uint32_t data_len, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization, FLAC__int32 * flac_restrict residual) #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) { - uint32_t i, j; - FLAC__int64 sum; - const FLAC__int32 *history; + uint32_t i, j; + FLAC__int64 sum; + const FLAC__int32 *history; #ifdef FLAC__OVERFLOW_DETECT_VERBOSE - fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization); - for(i=0;i 0); - - for(i = 0; i < data_len; i++) { - sum = 0; - history = data; - for(j = 0; j < order; j++) - sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); - if(FLAC__bitmath_silog2(sum >> lp_quantization) > 32) { - fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=%" PRId64 "\n", i, (sum >> lp_quantization)); - break; - } - if(FLAC__bitmath_silog2((FLAC__int64)(*data) - (sum >> lp_quantization)) > 32) { - fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, data=%d, sum=%" PRId64 ", residual=%" PRId64 "\n", i, *data, (int64_t)(sum >> lp_quantization), ((FLAC__int64)(*data) - (sum >> lp_quantization))); - break; - } - *(residual++) = *(data++) - (FLAC__int32)(sum >> lp_quantization); - } + FLAC__ASSERT(order > 0); + + for (i = 0; i < data_len; i++) { + sum = 0; + history = data; + for (j = 0; j < order; j++) { + sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); + } + if (FLAC__bitmath_silog2(sum >> lp_quantization) > 32) { + fprintf(stderr, "FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=%" PRId64 "\n", i, (sum >> lp_quantization)); + break; + } + if (FLAC__bitmath_silog2((FLAC__int64)(*data) - (sum >> lp_quantization)) > 32) { + fprintf(stderr, "FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, data=%d, sum=%" PRId64 ", residual=%" PRId64 "\n", i, *data, (int64_t)(sum >> lp_quantization), ((FLAC__int64)(*data) - (sum >> lp_quantization))); + break; + } + *(residual++) = *(data++) - (FLAC__int32)(sum >> lp_quantization); + } } #else /* fully unrolled version for normal use */ { - int i; - FLAC__int64 sum; - - FLAC__ASSERT(order > 0); - FLAC__ASSERT(order <= 32); - - /* - * We do unique versions up to 12th order since that's the subset limit. - * Also they are roughly ordered to match frequency of occurrence to - * minimize branching. - */ - if(order <= 12) { - if(order > 8) { - if(order > 10) { - if(order == 12) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; - sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; - sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; - sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; - sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; - sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; - sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; - sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); - } - } - else { /* order == 11 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; - sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; - sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; - sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; - sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; - sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; - sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); - } - } - } - else { - if(order == 10) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; - sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; - sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; - sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; - sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; - sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); - } - } - else { /* order == 9 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; - sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; - sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; - sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; - sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); - } - } - } - } - else if(order > 4) { - if(order > 6) { - if(order == 8) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; - sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; - sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; - sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); - } - } - else { /* order == 7 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; - sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; - sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); - } - } - } - else { - if(order == 6) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; - sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); - } - } - else { /* order == 5 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); - } - } - } - } - else { - if(order > 2) { - if(order == 4) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); - } - } - else { /* order == 3 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); - } - } - } - else { - if(order == 2) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); - } - } - else { /* order == 1 */ - for(i = 0; i < (int)data_len; i++) - residual[i] = data[i] - (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization); - } - } - } - } - else { /* order > 12 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - switch(order) { - case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32]; /* Falls through. */ - case 31: sum += qlp_coeff[30] * (FLAC__int64)data[i-31]; /* Falls through. */ - case 30: sum += qlp_coeff[29] * (FLAC__int64)data[i-30]; /* Falls through. */ - case 29: sum += qlp_coeff[28] * (FLAC__int64)data[i-29]; /* Falls through. */ - case 28: sum += qlp_coeff[27] * (FLAC__int64)data[i-28]; /* Falls through. */ - case 27: sum += qlp_coeff[26] * (FLAC__int64)data[i-27]; /* Falls through. */ - case 26: sum += qlp_coeff[25] * (FLAC__int64)data[i-26]; /* Falls through. */ - case 25: sum += qlp_coeff[24] * (FLAC__int64)data[i-25]; /* Falls through. */ - case 24: sum += qlp_coeff[23] * (FLAC__int64)data[i-24]; /* Falls through. */ - case 23: sum += qlp_coeff[22] * (FLAC__int64)data[i-23]; /* Falls through. */ - case 22: sum += qlp_coeff[21] * (FLAC__int64)data[i-22]; /* Falls through. */ - case 21: sum += qlp_coeff[20] * (FLAC__int64)data[i-21]; /* Falls through. */ - case 20: sum += qlp_coeff[19] * (FLAC__int64)data[i-20]; /* Falls through. */ - case 19: sum += qlp_coeff[18] * (FLAC__int64)data[i-19]; /* Falls through. */ - case 18: sum += qlp_coeff[17] * (FLAC__int64)data[i-18]; /* Falls through. */ - case 17: sum += qlp_coeff[16] * (FLAC__int64)data[i-17]; /* Falls through. */ - case 16: sum += qlp_coeff[15] * (FLAC__int64)data[i-16]; /* Falls through. */ - case 15: sum += qlp_coeff[14] * (FLAC__int64)data[i-15]; /* Falls through. */ - case 14: sum += qlp_coeff[13] * (FLAC__int64)data[i-14]; /* Falls through. */ - case 13: sum += qlp_coeff[12] * (FLAC__int64)data[i-13]; - sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; - sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; - sum += qlp_coeff[ 9] * (FLAC__int64)data[i-10]; - sum += qlp_coeff[ 8] * (FLAC__int64)data[i- 9]; - sum += qlp_coeff[ 7] * (FLAC__int64)data[i- 8]; - sum += qlp_coeff[ 6] * (FLAC__int64)data[i- 7]; - sum += qlp_coeff[ 5] * (FLAC__int64)data[i- 6]; - sum += qlp_coeff[ 4] * (FLAC__int64)data[i- 5]; - sum += qlp_coeff[ 3] * (FLAC__int64)data[i- 4]; - sum += qlp_coeff[ 2] * (FLAC__int64)data[i- 3]; - sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2]; - sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1]; - } - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); - } - } + int i; + FLAC__int64 sum; + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + /* + We do unique versions up to 12th order since that's the subset limit. + Also they are roughly ordered to match frequency of occurrence to + minimize branching. + */ + if (order <= 12) { + if (order > 8) { + if (order > 10) { + if (order == 12) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[11] * (FLAC__int64)data[i - 12]; + sum += qlp_coeff[10] * (FLAC__int64)data[i - 11]; + sum += qlp_coeff[9] * (FLAC__int64)data[i - 10]; + sum += qlp_coeff[8] * (FLAC__int64)data[i - 9]; + sum += qlp_coeff[7] * (FLAC__int64)data[i - 8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i - 7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i - 6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } else { /* order == 11 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[10] * (FLAC__int64)data[i - 11]; + sum += qlp_coeff[9] * (FLAC__int64)data[i - 10]; + sum += qlp_coeff[8] * (FLAC__int64)data[i - 9]; + sum += qlp_coeff[7] * (FLAC__int64)data[i - 8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i - 7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i - 6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + } else { + if (order == 10) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[9] * (FLAC__int64)data[i - 10]; + sum += qlp_coeff[8] * (FLAC__int64)data[i - 9]; + sum += qlp_coeff[7] * (FLAC__int64)data[i - 8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i - 7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i - 6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } else { /* order == 9 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[8] * (FLAC__int64)data[i - 9]; + sum += qlp_coeff[7] * (FLAC__int64)data[i - 8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i - 7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i - 6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + } + } else if (order > 4) { + if (order > 6) { + if (order == 8) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[7] * (FLAC__int64)data[i - 8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i - 7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i - 6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } else { /* order == 7 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[6] * (FLAC__int64)data[i - 7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i - 6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + } else { + if (order == 6) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[5] * (FLAC__int64)data[i - 6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } else { /* order == 5 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + } + } else { + if (order > 2) { + if (order == 4) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } else { /* order == 3 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } + } else { + if (order == 2) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } else { /* order == 1 */ + for (i = 0; i < (int)data_len; i++) { + residual[i] = data[i] - (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i - 1]) >> lp_quantization); + } + } + } + } + } else { /* order > 12 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + switch (order) { + case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i - 32]; /* Falls through. */ + case 31: sum += qlp_coeff[30] * (FLAC__int64)data[i - 31]; /* Falls through. */ + case 30: sum += qlp_coeff[29] * (FLAC__int64)data[i - 30]; /* Falls through. */ + case 29: sum += qlp_coeff[28] * (FLAC__int64)data[i - 29]; /* Falls through. */ + case 28: sum += qlp_coeff[27] * (FLAC__int64)data[i - 28]; /* Falls through. */ + case 27: sum += qlp_coeff[26] * (FLAC__int64)data[i - 27]; /* Falls through. */ + case 26: sum += qlp_coeff[25] * (FLAC__int64)data[i - 26]; /* Falls through. */ + case 25: sum += qlp_coeff[24] * (FLAC__int64)data[i - 25]; /* Falls through. */ + case 24: sum += qlp_coeff[23] * (FLAC__int64)data[i - 24]; /* Falls through. */ + case 23: sum += qlp_coeff[22] * (FLAC__int64)data[i - 23]; /* Falls through. */ + case 22: sum += qlp_coeff[21] * (FLAC__int64)data[i - 22]; /* Falls through. */ + case 21: sum += qlp_coeff[20] * (FLAC__int64)data[i - 21]; /* Falls through. */ + case 20: sum += qlp_coeff[19] * (FLAC__int64)data[i - 20]; /* Falls through. */ + case 19: sum += qlp_coeff[18] * (FLAC__int64)data[i - 19]; /* Falls through. */ + case 18: sum += qlp_coeff[17] * (FLAC__int64)data[i - 18]; /* Falls through. */ + case 17: sum += qlp_coeff[16] * (FLAC__int64)data[i - 17]; /* Falls through. */ + case 16: sum += qlp_coeff[15] * (FLAC__int64)data[i - 16]; /* Falls through. */ + case 15: sum += qlp_coeff[14] * (FLAC__int64)data[i - 15]; /* Falls through. */ + case 14: sum += qlp_coeff[13] * (FLAC__int64)data[i - 14]; /* Falls through. */ + case 13: sum += qlp_coeff[12] * (FLAC__int64)data[i - 13]; + sum += qlp_coeff[11] * (FLAC__int64)data[i - 12]; + sum += qlp_coeff[10] * (FLAC__int64)data[i - 11]; + sum += qlp_coeff[ 9] * (FLAC__int64)data[i - 10]; + sum += qlp_coeff[ 8] * (FLAC__int64)data[i - 9]; + sum += qlp_coeff[ 7] * (FLAC__int64)data[i - 8]; + sum += qlp_coeff[ 6] * (FLAC__int64)data[i - 7]; + sum += qlp_coeff[ 5] * (FLAC__int64)data[i - 6]; + sum += qlp_coeff[ 4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[ 3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[ 2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[ 1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[ 0] * (FLAC__int64)data[i - 1]; + } + residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + } + } } #endif @@ -786,515 +777,497 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f void FLAC__lpc_restore_signal(const FLAC__int32 * flac_restrict residual, uint32_t data_len, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization, FLAC__int32 * flac_restrict data) #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) { - FLAC__int64 sumo; - uint32_t i, j; - FLAC__int32 sum; - const FLAC__int32 *r = residual, *history; + FLAC__int64 sumo; + uint32_t i, j; + FLAC__int32 sum; + const FLAC__int32 *r = residual, *history; #ifdef FLAC__OVERFLOW_DETECT_VERBOSE - fprintf(stderr,"FLAC__lpc_restore_signal: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization); - for(i=0;i 0); - - for(i = 0; i < data_len; i++) { - sumo = 0; - sum = 0; - history = data; - for(j = 0; j < order; j++) { - sum += qlp_coeff[j] * (*(--history)); - sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history); - if(sumo > 2147483647ll || sumo < -2147483648ll) - fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%" PRId64 "\n",i,j,qlp_coeff[j],*history,sumo); - } - *(data++) = *(r++) + (sum >> lp_quantization); - } - - /* Here's a slower but clearer version: - for(i = 0; i < data_len; i++) { - sum = 0; - for(j = 0; j < order; j++) - sum += qlp_coeff[j] * data[i-j-1]; - data[i] = residual[i] + (sum >> lp_quantization); - } - */ + FLAC__ASSERT(order > 0); + + for (i = 0; i < data_len; i++) { + sumo = 0; + sum = 0; + history = data; + for (j = 0; j < order; j++) { + sum += qlp_coeff[j] * (*(--history)); + sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history); + if (sumo > 2147483647ll || sumo < -2147483648ll) { + fprintf(stderr, "FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%" PRId64 "\n", i, j, qlp_coeff[j], *history, sumo); + } + } + *(data++) = *(r++) + (sum >> lp_quantization); + } + + /* Here's a slower but clearer version: + for(i = 0; i < data_len; i++) { + sum = 0; + for(j = 0; j < order; j++) + sum += qlp_coeff[j] * data[i-j-1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + */ } #else /* fully unrolled version for normal use */ { - int i; - FLAC__int32 sum; - - FLAC__ASSERT(order > 0); - FLAC__ASSERT(order <= 32); - - /* - * We do unique versions up to 12th order since that's the subset limit. - * Also they are roughly ordered to match frequency of occurrence to - * minimize branching. - */ - if(order <= 12) { - if(order > 8) { - if(order > 10) { - if(order == 12) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[11] * data[i-12]; - sum += qlp_coeff[10] * data[i-11]; - sum += qlp_coeff[9] * data[i-10]; - sum += qlp_coeff[8] * data[i-9]; - sum += qlp_coeff[7] * data[i-8]; - sum += qlp_coeff[6] * data[i-7]; - sum += qlp_coeff[5] * data[i-6]; - sum += qlp_coeff[4] * data[i-5]; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - data[i] = residual[i] + (sum >> lp_quantization); - } - } - else { /* order == 11 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[10] * data[i-11]; - sum += qlp_coeff[9] * data[i-10]; - sum += qlp_coeff[8] * data[i-9]; - sum += qlp_coeff[7] * data[i-8]; - sum += qlp_coeff[6] * data[i-7]; - sum += qlp_coeff[5] * data[i-6]; - sum += qlp_coeff[4] * data[i-5]; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - data[i] = residual[i] + (sum >> lp_quantization); - } - } - } - else { - if(order == 10) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[9] * data[i-10]; - sum += qlp_coeff[8] * data[i-9]; - sum += qlp_coeff[7] * data[i-8]; - sum += qlp_coeff[6] * data[i-7]; - sum += qlp_coeff[5] * data[i-6]; - sum += qlp_coeff[4] * data[i-5]; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - data[i] = residual[i] + (sum >> lp_quantization); - } - } - else { /* order == 9 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[8] * data[i-9]; - sum += qlp_coeff[7] * data[i-8]; - sum += qlp_coeff[6] * data[i-7]; - sum += qlp_coeff[5] * data[i-6]; - sum += qlp_coeff[4] * data[i-5]; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - data[i] = residual[i] + (sum >> lp_quantization); - } - } - } - } - else if(order > 4) { - if(order > 6) { - if(order == 8) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[7] * data[i-8]; - sum += qlp_coeff[6] * data[i-7]; - sum += qlp_coeff[5] * data[i-6]; - sum += qlp_coeff[4] * data[i-5]; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - data[i] = residual[i] + (sum >> lp_quantization); - } - } - else { /* order == 7 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[6] * data[i-7]; - sum += qlp_coeff[5] * data[i-6]; - sum += qlp_coeff[4] * data[i-5]; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - data[i] = residual[i] + (sum >> lp_quantization); - } - } - } - else { - if(order == 6) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[5] * data[i-6]; - sum += qlp_coeff[4] * data[i-5]; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - data[i] = residual[i] + (sum >> lp_quantization); - } - } - else { /* order == 5 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[4] * data[i-5]; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - data[i] = residual[i] + (sum >> lp_quantization); - } - } - } - } - else { - if(order > 2) { - if(order == 4) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[3] * data[i-4]; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - data[i] = residual[i] + (sum >> lp_quantization); - } - } - else { /* order == 3 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[2] * data[i-3]; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - data[i] = residual[i] + (sum >> lp_quantization); - } - } - } - else { - if(order == 2) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[1] * data[i-2]; - sum += qlp_coeff[0] * data[i-1]; - data[i] = residual[i] + (sum >> lp_quantization); - } - } - else { /* order == 1 */ - for(i = 0; i < (int)data_len; i++) - data[i] = residual[i] + ((qlp_coeff[0] * data[i-1]) >> lp_quantization); - } - } - } - } - else { /* order > 12 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - switch(order) { - case 32: sum += qlp_coeff[31] * data[i-32]; /* Falls through. */ - case 31: sum += qlp_coeff[30] * data[i-31]; /* Falls through. */ - case 30: sum += qlp_coeff[29] * data[i-30]; /* Falls through. */ - case 29: sum += qlp_coeff[28] * data[i-29]; /* Falls through. */ - case 28: sum += qlp_coeff[27] * data[i-28]; /* Falls through. */ - case 27: sum += qlp_coeff[26] * data[i-27]; /* Falls through. */ - case 26: sum += qlp_coeff[25] * data[i-26]; /* Falls through. */ - case 25: sum += qlp_coeff[24] * data[i-25]; /* Falls through. */ - case 24: sum += qlp_coeff[23] * data[i-24]; /* Falls through. */ - case 23: sum += qlp_coeff[22] * data[i-23]; /* Falls through. */ - case 22: sum += qlp_coeff[21] * data[i-22]; /* Falls through. */ - case 21: sum += qlp_coeff[20] * data[i-21]; /* Falls through. */ - case 20: sum += qlp_coeff[19] * data[i-20]; /* Falls through. */ - case 19: sum += qlp_coeff[18] * data[i-19]; /* Falls through. */ - case 18: sum += qlp_coeff[17] * data[i-18]; /* Falls through. */ - case 17: sum += qlp_coeff[16] * data[i-17]; /* Falls through. */ - case 16: sum += qlp_coeff[15] * data[i-16]; /* Falls through. */ - case 15: sum += qlp_coeff[14] * data[i-15]; /* Falls through. */ - case 14: sum += qlp_coeff[13] * data[i-14]; /* Falls through. */ - case 13: sum += qlp_coeff[12] * data[i-13]; - sum += qlp_coeff[11] * data[i-12]; - sum += qlp_coeff[10] * data[i-11]; - sum += qlp_coeff[ 9] * data[i-10]; - sum += qlp_coeff[ 8] * data[i- 9]; - sum += qlp_coeff[ 7] * data[i- 8]; - sum += qlp_coeff[ 6] * data[i- 7]; - sum += qlp_coeff[ 5] * data[i- 6]; - sum += qlp_coeff[ 4] * data[i- 5]; - sum += qlp_coeff[ 3] * data[i- 4]; - sum += qlp_coeff[ 2] * data[i- 3]; - sum += qlp_coeff[ 1] * data[i- 2]; - sum += qlp_coeff[ 0] * data[i- 1]; - } - data[i] = residual[i] + (sum >> lp_quantization); - } - } + int i; + FLAC__int32 sum; + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + /* + We do unique versions up to 12th order since that's the subset limit. + Also they are roughly ordered to match frequency of occurrence to + minimize branching. + */ + if (order <= 12) { + if (order > 8) { + if (order > 10) { + if (order == 12) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[11] * data[i - 12]; + sum += qlp_coeff[10] * data[i - 11]; + sum += qlp_coeff[9] * data[i - 10]; + sum += qlp_coeff[8] * data[i - 9]; + sum += qlp_coeff[7] * data[i - 8]; + sum += qlp_coeff[6] * data[i - 7]; + sum += qlp_coeff[5] * data[i - 6]; + sum += qlp_coeff[4] * data[i - 5]; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } else { /* order == 11 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[10] * data[i - 11]; + sum += qlp_coeff[9] * data[i - 10]; + sum += qlp_coeff[8] * data[i - 9]; + sum += qlp_coeff[7] * data[i - 8]; + sum += qlp_coeff[6] * data[i - 7]; + sum += qlp_coeff[5] * data[i - 6]; + sum += qlp_coeff[4] * data[i - 5]; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } + } else { + if (order == 10) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[9] * data[i - 10]; + sum += qlp_coeff[8] * data[i - 9]; + sum += qlp_coeff[7] * data[i - 8]; + sum += qlp_coeff[6] * data[i - 7]; + sum += qlp_coeff[5] * data[i - 6]; + sum += qlp_coeff[4] * data[i - 5]; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } else { /* order == 9 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[8] * data[i - 9]; + sum += qlp_coeff[7] * data[i - 8]; + sum += qlp_coeff[6] * data[i - 7]; + sum += qlp_coeff[5] * data[i - 6]; + sum += qlp_coeff[4] * data[i - 5]; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } + } + } else if (order > 4) { + if (order > 6) { + if (order == 8) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[7] * data[i - 8]; + sum += qlp_coeff[6] * data[i - 7]; + sum += qlp_coeff[5] * data[i - 6]; + sum += qlp_coeff[4] * data[i - 5]; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } else { /* order == 7 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[6] * data[i - 7]; + sum += qlp_coeff[5] * data[i - 6]; + sum += qlp_coeff[4] * data[i - 5]; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } + } else { + if (order == 6) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[5] * data[i - 6]; + sum += qlp_coeff[4] * data[i - 5]; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } else { /* order == 5 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[4] * data[i - 5]; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } + } + } else { + if (order > 2) { + if (order == 4) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[3] * data[i - 4]; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } else { /* order == 3 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[2] * data[i - 3]; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } + } else { + if (order == 2) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + data[i] = residual[i] + (sum >> lp_quantization); + } + } else { /* order == 1 */ + for (i = 0; i < (int)data_len; i++) { + data[i] = residual[i] + ((qlp_coeff[0] * data[i - 1]) >> lp_quantization); + } + } + } + } + } else { /* order > 12 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + switch (order) { + case 32: sum += qlp_coeff[31] * data[i - 32]; /* Falls through. */ + case 31: sum += qlp_coeff[30] * data[i - 31]; /* Falls through. */ + case 30: sum += qlp_coeff[29] * data[i - 30]; /* Falls through. */ + case 29: sum += qlp_coeff[28] * data[i - 29]; /* Falls through. */ + case 28: sum += qlp_coeff[27] * data[i - 28]; /* Falls through. */ + case 27: sum += qlp_coeff[26] * data[i - 27]; /* Falls through. */ + case 26: sum += qlp_coeff[25] * data[i - 26]; /* Falls through. */ + case 25: sum += qlp_coeff[24] * data[i - 25]; /* Falls through. */ + case 24: sum += qlp_coeff[23] * data[i - 24]; /* Falls through. */ + case 23: sum += qlp_coeff[22] * data[i - 23]; /* Falls through. */ + case 22: sum += qlp_coeff[21] * data[i - 22]; /* Falls through. */ + case 21: sum += qlp_coeff[20] * data[i - 21]; /* Falls through. */ + case 20: sum += qlp_coeff[19] * data[i - 20]; /* Falls through. */ + case 19: sum += qlp_coeff[18] * data[i - 19]; /* Falls through. */ + case 18: sum += qlp_coeff[17] * data[i - 18]; /* Falls through. */ + case 17: sum += qlp_coeff[16] * data[i - 17]; /* Falls through. */ + case 16: sum += qlp_coeff[15] * data[i - 16]; /* Falls through. */ + case 15: sum += qlp_coeff[14] * data[i - 15]; /* Falls through. */ + case 14: sum += qlp_coeff[13] * data[i - 14]; /* Falls through. */ + case 13: sum += qlp_coeff[12] * data[i - 13]; + sum += qlp_coeff[11] * data[i - 12]; + sum += qlp_coeff[10] * data[i - 11]; + sum += qlp_coeff[ 9] * data[i - 10]; + sum += qlp_coeff[ 8] * data[i - 9]; + sum += qlp_coeff[ 7] * data[i - 8]; + sum += qlp_coeff[ 6] * data[i - 7]; + sum += qlp_coeff[ 5] * data[i - 6]; + sum += qlp_coeff[ 4] * data[i - 5]; + sum += qlp_coeff[ 3] * data[i - 4]; + sum += qlp_coeff[ 2] * data[i - 3]; + sum += qlp_coeff[ 1] * data[i - 2]; + sum += qlp_coeff[ 0] * data[i - 1]; + } + data[i] = residual[i] + (sum >> lp_quantization); + } + } } #endif void FLAC__lpc_restore_signal_wide(const FLAC__int32 * flac_restrict residual, uint32_t data_len, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization, FLAC__int32 * flac_restrict data) #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) { - uint32_t i, j; - FLAC__int64 sum; - const FLAC__int32 *r = residual, *history; + uint32_t i, j; + FLAC__int64 sum; + const FLAC__int32 *r = residual, *history; #ifdef FLAC__OVERFLOW_DETECT_VERBOSE - fprintf(stderr,"FLAC__lpc_restore_signal_wide: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization); - for(i=0;i 0); - - for(i = 0; i < data_len; i++) { - sum = 0; - history = data; - for(j = 0; j < order; j++) - sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); - if(FLAC__bitmath_silog2(sum >> lp_quantization) > 32) { - fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%" PRId64 "\n", i, (sum >> lp_quantization)); - break; - } - if(FLAC__bitmath_silog2((FLAC__int64)(*r) + (sum >> lp_quantization)) > 32) { - fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, residual=%d, sum=%" PRId64 ", data=%" PRId64 "\n", i, *r, (sum >> lp_quantization), ((FLAC__int64)(*r) + (sum >> lp_quantization))); - break; - } - *(data++) = *(r++) + (FLAC__int32)(sum >> lp_quantization); - } + FLAC__ASSERT(order > 0); + + for (i = 0; i < data_len; i++) { + sum = 0; + history = data; + for (j = 0; j < order; j++) { + sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); + } + if (FLAC__bitmath_silog2(sum >> lp_quantization) > 32) { + fprintf(stderr, "FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%" PRId64 "\n", i, (sum >> lp_quantization)); + break; + } + if (FLAC__bitmath_silog2((FLAC__int64)(*r) + (sum >> lp_quantization)) > 32) { + fprintf(stderr, "FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, residual=%d, sum=%" PRId64 ", data=%" PRId64 "\n", i, *r, (sum >> lp_quantization), ((FLAC__int64)(*r) + (sum >> lp_quantization))); + break; + } + *(data++) = *(r++) + (FLAC__int32)(sum >> lp_quantization); + } } #else /* fully unrolled version for normal use */ { - int i; - FLAC__int64 sum; - - FLAC__ASSERT(order > 0); - FLAC__ASSERT(order <= 32); - - /* - * We do unique versions up to 12th order since that's the subset limit. - * Also they are roughly ordered to match frequency of occurrence to - * minimize branching. - */ - if(order <= 12) { - if(order > 8) { - if(order > 10) { - if(order == 12) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; - sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; - sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; - sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; - sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; - sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; - sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; - sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - data[i] = (FLAC__int32) (residual[i] + (sum >> lp_quantization)); - } - } - else { /* order == 11 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; - sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; - sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; - sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; - sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; - sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; - sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - data[i] = (FLAC__int32) (residual[i] + (sum >> lp_quantization)); - } - } - } - else { - if(order == 10) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; - sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; - sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; - sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; - sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; - sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - data[i] = (FLAC__int32) (residual[i] + (sum >> lp_quantization)); - } - } - else { /* order == 9 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; - sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; - sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; - sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; - sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - data[i] = (FLAC__int32) (residual[i] + (sum >> lp_quantization)); - } - } - } - } - else if(order > 4) { - if(order > 6) { - if(order == 8) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; - sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; - sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; - sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - data[i] = (FLAC__int32) (residual[i] + (sum >> lp_quantization)); - } - } - else { /* order == 7 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; - sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; - sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - data[i] = (FLAC__int32) (residual[i] + (sum >> lp_quantization)); - } - } - } - else { - if(order == 6) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; - sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - data[i] = (FLAC__int32) (residual[i] + (sum >> lp_quantization)); - } - } - else { /* order == 5 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - data[i] = (FLAC__int32) (residual[i] + (sum >> lp_quantization)); - } - } - } - } - else { - if(order > 2) { - if(order == 4) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - data[i] = (FLAC__int32) (residual[i] + (sum >> lp_quantization)); - } - } - else { /* order == 3 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - data[i] = (FLAC__int32) (residual[i] + (sum >> lp_quantization)); - } - } - } - else { - if(order == 2) { - for(i = 0; i < (int)data_len; i++) { - sum = 0; - sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; - sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - data[i] = (FLAC__int32) (residual[i] + (sum >> lp_quantization)); - } - } - else { /* order == 1 */ - for(i = 0; i < (int)data_len; i++) - data[i] = residual[i] + (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization); - } - } - } - } - else { /* order > 12 */ - for(i = 0; i < (int)data_len; i++) { - sum = 0; - switch(order) { - case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32]; /* Falls through. */ - case 31: sum += qlp_coeff[30] * (FLAC__int64)data[i-31]; /* Falls through. */ - case 30: sum += qlp_coeff[29] * (FLAC__int64)data[i-30]; /* Falls through. */ - case 29: sum += qlp_coeff[28] * (FLAC__int64)data[i-29]; /* Falls through. */ - case 28: sum += qlp_coeff[27] * (FLAC__int64)data[i-28]; /* Falls through. */ - case 27: sum += qlp_coeff[26] * (FLAC__int64)data[i-27]; /* Falls through. */ - case 26: sum += qlp_coeff[25] * (FLAC__int64)data[i-26]; /* Falls through. */ - case 25: sum += qlp_coeff[24] * (FLAC__int64)data[i-25]; /* Falls through. */ - case 24: sum += qlp_coeff[23] * (FLAC__int64)data[i-24]; /* Falls through. */ - case 23: sum += qlp_coeff[22] * (FLAC__int64)data[i-23]; /* Falls through. */ - case 22: sum += qlp_coeff[21] * (FLAC__int64)data[i-22]; /* Falls through. */ - case 21: sum += qlp_coeff[20] * (FLAC__int64)data[i-21]; /* Falls through. */ - case 20: sum += qlp_coeff[19] * (FLAC__int64)data[i-20]; /* Falls through. */ - case 19: sum += qlp_coeff[18] * (FLAC__int64)data[i-19]; /* Falls through. */ - case 18: sum += qlp_coeff[17] * (FLAC__int64)data[i-18]; /* Falls through. */ - case 17: sum += qlp_coeff[16] * (FLAC__int64)data[i-17]; /* Falls through. */ - case 16: sum += qlp_coeff[15] * (FLAC__int64)data[i-16]; /* Falls through. */ - case 15: sum += qlp_coeff[14] * (FLAC__int64)data[i-15]; /* Falls through. */ - case 14: sum += qlp_coeff[13] * (FLAC__int64)data[i-14]; /* Falls through. */ - case 13: sum += qlp_coeff[12] * (FLAC__int64)data[i-13]; - sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; - sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; - sum += qlp_coeff[ 9] * (FLAC__int64)data[i-10]; - sum += qlp_coeff[ 8] * (FLAC__int64)data[i- 9]; - sum += qlp_coeff[ 7] * (FLAC__int64)data[i- 8]; - sum += qlp_coeff[ 6] * (FLAC__int64)data[i- 7]; - sum += qlp_coeff[ 5] * (FLAC__int64)data[i- 6]; - sum += qlp_coeff[ 4] * (FLAC__int64)data[i- 5]; - sum += qlp_coeff[ 3] * (FLAC__int64)data[i- 4]; - sum += qlp_coeff[ 2] * (FLAC__int64)data[i- 3]; - sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2]; - sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1]; - } - data[i] = (FLAC__int32) (residual[i] + (sum >> lp_quantization)); - } - } + int i; + FLAC__int64 sum; + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + /* + We do unique versions up to 12th order since that's the subset limit. + Also they are roughly ordered to match frequency of occurrence to + minimize branching. + */ + if (order <= 12) { + if (order > 8) { + if (order > 10) { + if (order == 12) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[11] * (FLAC__int64)data[i - 12]; + sum += qlp_coeff[10] * (FLAC__int64)data[i - 11]; + sum += qlp_coeff[9] * (FLAC__int64)data[i - 10]; + sum += qlp_coeff[8] * (FLAC__int64)data[i - 9]; + sum += qlp_coeff[7] * (FLAC__int64)data[i - 8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i - 7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i - 6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + data[i] = (FLAC__int32)(residual[i] + (sum >> lp_quantization)); + } + } else { /* order == 11 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[10] * (FLAC__int64)data[i - 11]; + sum += qlp_coeff[9] * (FLAC__int64)data[i - 10]; + sum += qlp_coeff[8] * (FLAC__int64)data[i - 9]; + sum += qlp_coeff[7] * (FLAC__int64)data[i - 8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i - 7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i - 6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + data[i] = (FLAC__int32)(residual[i] + (sum >> lp_quantization)); + } + } + } else { + if (order == 10) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[9] * (FLAC__int64)data[i - 10]; + sum += qlp_coeff[8] * (FLAC__int64)data[i - 9]; + sum += qlp_coeff[7] * (FLAC__int64)data[i - 8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i - 7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i - 6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + data[i] = (FLAC__int32)(residual[i] + (sum >> lp_quantization)); + } + } else { /* order == 9 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[8] * (FLAC__int64)data[i - 9]; + sum += qlp_coeff[7] * (FLAC__int64)data[i - 8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i - 7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i - 6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + data[i] = (FLAC__int32)(residual[i] + (sum >> lp_quantization)); + } + } + } + } else if (order > 4) { + if (order > 6) { + if (order == 8) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[7] * (FLAC__int64)data[i - 8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i - 7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i - 6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + data[i] = (FLAC__int32)(residual[i] + (sum >> lp_quantization)); + } + } else { /* order == 7 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[6] * (FLAC__int64)data[i - 7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i - 6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + data[i] = (FLAC__int32)(residual[i] + (sum >> lp_quantization)); + } + } + } else { + if (order == 6) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[5] * (FLAC__int64)data[i - 6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + data[i] = (FLAC__int32)(residual[i] + (sum >> lp_quantization)); + } + } else { /* order == 5 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + data[i] = (FLAC__int32)(residual[i] + (sum >> lp_quantization)); + } + } + } + } else { + if (order > 2) { + if (order == 4) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + data[i] = (FLAC__int32)(residual[i] + (sum >> lp_quantization)); + } + } else { /* order == 3 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + data[i] = (FLAC__int32)(residual[i] + (sum >> lp_quantization)); + } + } + } else { + if (order == 2) { + for (i = 0; i < (int)data_len; i++) { + sum = 0; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + data[i] = (FLAC__int32)(residual[i] + (sum >> lp_quantization)); + } + } else { /* order == 1 */ + for (i = 0; i < (int)data_len; i++) { + data[i] = residual[i] + (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i - 1]) >> lp_quantization); + } + } + } + } + } else { /* order > 12 */ + for (i = 0; i < (int)data_len; i++) { + sum = 0; + switch (order) { + case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i - 32]; /* Falls through. */ + case 31: sum += qlp_coeff[30] * (FLAC__int64)data[i - 31]; /* Falls through. */ + case 30: sum += qlp_coeff[29] * (FLAC__int64)data[i - 30]; /* Falls through. */ + case 29: sum += qlp_coeff[28] * (FLAC__int64)data[i - 29]; /* Falls through. */ + case 28: sum += qlp_coeff[27] * (FLAC__int64)data[i - 28]; /* Falls through. */ + case 27: sum += qlp_coeff[26] * (FLAC__int64)data[i - 27]; /* Falls through. */ + case 26: sum += qlp_coeff[25] * (FLAC__int64)data[i - 26]; /* Falls through. */ + case 25: sum += qlp_coeff[24] * (FLAC__int64)data[i - 25]; /* Falls through. */ + case 24: sum += qlp_coeff[23] * (FLAC__int64)data[i - 24]; /* Falls through. */ + case 23: sum += qlp_coeff[22] * (FLAC__int64)data[i - 23]; /* Falls through. */ + case 22: sum += qlp_coeff[21] * (FLAC__int64)data[i - 22]; /* Falls through. */ + case 21: sum += qlp_coeff[20] * (FLAC__int64)data[i - 21]; /* Falls through. */ + case 20: sum += qlp_coeff[19] * (FLAC__int64)data[i - 20]; /* Falls through. */ + case 19: sum += qlp_coeff[18] * (FLAC__int64)data[i - 19]; /* Falls through. */ + case 18: sum += qlp_coeff[17] * (FLAC__int64)data[i - 18]; /* Falls through. */ + case 17: sum += qlp_coeff[16] * (FLAC__int64)data[i - 17]; /* Falls through. */ + case 16: sum += qlp_coeff[15] * (FLAC__int64)data[i - 16]; /* Falls through. */ + case 15: sum += qlp_coeff[14] * (FLAC__int64)data[i - 15]; /* Falls through. */ + case 14: sum += qlp_coeff[13] * (FLAC__int64)data[i - 14]; /* Falls through. */ + case 13: sum += qlp_coeff[12] * (FLAC__int64)data[i - 13]; + sum += qlp_coeff[11] * (FLAC__int64)data[i - 12]; + sum += qlp_coeff[10] * (FLAC__int64)data[i - 11]; + sum += qlp_coeff[ 9] * (FLAC__int64)data[i - 10]; + sum += qlp_coeff[ 8] * (FLAC__int64)data[i - 9]; + sum += qlp_coeff[ 7] * (FLAC__int64)data[i - 8]; + sum += qlp_coeff[ 6] * (FLAC__int64)data[i - 7]; + sum += qlp_coeff[ 5] * (FLAC__int64)data[i - 6]; + sum += qlp_coeff[ 4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[ 3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[ 2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[ 1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[ 0] * (FLAC__int64)data[i - 1]; + } + data[i] = (FLAC__int32)(residual[i] + (sum >> lp_quantization)); + } + } } #endif @@ -1304,56 +1277,52 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 * flac_restrict residual, u #ifndef FLAC__INTEGER_ONLY_LIBRARY -double FLAC__lpc_compute_expected_bits_per_residual_sample(double lpc_error, uint32_t total_samples) -{ - double error_scale; +double FLAC__lpc_compute_expected_bits_per_residual_sample(double lpc_error, uint32_t total_samples) { + double error_scale; - FLAC__ASSERT(total_samples > 0); + FLAC__ASSERT(total_samples > 0); - error_scale = 0.5 / (double)total_samples; + error_scale = 0.5 / (double)total_samples; - return FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error, error_scale); + return FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error, error_scale); } -double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(double lpc_error, double error_scale) -{ - if(lpc_error > 0.0) { - double bps = (double)0.5 * log(error_scale * lpc_error) / M_LN2; - if(bps >= 0.0) - return bps; - else - return 0.0; - } - else if(lpc_error < 0.0) { /* error should not be negative but can happen due to inadequate floating-point resolution */ - return 1e32; - } - else { - return 0.0; - } +double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(double lpc_error, double error_scale) { + if (lpc_error > 0.0) { + double bps = (double)0.5 * log(error_scale * lpc_error) / M_LN2; + if (bps >= 0.0) { + return bps; + } else { + return 0.0; + } + } else if (lpc_error < 0.0) { /* error should not be negative but can happen due to inadequate floating-point resolution */ + return 1e32; + } else { + return 0.0; + } } -uint32_t FLAC__lpc_compute_best_order(const double lpc_error[], uint32_t max_order, uint32_t total_samples, uint32_t overhead_bits_per_order) -{ - uint32_t order, indx, best_index; /* 'index' the index into lpc_error; index==order-1 since lpc_error[0] is for order==1, lpc_error[1] is for order==2, etc */ - double bits, best_bits, error_scale; +uint32_t FLAC__lpc_compute_best_order(const double lpc_error[], uint32_t max_order, uint32_t total_samples, uint32_t overhead_bits_per_order) { + uint32_t order, indx, best_index; /* 'index' the index into lpc_error; index==order-1 since lpc_error[0] is for order==1, lpc_error[1] is for order==2, etc */ + double bits, best_bits, error_scale; - FLAC__ASSERT(max_order > 0); - FLAC__ASSERT(total_samples > 0); + FLAC__ASSERT(max_order > 0); + FLAC__ASSERT(total_samples > 0); - error_scale = 0.5 / (double)total_samples; + error_scale = 0.5 / (double)total_samples; - best_index = 0; - best_bits = (uint32_t)(-1); + best_index = 0; + best_bits = (uint32_t)(-1); - for(indx = 0, order = 1; indx < max_order; indx++, order++) { - bits = FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error[indx], error_scale) * (double)(total_samples - order) + (double)(order * overhead_bits_per_order); - if(bits < best_bits) { - best_index = indx; - best_bits = bits; - } - } + for (indx = 0, order = 1; indx < max_order; indx++, order++) { + bits = FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error[indx], error_scale) * (double)(total_samples - order) + (double)(order * overhead_bits_per_order); + if (bits < best_bits) { + best_index = indx; + best_bits = bits; + } + } - return best_index+1; /* +1 since indx of lpc_error[] is order-1 */ + return best_index + 1; /* +1 since indx of lpc_error[] is order-1 */ } #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ diff --git a/src/libflac/md5.c b/src/libflac/md5.c index 19c68a6c..90880316 100644 --- a/src/libflac/md5.c +++ b/src/libflac/md5.c @@ -12,29 +12,29 @@ #pragma GCC optimize ("O3") /* - * This code implements the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - * - * Changed so as no longer to depend on Colin Plumb's `usual.h' header - * definitions; now uses stuff from dpkg's config.h. - * - Ian Jackson . - * Still in the public domain. - * - * Josh Coalson: made some changes to integrate with libFLAC. - * Still in the public domain. - */ + This code implements the MD5 message-digest algorithm. + The algorithm is due to Ron Rivest. This code was + written by Colin Plumb in 1993, no copyright is claimed. + This code is in the public domain; do with it what you wish. + + Equivalent code is available from RSA Data Security, Inc. + This code has been tested against that, and is equivalent, + except that you don't need to include two pages of legalese + with every copy. + + To compute the message digest of a chunk of bytes, declare an + MD5Context structure, pass it to MD5Init, call MD5Update as + needed on buffers full of bytes, and then call MD5Final, which + will fill a supplied 16-byte array with the digest. + + Changed so as no longer to depend on Colin Plumb's `usual.h' header + definitions; now uses stuff from dpkg's config.h. + - Ian Jackson . + Still in the public domain. + + Josh Coalson: made some changes to integrate with libFLAC. + Still in the public domain. +*/ /* The four core functions - F1 is optimized somewhat */ @@ -49,124 +49,121 @@ (w += f(x,y,z) + in, w = (w<>(32-s)) + x) /* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - */ -static void FLAC__MD5Transform(FLAC__uint32 buf[4], FLAC__uint32 const in[16]) -{ - register FLAC__uint32 a, b, c, d; - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; + The core of the MD5 algorithm, this alters an existing MD5 hash to + reflect the addition of 16 longwords of new data. MD5Update blocks + the data and converts bytes into longwords for this routine. +*/ +static void FLAC__MD5Transform(FLAC__uint32 buf[4], FLAC__uint32 const in[16]) { + register FLAC__uint32 a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; } #if WORDS_BIGENDIAN //@@@@@@ OPT: use bswap/intrinsics -static void byteSwap(FLAC__uint32 *buf, uint32_t words) -{ - register FLAC__uint32 x; - do { - x = *buf; - x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); - *buf++ = (x >> 16) | (x << 16); - } while (--words); +static void byteSwap(FLAC__uint32 *buf, uint32_t words) { + register FLAC__uint32 x; + do { + x = *buf; + x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); + *buf++ = (x >> 16) | (x << 16); + } while (--words); } -static void byteSwapX16(FLAC__uint32 *buf) -{ - register FLAC__uint32 x; - - x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); - x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); - x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); - x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); - x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); - x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); - x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); - x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); - x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); - x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); - x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); - x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); - x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); - x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); - x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); - x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf = (x >> 16) | (x << 16); +static void byteSwapX16(FLAC__uint32 *buf) { + register FLAC__uint32 x; + + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); + x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf = (x >> 16) | (x << 16); } #else #define byteSwap(buf, words) @@ -174,345 +171,349 @@ static void byteSwapX16(FLAC__uint32 *buf) #endif /* - * Update context to reflect the concatenation of another buffer full - * of bytes. - */ -static void FLAC__MD5Update(FLAC__MD5Context *ctx, FLAC__byte const *buf, uint32_t len) -{ - FLAC__uint32 t; - - /* Update byte count */ - - t = ctx->bytes[0]; - if ((ctx->bytes[0] = t + len) < t) - ctx->bytes[1]++; /* Carry from low to high */ - - t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */ - if (t > len) { - memcpy((FLAC__byte *)ctx->in + 64 - t, buf, len); - return; - } - /* First chunk is an odd size */ - memcpy((FLAC__byte *)ctx->in + 64 - t, buf, t); - byteSwapX16(ctx->in); - FLAC__MD5Transform(ctx->buf, ctx->in); - buf += t; - len -= t; - - /* Process data in 64-byte chunks */ - while (len >= 64) { - memcpy(ctx->in, buf, 64); - byteSwapX16(ctx->in); - FLAC__MD5Transform(ctx->buf, ctx->in); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - memcpy(ctx->in, buf, len); + Update context to reflect the concatenation of another buffer full + of bytes. +*/ +static void FLAC__MD5Update(FLAC__MD5Context *ctx, FLAC__byte const *buf, uint32_t len) { + FLAC__uint32 t; + + /* Update byte count */ + + t = ctx->bytes[0]; + if ((ctx->bytes[0] = t + len) < t) { + ctx->bytes[1]++; /* Carry from low to high */ + } + + t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */ + if (t > len) { + memcpy((FLAC__byte *)ctx->in + 64 - t, buf, len); + return; + } + /* First chunk is an odd size */ + memcpy((FLAC__byte *)ctx->in + 64 - t, buf, t); + byteSwapX16(ctx->in); + FLAC__MD5Transform(ctx->buf, ctx->in); + buf += t; + len -= t; + + /* Process data in 64-byte chunks */ + while (len >= 64) { + memcpy(ctx->in, buf, 64); + byteSwapX16(ctx->in); + FLAC__MD5Transform(ctx->buf, ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + memcpy(ctx->in, buf, len); } /* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. - */ -void FLAC__MD5Init(FLAC__MD5Context *ctx) -{ - ctx->buf[0] = 0x67452301; - ctx->buf[1] = 0xefcdab89; - ctx->buf[2] = 0x98badcfe; - ctx->buf[3] = 0x10325476; - - ctx->bytes[0] = 0; - ctx->bytes[1] = 0; - - ctx->internal_buf.p8 = 0; - ctx->capacity = 0; + Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + initialization constants. +*/ +void FLAC__MD5Init(FLAC__MD5Context *ctx) { + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bytes[0] = 0; + ctx->bytes[1] = 0; + + ctx->internal_buf.p8 = 0; + ctx->capacity = 0; } /* - * Final wrapup - pad to 64-byte boundary with the bit pattern - * 1 0* (64-bit count of bits processed, MSB-first) - */ -void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx) -{ - int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ - FLAC__byte *p = (FLAC__byte *)ctx->in + count; - - /* Set the first char of padding to 0x80. There is always room. */ - *p++ = 0x80; - - /* Bytes of padding needed to make 56 bytes (-8..55) */ - count = 56 - 1 - count; - - if (count < 0) { /* Padding forces an extra block */ - memset(p, 0, count + 8); - byteSwapX16(ctx->in); - FLAC__MD5Transform(ctx->buf, ctx->in); - p = (FLAC__byte *)ctx->in; - count = 56; - } - memset(p, 0, count); - byteSwap(ctx->in, 14); - - /* Append length in bits and transform */ - ctx->in[14] = ctx->bytes[0] << 3; - ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; - FLAC__MD5Transform(ctx->buf, ctx->in); - - byteSwap(ctx->buf, 4); - memcpy(digest, ctx->buf, 16); - if (0 != ctx->internal_buf.p8) { - free(ctx->internal_buf.p8); - ctx->internal_buf.p8 = 0; - ctx->capacity = 0; - } - memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ + Final wrapup - pad to 64-byte boundary with the bit pattern + 1 0* (64-bit count of bits processed, MSB-first) +*/ +void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx) { + int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ + FLAC__byte *p = (FLAC__byte *)ctx->in + count; + + /* Set the first char of padding to 0x80. There is always room. */ + *p++ = 0x80; + + /* Bytes of padding needed to make 56 bytes (-8..55) */ + count = 56 - 1 - count; + + if (count < 0) { /* Padding forces an extra block */ + memset(p, 0, count + 8); + byteSwapX16(ctx->in); + FLAC__MD5Transform(ctx->buf, ctx->in); + p = (FLAC__byte *)ctx->in; + count = 56; + } + memset(p, 0, count); + byteSwap(ctx->in, 14); + + /* Append length in bits and transform */ + ctx->in[14] = ctx->bytes[0] << 3; + ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; + FLAC__MD5Transform(ctx->buf, ctx->in); + + byteSwap(ctx->buf, 4); + memcpy(digest, ctx->buf, 16); + if (0 != ctx->internal_buf.p8) { + free(ctx->internal_buf.p8); + ctx->internal_buf.p8 = 0; + ctx->capacity = 0; + } + memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ } /* - * Convert the incoming audio signal to a byte stream - */ -static void format_input_(FLAC__multibyte *mbuf, const FLAC__int32 * const signal[], uint32_t channels, uint32_t samples, uint32_t bytes_per_sample) -{ - FLAC__byte *buf_ = mbuf->p8; - FLAC__int16 *buf16 = mbuf->p16; - FLAC__int32 *buf32 = mbuf->p32; - FLAC__int32 a_word; - uint32_t channel, sample; - - /* Storage in the output buffer, buf, is little endian. */ + Convert the incoming audio signal to a byte stream +*/ +static void format_input_(FLAC__multibyte *mbuf, const FLAC__int32 * const signal[], uint32_t channels, uint32_t samples, uint32_t bytes_per_sample) { + FLAC__byte *buf_ = mbuf->p8; + FLAC__int16 *buf16 = mbuf->p16; + FLAC__int32 *buf32 = mbuf->p32; + FLAC__int32 a_word; + uint32_t channel, sample; + + /* Storage in the output buffer, buf, is little endian. */ #define BYTES_CHANNEL_SELECTOR(bytes, channels) (bytes * 100 + channels) - /* First do the most commonly used combinations. */ - switch (BYTES_CHANNEL_SELECTOR (bytes_per_sample, channels)) { - /* One byte per sample. */ - case (BYTES_CHANNEL_SELECTOR (1, 1)): - for (sample = 0; sample < samples; sample++) - *buf_++ = signal[0][sample]; - return; - - case (BYTES_CHANNEL_SELECTOR (1, 2)): - for (sample = 0; sample < samples; sample++) { - *buf_++ = signal[0][sample]; - *buf_++ = signal[1][sample]; - } - return; - - case (BYTES_CHANNEL_SELECTOR (1, 4)): - for (sample = 0; sample < samples; sample++) { - *buf_++ = signal[0][sample]; - *buf_++ = signal[1][sample]; - *buf_++ = signal[2][sample]; - *buf_++ = signal[3][sample]; - } - return; - - case (BYTES_CHANNEL_SELECTOR (1, 6)): - for (sample = 0; sample < samples; sample++) { - *buf_++ = signal[0][sample]; - *buf_++ = signal[1][sample]; - *buf_++ = signal[2][sample]; - *buf_++ = signal[3][sample]; - *buf_++ = signal[4][sample]; - *buf_++ = signal[5][sample]; - } - return; - - case (BYTES_CHANNEL_SELECTOR (1, 8)): - for (sample = 0; sample < samples; sample++) { - *buf_++ = signal[0][sample]; - *buf_++ = signal[1][sample]; - *buf_++ = signal[2][sample]; - *buf_++ = signal[3][sample]; - *buf_++ = signal[4][sample]; - *buf_++ = signal[5][sample]; - *buf_++ = signal[6][sample]; - *buf_++ = signal[7][sample]; - } - return; - - /* Two bytes per sample. */ - case (BYTES_CHANNEL_SELECTOR (2, 1)): - for (sample = 0; sample < samples; sample++) - *buf16++ = H2LE_16(signal[0][sample]); - return; - - case (BYTES_CHANNEL_SELECTOR (2, 2)): - for (sample = 0; sample < samples; sample++) { - *buf16++ = H2LE_16(signal[0][sample]); - *buf16++ = H2LE_16(signal[1][sample]); - } - return; - - case (BYTES_CHANNEL_SELECTOR (2, 4)): - for (sample = 0; sample < samples; sample++) { - *buf16++ = H2LE_16(signal[0][sample]); - *buf16++ = H2LE_16(signal[1][sample]); - *buf16++ = H2LE_16(signal[2][sample]); - *buf16++ = H2LE_16(signal[3][sample]); - } - return; - - case (BYTES_CHANNEL_SELECTOR (2, 6)): - for (sample = 0; sample < samples; sample++) { - *buf16++ = H2LE_16(signal[0][sample]); - *buf16++ = H2LE_16(signal[1][sample]); - *buf16++ = H2LE_16(signal[2][sample]); - *buf16++ = H2LE_16(signal[3][sample]); - *buf16++ = H2LE_16(signal[4][sample]); - *buf16++ = H2LE_16(signal[5][sample]); - } - return; - - case (BYTES_CHANNEL_SELECTOR (2, 8)): - for (sample = 0; sample < samples; sample++) { - *buf16++ = H2LE_16(signal[0][sample]); - *buf16++ = H2LE_16(signal[1][sample]); - *buf16++ = H2LE_16(signal[2][sample]); - *buf16++ = H2LE_16(signal[3][sample]); - *buf16++ = H2LE_16(signal[4][sample]); - *buf16++ = H2LE_16(signal[5][sample]); - *buf16++ = H2LE_16(signal[6][sample]); - *buf16++ = H2LE_16(signal[7][sample]); - } - return; - - /* Three bytes per sample. */ - case (BYTES_CHANNEL_SELECTOR (3, 1)): - for (sample = 0; sample < samples; sample++) { - a_word = signal[0][sample]; - *buf_++ = (FLAC__byte)a_word; a_word >>= 8; - *buf_++ = (FLAC__byte)a_word; a_word >>= 8; - *buf_++ = (FLAC__byte)a_word; - } - return; - - case (BYTES_CHANNEL_SELECTOR (3, 2)): - for (sample = 0; sample < samples; sample++) { - a_word = signal[0][sample]; - *buf_++ = (FLAC__byte)a_word; a_word >>= 8; - *buf_++ = (FLAC__byte)a_word; a_word >>= 8; - *buf_++ = (FLAC__byte)a_word; - a_word = signal[1][sample]; - *buf_++ = (FLAC__byte)a_word; a_word >>= 8; - *buf_++ = (FLAC__byte)a_word; a_word >>= 8; - *buf_++ = (FLAC__byte)a_word; - } - return; - - /* Four bytes per sample. */ - case (BYTES_CHANNEL_SELECTOR (4, 1)): - for (sample = 0; sample < samples; sample++) - *buf32++ = H2LE_32(signal[0][sample]); - return; - - case (BYTES_CHANNEL_SELECTOR (4, 2)): - for (sample = 0; sample < samples; sample++) { - *buf32++ = H2LE_32(signal[0][sample]); - *buf32++ = H2LE_32(signal[1][sample]); - } - return; - - case (BYTES_CHANNEL_SELECTOR (4, 4)): - for (sample = 0; sample < samples; sample++) { - *buf32++ = H2LE_32(signal[0][sample]); - *buf32++ = H2LE_32(signal[1][sample]); - *buf32++ = H2LE_32(signal[2][sample]); - *buf32++ = H2LE_32(signal[3][sample]); - } - return; - - case (BYTES_CHANNEL_SELECTOR (4, 6)): - for (sample = 0; sample < samples; sample++) { - *buf32++ = H2LE_32(signal[0][sample]); - *buf32++ = H2LE_32(signal[1][sample]); - *buf32++ = H2LE_32(signal[2][sample]); - *buf32++ = H2LE_32(signal[3][sample]); - *buf32++ = H2LE_32(signal[4][sample]); - *buf32++ = H2LE_32(signal[5][sample]); - } - return; - - case (BYTES_CHANNEL_SELECTOR (4, 8)): - for (sample = 0; sample < samples; sample++) { - *buf32++ = H2LE_32(signal[0][sample]); - *buf32++ = H2LE_32(signal[1][sample]); - *buf32++ = H2LE_32(signal[2][sample]); - *buf32++ = H2LE_32(signal[3][sample]); - *buf32++ = H2LE_32(signal[4][sample]); - *buf32++ = H2LE_32(signal[5][sample]); - *buf32++ = H2LE_32(signal[6][sample]); - *buf32++ = H2LE_32(signal[7][sample]); - } - return; - - default: - break; - } - - /* General version. */ - switch (bytes_per_sample) { - case 1: - for (sample = 0; sample < samples; sample++) - for (channel = 0; channel < channels; channel++) - *buf_++ = signal[channel][sample]; - return; - - case 2: - for (sample = 0; sample < samples; sample++) - for (channel = 0; channel < channels; channel++) - *buf16++ = H2LE_16(signal[channel][sample]); - return; - - case 3: - for (sample = 0; sample < samples; sample++) - for (channel = 0; channel < channels; channel++) { - a_word = signal[channel][sample]; - *buf_++ = (FLAC__byte)a_word; a_word >>= 8; - *buf_++ = (FLAC__byte)a_word; a_word >>= 8; - *buf_++ = (FLAC__byte)a_word; - } - return; - - case 4: - for (sample = 0; sample < samples; sample++) - for (channel = 0; channel < channels; channel++) - *buf32++ = H2LE_32(signal[channel][sample]); - return; - - default: - break; - } + /* First do the most commonly used combinations. */ + switch (BYTES_CHANNEL_SELECTOR(bytes_per_sample, channels)) { + /* One byte per sample. */ + case (BYTES_CHANNEL_SELECTOR(1, 1)): + for (sample = 0; sample < samples; sample++) { + *buf_++ = signal[0][sample]; + } + return; + + case (BYTES_CHANNEL_SELECTOR(1, 2)): + for (sample = 0; sample < samples; sample++) { + *buf_++ = signal[0][sample]; + *buf_++ = signal[1][sample]; + } + return; + + case (BYTES_CHANNEL_SELECTOR(1, 4)): + for (sample = 0; sample < samples; sample++) { + *buf_++ = signal[0][sample]; + *buf_++ = signal[1][sample]; + *buf_++ = signal[2][sample]; + *buf_++ = signal[3][sample]; + } + return; + + case (BYTES_CHANNEL_SELECTOR(1, 6)): + for (sample = 0; sample < samples; sample++) { + *buf_++ = signal[0][sample]; + *buf_++ = signal[1][sample]; + *buf_++ = signal[2][sample]; + *buf_++ = signal[3][sample]; + *buf_++ = signal[4][sample]; + *buf_++ = signal[5][sample]; + } + return; + + case (BYTES_CHANNEL_SELECTOR(1, 8)): + for (sample = 0; sample < samples; sample++) { + *buf_++ = signal[0][sample]; + *buf_++ = signal[1][sample]; + *buf_++ = signal[2][sample]; + *buf_++ = signal[3][sample]; + *buf_++ = signal[4][sample]; + *buf_++ = signal[5][sample]; + *buf_++ = signal[6][sample]; + *buf_++ = signal[7][sample]; + } + return; + + /* Two bytes per sample. */ + case (BYTES_CHANNEL_SELECTOR(2, 1)): + for (sample = 0; sample < samples; sample++) { + *buf16++ = H2LE_16(signal[0][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR(2, 2)): + for (sample = 0; sample < samples; sample++) { + *buf16++ = H2LE_16(signal[0][sample]); + *buf16++ = H2LE_16(signal[1][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR(2, 4)): + for (sample = 0; sample < samples; sample++) { + *buf16++ = H2LE_16(signal[0][sample]); + *buf16++ = H2LE_16(signal[1][sample]); + *buf16++ = H2LE_16(signal[2][sample]); + *buf16++ = H2LE_16(signal[3][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR(2, 6)): + for (sample = 0; sample < samples; sample++) { + *buf16++ = H2LE_16(signal[0][sample]); + *buf16++ = H2LE_16(signal[1][sample]); + *buf16++ = H2LE_16(signal[2][sample]); + *buf16++ = H2LE_16(signal[3][sample]); + *buf16++ = H2LE_16(signal[4][sample]); + *buf16++ = H2LE_16(signal[5][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR(2, 8)): + for (sample = 0; sample < samples; sample++) { + *buf16++ = H2LE_16(signal[0][sample]); + *buf16++ = H2LE_16(signal[1][sample]); + *buf16++ = H2LE_16(signal[2][sample]); + *buf16++ = H2LE_16(signal[3][sample]); + *buf16++ = H2LE_16(signal[4][sample]); + *buf16++ = H2LE_16(signal[5][sample]); + *buf16++ = H2LE_16(signal[6][sample]); + *buf16++ = H2LE_16(signal[7][sample]); + } + return; + + /* Three bytes per sample. */ + case (BYTES_CHANNEL_SELECTOR(3, 1)): + for (sample = 0; sample < samples; sample++) { + a_word = signal[0][sample]; + *buf_++ = (FLAC__byte)a_word; a_word >>= 8; + *buf_++ = (FLAC__byte)a_word; a_word >>= 8; + *buf_++ = (FLAC__byte)a_word; + } + return; + + case (BYTES_CHANNEL_SELECTOR(3, 2)): + for (sample = 0; sample < samples; sample++) { + a_word = signal[0][sample]; + *buf_++ = (FLAC__byte)a_word; a_word >>= 8; + *buf_++ = (FLAC__byte)a_word; a_word >>= 8; + *buf_++ = (FLAC__byte)a_word; + a_word = signal[1][sample]; + *buf_++ = (FLAC__byte)a_word; a_word >>= 8; + *buf_++ = (FLAC__byte)a_word; a_word >>= 8; + *buf_++ = (FLAC__byte)a_word; + } + return; + + /* Four bytes per sample. */ + case (BYTES_CHANNEL_SELECTOR(4, 1)): + for (sample = 0; sample < samples; sample++) { + *buf32++ = H2LE_32(signal[0][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR(4, 2)): + for (sample = 0; sample < samples; sample++) { + *buf32++ = H2LE_32(signal[0][sample]); + *buf32++ = H2LE_32(signal[1][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR(4, 4)): + for (sample = 0; sample < samples; sample++) { + *buf32++ = H2LE_32(signal[0][sample]); + *buf32++ = H2LE_32(signal[1][sample]); + *buf32++ = H2LE_32(signal[2][sample]); + *buf32++ = H2LE_32(signal[3][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR(4, 6)): + for (sample = 0; sample < samples; sample++) { + *buf32++ = H2LE_32(signal[0][sample]); + *buf32++ = H2LE_32(signal[1][sample]); + *buf32++ = H2LE_32(signal[2][sample]); + *buf32++ = H2LE_32(signal[3][sample]); + *buf32++ = H2LE_32(signal[4][sample]); + *buf32++ = H2LE_32(signal[5][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR(4, 8)): + for (sample = 0; sample < samples; sample++) { + *buf32++ = H2LE_32(signal[0][sample]); + *buf32++ = H2LE_32(signal[1][sample]); + *buf32++ = H2LE_32(signal[2][sample]); + *buf32++ = H2LE_32(signal[3][sample]); + *buf32++ = H2LE_32(signal[4][sample]); + *buf32++ = H2LE_32(signal[5][sample]); + *buf32++ = H2LE_32(signal[6][sample]); + *buf32++ = H2LE_32(signal[7][sample]); + } + return; + + default: + break; + } + + /* General version. */ + switch (bytes_per_sample) { + case 1: + for (sample = 0; sample < samples; sample++) + for (channel = 0; channel < channels; channel++) { + *buf_++ = signal[channel][sample]; + } + return; + + case 2: + for (sample = 0; sample < samples; sample++) + for (channel = 0; channel < channels; channel++) { + *buf16++ = H2LE_16(signal[channel][sample]); + } + return; + + case 3: + for (sample = 0; sample < samples; sample++) + for (channel = 0; channel < channels; channel++) { + a_word = signal[channel][sample]; + *buf_++ = (FLAC__byte)a_word; a_word >>= 8; + *buf_++ = (FLAC__byte)a_word; a_word >>= 8; + *buf_++ = (FLAC__byte)a_word; + } + return; + + case 4: + for (sample = 0; sample < samples; sample++) + for (channel = 0; channel < channels; channel++) { + *buf32++ = H2LE_32(signal[channel][sample]); + } + return; + + default: + break; + } } /* - * Convert the incoming audio signal to a byte stream and FLAC__MD5Update it. - */ -FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], uint32_t channels, uint32_t samples, uint32_t bytes_per_sample) -{ - const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample; - - /* overflow check */ - if ((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample) - return false; - if ((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples) - return false; - - if (ctx->capacity < bytes_needed) { - if (0 == (ctx->internal_buf.p8 = safe_realloc_(ctx->internal_buf.p8, bytes_needed))) { - if (0 == (ctx->internal_buf.p8 = safe_malloc_(bytes_needed))) { - ctx->capacity = 0; - return false; - } - } - ctx->capacity = bytes_needed; - } - - format_input_(&ctx->internal_buf, signal, channels, samples, bytes_per_sample); - - FLAC__MD5Update(ctx, ctx->internal_buf.p8, bytes_needed); - - return true; + Convert the incoming audio signal to a byte stream and FLAC__MD5Update it. +*/ +FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], uint32_t channels, uint32_t samples, uint32_t bytes_per_sample) { + const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample; + + /* overflow check */ + if ((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample) { + return false; + } + if ((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples) { + return false; + } + + if (ctx->capacity < bytes_needed) { + if (0 == (ctx->internal_buf.p8 = safe_realloc_(ctx->internal_buf.p8, bytes_needed))) { + if (0 == (ctx->internal_buf.p8 = safe_malloc_(bytes_needed))) { + ctx->capacity = 0; + return false; + } + } + ctx->capacity = bytes_needed; + } + + format_input_(&ctx->internal_buf, signal, channels, samples, bytes_per_sample); + + FLAC__MD5Update(ctx, ctx->internal_buf.p8, bytes_needed); + + return true; } diff --git a/src/libflac/memory.c b/src/libflac/memory.c index c2ac3605..9a8426f6 100644 --- a/src/libflac/memory.c +++ b/src/libflac/memory.c @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2001-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ //#ifdef HAVE_CONFIG_H # include "config.h" @@ -44,177 +44,177 @@ #pragma GCC optimize ("O3") -void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address) -{ - void *x; +void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address) { + void *x; - FLAC__ASSERT(0 != aligned_address); + FLAC__ASSERT(0 != aligned_address); #ifdef FLAC__ALIGN_MALLOC_DATA - /* align on 32-byte (256-bit) boundary */ - x = safe_malloc_add_2op_(bytes, /*+*/31L); - *aligned_address = (void*)(((uintptr_t)x + 31L) & -32L); + /* align on 32-byte (256-bit) boundary */ + x = safe_malloc_add_2op_(bytes, /*+*/31L); + *aligned_address = (void*)(((uintptr_t)x + 31L) & -32L); #else - x = safe_malloc_(bytes); - *aligned_address = x; + x = safe_malloc_(bytes); + *aligned_address = x; #endif - return x; + return x; } -FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer) -{ - FLAC__int32 *pu; /* unaligned pointer */ - union { /* union needed to comply with C99 pointer aliasing rules */ - FLAC__int32 *pa; /* aligned pointer */ - void *pv; /* aligned pointer alias */ - } u; - - FLAC__ASSERT(elements > 0); - FLAC__ASSERT(0 != unaligned_pointer); - FLAC__ASSERT(0 != aligned_pointer); - FLAC__ASSERT(unaligned_pointer != aligned_pointer); - - if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ - return false; - - pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); - if(0 == pu) { - return false; - } - else { - if(*unaligned_pointer != 0) - free(*unaligned_pointer); - *unaligned_pointer = pu; - *aligned_pointer = u.pa; - return true; - } +FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer) { + FLAC__int32 *pu; /* unaligned pointer */ + union { /* union needed to comply with C99 pointer aliasing rules */ + FLAC__int32 *pa; /* aligned pointer */ + void *pv; /* aligned pointer alias */ + } u; + + FLAC__ASSERT(elements > 0); + FLAC__ASSERT(0 != unaligned_pointer); + FLAC__ASSERT(0 != aligned_pointer); + FLAC__ASSERT(unaligned_pointer != aligned_pointer); + + if (elements > SIZE_MAX / sizeof(*pu)) { /* overflow check */ + return false; + } + + pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); + if (0 == pu) { + return false; + } else { + if (*unaligned_pointer != 0) { + free(*unaligned_pointer); + } + *unaligned_pointer = pu; + *aligned_pointer = u.pa; + return true; + } } -FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer) -{ - FLAC__uint32 *pu; /* unaligned pointer */ - union { /* union needed to comply with C99 pointer aliasing rules */ - FLAC__uint32 *pa; /* aligned pointer */ - void *pv; /* aligned pointer alias */ - } u; - - FLAC__ASSERT(elements > 0); - FLAC__ASSERT(0 != unaligned_pointer); - FLAC__ASSERT(0 != aligned_pointer); - FLAC__ASSERT(unaligned_pointer != aligned_pointer); - - if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ - return false; - - pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); - if(0 == pu) { - return false; - } - else { - if(*unaligned_pointer != 0) - free(*unaligned_pointer); - *unaligned_pointer = pu; - *aligned_pointer = u.pa; - return true; - } +FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer) { + FLAC__uint32 *pu; /* unaligned pointer */ + union { /* union needed to comply with C99 pointer aliasing rules */ + FLAC__uint32 *pa; /* aligned pointer */ + void *pv; /* aligned pointer alias */ + } u; + + FLAC__ASSERT(elements > 0); + FLAC__ASSERT(0 != unaligned_pointer); + FLAC__ASSERT(0 != aligned_pointer); + FLAC__ASSERT(unaligned_pointer != aligned_pointer); + + if (elements > SIZE_MAX / sizeof(*pu)) { /* overflow check */ + return false; + } + + pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); + if (0 == pu) { + return false; + } else { + if (*unaligned_pointer != 0) { + free(*unaligned_pointer); + } + *unaligned_pointer = pu; + *aligned_pointer = u.pa; + return true; + } } -FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer) -{ - FLAC__uint64 *pu; /* unaligned pointer */ - union { /* union needed to comply with C99 pointer aliasing rules */ - FLAC__uint64 *pa; /* aligned pointer */ - void *pv; /* aligned pointer alias */ - } u; - - FLAC__ASSERT(elements > 0); - FLAC__ASSERT(0 != unaligned_pointer); - FLAC__ASSERT(0 != aligned_pointer); - FLAC__ASSERT(unaligned_pointer != aligned_pointer); - - if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ - return false; - - pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); - if(0 == pu) { - return false; - } - else { - if(*unaligned_pointer != 0) - free(*unaligned_pointer); - *unaligned_pointer = pu; - *aligned_pointer = u.pa; - return true; - } +FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer) { + FLAC__uint64 *pu; /* unaligned pointer */ + union { /* union needed to comply with C99 pointer aliasing rules */ + FLAC__uint64 *pa; /* aligned pointer */ + void *pv; /* aligned pointer alias */ + } u; + + FLAC__ASSERT(elements > 0); + FLAC__ASSERT(0 != unaligned_pointer); + FLAC__ASSERT(0 != aligned_pointer); + FLAC__ASSERT(unaligned_pointer != aligned_pointer); + + if (elements > SIZE_MAX / sizeof(*pu)) { /* overflow check */ + return false; + } + + pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); + if (0 == pu) { + return false; + } else { + if (*unaligned_pointer != 0) { + free(*unaligned_pointer); + } + *unaligned_pointer = pu; + *aligned_pointer = u.pa; + return true; + } } -FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, uint32_t **unaligned_pointer, uint32_t **aligned_pointer) -{ - uint32_t *pu; /* unaligned pointer */ - union { /* union needed to comply with C99 pointer aliasing rules */ - uint32_t *pa; /* aligned pointer */ - void *pv; /* aligned pointer alias */ - } u; - - FLAC__ASSERT(elements > 0); - FLAC__ASSERT(0 != unaligned_pointer); - FLAC__ASSERT(0 != aligned_pointer); - FLAC__ASSERT(unaligned_pointer != aligned_pointer); - - if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ - return false; - - pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); - if(0 == pu) { - return false; - } - else { - if(*unaligned_pointer != 0) - free(*unaligned_pointer); - *unaligned_pointer = pu; - *aligned_pointer = u.pa; - return true; - } +FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, uint32_t **unaligned_pointer, uint32_t **aligned_pointer) { + uint32_t *pu; /* unaligned pointer */ + union { /* union needed to comply with C99 pointer aliasing rules */ + uint32_t *pa; /* aligned pointer */ + void *pv; /* aligned pointer alias */ + } u; + + FLAC__ASSERT(elements > 0); + FLAC__ASSERT(0 != unaligned_pointer); + FLAC__ASSERT(0 != aligned_pointer); + FLAC__ASSERT(unaligned_pointer != aligned_pointer); + + if (elements > SIZE_MAX / sizeof(*pu)) { /* overflow check */ + return false; + } + + pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); + if (0 == pu) { + return false; + } else { + if (*unaligned_pointer != 0) { + free(*unaligned_pointer); + } + *unaligned_pointer = pu; + *aligned_pointer = u.pa; + return true; + } } #ifndef FLAC__INTEGER_ONLY_LIBRARY -FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer) -{ - FLAC__real *pu; /* unaligned pointer */ - union { /* union needed to comply with C99 pointer aliasing rules */ - FLAC__real *pa; /* aligned pointer */ - void *pv; /* aligned pointer alias */ - } u; - - FLAC__ASSERT(elements > 0); - FLAC__ASSERT(0 != unaligned_pointer); - FLAC__ASSERT(0 != aligned_pointer); - FLAC__ASSERT(unaligned_pointer != aligned_pointer); - - if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ - return false; - - pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); - if(0 == pu) { - return false; - } - else { - if(*unaligned_pointer != 0) - free(*unaligned_pointer); - *unaligned_pointer = pu; - *aligned_pointer = u.pa; - return true; - } +FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer) { + FLAC__real *pu; /* unaligned pointer */ + union { /* union needed to comply with C99 pointer aliasing rules */ + FLAC__real *pa; /* aligned pointer */ + void *pv; /* aligned pointer alias */ + } u; + + FLAC__ASSERT(elements > 0); + FLAC__ASSERT(0 != unaligned_pointer); + FLAC__ASSERT(0 != aligned_pointer); + FLAC__ASSERT(unaligned_pointer != aligned_pointer); + + if (elements > SIZE_MAX / sizeof(*pu)) { /* overflow check */ + return false; + } + + pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); + if (0 == pu) { + return false; + } else { + if (*unaligned_pointer != 0) { + free(*unaligned_pointer); + } + *unaligned_pointer = pu; + *aligned_pointer = u.pa; + return true; + } } #endif -void *safe_malloc_mul_2op_p(size_t size1, size_t size2) -{ - if(!size1 || !size2) - return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ - if(size1 > SIZE_MAX / size2) - return 0; - return malloc(size1*size2); +void *safe_malloc_mul_2op_p(size_t size1, size_t size2) { + if (!size1 || !size2) { + return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ + } + if (size1 > SIZE_MAX / size2) { + return 0; + } + return malloc(size1 * size2); } diff --git a/src/libflac/private/bitmath.h b/src/libflac/private/bitmath.h index 473227d8..d0a24c1b 100644 --- a/src/libflac/private/bitmath.h +++ b/src/libflac/private/bitmath.h @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2001-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__PRIVATE__BITMATH_H #define FLAC__PRIVATE__BITMATH_H @@ -45,165 +45,159 @@ #endif /* Will never be emitted for MSVC, GCC, Intel compilers */ -static inline uint32_t FLAC__clz_soft_uint32(FLAC__uint32 word) -{ - static const uint8_t byte_to_unary_table[] PROGMEM = { - 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - }; - - return word > 0xffffff ? pgm_read_byte(&byte_to_unary_table[word >> 24]) : - word > 0xffff ? pgm_read_byte(&byte_to_unary_table[word >> 16]) + 8 : - word > 0xff ? pgm_read_byte(&byte_to_unary_table[word >> 8]) + 16 : - pgm_read_byte(&byte_to_unary_table[word]) + 24; +static inline uint32_t FLAC__clz_soft_uint32(FLAC__uint32 word) { + static const uint8_t byte_to_unary_table[] PROGMEM = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + + return word > 0xffffff ? pgm_read_byte(&byte_to_unary_table[word >> 24]) : + word > 0xffff ? pgm_read_byte(&byte_to_unary_table[word >> 16]) + 8 : + word > 0xff ? pgm_read_byte(&byte_to_unary_table[word >> 8]) + 16 : + pgm_read_byte(&byte_to_unary_table[word]) + 24; } -static inline uint32_t FLAC__clz_uint32(FLAC__uint32 v) -{ -/* Never used with input 0 */ - FLAC__ASSERT(v > 0); +static inline uint32_t FLAC__clz_uint32(FLAC__uint32 v) { + /* Never used with input 0 */ + FLAC__ASSERT(v > 0); #if defined(__INTEL_COMPILER) - return _bit_scan_reverse(v) ^ 31U; + return _bit_scan_reverse(v) ^ 31U; #elif defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -/* This will translate either to (bsr ^ 31U), clz , ctlz, cntlz, lzcnt depending on - * -march= setting or to a software routine in exotic machines. */ - return __builtin_clz(v); + /* This will translate either to (bsr ^ 31U), clz , ctlz, cntlz, lzcnt depending on + -march= setting or to a software routine in exotic machines. */ + return __builtin_clz(v); #elif defined(_MSC_VER) - { - uint32_t idx; - _BitScanReverse(&idx, v); - return idx ^ 31U; - } + { + uint32_t idx; + _BitScanReverse(&idx, v); + return idx ^ 31U; + } #else - return FLAC__clz_soft_uint32(v); + return FLAC__clz_soft_uint32(v); #endif } /* Used when 64-bit bsr/clz is unavailable; can use 32-bit bsr/clz when possible */ -static inline uint32_t FLAC__clz_soft_uint64(FLAC__uint64 word) -{ - return (FLAC__uint32)(word>>32) ? FLAC__clz_uint32((FLAC__uint32)(word>>32)) : - FLAC__clz_uint32((FLAC__uint32)word) + 32; +static inline uint32_t FLAC__clz_soft_uint64(FLAC__uint64 word) { + return (FLAC__uint32)(word >> 32) ? FLAC__clz_uint32((FLAC__uint32)(word >> 32)) : + FLAC__clz_uint32((FLAC__uint32)word) + 32; } -static inline uint32_t FLAC__clz_uint64(FLAC__uint64 v) -{ - /* Never used with input 0 */ - FLAC__ASSERT(v > 0); +static inline uint32_t FLAC__clz_uint64(FLAC__uint64 v) { + /* Never used with input 0 */ + FLAC__ASSERT(v > 0); #if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) - return __builtin_clzll(v); + return __builtin_clzll(v); #elif (defined(__INTEL_COMPILER) || defined(_MSC_VER)) && (defined(_M_IA64) || defined(_M_X64)) - { - uint32_t idx; - _BitScanReverse64(&idx, v); - return idx ^ 63U; - } + { + uint32_t idx; + _BitScanReverse64(&idx, v); + return idx ^ 63U; + } #else - return FLAC__clz_soft_uint64(v); + return FLAC__clz_soft_uint64(v); #endif } /* These two functions work with input 0 */ -static inline uint32_t FLAC__clz2_uint32(FLAC__uint32 v) -{ - if (!v) - return 32; - return FLAC__clz_uint32(v); +static inline uint32_t FLAC__clz2_uint32(FLAC__uint32 v) { + if (!v) { + return 32; + } + return FLAC__clz_uint32(v); } -static inline uint32_t FLAC__clz2_uint64(FLAC__uint64 v) -{ - if (!v) - return 64; - return FLAC__clz_uint64(v); +static inline uint32_t FLAC__clz2_uint64(FLAC__uint64 v) { + if (!v) { + return 64; + } + return FLAC__clz_uint64(v); } -/* An example of what FLAC__bitmath_ilog2() computes: - * - * ilog2( 0) = assertion failure - * ilog2( 1) = 0 - * ilog2( 2) = 1 - * ilog2( 3) = 1 - * ilog2( 4) = 2 - * ilog2( 5) = 2 - * ilog2( 6) = 2 - * ilog2( 7) = 2 - * ilog2( 8) = 3 - * ilog2( 9) = 3 - * ilog2(10) = 3 - * ilog2(11) = 3 - * ilog2(12) = 3 - * ilog2(13) = 3 - * ilog2(14) = 3 - * ilog2(15) = 3 - * ilog2(16) = 4 - * ilog2(17) = 4 - * ilog2(18) = 4 - */ - -static inline uint32_t FLAC__bitmath_ilog2(FLAC__uint32 v) -{ - FLAC__ASSERT(v > 0); +/* An example of what FLAC__bitmath_ilog2() computes: + + ilog2( 0) = assertion failure + ilog2( 1) = 0 + ilog2( 2) = 1 + ilog2( 3) = 1 + ilog2( 4) = 2 + ilog2( 5) = 2 + ilog2( 6) = 2 + ilog2( 7) = 2 + ilog2( 8) = 3 + ilog2( 9) = 3 + ilog2(10) = 3 + ilog2(11) = 3 + ilog2(12) = 3 + ilog2(13) = 3 + ilog2(14) = 3 + ilog2(15) = 3 + ilog2(16) = 4 + ilog2(17) = 4 + ilog2(18) = 4 +*/ + +static inline uint32_t FLAC__bitmath_ilog2(FLAC__uint32 v) { + FLAC__ASSERT(v > 0); #if defined(__INTEL_COMPILER) - return _bit_scan_reverse(v); + return _bit_scan_reverse(v); #elif defined(_MSC_VER) - { - uint32_t idx; - _BitScanReverse(&idx, v); - return idx; - } + { + uint32_t idx; + _BitScanReverse(&idx, v); + return idx; + } #else - return FLAC__clz_uint32(v) ^ 31U; + return FLAC__clz_uint32(v) ^ 31U; #endif } -static inline uint32_t FLAC__bitmath_ilog2_wide(FLAC__uint64 v) -{ - FLAC__ASSERT(v > 0); +static inline uint32_t FLAC__bitmath_ilog2_wide(FLAC__uint64 v) { + FLAC__ASSERT(v > 0); #if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) - return __builtin_clzll(v) ^ 63U; -/* Sorry, only supported in x64/Itanium.. and both have fast FPU which makes integer-only encoder pointless */ + return __builtin_clzll(v) ^ 63U; + /* Sorry, only supported in x64/Itanium.. and both have fast FPU which makes integer-only encoder pointless */ #elif (defined(__INTEL_COMPILER) || defined(_MSC_VER)) && (defined(_M_IA64) || defined(_M_X64)) - { - uint32_t idx; - _BitScanReverse64(&idx, v); - return idx; - } + { + uint32_t idx; + _BitScanReverse64(&idx, v); + return idx; + } #else -/* Brain-damaged compilers will use the fastest possible way that is, - de Bruijn sequences (http://supertech.csail.mit.edu/papers/debruijn.pdf) - (C) Timothy B. Terriberry (tterribe@xiph.org) 2001-2009 CC0 (Public domain). -*/ - { - static const uint8_t DEBRUIJN_IDX64[64]={ - 0, 1, 2, 7, 3,13, 8,19, 4,25,14,28, 9,34,20,40, - 5,17,26,38,15,46,29,48,10,31,35,54,21,50,41,57, - 63, 6,12,18,24,27,33,39,16,37,45,47,30,53,49,56, - 62,11,23,32,36,44,52,55,61,22,43,51,60,42,59,58 - }; - v|= v>>1; - v|= v>>2; - v|= v>>4; - v|= v>>8; - v|= v>>16; - v|= v>>32; - v= (v>>1)+1; - return DEBRUIJN_IDX64[v*FLAC__U64L(0x218A392CD3D5DBF)>>58&0x3F]; - } + /* Brain-damaged compilers will use the fastest possible way that is, + de Bruijn sequences (http://supertech.csail.mit.edu/papers/debruijn.pdf) + (C) Timothy B. Terriberry (tterribe@xiph.org) 2001-2009 CC0 (Public domain). + */ + { + static const uint8_t DEBRUIJN_IDX64[64] = { + 0, 1, 2, 7, 3, 13, 8, 19, 4, 25, 14, 28, 9, 34, 20, 40, + 5, 17, 26, 38, 15, 46, 29, 48, 10, 31, 35, 54, 21, 50, 41, 57, + 63, 6, 12, 18, 24, 27, 33, 39, 16, 37, 45, 47, 30, 53, 49, 56, + 62, 11, 23, 32, 36, 44, 52, 55, 61, 22, 43, 51, 60, 42, 59, 58 + }; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v |= v >> 32; + v = (v >> 1) + 1; + return DEBRUIJN_IDX64[v * FLAC__U64L(0x218A392CD3D5DBF) >> 58 & 0x3F]; + } #endif } diff --git a/src/libflac/private/bitreader.h b/src/libflac/private/bitreader.h index a1abdad0..073f4fdd 100644 --- a/src/libflac/private/bitreader.h +++ b/src/libflac/private/bitreader.h @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2000-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__PRIVATE__BITREADER_H #define FLAC__PRIVATE__BITREADER_H @@ -38,16 +38,16 @@ #include "cpu.h" /* - * opaque structure definition - */ + opaque structure definition +*/ struct FLAC__BitReader; typedef struct FLAC__BitReader FLAC__BitReader; -typedef FLAC__bool (*FLAC__BitReaderReadCallback)(FLAC__byte buffer[], size_t *bytes, void *client_data); +typedef FLAC__bool(*FLAC__BitReaderReadCallback)(FLAC__byte buffer[], size_t *bytes, void *client_data); /* - * construction, deletion, initialization, etc functions - */ + construction, deletion, initialization, etc functions +*/ FLAC__BitReader *FLAC__bitreader_new(void); void FLAC__bitreader_delete(FLAC__BitReader *br); FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd); @@ -56,21 +56,21 @@ FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br); //void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out); /* - * CRC functions - */ + CRC functions +*/ void FLAC__bitreader_reset_read_crc16(FLAC__BitReader *br, FLAC__uint16 seed); FLAC__uint16 FLAC__bitreader_get_read_crc16(FLAC__BitReader *br); /* - * info functions - */ + info functions +*/ FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br); uint32_t FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br); uint32_t FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br); /* - * read functions - */ + read functions +*/ FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, uint32_t bits); FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, uint32_t bits); diff --git a/src/libflac/private/cpu.h b/src/libflac/private/cpu.h index fee2a656..09b1c015 100644 --- a/src/libflac/private/cpu.h +++ b/src/libflac/private/cpu.h @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2001-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__PRIVATE__CPU_H #define FLAC__PRIVATE__CPU_H @@ -62,86 +62,86 @@ #if FLAC__HAS_X86INTRIN /* SSE intrinsics support by ICC/MSVC/GCC */ #if defined __INTEL_COMPILER - #define FLAC__SSE_TARGET(x) - #define FLAC__SSE_SUPPORTED 1 - #define FLAC__SSE2_SUPPORTED 1 - #if (__INTEL_COMPILER >= 1000) /* Intel C++ Compiler 10.0 */ - #define FLAC__SSSE3_SUPPORTED 1 - #define FLAC__SSE4_1_SUPPORTED 1 - #endif - #if (__INTEL_COMPILER >= 1110) /* Intel C++ Compiler 11.1 */ - #define FLAC__AVX_SUPPORTED 1 - #endif - #if (__INTEL_COMPILER >= 1300) /* Intel C++ Compiler 13.0 */ - #define FLAC__AVX2_SUPPORTED 1 - #define FLAC__FMA_SUPPORTED 1 - #endif +#define FLAC__SSE_TARGET(x) +#define FLAC__SSE_SUPPORTED 1 +#define FLAC__SSE2_SUPPORTED 1 +#if (__INTEL_COMPILER >= 1000) /* Intel C++ Compiler 10.0 */ +#define FLAC__SSSE3_SUPPORTED 1 +#define FLAC__SSE4_1_SUPPORTED 1 +#endif +#if (__INTEL_COMPILER >= 1110) /* Intel C++ Compiler 11.1 */ +#define FLAC__AVX_SUPPORTED 1 +#endif +#if (__INTEL_COMPILER >= 1300) /* Intel C++ Compiler 13.0 */ +#define FLAC__AVX2_SUPPORTED 1 +#define FLAC__FMA_SUPPORTED 1 +#endif #elif defined __clang__ && __has_attribute(__target__) /* clang */ - #define FLAC__SSE_TARGET(x) __attribute__ ((__target__ (x))) - #if __has_builtin(__builtin_ia32_maxps) - #define FLAC__SSE_SUPPORTED 1 - #endif - #if __has_builtin(__builtin_ia32_pmuludq128) - #define FLAC__SSE2_SUPPORTED 1 - #endif - #if __has_builtin(__builtin_ia32_pabsd128) - #define FLAC__SSSE3_SUPPORTED 1 - #endif - #if __has_builtin(__builtin_ia32_pmuldq128) - #define FLAC__SSE4_1_SUPPORTED 1 - #endif - #if __has_builtin(__builtin_ia32_pabsd256) - #define FLAC__AVX2_SUPPORTED 1 - #endif +#define FLAC__SSE_TARGET(x) __attribute__ ((__target__ (x))) +#if __has_builtin(__builtin_ia32_maxps) +#define FLAC__SSE_SUPPORTED 1 +#endif +#if __has_builtin(__builtin_ia32_pmuludq128) +#define FLAC__SSE2_SUPPORTED 1 +#endif +#if __has_builtin(__builtin_ia32_pabsd128) +#define FLAC__SSSE3_SUPPORTED 1 +#endif +#if __has_builtin(__builtin_ia32_pmuldq128) +#define FLAC__SSE4_1_SUPPORTED 1 +#endif +#if __has_builtin(__builtin_ia32_pabsd256) +#define FLAC__AVX2_SUPPORTED 1 +#endif #elif defined __GNUC__ && !defined __clang__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) /* GCC 4.9+ */ - #define FLAC__SSE_TARGET(x) __attribute__ ((__target__ (x))) - #define FLAC__SSE_SUPPORTED 1 - #define FLAC__SSE2_SUPPORTED 1 - #define FLAC__SSSE3_SUPPORTED 1 - #define FLAC__SSE4_1_SUPPORTED 1 - #ifdef FLAC__USE_AVX - #define FLAC__AVX_SUPPORTED 1 - #define FLAC__AVX2_SUPPORTED 1 - #define FLAC__FMA_SUPPORTED 1 - #endif +#define FLAC__SSE_TARGET(x) __attribute__ ((__target__ (x))) +#define FLAC__SSE_SUPPORTED 1 +#define FLAC__SSE2_SUPPORTED 1 +#define FLAC__SSSE3_SUPPORTED 1 +#define FLAC__SSE4_1_SUPPORTED 1 +#ifdef FLAC__USE_AVX +#define FLAC__AVX_SUPPORTED 1 +#define FLAC__AVX2_SUPPORTED 1 +#define FLAC__FMA_SUPPORTED 1 +#endif #elif defined _MSC_VER - #define FLAC__SSE_TARGET(x) - #define FLAC__SSE_SUPPORTED 1 - #define FLAC__SSE2_SUPPORTED 1 - #if (_MSC_VER >= 1500) /* MS Visual Studio 2008 */ - #define FLAC__SSSE3_SUPPORTED 1 - #define FLAC__SSE4_1_SUPPORTED 1 - #endif - #if (_MSC_FULL_VER >= 160040219) /* MS Visual Studio 2010 SP1 */ - #define FLAC__AVX_SUPPORTED 1 - #endif - #if (_MSC_VER >= 1700) /* MS Visual Studio 2012 */ - #define FLAC__AVX2_SUPPORTED 1 - #define FLAC__FMA_SUPPORTED 1 - #endif +#define FLAC__SSE_TARGET(x) +#define FLAC__SSE_SUPPORTED 1 +#define FLAC__SSE2_SUPPORTED 1 +#if (_MSC_VER >= 1500) /* MS Visual Studio 2008 */ +#define FLAC__SSSE3_SUPPORTED 1 +#define FLAC__SSE4_1_SUPPORTED 1 +#endif +#if (_MSC_FULL_VER >= 160040219) /* MS Visual Studio 2010 SP1 */ +#define FLAC__AVX_SUPPORTED 1 +#endif +#if (_MSC_VER >= 1700) /* MS Visual Studio 2012 */ +#define FLAC__AVX2_SUPPORTED 1 +#define FLAC__FMA_SUPPORTED 1 +#endif #else - #define FLAC__SSE_TARGET(x) - #ifdef __SSE__ - #define FLAC__SSE_SUPPORTED 1 - #endif - #ifdef __SSE2__ - #define FLAC__SSE2_SUPPORTED 1 - #endif - #ifdef __SSSE3__ - #define FLAC__SSSE3_SUPPORTED 1 - #endif - #ifdef __SSE4_1__ - #define FLAC__SSE4_1_SUPPORTED 1 - #endif - #ifdef __AVX__ - #define FLAC__AVX_SUPPORTED 1 - #endif - #ifdef __AVX2__ - #define FLAC__AVX2_SUPPORTED 1 - #endif - #ifdef __FMA__ - #define FLAC__FMA_SUPPORTED 1 - #endif +#define FLAC__SSE_TARGET(x) +#ifdef __SSE__ +#define FLAC__SSE_SUPPORTED 1 +#endif +#ifdef __SSE2__ +#define FLAC__SSE2_SUPPORTED 1 +#endif +#ifdef __SSSE3__ +#define FLAC__SSSE3_SUPPORTED 1 +#endif +#ifdef __SSE4_1__ +#define FLAC__SSE4_1_SUPPORTED 1 +#endif +#ifdef __AVX__ +#define FLAC__AVX_SUPPORTED 1 +#endif +#ifdef __AVX2__ +#define FLAC__AVX2_SUPPORTED 1 +#endif +#ifdef __FMA__ +#define FLAC__FMA_SUPPORTED 1 +#endif #endif /* compiler version */ #endif /* intrinsics support */ @@ -151,39 +151,39 @@ #endif typedef enum { - FLAC__CPUINFO_TYPE_IA32, - FLAC__CPUINFO_TYPE_X86_64, - FLAC__CPUINFO_TYPE_PPC, - FLAC__CPUINFO_TYPE_UNKNOWN + FLAC__CPUINFO_TYPE_IA32, + FLAC__CPUINFO_TYPE_X86_64, + FLAC__CPUINFO_TYPE_PPC, + FLAC__CPUINFO_TYPE_UNKNOWN } FLAC__CPUInfo_Type; typedef struct { - FLAC__bool intel; - - FLAC__bool cmov; - FLAC__bool mmx; - FLAC__bool sse; - FLAC__bool sse2; - - FLAC__bool sse3; - FLAC__bool ssse3; - FLAC__bool sse41; - FLAC__bool sse42; - FLAC__bool avx; - FLAC__bool avx2; - FLAC__bool fma; + FLAC__bool intel; + + FLAC__bool cmov; + FLAC__bool mmx; + FLAC__bool sse; + FLAC__bool sse2; + + FLAC__bool sse3; + FLAC__bool ssse3; + FLAC__bool sse41; + FLAC__bool sse42; + FLAC__bool avx; + FLAC__bool avx2; + FLAC__bool fma; } FLAC__CPUInfo_x86; typedef struct { - FLAC__bool arch_3_00; - FLAC__bool arch_2_07; + FLAC__bool arch_3_00; + FLAC__bool arch_2_07; } FLAC__CPUInfo_ppc; typedef struct { - FLAC__bool use_asm; - FLAC__CPUInfo_Type type; - FLAC__CPUInfo_x86 x86; - FLAC__CPUInfo_ppc ppc; + FLAC__bool use_asm; + FLAC__CPUInfo_Type type; + FLAC__CPUInfo_x86 x86; + FLAC__CPUInfo_ppc ppc; } FLAC__CPUInfo; void FLAC__cpu_info(FLAC__CPUInfo *info); diff --git a/src/libflac/private/crc.h b/src/libflac/private/crc.h index 0491b9e3..bd274ef7 100644 --- a/src/libflac/private/crc.h +++ b/src/libflac/private/crc.h @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2000-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__PRIVATE__CRC_H #define FLAC__PRIVATE__CRC_H @@ -39,7 +39,7 @@ #include "../FLAC/ordinals.h" -/* 8 bit CRC generator, MSB shifted first +/* 8 bit CRC generator, MSB shifted first ** polynomial = x^8 + x^2 + x^1 + x^0 ** init = 0 */ @@ -49,7 +49,7 @@ void FLAC__crc8_update(const FLAC__byte data, FLAC__uint8 *crc); void FLAC__crc8_update_block(const FLAC__byte *data, unsigned len, FLAC__uint8 *crc); FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len); -/* 16 bit CRC generator, MSB shifted first +/* 16 bit CRC generator, MSB shifted first ** polynomial = x^16 + x^15 + x^2 + x^0 ** init = 0 */ diff --git a/src/libflac/private/fixed.h b/src/libflac/private/fixed.h index 21e5f052..a4ab37a0 100644 --- a/src/libflac/private/fixed.h +++ b/src/libflac/private/fixed.h @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2000-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__PRIVATE__FIXED_H #define FLAC__PRIVATE__FIXED_H @@ -42,20 +42,20 @@ #include "../FLAC/format.h" /* - * FLAC__fixed_compute_best_predictor() - * -------------------------------------------------------------------- - * Compute the best fixed predictor and the expected bits-per-sample - * of the residual signal for each order. The _wide() version uses - * 64-bit integers which is statistically necessary when bits-per- - * sample + log2(blocksize) > 30 - * - * IN data[0,data_len-1] - * IN data_len - * OUT residual_bits_per_sample[0,FLAC__MAX_FIXED_ORDER] - */ + FLAC__fixed_compute_best_predictor() + -------------------------------------------------------------------- + Compute the best fixed predictor and the expected bits-per-sample + of the residual signal for each order. The _wide() version uses + 64-bit integers which is statistically necessary when bits-per- + sample + log2(blocksize) > 30 + + IN data[0,data_len-1] + IN data_len + OUT residual_bits_per_sample[0,FLAC__MAX_FIXED_ORDER] +*/ #ifndef FLAC__INTEGER_ONLY_LIBRARY -uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); -uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); +uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); # ifndef FLAC__NO_ASM # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN # ifdef FLAC__SSE2_SUPPORTED @@ -63,45 +63,45 @@ uint32_t FLAC__fixed_compute_best_predictor_intrin_sse2(const FLAC__int32 data[] uint32_t FLAC__fixed_compute_best_predictor_wide_intrin_sse2(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); # endif # ifdef FLAC__SSSE3_SUPPORTED -uint32_t FLAC__fixed_compute_best_predictor_intrin_ssse3(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +uint32_t FLAC__fixed_compute_best_predictor_intrin_ssse3(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); uint32_t FLAC__fixed_compute_best_predictor_wide_intrin_ssse3(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); # endif # endif # if defined FLAC__CPU_IA32 && defined FLAC__HAS_NASM -uint32_t FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +uint32_t FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); # endif # endif #else -uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); -uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); +uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); #endif /* - * FLAC__fixed_compute_residual() - * -------------------------------------------------------------------- - * Compute the residual signal obtained from sutracting the predicted - * signal from the original. - * - * IN data[-order,data_len-1] original signal (NOTE THE INDICES!) - * IN data_len length of original signal - * IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order - * OUT residual[0,data_len-1] residual signal - */ + FLAC__fixed_compute_residual() + -------------------------------------------------------------------- + Compute the residual signal obtained from sutracting the predicted + signal from the original. + + IN data[-order,data_len-1] original signal (NOTE THE INDICES!) + IN data_len length of original signal + IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order + OUT residual[0,data_len-1] residual signal +*/ void FLAC__fixed_compute_residual(const FLAC__int32 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[]); /* - * FLAC__fixed_restore_signal() - * -------------------------------------------------------------------- - * Restore the original signal by summing the residual and the - * predictor. - * - * IN residual[0,data_len-1] residual signal - * IN data_len length of original signal - * IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order + FLAC__fixed_restore_signal() + -------------------------------------------------------------------- + Restore the original signal by summing the residual and the + predictor. + + IN residual[0,data_len-1] residual signal + IN data_len length of original signal + IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order * *** IMPORTANT: the caller must pass in the historical samples: - * IN data[-order,-1] previously-reconstructed historical samples - * OUT data[0,data_len-1] original signal - */ + IN data[-order,-1] previously-reconstructed historical samples + OUT data[0,data_len-1] original signal +*/ void FLAC__fixed_restore_signal(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int32 data[]); #endif diff --git a/src/libflac/private/float.h b/src/libflac/private/float.h index 8d2d2f74..e4c2a400 100644 --- a/src/libflac/private/float.h +++ b/src/libflac/private/float.h @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2004-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2004-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__PRIVATE__FLOAT_H #define FLAC__PRIVATE__FLOAT_H @@ -40,24 +40,24 @@ #include "../FLAC/ordinals.h" /* - * All the code in libFLAC that uses float and double - * should be protected by checks of the macro - * FLAC__INTEGER_ONLY_LIBRARY. - * - */ + All the code in libFLAC that uses float and double + should be protected by checks of the macro + FLAC__INTEGER_ONLY_LIBRARY. + +*/ #ifndef FLAC__INTEGER_ONLY_LIBRARY /* - * FLAC__real is the basic floating point type used in LPC analysis. - * - * WATCHOUT: changing FLAC__real will change the signatures of many - * functions that have assembly language equivalents and break them. - */ + FLAC__real is the basic floating point type used in LPC analysis. + + WATCHOUT: changing FLAC__real will change the signatures of many + functions that have assembly language equivalents and break them. +*/ typedef float FLAC__real; #else /* - * The convention for FLAC__fixedpoint is to use the upper 16 bits - * for the integer part and lower 16 bits for the fractional part. - */ + The convention for FLAC__fixedpoint is to use the upper 16 bits + for the integer part and lower 16 bits for the fractional part. +*/ typedef FLAC__int32 FLAC__fixedpoint; extern const FLAC__fixedpoint FLAC__FP_ZERO; extern const FLAC__fixedpoint FLAC__FP_ONE_HALF; @@ -72,22 +72,22 @@ extern const FLAC__fixedpoint FLAC__FP_E; #define FLAC__fixedpoint_div(x, y) ( (FLAC__fixedpoint) ( ( ((FLAC__int64)(x)<<32) / (FLAC__int64)(y) ) >> 16 ) ) /* - * FLAC__fixedpoint_log2() - * -------------------------------------------------------------------- - * Returns the base-2 logarithm of the fixed-point number 'x' using an - * algorithm by Knuth for x >= 1.0 - * - * 'fracbits' is the number of fractional bits of 'x'. 'fracbits' must - * be < 32 and evenly divisible by 4 (0 is OK but not very precise). - * - * 'precision' roughly limits the number of iterations that are done; - * use (uint32_t)(-1) for maximum precision. - * - * If 'x' is less than one -- that is, x < (1<= 1.0 + + 'fracbits' is the number of fractional bits of 'x'. 'fracbits' must + be < 32 and evenly divisible by 4 (0 is OK but not very precise). + + 'precision' roughly limits the number of iterations that are done; + use (uint32_t)(-1) for maximum precision. + + If 'x' is less than one -- that is, x < (1< 0. - * - * IN data[0,data_len-1] - * IN data_len - * IN 0 < lag <= data_len - * OUT autoc[0,lag-1] - */ + FLAC__lpc_compute_autocorrelation() + -------------------------------------------------------------------- + Compute the autocorrelation for lags between 0 and lag-1. + Assumes data[] outside of [0,data_len-1] == 0. + Asserts that lag > 0. + + IN data[0,data_len-1] + IN data_len + IN 0 < lag <= data_len + OUT autoc[0,lag-1] +*/ void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); #ifndef FLAC__NO_ASM # ifdef FLAC__CPU_IA32 @@ -108,63 +108,63 @@ void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_16(const FLAC__real #endif /* - * FLAC__lpc_compute_lp_coefficients() - * -------------------------------------------------------------------- - * Computes LP coefficients for orders 1..max_order. - * Do not call if autoc[0] == 0.0. This means the signal is zero - * and there is no point in calculating a predictor. - * - * IN autoc[0,max_order] autocorrelation values - * IN 0 < max_order <= FLAC__MAX_LPC_ORDER max LP order to compute - * OUT lp_coeff[0,max_order-1][0,max_order-1] LP coefficients for each order + FLAC__lpc_compute_lp_coefficients() + -------------------------------------------------------------------- + Computes LP coefficients for orders 1..max_order. + Do not call if autoc[0] == 0.0. This means the signal is zero + and there is no point in calculating a predictor. + + IN autoc[0,max_order] autocorrelation values + IN 0 < max_order <= FLAC__MAX_LPC_ORDER max LP order to compute + OUT lp_coeff[0,max_order-1][0,max_order-1] LP coefficients for each order * *** IMPORTANT: * *** lp_coeff[0,max_order-1][max_order,FLAC__MAX_LPC_ORDER-1] are untouched - * OUT error[0,max_order-1] error for each order (more - * specifically, the variance of - * the error signal times # of - * samples in the signal) - * - * Example: if max_order is 9, the LP coefficients for order 9 will be - * in lp_coeff[8][0,8], the LP coefficients for order 8 will be - * in lp_coeff[7][0,7], etc. - */ + OUT error[0,max_order-1] error for each order (more + specifically, the variance of + the error signal times # of + samples in the signal) + + Example: if max_order is 9, the LP coefficients for order 9 will be + in lp_coeff[8][0,8], the LP coefficients for order 8 will be + in lp_coeff[7][0,7], etc. +*/ void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], uint32_t *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], double error[]); /* - * FLAC__lpc_quantize_coefficients() - * -------------------------------------------------------------------- - * Quantizes the LP coefficients. NOTE: precision + bits_per_sample - * must be less than 32 (sizeof(FLAC__int32)*8). - * - * IN lp_coeff[0,order-1] LP coefficients - * IN order LP order - * IN FLAC__MIN_QLP_COEFF_PRECISION < precision - * desired precision (in bits, including sign - * bit) of largest coefficient - * OUT qlp_coeff[0,order-1] quantized coefficients - * OUT shift # of bits to shift right to get approximated - * LP coefficients. NOTE: could be negative. - * RETURN 0 => quantization OK - * 1 => coefficients require too much shifting for *shift to - * fit in the LPC subframe header. 'shift' is unset. - * 2 => coefficients are all zero, which is bad. 'shift' is - * unset. - */ + FLAC__lpc_quantize_coefficients() + -------------------------------------------------------------------- + Quantizes the LP coefficients. NOTE: precision + bits_per_sample + must be less than 32 (sizeof(FLAC__int32)*8). + + IN lp_coeff[0,order-1] LP coefficients + IN order LP order + IN FLAC__MIN_QLP_COEFF_PRECISION < precision + desired precision (in bits, including sign + bit) of largest coefficient + OUT qlp_coeff[0,order-1] quantized coefficients + OUT shift # of bits to shift right to get approximated + LP coefficients. NOTE: could be negative. + RETURN 0 => quantization OK + 1 => coefficients require too much shifting for *shift to + fit in the LPC subframe header. 'shift' is unset. + 2 => coefficients are all zero, which is bad. 'shift' is + unset. +*/ int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], uint32_t order, uint32_t precision, FLAC__int32 qlp_coeff[], int *shift); /* - * FLAC__lpc_compute_residual_from_qlp_coefficients() - * -------------------------------------------------------------------- - * Compute the residual signal obtained from sutracting the predicted - * signal from the original. - * - * IN data[-order,data_len-1] original signal (NOTE THE INDICES!) - * IN data_len length of original signal - * IN qlp_coeff[0,order-1] quantized LP coefficients - * IN order > 0 LP order - * IN lp_quantization quantization of LP coefficients in bits - * OUT residual[0,data_len-1] residual signal - */ + FLAC__lpc_compute_residual_from_qlp_coefficients() + -------------------------------------------------------------------- + Compute the residual signal obtained from sutracting the predicted + signal from the original. + + IN data[-order,data_len-1] original signal (NOTE THE INDICES!) + IN data_len length of original signal + IN qlp_coeff[0,order-1] quantized LP coefficients + IN order > 0 LP order + IN lp_quantization quantization of LP coefficients in bits + OUT residual[0,data_len-1] residual signal +*/ void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); #ifndef FLAC__NO_ASM @@ -195,20 +195,20 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2(const FLA #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ /* - * FLAC__lpc_restore_signal() - * -------------------------------------------------------------------- - * Restore the original signal by summing the residual and the - * predictor. - * - * IN residual[0,data_len-1] residual signal - * IN data_len length of original signal - * IN qlp_coeff[0,order-1] quantized LP coefficients - * IN order > 0 LP order - * IN lp_quantization quantization of LP coefficients in bits + FLAC__lpc_restore_signal() + -------------------------------------------------------------------- + Restore the original signal by summing the residual and the + predictor. + + IN residual[0,data_len-1] residual signal + IN data_len length of original signal + IN qlp_coeff[0,order-1] quantized LP coefficients + IN order > 0 LP order + IN lp_quantization quantization of LP coefficients in bits * *** IMPORTANT: the caller must pass in the historical samples: - * IN data[-order,-1] previously-reconstructed historical samples - * OUT data[0,data_len-1] original signal - */ + IN data[-order,-1] previously-reconstructed historical samples + OUT data[0,data_len-1] original signal +*/ void FLAC__lpc_restore_signal(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); #ifndef FLAC__NO_ASM @@ -231,31 +231,31 @@ void FLAC__lpc_restore_signal_wide_intrin_sse41(const FLAC__int32 residual[], ui #ifndef FLAC__INTEGER_ONLY_LIBRARY /* - * FLAC__lpc_compute_expected_bits_per_residual_sample() - * -------------------------------------------------------------------- - * Compute the expected number of bits per residual signal sample - * based on the LP error (which is related to the residual variance). - * - * IN lpc_error >= 0.0 error returned from calculating LP coefficients - * IN total_samples > 0 # of samples in residual signal - * RETURN expected bits per sample - */ + FLAC__lpc_compute_expected_bits_per_residual_sample() + -------------------------------------------------------------------- + Compute the expected number of bits per residual signal sample + based on the LP error (which is related to the residual variance). + + IN lpc_error >= 0.0 error returned from calculating LP coefficients + IN total_samples > 0 # of samples in residual signal + RETURN expected bits per sample +*/ double FLAC__lpc_compute_expected_bits_per_residual_sample(double lpc_error, uint32_t total_samples); double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(double lpc_error, double error_scale); /* - * FLAC__lpc_compute_best_order() - * -------------------------------------------------------------------- - * Compute the best order from the array of signal errors returned - * during coefficient computation. - * - * IN lpc_error[0,max_order-1] >= 0.0 error returned from calculating LP coefficients - * IN max_order > 0 max LP order - * IN total_samples > 0 # of samples in residual signal - * IN overhead_bits_per_order # of bits overhead for each increased LP order - * (includes warmup sample size and quantized LP coefficient) - * RETURN [1,max_order] best order - */ + FLAC__lpc_compute_best_order() + -------------------------------------------------------------------- + Compute the best order from the array of signal errors returned + during coefficient computation. + + IN lpc_error[0,max_order-1] >= 0.0 error returned from calculating LP coefficients + IN max_order > 0 max LP order + IN total_samples > 0 # of samples in residual signal + IN overhead_bits_per_order # of bits overhead for each increased LP order + (includes warmup sample size and quantized LP coefficient) + RETURN [1,max_order] best order +*/ uint32_t FLAC__lpc_compute_best_order(const double lpc_error[], uint32_t max_order, uint32_t total_samples, uint32_t overhead_bits_per_order); #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ diff --git a/src/libflac/private/macros.h b/src/libflac/private/macros.h index 3a8072ec..260859cf 100644 --- a/src/libflac/private/macros.h +++ b/src/libflac/private/macros.h @@ -1,33 +1,33 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2012-2016 Xiph.org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2012-2016 Xiph.org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__PRIVATE__MACROS_H #define FLAC__PRIVATE__MACROS_H diff --git a/src/libflac/private/md5.h b/src/libflac/private/md5.h index 9817415b..393836c1 100644 --- a/src/libflac/private/md5.h +++ b/src/libflac/private/md5.h @@ -2,44 +2,44 @@ #define FLAC__PRIVATE__MD5_H /* - * This is the header file for the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - * - * Changed so as no longer to depend on Colin Plumb's `usual.h' - * header definitions; now uses stuff from dpkg's config.h - * - Ian Jackson . - * Still in the public domain. - * - * Josh Coalson: made some changes to integrate with libFLAC. - * Still in the public domain, with no warranty. - */ + This is the header file for the MD5 message-digest algorithm. + The algorithm is due to Ron Rivest. This code was + written by Colin Plumb in 1993, no copyright is claimed. + This code is in the public domain; do with it what you wish. + + Equivalent code is available from RSA Data Security, Inc. + This code has been tested against that, and is equivalent, + except that you don't need to include two pages of legalese + with every copy. + + To compute the message digest of a chunk of bytes, declare an + MD5Context structure, pass it to MD5Init, call MD5Update as + needed on buffers full of bytes, and then call MD5Final, which + will fill a supplied 16-byte array with the digest. + + Changed so as no longer to depend on Colin Plumb's `usual.h' + header definitions; now uses stuff from dpkg's config.h + - Ian Jackson . + Still in the public domain. + + Josh Coalson: made some changes to integrate with libFLAC. + Still in the public domain, with no warranty. +*/ #include "../FLAC/ordinals.h" typedef union { - FLAC__byte *p8; - FLAC__int16 *p16; - FLAC__int32 *p32; + FLAC__byte *p8; + FLAC__int16 *p16; + FLAC__int32 *p32; } FLAC__multibyte; typedef struct { - FLAC__uint32 in[16]; - FLAC__uint32 buf[4]; - FLAC__uint32 bytes[2]; - FLAC__multibyte internal_buf; - size_t capacity; + FLAC__uint32 in[16]; + FLAC__uint32 buf[4]; + FLAC__uint32 bytes[2]; + FLAC__multibyte internal_buf; + size_t capacity; } FLAC__MD5Context; void FLAC__MD5Init(FLAC__MD5Context *context); diff --git a/src/libflac/private/memory.h b/src/libflac/private/memory.h index d8c0ed38..9ed2a088 100644 --- a/src/libflac/private/memory.h +++ b/src/libflac/private/memory.h @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2001-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__PRIVATE__MEMORY_H #define FLAC__PRIVATE__MEMORY_H @@ -42,9 +42,9 @@ #include "float.h" #include "../FLAC/ordinals.h" /* for FLAC__bool */ -/* Returns the unaligned address returned by malloc. - * Use free() on this address to deallocate. - */ +/* Returns the unaligned address returned by malloc. + Use free() on this address to deallocate. +*/ void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address); FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer); FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer); diff --git a/src/libflac/private/metadata.h b/src/libflac/private/metadata.h index 7cb5e62e..78e74e66 100644 --- a/src/libflac/private/metadata.h +++ b/src/libflac/private/metadata.h @@ -1,44 +1,44 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2002-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2002-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__PRIVATE__METADATA_H #define FLAC__PRIVATE__METADATA_H #include "../FLAC/metadata.h" -/* WATCHOUT: all malloc()ed data in the block is free()ed; this may not - * be a consistent state (e.g. PICTURE) or equivalent to the initial - * state after FLAC__metadata_object_new() - */ +/* WATCHOUT: all malloc()ed data in the block is free()ed; this may not + be a consistent state (e.g. PICTURE) or equivalent to the initial + state after FLAC__metadata_object_new() +*/ void FLAC__metadata_object_delete_data(FLAC__StreamMetadata *object); void FLAC__metadata_object_cuesheet_track_delete_data(FLAC__StreamMetadata_CueSheet_Track *object); diff --git a/src/libflac/private/window.h b/src/libflac/private/window.h index a3ab2f93..1ff1af66 100644 --- a/src/libflac/private/window.h +++ b/src/libflac/private/window.h @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2006-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2006-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__PRIVATE__WINDOW_H #define FLAC__PRIVATE__WINDOW_H @@ -43,14 +43,14 @@ #ifndef FLAC__INTEGER_ONLY_LIBRARY /* - * FLAC__window_*() - * -------------------------------------------------------------------- - * Calculates window coefficients according to different apodization - * functions. - * - * OUT window[0,L-1] - * IN L (number of points in window) - */ + FLAC__window_*() + -------------------------------------------------------------------- + Calculates window coefficients according to different apodization + functions. + + OUT window[0,L-1] + IN L (number of points in window) +*/ void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L); void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L); void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L); diff --git a/src/libflac/protected/all.h b/src/libflac/protected/all.h index 9468bd3b..1c505db3 100644 --- a/src/libflac/protected/all.h +++ b/src/libflac/protected/all.h @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2001-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__PROTECTED__ALL_H #define FLAC__PROTECTED__ALL_H diff --git a/src/libflac/protected/stream_decoder.h b/src/libflac/protected/stream_decoder.h index 9bab8806..321dfda3 100644 --- a/src/libflac/protected/stream_decoder.h +++ b/src/libflac/protected/stream_decoder.h @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2000-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__PROTECTED__STREAM_DECODER_H #define FLAC__PROTECTED__STREAM_DECODER_H @@ -39,22 +39,22 @@ #endif typedef struct FLAC__StreamDecoderProtected { - FLAC__StreamDecoderState state; - FLAC__StreamDecoderInitStatus initstate; - uint32_t channels; - FLAC__ChannelAssignment channel_assignment; - uint32_t bits_per_sample; - uint32_t sample_rate; /* in Hz */ - uint32_t blocksize; /* in samples (per channel) */ - FLAC__bool md5_checking; /* if true, generate MD5 signature of decoded data and compare against signature in the STREAMINFO metadata block */ + FLAC__StreamDecoderState state; + FLAC__StreamDecoderInitStatus initstate; + uint32_t channels; + FLAC__ChannelAssignment channel_assignment; + uint32_t bits_per_sample; + uint32_t sample_rate; /* in Hz */ + uint32_t blocksize; /* in samples (per channel) */ + FLAC__bool md5_checking; /* if true, generate MD5 signature of decoded data and compare against signature in the STREAMINFO metadata block */ #if FLAC__HAS_OGG - FLAC__OggDecoderAspect ogg_decoder_aspect; + FLAC__OggDecoderAspect ogg_decoder_aspect; #endif } FLAC__StreamDecoderProtected; /* - * Return the number of input bytes consumed - */ + Return the number of input bytes consumed +*/ uint32_t FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder); #endif diff --git a/src/libflac/protected/stream_encoder.h b/src/libflac/protected/stream_encoder.h index f4b52287..bb568394 100644 --- a/src/libflac/protected/stream_encoder.h +++ b/src/libflac/protected/stream_encoder.h @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2001-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__PROTECTED__STREAM_ENCODER_H #define FLAC__PROTECTED__STREAM_ENCODER_H @@ -45,73 +45,73 @@ #define FLAC__MAX_APODIZATION_FUNCTIONS 32 typedef enum { - FLAC__APODIZATION_BARTLETT, - FLAC__APODIZATION_BARTLETT_HANN, - FLAC__APODIZATION_BLACKMAN, - FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE, - FLAC__APODIZATION_CONNES, - FLAC__APODIZATION_FLATTOP, - FLAC__APODIZATION_GAUSS, - FLAC__APODIZATION_HAMMING, - FLAC__APODIZATION_HANN, - FLAC__APODIZATION_KAISER_BESSEL, - FLAC__APODIZATION_NUTTALL, - FLAC__APODIZATION_RECTANGLE, - FLAC__APODIZATION_TRIANGLE, - FLAC__APODIZATION_TUKEY, - FLAC__APODIZATION_PARTIAL_TUKEY, - FLAC__APODIZATION_PUNCHOUT_TUKEY, - FLAC__APODIZATION_WELCH + FLAC__APODIZATION_BARTLETT, + FLAC__APODIZATION_BARTLETT_HANN, + FLAC__APODIZATION_BLACKMAN, + FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE, + FLAC__APODIZATION_CONNES, + FLAC__APODIZATION_FLATTOP, + FLAC__APODIZATION_GAUSS, + FLAC__APODIZATION_HAMMING, + FLAC__APODIZATION_HANN, + FLAC__APODIZATION_KAISER_BESSEL, + FLAC__APODIZATION_NUTTALL, + FLAC__APODIZATION_RECTANGLE, + FLAC__APODIZATION_TRIANGLE, + FLAC__APODIZATION_TUKEY, + FLAC__APODIZATION_PARTIAL_TUKEY, + FLAC__APODIZATION_PUNCHOUT_TUKEY, + FLAC__APODIZATION_WELCH } FLAC__ApodizationFunction; typedef struct { - FLAC__ApodizationFunction type; - union { - struct { - FLAC__real stddev; - } gauss; - struct { - FLAC__real p; - } tukey; - struct { - FLAC__real p; - FLAC__real start; - FLAC__real end; - } multiple_tukey; - } parameters; + FLAC__ApodizationFunction type; + union { + struct { + FLAC__real stddev; + } gauss; + struct { + FLAC__real p; + } tukey; + struct { + FLAC__real p; + FLAC__real start; + FLAC__real end; + } multiple_tukey; + } parameters; } FLAC__ApodizationSpecification; #endif // #ifndef FLAC__INTEGER_ONLY_LIBRARY typedef struct FLAC__StreamEncoderProtected { - FLAC__StreamEncoderState state; - FLAC__bool verify; - FLAC__bool streamable_subset; - FLAC__bool do_md5; - FLAC__bool do_mid_side_stereo; - FLAC__bool loose_mid_side_stereo; - uint32_t channels; - uint32_t bits_per_sample; - uint32_t sample_rate; - uint32_t blocksize; + FLAC__StreamEncoderState state; + FLAC__bool verify; + FLAC__bool streamable_subset; + FLAC__bool do_md5; + FLAC__bool do_mid_side_stereo; + FLAC__bool loose_mid_side_stereo; + uint32_t channels; + uint32_t bits_per_sample; + uint32_t sample_rate; + uint32_t blocksize; #ifndef FLAC__INTEGER_ONLY_LIBRARY - uint32_t num_apodizations; - FLAC__ApodizationSpecification apodizations[FLAC__MAX_APODIZATION_FUNCTIONS]; + uint32_t num_apodizations; + FLAC__ApodizationSpecification apodizations[FLAC__MAX_APODIZATION_FUNCTIONS]; #endif - uint32_t max_lpc_order; - uint32_t qlp_coeff_precision; - FLAC__bool do_qlp_coeff_prec_search; - FLAC__bool do_exhaustive_model_search; - FLAC__bool do_escape_coding; - uint32_t min_residual_partition_order; - uint32_t max_residual_partition_order; - uint32_t rice_parameter_search_dist; - FLAC__uint64 total_samples_estimate; - FLAC__StreamMetadata **metadata; - uint32_t num_metadata_blocks; - FLAC__uint64 streaminfo_offset, seektable_offset, audio_offset; + uint32_t max_lpc_order; + uint32_t qlp_coeff_precision; + FLAC__bool do_qlp_coeff_prec_search; + FLAC__bool do_exhaustive_model_search; + FLAC__bool do_escape_coding; + uint32_t min_residual_partition_order; + uint32_t max_residual_partition_order; + uint32_t rice_parameter_search_dist; + FLAC__uint64 total_samples_estimate; + FLAC__StreamMetadata **metadata; + uint32_t num_metadata_blocks; + FLAC__uint64 streaminfo_offset, seektable_offset, audio_offset; #if FLAC__HAS_OGG - FLAC__OggEncoderAspect ogg_encoder_aspect; + FLAC__OggEncoderAspect ogg_encoder_aspect; #endif } FLAC__StreamEncoderProtected; diff --git a/src/libflac/share/alloc.h b/src/libflac/share/alloc.h index c3791d67..f1aa6c73 100644 --- a/src/libflac/share/alloc.h +++ b/src/libflac/share/alloc.h @@ -1,34 +1,34 @@ -/* alloc - Convenience routines for safely allocating memory - * Copyright (C) 2007-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* alloc - Convenience routines for safely allocating memory + Copyright (C) 2007-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__SHARE__ALLOC_H #define FLAC__SHARE__ALLOC_H @@ -37,9 +37,9 @@ # include "../config.h" //#endif -/* WATCHOUT: for c++ you may have to #define __STDC_LIMIT_MACROS 1 real early - * before #including this file, otherwise SIZE_MAX might not be defined - */ +/* WATCHOUT: for c++ you may have to #define __STDC_LIMIT_MACROS 1 real early + before #including this file, otherwise SIZE_MAX might not be defined +*/ #include /* for SIZE_MAX */ //#if HAVE_STDINT_H @@ -63,157 +63,169 @@ # define SIZE_MAX SIZE_T_MAX #endif -/* avoid malloc()ing 0 bytes, see: - * https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003 +/* avoid malloc()ing 0 bytes, see: + https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003 */ -static inline void *safe_malloc_(size_t size) -{ - /* malloc(0) is undefined; FLAC src convention is to always allocate */ - if(!size) - size++; - return malloc(size); +static inline void *safe_malloc_(size_t size) { + /* malloc(0) is undefined; FLAC src convention is to always allocate */ + if (!size) { + size++; + } + return malloc(size); } -static inline void *safe_calloc_(size_t nmemb, size_t size) -{ - if(!nmemb || !size) - return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ - return calloc(nmemb, size); +static inline void *safe_calloc_(size_t nmemb, size_t size) { + if (!nmemb || !size) { + return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ + } + return calloc(nmemb, size); } /*@@@@ there's probably a better way to prevent overflows when allocating untrusted sums but this works for now */ -static inline void *safe_malloc_add_2op_(size_t size1, size_t size2) -{ - size2 += size1; - if(size2 < size1) - return 0; - return safe_malloc_(size2); +static inline void *safe_malloc_add_2op_(size_t size1, size_t size2) { + size2 += size1; + if (size2 < size1) { + return 0; + } + return safe_malloc_(size2); } -static inline void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3) -{ - size2 += size1; - if(size2 < size1) - return 0; - size3 += size2; - if(size3 < size2) - return 0; - return safe_malloc_(size3); +static inline void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3) { + size2 += size1; + if (size2 < size1) { + return 0; + } + size3 += size2; + if (size3 < size2) { + return 0; + } + return safe_malloc_(size3); } -static inline void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4) -{ - size2 += size1; - if(size2 < size1) - return 0; - size3 += size2; - if(size3 < size2) - return 0; - size4 += size3; - if(size4 < size3) - return 0; - return safe_malloc_(size4); +static inline void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4) { + size2 += size1; + if (size2 < size1) { + return 0; + } + size3 += size2; + if (size3 < size2) { + return 0; + } + size4 += size3; + if (size4 < size3) { + return 0; + } + return safe_malloc_(size4); } void *safe_malloc_mul_2op_(size_t size1, size_t size2) ; -static inline void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3) -{ - if(!size1 || !size2 || !size3) - return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ - if(size1 > SIZE_MAX / size2) - return 0; - size1 *= size2; - if(size1 > SIZE_MAX / size3) - return 0; - return malloc(size1*size3); +static inline void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3) { + if (!size1 || !size2 || !size3) { + return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ + } + if (size1 > SIZE_MAX / size2) { + return 0; + } + size1 *= size2; + if (size1 > SIZE_MAX / size3) { + return 0; + } + return malloc(size1 * size3); } /* size1*size2 + size3 */ -static inline void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3) -{ - if(!size1 || !size2) - return safe_malloc_(size3); - if(size1 > SIZE_MAX / size2) - return 0; - return safe_malloc_add_2op_(size1*size2, size3); +static inline void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3) { + if (!size1 || !size2) { + return safe_malloc_(size3); + } + if (size1 > SIZE_MAX / size2) { + return 0; + } + return safe_malloc_add_2op_(size1 * size2, size3); } /* size1 * (size2 + size3) */ -static inline void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3) -{ - if(!size1 || (!size2 && !size3)) - return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ - size2 += size3; - if(size2 < size3) - return 0; - if(size1 > SIZE_MAX / size2) - return 0; - return malloc(size1*size2); +static inline void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3) { + if (!size1 || (!size2 && !size3)) { + return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ + } + size2 += size3; + if (size2 < size3) { + return 0; + } + if (size1 > SIZE_MAX / size2) { + return 0; + } + return malloc(size1 * size2); } -static inline void *safe_realloc_(void *ptr, size_t size) -{ - void *oldptr = ptr; - void *newptr = realloc(ptr, size); - if(size > 0 && newptr == 0) - free(oldptr); - return newptr; +static inline void *safe_realloc_(void *ptr, size_t size) { + void *oldptr = ptr; + void *newptr = realloc(ptr, size); + if (size > 0 && newptr == 0) { + free(oldptr); + } + return newptr; } -static inline void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2) -{ - size2 += size1; - if(size2 < size1) { - free(ptr); - return 0; - } - return realloc(ptr, size2); +static inline void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2) { + size2 += size1; + if (size2 < size1) { + free(ptr); + return 0; + } + return realloc(ptr, size2); } -static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) -{ - size2 += size1; - if(size2 < size1) - return 0; - size3 += size2; - if(size3 < size2) - return 0; - return realloc(ptr, size3); +static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) { + size2 += size1; + if (size2 < size1) { + return 0; + } + size3 += size2; + if (size3 < size2) { + return 0; + } + return realloc(ptr, size3); } -static inline void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4) -{ - size2 += size1; - if(size2 < size1) - return 0; - size3 += size2; - if(size3 < size2) - return 0; - size4 += size3; - if(size4 < size3) - return 0; - return realloc(ptr, size4); +static inline void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4) { + size2 += size1; + if (size2 < size1) { + return 0; + } + size3 += size2; + if (size3 < size2) { + return 0; + } + size4 += size3; + if (size4 < size3) { + return 0; + } + return realloc(ptr, size4); } -static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2) -{ - if(!size1 || !size2) - return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ - if(size1 > SIZE_MAX / size2) - return 0; - return safe_realloc_(ptr, size1*size2); +static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2) { + if (!size1 || !size2) { + return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ + } + if (size1 > SIZE_MAX / size2) { + return 0; + } + return safe_realloc_(ptr, size1 * size2); } /* size1 * (size2 + size3) */ -static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) -{ - if(!size1 || (!size2 && !size3)) - return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ - size2 += size3; - if(size2 < size3) - return 0; - return safe_realloc_mul_2op_(ptr, size1, size2); +static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) { + if (!size1 || (!size2 && !size3)) { + return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ + } + size2 += size3; + if (size2 < size3) { + return 0; + } + return safe_realloc_mul_2op_(ptr, size1, size2); } #endif diff --git a/src/libflac/share/compat.h b/src/libflac/share/compat.h index c28054be..2352a241 100644 --- a/src/libflac/share/compat.h +++ b/src/libflac/share/compat.h @@ -1,40 +1,40 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2012-2016 Xiph.org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* This is the preferred location of all CPP hackery to make $random_compiler - * work like something approaching a C99 (or maybe more accurately GNU99) - * compiler. - * - * It is assumed that this header will be included after "config.h". - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2012-2016 Xiph.org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* This is the preferred location of all CPP hackery to make $random_compiler + work like something approaching a C99 (or maybe more accurately GNU99) + compiler. + + It is assumed that this header will be included after "config.h". +*/ #ifndef FLAC__SHARE__COMPAT_H #define FLAC__SHARE__COMPAT_H @@ -194,12 +194,12 @@ #define M_PI 3.14159265358979323846 #endif -/* FLAC needs to compile and work correctly on systems with a normal ISO C99 - * snprintf as well as Microsoft Visual Studio which has an non-standards - * conformant snprint_s function. - * - * This function wraps the MS version to behave more like the ISO version. - */ +/* FLAC needs to compile and work correctly on systems with a normal ISO C99 + snprintf as well as Microsoft Visual Studio which has an non-standards + conformant snprint_s function. + + This function wraps the MS version to behave more like the ISO version. +*/ #include #ifdef __cplusplus extern "C" { diff --git a/src/libflac/share/endswap.h b/src/libflac/share/endswap.h index 9088a747..71fc097d 100644 --- a/src/libflac/share/endswap.h +++ b/src/libflac/share/endswap.h @@ -1,33 +1,33 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2012-2016 Xiph.org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2012-2016 Xiph.org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ /* It is assumed that this header will be included after "config.h". */ @@ -35,9 +35,8 @@ /* GCC prior to 4.8 didn't provide bswap16 on x86_64 */ #if ! HAVE_BSWAP16 -static inline unsigned short __builtin_bswap16(unsigned short a) -{ - return (a<<8)|(a>>8); +static inline unsigned short __builtin_bswap16(unsigned short a) { + return (a << 8) | (a >> 8); } #endif diff --git a/src/libflac/share/getopt.h b/src/libflac/share/getopt.h index 66aced0f..82c8df1f 100644 --- a/src/libflac/share/getopt.h +++ b/src/libflac/share/getopt.h @@ -12,24 +12,24 @@ around code, while at the same time trying to touch the original as little as possible. */ -/* Declarations for getopt. - Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. - This file is part of the GNU C Library. +/* Declarations for getopt. + Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. + This file is part of the GNU C Library. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #ifndef SHARE__GETOPT_H #define SHARE__GETOPT_H @@ -42,30 +42,30 @@ extern "C" { #endif -/* For communication from `share__getopt' to the caller. - When `share__getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ +/* For communication from `share__getopt' to the caller. + When `share__getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ extern char *share__optarg; -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `share__getopt'. +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `share__getopt'. - On entry to `share__getopt', zero means this is the first call; initialize. + On entry to `share__getopt', zero means this is the first call; initialize. - When `share__getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. + When `share__getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. - Otherwise, `share__optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ + Otherwise, `share__optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ extern int share__optind; -/* Callers store zero here to inhibit the error message `share__getopt' prints - for unrecognized options. */ +/* Callers store zero here to inhibit the error message `share__getopt' prints + for unrecognized options. */ extern int share__opterr; @@ -74,39 +74,38 @@ extern int share__opterr; extern int share__optopt; /*[JEC] was:#ifndef __need_getopt */ -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to share__getopt_long or share__getopt_long_only is a vector - of `struct share__option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - share__no_argument (or 0) if the option does not take an argument, - share__required_argument (or 1) if the option requires an argument, - share__optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `share__optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `share__getopt' - returns the contents of the `val' field. */ - -struct share__option -{ +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to share__getopt_long or share__getopt_long_only is a vector + of `struct share__option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + share__no_argument (or 0) if the option does not take an argument, + share__required_argument (or 1) if the option requires an argument, + share__optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `share__optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `share__getopt' + returns the contents of the `val' field. */ + +struct share__option { # if defined __STDC__ && __STDC__ - const char *name; + const char *name; # else - char *name; + char *name; # endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; }; /* Names for the values of the `has_arg' field of `struct share__option'. */ @@ -117,52 +116,52 @@ struct share__option /*[JEC] was:#endif*/ /* need getopt */ -/* Get definitions and prototypes for functions to process the - arguments in ARGV (ARGC of them, minus the program name) for - options given in OPTS. +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. - Return the option character from OPTS just read. Return -1 when - there are no more options. For unrecognized options, or options - missing arguments, `share__optopt' is set to the option letter, and '?' is - returned. + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, `share__optopt' is set to the option letter, and '?' is + returned. - The OPTS string is a list of characters which are recognized option - letters, optionally followed by colons, specifying that that letter - takes an argument, to be placed in `share__optarg'. + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in `share__optarg'. - If a letter in OPTS is followed by two colons, its argument is - optional. This behavior is specific to the GNU `share__getopt'. + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU `share__getopt'. - The argument `--' causes premature termination of argument - scanning, explicitly telling `share__getopt' that there are no more - options. + The argument `--' causes premature termination of argument + scanning, explicitly telling `share__getopt' that there are no more + options. - If OPTS begins with `--', then non-option arguments are treated as - arguments to the option '\0'. This behavior is specific to the GNU - `share__getopt'. */ + If OPTS begins with `--', then non-option arguments are treated as + arguments to the option '\0'. This behavior is specific to the GNU + `share__getopt'. */ /*[JEC] was:#if defined __STDC__ && __STDC__*/ /*[JEC] was:# ifdef __GNU_LIBRARY__*/ -/* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. To avoid compilation - errors, only prototype getopt for the GNU C library. */ -extern int share__getopt (int argc, char *const *argv, const char *shortopts); +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int share__getopt(int argc, char *const *argv, const char *shortopts); /*[JEC] was:# else*/ /* not __GNU_LIBRARY__ */ /*[JEC] was:extern int getopt ();*/ /*[JEC] was:# endif*/ /* __GNU_LIBRARY__ */ /*[JEC] was:# ifndef __need_getopt*/ -extern int share__getopt_long (int argc, char *const *argv, const char *shortopts, - const struct share__option *longopts, int *longind); -extern int share__getopt_long_only (int argc, char *const *argv, - const char *shortopts, - const struct share__option *longopts, int *longind); +extern int share__getopt_long(int argc, char *const *argv, const char *shortopts, + const struct share__option *longopts, int *longind); +extern int share__getopt_long_only(int argc, char *const *argv, + const char *shortopts, + const struct share__option *longopts, int *longind); /* Internal only. Users should not call this directly. */ -extern int share___getopt_internal (int argc, char *const *argv, - const char *shortopts, - const struct share__option *longopts, int *longind, - int long_only); +extern int share___getopt_internal(int argc, char *const *argv, + const char *shortopts, + const struct share__option *longopts, int *longind, + int long_only); /*[JEC] was:# endif*/ /*[JEC] was:#else*/ /* not __STDC__ */ /*[JEC] was:extern int getopt ();*/ diff --git a/src/libflac/share/macros.h b/src/libflac/share/macros.h index 20b3ea56..ddc6c51d 100644 --- a/src/libflac/share/macros.h +++ b/src/libflac/share/macros.h @@ -1,43 +1,43 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2013-2016 Xiph.org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2013-2016 Xiph.org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #include -/* FLAC_CHECK_RETURN : Check the return value of the provided function and - * print an error message if it fails (ie returns a value < 0). - * - * Ideally, a library should not print anything, but this macro is only used - * for things that extremely unlikely to fail, like `chown` to a previoulsy - * saved `uid`. - */ +/* FLAC_CHECK_RETURN : Check the return value of the provided function and + print an error message if it fails (ie returns a value < 0). + + Ideally, a library should not print anything, but this macro is only used + for things that extremely unlikely to fail, like `chown` to a previously + saved `uid`. +*/ #define FLAC_CHECK_RETURN(x) \ { if ((x) < 0) \ diff --git a/src/libflac/share/private.h b/src/libflac/share/private.h index 03083d3f..6db077c3 100644 --- a/src/libflac/share/private.h +++ b/src/libflac/share/private.h @@ -1,41 +1,41 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2013-2016 Xiph.org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2013-2016 Xiph.org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef FLAC__SHARE__PRIVATE_H #define FLAC__SHARE__PRIVATE_H /* - * Unpublished debug routines from libFLAC. This should not be used from any - * client code other than code shipped with the FLAC sources. - */ + Unpublished debug routines from libFLAC. This should not be used from any + client code other than code shipped with the FLAC sources. +*/ FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value); FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value); FLAC_API FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value); diff --git a/src/libflac/share/safe_str.h b/src/libflac/share/safe_str.h index 6709334e..848597c1 100644 --- a/src/libflac/share/safe_str.h +++ b/src/libflac/share/safe_str.h @@ -1,71 +1,71 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2013-2016 Xiph.org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* Safe string handling functions to replace things like strcpy, strncpy, - * strcat, strncat etc. - * All of these functions guarantee a correctly NUL terminated string but - * the string may be truncated if the destination buffer was too short. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2013-2016 Xiph.org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* Safe string handling functions to replace things like strcpy, strncpy, + strcat, strncat etc. + All of these functions guarantee a correctly NUL terminated string but + the string may be truncated if the destination buffer was too short. +*/ #ifndef FLAC__SHARE_SAFE_STR_H #define FLAC__SHARE_SAFE_STR_H static inline char * -safe_strncat(char *dest, const char *src, size_t dest_size) -{ - char * ret; +safe_strncat(char *dest, const char *src, size_t dest_size) { + char * ret; - if (dest_size < 1) - return dest; + if (dest_size < 1) { + return dest; + } - /* Assume dist has space for a term character .. */ - ret = strncat(dest, src, dest_size - strlen (dest)); - /* .. but set it explicitly. */ - dest [dest_size - 1] = 0; + /* Assume dist has space for a term character .. */ + ret = strncat(dest, src, dest_size - strlen(dest)); + /* .. but set it explicitly. */ + dest [dest_size - 1] = 0; - return ret; + return ret; } static inline char * -safe_strncpy(char *dest, const char *src, size_t dest_size) -{ - char * ret; +safe_strncpy(char *dest, const char *src, size_t dest_size) { + char * ret; - if (dest_size < 1) - return dest; + if (dest_size < 1) { + return dest; + } - ret = strncpy(dest, src, dest_size - 1); - dest [dest_size - 1] = 0; + ret = strncpy(dest, src, dest_size - 1); + dest [dest_size - 1] = 0; - return ret; + return ret; } #endif /* FLAC__SHARE_SAFE_STR_H */ diff --git a/src/libflac/share/utf8.h b/src/libflac/share/utf8.h index 7d6650d6..443d630e 100644 --- a/src/libflac/share/utf8.h +++ b/src/libflac/share/utf8.h @@ -2,22 +2,22 @@ #define SHARE__UTF8_H /* - * Convert a string between UTF-8 and the locale's charset. - * Invalid bytes are replaced by '#', and characters that are - * not available in the target encoding are replaced by '?'. - * - * If the locale's charset is not set explicitly then it is - * obtained using nl_langinfo(CODESET), where available, the - * environment variable CHARSET, or assumed to be US-ASCII. - * - * Return value of conversion functions: - * - * -1 : memory allocation failed - * 0 : data was converted exactly - * 1 : valid data was converted approximately (using '?') - * 2 : input was invalid (but still converted, using '#') - * 3 : unknown encoding (but still converted, using '?') - */ + Convert a string between UTF-8 and the locale's charset. + Invalid bytes are replaced by '#', and characters that are + not available in the target encoding are replaced by '?'. + + If the locale's charset is not set explicitly then it is + obtained using nl_langinfo(CODESET), where available, the + environment variable CHARSET, or assumed to be US-ASCII. + + Return value of conversion functions: + + -1 : memory allocation failed + 0 : data was converted exactly + 1 : valid data was converted approximately (using '?') + 2 : input was invalid (but still converted, using '#') + 3 : unknown encoding (but still converted, using '?') +*/ int utf8_encode(const char *from, char **to); int utf8_decode(const char *from, char **to); diff --git a/src/libflac/stream_decoder.c b/src/libflac/stream_decoder.c index eabcf092..9562e29a 100644 --- a/src/libflac/stream_decoder.c +++ b/src/libflac/stream_decoder.c @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2000-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ //#ifdef HAVE_CONFIG_H # include "config.h" @@ -63,17 +63,17 @@ FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC = FLAC__HAS_OGG; /*********************************************************************** - * - * Private static data - * + + Private static data + ***********************************************************************/ static const FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' }; /*********************************************************************** - * - * Private class method prototypes - * + + Private class method prototypes + ***********************************************************************/ static void set_defaults_(FLAC__StreamDecoder *decoder); @@ -116,70 +116,70 @@ static FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLA //static FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data); /*********************************************************************** - * - * Private class data - * + + Private class data + ***********************************************************************/ typedef struct FLAC__StreamDecoderPrivate { - FLAC__bool is_ogg; - FLAC__StreamDecoderReadCallback read_callback; - FLAC__StreamDecoderSeekCallback seek_callback; - FLAC__StreamDecoderTellCallback tell_callback; - FLAC__StreamDecoderLengthCallback length_callback; - FLAC__StreamDecoderEofCallback eof_callback; - FLAC__StreamDecoderWriteCallback write_callback; - FLAC__StreamDecoderMetadataCallback metadata_callback; - FLAC__StreamDecoderErrorCallback error_callback; - /* generic 32-bit datapath: */ - void (*local_lpc_restore_signal)(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); - /* generic 64-bit datapath: */ - void (*local_lpc_restore_signal_64bit)(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); - /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit): */ - void (*local_lpc_restore_signal_16bit)(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); - void *client_data; -// FILE *file; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */ - FLAC__BitReader *input; - FLAC__int32 *output[FLAC__MAX_CHANNELS]; - FLAC__int32 *residual[FLAC__MAX_CHANNELS]; /* WATCHOUT: these are the aligned pointers; the real pointers that should be free()'d are residual_unaligned[] below */ - FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents[FLAC__MAX_CHANNELS]; - uint32_t output_capacity, output_channels; - FLAC__uint32 fixed_block_size, next_fixed_block_size; - FLAC__uint64 samples_decoded; - FLAC__bool has_stream_info, has_seek_table; - FLAC__StreamMetadata stream_info; - FLAC__StreamMetadata seek_table; - FLAC__bool metadata_filter[128]; /* MAGIC number 128 == total number of metadata block types == 1 << 7 */ - FLAC__byte *metadata_filter_ids; - size_t metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */ - FLAC__Frame frame; - FLAC__bool cached; /* true if there is a byte in lookahead */ - FLAC__CPUInfo cpuinfo; - FLAC__byte header_warmup[2]; /* contains the sync code and reserved bits */ - FLAC__byte lookahead; /* temp storage when we need to look ahead one byte in the stream */ - /* unaligned (original) pointers to allocated data */ - FLAC__int32 *residual_unaligned[FLAC__MAX_CHANNELS]; - FLAC__bool do_md5_checking; /* initially gets protected_->md5_checking but is turned off after a seek or if the metadata has a zero MD5 */ - FLAC__bool internal_reset_hack; /* used only during init() so we can call reset to set up the decoder without rewinding the input */ - FLAC__bool is_seeking; - FLAC__MD5Context md5context; - FLAC__byte computed_md5sum[16]; /* this is the sum we computed from the decoded data */ - /* (the rest of these are only used for seeking) */ - FLAC__Frame last_frame; /* holds the info of the last frame we seeked to */ - FLAC__uint64 first_frame_offset; /* hint to the seek routine of where in the stream the first audio frame starts */ - FLAC__uint64 target_sample; - uint32_t unparseable_frame_count; /* used to tell whether we're decoding a future version of FLAC or just got a bad sync */ - FLAC__bool got_a_frame; /* hack needed in Ogg FLAC seek routine to check when process_single() actually writes a frame */ + FLAC__bool is_ogg; + FLAC__StreamDecoderReadCallback read_callback; + FLAC__StreamDecoderSeekCallback seek_callback; + FLAC__StreamDecoderTellCallback tell_callback; + FLAC__StreamDecoderLengthCallback length_callback; + FLAC__StreamDecoderEofCallback eof_callback; + FLAC__StreamDecoderWriteCallback write_callback; + FLAC__StreamDecoderMetadataCallback metadata_callback; + FLAC__StreamDecoderErrorCallback error_callback; + /* generic 32-bit datapath: */ + void (*local_lpc_restore_signal)(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); + /* generic 64-bit datapath: */ + void (*local_lpc_restore_signal_64bit)(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); + /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit): */ + void (*local_lpc_restore_signal_16bit)(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); + void *client_data; + // FILE *file; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */ + FLAC__BitReader *input; + FLAC__int32 *output[FLAC__MAX_CHANNELS]; + FLAC__int32 *residual[FLAC__MAX_CHANNELS]; /* WATCHOUT: these are the aligned pointers; the real pointers that should be free()'d are residual_unaligned[] below */ + FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents[FLAC__MAX_CHANNELS]; + uint32_t output_capacity, output_channels; + FLAC__uint32 fixed_block_size, next_fixed_block_size; + FLAC__uint64 samples_decoded; + FLAC__bool has_stream_info, has_seek_table; + FLAC__StreamMetadata stream_info; + FLAC__StreamMetadata seek_table; + FLAC__bool metadata_filter[128]; /* MAGIC number 128 == total number of metadata block types == 1 << 7 */ + FLAC__byte *metadata_filter_ids; + size_t metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */ + FLAC__Frame frame; + FLAC__bool cached; /* true if there is a byte in lookahead */ + FLAC__CPUInfo cpuinfo; + FLAC__byte header_warmup[2]; /* contains the sync code and reserved bits */ + FLAC__byte lookahead; /* temp storage when we need to look ahead one byte in the stream */ + /* unaligned (original) pointers to allocated data */ + FLAC__int32 *residual_unaligned[FLAC__MAX_CHANNELS]; + FLAC__bool do_md5_checking; /* initially gets protected_->md5_checking but is turned off after a seek or if the metadata has a zero MD5 */ + FLAC__bool internal_reset_hack; /* used only during init() so we can call reset to set up the decoder without rewinding the input */ + FLAC__bool is_seeking; + FLAC__MD5Context md5context; + FLAC__byte computed_md5sum[16]; /* this is the sum we computed from the decoded data */ + /* (the rest of these are only used for seeking) */ + FLAC__Frame last_frame; /* holds the info of the last frame we seeked to */ + FLAC__uint64 first_frame_offset; /* hint to the seek routine of where in the stream the first audio frame starts */ + FLAC__uint64 target_sample; + uint32_t unparseable_frame_count; /* used to tell whether we're decoding a future version of FLAC or just got a bad sync */ + FLAC__bool got_a_frame; /* hack needed in Ogg FLAC seek routine to check when process_single() actually writes a frame */ } FLAC__StreamDecoderPrivate; /*********************************************************************** - * - * Public static class data - * + + Public static class data + ***********************************************************************/ // Not used in AudioGeneratorFLAC, save some RAM /* -FLAC_API const char * const FLAC__StreamDecoderStateString[] = { + FLAC_API const char * const FLAC__StreamDecoderStateString[] = { "FLAC__STREAM_DECODER_SEARCH_FOR_METADATA", "FLAC__STREAM_DECODER_READ_METADATA", "FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC", @@ -190,3226 +190,3343 @@ FLAC_API const char * const FLAC__StreamDecoderStateString[] = { "FLAC__STREAM_DECODER_ABORTED", "FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR", "FLAC__STREAM_DECODER_UNINITIALIZED" -}; + }; -FLAC_API const char * const FLAC__StreamDecoderInitStatusString[] = { + FLAC_API const char * const FLAC__StreamDecoderInitStatusString[] = { "FLAC__STREAM_DECODER_INIT_STATUS_OK", "FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER", "FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS", "FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR", "FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE", "FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED" -}; + }; -FLAC_API const char * const FLAC__StreamDecoderReadStatusString[] = { + FLAC_API const char * const FLAC__StreamDecoderReadStatusString[] = { "FLAC__STREAM_DECODER_READ_STATUS_CONTINUE", "FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM", "FLAC__STREAM_DECODER_READ_STATUS_ABORT" -}; + }; -FLAC_API const char * const FLAC__StreamDecoderSeekStatusString[] = { + FLAC_API const char * const FLAC__StreamDecoderSeekStatusString[] = { "FLAC__STREAM_DECODER_SEEK_STATUS_OK", "FLAC__STREAM_DECODER_SEEK_STATUS_ERROR", "FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED" -}; + }; -FLAC_API const char * const FLAC__StreamDecoderTellStatusString[] = { + FLAC_API const char * const FLAC__StreamDecoderTellStatusString[] = { "FLAC__STREAM_DECODER_TELL_STATUS_OK", "FLAC__STREAM_DECODER_TELL_STATUS_ERROR", "FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED" -}; + }; -FLAC_API const char * const FLAC__StreamDecoderLengthStatusString[] = { + FLAC_API const char * const FLAC__StreamDecoderLengthStatusString[] = { "FLAC__STREAM_DECODER_LENGTH_STATUS_OK", "FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR", "FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED" -}; + }; -FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[] = { + FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[] = { "FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE", "FLAC__STREAM_DECODER_WRITE_STATUS_ABORT" -}; + }; */ FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[] = { - "FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC", - "FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER", - "FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH", - "FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM" + "FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC", + "FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER", + "FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH", + "FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM" }; /*********************************************************************** - * - * Class constructor/destructor - * + + Class constructor/destructor + ***********************************************************************/ -FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void) -{ - FLAC__StreamDecoder *decoder; - uint32_t i; +FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void) { + FLAC__StreamDecoder *decoder; + uint32_t i; - FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ + FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ - decoder = calloc(1, sizeof(FLAC__StreamDecoder)); - if(decoder == 0) { - return 0; - } + decoder = calloc(1, sizeof(FLAC__StreamDecoder)); + if (decoder == 0) { + return 0; + } - decoder->protected_ = calloc(1, sizeof(FLAC__StreamDecoderProtected)); - if(decoder->protected_ == 0) { - free(decoder); - return 0; - } + decoder->protected_ = calloc(1, sizeof(FLAC__StreamDecoderProtected)); + if (decoder->protected_ == 0) { + free(decoder); + return 0; + } - decoder->private_ = calloc(1, sizeof(FLAC__StreamDecoderPrivate)); - if(decoder->private_ == 0) { - free(decoder->protected_); - free(decoder); - return 0; - } + decoder->private_ = calloc(1, sizeof(FLAC__StreamDecoderPrivate)); + if (decoder->private_ == 0) { + free(decoder->protected_); + free(decoder); + return 0; + } - decoder->private_->input = FLAC__bitreader_new(); - if(decoder->private_->input == 0) { - free(decoder->private_); - free(decoder->protected_); - free(decoder); - return 0; - } + decoder->private_->input = FLAC__bitreader_new(); + if (decoder->private_->input == 0) { + free(decoder->private_); + free(decoder->protected_); + free(decoder); + return 0; + } - decoder->private_->metadata_filter_ids_capacity = 16; - if(0 == (decoder->private_->metadata_filter_ids = malloc((FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) * decoder->private_->metadata_filter_ids_capacity))) { - FLAC__bitreader_delete(decoder->private_->input); - free(decoder->private_); - free(decoder->protected_); - free(decoder); - return 0; - } + decoder->private_->metadata_filter_ids_capacity = 16; + if (0 == (decoder->private_->metadata_filter_ids = malloc((FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8) * decoder->private_->metadata_filter_ids_capacity))) { + FLAC__bitreader_delete(decoder->private_->input); + free(decoder->private_); + free(decoder->protected_); + free(decoder); + return 0; + } - for(i = 0; i < FLAC__MAX_CHANNELS; i++) { - decoder->private_->output[i] = 0; - decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; - } + for (i = 0; i < FLAC__MAX_CHANNELS; i++) { + decoder->private_->output[i] = 0; + decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; + } - decoder->private_->output_capacity = 0; - decoder->private_->output_channels = 0; - decoder->private_->has_seek_table = false; + decoder->private_->output_capacity = 0; + decoder->private_->output_channels = 0; + decoder->private_->has_seek_table = false; - for(i = 0; i < FLAC__MAX_CHANNELS; i++) - FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&decoder->private_->partitioned_rice_contents[i]); + for (i = 0; i < FLAC__MAX_CHANNELS; i++) { + FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&decoder->private_->partitioned_rice_contents[i]); + } -// decoder->private_->file = 0; + // decoder->private_->file = 0; - set_defaults_(decoder); + set_defaults_(decoder); - decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED; + decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED; - return decoder; + return decoder; } -FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder) -{ - uint32_t i; +FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder) { + uint32_t i; - if (decoder == NULL) - return ; + if (decoder == NULL) { + return ; + } - FLAC__ASSERT(0 != decoder->protected_); - FLAC__ASSERT(0 != decoder->private_); - FLAC__ASSERT(0 != decoder->private_->input); + FLAC__ASSERT(0 != decoder->protected_); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->private_->input); - (void)FLAC__stream_decoder_finish(decoder); + (void)FLAC__stream_decoder_finish(decoder); - if(0 != decoder->private_->metadata_filter_ids) - free(decoder->private_->metadata_filter_ids); + if (0 != decoder->private_->metadata_filter_ids) { + free(decoder->private_->metadata_filter_ids); + } - FLAC__bitreader_delete(decoder->private_->input); + FLAC__bitreader_delete(decoder->private_->input); - for(i = 0; i < FLAC__MAX_CHANNELS; i++) - FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&decoder->private_->partitioned_rice_contents[i]); + for (i = 0; i < FLAC__MAX_CHANNELS; i++) { + FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&decoder->private_->partitioned_rice_contents[i]); + } - free(decoder->private_); - free(decoder->protected_); - free(decoder); + free(decoder->private_); + free(decoder->protected_); + free(decoder); } /*********************************************************************** - * - * Public class methods - * + + Public class methods + ***********************************************************************/ static FLAC__StreamDecoderInitStatus init_stream_internal_( - FLAC__StreamDecoder *decoder, - FLAC__StreamDecoderReadCallback read_callback, - FLAC__StreamDecoderSeekCallback seek_callback, - FLAC__StreamDecoderTellCallback tell_callback, - FLAC__StreamDecoderLengthCallback length_callback, - FLAC__StreamDecoderEofCallback eof_callback, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data, - FLAC__bool is_ogg -) -{ - FLAC__ASSERT(0 != decoder); - - if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) - return FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED; - - if(FLAC__HAS_OGG == 0 && is_ogg) - return FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER; - - if( - 0 == read_callback || - 0 == write_callback || - 0 == error_callback || - (seek_callback && (0 == tell_callback || 0 == length_callback || 0 == eof_callback)) - ) - return FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS; + FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderReadCallback read_callback, + FLAC__StreamDecoderSeekCallback seek_callback, + FLAC__StreamDecoderTellCallback tell_callback, + FLAC__StreamDecoderLengthCallback length_callback, + FLAC__StreamDecoderEofCallback eof_callback, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data, + FLAC__bool is_ogg +) { + FLAC__ASSERT(0 != decoder); + + if (decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) { + return FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED; + } + + if (FLAC__HAS_OGG == 0 && is_ogg) { + return FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER; + } + + if ( + 0 == read_callback || + 0 == write_callback || + 0 == error_callback || + (seek_callback && (0 == tell_callback || 0 == length_callback || 0 == eof_callback)) + ) { + return FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS; + } #if FLAC__HAS_OGG - decoder->private_->is_ogg = is_ogg; - if(is_ogg && !FLAC__ogg_decoder_aspect_init(&decoder->protected_->ogg_decoder_aspect)) - return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE; + decoder->private_->is_ogg = is_ogg; + if (is_ogg && !FLAC__ogg_decoder_aspect_init(&decoder->protected_->ogg_decoder_aspect)) { + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE; + } #endif - /* - * get the CPU info and set the function pointers - */ - FLAC__cpu_info(&decoder->private_->cpuinfo); - /* first default to the non-asm routines */ - decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal; - decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide; - decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal; - /* now override with asm where appropriate */ + /* + get the CPU info and set the function pointers + */ + FLAC__cpu_info(&decoder->private_->cpuinfo); + /* first default to the non-asm routines */ + decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal; + decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide; + decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal; + /* now override with asm where appropriate */ #ifndef FLAC__NO_ASM - if(decoder->private_->cpuinfo.use_asm) { + if (decoder->private_->cpuinfo.use_asm) { #ifdef FLAC__CPU_IA32 - FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32); + FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32); #ifdef FLAC__HAS_NASM - decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_asm_ia32; /* OPT_IA32: was really necessary for GCC < 4.9 */ - if (decoder->private_->cpuinfo.x86.mmx) { - decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32; - decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx; - } - else { - decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32; - decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32; - } + decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_asm_ia32; /* OPT_IA32: was really necessary for GCC < 4.9 */ + if (decoder->private_->cpuinfo.x86.mmx) { + decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32; + decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx; + } else { + decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32; + decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32; + } #endif #if FLAC__HAS_X86INTRIN && ! defined FLAC__INTEGER_ONLY_LIBRARY # if defined FLAC__SSE4_1_SUPPORTED - if (decoder->private_->cpuinfo.x86.sse41) { + if (decoder->private_->cpuinfo.x86.sse41) { # if !defined FLAC__HAS_NASM /* these are not undoubtedly faster than their MMX ASM counterparts */ - decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_intrin_sse41; - decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_16_intrin_sse41; + decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_intrin_sse41; + decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_16_intrin_sse41; # endif - decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_intrin_sse41; - } + decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_intrin_sse41; + } # endif #endif #elif defined FLAC__CPU_X86_64 - FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_X86_64); - /* No useful SSE optimizations yet */ + FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_X86_64); + /* No useful SSE optimizations yet */ #endif - } + } #endif - /* from here on, errors are fatal */ - - if(!FLAC__bitreader_init(decoder->private_->input, read_callback_, decoder)) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR; - } - - decoder->private_->read_callback = read_callback; - decoder->private_->seek_callback = seek_callback; - decoder->private_->tell_callback = tell_callback; - decoder->private_->length_callback = length_callback; - decoder->private_->eof_callback = eof_callback; - decoder->private_->write_callback = write_callback; - decoder->private_->metadata_callback = metadata_callback; - decoder->private_->error_callback = error_callback; - decoder->private_->client_data = client_data; - decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size = 0; - decoder->private_->samples_decoded = 0; - decoder->private_->has_stream_info = false; - decoder->private_->cached = false; + /* from here on, errors are fatal */ - decoder->private_->do_md5_checking = decoder->protected_->md5_checking; - decoder->private_->is_seeking = false; + if (!FLAC__bitreader_init(decoder->private_->input, read_callback_, decoder)) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR; + } - decoder->private_->internal_reset_hack = true; /* so the following reset does not try to rewind the input */ - if(!FLAC__stream_decoder_reset(decoder)) { - /* above call sets the state for us */ - return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR; - } + decoder->private_->read_callback = read_callback; + decoder->private_->seek_callback = seek_callback; + decoder->private_->tell_callback = tell_callback; + decoder->private_->length_callback = length_callback; + decoder->private_->eof_callback = eof_callback; + decoder->private_->write_callback = write_callback; + decoder->private_->metadata_callback = metadata_callback; + decoder->private_->error_callback = error_callback; + decoder->private_->client_data = client_data; + decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size = 0; + decoder->private_->samples_decoded = 0; + decoder->private_->has_stream_info = false; + decoder->private_->cached = false; + + decoder->private_->do_md5_checking = decoder->protected_->md5_checking; + decoder->private_->is_seeking = false; + + decoder->private_->internal_reset_hack = true; /* so the following reset does not try to rewind the input */ + if (!FLAC__stream_decoder_reset(decoder)) { + /* above call sets the state for us */ + return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR; + } - return FLAC__STREAM_DECODER_INIT_STATUS_OK; + return FLAC__STREAM_DECODER_INIT_STATUS_OK; } FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream( - FLAC__StreamDecoder *decoder, - FLAC__StreamDecoderReadCallback read_callback, - FLAC__StreamDecoderSeekCallback seek_callback, - FLAC__StreamDecoderTellCallback tell_callback, - FLAC__StreamDecoderLengthCallback length_callback, - FLAC__StreamDecoderEofCallback eof_callback, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -) -{ - return init_stream_internal_( - decoder, - read_callback, - seek_callback, - tell_callback, - length_callback, - eof_callback, - write_callback, - metadata_callback, - error_callback, - client_data, - /*is_ogg=*/false - ); + FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderReadCallback read_callback, + FLAC__StreamDecoderSeekCallback seek_callback, + FLAC__StreamDecoderTellCallback tell_callback, + FLAC__StreamDecoderLengthCallback length_callback, + FLAC__StreamDecoderEofCallback eof_callback, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +) { + return init_stream_internal_( + decoder, + read_callback, + seek_callback, + tell_callback, + length_callback, + eof_callback, + write_callback, + metadata_callback, + error_callback, + client_data, + /*is_ogg=*/false + ); } FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_stream( - FLAC__StreamDecoder *decoder, - FLAC__StreamDecoderReadCallback read_callback, - FLAC__StreamDecoderSeekCallback seek_callback, - FLAC__StreamDecoderTellCallback tell_callback, - FLAC__StreamDecoderLengthCallback length_callback, - FLAC__StreamDecoderEofCallback eof_callback, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -) -{ - return init_stream_internal_( - decoder, - read_callback, - seek_callback, - tell_callback, - length_callback, - eof_callback, - write_callback, - metadata_callback, - error_callback, - client_data, - /*is_ogg=*/true - ); + FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderReadCallback read_callback, + FLAC__StreamDecoderSeekCallback seek_callback, + FLAC__StreamDecoderTellCallback tell_callback, + FLAC__StreamDecoderLengthCallback length_callback, + FLAC__StreamDecoderEofCallback eof_callback, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +) { + return init_stream_internal_( + decoder, + read_callback, + seek_callback, + tell_callback, + length_callback, + eof_callback, + write_callback, + metadata_callback, + error_callback, + client_data, + /*is_ogg=*/true + ); } #if 0 static FLAC__StreamDecoderInitStatus init_FILE_internal_( - FLAC__StreamDecoder *decoder, - FILE *file, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data, - FLAC__bool is_ogg -) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != file); - - if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) - return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED; - - if(0 == write_callback || 0 == error_callback) - return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS; - - /* - * To make sure that our file does not go unclosed after an error, we - * must assign the FILE pointer before any further error can occur in - * this routine. - */ - if(file == stdin) - file = get_binary_stdin_(); /* just to be safe */ - - decoder->private_->file = file; - - return init_stream_internal_( - decoder, - file_read_callback_, - decoder->private_->file == stdin? 0: file_seek_callback_, - decoder->private_->file == stdin? 0: file_tell_callback_, - decoder->private_->file == stdin? 0: file_length_callback_, - file_eof_callback_, - write_callback, - metadata_callback, - error_callback, - client_data, - is_ogg - ); + FLAC__StreamDecoder *decoder, + FILE *file, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data, + FLAC__bool is_ogg +) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != file); + + if (decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) { + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED; + } + + if (0 == write_callback || 0 == error_callback) { + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS; + } + + /* + To make sure that our file does not go unclosed after an error, we + must assign the FILE pointer before any further error can occur in + this routine. + */ + if (file == stdin) { + file = get_binary_stdin_(); /* just to be safe */ + } + + decoder->private_->file = file; + + return init_stream_internal_( + decoder, + file_read_callback_, + decoder->private_->file == stdin ? 0 : file_seek_callback_, + decoder->private_->file == stdin ? 0 : file_tell_callback_, + decoder->private_->file == stdin ? 0 : file_length_callback_, + file_eof_callback_, + write_callback, + metadata_callback, + error_callback, + client_data, + is_ogg + ); } FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_FILE( - FLAC__StreamDecoder *decoder, - FILE *file, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -) -{ - return init_FILE_internal_(decoder, file, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/false); + FLAC__StreamDecoder *decoder, + FILE *file, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +) { + return init_FILE_internal_(decoder, file, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/false); } FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_FILE( - FLAC__StreamDecoder *decoder, - FILE *file, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -) -{ - return init_FILE_internal_(decoder, file, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/true); + FLAC__StreamDecoder *decoder, + FILE *file, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +) { + return init_FILE_internal_(decoder, file, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/true); } static FLAC__StreamDecoderInitStatus init_file_internal_( - FLAC__StreamDecoder *decoder, - const char *filename, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data, - FLAC__bool is_ogg -) -{ - FILE *file; - - FLAC__ASSERT(0 != decoder); - - /* - * To make sure that our file does not go unclosed after an error, we - * have to do the same entrance checks here that are later performed - * in FLAC__stream_decoder_init_FILE() before the FILE* is assigned. - */ - if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) - return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED; + FLAC__StreamDecoder *decoder, + const char *filename, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data, + FLAC__bool is_ogg +) { + FILE *file; + + FLAC__ASSERT(0 != decoder); + + /* + To make sure that our file does not go unclosed after an error, we + have to do the same entrance checks here that are later performed + in FLAC__stream_decoder_init_FILE() before the FILE* is assigned. + */ + if (decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) { + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED; + } - if(0 == write_callback || 0 == error_callback) - return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS; + if (0 == write_callback || 0 == error_callback) { + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS; + } - file = filename? flac_fopen(filename, "rb") : stdin; + file = filename ? flac_fopen(filename, "rb") : stdin; - if(0 == file) - return FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE; + if (0 == file) { + return FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE; + } - return init_FILE_internal_(decoder, file, write_callback, metadata_callback, error_callback, client_data, is_ogg); + return init_FILE_internal_(decoder, file, write_callback, metadata_callback, error_callback, client_data, is_ogg); } FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file( - FLAC__StreamDecoder *decoder, - const char *filename, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -) -{ - return init_file_internal_(decoder, filename, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/false); + FLAC__StreamDecoder *decoder, + const char *filename, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +) { + return init_file_internal_(decoder, filename, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/false); } FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_file( - FLAC__StreamDecoder *decoder, - const char *filename, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -) -{ - return init_file_internal_(decoder, filename, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/true); + FLAC__StreamDecoder *decoder, + const char *filename, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +) { + return init_file_internal_(decoder, filename, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/true); } #endif -FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder) -{ - FLAC__bool md5_failed = false; - uint32_t i; - - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->private_); - FLAC__ASSERT(0 != decoder->protected_); - - if(decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED) - return true; - - /* see the comment in FLAC__stream_decoder_reset() as to why we - * always call FLAC__MD5Final() - */ - FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context); - - free(decoder->private_->seek_table.data.seek_table.points); - decoder->private_->seek_table.data.seek_table.points = 0; - decoder->private_->has_seek_table = false; - - FLAC__bitreader_free(decoder->private_->input); - for(i = 0; i < FLAC__MAX_CHANNELS; i++) { - /* WATCHOUT: - * FLAC__lpc_restore_signal_asm_ia32_mmx() and ..._intrin_sseN() - * require that the output arrays have a buffer of up to 3 zeroes - * in front (at negative indices) for alignment purposes; - * we use 4 to keep the data well-aligned. - */ - if(0 != decoder->private_->output[i]) { - free(decoder->private_->output[i]-4); - decoder->private_->output[i] = 0; - } - if(0 != decoder->private_->residual_unaligned[i]) { - free(decoder->private_->residual_unaligned[i]); - decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; - } - } - decoder->private_->output_capacity = 0; - decoder->private_->output_channels = 0; +FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder) { + FLAC__bool md5_failed = false; + uint32_t i; + + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + + if (decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED) { + return true; + } + + /* see the comment in FLAC__stream_decoder_reset() as to why we + always call FLAC__MD5Final() + */ + FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context); + + free(decoder->private_->seek_table.data.seek_table.points); + decoder->private_->seek_table.data.seek_table.points = 0; + decoder->private_->has_seek_table = false; + + FLAC__bitreader_free(decoder->private_->input); + for (i = 0; i < FLAC__MAX_CHANNELS; i++) { + /* WATCHOUT: + FLAC__lpc_restore_signal_asm_ia32_mmx() and ..._intrin_sseN() + require that the output arrays have a buffer of up to 3 zeroes + in front (at negative indices) for alignment purposes; + we use 4 to keep the data well-aligned. + */ + if (0 != decoder->private_->output[i]) { + free(decoder->private_->output[i] - 4); + decoder->private_->output[i] = 0; + } + if (0 != decoder->private_->residual_unaligned[i]) { + free(decoder->private_->residual_unaligned[i]); + decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; + } + } + decoder->private_->output_capacity = 0; + decoder->private_->output_channels = 0; #if FLAC__HAS_OGG - if(decoder->private_->is_ogg) - FLAC__ogg_decoder_aspect_finish(&decoder->protected_->ogg_decoder_aspect); + if (decoder->private_->is_ogg) { + FLAC__ogg_decoder_aspect_finish(&decoder->protected_->ogg_decoder_aspect); + } #endif #if 0 - if(0 != decoder->private_->file) { - if(decoder->private_->file != stdin) - fclose(decoder->private_->file); - decoder->private_->file = 0; - } + if (0 != decoder->private_->file) { + if (decoder->private_->file != stdin) { + fclose(decoder->private_->file); + } + decoder->private_->file = 0; + } #endif - if(decoder->private_->do_md5_checking) { - if(memcmp(decoder->private_->stream_info.data.stream_info.md5sum, decoder->private_->computed_md5sum, 16)) - md5_failed = true; - } - decoder->private_->is_seeking = false; + if (decoder->private_->do_md5_checking) { + if (memcmp(decoder->private_->stream_info.data.stream_info.md5sum, decoder->private_->computed_md5sum, 16)) { + md5_failed = true; + } + } + decoder->private_->is_seeking = false; - set_defaults_(decoder); + set_defaults_(decoder); - decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED; + decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED; - return !md5_failed; + return !md5_failed; } -FLAC_API FLAC__bool FLAC__stream_decoder_set_ogg_serial_number(FLAC__StreamDecoder *decoder, long value) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->private_); - FLAC__ASSERT(0 != decoder->protected_); - if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) - return false; +FLAC_API FLAC__bool FLAC__stream_decoder_set_ogg_serial_number(FLAC__StreamDecoder *decoder, long value) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + if (decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) { + return false; + } #if FLAC__HAS_OGG - /* can't check decoder->private_->is_ogg since that's not set until init time */ - FLAC__ogg_decoder_aspect_set_serial_number(&decoder->protected_->ogg_decoder_aspect, value); - return true; + /* can't check decoder->private_->is_ogg since that's not set until init time */ + FLAC__ogg_decoder_aspect_set_serial_number(&decoder->protected_->ogg_decoder_aspect, value); + return true; #else - (void)value; - return false; + (void)value; + return false; #endif } -FLAC_API FLAC__bool FLAC__stream_decoder_set_md5_checking(FLAC__StreamDecoder *decoder, FLAC__bool value) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->protected_); - if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) - return false; - decoder->protected_->md5_checking = value; - return true; -} - -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->private_); - FLAC__ASSERT(0 != decoder->protected_); - FLAC__ASSERT((uint32_t)type <= FLAC__MAX_METADATA_TYPE_CODE); - /* double protection */ - if((uint32_t)type > FLAC__MAX_METADATA_TYPE_CODE) - return false; - if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) - return false; - decoder->private_->metadata_filter[type] = true; - if(type == FLAC__METADATA_TYPE_APPLICATION) - decoder->private_->metadata_filter_ids_count = 0; - return true; -} - -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->private_); - FLAC__ASSERT(0 != decoder->protected_); - FLAC__ASSERT(0 != id); - if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) - return false; - - if(decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION]) - return true; - - FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids); - - if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { - if(0 == (decoder->private_->metadata_filter_ids = safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - decoder->private_->metadata_filter_ids_capacity *= 2; - } - - memcpy(decoder->private_->metadata_filter_ids + decoder->private_->metadata_filter_ids_count * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8)); - decoder->private_->metadata_filter_ids_count++; - - return true; -} - -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder) -{ - uint32_t i; - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->private_); - FLAC__ASSERT(0 != decoder->protected_); - if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) - return false; - for(i = 0; i < sizeof(decoder->private_->metadata_filter) / sizeof(decoder->private_->metadata_filter[0]); i++) - decoder->private_->metadata_filter[i] = true; - decoder->private_->metadata_filter_ids_count = 0; - return true; -} - -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->private_); - FLAC__ASSERT(0 != decoder->protected_); - FLAC__ASSERT((uint32_t)type <= FLAC__MAX_METADATA_TYPE_CODE); - /* double protection */ - if((uint32_t)type > FLAC__MAX_METADATA_TYPE_CODE) - return false; - if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) - return false; - decoder->private_->metadata_filter[type] = false; - if(type == FLAC__METADATA_TYPE_APPLICATION) - decoder->private_->metadata_filter_ids_count = 0; - return true; -} - -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->private_); - FLAC__ASSERT(0 != decoder->protected_); - FLAC__ASSERT(0 != id); - if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) - return false; - - if(!decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION]) - return true; - - FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids); - - if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { - if(0 == (decoder->private_->metadata_filter_ids = safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - decoder->private_->metadata_filter_ids_capacity *= 2; - } - - memcpy(decoder->private_->metadata_filter_ids + decoder->private_->metadata_filter_ids_count * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8)); - decoder->private_->metadata_filter_ids_count++; - - return true; -} - -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->private_); - FLAC__ASSERT(0 != decoder->protected_); - if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) - return false; - memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter)); - decoder->private_->metadata_filter_ids_count = 0; - return true; -} - -FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->protected_); - return decoder->protected_->state; +FLAC_API FLAC__bool FLAC__stream_decoder_set_md5_checking(FLAC__StreamDecoder *decoder, FLAC__bool value) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + if (decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) { + return false; + } + decoder->protected_->md5_checking = value; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + FLAC__ASSERT((uint32_t)type <= FLAC__MAX_METADATA_TYPE_CODE); + /* double protection */ + if ((uint32_t)type > FLAC__MAX_METADATA_TYPE_CODE) { + return false; + } + if (decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) { + return false; + } + decoder->private_->metadata_filter[type] = true; + if (type == FLAC__METADATA_TYPE_APPLICATION) { + decoder->private_->metadata_filter_ids_count = 0; + } + return true; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + FLAC__ASSERT(0 != id); + if (decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) { + return false; + } + + if (decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION]) { + return true; + } + + FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids); + + if (decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { + if (0 == (decoder->private_->metadata_filter_ids = safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + decoder->private_->metadata_filter_ids_capacity *= 2; + } + + memcpy(decoder->private_->metadata_filter_ids + decoder->private_->metadata_filter_ids_count * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8)); + decoder->private_->metadata_filter_ids_count++; + + return true; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder) { + uint32_t i; + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + if (decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) { + return false; + } + for (i = 0; i < sizeof(decoder->private_->metadata_filter) / sizeof(decoder->private_->metadata_filter[0]); i++) { + decoder->private_->metadata_filter[i] = true; + } + decoder->private_->metadata_filter_ids_count = 0; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + FLAC__ASSERT((uint32_t)type <= FLAC__MAX_METADATA_TYPE_CODE); + /* double protection */ + if ((uint32_t)type > FLAC__MAX_METADATA_TYPE_CODE) { + return false; + } + if (decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) { + return false; + } + decoder->private_->metadata_filter[type] = false; + if (type == FLAC__METADATA_TYPE_APPLICATION) { + decoder->private_->metadata_filter_ids_count = 0; + } + return true; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + FLAC__ASSERT(0 != id); + if (decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) { + return false; + } + + if (!decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION]) { + return true; + } + + FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids); + + if (decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { + if (0 == (decoder->private_->metadata_filter_ids = safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + decoder->private_->metadata_filter_ids_capacity *= 2; + } + + memcpy(decoder->private_->metadata_filter_ids + decoder->private_->metadata_filter_ids_count * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8)); + decoder->private_->metadata_filter_ids_count++; + + return true; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); + if (decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) { + return false; + } + memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter)); + decoder->private_->metadata_filter_ids_count = 0; + return true; +} + +FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + return decoder->protected_->state; } #if 0 -FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string(const FLAC__StreamDecoder *decoder) -{ - return FLAC__StreamDecoderStateString[decoder->protected_->state]; +FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string(const FLAC__StreamDecoder *decoder) { + return FLAC__StreamDecoderStateString[decoder->protected_->state]; } #endif -FLAC_API FLAC__bool FLAC__stream_decoder_get_md5_checking(const FLAC__StreamDecoder *decoder) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->protected_); - return decoder->protected_->md5_checking; +FLAC_API FLAC__bool FLAC__stream_decoder_get_md5_checking(const FLAC__StreamDecoder *decoder) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + return decoder->protected_->md5_checking; } -FLAC_API FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->protected_); - return decoder->private_->has_stream_info? decoder->private_->stream_info.data.stream_info.total_samples : 0; +FLAC_API FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + return decoder->private_->has_stream_info ? decoder->private_->stream_info.data.stream_info.total_samples : 0; } -FLAC_API uint32_t FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->protected_); - return decoder->protected_->channels; +FLAC_API uint32_t FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + return decoder->protected_->channels; } -FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->protected_); - return decoder->protected_->channel_assignment; +FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + return decoder->protected_->channel_assignment; } -FLAC_API uint32_t FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->protected_); - return decoder->protected_->bits_per_sample; +FLAC_API uint32_t FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + return decoder->protected_->bits_per_sample; } -FLAC_API uint32_t FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->protected_); - return decoder->protected_->sample_rate; +FLAC_API uint32_t FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + return decoder->protected_->sample_rate; } -FLAC_API uint32_t FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->protected_); - return decoder->protected_->blocksize; +FLAC_API uint32_t FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + return decoder->protected_->blocksize; } -FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamDecoder *decoder, FLAC__uint64 *position) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->private_); - FLAC__ASSERT(0 != position); +FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamDecoder *decoder, FLAC__uint64 *position) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != position); - if(FLAC__HAS_OGG && decoder->private_->is_ogg) - return false; + if (FLAC__HAS_OGG && decoder->private_->is_ogg) { + return false; + } - if(0 == decoder->private_->tell_callback) - return false; - if(decoder->private_->tell_callback(decoder, position, decoder->private_->client_data) != FLAC__STREAM_DECODER_TELL_STATUS_OK) - return false; - /* should never happen since all FLAC frames and metadata blocks are byte aligned, but check just in case */ - if(!FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)) - return false; - FLAC__ASSERT(*position >= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder)); - *position -= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder); - return true; + if (0 == decoder->private_->tell_callback) { + return false; + } + if (decoder->private_->tell_callback(decoder, position, decoder->private_->client_data) != FLAC__STREAM_DECODER_TELL_STATUS_OK) { + return false; + } + /* should never happen since all FLAC frames and metadata blocks are byte aligned, but check just in case */ + if (!FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)) { + return false; + } + FLAC__ASSERT(*position >= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder)); + *position -= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder); + return true; } -FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->private_); - FLAC__ASSERT(0 != decoder->protected_); +FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); - if(!decoder->private_->internal_reset_hack && decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED) - return false; + if (!decoder->private_->internal_reset_hack && decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED) { + return false; + } - decoder->private_->samples_decoded = 0; - decoder->private_->do_md5_checking = false; + decoder->private_->samples_decoded = 0; + decoder->private_->do_md5_checking = false; #if FLAC__HAS_OGG - if(decoder->private_->is_ogg) - FLAC__ogg_decoder_aspect_flush(&decoder->protected_->ogg_decoder_aspect); + if (decoder->private_->is_ogg) { + FLAC__ogg_decoder_aspect_flush(&decoder->protected_->ogg_decoder_aspect); + } #endif - if(!FLAC__bitreader_clear(decoder->private_->input)) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + if (!FLAC__bitreader_clear(decoder->private_->input)) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; + return true; } -FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->private_); - FLAC__ASSERT(0 != decoder->protected_); +FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + FLAC__ASSERT(0 != decoder->protected_); - if(!FLAC__stream_decoder_flush(decoder)) { - /* above call sets the state for us */ - return false; - } + if (!FLAC__stream_decoder_flush(decoder)) { + /* above call sets the state for us */ + return false; + } #if FLAC__HAS_OGG - /*@@@ could go in !internal_reset_hack block below */ - if(decoder->private_->is_ogg) - FLAC__ogg_decoder_aspect_reset(&decoder->protected_->ogg_decoder_aspect); + /*@@@ could go in !internal_reset_hack block below */ + if (decoder->private_->is_ogg) { + FLAC__ogg_decoder_aspect_reset(&decoder->protected_->ogg_decoder_aspect); + } #endif - /* Rewind if necessary. If FLAC__stream_decoder_init() is calling us, - * (internal_reset_hack) don't try to rewind since we are already at - * the beginning of the stream and don't want to fail if the input is - * not seekable. - */ - if(!decoder->private_->internal_reset_hack) { + /* Rewind if necessary. If FLAC__stream_decoder_init() is calling us, + (internal_reset_hack) don't try to rewind since we are already at + the beginning of the stream and don't want to fail if the input is + not seekable. + */ + if (!decoder->private_->internal_reset_hack) { #if 0 - if(decoder->private_->file == stdin) - return false; /* can't rewind stdin, reset fails */ + if (decoder->private_->file == stdin) { + return false; /* can't rewind stdin, reset fails */ + } #endif - if(decoder->private_->seek_callback && decoder->private_->seek_callback(decoder, 0, decoder->private_->client_data) == FLAC__STREAM_DECODER_SEEK_STATUS_ERROR) - return false; /* seekable and seek fails, reset fails */ - } - else - decoder->private_->internal_reset_hack = false; - - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA; - - decoder->private_->has_stream_info = false; - - free(decoder->private_->seek_table.data.seek_table.points); - decoder->private_->seek_table.data.seek_table.points = 0; - decoder->private_->has_seek_table = false; - - decoder->private_->do_md5_checking = decoder->protected_->md5_checking; - /* - * This goes in reset() and not flush() because according to the spec, a - * fixed-blocksize stream must stay that way through the whole stream. - */ - decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size = 0; - - /* We initialize the FLAC__MD5Context even though we may never use it. This - * is because md5 checking may be turned on to start and then turned off if - * a seek occurs. So we init the context here and finalize it in - * FLAC__stream_decoder_finish() to make sure things are always cleaned up - * properly. - */ - FLAC__MD5Init(&decoder->private_->md5context); - - decoder->private_->first_frame_offset = 0; - decoder->private_->unparseable_frame_count = 0; - - return true; -} - -FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder) -{ - FLAC__bool got_a_frame; - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->protected_); - - while(1) { - switch(decoder->protected_->state) { - case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: - if(!find_metadata_(decoder)) - return false; /* above function sets the status for us */ - break; - case FLAC__STREAM_DECODER_READ_METADATA: - if(!read_metadata_(decoder)) - return false; /* above function sets the status for us */ - else - return true; - case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: - if(!frame_sync_(decoder)) - return true; /* above function sets the status for us */ - break; - case FLAC__STREAM_DECODER_READ_FRAME: - if(!read_frame_(decoder, &got_a_frame, /*do_full_decode=*/true)) - return false; /* above function sets the status for us */ - if(got_a_frame) - return true; /* above function sets the status for us */ - break; - case FLAC__STREAM_DECODER_END_OF_STREAM: - case FLAC__STREAM_DECODER_ABORTED: - return true; - default: - FLAC__ASSERT(0); - return false; - } - } -} - -FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->protected_); - - while(1) { - switch(decoder->protected_->state) { - case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: - if(!find_metadata_(decoder)) - return false; /* above function sets the status for us */ - break; - case FLAC__STREAM_DECODER_READ_METADATA: - if(!read_metadata_(decoder)) - return false; /* above function sets the status for us */ - break; - case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: - case FLAC__STREAM_DECODER_READ_FRAME: - case FLAC__STREAM_DECODER_END_OF_STREAM: - case FLAC__STREAM_DECODER_ABORTED: - return true; - default: - FLAC__ASSERT(0); - return false; - } - } -} - -FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder) -{ - FLAC__bool dummy; - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->protected_); - - while(1) { - switch(decoder->protected_->state) { - case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: - if(!find_metadata_(decoder)) - return false; /* above function sets the status for us */ - break; - case FLAC__STREAM_DECODER_READ_METADATA: - if(!read_metadata_(decoder)) - return false; /* above function sets the status for us */ - break; - case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: - if(!frame_sync_(decoder)) - return true; /* above function sets the status for us */ - break; - case FLAC__STREAM_DECODER_READ_FRAME: - if(!read_frame_(decoder, &dummy, /*do_full_decode=*/true)) - return false; /* above function sets the status for us */ - break; - case FLAC__STREAM_DECODER_END_OF_STREAM: - case FLAC__STREAM_DECODER_ABORTED: - return true; - default: - FLAC__ASSERT(0); - return false; - } - } -} - -FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder) -{ - FLAC__bool got_a_frame; - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->protected_); - - while(1) { - switch(decoder->protected_->state) { - case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: - case FLAC__STREAM_DECODER_READ_METADATA: - return false; /* above function sets the status for us */ - case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: - if(!frame_sync_(decoder)) - return true; /* above function sets the status for us */ - break; - case FLAC__STREAM_DECODER_READ_FRAME: - if(!read_frame_(decoder, &got_a_frame, /*do_full_decode=*/false)) - return false; /* above function sets the status for us */ - if(got_a_frame) - return true; /* above function sets the status for us */ - break; - case FLAC__STREAM_DECODER_END_OF_STREAM: - case FLAC__STREAM_DECODER_ABORTED: - return true; - default: - FLAC__ASSERT(0); - return false; - } - } -} - -FLAC_API FLAC__bool FLAC__stream_decoder_seek_absolute(FLAC__StreamDecoder *decoder, FLAC__uint64 sample) -{ - FLAC__uint64 length; - - FLAC__ASSERT(0 != decoder); - - if( - decoder->protected_->state != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA && - decoder->protected_->state != FLAC__STREAM_DECODER_READ_METADATA && - decoder->protected_->state != FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC && - decoder->protected_->state != FLAC__STREAM_DECODER_READ_FRAME && - decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM - ) - return false; - - if(0 == decoder->private_->seek_callback) - return false; - - FLAC__ASSERT(decoder->private_->seek_callback); - FLAC__ASSERT(decoder->private_->tell_callback); - FLAC__ASSERT(decoder->private_->length_callback); - FLAC__ASSERT(decoder->private_->eof_callback); - - if(FLAC__stream_decoder_get_total_samples(decoder) > 0 && sample >= FLAC__stream_decoder_get_total_samples(decoder)) - return false; - - decoder->private_->is_seeking = true; - - /* turn off md5 checking if a seek is attempted */ - decoder->private_->do_md5_checking = false; - - /* get the file length (currently our algorithm needs to know the length so it's also an error to get FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED) */ - if(decoder->private_->length_callback(decoder, &length, decoder->private_->client_data) != FLAC__STREAM_DECODER_LENGTH_STATUS_OK) { - decoder->private_->is_seeking = false; - return false; - } - - /* if we haven't finished processing the metadata yet, do that so we have the STREAMINFO, SEEK_TABLE, and first_frame_offset */ - if( - decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA || - decoder->protected_->state == FLAC__STREAM_DECODER_READ_METADATA - ) { - if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder)) { - /* above call sets the state for us */ - decoder->private_->is_seeking = false; - return false; - } - /* check this again in case we didn't know total_samples the first time */ - if(FLAC__stream_decoder_get_total_samples(decoder) > 0 && sample >= FLAC__stream_decoder_get_total_samples(decoder)) { - decoder->private_->is_seeking = false; - return false; - } - } - - { - const FLAC__bool ok = + if (decoder->private_->seek_callback && decoder->private_->seek_callback(decoder, 0, decoder->private_->client_data) == FLAC__STREAM_DECODER_SEEK_STATUS_ERROR) { + return false; /* seekable and seek fails, reset fails */ + } + } else { + decoder->private_->internal_reset_hack = false; + } + + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA; + + decoder->private_->has_stream_info = false; + + free(decoder->private_->seek_table.data.seek_table.points); + decoder->private_->seek_table.data.seek_table.points = 0; + decoder->private_->has_seek_table = false; + + decoder->private_->do_md5_checking = decoder->protected_->md5_checking; + /* + This goes in reset() and not flush() because according to the spec, a + fixed-blocksize stream must stay that way through the whole stream. + */ + decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size = 0; + + /* We initialize the FLAC__MD5Context even though we may never use it. This + is because md5 checking may be turned on to start and then turned off if + a seek occurs. So we init the context here and finalize it in + FLAC__stream_decoder_finish() to make sure things are always cleaned up + properly. + */ + FLAC__MD5Init(&decoder->private_->md5context); + + decoder->private_->first_frame_offset = 0; + decoder->private_->unparseable_frame_count = 0; + + return true; +} + +FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder) { + FLAC__bool got_a_frame; + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + + while (1) { + switch (decoder->protected_->state) { + case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: + if (!find_metadata_(decoder)) { + return false; /* above function sets the status for us */ + } + break; + case FLAC__STREAM_DECODER_READ_METADATA: + if (!read_metadata_(decoder)) { + return false; /* above function sets the status for us */ + } else { + return true; + } + case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: + if (!frame_sync_(decoder)) { + return true; /* above function sets the status for us */ + } + break; + case FLAC__STREAM_DECODER_READ_FRAME: + if (!read_frame_(decoder, &got_a_frame, /*do_full_decode=*/true)) { + return false; /* above function sets the status for us */ + } + if (got_a_frame) { + return true; /* above function sets the status for us */ + } + break; + case FLAC__STREAM_DECODER_END_OF_STREAM: + case FLAC__STREAM_DECODER_ABORTED: + return true; + default: + FLAC__ASSERT(0); + return false; + } + } +} + +FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + + while (1) { + switch (decoder->protected_->state) { + case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: + if (!find_metadata_(decoder)) { + return false; /* above function sets the status for us */ + } + break; + case FLAC__STREAM_DECODER_READ_METADATA: + if (!read_metadata_(decoder)) { + return false; /* above function sets the status for us */ + } + break; + case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: + case FLAC__STREAM_DECODER_READ_FRAME: + case FLAC__STREAM_DECODER_END_OF_STREAM: + case FLAC__STREAM_DECODER_ABORTED: + return true; + default: + FLAC__ASSERT(0); + return false; + } + } +} + +FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder) { + FLAC__bool dummy; + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + + while (1) { + switch (decoder->protected_->state) { + case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: + if (!find_metadata_(decoder)) { + return false; /* above function sets the status for us */ + } + break; + case FLAC__STREAM_DECODER_READ_METADATA: + if (!read_metadata_(decoder)) { + return false; /* above function sets the status for us */ + } + break; + case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: + if (!frame_sync_(decoder)) { + return true; /* above function sets the status for us */ + } + break; + case FLAC__STREAM_DECODER_READ_FRAME: + if (!read_frame_(decoder, &dummy, /*do_full_decode=*/true)) { + return false; /* above function sets the status for us */ + } + break; + case FLAC__STREAM_DECODER_END_OF_STREAM: + case FLAC__STREAM_DECODER_ABORTED: + return true; + default: + FLAC__ASSERT(0); + return false; + } + } +} + +FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder) { + FLAC__bool got_a_frame; + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->protected_); + + while (1) { + switch (decoder->protected_->state) { + case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: + case FLAC__STREAM_DECODER_READ_METADATA: + return false; /* above function sets the status for us */ + case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: + if (!frame_sync_(decoder)) { + return true; /* above function sets the status for us */ + } + break; + case FLAC__STREAM_DECODER_READ_FRAME: + if (!read_frame_(decoder, &got_a_frame, /*do_full_decode=*/false)) { + return false; /* above function sets the status for us */ + } + if (got_a_frame) { + return true; /* above function sets the status for us */ + } + break; + case FLAC__STREAM_DECODER_END_OF_STREAM: + case FLAC__STREAM_DECODER_ABORTED: + return true; + default: + FLAC__ASSERT(0); + return false; + } + } +} + +FLAC_API FLAC__bool FLAC__stream_decoder_seek_absolute(FLAC__StreamDecoder *decoder, FLAC__uint64 sample) { + FLAC__uint64 length; + + FLAC__ASSERT(0 != decoder); + + if ( + decoder->protected_->state != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA && + decoder->protected_->state != FLAC__STREAM_DECODER_READ_METADATA && + decoder->protected_->state != FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC && + decoder->protected_->state != FLAC__STREAM_DECODER_READ_FRAME && + decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM + ) { + return false; + } + + if (0 == decoder->private_->seek_callback) { + return false; + } + + FLAC__ASSERT(decoder->private_->seek_callback); + FLAC__ASSERT(decoder->private_->tell_callback); + FLAC__ASSERT(decoder->private_->length_callback); + FLAC__ASSERT(decoder->private_->eof_callback); + + if (FLAC__stream_decoder_get_total_samples(decoder) > 0 && sample >= FLAC__stream_decoder_get_total_samples(decoder)) { + return false; + } + + decoder->private_->is_seeking = true; + + /* turn off md5 checking if a seek is attempted */ + decoder->private_->do_md5_checking = false; + + /* get the file length (currently our algorithm needs to know the length so it's also an error to get FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED) */ + if (decoder->private_->length_callback(decoder, &length, decoder->private_->client_data) != FLAC__STREAM_DECODER_LENGTH_STATUS_OK) { + decoder->private_->is_seeking = false; + return false; + } + + /* if we haven't finished processing the metadata yet, do that so we have the STREAMINFO, SEEK_TABLE, and first_frame_offset */ + if ( + decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA || + decoder->protected_->state == FLAC__STREAM_DECODER_READ_METADATA + ) { + if (!FLAC__stream_decoder_process_until_end_of_metadata(decoder)) { + /* above call sets the state for us */ + decoder->private_->is_seeking = false; + return false; + } + /* check this again in case we didn't know total_samples the first time */ + if (FLAC__stream_decoder_get_total_samples(decoder) > 0 && sample >= FLAC__stream_decoder_get_total_samples(decoder)) { + decoder->private_->is_seeking = false; + return false; + } + } + + { + const FLAC__bool ok = #if FLAC__HAS_OGG - decoder->private_->is_ogg? - seek_to_absolute_sample_ogg_(decoder, length, sample) : + decoder->private_->is_ogg ? + seek_to_absolute_sample_ogg_(decoder, length, sample) : #endif - seek_to_absolute_sample_(decoder, length, sample) - ; - decoder->private_->is_seeking = false; - return ok; - } + seek_to_absolute_sample_(decoder, length, sample) + ; + decoder->private_->is_seeking = false; + return ok; + } } /*********************************************************************** - * - * Protected class methods - * + + Protected class methods + ***********************************************************************/ -uint32_t FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder) -{ - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); - FLAC__ASSERT(!(FLAC__bitreader_get_input_bits_unconsumed(decoder->private_->input) & 7)); - return FLAC__bitreader_get_input_bits_unconsumed(decoder->private_->input) / 8; +uint32_t FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder) { + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + FLAC__ASSERT(!(FLAC__bitreader_get_input_bits_unconsumed(decoder->private_->input) & 7)); + return FLAC__bitreader_get_input_bits_unconsumed(decoder->private_->input) / 8; } /*********************************************************************** - * - * Private class methods - * + + Private class methods + ***********************************************************************/ -void set_defaults_(FLAC__StreamDecoder *decoder) -{ - decoder->private_->is_ogg = false; - decoder->private_->read_callback = 0; - decoder->private_->seek_callback = 0; - decoder->private_->tell_callback = 0; - decoder->private_->length_callback = 0; - decoder->private_->eof_callback = 0; - decoder->private_->write_callback = 0; - decoder->private_->metadata_callback = 0; - decoder->private_->error_callback = 0; - decoder->private_->client_data = 0; - - memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter)); - decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] = true; - decoder->private_->metadata_filter_ids_count = 0; - - decoder->protected_->md5_checking = false; +void set_defaults_(FLAC__StreamDecoder *decoder) { + decoder->private_->is_ogg = false; + decoder->private_->read_callback = 0; + decoder->private_->seek_callback = 0; + decoder->private_->tell_callback = 0; + decoder->private_->length_callback = 0; + decoder->private_->eof_callback = 0; + decoder->private_->write_callback = 0; + decoder->private_->metadata_callback = 0; + decoder->private_->error_callback = 0; + decoder->private_->client_data = 0; + + memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter)); + decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] = true; + decoder->private_->metadata_filter_ids_count = 0; + + decoder->protected_->md5_checking = false; #if FLAC__HAS_OGG - FLAC__ogg_decoder_aspect_set_defaults(&decoder->protected_->ogg_decoder_aspect); + FLAC__ogg_decoder_aspect_set_defaults(&decoder->protected_->ogg_decoder_aspect); #endif } #if 0 /* - * This will forcibly set stdin to binary mode (for OSes that require it) - */ -FILE *get_binary_stdin_(void) -{ - /* if something breaks here it is probably due to the presence or - * absence of an underscore before the identifiers 'setmode', - * 'fileno', and/or 'O_BINARY'; check your system header files. - */ + This will forcibly set stdin to binary mode (for OSes that require it) +*/ +FILE *get_binary_stdin_(void) { + /* if something breaks here it is probably due to the presence or + absence of an underscore before the identifiers 'setmode', + 'fileno', and/or 'O_BINARY'; check your system header files. + */ #if defined _MSC_VER || defined __MINGW32__ - _setmode(_fileno(stdin), _O_BINARY); + _setmode(_fileno(stdin), _O_BINARY); #elif defined __EMX__ - setmode(fileno(stdin), O_BINARY); + setmode(fileno(stdin), O_BINARY); #endif - return stdin; + return stdin; } #endif -FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_t channels) -{ - uint32_t i; - FLAC__int32 *tmp; - - if(size <= decoder->private_->output_capacity && channels <= decoder->private_->output_channels) - return true; - - /* simply using realloc() is not practical because the number of channels may change mid-stream */ - - for(i = 0; i < FLAC__MAX_CHANNELS; i++) { - if(0 != decoder->private_->output[i]) { - free(decoder->private_->output[i]-4); - decoder->private_->output[i] = 0; - } - if(0 != decoder->private_->residual_unaligned[i]) { - free(decoder->private_->residual_unaligned[i]); - decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; - } - } - - for(i = 0; i < channels; i++) { - /* WATCHOUT: - * FLAC__lpc_restore_signal_asm_ia32_mmx() and ..._intrin_sseN() - * require that the output arrays have a buffer of up to 3 zeroes - * in front (at negative indices) for alignment purposes; - * we use 4 to keep the data well-aligned. - */ - tmp = safe_malloc_muladd2_(sizeof(FLAC__int32), /*times (*/size, /*+*/4/*)*/); - if(tmp == 0) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - memset(tmp, 0, sizeof(FLAC__int32)*4); - decoder->private_->output[i] = tmp + 4; - - if(!FLAC__memory_alloc_aligned_int32_array(size, &decoder->private_->residual_unaligned[i], &decoder->private_->residual[i])) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - } - - decoder->private_->output_capacity = size; - decoder->private_->output_channels = channels; - - return true; -} - -FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id) -{ - size_t i; - - FLAC__ASSERT(0 != decoder); - FLAC__ASSERT(0 != decoder->private_); - - for(i = 0; i < decoder->private_->metadata_filter_ids_count; i++) - if(0 == memcmp(decoder->private_->metadata_filter_ids + i * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8))) - return true; - - return false; -} - -FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder) -{ - FLAC__uint32 x; - uint32_t i, id; - FLAC__bool first = true; - - FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); - - for(i = id = 0; i < 4; ) { - if(decoder->private_->cached) { - x = (FLAC__uint32)decoder->private_->lookahead; - decoder->private_->cached = false; - } - else { - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) - return false; /* read_callback_ sets the state for us */ - } - if(x == FLAC__STREAM_SYNC_STRING[i]) { - first = true; - i++; - id = 0; - continue; - } - - if(id >= 3) - return false; - - if(x == ID3V2_TAG_[id]) { - id++; - i = 0; - if(id == 3) { - if(!skip_id3v2_tag_(decoder)) - return false; /* skip_id3v2_tag_ sets the state for us */ - } - continue; - } - id = 0; - if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ - decoder->private_->header_warmup[0] = (FLAC__byte)x; - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) - return false; /* read_callback_ sets the state for us */ - - /* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */ - /* else we have to check if the second byte is the end of a sync code */ - if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ - decoder->private_->lookahead = (FLAC__byte)x; - decoder->private_->cached = true; - } - else if(x >> 1 == 0x7c) { /* MAGIC NUMBER for the last 6 sync bits and reserved 7th bit */ - decoder->private_->header_warmup[1] = (FLAC__byte)x; - decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME; - return true; - } - } - i = 0; - if(first) { - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); - first = false; - } - } - - decoder->protected_->state = FLAC__STREAM_DECODER_READ_METADATA; - return true; -} - -FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) -{ - FLAC__bool is_last; - FLAC__uint32 i, x, type, length; - - FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); - - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_IS_LAST_LEN)) - return false; /* read_callback_ sets the state for us */ - is_last = x? true : false; - - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &type, FLAC__STREAM_METADATA_TYPE_LEN)) - return false; /* read_callback_ sets the state for us */ - - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &length, FLAC__STREAM_METADATA_LENGTH_LEN)) - return false; /* read_callback_ sets the state for us */ - - if(type == FLAC__METADATA_TYPE_STREAMINFO) { - if(!read_metadata_streaminfo_(decoder, is_last, length)) - return false; - - decoder->private_->has_stream_info = true; - if(0 == memcmp(decoder->private_->stream_info.data.stream_info.md5sum, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16)) - decoder->private_->do_md5_checking = false; - if(!decoder->private_->is_seeking && decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] && decoder->private_->metadata_callback) - decoder->private_->metadata_callback(decoder, &decoder->private_->stream_info, decoder->private_->client_data); - } - else if(type == FLAC__METADATA_TYPE_SEEKTABLE) { - /* just in case we already have a seek table, and reading the next one fails: */ - decoder->private_->has_seek_table = false; - - if(!read_metadata_seektable_(decoder, is_last, length)) - return false; - - decoder->private_->has_seek_table = true; - if(!decoder->private_->is_seeking && decoder->private_->metadata_filter[FLAC__METADATA_TYPE_SEEKTABLE] && decoder->private_->metadata_callback) - decoder->private_->metadata_callback(decoder, &decoder->private_->seek_table, decoder->private_->client_data); - } - else { - FLAC__bool skip_it = !decoder->private_->metadata_filter[type]; - uint32_t real_length = length; - FLAC__StreamMetadata block; - - memset(&block, 0, sizeof(block)); - block.is_last = is_last; - block.type = (FLAC__MetadataType)type; - block.length = length; - - if(type == FLAC__METADATA_TYPE_APPLICATION) { - if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8)) - return false; /* read_callback_ sets the state for us */ - - if(real_length < FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) { /* underflow check */ - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;/*@@@@@@ maybe wrong error? need to resync?*/ - return false; - } - - real_length -= FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8; - - if(decoder->private_->metadata_filter_ids_count > 0 && has_id_filtered_(decoder, block.data.application.id)) - skip_it = !skip_it; - } - - if(skip_it) { - if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, real_length)) - return false; /* read_callback_ sets the state for us */ - } - else { - FLAC__bool ok = true; - switch(type) { - case FLAC__METADATA_TYPE_PADDING: - /* skip the padding bytes */ - if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, real_length)) - ok = false; /* read_callback_ sets the state for us */ - break; - case FLAC__METADATA_TYPE_APPLICATION: - /* remember, we read the ID already */ - if(real_length > 0) { - if(0 == (block.data.application.data = malloc(real_length))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - ok = false; - } - else if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.data, real_length)) - ok = false; /* read_callback_ sets the state for us */ - } - else - block.data.application.data = 0; - break; - case FLAC__METADATA_TYPE_VORBIS_COMMENT: - if(!read_metadata_vorbiscomment_(decoder, &block.data.vorbis_comment, real_length)) - ok = false; - break; - case FLAC__METADATA_TYPE_CUESHEET: - if(!read_metadata_cuesheet_(decoder, &block.data.cue_sheet)) - ok = false; - break; - case FLAC__METADATA_TYPE_PICTURE: - if(!read_metadata_picture_(decoder, &block.data.picture)) - ok = false; - break; - case FLAC__METADATA_TYPE_STREAMINFO: - case FLAC__METADATA_TYPE_SEEKTABLE: - FLAC__ASSERT(0); - break; - default: - if(real_length > 0) { - if(0 == (block.data.unknown.data = malloc(real_length))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - ok = false; - } - else if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.unknown.data, real_length)) - ok = false; /* read_callback_ sets the state for us */ - } - else - block.data.unknown.data = 0; - break; - } - if(ok && !decoder->private_->is_seeking && decoder->private_->metadata_callback) - decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data); - - /* now we have to free any malloc()ed data in the block */ - switch(type) { - case FLAC__METADATA_TYPE_PADDING: - break; - case FLAC__METADATA_TYPE_APPLICATION: - if(0 != block.data.application.data) - free(block.data.application.data); - break; - case FLAC__METADATA_TYPE_VORBIS_COMMENT: - if(0 != block.data.vorbis_comment.vendor_string.entry) - free(block.data.vorbis_comment.vendor_string.entry); - if(block.data.vorbis_comment.num_comments > 0) - for(i = 0; i < block.data.vorbis_comment.num_comments; i++) - if(0 != block.data.vorbis_comment.comments[i].entry) - free(block.data.vorbis_comment.comments[i].entry); - if(0 != block.data.vorbis_comment.comments) - free(block.data.vorbis_comment.comments); - break; - case FLAC__METADATA_TYPE_CUESHEET: - if(block.data.cue_sheet.num_tracks > 0) - for(i = 0; i < block.data.cue_sheet.num_tracks; i++) - if(0 != block.data.cue_sheet.tracks[i].indices) - free(block.data.cue_sheet.tracks[i].indices); - if(0 != block.data.cue_sheet.tracks) - free(block.data.cue_sheet.tracks); - break; - case FLAC__METADATA_TYPE_PICTURE: - if(0 != block.data.picture.mime_type) - free(block.data.picture.mime_type); - if(0 != block.data.picture.description) - free(block.data.picture.description); - if(0 != block.data.picture.data) - free(block.data.picture.data); - break; - case FLAC__METADATA_TYPE_STREAMINFO: - case FLAC__METADATA_TYPE_SEEKTABLE: - FLAC__ASSERT(0); - default: - if(0 != block.data.unknown.data) - free(block.data.unknown.data); - break; - } - - if(!ok) /* anything that unsets "ok" should also make sure decoder->protected_->state is updated */ - return false; - } - } - - if(is_last) { - /* if this fails, it's OK, it's just a hint for the seek routine */ - if(!FLAC__stream_decoder_get_decode_position(decoder, &decoder->private_->first_frame_offset)) - decoder->private_->first_frame_offset = 0; - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - } - - return true; -} - -FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, uint32_t length) -{ - FLAC__uint32 x; - uint32_t bits, used_bits = 0; - - FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); - - decoder->private_->stream_info.type = FLAC__METADATA_TYPE_STREAMINFO; - decoder->private_->stream_info.is_last = is_last; - decoder->private_->stream_info.length = length; - - bits = FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN; - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, bits)) - return false; /* read_callback_ sets the state for us */ - decoder->private_->stream_info.data.stream_info.min_blocksize = x; - used_bits += bits; - - bits = FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN; - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN)) - return false; /* read_callback_ sets the state for us */ - decoder->private_->stream_info.data.stream_info.max_blocksize = x; - used_bits += bits; - - bits = FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN; - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN)) - return false; /* read_callback_ sets the state for us */ - decoder->private_->stream_info.data.stream_info.min_framesize = x; - used_bits += bits; - - bits = FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN; - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN)) - return false; /* read_callback_ sets the state for us */ - decoder->private_->stream_info.data.stream_info.max_framesize = x; - used_bits += bits; - - bits = FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN; - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN)) - return false; /* read_callback_ sets the state for us */ - decoder->private_->stream_info.data.stream_info.sample_rate = x; - used_bits += bits; - - bits = FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN; - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN)) - return false; /* read_callback_ sets the state for us */ - decoder->private_->stream_info.data.stream_info.channels = x+1; - used_bits += bits; - - bits = FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN; - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN)) - return false; /* read_callback_ sets the state for us */ - decoder->private_->stream_info.data.stream_info.bits_per_sample = x+1; - used_bits += bits; - - bits = FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN; - if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &decoder->private_->stream_info.data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)) - return false; /* read_callback_ sets the state for us */ - used_bits += bits; - - if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, decoder->private_->stream_info.data.stream_info.md5sum, 16)) - return false; /* read_callback_ sets the state for us */ - used_bits += 16*8; - - /* skip the rest of the block */ - FLAC__ASSERT(used_bits % 8 == 0); - if (length < (used_bits / 8)) - return false; /* read_callback_ sets the state for us */ - length -= (used_bits / 8); - if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length)) - return false; /* read_callback_ sets the state for us */ - - return true; -} - -FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, uint32_t length) -{ - FLAC__uint32 i, x; - FLAC__uint64 xx; - - FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); - - decoder->private_->seek_table.type = FLAC__METADATA_TYPE_SEEKTABLE; - decoder->private_->seek_table.is_last = is_last; - decoder->private_->seek_table.length = length; - - decoder->private_->seek_table.data.seek_table.num_points = length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH; - - /* use realloc since we may pass through here several times (e.g. after seeking) */ - if(0 == (decoder->private_->seek_table.data.seek_table.points = safe_realloc_mul_2op_(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint)))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - for(i = 0; i < decoder->private_->seek_table.data.seek_table.num_points; i++) { - if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN)) - return false; /* read_callback_ sets the state for us */ - decoder->private_->seek_table.data.seek_table.points[i].sample_number = xx; - - if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN)) - return false; /* read_callback_ sets the state for us */ - decoder->private_->seek_table.data.seek_table.points[i].stream_offset = xx; - - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN)) - return false; /* read_callback_ sets the state for us */ - decoder->private_->seek_table.data.seek_table.points[i].frame_samples = x; - } - length -= (decoder->private_->seek_table.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH); - /* if there is a partial point left, skip over it */ - if(length > 0) { - /*@@@ do a send_error_to_client_() here? there's an argument for either way */ - if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length)) - return false; /* read_callback_ sets the state for us */ - } - - return true; -} - -FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj, uint32_t length) -{ - FLAC__uint32 i; - - FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); - - /* read vendor string */ - if (length >= 8) { - length -= 8; /* vendor string length + num comments entries alone take 8 bytes */ - FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); - if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length)) - return false; /* read_callback_ sets the state for us */ - if (obj->vendor_string.length > 0) { - if (length < obj->vendor_string.length) { - obj->vendor_string.length = 0; - obj->vendor_string.entry = 0; - goto skip; - } - else - length -= obj->vendor_string.length; - if (0 == (obj->vendor_string.entry = safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->vendor_string.entry, obj->vendor_string.length)) - return false; /* read_callback_ sets the state for us */ - obj->vendor_string.entry[obj->vendor_string.length] = '\0'; - } - else - obj->vendor_string.entry = 0; - - /* read num comments */ - FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN == 32); - if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->num_comments)) - return false; /* read_callback_ sets the state for us */ - - /* read comments */ - if (obj->num_comments > 100000) { - /* Possibly malicious file. */ - obj->num_comments = 0; - return false; - } - if (obj->num_comments > 0) { - if (0 == (obj->comments = safe_malloc_mul_2op_p(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) { - obj->num_comments = 0; - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - for (i = 0; i < obj->num_comments; i++) { - /* Initialize here just to make sure. */ - obj->comments[i].length = 0; - obj->comments[i].entry = 0; - - FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); - if (length < 4) { - obj->num_comments = i; - goto skip; - } - else - length -= 4; - if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length)) { - obj->num_comments = i; - return false; /* read_callback_ sets the state for us */ - } - if (obj->comments[i].length > 0) { - if (length < obj->comments[i].length) { - obj->num_comments = i; - goto skip; - } - else - length -= obj->comments[i].length; - if (0 == (obj->comments[i].entry = safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - obj->num_comments = i; - return false; - } - memset (obj->comments[i].entry, 0, obj->comments[i].length) ; - if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->comments[i].entry, obj->comments[i].length)) { - /* Current i-th entry is bad, so we delete it. */ - free (obj->comments[i].entry) ; - obj->comments[i].entry = NULL ; - obj->num_comments = i; - goto skip; - } - obj->comments[i].entry[obj->comments[i].length] = '\0'; - } - else - obj->comments[i].entry = 0; - } - } - } - - skip: - if (length > 0) { - /* length > 0 can only happen on files with invalid data in comments */ - if(obj->num_comments < 1) { - free(obj->comments); - obj->comments = NULL; - } - if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length)) - return false; /* read_callback_ sets the state for us */ - } - - return true; -} - -FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj) -{ - FLAC__uint32 i, j, x; - - FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); - - memset(obj, 0, sizeof(FLAC__StreamMetadata_CueSheet)); - - FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0); - if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)obj->media_catalog_number, FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN/8)) - return false; /* read_callback_ sets the state for us */ - - if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &obj->lead_in, FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN)) - return false; /* read_callback_ sets the state for us */ - - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN)) - return false; /* read_callback_ sets the state for us */ - obj->is_cd = x? true : false; - - if(!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN)) - return false; /* read_callback_ sets the state for us */ - - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN)) - return false; /* read_callback_ sets the state for us */ - obj->num_tracks = x; - - if(obj->num_tracks > 0) { - if(0 == (obj->tracks = safe_calloc_(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - for(i = 0; i < obj->num_tracks; i++) { - FLAC__StreamMetadata_CueSheet_Track *track = &obj->tracks[i]; - if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &track->offset, FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN)) - return false; /* read_callback_ sets the state for us */ - - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN)) - return false; /* read_callback_ sets the state for us */ - track->number = (FLAC__byte)x; - - FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0); - if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)track->isrc, FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN/8)) - return false; /* read_callback_ sets the state for us */ - - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN)) - return false; /* read_callback_ sets the state for us */ - track->type = x; - - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN)) - return false; /* read_callback_ sets the state for us */ - track->pre_emphasis = x; - - if(!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN)) - return false; /* read_callback_ sets the state for us */ - - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN)) - return false; /* read_callback_ sets the state for us */ - track->num_indices = (FLAC__byte)x; - - if(track->num_indices > 0) { - if(0 == (track->indices = safe_calloc_(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - for(j = 0; j < track->num_indices; j++) { - FLAC__StreamMetadata_CueSheet_Index *indx = &track->indices[j]; - if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &indx->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN)) - return false; /* read_callback_ sets the state for us */ - - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN)) - return false; /* read_callback_ sets the state for us */ - indx->number = (FLAC__byte)x; - - if(!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN)) - return false; /* read_callback_ sets the state for us */ - } - } - } - } - - return true; -} - -FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj) -{ - FLAC__uint32 x; - - FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); - - /* read type */ - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_TYPE_LEN)) - return false; /* read_callback_ sets the state for us */ - obj->type = x; - - /* read MIME type */ - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN)) - return false; /* read_callback_ sets the state for us */ - if(0 == (obj->mime_type = safe_malloc_add_2op_(x, /*+*/1))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - if(x > 0) { - if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)obj->mime_type, x)) - return false; /* read_callback_ sets the state for us */ - } - obj->mime_type[x] = '\0'; - - /* read description */ - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN)) - return false; /* read_callback_ sets the state for us */ - if(0 == (obj->description = safe_malloc_add_2op_(x, /*+*/1))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - if(x > 0) { - if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->description, x)) - return false; /* read_callback_ sets the state for us */ - } - obj->description[x] = '\0'; - - /* read width */ - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->width, FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN)) - return false; /* read_callback_ sets the state for us */ - - /* read height */ - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->height, FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN)) - return false; /* read_callback_ sets the state for us */ - - /* read depth */ - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->depth, FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN)) - return false; /* read_callback_ sets the state for us */ - - /* read colors */ - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->colors, FLAC__STREAM_METADATA_PICTURE_COLORS_LEN)) - return false; /* read_callback_ sets the state for us */ - - /* read data */ - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &(obj->data_length), FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN)) - return false; /* read_callback_ sets the state for us */ - if(0 == (obj->data = safe_malloc_(obj->data_length))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - if(obj->data_length > 0) { - if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->data, obj->data_length)) - return false; /* read_callback_ sets the state for us */ - } - - return true; -} - -FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder) -{ - FLAC__uint32 x; - uint32_t i, skip; - - /* skip the version and flags bytes */ - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 24)) - return false; /* read_callback_ sets the state for us */ - /* get the size (in bytes) to skip */ - skip = 0; - for(i = 0; i < 4; i++) { - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) - return false; /* read_callback_ sets the state for us */ - skip <<= 7; - skip |= (x & 0x7f); - } - /* skip the rest of the tag */ - if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, skip)) - return false; /* read_callback_ sets the state for us */ - return true; -} - -FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder) -{ - FLAC__uint32 x; - FLAC__bool first = true; - - /* If we know the total number of samples in the stream, stop if we've read that many. */ - /* This will stop us, for example, from wasting time trying to sync on an ID3V1 tag. */ - if(FLAC__stream_decoder_get_total_samples(decoder) > 0) { - if(decoder->private_->samples_decoded >= FLAC__stream_decoder_get_total_samples(decoder)) { - decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM; - return true; - } - } - - /* make sure we're byte aligned */ - if(!FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)) { - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__bitreader_bits_left_for_byte_alignment(decoder->private_->input))) - return false; /* read_callback_ sets the state for us */ - } - - while(1) { - if(decoder->private_->cached) { - x = (FLAC__uint32)decoder->private_->lookahead; - decoder->private_->cached = false; - } - else { - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) - return false; /* read_callback_ sets the state for us */ - } - if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ - decoder->private_->header_warmup[0] = (FLAC__byte)x; - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) - return false; /* read_callback_ sets the state for us */ - - /* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */ - /* else we have to check if the second byte is the end of a sync code */ - if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ - decoder->private_->lookahead = (FLAC__byte)x; - decoder->private_->cached = true; - } - else if(x >> 1 == 0x7c) { /* MAGIC NUMBER for the last 6 sync bits and reserved 7th bit */ - decoder->private_->header_warmup[1] = (FLAC__byte)x; - decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME; - return true; - } - } - if(first) { - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); - first = false; - } - } - - return true; -} - -FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FLAC__bool do_full_decode) -{ - uint32_t channel; - uint32_t i; - FLAC__int32 mid, side; - uint32_t frame_crc; /* the one we calculate from the input stream */ - FLAC__uint32 x; - - *got_a_frame = false; - - /* init the CRC */ - frame_crc = 0; - frame_crc = FLAC__CRC16_UPDATE(decoder->private_->header_warmup[0], frame_crc); - frame_crc = FLAC__CRC16_UPDATE(decoder->private_->header_warmup[1], frame_crc); - FLAC__bitreader_reset_read_crc16(decoder->private_->input, (FLAC__uint16)frame_crc); - - if(!read_frame_header_(decoder)) - return false; - if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means we didn't sync on a valid header */ - return true; - if(!allocate_output_(decoder, decoder->private_->frame.header.blocksize, decoder->private_->frame.header.channels)) - return false; - for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) { - /* - * first figure the correct bits-per-sample of the subframe - */ - uint32_t bps = decoder->private_->frame.header.bits_per_sample; - switch(decoder->private_->frame.header.channel_assignment) { - case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: - /* no adjustment needed */ - break; - case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: - FLAC__ASSERT(decoder->private_->frame.header.channels == 2); - if(channel == 1) - bps++; - break; - case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: - FLAC__ASSERT(decoder->private_->frame.header.channels == 2); - if(channel == 0) - bps++; - break; - case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: - FLAC__ASSERT(decoder->private_->frame.header.channels == 2); - if(channel == 1) - bps++; - break; - default: - FLAC__ASSERT(0); - } - /* - * now read it - */ - if(!read_subframe_(decoder, channel, bps, do_full_decode)) - return false; - if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption */ - return true; - } - if(!read_zero_padding_(decoder)) - return false; - if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption (i.e. "zero bits" were not all zeroes) */ - return true; - - /* - * Read the frame CRC-16 from the footer and check - */ - frame_crc = FLAC__bitreader_get_read_crc16(decoder->private_->input); - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__FRAME_FOOTER_CRC_LEN)) - return false; /* read_callback_ sets the state for us */ - if(frame_crc == x) { - if(do_full_decode) { - /* Undo any special channel coding */ - switch(decoder->private_->frame.header.channel_assignment) { - case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: - /* do nothing */ - break; - case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: - FLAC__ASSERT(decoder->private_->frame.header.channels == 2); - for(i = 0; i < decoder->private_->frame.header.blocksize; i++) - decoder->private_->output[1][i] = decoder->private_->output[0][i] - decoder->private_->output[1][i]; - break; - case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: - FLAC__ASSERT(decoder->private_->frame.header.channels == 2); - for(i = 0; i < decoder->private_->frame.header.blocksize; i++) - decoder->private_->output[0][i] += decoder->private_->output[1][i]; - break; - case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: - FLAC__ASSERT(decoder->private_->frame.header.channels == 2); - for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { +FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_t channels) { + uint32_t i; + FLAC__int32 *tmp; + + if (size <= decoder->private_->output_capacity && channels <= decoder->private_->output_channels) { + return true; + } + + /* simply using realloc() is not practical because the number of channels may change mid-stream */ + + for (i = 0; i < FLAC__MAX_CHANNELS; i++) { + if (0 != decoder->private_->output[i]) { + free(decoder->private_->output[i] - 4); + decoder->private_->output[i] = 0; + } + if (0 != decoder->private_->residual_unaligned[i]) { + free(decoder->private_->residual_unaligned[i]); + decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; + } + } + + for (i = 0; i < channels; i++) { + /* WATCHOUT: + FLAC__lpc_restore_signal_asm_ia32_mmx() and ..._intrin_sseN() + require that the output arrays have a buffer of up to 3 zeroes + in front (at negative indices) for alignment purposes; + we use 4 to keep the data well-aligned. + */ + tmp = safe_malloc_muladd2_(sizeof(FLAC__int32), /*times (*/size, /*+*/4/*)*/); + if (tmp == 0) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + memset(tmp, 0, sizeof(FLAC__int32) * 4); + decoder->private_->output[i] = tmp + 4; + + if (!FLAC__memory_alloc_aligned_int32_array(size, &decoder->private_->residual_unaligned[i], &decoder->private_->residual[i])) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + } + + decoder->private_->output_capacity = size; + decoder->private_->output_channels = channels; + + return true; +} + +FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id) { + size_t i; + + FLAC__ASSERT(0 != decoder); + FLAC__ASSERT(0 != decoder->private_); + + for (i = 0; i < decoder->private_->metadata_filter_ids_count; i++) + if (0 == memcmp(decoder->private_->metadata_filter_ids + i * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8))) { + return true; + } + + return false; +} + +FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder) { + FLAC__uint32 x; + uint32_t i, id; + FLAC__bool first = true; + + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + + for (i = id = 0; i < 4;) { + if (decoder->private_->cached) { + x = (FLAC__uint32)decoder->private_->lookahead; + decoder->private_->cached = false; + } else { + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) { + return false; /* read_callback_ sets the state for us */ + } + } + if (x == FLAC__STREAM_SYNC_STRING[i]) { + first = true; + i++; + id = 0; + continue; + } + + if (id >= 3) { + return false; + } + + if (x == ID3V2_TAG_[id]) { + id++; + i = 0; + if (id == 3) { + if (!skip_id3v2_tag_(decoder)) { + return false; /* skip_id3v2_tag_ sets the state for us */ + } + } + continue; + } + id = 0; + if (x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ + decoder->private_->header_warmup[0] = (FLAC__byte)x; + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) { + return false; /* read_callback_ sets the state for us */ + } + + /* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */ + /* else we have to check if the second byte is the end of a sync code */ + if (x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ + decoder->private_->lookahead = (FLAC__byte)x; + decoder->private_->cached = true; + } else if (x >> 1 == 0x7c) { /* MAGIC NUMBER for the last 6 sync bits and reserved 7th bit */ + decoder->private_->header_warmup[1] = (FLAC__byte)x; + decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME; + return true; + } + } + i = 0; + if (first) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + first = false; + } + } + + decoder->protected_->state = FLAC__STREAM_DECODER_READ_METADATA; + return true; +} + +FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) { + FLAC__bool is_last; + FLAC__uint32 i, x, type, length; + + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_IS_LAST_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + is_last = x ? true : false; + + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &type, FLAC__STREAM_METADATA_TYPE_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &length, FLAC__STREAM_METADATA_LENGTH_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + + if (type == FLAC__METADATA_TYPE_STREAMINFO) { + if (!read_metadata_streaminfo_(decoder, is_last, length)) { + return false; + } + + decoder->private_->has_stream_info = true; + if (0 == memcmp(decoder->private_->stream_info.data.stream_info.md5sum, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16)) { + decoder->private_->do_md5_checking = false; + } + if (!decoder->private_->is_seeking && decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] && decoder->private_->metadata_callback) { + decoder->private_->metadata_callback(decoder, &decoder->private_->stream_info, decoder->private_->client_data); + } + } else if (type == FLAC__METADATA_TYPE_SEEKTABLE) { + /* just in case we already have a seek table, and reading the next one fails: */ + decoder->private_->has_seek_table = false; + + if (!read_metadata_seektable_(decoder, is_last, length)) { + return false; + } + + decoder->private_->has_seek_table = true; + if (!decoder->private_->is_seeking && decoder->private_->metadata_filter[FLAC__METADATA_TYPE_SEEKTABLE] && decoder->private_->metadata_callback) { + decoder->private_->metadata_callback(decoder, &decoder->private_->seek_table, decoder->private_->client_data); + } + } else { + FLAC__bool skip_it = !decoder->private_->metadata_filter[type]; + uint32_t real_length = length; + FLAC__StreamMetadata block; + + memset(&block, 0, sizeof(block)); + block.is_last = is_last; + block.type = (FLAC__MetadataType)type; + block.length = length; + + if (type == FLAC__METADATA_TYPE_APPLICATION) { + if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8)) { + return false; /* read_callback_ sets the state for us */ + } + + if (real_length < FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8) { /* underflow check */ + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;/*@@@@@@ maybe wrong error? need to resync?*/ + return false; + } + + real_length -= FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8; + + if (decoder->private_->metadata_filter_ids_count > 0 && has_id_filtered_(decoder, block.data.application.id)) { + skip_it = !skip_it; + } + } + + if (skip_it) { + if (!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, real_length)) { + return false; /* read_callback_ sets the state for us */ + } + } else { + FLAC__bool ok = true; + switch (type) { + case FLAC__METADATA_TYPE_PADDING: + /* skip the padding bytes */ + if (!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, real_length)) { + ok = false; /* read_callback_ sets the state for us */ + } + break; + case FLAC__METADATA_TYPE_APPLICATION: + /* remember, we read the ID already */ + if (real_length > 0) { + if (0 == (block.data.application.data = malloc(real_length))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + ok = false; + } else if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.data, real_length)) { + ok = false; /* read_callback_ sets the state for us */ + } + } else { + block.data.application.data = 0; + } + break; + case FLAC__METADATA_TYPE_VORBIS_COMMENT: + if (!read_metadata_vorbiscomment_(decoder, &block.data.vorbis_comment, real_length)) { + ok = false; + } + break; + case FLAC__METADATA_TYPE_CUESHEET: + if (!read_metadata_cuesheet_(decoder, &block.data.cue_sheet)) { + ok = false; + } + break; + case FLAC__METADATA_TYPE_PICTURE: + if (!read_metadata_picture_(decoder, &block.data.picture)) { + ok = false; + } + break; + case FLAC__METADATA_TYPE_STREAMINFO: + case FLAC__METADATA_TYPE_SEEKTABLE: + FLAC__ASSERT(0); + break; + default: + if (real_length > 0) { + if (0 == (block.data.unknown.data = malloc(real_length))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + ok = false; + } else if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.unknown.data, real_length)) { + ok = false; /* read_callback_ sets the state for us */ + } + } else { + block.data.unknown.data = 0; + } + break; + } + if (ok && !decoder->private_->is_seeking && decoder->private_->metadata_callback) { + decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data); + } + + /* now we have to free any malloc()ed data in the block */ + switch (type) { + case FLAC__METADATA_TYPE_PADDING: + break; + case FLAC__METADATA_TYPE_APPLICATION: + if (0 != block.data.application.data) { + free(block.data.application.data); + } + break; + case FLAC__METADATA_TYPE_VORBIS_COMMENT: + if (0 != block.data.vorbis_comment.vendor_string.entry) { + free(block.data.vorbis_comment.vendor_string.entry); + } + if (block.data.vorbis_comment.num_comments > 0) + for (i = 0; i < block.data.vorbis_comment.num_comments; i++) + if (0 != block.data.vorbis_comment.comments[i].entry) { + free(block.data.vorbis_comment.comments[i].entry); + } + if (0 != block.data.vorbis_comment.comments) { + free(block.data.vorbis_comment.comments); + } + break; + case FLAC__METADATA_TYPE_CUESHEET: + if (block.data.cue_sheet.num_tracks > 0) + for (i = 0; i < block.data.cue_sheet.num_tracks; i++) + if (0 != block.data.cue_sheet.tracks[i].indices) { + free(block.data.cue_sheet.tracks[i].indices); + } + if (0 != block.data.cue_sheet.tracks) { + free(block.data.cue_sheet.tracks); + } + break; + case FLAC__METADATA_TYPE_PICTURE: + if (0 != block.data.picture.mime_type) { + free(block.data.picture.mime_type); + } + if (0 != block.data.picture.description) { + free(block.data.picture.description); + } + if (0 != block.data.picture.data) { + free(block.data.picture.data); + } + break; + case FLAC__METADATA_TYPE_STREAMINFO: + case FLAC__METADATA_TYPE_SEEKTABLE: + FLAC__ASSERT(0); + default: + if (0 != block.data.unknown.data) { + free(block.data.unknown.data); + } + break; + } + + if (!ok) { /* anything that unsets "ok" should also make sure decoder->protected_->state is updated */ + return false; + } + } + } + + if (is_last) { + /* if this fails, it's OK, it's just a hint for the seek routine */ + if (!FLAC__stream_decoder_get_decode_position(decoder, &decoder->private_->first_frame_offset)) { + decoder->private_->first_frame_offset = 0; + } + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + } + + return true; +} + +FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, uint32_t length) { + FLAC__uint32 x; + uint32_t bits, used_bits = 0; + + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + + decoder->private_->stream_info.type = FLAC__METADATA_TYPE_STREAMINFO; + decoder->private_->stream_info.is_last = is_last; + decoder->private_->stream_info.length = length; + + bits = FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN; + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, bits)) { + return false; /* read_callback_ sets the state for us */ + } + decoder->private_->stream_info.data.stream_info.min_blocksize = x; + used_bits += bits; + + bits = FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN; + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + decoder->private_->stream_info.data.stream_info.max_blocksize = x; + used_bits += bits; + + bits = FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN; + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + decoder->private_->stream_info.data.stream_info.min_framesize = x; + used_bits += bits; + + bits = FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN; + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + decoder->private_->stream_info.data.stream_info.max_framesize = x; + used_bits += bits; + + bits = FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN; + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + decoder->private_->stream_info.data.stream_info.sample_rate = x; + used_bits += bits; + + bits = FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN; + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + decoder->private_->stream_info.data.stream_info.channels = x + 1; + used_bits += bits; + + bits = FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN; + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + decoder->private_->stream_info.data.stream_info.bits_per_sample = x + 1; + used_bits += bits; + + bits = FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN; + if (!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &decoder->private_->stream_info.data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + used_bits += bits; + + if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, decoder->private_->stream_info.data.stream_info.md5sum, 16)) { + return false; /* read_callback_ sets the state for us */ + } + used_bits += 16 * 8; + + /* skip the rest of the block */ + FLAC__ASSERT(used_bits % 8 == 0); + if (length < (used_bits / 8)) { + return false; /* read_callback_ sets the state for us */ + } + length -= (used_bits / 8); + if (!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length)) { + return false; /* read_callback_ sets the state for us */ + } + + return true; +} + +FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, uint32_t length) { + FLAC__uint32 i, x; + FLAC__uint64 xx; + + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + + decoder->private_->seek_table.type = FLAC__METADATA_TYPE_SEEKTABLE; + decoder->private_->seek_table.is_last = is_last; + decoder->private_->seek_table.length = length; + + decoder->private_->seek_table.data.seek_table.num_points = length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH; + + /* use realloc since we may pass through here several times (e.g. after seeking) */ + if (0 == (decoder->private_->seek_table.data.seek_table.points = safe_realloc_mul_2op_(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint)))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + for (i = 0; i < decoder->private_->seek_table.data.seek_table.num_points; i++) { + if (!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + decoder->private_->seek_table.data.seek_table.points[i].sample_number = xx; + + if (!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + decoder->private_->seek_table.data.seek_table.points[i].stream_offset = xx; + + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + decoder->private_->seek_table.data.seek_table.points[i].frame_samples = x; + } + length -= (decoder->private_->seek_table.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH); + /* if there is a partial point left, skip over it */ + if (length > 0) { + /*@@@ do a send_error_to_client_() here? there's an argument for either way */ + if (!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length)) { + return false; /* read_callback_ sets the state for us */ + } + } + + return true; +} + +FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj, uint32_t length) { + FLAC__uint32 i; + + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + + /* read vendor string */ + if (length >= 8) { + length -= 8; /* vendor string length + num comments entries alone take 8 bytes */ + FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); + if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length)) { + return false; /* read_callback_ sets the state for us */ + } + if (obj->vendor_string.length > 0) { + if (length < obj->vendor_string.length) { + obj->vendor_string.length = 0; + obj->vendor_string.entry = 0; + goto skip; + } else { + length -= obj->vendor_string.length; + } + if (0 == (obj->vendor_string.entry = safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->vendor_string.entry, obj->vendor_string.length)) { + return false; /* read_callback_ sets the state for us */ + } + obj->vendor_string.entry[obj->vendor_string.length] = '\0'; + } else { + obj->vendor_string.entry = 0; + } + + /* read num comments */ + FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN == 32); + if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->num_comments)) { + return false; /* read_callback_ sets the state for us */ + } + + /* read comments */ + if (obj->num_comments > 100000) { + /* Possibly malicious file. */ + obj->num_comments = 0; + return false; + } + if (obj->num_comments > 0) { + if (0 == (obj->comments = safe_malloc_mul_2op_p(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) { + obj->num_comments = 0; + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + for (i = 0; i < obj->num_comments; i++) { + /* Initialize here just to make sure. */ + obj->comments[i].length = 0; + obj->comments[i].entry = 0; + + FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); + if (length < 4) { + obj->num_comments = i; + goto skip; + } else { + length -= 4; + } + if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length)) { + obj->num_comments = i; + return false; /* read_callback_ sets the state for us */ + } + if (obj->comments[i].length > 0) { + if (length < obj->comments[i].length) { + obj->num_comments = i; + goto skip; + } else { + length -= obj->comments[i].length; + } + if (0 == (obj->comments[i].entry = safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + obj->num_comments = i; + return false; + } + memset(obj->comments[i].entry, 0, obj->comments[i].length) ; + if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->comments[i].entry, obj->comments[i].length)) { + /* Current i-th entry is bad, so we delete it. */ + free(obj->comments[i].entry) ; + obj->comments[i].entry = NULL ; + obj->num_comments = i; + goto skip; + } + obj->comments[i].entry[obj->comments[i].length] = '\0'; + } else { + obj->comments[i].entry = 0; + } + } + } + } + +skip: + if (length > 0) { + /* length > 0 can only happen on files with invalid data in comments */ + if (obj->num_comments < 1) { + free(obj->comments); + obj->comments = NULL; + } + if (!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length)) { + return false; /* read_callback_ sets the state for us */ + } + } + + return true; +} + +FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj) { + FLAC__uint32 i, j, x; + + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + + memset(obj, 0, sizeof(FLAC__StreamMetadata_CueSheet)); + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0); + if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)obj->media_catalog_number, FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN / 8)) { + return false; /* read_callback_ sets the state for us */ + } + + if (!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &obj->lead_in, FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + obj->is_cd = x ? true : false; + + if (!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + obj->num_tracks = x; + + if (obj->num_tracks > 0) { + if (0 == (obj->tracks = safe_calloc_(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + for (i = 0; i < obj->num_tracks; i++) { + FLAC__StreamMetadata_CueSheet_Track *track = &obj->tracks[i]; + if (!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &track->offset, FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + track->number = (FLAC__byte)x; + + FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0); + if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)track->isrc, FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN / 8)) { + return false; /* read_callback_ sets the state for us */ + } + + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + track->type = x; + + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + track->pre_emphasis = x; + + if (!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + track->num_indices = (FLAC__byte)x; + + if (track->num_indices > 0) { + if (0 == (track->indices = safe_calloc_(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + for (j = 0; j < track->num_indices; j++) { + FLAC__StreamMetadata_CueSheet_Index *indx = &track->indices[j]; + if (!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &indx->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + indx->number = (FLAC__byte)x; + + if (!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + } + } + } + } + + return true; +} + +FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj) { + FLAC__uint32 x; + + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + + /* read type */ + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_TYPE_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + obj->type = x; + + /* read MIME type */ + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + if (0 == (obj->mime_type = safe_malloc_add_2op_(x, /*+*/1))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + if (x > 0) { + if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)obj->mime_type, x)) { + return false; /* read_callback_ sets the state for us */ + } + } + obj->mime_type[x] = '\0'; + + /* read description */ + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + if (0 == (obj->description = safe_malloc_add_2op_(x, /*+*/1))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + if (x > 0) { + if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->description, x)) { + return false; /* read_callback_ sets the state for us */ + } + } + obj->description[x] = '\0'; + + /* read width */ + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->width, FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + + /* read height */ + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->height, FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + + /* read depth */ + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->depth, FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + + /* read colors */ + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->colors, FLAC__STREAM_METADATA_PICTURE_COLORS_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + + /* read data */ + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &(obj->data_length), FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + if (0 == (obj->data = safe_malloc_(obj->data_length))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + if (obj->data_length > 0) { + if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->data, obj->data_length)) { + return false; /* read_callback_ sets the state for us */ + } + } + + return true; +} + +FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder) { + FLAC__uint32 x; + uint32_t i, skip; + + /* skip the version and flags bytes */ + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 24)) { + return false; /* read_callback_ sets the state for us */ + } + /* get the size (in bytes) to skip */ + skip = 0; + for (i = 0; i < 4; i++) { + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) { + return false; /* read_callback_ sets the state for us */ + } + skip <<= 7; + skip |= (x & 0x7f); + } + /* skip the rest of the tag */ + if (!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, skip)) { + return false; /* read_callback_ sets the state for us */ + } + return true; +} + +FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder) { + FLAC__uint32 x; + FLAC__bool first = true; + + /* If we know the total number of samples in the stream, stop if we've read that many. */ + /* This will stop us, for example, from wasting time trying to sync on an ID3V1 tag. */ + if (FLAC__stream_decoder_get_total_samples(decoder) > 0) { + if (decoder->private_->samples_decoded >= FLAC__stream_decoder_get_total_samples(decoder)) { + decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM; + return true; + } + } + + /* make sure we're byte aligned */ + if (!FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)) { + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__bitreader_bits_left_for_byte_alignment(decoder->private_->input))) { + return false; /* read_callback_ sets the state for us */ + } + } + + while (1) { + if (decoder->private_->cached) { + x = (FLAC__uint32)decoder->private_->lookahead; + decoder->private_->cached = false; + } else { + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) { + return false; /* read_callback_ sets the state for us */ + } + } + if (x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ + decoder->private_->header_warmup[0] = (FLAC__byte)x; + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) { + return false; /* read_callback_ sets the state for us */ + } + + /* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */ + /* else we have to check if the second byte is the end of a sync code */ + if (x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ + decoder->private_->lookahead = (FLAC__byte)x; + decoder->private_->cached = true; + } else if (x >> 1 == 0x7c) { /* MAGIC NUMBER for the last 6 sync bits and reserved 7th bit */ + decoder->private_->header_warmup[1] = (FLAC__byte)x; + decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME; + return true; + } + } + if (first) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + first = false; + } + } + + return true; +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FLAC__bool do_full_decode) { + uint32_t channel; + uint32_t i; + FLAC__int32 mid, side; + uint32_t frame_crc; /* the one we calculate from the input stream */ + FLAC__uint32 x; + + *got_a_frame = false; + + /* init the CRC */ + frame_crc = 0; + frame_crc = FLAC__CRC16_UPDATE(decoder->private_->header_warmup[0], frame_crc); + frame_crc = FLAC__CRC16_UPDATE(decoder->private_->header_warmup[1], frame_crc); + FLAC__bitreader_reset_read_crc16(decoder->private_->input, (FLAC__uint16)frame_crc); + + if (!read_frame_header_(decoder)) { + return false; + } + if (decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) { /* means we didn't sync on a valid header */ + return true; + } + if (!allocate_output_(decoder, decoder->private_->frame.header.blocksize, decoder->private_->frame.header.channels)) { + return false; + } + for (channel = 0; channel < decoder->private_->frame.header.channels; channel++) { + /* + first figure the correct bits-per-sample of the subframe + */ + uint32_t bps = decoder->private_->frame.header.bits_per_sample; + switch (decoder->private_->frame.header.channel_assignment) { + case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: + /* no adjustment needed */ + break; + case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: + FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + if (channel == 1) { + bps++; + } + break; + case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: + FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + if (channel == 0) { + bps++; + } + break; + case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: + FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + if (channel == 1) { + bps++; + } + break; + default: + FLAC__ASSERT(0); + } + /* + now read it + */ + if (!read_subframe_(decoder, channel, bps, do_full_decode)) { + return false; + } + if (decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) { /* means bad sync or got corruption */ + return true; + } + } + if (!read_zero_padding_(decoder)) { + return false; + } + if (decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) { /* means bad sync or got corruption (i.e. "zero bits" were not all zeroes) */ + return true; + } + + /* + Read the frame CRC-16 from the footer and check + */ + frame_crc = FLAC__bitreader_get_read_crc16(decoder->private_->input); + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__FRAME_FOOTER_CRC_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + if (frame_crc == x) { + if (do_full_decode) { + /* Undo any special channel coding */ + switch (decoder->private_->frame.header.channel_assignment) { + case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: + /* do nothing */ + break; + case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: + FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + for (i = 0; i < decoder->private_->frame.header.blocksize; i++) { + decoder->private_->output[1][i] = decoder->private_->output[0][i] - decoder->private_->output[1][i]; + } + break; + case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: + FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + for (i = 0; i < decoder->private_->frame.header.blocksize; i++) { + decoder->private_->output[0][i] += decoder->private_->output[1][i]; + } + break; + case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: + FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + for (i = 0; i < decoder->private_->frame.header.blocksize; i++) { #if 1 - mid = decoder->private_->output[0][i]; - side = decoder->private_->output[1][i]; - mid = ((uint32_t) mid) << 1; - mid |= (side & 1); /* i.e. if 'side' is odd... */ - decoder->private_->output[0][i] = (mid + side) >> 1; - decoder->private_->output[1][i] = (mid - side) >> 1; + mid = decoder->private_->output[0][i]; + side = decoder->private_->output[1][i]; + mid = ((uint32_t) mid) << 1; + mid |= (side & 1); /* i.e. if 'side' is odd... */ + decoder->private_->output[0][i] = (mid + side) >> 1; + decoder->private_->output[1][i] = (mid - side) >> 1; #else - /* OPT: without 'side' temp variable */ - mid = (decoder->private_->output[0][i] << 1) | (decoder->private_->output[1][i] & 1); /* i.e. if 'side' is odd... */ - decoder->private_->output[0][i] = (mid + decoder->private_->output[1][i]) >> 1; - decoder->private_->output[1][i] = (mid - decoder->private_->output[1][i]) >> 1; + /* OPT: without 'side' temp variable */ + mid = (decoder->private_->output[0][i] << 1) | (decoder->private_->output[1][i] & 1); /* i.e. if 'side' is odd... */ + decoder->private_->output[0][i] = (mid + decoder->private_->output[1][i]) >> 1; + decoder->private_->output[1][i] = (mid - decoder->private_->output[1][i]) >> 1; #endif - } - break; - default: - FLAC__ASSERT(0); - break; - } - } - } - else { - /* Bad frame, emit error and zero the output signal */ - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH); - if(do_full_decode) { - for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) { - memset(decoder->private_->output[channel], 0, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize); - } - } - } - - *got_a_frame = true; - - /* we wait to update fixed_block_size until here, when we're sure we've got a proper frame and hence a correct blocksize */ - if(decoder->private_->next_fixed_block_size) - decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size; - - /* put the latest values into the public section of the decoder instance */ - decoder->protected_->channels = decoder->private_->frame.header.channels; - decoder->protected_->channel_assignment = decoder->private_->frame.header.channel_assignment; - decoder->protected_->bits_per_sample = decoder->private_->frame.header.bits_per_sample; - decoder->protected_->sample_rate = decoder->private_->frame.header.sample_rate; - decoder->protected_->blocksize = decoder->private_->frame.header.blocksize; - - FLAC__ASSERT(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); - decoder->private_->samples_decoded = decoder->private_->frame.header.number.sample_number + decoder->private_->frame.header.blocksize; - - /* write it */ - if(do_full_decode) { - if(write_audio_frame_to_client_(decoder, &decoder->private_->frame, (const FLAC__int32 * const *)decoder->private_->output) != FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE) { - decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED; - return false; - } - } - - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; -} - -FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder) -{ - FLAC__uint32 x; - FLAC__uint64 xx; - uint32_t i, blocksize_hint = 0, sample_rate_hint = 0; - FLAC__byte crc8, raw_header[16]; /* MAGIC NUMBER based on the maximum frame header size, including CRC */ - uint32_t raw_header_len; - FLAC__bool is_unparseable = false; - - FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); - - /* init the raw header with the saved bits from synchronization */ - raw_header[0] = decoder->private_->header_warmup[0]; - raw_header[1] = decoder->private_->header_warmup[1]; - raw_header_len = 2; - - /* check to make sure that reserved bit is 0 */ - if(raw_header[1] & 0x02) /* MAGIC NUMBER */ - is_unparseable = true; - - /* - * Note that along the way as we read the header, we look for a sync - * code inside. If we find one it would indicate that our original - * sync was bad since there cannot be a sync code in a valid header. - * - * Three kinds of things can go wrong when reading the frame header: - * 1) We may have sync'ed incorrectly and not landed on a frame header. - * If we don't find a sync code, it can end up looking like we read - * a valid but unparseable header, until getting to the frame header - * CRC. Even then we could get a false positive on the CRC. - * 2) We may have sync'ed correctly but on an unparseable frame (from a - * future encoder). - * 3) We may be on a damaged frame which appears valid but unparseable. - * - * For all these reasons, we try and read a complete frame header as - * long as it seems valid, even if unparseable, up until the frame - * header CRC. - */ - - /* - * read in the raw header as bytes so we can CRC it, and parse it on the way - */ - for(i = 0; i < 2; i++) { - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) - return false; /* read_callback_ sets the state for us */ - if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ - /* if we get here it means our original sync was erroneous since the sync code cannot appear in the header */ - decoder->private_->lookahead = (FLAC__byte)x; - decoder->private_->cached = true; - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } - raw_header[raw_header_len++] = (FLAC__byte)x; - } - - switch(x = raw_header[2] >> 4) { - case 0: - is_unparseable = true; - break; - case 1: - decoder->private_->frame.header.blocksize = 192; - break; - case 2: - case 3: - case 4: - case 5: - decoder->private_->frame.header.blocksize = 576 << (x-2); - break; - case 6: - case 7: - blocksize_hint = x; - break; - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - decoder->private_->frame.header.blocksize = 256 << (x-8); - break; - default: - FLAC__ASSERT(0); - break; - } - - switch(x = raw_header[2] & 0x0f) { - case 0: - if(decoder->private_->has_stream_info) - decoder->private_->frame.header.sample_rate = decoder->private_->stream_info.data.stream_info.sample_rate; - else - is_unparseable = true; - break; - case 1: - decoder->private_->frame.header.sample_rate = 88200; - break; - case 2: - decoder->private_->frame.header.sample_rate = 176400; - break; - case 3: - decoder->private_->frame.header.sample_rate = 192000; - break; - case 4: - decoder->private_->frame.header.sample_rate = 8000; - break; - case 5: - decoder->private_->frame.header.sample_rate = 16000; - break; - case 6: - decoder->private_->frame.header.sample_rate = 22050; - break; - case 7: - decoder->private_->frame.header.sample_rate = 24000; - break; - case 8: - decoder->private_->frame.header.sample_rate = 32000; - break; - case 9: - decoder->private_->frame.header.sample_rate = 44100; - break; - case 10: - decoder->private_->frame.header.sample_rate = 48000; - break; - case 11: - decoder->private_->frame.header.sample_rate = 96000; - break; - case 12: - case 13: - case 14: - sample_rate_hint = x; - break; - case 15: - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - default: - FLAC__ASSERT(0); - } - - x = (uint32_t)(raw_header[3] >> 4); - if(x & 8) { - decoder->private_->frame.header.channels = 2; - switch(x & 7) { - case 0: - decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE; - break; - case 1: - decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE; - break; - case 2: - decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_MID_SIDE; - break; - default: - is_unparseable = true; - break; - } - } - else { - decoder->private_->frame.header.channels = (uint32_t)x + 1; - decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT; - } - - switch(x = (uint32_t)(raw_header[3] & 0x0e) >> 1) { - case 0: - if(decoder->private_->has_stream_info) - decoder->private_->frame.header.bits_per_sample = decoder->private_->stream_info.data.stream_info.bits_per_sample; - else - is_unparseable = true; - break; - case 1: - decoder->private_->frame.header.bits_per_sample = 8; - break; - case 2: - decoder->private_->frame.header.bits_per_sample = 12; - break; - case 4: - decoder->private_->frame.header.bits_per_sample = 16; - break; - case 5: - decoder->private_->frame.header.bits_per_sample = 20; - break; - case 6: - decoder->private_->frame.header.bits_per_sample = 24; - break; - case 3: - case 7: - is_unparseable = true; - break; - default: - FLAC__ASSERT(0); - break; - } - - /* check to make sure that reserved bit is 0 */ - if(raw_header[3] & 0x01) /* MAGIC NUMBER */ - is_unparseable = true; - - /* read the frame's starting sample number (or frame number as the case may be) */ - if( - raw_header[1] & 0x01 || - /*@@@ this clause is a concession to the old way of doing variable blocksize; the only known implementation is flake and can probably be removed without inconveniencing anyone */ - (decoder->private_->has_stream_info && decoder->private_->stream_info.data.stream_info.min_blocksize != decoder->private_->stream_info.data.stream_info.max_blocksize) - ) { /* variable blocksize */ - if(!FLAC__bitreader_read_utf8_uint64(decoder->private_->input, &xx, raw_header, &raw_header_len)) - return false; /* read_callback_ sets the state for us */ - if(xx == FLAC__U64L(0xffffffffffffffff)) { /* i.e. non-UTF8 code... */ - decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */ - decoder->private_->cached = true; - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } - decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER; - decoder->private_->frame.header.number.sample_number = xx; - } - else { /* fixed blocksize */ - if(!FLAC__bitreader_read_utf8_uint32(decoder->private_->input, &x, raw_header, &raw_header_len)) - return false; /* read_callback_ sets the state for us */ - if(x == 0xffffffff) { /* i.e. non-UTF8 code... */ - decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */ - decoder->private_->cached = true; - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } - decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER; - decoder->private_->frame.header.number.frame_number = x; - } - - if(blocksize_hint) { - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) - return false; /* read_callback_ sets the state for us */ - raw_header[raw_header_len++] = (FLAC__byte)x; - if(blocksize_hint == 7) { - FLAC__uint32 _x; - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &_x, 8)) - return false; /* read_callback_ sets the state for us */ - raw_header[raw_header_len++] = (FLAC__byte)_x; - x = (x << 8) | _x; - } - decoder->private_->frame.header.blocksize = x+1; - } - - if(sample_rate_hint) { - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) - return false; /* read_callback_ sets the state for us */ - raw_header[raw_header_len++] = (FLAC__byte)x; - if(sample_rate_hint != 12) { - FLAC__uint32 _x; - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &_x, 8)) - return false; /* read_callback_ sets the state for us */ - raw_header[raw_header_len++] = (FLAC__byte)_x; - x = (x << 8) | _x; - } - if(sample_rate_hint == 12) - decoder->private_->frame.header.sample_rate = x*1000; - else if(sample_rate_hint == 13) - decoder->private_->frame.header.sample_rate = x; - else - decoder->private_->frame.header.sample_rate = x*10; - } - - /* read the CRC-8 byte */ - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) - return false; /* read_callback_ sets the state for us */ - crc8 = (FLAC__byte)x; - - if(FLAC__crc8(raw_header, raw_header_len) != crc8) { - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } - - /* calculate the sample number from the frame number if needed */ - decoder->private_->next_fixed_block_size = 0; - if(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER) { - x = decoder->private_->frame.header.number.frame_number; - decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER; - if(decoder->private_->fixed_block_size) - decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->fixed_block_size * (FLAC__uint64)x; - else if(decoder->private_->has_stream_info) { - if(decoder->private_->stream_info.data.stream_info.min_blocksize == decoder->private_->stream_info.data.stream_info.max_blocksize) { - decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->stream_info.data.stream_info.min_blocksize * (FLAC__uint64)x; - decoder->private_->next_fixed_block_size = decoder->private_->stream_info.data.stream_info.max_blocksize; - } - else - is_unparseable = true; - } - else if(x == 0) { - decoder->private_->frame.header.number.sample_number = 0; - decoder->private_->next_fixed_block_size = decoder->private_->frame.header.blocksize; - } - else { - /* can only get here if the stream has invalid frame numbering and no STREAMINFO, so assume it's not the last (possibly short) frame */ - decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->frame.header.blocksize * (FLAC__uint64)x; - } - } - - if(is_unparseable) { - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } - - return true; -} - -FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode) -{ - FLAC__uint32 x; - FLAC__bool wasted_bits; - uint32_t i; - - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) /* MAGIC NUMBER */ - return false; /* read_callback_ sets the state for us */ - - wasted_bits = (x & 1); - x &= 0xfe; - - if(wasted_bits) { - uint32_t u; - if(!FLAC__bitreader_read_unary_unsigned(decoder->private_->input, &u)) - return false; /* read_callback_ sets the state for us */ - decoder->private_->frame.subframes[channel].wasted_bits = u+1; - if (decoder->private_->frame.subframes[channel].wasted_bits >= bps) - return false; - bps -= decoder->private_->frame.subframes[channel].wasted_bits; - } - else - decoder->private_->frame.subframes[channel].wasted_bits = 0; - - /* - * Lots of magic numbers here - */ - if(x & 0x80) { - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } - else if(x == 0) { - if(!read_subframe_constant_(decoder, channel, bps, do_full_decode)) - return false; - } - else if(x == 2) { - if(!read_subframe_verbatim_(decoder, channel, bps, do_full_decode)) - return false; - } - else if(x < 16) { - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } - else if(x <= 24) { - if(!read_subframe_fixed_(decoder, channel, bps, (x>>1)&7, do_full_decode)) - return false; - if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption */ - return true; - } - else if(x < 64) { - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } - else { - if(!read_subframe_lpc_(decoder, channel, bps, ((x>>1)&31)+1, do_full_decode)) - return false; - if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption */ - return true; - } - - if(wasted_bits && do_full_decode) { - x = decoder->private_->frame.subframes[channel].wasted_bits; - for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { - uint32_t val = decoder->private_->output[channel][i]; - decoder->private_->output[channel][i] = (val << x); - } - } - - return true; -} - -FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode) -{ - FLAC__Subframe_Constant *subframe = &decoder->private_->frame.subframes[channel].data.constant; - FLAC__int32 x; - uint32_t i; - FLAC__int32 *output = decoder->private_->output[channel]; - - decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_CONSTANT; - - if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps)) - return false; /* read_callback_ sets the state for us */ - - subframe->value = x; - - /* decode the subframe */ - if(do_full_decode) { - for(i = 0; i < decoder->private_->frame.header.blocksize; i++) - output[i] = x; - } - - return true; -} - -FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, const uint32_t order, FLAC__bool do_full_decode) -{ - FLAC__Subframe_Fixed *subframe = &decoder->private_->frame.subframes[channel].data.fixed; - FLAC__int32 i32; - FLAC__uint32 u32; - uint32_t u; - - decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_FIXED; - - subframe->residual = decoder->private_->residual[channel]; - subframe->order = order; - - /* read warm-up samples */ - for(u = 0; u < order; u++) { - if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, bps)) - return false; /* read_callback_ sets the state for us */ - subframe->warmup[u] = i32; - } - - /* read entropy coding method info */ - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN)) - return false; /* read_callback_ sets the state for us */ - subframe->entropy_coding_method.type = (FLAC__EntropyCodingMethodType)u32; - switch(subframe->entropy_coding_method.type) { - case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: - case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN)) - return false; /* read_callback_ sets the state for us */ - if(decoder->private_->frame.header.blocksize >> u32 < order) { - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } - subframe->entropy_coding_method.data.partitioned_rice.order = u32; - subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel]; - break; - default: - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } - - /* read residual */ - switch(subframe->entropy_coding_method.type) { - case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: - case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: - if(!read_residual_partitioned_rice_(decoder, order, subframe->entropy_coding_method.data.partitioned_rice.order, &decoder->private_->partitioned_rice_contents[channel], decoder->private_->residual[channel], /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2)) - return false; - break; - default: - FLAC__ASSERT(0); - } - - /* decode the subframe */ - if(do_full_decode) { - memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order); - FLAC__fixed_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->output[channel]+order); - } - - return true; -} - -FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, const uint32_t order, FLAC__bool do_full_decode) -{ - FLAC__Subframe_LPC *subframe = &decoder->private_->frame.subframes[channel].data.lpc; - FLAC__int32 i32; - FLAC__uint32 u32; - uint32_t u; - - decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_LPC; - - subframe->residual = decoder->private_->residual[channel]; - subframe->order = order; - - /* read warm-up samples */ - for(u = 0; u < order; u++) { - if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, bps)) - return false; /* read_callback_ sets the state for us */ - subframe->warmup[u] = i32; - } - - /* read qlp coeff precision */ - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN)) - return false; /* read_callback_ sets the state for us */ - if(u32 == (1u << FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN) - 1) { - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } - subframe->qlp_coeff_precision = u32+1; - - /* read qlp shift */ - if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN)) - return false; /* read_callback_ sets the state for us */ - if(i32 < 0) { - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } - subframe->quantization_level = i32; - - /* read quantized lp coefficiencts */ - for(u = 0; u < order; u++) { - if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, subframe->qlp_coeff_precision)) - return false; /* read_callback_ sets the state for us */ - subframe->qlp_coeff[u] = i32; - } - - /* read entropy coding method info */ - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN)) - return false; /* read_callback_ sets the state for us */ - subframe->entropy_coding_method.type = (FLAC__EntropyCodingMethodType)u32; - switch(subframe->entropy_coding_method.type) { - case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: - case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN)) - return false; /* read_callback_ sets the state for us */ - if(decoder->private_->frame.header.blocksize >> u32 < order) { - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } - subframe->entropy_coding_method.data.partitioned_rice.order = u32; - subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel]; - break; - default: - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } - - /* read residual */ - switch(subframe->entropy_coding_method.type) { - case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: - case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: - if(!read_residual_partitioned_rice_(decoder, order, subframe->entropy_coding_method.data.partitioned_rice.order, &decoder->private_->partitioned_rice_contents[channel], decoder->private_->residual[channel], /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2)) - return false; - break; - default: - FLAC__ASSERT(0); - } - - /* decode the subframe */ - if(do_full_decode) { - memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order); - if(bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32) - if(bps <= 16 && subframe->qlp_coeff_precision <= 16) - decoder->private_->local_lpc_restore_signal_16bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); - else - decoder->private_->local_lpc_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); - else - decoder->private_->local_lpc_restore_signal_64bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); - } - - return true; -} - -FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode) -{ - FLAC__Subframe_Verbatim *subframe = &decoder->private_->frame.subframes[channel].data.verbatim; - FLAC__int32 x, *residual = decoder->private_->residual[channel]; - uint32_t i; - - decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_VERBATIM; - - subframe->data = residual; - - for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { - if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps)) - return false; /* read_callback_ sets the state for us */ - residual[i] = x; - } - - /* decode the subframe */ - if(do_full_decode) - memcpy(decoder->private_->output[channel], subframe->data, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize); - - return true; -} - -FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, uint32_t predictor_order, uint32_t partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual, FLAC__bool is_extended) -{ - FLAC__uint32 rice_parameter; - int i; - uint32_t partition, sample, u; - const uint32_t partitions = 1u << partition_order; - const uint32_t partition_samples = partition_order > 0? decoder->private_->frame.header.blocksize >> partition_order : decoder->private_->frame.header.blocksize - predictor_order; - const uint32_t plen = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; - const uint32_t pesc = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; - - /* invalid predictor and partition orders mush be handled in the callers */ - FLAC__ASSERT(partition_order > 0? partition_samples >= predictor_order : decoder->private_->frame.header.blocksize >= predictor_order); - - if(!FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, flac_max(6u, partition_order))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - - sample = 0; - for(partition = 0; partition < partitions; partition++) { - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &rice_parameter, plen)) - return false; /* read_callback_ sets the state for us */ - partitioned_rice_contents->parameters[partition] = rice_parameter; - if(rice_parameter < pesc) { - partitioned_rice_contents->raw_bits[partition] = 0; - u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order; - if(!FLAC__bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter)) - return false; /* read_callback_ sets the state for us */ - sample += u; - } - else { - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN)) - return false; /* read_callback_ sets the state for us */ - partitioned_rice_contents->raw_bits[partition] = rice_parameter; - for(u = (partition_order == 0 || partition > 0)? 0 : predictor_order; u < partition_samples; u++, sample++) { - if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i, rice_parameter)) - return false; /* read_callback_ sets the state for us */ - residual[sample] = i; - } - } - } - - return true; -} - -FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder) -{ - if(!FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)) { - FLAC__uint32 zero = 0; - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &zero, FLAC__bitreader_bits_left_for_byte_alignment(decoder->private_->input))) - return false; /* read_callback_ sets the state for us */ - if(zero != 0) { - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - } - } - return true; -} - -FLAC__bool read_callback_(FLAC__byte buffer[], size_t *bytes, void *client_data) -{ - FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder *)client_data; - - if( + } + break; + default: + FLAC__ASSERT(0); + break; + } + } + } else { + /* Bad frame, emit error and zero the output signal */ + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH); + if (do_full_decode) { + for (channel = 0; channel < decoder->private_->frame.header.channels; channel++) { + memset(decoder->private_->output[channel], 0, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize); + } + } + } + + *got_a_frame = true; + + /* we wait to update fixed_block_size until here, when we're sure we've got a proper frame and hence a correct blocksize */ + if (decoder->private_->next_fixed_block_size) { + decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size; + } + + /* put the latest values into the public section of the decoder instance */ + decoder->protected_->channels = decoder->private_->frame.header.channels; + decoder->protected_->channel_assignment = decoder->private_->frame.header.channel_assignment; + decoder->protected_->bits_per_sample = decoder->private_->frame.header.bits_per_sample; + decoder->protected_->sample_rate = decoder->private_->frame.header.sample_rate; + decoder->protected_->blocksize = decoder->private_->frame.header.blocksize; + + FLAC__ASSERT(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); + decoder->private_->samples_decoded = decoder->private_->frame.header.number.sample_number + decoder->private_->frame.header.blocksize; + + /* write it */ + if (do_full_decode) { + if (write_audio_frame_to_client_(decoder, &decoder->private_->frame, (const FLAC__int32 * const *)decoder->private_->output) != FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE) { + decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED; + return false; + } + } + + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; +} +#pragma GCC diagnostic pop + +FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder) { + FLAC__uint32 x; + FLAC__uint64 xx; + uint32_t i, blocksize_hint = 0, sample_rate_hint = 0; + FLAC__byte crc8, raw_header[16]; /* MAGIC NUMBER based on the maximum frame header size, including CRC */ + uint32_t raw_header_len; + FLAC__bool is_unparseable = false; + + FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); + + /* init the raw header with the saved bits from synchronization */ + raw_header[0] = decoder->private_->header_warmup[0]; + raw_header[1] = decoder->private_->header_warmup[1]; + raw_header_len = 2; + + /* check to make sure that reserved bit is 0 */ + if (raw_header[1] & 0x02) { /* MAGIC NUMBER */ + is_unparseable = true; + } + + /* + Note that along the way as we read the header, we look for a sync + code inside. If we find one it would indicate that our original + sync was bad since there cannot be a sync code in a valid header. + + Three kinds of things can go wrong when reading the frame header: + 1) We may have sync'ed incorrectly and not landed on a frame header. + If we don't find a sync code, it can end up looking like we read + a valid but unparsable header, until getting to the frame header + CRC. Even then we could get a false positive on the CRC. + 2) We may have sync'ed correctly but on an unparsable frame (from a + future encoder). + 3) We may be on a damaged frame which appears valid but unparsable. + + For all these reasons, we try and read a complete frame header as + long as it seems valid, even if unparsable, up until the frame + header CRC. + */ + + /* + read in the raw header as bytes so we can CRC it, and parse it on the way + */ + for (i = 0; i < 2; i++) { + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) { + return false; /* read_callback_ sets the state for us */ + } + if (x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ + /* if we get here it means our original sync was erroneous since the sync code cannot appear in the header */ + decoder->private_->lookahead = (FLAC__byte)x; + decoder->private_->cached = true; + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + raw_header[raw_header_len++] = (FLAC__byte)x; + } + + switch (x = raw_header[2] >> 4) { + case 0: + is_unparseable = true; + break; + case 1: + decoder->private_->frame.header.blocksize = 192; + break; + case 2: + case 3: + case 4: + case 5: + decoder->private_->frame.header.blocksize = 576 << (x - 2); + break; + case 6: + case 7: + blocksize_hint = x; + break; + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + decoder->private_->frame.header.blocksize = 256 << (x - 8); + break; + default: + FLAC__ASSERT(0); + break; + } + + switch (x = raw_header[2] & 0x0f) { + case 0: + if (decoder->private_->has_stream_info) { + decoder->private_->frame.header.sample_rate = decoder->private_->stream_info.data.stream_info.sample_rate; + } else { + is_unparseable = true; + } + break; + case 1: + decoder->private_->frame.header.sample_rate = 88200; + break; + case 2: + decoder->private_->frame.header.sample_rate = 176400; + break; + case 3: + decoder->private_->frame.header.sample_rate = 192000; + break; + case 4: + decoder->private_->frame.header.sample_rate = 8000; + break; + case 5: + decoder->private_->frame.header.sample_rate = 16000; + break; + case 6: + decoder->private_->frame.header.sample_rate = 22050; + break; + case 7: + decoder->private_->frame.header.sample_rate = 24000; + break; + case 8: + decoder->private_->frame.header.sample_rate = 32000; + break; + case 9: + decoder->private_->frame.header.sample_rate = 44100; + break; + case 10: + decoder->private_->frame.header.sample_rate = 48000; + break; + case 11: + decoder->private_->frame.header.sample_rate = 96000; + break; + case 12: + case 13: + case 14: + sample_rate_hint = x; + break; + case 15: + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + default: + FLAC__ASSERT(0); + } + + x = (uint32_t)(raw_header[3] >> 4); + if (x & 8) { + decoder->private_->frame.header.channels = 2; + switch (x & 7) { + case 0: + decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE; + break; + case 1: + decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE; + break; + case 2: + decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_MID_SIDE; + break; + default: + is_unparseable = true; + break; + } + } else { + decoder->private_->frame.header.channels = (uint32_t)x + 1; + decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT; + } + + switch (x = (uint32_t)(raw_header[3] & 0x0e) >> 1) { + case 0: + if (decoder->private_->has_stream_info) { + decoder->private_->frame.header.bits_per_sample = decoder->private_->stream_info.data.stream_info.bits_per_sample; + } else { + is_unparseable = true; + } + break; + case 1: + decoder->private_->frame.header.bits_per_sample = 8; + break; + case 2: + decoder->private_->frame.header.bits_per_sample = 12; + break; + case 4: + decoder->private_->frame.header.bits_per_sample = 16; + break; + case 5: + decoder->private_->frame.header.bits_per_sample = 20; + break; + case 6: + decoder->private_->frame.header.bits_per_sample = 24; + break; + case 3: + case 7: + is_unparseable = true; + break; + default: + FLAC__ASSERT(0); + break; + } + + /* check to make sure that reserved bit is 0 */ + if (raw_header[3] & 0x01) { /* MAGIC NUMBER */ + is_unparseable = true; + } + + /* read the frame's starting sample number (or frame number as the case may be) */ + if ( + raw_header[1] & 0x01 || + /*@@@ this clause is a concession to the old way of doing variable blocksize; the only known implementation is flake and can probably be removed without inconveniencing anyone */ + (decoder->private_->has_stream_info && decoder->private_->stream_info.data.stream_info.min_blocksize != decoder->private_->stream_info.data.stream_info.max_blocksize) + ) { /* variable blocksize */ + if (!FLAC__bitreader_read_utf8_uint64(decoder->private_->input, &xx, raw_header, &raw_header_len)) { + return false; /* read_callback_ sets the state for us */ + } + if (xx == FLAC__U64L(0xffffffffffffffff)) { /* i.e. non-UTF8 code... */ + decoder->private_->lookahead = raw_header[raw_header_len - 1]; /* back up as much as we can */ + decoder->private_->cached = true; + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER; + decoder->private_->frame.header.number.sample_number = xx; + } else { /* fixed blocksize */ + if (!FLAC__bitreader_read_utf8_uint32(decoder->private_->input, &x, raw_header, &raw_header_len)) { + return false; /* read_callback_ sets the state for us */ + } + if (x == 0xffffffff) { /* i.e. non-UTF8 code... */ + decoder->private_->lookahead = raw_header[raw_header_len - 1]; /* back up as much as we can */ + decoder->private_->cached = true; + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER; + decoder->private_->frame.header.number.frame_number = x; + } + + if (blocksize_hint) { + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) { + return false; /* read_callback_ sets the state for us */ + } + raw_header[raw_header_len++] = (FLAC__byte)x; + if (blocksize_hint == 7) { + FLAC__uint32 _x; + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &_x, 8)) { + return false; /* read_callback_ sets the state for us */ + } + raw_header[raw_header_len++] = (FLAC__byte)_x; + x = (x << 8) | _x; + } + decoder->private_->frame.header.blocksize = x + 1; + } + + if (sample_rate_hint) { + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) { + return false; /* read_callback_ sets the state for us */ + } + raw_header[raw_header_len++] = (FLAC__byte)x; + if (sample_rate_hint != 12) { + FLAC__uint32 _x; + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &_x, 8)) { + return false; /* read_callback_ sets the state for us */ + } + raw_header[raw_header_len++] = (FLAC__byte)_x; + x = (x << 8) | _x; + } + if (sample_rate_hint == 12) { + decoder->private_->frame.header.sample_rate = x * 1000; + } else if (sample_rate_hint == 13) { + decoder->private_->frame.header.sample_rate = x; + } else { + decoder->private_->frame.header.sample_rate = x * 10; + } + } + + /* read the CRC-8 byte */ + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) { + return false; /* read_callback_ sets the state for us */ + } + crc8 = (FLAC__byte)x; + + if (FLAC__crc8(raw_header, raw_header_len) != crc8) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + + /* calculate the sample number from the frame number if needed */ + decoder->private_->next_fixed_block_size = 0; + if (decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER) { + x = decoder->private_->frame.header.number.frame_number; + decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER; + if (decoder->private_->fixed_block_size) { + decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->fixed_block_size * (FLAC__uint64)x; + } else if (decoder->private_->has_stream_info) { + if (decoder->private_->stream_info.data.stream_info.min_blocksize == decoder->private_->stream_info.data.stream_info.max_blocksize) { + decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->stream_info.data.stream_info.min_blocksize * (FLAC__uint64)x; + decoder->private_->next_fixed_block_size = decoder->private_->stream_info.data.stream_info.max_blocksize; + } else { + is_unparseable = true; + } + } else if (x == 0) { + decoder->private_->frame.header.number.sample_number = 0; + decoder->private_->next_fixed_block_size = decoder->private_->frame.header.blocksize; + } else { + /* can only get here if the stream has invalid frame numbering and no STREAMINFO, so assume it's not the last (possibly short) frame */ + decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->frame.header.blocksize * (FLAC__uint64)x; + } + } + + if (is_unparseable) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + + return true; +} + +FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode) { + FLAC__uint32 x; + FLAC__bool wasted_bits; + uint32_t i; + + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) { /* MAGIC NUMBER */ + return false; /* read_callback_ sets the state for us */ + } + + wasted_bits = (x & 1); + x &= 0xfe; + + if (wasted_bits) { + uint32_t u; + if (!FLAC__bitreader_read_unary_unsigned(decoder->private_->input, &u)) { + return false; /* read_callback_ sets the state for us */ + } + decoder->private_->frame.subframes[channel].wasted_bits = u + 1; + if (decoder->private_->frame.subframes[channel].wasted_bits >= bps) { + return false; + } + bps -= decoder->private_->frame.subframes[channel].wasted_bits; + } else { + decoder->private_->frame.subframes[channel].wasted_bits = 0; + } + + /* + Lots of magic numbers here + */ + if (x & 0x80) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } else if (x == 0) { + if (!read_subframe_constant_(decoder, channel, bps, do_full_decode)) { + return false; + } + } else if (x == 2) { + if (!read_subframe_verbatim_(decoder, channel, bps, do_full_decode)) { + return false; + } + } else if (x < 16) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } else if (x <= 24) { + if (!read_subframe_fixed_(decoder, channel, bps, (x >> 1) & 7, do_full_decode)) { + return false; + } + if (decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) { /* means bad sync or got corruption */ + return true; + } + } else if (x < 64) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } else { + if (!read_subframe_lpc_(decoder, channel, bps, ((x >> 1) & 31) + 1, do_full_decode)) { + return false; + } + if (decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) { /* means bad sync or got corruption */ + return true; + } + } + + if (wasted_bits && do_full_decode) { + x = decoder->private_->frame.subframes[channel].wasted_bits; + for (i = 0; i < decoder->private_->frame.header.blocksize; i++) { + uint32_t val = decoder->private_->output[channel][i]; + decoder->private_->output[channel][i] = (val << x); + } + } + + return true; +} + +FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode) { + FLAC__Subframe_Constant *subframe = &decoder->private_->frame.subframes[channel].data.constant; + FLAC__int32 x; + uint32_t i; + FLAC__int32 *output = decoder->private_->output[channel]; + + decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_CONSTANT; + + if (!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps)) { + return false; /* read_callback_ sets the state for us */ + } + + subframe->value = x; + + /* decode the subframe */ + if (do_full_decode) { + for (i = 0; i < decoder->private_->frame.header.blocksize; i++) { + output[i] = x; + } + } + + return true; +} + +FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, const uint32_t order, FLAC__bool do_full_decode) { + FLAC__Subframe_Fixed *subframe = &decoder->private_->frame.subframes[channel].data.fixed; + FLAC__int32 i32; + FLAC__uint32 u32; + uint32_t u; + + decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_FIXED; + + subframe->residual = decoder->private_->residual[channel]; + subframe->order = order; + + /* read warm-up samples */ + for (u = 0; u < order; u++) { + if (!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, bps)) { + return false; /* read_callback_ sets the state for us */ + } + subframe->warmup[u] = i32; + } + + /* read entropy coding method info */ + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + subframe->entropy_coding_method.type = (FLAC__EntropyCodingMethodType)u32; + switch (subframe->entropy_coding_method.type) { + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + if (decoder->private_->frame.header.blocksize >> u32 < order) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + subframe->entropy_coding_method.data.partitioned_rice.order = u32; + subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel]; + break; + default: + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + + /* read residual */ + switch (subframe->entropy_coding_method.type) { + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: + if (!read_residual_partitioned_rice_(decoder, order, subframe->entropy_coding_method.data.partitioned_rice.order, &decoder->private_->partitioned_rice_contents[channel], decoder->private_->residual[channel], /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2)) { + return false; + } + break; + default: + FLAC__ASSERT(0); + } + + /* decode the subframe */ + if (do_full_decode) { + memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order); + FLAC__fixed_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize - order, order, decoder->private_->output[channel] + order); + } + + return true; +} + +FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, const uint32_t order, FLAC__bool do_full_decode) { + FLAC__Subframe_LPC *subframe = &decoder->private_->frame.subframes[channel].data.lpc; + FLAC__int32 i32; + FLAC__uint32 u32; + uint32_t u; + + decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_LPC; + + subframe->residual = decoder->private_->residual[channel]; + subframe->order = order; + + /* read warm-up samples */ + for (u = 0; u < order; u++) { + if (!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, bps)) { + return false; /* read_callback_ sets the state for us */ + } + subframe->warmup[u] = i32; + } + + /* read qlp coeff precision */ + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + if (u32 == (1u << FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN) - 1) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + subframe->qlp_coeff_precision = u32 + 1; + + /* read qlp shift */ + if (!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + if (i32 < 0) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + subframe->quantization_level = i32; + + /* read quantized lp coefficiencts */ + for (u = 0; u < order; u++) { + if (!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, subframe->qlp_coeff_precision)) { + return false; /* read_callback_ sets the state for us */ + } + subframe->qlp_coeff[u] = i32; + } + + /* read entropy coding method info */ + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + subframe->entropy_coding_method.type = (FLAC__EntropyCodingMethodType)u32; + switch (subframe->entropy_coding_method.type) { + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + if (decoder->private_->frame.header.blocksize >> u32 < order) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + subframe->entropy_coding_method.data.partitioned_rice.order = u32; + subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel]; + break; + default: + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + + /* read residual */ + switch (subframe->entropy_coding_method.type) { + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: + if (!read_residual_partitioned_rice_(decoder, order, subframe->entropy_coding_method.data.partitioned_rice.order, &decoder->private_->partitioned_rice_contents[channel], decoder->private_->residual[channel], /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2)) { + return false; + } + break; + default: + FLAC__ASSERT(0); + } + + /* decode the subframe */ + if (do_full_decode) { + memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order); + if (bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32) + if (bps <= 16 && subframe->qlp_coeff_precision <= 16) { + decoder->private_->local_lpc_restore_signal_16bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize - order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel] + order); + } else { + decoder->private_->local_lpc_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize - order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel] + order); + } else { + decoder->private_->local_lpc_restore_signal_64bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize - order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel] + order); + } + } + + return true; +} + +FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode) { + FLAC__Subframe_Verbatim *subframe = &decoder->private_->frame.subframes[channel].data.verbatim; + FLAC__int32 x, *residual = decoder->private_->residual[channel]; + uint32_t i; + + decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_VERBATIM; + + subframe->data = residual; + + for (i = 0; i < decoder->private_->frame.header.blocksize; i++) { + if (!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps)) { + return false; /* read_callback_ sets the state for us */ + } + residual[i] = x; + } + + /* decode the subframe */ + if (do_full_decode) { + memcpy(decoder->private_->output[channel], subframe->data, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize); + } + + return true; +} + +FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, uint32_t predictor_order, uint32_t partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual, FLAC__bool is_extended) { + FLAC__uint32 rice_parameter; + int i; + uint32_t partition, sample, u; + const uint32_t partitions = 1u << partition_order; + const uint32_t partition_samples = partition_order > 0 ? decoder->private_->frame.header.blocksize >> partition_order : decoder->private_->frame.header.blocksize - predictor_order; + const uint32_t plen = is_extended ? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; + const uint32_t pesc = is_extended ? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; + + /* invalid predictor and partition orders mush be handled in the callers */ + FLAC__ASSERT(partition_order > 0 ? partition_samples >= predictor_order : decoder->private_->frame.header.blocksize >= predictor_order); + + if (!FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, flac_max(6u, partition_order))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + + sample = 0; + for (partition = 0; partition < partitions; partition++) { + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &rice_parameter, plen)) { + return false; /* read_callback_ sets the state for us */ + } + partitioned_rice_contents->parameters[partition] = rice_parameter; + if (rice_parameter < pesc) { + partitioned_rice_contents->raw_bits[partition] = 0; + u = (partition_order == 0 || partition > 0) ? partition_samples : partition_samples - predictor_order; + if (!FLAC__bitreader_read_rice_signed_block(decoder->private_->input, (int *)(residual + sample), u, rice_parameter)) { + return false; /* read_callback_ sets the state for us */ + } + sample += u; + } else { + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN)) { + return false; /* read_callback_ sets the state for us */ + } + partitioned_rice_contents->raw_bits[partition] = rice_parameter; + for (u = (partition_order == 0 || partition > 0) ? 0 : predictor_order; u < partition_samples; u++, sample++) { + if (!FLAC__bitreader_read_raw_int32(decoder->private_->input, (FLAC__int32 *)&i, rice_parameter)) { + return false; /* read_callback_ sets the state for us */ + } + residual[sample] = i; + } + } + } + + return true; +} + +FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder) { + if (!FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)) { + FLAC__uint32 zero = 0; + if (!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &zero, FLAC__bitreader_bits_left_for_byte_alignment(decoder->private_->input))) { + return false; /* read_callback_ sets the state for us */ + } + if (zero != 0) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + } + } + return true; +} + +FLAC__bool read_callback_(FLAC__byte buffer[], size_t *bytes, void *client_data) { + FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder *)client_data; + + if ( #if FLAC__HAS_OGG - /* see [1] HACK NOTE below for why we don't call the eof_callback when decoding Ogg FLAC */ - !decoder->private_->is_ogg && + /* see [1] HACK NOTE below for why we don't call the eof_callback when decoding Ogg FLAC */ + !decoder->private_->is_ogg && #endif - decoder->private_->eof_callback && decoder->private_->eof_callback(decoder, decoder->private_->client_data) - ) { - *bytes = 0; - decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM; - return false; - } - else if(*bytes > 0) { - /* While seeking, it is possible for our seek to land in the - * middle of audio data that looks exactly like a frame header - * from a future version of an encoder. When that happens, our - * error callback will get an - * FLAC__STREAM_DECODER_UNPARSEABLE_STREAM and increment its - * unparseable_frame_count. But there is a remote possibility - * that it is properly synced at such a "future-codec frame", - * so to make sure, we wait to see many "unparseable" errors in - * a row before bailing out. - */ - if(decoder->private_->is_seeking && decoder->private_->unparseable_frame_count > 20) { - decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED; - return false; - } - else { - const FLAC__StreamDecoderReadStatus status = + decoder->private_->eof_callback && decoder->private_->eof_callback(decoder, decoder->private_->client_data) + ) { + *bytes = 0; + decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM; + return false; + } else if (*bytes > 0) { + /* While seeking, it is possible for our seek to land in the + middle of audio data that looks exactly like a frame header + from a future version of an encoder. When that happens, our + error callback will get an + FLAC__STREAM_DECODER_UNPARSEABLE_STREAM and increment its + unparseable_frame_count. But there is a remote possibility + that it is properly synced at such a "future-codec frame", + so to make sure, we wait to see many "unparsable" errors in + a row before bailing out. + */ + if (decoder->private_->is_seeking && decoder->private_->unparseable_frame_count > 20) { + decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED; + return false; + } else { + const FLAC__StreamDecoderReadStatus status = #if FLAC__HAS_OGG - decoder->private_->is_ogg? - read_callback_ogg_aspect_(decoder, buffer, bytes) : + decoder->private_->is_ogg ? + read_callback_ogg_aspect_(decoder, buffer, bytes) : #endif - decoder->private_->read_callback(decoder, buffer, bytes, decoder->private_->client_data) - ; - if(status == FLAC__STREAM_DECODER_READ_STATUS_ABORT) { - decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED; - return false; - } - else if(*bytes == 0) { - if( - status == FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM || - ( + decoder->private_->read_callback(decoder, buffer, bytes, decoder->private_->client_data) + ; + if (status == FLAC__STREAM_DECODER_READ_STATUS_ABORT) { + decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED; + return false; + } else if (*bytes == 0) { + if ( + status == FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM || + ( #if FLAC__HAS_OGG - /* see [1] HACK NOTE below for why we don't call the eof_callback when decoding Ogg FLAC */ - !decoder->private_->is_ogg && + /* see [1] HACK NOTE below for why we don't call the eof_callback when decoding Ogg FLAC */ + !decoder->private_->is_ogg && #endif - decoder->private_->eof_callback && decoder->private_->eof_callback(decoder, decoder->private_->client_data) - ) - ) { - decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM; - return false; - } - else - return true; - } - else - return true; - } - } - else { - /* abort to avoid a deadlock */ - decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED; - return false; - } - /* [1] @@@ HACK NOTE: The end-of-stream checking has to be hacked around - * for Ogg FLAC. This is because the ogg decoder aspect can lose sync - * and at the same time hit the end of the stream (for example, seeking - * to a point that is after the beginning of the last Ogg page). There - * is no way to report an Ogg sync loss through the callbacks (see note - * in read_callback_ogg_aspect_()) so it returns CONTINUE with *bytes==0. - * So to keep the decoder from stopping at this point we gate the call - * to the eof_callback and let the Ogg decoder aspect set the - * end-of-stream state when it is needed. - */ + decoder->private_->eof_callback && decoder->private_->eof_callback(decoder, decoder->private_->client_data) + ) + ) { + decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM; + return false; + } else { + return true; + } + } else { + return true; + } + } + } else { + /* abort to avoid a deadlock */ + decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED; + return false; + } + /* [1] @@@ HACK NOTE: The end-of-stream checking has to be hacked around + for Ogg FLAC. This is because the ogg decoder aspect can lose sync + and at the same time hit the end of the stream (for example, seeking + to a point that is after the beginning of the last Ogg page). There + is no way to report an Ogg sync loss through the callbacks (see note + in read_callback_ogg_aspect_()) so it returns CONTINUE with *bytes==0. + So to keep the decoder from stopping at this point we gate the call + to the eof_callback and let the Ogg decoder aspect set the + end-of-stream state when it is needed. + */ } #if FLAC__HAS_OGG -FLAC__StreamDecoderReadStatus read_callback_ogg_aspect_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes) -{ - switch(FLAC__ogg_decoder_aspect_read_callback_wrapper(&decoder->protected_->ogg_decoder_aspect, buffer, bytes, read_callback_proxy_, decoder, decoder->private_->client_data)) { - case FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK: - return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; - /* we don't really have a way to handle lost sync via read - * callback so we'll let it pass and let the underlying - * FLAC decoder catch the error - */ - case FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC: - return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; - case FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM: - return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; - case FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC: - case FLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION: - case FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT: - case FLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR: - case FLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR: - return FLAC__STREAM_DECODER_READ_STATUS_ABORT; - default: - FLAC__ASSERT(0); - /* double protection */ - return FLAC__STREAM_DECODER_READ_STATUS_ABORT; - } -} - -FLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) -{ - FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder*)void_decoder; - - switch(decoder->private_->read_callback(decoder, buffer, bytes, client_data)) { - case FLAC__STREAM_DECODER_READ_STATUS_CONTINUE: - return FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK; - case FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM: - return FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM; - case FLAC__STREAM_DECODER_READ_STATUS_ABORT: - return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT; - default: - /* double protection: */ - FLAC__ASSERT(0); - return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT; - } +FLAC__StreamDecoderReadStatus read_callback_ogg_aspect_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes) { + switch (FLAC__ogg_decoder_aspect_read_callback_wrapper(&decoder->protected_->ogg_decoder_aspect, buffer, bytes, read_callback_proxy_, decoder, decoder->private_->client_data)) { + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK: + return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + /* we don't really have a way to handle lost sync via read + callback so we'll let it pass and let the underlying + FLAC decoder catch the error + */ + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC: + return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM: + return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC: + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION: + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT: + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR: + case FLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR: + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + default: + FLAC__ASSERT(0); + /* double protection */ + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + } +} + +FLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) { + FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder*)void_decoder; + + switch (decoder->private_->read_callback(decoder, buffer, bytes, client_data)) { + case FLAC__STREAM_DECODER_READ_STATUS_CONTINUE: + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK; + case FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM: + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM; + case FLAC__STREAM_DECODER_READ_STATUS_ABORT: + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT; + default: + /* double protection: */ + FLAC__ASSERT(0); + return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT; + } } #endif -FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[]) -{ - if(decoder->private_->is_seeking) { - FLAC__uint64 this_frame_sample = frame->header.number.sample_number; - FLAC__uint64 next_frame_sample = this_frame_sample + (FLAC__uint64)frame->header.blocksize; - FLAC__uint64 target_sample = decoder->private_->target_sample; +FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[]) { + if (decoder->private_->is_seeking) { + FLAC__uint64 this_frame_sample = frame->header.number.sample_number; + FLAC__uint64 next_frame_sample = this_frame_sample + (FLAC__uint64)frame->header.blocksize; + FLAC__uint64 target_sample = decoder->private_->target_sample; - FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); + FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); #if FLAC__HAS_OGG - decoder->private_->got_a_frame = true; + decoder->private_->got_a_frame = true; #endif - decoder->private_->last_frame = *frame; /* save the frame */ - if(this_frame_sample <= target_sample && target_sample < next_frame_sample) { /* we hit our target frame */ - uint32_t delta = (uint32_t)(target_sample - this_frame_sample); - /* kick out of seek mode */ - decoder->private_->is_seeking = false; - /* shift out the samples before target_sample */ - if(delta > 0) { - uint32_t channel; - const FLAC__int32 *newbuffer[FLAC__MAX_CHANNELS]; - for(channel = 0; channel < frame->header.channels; channel++) - newbuffer[channel] = buffer[channel] + delta; - decoder->private_->last_frame.header.blocksize -= delta; - decoder->private_->last_frame.header.number.sample_number += (FLAC__uint64)delta; - /* write the relevant samples */ - return decoder->private_->write_callback(decoder, &decoder->private_->last_frame, newbuffer, decoder->private_->client_data); - } - else { - /* write the relevant samples */ - return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data); - } - } - else { - return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; - } - } - else { - /* - * If we never got STREAMINFO, turn off MD5 checking to save - * cycles since we don't have a sum to compare to anyway - */ - if(!decoder->private_->has_stream_info) - decoder->private_->do_md5_checking = false; - if(decoder->private_->do_md5_checking) { - if(!FLAC__MD5Accumulate(&decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8)) - return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; - } - return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data); - } -} - -void send_error_to_client_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status) -{ - if(!decoder->private_->is_seeking) - decoder->private_->error_callback(decoder, status, decoder->private_->client_data); - else if(status == FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM) - decoder->private_->unparseable_frame_count++; -} - -FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample) -{ - FLAC__uint64 first_frame_offset = decoder->private_->first_frame_offset, lower_bound, upper_bound, lower_bound_sample, upper_bound_sample, this_frame_sample; - FLAC__int64 pos = -1; - int i; - uint32_t approx_bytes_per_frame; - FLAC__bool first_seek = true; - const FLAC__uint64 total_samples = FLAC__stream_decoder_get_total_samples(decoder); - const uint32_t min_blocksize = decoder->private_->stream_info.data.stream_info.min_blocksize; - const uint32_t max_blocksize = decoder->private_->stream_info.data.stream_info.max_blocksize; - const uint32_t max_framesize = decoder->private_->stream_info.data.stream_info.max_framesize; - const uint32_t min_framesize = decoder->private_->stream_info.data.stream_info.min_framesize; - /* take these from the current frame in case they've changed mid-stream */ - uint32_t channels = FLAC__stream_decoder_get_channels(decoder); - uint32_t bps = FLAC__stream_decoder_get_bits_per_sample(decoder); - const FLAC__StreamMetadata_SeekTable *seek_table = decoder->private_->has_seek_table? &decoder->private_->seek_table.data.seek_table : 0; - - /* use values from stream info if we didn't decode a frame */ - if(channels == 0) - channels = decoder->private_->stream_info.data.stream_info.channels; - if(bps == 0) - bps = decoder->private_->stream_info.data.stream_info.bits_per_sample; - - /* we are just guessing here */ - if(max_framesize > 0) - approx_bytes_per_frame = (max_framesize + min_framesize) / 2 + 1; - /* - * Check if it's a known fixed-blocksize stream. Note that though - * the spec doesn't allow zeroes in the STREAMINFO block, we may - * never get a STREAMINFO block when decoding so the value of - * min_blocksize might be zero. - */ - else if(min_blocksize == max_blocksize && min_blocksize > 0) { - /* note there are no () around 'bps/8' to keep precision up since it's an integer calculation */ - approx_bytes_per_frame = min_blocksize * channels * bps/8 + 64; - } - else - approx_bytes_per_frame = 4096 * channels * bps/8 + 64; - - /* - * First, we set an upper and lower bound on where in the - * stream we will search. For now we assume the worst case - * scenario, which is our best guess at the beginning of - * the first frame and end of the stream. - */ - lower_bound = first_frame_offset; - lower_bound_sample = 0; - upper_bound = stream_length; - upper_bound_sample = total_samples > 0 ? total_samples : target_sample /*estimate it*/; - - /* - * Now we refine the bounds if we have a seektable with - * suitable points. Note that according to the spec they - * must be ordered by ascending sample number. - * - * Note: to protect against invalid seek tables we will ignore points - * that have frame_samples==0 or sample_number>=total_samples - */ - if(seek_table) { - FLAC__uint64 new_lower_bound = lower_bound; - FLAC__uint64 new_upper_bound = upper_bound; - FLAC__uint64 new_lower_bound_sample = lower_bound_sample; - FLAC__uint64 new_upper_bound_sample = upper_bound_sample; - - /* find the closest seek point <= target_sample, if it exists */ - for(i = (int)seek_table->num_points - 1; i >= 0; i--) { - if( - seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && - seek_table->points[i].frame_samples > 0 && /* defense against bad seekpoints */ - (total_samples <= 0 || seek_table->points[i].sample_number < total_samples) && /* defense against bad seekpoints */ - seek_table->points[i].sample_number <= target_sample - ) - break; - } - if(i >= 0) { /* i.e. we found a suitable seek point... */ - new_lower_bound = first_frame_offset + seek_table->points[i].stream_offset; - new_lower_bound_sample = seek_table->points[i].sample_number; - } - - /* find the closest seek point > target_sample, if it exists */ - for(i = 0; i < (int)seek_table->num_points; i++) { - if( - seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && - seek_table->points[i].frame_samples > 0 && /* defense against bad seekpoints */ - (total_samples <= 0 || seek_table->points[i].sample_number < total_samples) && /* defense against bad seekpoints */ - seek_table->points[i].sample_number > target_sample - ) - break; - } - if(i < (int)seek_table->num_points) { /* i.e. we found a suitable seek point... */ - new_upper_bound = first_frame_offset + seek_table->points[i].stream_offset; - new_upper_bound_sample = seek_table->points[i].sample_number; - } - /* final protection against unsorted seek tables; keep original values if bogus */ - if(new_upper_bound >= new_lower_bound) { - lower_bound = new_lower_bound; - upper_bound = new_upper_bound; - lower_bound_sample = new_lower_bound_sample; - upper_bound_sample = new_upper_bound_sample; - } - } - - FLAC__ASSERT(upper_bound_sample >= lower_bound_sample); - /* there are 2 insidious ways that the following equality occurs, which - * we need to fix: - * 1) total_samples is 0 (unknown) and target_sample is 0 - * 2) total_samples is 0 (unknown) and target_sample happens to be - * exactly equal to the last seek point in the seek table; this - * means there is no seek point above it, and upper_bound_samples - * remains equal to the estimate (of target_samples) we made above - * in either case it does not hurt to move upper_bound_sample up by 1 - */ - if(upper_bound_sample == lower_bound_sample) - upper_bound_sample++; - - decoder->private_->target_sample = target_sample; - while(1) { - /* check if the bounds are still ok */ - if (lower_bound_sample >= upper_bound_sample || lower_bound > upper_bound) { - decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; - return false; - } + decoder->private_->last_frame = *frame; /* save the frame */ + if (this_frame_sample <= target_sample && target_sample < next_frame_sample) { /* we hit our target frame */ + uint32_t delta = (uint32_t)(target_sample - this_frame_sample); + /* kick out of seek mode */ + decoder->private_->is_seeking = false; + /* shift out the samples before target_sample */ + if (delta > 0) { + uint32_t channel; + const FLAC__int32 *newbuffer[FLAC__MAX_CHANNELS]; + for (channel = 0; channel < frame->header.channels; channel++) { + newbuffer[channel] = buffer[channel] + delta; + } + decoder->private_->last_frame.header.blocksize -= delta; + decoder->private_->last_frame.header.number.sample_number += (FLAC__uint64)delta; + /* write the relevant samples */ + return decoder->private_->write_callback(decoder, &decoder->private_->last_frame, newbuffer, decoder->private_->client_data); + } else { + /* write the relevant samples */ + return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data); + } + } else { + return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; + } + } else { + /* + If we never got STREAMINFO, turn off MD5 checking to save + cycles since we don't have a sum to compare to anyway + */ + if (!decoder->private_->has_stream_info) { + decoder->private_->do_md5_checking = false; + } + if (decoder->private_->do_md5_checking) { + if (!FLAC__MD5Accumulate(&decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample + 7) / 8)) { + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + } + } + return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data); + } +} + +void send_error_to_client_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status) { + if (!decoder->private_->is_seeking) { + decoder->private_->error_callback(decoder, status, decoder->private_->client_data); + } else if (status == FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM) { + decoder->private_->unparseable_frame_count++; + } +} + +FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample) { + FLAC__uint64 first_frame_offset = decoder->private_->first_frame_offset, lower_bound, upper_bound, lower_bound_sample, upper_bound_sample, this_frame_sample; + FLAC__int64 pos = -1; + int i; + uint32_t approx_bytes_per_frame; + FLAC__bool first_seek = true; + const FLAC__uint64 total_samples = FLAC__stream_decoder_get_total_samples(decoder); + const uint32_t min_blocksize = decoder->private_->stream_info.data.stream_info.min_blocksize; + const uint32_t max_blocksize = decoder->private_->stream_info.data.stream_info.max_blocksize; + const uint32_t max_framesize = decoder->private_->stream_info.data.stream_info.max_framesize; + const uint32_t min_framesize = decoder->private_->stream_info.data.stream_info.min_framesize; + /* take these from the current frame in case they've changed mid-stream */ + uint32_t channels = FLAC__stream_decoder_get_channels(decoder); + uint32_t bps = FLAC__stream_decoder_get_bits_per_sample(decoder); + const FLAC__StreamMetadata_SeekTable *seek_table = decoder->private_->has_seek_table ? &decoder->private_->seek_table.data.seek_table : 0; + + /* use values from stream info if we didn't decode a frame */ + if (channels == 0) { + channels = decoder->private_->stream_info.data.stream_info.channels; + } + if (bps == 0) { + bps = decoder->private_->stream_info.data.stream_info.bits_per_sample; + } + + /* we are just guessing here */ + if (max_framesize > 0) { + approx_bytes_per_frame = (max_framesize + min_framesize) / 2 + 1; + } + /* + Check if it's a known fixed-blocksize stream. Note that though + the spec doesn't allow zeroes in the STREAMINFO block, we may + never get a STREAMINFO block when decoding so the value of + min_blocksize might be zero. + */ + else if (min_blocksize == max_blocksize && min_blocksize > 0) { + /* note there are no () around 'bps/8' to keep precision up since it's an integer calculation */ + approx_bytes_per_frame = min_blocksize * channels * bps / 8 + 64; + } else { + approx_bytes_per_frame = 4096 * channels * bps / 8 + 64; + } + + /* + First, we set an upper and lower bound on where in the + stream we will search. For now we assume the worst case + scenario, which is our best guess at the beginning of + the first frame and end of the stream. + */ + lower_bound = first_frame_offset; + lower_bound_sample = 0; + upper_bound = stream_length; + upper_bound_sample = total_samples > 0 ? total_samples : target_sample /*estimate it*/; + + /* + Now we refine the bounds if we have a seektable with + suitable points. Note that according to the spec they + must be ordered by ascending sample number. + + Note: to protect against invalid seek tables we will ignore points + that have frame_samples==0 or sample_number>=total_samples + */ + if (seek_table) { + FLAC__uint64 new_lower_bound = lower_bound; + FLAC__uint64 new_upper_bound = upper_bound; + FLAC__uint64 new_lower_bound_sample = lower_bound_sample; + FLAC__uint64 new_upper_bound_sample = upper_bound_sample; + + /* find the closest seek point <= target_sample, if it exists */ + for (i = (int)seek_table->num_points - 1; i >= 0; i--) { + if ( + seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && + seek_table->points[i].frame_samples > 0 && /* defense against bad seekpoints */ + (total_samples <= 0 || seek_table->points[i].sample_number < total_samples) && /* defense against bad seekpoints */ + seek_table->points[i].sample_number <= target_sample + ) { + break; + } + } + if (i >= 0) { /* i.e. we found a suitable seek point... */ + new_lower_bound = first_frame_offset + seek_table->points[i].stream_offset; + new_lower_bound_sample = seek_table->points[i].sample_number; + } + + /* find the closest seek point > target_sample, if it exists */ + for (i = 0; i < (int)seek_table->num_points; i++) { + if ( + seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && + seek_table->points[i].frame_samples > 0 && /* defense against bad seekpoints */ + (total_samples <= 0 || seek_table->points[i].sample_number < total_samples) && /* defense against bad seekpoints */ + seek_table->points[i].sample_number > target_sample + ) { + break; + } + } + if (i < (int)seek_table->num_points) { /* i.e. we found a suitable seek point... */ + new_upper_bound = first_frame_offset + seek_table->points[i].stream_offset; + new_upper_bound_sample = seek_table->points[i].sample_number; + } + /* final protection against unsorted seek tables; keep original values if bogus */ + if (new_upper_bound >= new_lower_bound) { + lower_bound = new_lower_bound; + upper_bound = new_upper_bound; + lower_bound_sample = new_lower_bound_sample; + upper_bound_sample = new_upper_bound_sample; + } + } + + FLAC__ASSERT(upper_bound_sample >= lower_bound_sample); + /* there are 2 insidious ways that the following equality occurs, which + we need to fix: + 1) total_samples is 0 (unknown) and target_sample is 0 + 2) total_samples is 0 (unknown) and target_sample happens to be + exactly equal to the last seek point in the seek table; this + means there is no seek point above it, and upper_bound_samples + remains equal to the estimate (of target_samples) we made above + in either case it does not hurt to move upper_bound_sample up by 1 + */ + if (upper_bound_sample == lower_bound_sample) { + upper_bound_sample++; + } + + decoder->private_->target_sample = target_sample; + while (1) { + /* check if the bounds are still ok */ + if (lower_bound_sample >= upper_bound_sample || lower_bound > upper_bound) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } #ifndef FLAC__INTEGER_ONLY_LIBRARY - pos = (FLAC__int64)lower_bound + (FLAC__int64)((double)(target_sample - lower_bound_sample) / (double)(upper_bound_sample - lower_bound_sample) * (double)(upper_bound - lower_bound)) - approx_bytes_per_frame; + pos = (FLAC__int64)lower_bound + (FLAC__int64)((double)(target_sample - lower_bound_sample) / (double)(upper_bound_sample - lower_bound_sample) * (double)(upper_bound - lower_bound)) - approx_bytes_per_frame; #else - /* a little less accurate: */ - if(upper_bound - lower_bound < 0xffffffff) - pos = (FLAC__int64)lower_bound + (FLAC__int64)(((target_sample - lower_bound_sample) * (upper_bound - lower_bound)) / (upper_bound_sample - lower_bound_sample)) - approx_bytes_per_frame; - else /* @@@ WATCHOUT, ~2TB limit */ - pos = (FLAC__int64)lower_bound + (FLAC__int64)((((target_sample - lower_bound_sample)>>8) * ((upper_bound - lower_bound)>>8)) / ((upper_bound_sample - lower_bound_sample)>>16)) - approx_bytes_per_frame; + /* a little less accurate: */ + if (upper_bound - lower_bound < 0xffffffff) { + pos = (FLAC__int64)lower_bound + (FLAC__int64)(((target_sample - lower_bound_sample) * (upper_bound - lower_bound)) / (upper_bound_sample - lower_bound_sample)) - approx_bytes_per_frame; + } else { /* @@@ WATCHOUT, ~2TB limit */ + pos = (FLAC__int64)lower_bound + (FLAC__int64)((((target_sample - lower_bound_sample) >> 8) * ((upper_bound - lower_bound) >> 8)) / ((upper_bound_sample - lower_bound_sample) >> 16)) - approx_bytes_per_frame; + } #endif - if(pos >= (FLAC__int64)upper_bound) - pos = (FLAC__int64)upper_bound - 1; - if(pos < (FLAC__int64)lower_bound) - pos = (FLAC__int64)lower_bound; - if(decoder->private_->seek_callback(decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__STREAM_DECODER_SEEK_STATUS_OK) { - decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; - return false; - } - if(!FLAC__stream_decoder_flush(decoder)) { - /* above call sets the state for us */ - return false; - } - /* Now we need to get a frame. First we need to reset our - * unparseable_frame_count; if we get too many unparseable - * frames in a row, the read callback will return - * FLAC__STREAM_DECODER_READ_STATUS_ABORT, causing - * FLAC__stream_decoder_process_single() to return false. - */ - decoder->private_->unparseable_frame_count = 0; - if(!FLAC__stream_decoder_process_single(decoder) || - decoder->protected_->state == FLAC__STREAM_DECODER_ABORTED) { - decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; - return false; - } - /* our write callback will change the state when it gets to the target frame */ - /* actually, we could have got_a_frame if our decoder is at FLAC__STREAM_DECODER_END_OF_STREAM so we need to check for that also */ + if (pos >= (FLAC__int64)upper_bound) { + pos = (FLAC__int64)upper_bound - 1; + } + if (pos < (FLAC__int64)lower_bound) { + pos = (FLAC__int64)lower_bound; + } + if (decoder->private_->seek_callback(decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__STREAM_DECODER_SEEK_STATUS_OK) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + if (!FLAC__stream_decoder_flush(decoder)) { + /* above call sets the state for us */ + return false; + } + /* Now we need to get a frame. First we need to reset our + unparseable_frame_count; if we get too many unparsable + frames in a row, the read callback will return + FLAC__STREAM_DECODER_READ_STATUS_ABORT, causing + FLAC__stream_decoder_process_single() to return false. + */ + decoder->private_->unparseable_frame_count = 0; + if (!FLAC__stream_decoder_process_single(decoder) || + decoder->protected_->state == FLAC__STREAM_DECODER_ABORTED) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + /* our write callback will change the state when it gets to the target frame */ + /* actually, we could have got_a_frame if our decoder is at FLAC__STREAM_DECODER_END_OF_STREAM so we need to check for that also */ #if 0 - /*@@@@@@ used to be the following; not clear if the check for end of stream is needed anymore */ - if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING && decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM) - break; + /*@@@@@@ used to be the following; not clear if the check for end of stream is needed anymore */ + if (decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING && decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM) { + break; + } #endif - if(!decoder->private_->is_seeking) - break; - - FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); - this_frame_sample = decoder->private_->last_frame.header.number.sample_number; - - if (0 == decoder->private_->samples_decoded || (this_frame_sample + decoder->private_->last_frame.header.blocksize >= upper_bound_sample && !first_seek)) { - if (pos == (FLAC__int64)lower_bound) { - /* can't move back any more than the first frame, something is fatally wrong */ - decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; - return false; - } - /* our last move backwards wasn't big enough, try again */ - approx_bytes_per_frame = approx_bytes_per_frame? approx_bytes_per_frame * 2 : 16; - continue; - } - /* allow one seek over upper bound, so we can get a correct upper_bound_sample for streams with unknown total_samples */ - first_seek = false; - - /* make sure we are not seeking in corrupted stream */ - if (this_frame_sample < lower_bound_sample) { - decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; - return false; - } - - /* we need to narrow the search */ - if(target_sample < this_frame_sample) { - upper_bound_sample = this_frame_sample + decoder->private_->last_frame.header.blocksize; -/*@@@@@@ what will decode position be if at end of stream? */ - if(!FLAC__stream_decoder_get_decode_position(decoder, &upper_bound)) { - decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; - return false; - } - approx_bytes_per_frame = (uint32_t)(2 * (upper_bound - pos) / 3 + 16); - } - else { /* target_sample >= this_frame_sample + this frame's blocksize */ - lower_bound_sample = this_frame_sample + decoder->private_->last_frame.header.blocksize; - if(!FLAC__stream_decoder_get_decode_position(decoder, &lower_bound)) { - decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; - return false; - } - approx_bytes_per_frame = (uint32_t)(2 * (lower_bound - pos) / 3 + 16); - } - } - - return true; + if (!decoder->private_->is_seeking) { + break; + } + + FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); + this_frame_sample = decoder->private_->last_frame.header.number.sample_number; + + if (0 == decoder->private_->samples_decoded || (this_frame_sample + decoder->private_->last_frame.header.blocksize >= upper_bound_sample && !first_seek)) { + if (pos == (FLAC__int64)lower_bound) { + /* can't move back any more than the first frame, something is fatally wrong */ + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + /* our last move backwards wasn't big enough, try again */ + approx_bytes_per_frame = approx_bytes_per_frame ? approx_bytes_per_frame * 2 : 16; + continue; + } + /* allow one seek over upper bound, so we can get a correct upper_bound_sample for streams with unknown total_samples */ + first_seek = false; + + /* make sure we are not seeking in corrupted stream */ + if (this_frame_sample < lower_bound_sample) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + + /* we need to narrow the search */ + if (target_sample < this_frame_sample) { + upper_bound_sample = this_frame_sample + decoder->private_->last_frame.header.blocksize; + /*@@@@@@ what will decode position be if at end of stream? */ + if (!FLAC__stream_decoder_get_decode_position(decoder, &upper_bound)) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + approx_bytes_per_frame = (uint32_t)(2 * (upper_bound - pos) / 3 + 16); + } else { /* target_sample >= this_frame_sample + this frame's blocksize */ + lower_bound_sample = this_frame_sample + decoder->private_->last_frame.header.blocksize; + if (!FLAC__stream_decoder_get_decode_position(decoder, &lower_bound)) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + approx_bytes_per_frame = (uint32_t)(2 * (lower_bound - pos) / 3 + 16); + } + } + + return true; } #if FLAC__HAS_OGG -FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample) -{ - FLAC__uint64 left_pos = 0, right_pos = stream_length; - FLAC__uint64 left_sample = 0, right_sample = FLAC__stream_decoder_get_total_samples(decoder); - FLAC__uint64 this_frame_sample = (FLAC__uint64)0 - 1; - FLAC__uint64 pos = 0; /* only initialized to avoid compiler warning */ - FLAC__bool did_a_seek; - uint32_t iteration = 0; - - /* In the first iterations, we will calculate the target byte position - * by the distance from the target sample to left_sample and - * right_sample (let's call it "proportional search"). After that, we - * will switch to binary search. - */ - uint32_t BINARY_SEARCH_AFTER_ITERATION = 2; - - /* We will switch to a linear search once our current sample is less - * than this number of samples ahead of the target sample - */ - static const FLAC__uint64 LINEAR_SEARCH_WITHIN_SAMPLES = FLAC__MAX_BLOCK_SIZE * 2; - - /* If the total number of samples is unknown, use a large value, and - * force binary search immediately. - */ - if(right_sample == 0) { - right_sample = (FLAC__uint64)(-1); - BINARY_SEARCH_AFTER_ITERATION = 0; - } - - decoder->private_->target_sample = target_sample; - for( ; ; iteration++) { - if (iteration == 0 || this_frame_sample > target_sample || target_sample - this_frame_sample > LINEAR_SEARCH_WITHIN_SAMPLES) { - if (iteration >= BINARY_SEARCH_AFTER_ITERATION) { - pos = (right_pos + left_pos) / 2; - } - else { +FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample) { + FLAC__uint64 left_pos = 0, right_pos = stream_length; + FLAC__uint64 left_sample = 0, right_sample = FLAC__stream_decoder_get_total_samples(decoder); + FLAC__uint64 this_frame_sample = (FLAC__uint64)0 - 1; + FLAC__uint64 pos = 0; /* only initialized to avoid compiler warning */ + FLAC__bool did_a_seek; + uint32_t iteration = 0; + + /* In the first iterations, we will calculate the target byte position + by the distance from the target sample to left_sample and + right_sample (let's call it "proportional search"). After that, we + will switch to binary search. + */ + uint32_t BINARY_SEARCH_AFTER_ITERATION = 2; + + /* We will switch to a linear search once our current sample is less + than this number of samples ahead of the target sample + */ + static const FLAC__uint64 LINEAR_SEARCH_WITHIN_SAMPLES = FLAC__MAX_BLOCK_SIZE * 2; + + /* If the total number of samples is unknown, use a large value, and + force binary search immediately. + */ + if (right_sample == 0) { + right_sample = (FLAC__uint64)(-1); + BINARY_SEARCH_AFTER_ITERATION = 0; + } + + decoder->private_->target_sample = target_sample; + for (; ; iteration++) { + if (iteration == 0 || this_frame_sample > target_sample || target_sample - this_frame_sample > LINEAR_SEARCH_WITHIN_SAMPLES) { + if (iteration >= BINARY_SEARCH_AFTER_ITERATION) { + pos = (right_pos + left_pos) / 2; + } else { #ifndef FLAC__INTEGER_ONLY_LIBRARY - pos = (FLAC__uint64)((double)(target_sample - left_sample) / (double)(right_sample - left_sample) * (double)(right_pos - left_pos)); + pos = (FLAC__uint64)((double)(target_sample - left_sample) / (double)(right_sample - left_sample) * (double)(right_pos - left_pos)); #else - /* a little less accurate: */ - if ((target_sample-left_sample <= 0xffffffff) && (right_pos-left_pos <= 0xffffffff)) - pos = (FLAC__int64)(((target_sample-left_sample) * (right_pos-left_pos)) / (right_sample-left_sample)); - else /* @@@ WATCHOUT, ~2TB limit */ - pos = (FLAC__int64)((((target_sample-left_sample)>>8) * ((right_pos-left_pos)>>8)) / ((right_sample-left_sample)>>16)); + /* a little less accurate: */ + if ((target_sample - left_sample <= 0xffffffff) && (right_pos - left_pos <= 0xffffffff)) { + pos = (FLAC__int64)(((target_sample - left_sample) * (right_pos - left_pos)) / (right_sample - left_sample)); + } else { /* @@@ WATCHOUT, ~2TB limit */ + pos = (FLAC__int64)((((target_sample - left_sample) >> 8) * ((right_pos - left_pos) >> 8)) / ((right_sample - left_sample) >> 16)); + } #endif - /* @@@ TODO: might want to limit pos to some distance - * before EOF, to make sure we land before the last frame, - * thereby getting a this_frame_sample and so having a better - * estimate. - */ - } - - /* physical seek */ - if(decoder->private_->seek_callback((FLAC__StreamDecoder*)decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__STREAM_DECODER_SEEK_STATUS_OK) { - decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; - return false; - } - if(!FLAC__stream_decoder_flush(decoder)) { - /* above call sets the state for us */ - return false; - } - did_a_seek = true; - } - else - did_a_seek = false; - - decoder->private_->got_a_frame = false; - if(!FLAC__stream_decoder_process_single(decoder) || - decoder->protected_->state == FLAC__STREAM_DECODER_ABORTED) { - decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; - return false; - } - if(!decoder->private_->got_a_frame) { - if(did_a_seek) { - /* this can happen if we seek to a point after the last frame; we drop - * to binary search right away in this case to avoid any wasted - * iterations of proportional search. - */ - right_pos = pos; - BINARY_SEARCH_AFTER_ITERATION = 0; - } - else { - /* this can probably only happen if total_samples is unknown and the - * target_sample is past the end of the stream - */ - decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; - return false; - } - } - /* our write callback will change the state when it gets to the target frame */ - else if(!decoder->private_->is_seeking) { - break; - } - else { - this_frame_sample = decoder->private_->last_frame.header.number.sample_number; - FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); - - if (did_a_seek) { - if (this_frame_sample <= target_sample) { - /* The 'equal' case should not happen, since - * FLAC__stream_decoder_process_single() - * should recognize that it has hit the - * target sample and we would exit through - * the 'break' above. - */ - FLAC__ASSERT(this_frame_sample != target_sample); - - left_sample = this_frame_sample; - /* sanity check to avoid infinite loop */ - if (left_pos == pos) { - decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; - return false; - } - left_pos = pos; - } - else { - right_sample = this_frame_sample; - /* sanity check to avoid infinite loop */ - if (right_pos == pos) { - decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; - return false; - } - right_pos = pos; - } - } - } - } - - return true; + /* @@@ TODO: might want to limit pos to some distance + before EOF, to make sure we land before the last frame, + thereby getting a this_frame_sample and so having a better + estimate. + */ + } + + /* physical seek */ + if (decoder->private_->seek_callback((FLAC__StreamDecoder*)decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__STREAM_DECODER_SEEK_STATUS_OK) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + if (!FLAC__stream_decoder_flush(decoder)) { + /* above call sets the state for us */ + return false; + } + did_a_seek = true; + } else { + did_a_seek = false; + } + + decoder->private_->got_a_frame = false; + if (!FLAC__stream_decoder_process_single(decoder) || + decoder->protected_->state == FLAC__STREAM_DECODER_ABORTED) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + if (!decoder->private_->got_a_frame) { + if (did_a_seek) { + /* this can happen if we seek to a point after the last frame; we drop + to binary search right away in this case to avoid any wasted + iterations of proportional search. + */ + right_pos = pos; + BINARY_SEARCH_AFTER_ITERATION = 0; + } else { + /* this can probably only happen if total_samples is unknown and the + target_sample is past the end of the stream + */ + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + } + /* our write callback will change the state when it gets to the target frame */ + else if (!decoder->private_->is_seeking) { + break; + } else { + this_frame_sample = decoder->private_->last_frame.header.number.sample_number; + FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); + + if (did_a_seek) { + if (this_frame_sample <= target_sample) { + /* The 'equal' case should not happen, since + FLAC__stream_decoder_process_single() + should recognize that it has hit the + target sample and we would exit through + the 'break' above. + */ + FLAC__ASSERT(this_frame_sample != target_sample); + + left_sample = this_frame_sample; + /* sanity check to avoid infinite loop */ + if (left_pos == pos) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + left_pos = pos; + } else { + right_sample = this_frame_sample; + /* sanity check to avoid infinite loop */ + if (right_pos == pos) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + right_pos = pos; + } + } + } + } + + return true; } #endif #if 0 -FLAC__StreamDecoderReadStatus file_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) -{ - (void)client_data; - - if(*bytes > 0) { - *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, decoder->private_->file); - if(ferror(decoder->private_->file)) - return FLAC__STREAM_DECODER_READ_STATUS_ABORT; - else if(*bytes == 0) - return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; - else - return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; - } - else - return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */ -} - -FLAC__StreamDecoderSeekStatus file_seek_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) -{ - (void)client_data; - - if(decoder->private_->file == stdin) - return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; - else if(fseeko(decoder->private_->file, (FLAC__off_t)absolute_byte_offset, SEEK_SET) < 0) - return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; - else - return FLAC__STREAM_DECODER_SEEK_STATUS_OK; -} - -FLAC__StreamDecoderTellStatus file_tell_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) -{ - FLAC__off_t pos; - (void)client_data; - - if(decoder->private_->file == stdin) - return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED; - else if((pos = ftello(decoder->private_->file)) < 0) - return FLAC__STREAM_DECODER_TELL_STATUS_ERROR; - else { - *absolute_byte_offset = (FLAC__uint64)pos; - return FLAC__STREAM_DECODER_TELL_STATUS_OK; - } -} - -FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) -{ - struct flac_stat_s filestats; - (void)client_data; - - if(decoder->private_->file == stdin) - return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED; - else if(flac_fstat(fileno(decoder->private_->file), &filestats) != 0) - return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR; - else { - *stream_length = (FLAC__uint64)filestats.st_size; - return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; - } -} - -FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data) -{ - (void)client_data; - - return feof(decoder->private_->file)? true : false; +FLAC__StreamDecoderReadStatus file_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) { + (void)client_data; + + if (*bytes > 0) { + *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, decoder->private_->file); + if (ferror(decoder->private_->file)) { + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + } else if (*bytes == 0) { + return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; + } else { + return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + } + } else { + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */ + } +} + +FLAC__StreamDecoderSeekStatus file_seek_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) { + (void)client_data; + + if (decoder->private_->file == stdin) { + return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; + } else if (fseeko(decoder->private_->file, (FLAC__off_t)absolute_byte_offset, SEEK_SET) < 0) { + return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; + } else { + return FLAC__STREAM_DECODER_SEEK_STATUS_OK; + } +} + +FLAC__StreamDecoderTellStatus file_tell_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) { + FLAC__off_t pos; + (void)client_data; + + if (decoder->private_->file == stdin) { + return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED; + } else if ((pos = ftello(decoder->private_->file)) < 0) { + return FLAC__STREAM_DECODER_TELL_STATUS_ERROR; + } else { + *absolute_byte_offset = (FLAC__uint64)pos; + return FLAC__STREAM_DECODER_TELL_STATUS_OK; + } +} + +FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) { + struct flac_stat_s filestats; + (void)client_data; + + if (decoder->private_->file == stdin) { + return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED; + } else if (flac_fstat(fileno(decoder->private_->file), &filestats) != 0) { + return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR; + } else { + *stream_length = (FLAC__uint64)filestats.st_size; + return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; + } +} + +FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data) { + (void)client_data; + + return feof(decoder->private_->file) ? true : false; } #endif -FLAC_API const void *FLAC__get_decoder_client_data(FLAC__StreamDecoder *decoder) -{ - return decoder->private_->client_data; +FLAC_API const void *FLAC__get_decoder_client_data(FLAC__StreamDecoder *decoder) { + return decoder->private_->client_data; } diff --git a/src/libflac/window.c b/src/libflac/window.c index 397f7b16..96c7549a 100644 --- a/src/libflac/window.c +++ b/src/libflac/window.c @@ -1,34 +1,34 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2006-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +/* libFLAC - Free Lossless Audio Codec library + Copyright (C) 2006-2009 Josh Coalson + Copyright (C) 2011-2016 Xiph.Org Foundation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ //#ifdef HAVE_CONFIG_H # include "config.h" @@ -45,240 +45,250 @@ #ifndef FLAC__INTEGER_ONLY_LIBRARY -void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L) -{ - const FLAC__int32 N = L - 1; - FLAC__int32 n; - - if (L & 1) { - for (n = 0; n <= N/2; n++) - window[n] = 2.0f * n / (float)N; - for (; n <= N; n++) - window[n] = 2.0f - 2.0f * n / (float)N; - } - else { - for (n = 0; n <= L/2-1; n++) - window[n] = 2.0f * n / (float)N; - for (; n <= N; n++) - window[n] = 2.0f - 2.0f * n / (float)N; - } +void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L) { + const FLAC__int32 N = L - 1; + FLAC__int32 n; + + if (L & 1) { + for (n = 0; n <= N / 2; n++) { + window[n] = 2.0f * n / (float)N; + } + for (; n <= N; n++) { + window[n] = 2.0f - 2.0f * n / (float)N; + } + } else { + for (n = 0; n <= L / 2 - 1; n++) { + window[n] = 2.0f * n / (float)N; + } + for (; n <= N; n++) { + window[n] = 2.0f - 2.0f * n / (float)N; + } + } } -void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L) -{ - const FLAC__int32 N = L - 1; - FLAC__int32 n; +void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L) { + const FLAC__int32 N = L - 1; + FLAC__int32 n; - for (n = 0; n < L; n++) - window[n] = (FLAC__real)(0.62f - 0.48f * fabsf((float)n/(float)N-0.5f) - 0.38f * cosf(2.0f * M_PI * ((float)n/(float)N))); + for (n = 0; n < L; n++) { + window[n] = (FLAC__real)(0.62f - 0.48f * fabsf((float)n / (float)N - 0.5f) - 0.38f * cosf(2.0f * M_PI * ((float)n / (float)N))); + } } -void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L) -{ - const FLAC__int32 N = L - 1; - FLAC__int32 n; +void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L) { + const FLAC__int32 N = L - 1; + FLAC__int32 n; - for (n = 0; n < L; n++) - window[n] = (FLAC__real)(0.42f - 0.5f * cosf(2.0f * M_PI * n / N) + 0.08f * cosf(4.0f * M_PI * n / N)); + for (n = 0; n < L; n++) { + window[n] = (FLAC__real)(0.42f - 0.5f * cosf(2.0f * M_PI * n / N) + 0.08f * cosf(4.0f * M_PI * n / N)); + } } /* 4-term -92dB side-lobe */ -void FLAC__window_blackman_harris_4term_92db_sidelobe(FLAC__real *window, const FLAC__int32 L) -{ - const FLAC__int32 N = L - 1; - FLAC__int32 n; +void FLAC__window_blackman_harris_4term_92db_sidelobe(FLAC__real *window, const FLAC__int32 L) { + const FLAC__int32 N = L - 1; + FLAC__int32 n; - for (n = 0; n <= N; n++) - window[n] = (FLAC__real)(0.35875f - 0.48829f * cosf(2.0f * M_PI * n / N) + 0.14128f * cosf(4.0f * M_PI * n / N) - 0.01168f * cosf(6.0f * M_PI * n / N)); + for (n = 0; n <= N; n++) { + window[n] = (FLAC__real)(0.35875f - 0.48829f * cosf(2.0f * M_PI * n / N) + 0.14128f * cosf(4.0f * M_PI * n / N) - 0.01168f * cosf(6.0f * M_PI * n / N)); + } } -void FLAC__window_connes(FLAC__real *window, const FLAC__int32 L) -{ - const FLAC__int32 N = L - 1; - const double N2 = (double)N / 2.; - FLAC__int32 n; - - for (n = 0; n <= N; n++) { - double k = ((double)n - N2) / N2; - k = 1.0f - k * k; - window[n] = (FLAC__real)(k * k); - } +void FLAC__window_connes(FLAC__real *window, const FLAC__int32 L) { + const FLAC__int32 N = L - 1; + const double N2 = (double)N / 2.; + FLAC__int32 n; + + for (n = 0; n <= N; n++) { + double k = ((double)n - N2) / N2; + k = 1.0f - k * k; + window[n] = (FLAC__real)(k * k); + } } -void FLAC__window_flattop(FLAC__real *window, const FLAC__int32 L) -{ - const FLAC__int32 N = L - 1; - FLAC__int32 n; +void FLAC__window_flattop(FLAC__real *window, const FLAC__int32 L) { + const FLAC__int32 N = L - 1; + FLAC__int32 n; - for (n = 0; n < L; n++) - window[n] = (FLAC__real)(0.21557895f - 0.41663158f * cosf(2.0f * M_PI * n / N) + 0.277263158f * cosf(4.0f * M_PI * n / N) - 0.083578947f * cosf(6.0f * M_PI * n / N) + 0.006947368f * cosf(8.0f * M_PI * n / N)); + for (n = 0; n < L; n++) { + window[n] = (FLAC__real)(0.21557895f - 0.41663158f * cosf(2.0f * M_PI * n / N) + 0.277263158f * cosf(4.0f * M_PI * n / N) - 0.083578947f * cosf(6.0f * M_PI * n / N) + 0.006947368f * cosf(8.0f * M_PI * n / N)); + } } -void FLAC__window_gauss(FLAC__real *window, const FLAC__int32 L, const FLAC__real stddev) -{ - const FLAC__int32 N = L - 1; - const double N2 = (double)N / 2.; - FLAC__int32 n; +void FLAC__window_gauss(FLAC__real *window, const FLAC__int32 L, const FLAC__real stddev) { + const FLAC__int32 N = L - 1; + const double N2 = (double)N / 2.; + FLAC__int32 n; - for (n = 0; n <= N; n++) { - const double k = ((double)n - N2) / (stddev * N2); - window[n] = (FLAC__real)exp(-0.5f * k * k); - } + for (n = 0; n <= N; n++) { + const double k = ((double)n - N2) / (stddev * N2); + window[n] = (FLAC__real)exp(-0.5f * k * k); + } } -void FLAC__window_hamming(FLAC__real *window, const FLAC__int32 L) -{ - const FLAC__int32 N = L - 1; - FLAC__int32 n; +void FLAC__window_hamming(FLAC__real *window, const FLAC__int32 L) { + const FLAC__int32 N = L - 1; + FLAC__int32 n; - for (n = 0; n < L; n++) - window[n] = (FLAC__real)(0.54f - 0.46f * cosf(2.0f * M_PI * n / N)); + for (n = 0; n < L; n++) { + window[n] = (FLAC__real)(0.54f - 0.46f * cosf(2.0f * M_PI * n / N)); + } } -void FLAC__window_hann(FLAC__real *window, const FLAC__int32 L) -{ - const FLAC__int32 N = L - 1; - FLAC__int32 n; +void FLAC__window_hann(FLAC__real *window, const FLAC__int32 L) { + const FLAC__int32 N = L - 1; + FLAC__int32 n; - for (n = 0; n < L; n++) - window[n] = (FLAC__real)(0.5f - 0.5f * cosf(2.0f * M_PI * n / N)); + for (n = 0; n < L; n++) { + window[n] = (FLAC__real)(0.5f - 0.5f * cosf(2.0f * M_PI * n / N)); + } } -void FLAC__window_kaiser_bessel(FLAC__real *window, const FLAC__int32 L) -{ - const FLAC__int32 N = L - 1; - FLAC__int32 n; +void FLAC__window_kaiser_bessel(FLAC__real *window, const FLAC__int32 L) { + const FLAC__int32 N = L - 1; + FLAC__int32 n; - for (n = 0; n < L; n++) - window[n] = (FLAC__real)(0.402f - 0.498f * cosf(2.0f * M_PI * n / N) + 0.098f * cosf(4.0f * M_PI * n / N) - 0.001f * cosf(6.0f * M_PI * n / N)); + for (n = 0; n < L; n++) { + window[n] = (FLAC__real)(0.402f - 0.498f * cosf(2.0f * M_PI * n / N) + 0.098f * cosf(4.0f * M_PI * n / N) - 0.001f * cosf(6.0f * M_PI * n / N)); + } } -void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L) -{ - const FLAC__int32 N = L - 1; - FLAC__int32 n; +void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L) { + const FLAC__int32 N = L - 1; + FLAC__int32 n; - for (n = 0; n < L; n++) - window[n] = (FLAC__real)(0.3635819f - 0.4891775f*cosf(2.0f*M_PI*n/N) + 0.1365995f*cosf(4.0f*M_PI*n/N) - 0.0106411f*cosf(6.0f*M_PI*n/N)); + for (n = 0; n < L; n++) { + window[n] = (FLAC__real)(0.3635819f - 0.4891775f * cosf(2.0f * M_PI * n / N) + 0.1365995f * cosf(4.0f * M_PI * n / N) - 0.0106411f * cosf(6.0f * M_PI * n / N)); + } } -void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L) -{ - FLAC__int32 n; +void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L) { + FLAC__int32 n; - for (n = 0; n < L; n++) - window[n] = 1.0f; + for (n = 0; n < L; n++) { + window[n] = 1.0f; + } } -void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L) -{ - FLAC__int32 n; - - if (L & 1) { - for (n = 1; n <= (L+1)/2; n++) - window[n-1] = 2.0f * n / ((float)L + 1.0f); - for (; n <= L; n++) - window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f); - } - else { - for (n = 1; n <= L/2; n++) - window[n-1] = 2.0f * n / ((float)L + 1.0f); - for (; n <= L; n++) - window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f); - } +void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L) { + FLAC__int32 n; + + if (L & 1) { + for (n = 1; n <= (L + 1) / 2; n++) { + window[n - 1] = 2.0f * n / ((float)L + 1.0f); + } + for (; n <= L; n++) { + window[n - 1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f); + } + } else { + for (n = 1; n <= L / 2; n++) { + window[n - 1] = 2.0f * n / ((float)L + 1.0f); + } + for (; n <= L; n++) { + window[n - 1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f); + } + } } -void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p) -{ - if (p <= 0.0) - FLAC__window_rectangle(window, L); - else if (p >= 1.0) - FLAC__window_hann(window, L); - else { - const FLAC__int32 Np = (FLAC__int32)(p / 2.0f * L) - 1; - FLAC__int32 n; - /* start with rectangle... */ - FLAC__window_rectangle(window, L); - /* ...replace ends with hann */ - if (Np > 0) { - for (n = 0; n <= Np; n++) { - window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * n / Np)); - window[L-Np-1+n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * (n+Np) / Np)); - } - } - } +void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p) { + if (p <= 0.0) { + FLAC__window_rectangle(window, L); + } else if (p >= 1.0) { + FLAC__window_hann(window, L); + } else { + const FLAC__int32 Np = (FLAC__int32)(p / 2.0f * L) - 1; + FLAC__int32 n; + /* start with rectangle... */ + FLAC__window_rectangle(window, L); + /* ...replace ends with hann */ + if (Np > 0) { + for (n = 0; n <= Np; n++) { + window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * n / Np)); + window[L - Np - 1 + n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * (n + Np) / Np)); + } + } + } } -void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end) -{ - const FLAC__int32 start_n = (FLAC__int32)(start * L); - const FLAC__int32 end_n = (FLAC__int32)(end * L); - const FLAC__int32 N = end_n - start_n; - FLAC__int32 Np, n, i; - - if (p <= 0.0f) - FLAC__window_partial_tukey(window, L, 0.05f, start, end); - else if (p >= 1.0f) - FLAC__window_partial_tukey(window, L, 0.95f, start, end); - else { - - Np = (FLAC__int32)(p / 2.0f * N); - - for (n = 0; n < start_n && n < L; n++) - window[n] = 0.0f; - for (i = 1; n < (start_n+Np) && n < L; n++, i++) - window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Np)); - for (; n < (end_n-Np) && n < L; n++) - window[n] = 1.0f; - for (i = Np; n < end_n && n < L; n++, i--) - window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Np)); - for (; n < L; n++) - window[n] = 0.0f; - } +void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end) { + const FLAC__int32 start_n = (FLAC__int32)(start * L); + const FLAC__int32 end_n = (FLAC__int32)(end * L); + const FLAC__int32 N = end_n - start_n; + FLAC__int32 Np, n, i; + + if (p <= 0.0f) { + FLAC__window_partial_tukey(window, L, 0.05f, start, end); + } else if (p >= 1.0f) { + FLAC__window_partial_tukey(window, L, 0.95f, start, end); + } else { + + Np = (FLAC__int32)(p / 2.0f * N); + + for (n = 0; n < start_n && n < L; n++) { + window[n] = 0.0f; + } + for (i = 1; n < (start_n + Np) && n < L; n++, i++) { + window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Np)); + } + for (; n < (end_n - Np) && n < L; n++) { + window[n] = 1.0f; + } + for (i = Np; n < end_n && n < L; n++, i--) { + window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Np)); + } + for (; n < L; n++) { + window[n] = 0.0f; + } + } } -void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end) -{ - const FLAC__int32 start_n = (FLAC__int32)(start * L); - const FLAC__int32 end_n = (FLAC__int32)(end * L); - FLAC__int32 Ns, Ne, n, i; - - if (p <= 0.0f) - FLAC__window_punchout_tukey(window, L, 0.05f, start, end); - else if (p >= 1.0f) - FLAC__window_punchout_tukey(window, L, 0.95f, start, end); - else { - - Ns = (FLAC__int32)(p / 2.0f * start_n); - Ne = (FLAC__int32)(p / 2.0f * (L - end_n)); - - for (n = 0, i = 1; n < Ns && n < L; n++, i++) - window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Ns)); - for (; n < start_n-Ns && n < L; n++) - window[n] = 1.0f; - for (i = Ns; n < start_n && n < L; n++, i--) - window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Ns)); - for (; n < end_n && n < L; n++) - window[n] = 0.0f; - for (i = 1; n < end_n+Ne && n < L; n++, i++) - window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Ne)); - for (; n < L - (Ne) && n < L; n++) - window[n] = 1.0f; - for (i = Ne; n < L; n++, i--) - window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Ne)); - } +void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end) { + const FLAC__int32 start_n = (FLAC__int32)(start * L); + const FLAC__int32 end_n = (FLAC__int32)(end * L); + FLAC__int32 Ns, Ne, n, i; + + if (p <= 0.0f) { + FLAC__window_punchout_tukey(window, L, 0.05f, start, end); + } else if (p >= 1.0f) { + FLAC__window_punchout_tukey(window, L, 0.95f, start, end); + } else { + + Ns = (FLAC__int32)(p / 2.0f * start_n); + Ne = (FLAC__int32)(p / 2.0f * (L - end_n)); + + for (n = 0, i = 1; n < Ns && n < L; n++, i++) { + window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Ns)); + } + for (; n < start_n - Ns && n < L; n++) { + window[n] = 1.0f; + } + for (i = Ns; n < start_n && n < L; n++, i--) { + window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Ns)); + } + for (; n < end_n && n < L; n++) { + window[n] = 0.0f; + } + for (i = 1; n < end_n + Ne && n < L; n++, i++) { + window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Ne)); + } + for (; n < L - (Ne) && n < L; n++) { + window[n] = 1.0f; + } + for (i = Ne; n < L; n++, i--) { + window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Ne)); + } + } } -void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L) -{ - const FLAC__int32 N = L - 1; - const double N2 = (double)N / 2.; - FLAC__int32 n; +void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L) { + const FLAC__int32 N = L - 1; + const double N2 = (double)N / 2.; + FLAC__int32 n; - for (n = 0; n <= N; n++) { - const double k = ((double)n - N2) / N2; - window[n] = (FLAC__real)(1.0f - k * k); - } + for (n = 0; n <= N; n++) { + const double k = ((double)n - N2) / N2; + window[n] = (FLAC__real)(1.0f - k * k); + } } #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ diff --git a/src/libhelix-aac/aaccommon.h b/src/libhelix-aac/aaccommon.h index 804337cd..462f1046 100644 --- a/src/libhelix-aac/aaccommon.h +++ b/src/libhelix-aac/aaccommon.h @@ -1,46 +1,46 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: aaccommon.h,v 1.1 2005/02/26 01:47:34 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: aaccommon.h,v 1.1 2005/02/26 01:47:34 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * aaccommon.h - implementation-independent API's, datatypes, and definitions + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + aaccommon.h - implementation-independent API's, datatypes, and definitions **************************************************************************************/ #ifndef _AACCOMMON_H @@ -51,7 +51,7 @@ // Can't fit in ESP8266 RAM #ifndef ESP8266 - #define AAC_ENABLE_SBR 1 +#define AAC_ENABLE_SBR 1 #endif #pragma GCC optimize ("O3") @@ -98,60 +98,60 @@ /* AAC file format */ enum { - AAC_FF_Unknown = 0, /* should be 0 on init */ + AAC_FF_Unknown = 0, /* should be 0 on init */ - AAC_FF_ADTS = 1, - AAC_FF_ADIF = 2, - AAC_FF_RAW = 3 + AAC_FF_ADTS = 1, + AAC_FF_ADIF = 2, + AAC_FF_RAW = 3 }; /* syntactic element type */ enum { - AAC_ID_INVALID = -1, - - AAC_ID_SCE = 0, - AAC_ID_CPE = 1, - AAC_ID_CCE = 2, - AAC_ID_LFE = 3, - AAC_ID_DSE = 4, - AAC_ID_PCE = 5, - AAC_ID_FIL = 6, - AAC_ID_END = 7 + AAC_ID_INVALID = -1, + + AAC_ID_SCE = 0, + AAC_ID_CPE = 1, + AAC_ID_CCE = 2, + AAC_ID_LFE = 3, + AAC_ID_DSE = 4, + AAC_ID_PCE = 5, + AAC_ID_FIL = 6, + AAC_ID_END = 7 }; typedef struct _AACDecInfo { - /* pointers to platform-specific state information */ - void *psInfoBase; /* baseline MPEG-4 LC decoding */ - void *psInfoSBR; /* MPEG-4 SBR decoding */ - - /* raw decoded data, before rounding to 16-bit PCM (for postprocessing such as SBR) */ - void *rawSampleBuf[AAC_MAX_NCHANS]; - int rawSampleBytes; - int rawSampleFBits; - - /* fill data (can be used for processing SBR or other extensions) */ - unsigned char *fillBuf; - int fillCount; - int fillExtType; - - /* block information */ - int prevBlockID; - int currBlockID; - int currInstTag; - int sbDeinterleaveReqd[MAX_NCHANS_ELEM]; - int adtsBlocksLeft; - - /* user-accessible info */ - int bitRate; - int nChans; - int sampRate; - int profile; - int format; - int sbrEnabled; - int tnsUsed; - int pnsUsed; - int frameCount; + /* pointers to platform-specific state information */ + void *psInfoBase; /* baseline MPEG-4 LC decoding */ + void *psInfoSBR; /* MPEG-4 SBR decoding */ + + /* raw decoded data, before rounding to 16-bit PCM (for postprocessing such as SBR) */ + void *rawSampleBuf[AAC_MAX_NCHANS]; + int rawSampleBytes; + int rawSampleFBits; + + /* fill data (can be used for processing SBR or other extensions) */ + unsigned char *fillBuf; + int fillCount; + int fillExtType; + + /* block information */ + int prevBlockID; + int currBlockID; + int currInstTag; + int sbDeinterleaveReqd[MAX_NCHANS_ELEM]; + int adtsBlocksLeft; + + /* user-accessible info */ + int bitRate; + int nChans; + int sampRate; + int profile; + int format; + int sbrEnabled; + int tnsUsed; + int pnsUsed; + int frameCount; } AACDecInfo; @@ -198,10 +198,10 @@ extern const /*short*/ int sfBandTabShort[76]; extern const int sfBandTabLongOffset[NUM_SAMPLE_RATES]; extern const /*short*/ int sfBandTabLong[325]; extern const int tnsMaxBandsShortOffset[AAC_NUM_PROFILES]; -extern const unsigned /*char*/ int tnsMaxBandsShort[2*NUM_SAMPLE_RATES]; +extern const unsigned /*char*/ int tnsMaxBandsShort[2 * NUM_SAMPLE_RATES]; extern const unsigned /*char*/ int tnsMaxOrderShort[AAC_NUM_PROFILES]; extern const int tnsMaxBandsLongOffset[AAC_NUM_PROFILES]; -extern const unsigned /*char*/ int tnsMaxBandsLong[2*NUM_SAMPLE_RATES]; +extern const unsigned /*char*/ int tnsMaxBandsLong[2 * NUM_SAMPLE_RATES]; extern const unsigned /*char*/ int tnsMaxOrderLong[AAC_NUM_PROFILES]; #endif /* _AACCOMMON_H */ diff --git a/src/libhelix-aac/aacdec.c b/src/libhelix-aac/aacdec.c index cb0e5041..56ebed05 100644 --- a/src/libhelix-aac/aacdec.c +++ b/src/libhelix-aac/aacdec.c @@ -1,46 +1,46 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: aacdec.c,v 1.1 2005/02/26 01:47:31 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: aacdec.c,v 1.1 2005/02/26 01:47:31 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * February 2005 - * - * aacdec.c - platform-independent top level decoder API + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + February 2005 + + aacdec.c - platform-independent top level decoder API **************************************************************************************/ #include "aaccommon.h" @@ -51,426 +51,448 @@ #define PROFILE_END() /************************************************************************************** - * Function: AACInitDecoder - * - * Description: allocate memory for platform-specific data - * clear all the user-accessible fields - * initialize SBR decoder if enabled - * - * Inputs: none - * - * Outputs: none - * - * Return: handle to AAC decoder instance, 0 if malloc fails + Function: AACInitDecoder + + Description: allocate memory for platform-specific data + clear all the user-accessible fields + initialize SBR decoder if enabled + + Inputs: none + + Outputs: none + + Return: handle to AAC decoder instance, 0 if malloc fails **************************************************************************************/ -HAACDecoder AACInitDecoder(void) -{ - AACDecInfo *aacDecInfo; +HAACDecoder AACInitDecoder(void) { + AACDecInfo *aacDecInfo; - aacDecInfo = AllocateBuffers(); - if (!aacDecInfo) - return 0; + aacDecInfo = AllocateBuffers(); + if (!aacDecInfo) { + return 0; + } #ifdef AAC_ENABLE_SBR - if (InitSBR(aacDecInfo)) { - AACFreeDecoder(aacDecInfo); - return 0; - } + if (InitSBR(aacDecInfo)) { + AACFreeDecoder(aacDecInfo); + return 0; + } #endif - return (HAACDecoder)aacDecInfo; + return (HAACDecoder)aacDecInfo; } -HAACDecoder AACInitDecoderPre(void *ptr, int sz) -{ - AACDecInfo *aacDecInfo; +HAACDecoder AACInitDecoderPre(void *ptr, int sz) { + AACDecInfo *aacDecInfo; - aacDecInfo = AllocateBuffersPre(&ptr, &sz); - if (!aacDecInfo) - return 0; + aacDecInfo = AllocateBuffersPre(&ptr, &sz); + if (!aacDecInfo) { + return 0; + } #ifdef AAC_ENABLE_SBR - if (InitSBRPre(aacDecInfo, &ptr, &sz)) { - return 0; - } + if (InitSBRPre(aacDecInfo, &ptr, &sz)) { + return 0; + } #endif - return (HAACDecoder)aacDecInfo; + return (HAACDecoder)aacDecInfo; } /************************************************************************************** - * Function: AACFreeDecoder - * - * Description: free platform-specific data allocated by AACInitDecoder - * free SBR decoder if enabled - * - * Inputs: valid AAC decoder instance pointer (HAACDecoder) - * - * Outputs: none - * - * Return: none + Function: AACFreeDecoder + + Description: free platform-specific data allocated by AACInitDecoder + free SBR decoder if enabled + + Inputs: valid AAC decoder instance pointer (HAACDecoder) + + Outputs: none + + Return: none **************************************************************************************/ -void AACFreeDecoder(HAACDecoder hAACDecoder) -{ - AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder; +void AACFreeDecoder(HAACDecoder hAACDecoder) { + AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder; - if (!aacDecInfo) - return; + if (!aacDecInfo) { + return; + } #ifdef AAC_ENABLE_SBR - FreeSBR(aacDecInfo); + FreeSBR(aacDecInfo); #endif - FreeBuffers(aacDecInfo); + FreeBuffers(aacDecInfo); } /************************************************************************************** - * Function: AACFindSyncWord - * - * Description: locate the next byte-alinged sync word in the raw AAC stream - * - * Inputs: buffer to search for sync word - * max number of bytes to search in buffer - * - * Outputs: none - * - * Return: offset to first sync word (bytes from start of buf) - * -1 if sync not found after searching nBytes + Function: AACFindSyncWord + + Description: locate the next byte-alinged sync word in the raw AAC stream + + Inputs: buffer to search for sync word + max number of bytes to search in buffer + + Outputs: none + + Return: offset to first sync word (bytes from start of buf) + -1 if sync not found after searching nBytes **************************************************************************************/ -int AACFindSyncWord(unsigned char *buf, int nBytes) -{ - int i; - - /* find byte-aligned syncword (12 bits = 0xFFF) */ - for (i = 0; i < nBytes - 1; i++) { - if ( (buf[i+0] & SYNCWORDH) == SYNCWORDH && (buf[i+1] & SYNCWORDL) == SYNCWORDL ) - return i; - } - - return -1; +int AACFindSyncWord(unsigned char *buf, int nBytes) { + int i; + + /* find byte-aligned syncword (12 bits = 0xFFF) */ + for (i = 0; i < nBytes - 1; i++) { + if ((buf[i + 0] & SYNCWORDH) == SYNCWORDH && (buf[i + 1] & SYNCWORDL) == SYNCWORDL) { + return i; + } + } + + return -1; } /************************************************************************************** - * Function: AACGetLastFrameInfo - * - * Description: get info about last AAC frame decoded (number of samples decoded, - * sample rate, bit rate, etc.) - * - * Inputs: valid AAC decoder instance pointer (HAACDecoder) - * pointer to AACFrameInfo struct - * - * Outputs: filled-in AACFrameInfo struct - * - * Return: none - * - * Notes: call this right after calling AACDecode() + Function: AACGetLastFrameInfo + + Description: get info about last AAC frame decoded (number of samples decoded, + sample rate, bit rate, etc.) + + Inputs: valid AAC decoder instance pointer (HAACDecoder) + pointer to AACFrameInfo struct + + Outputs: filled-in AACFrameInfo struct + + Return: none + + Notes: call this right after calling AACDecode() **************************************************************************************/ -void AACGetLastFrameInfo(HAACDecoder hAACDecoder, AACFrameInfo *aacFrameInfo) -{ - AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder; - - if (!aacDecInfo) { - aacFrameInfo->bitRate = 0; - aacFrameInfo->nChans = 0; - aacFrameInfo->sampRateCore = 0; - aacFrameInfo->sampRateOut = 0; - aacFrameInfo->bitsPerSample = 0; - aacFrameInfo->outputSamps = 0; - aacFrameInfo->profile = 0; - aacFrameInfo->tnsUsed = 0; - aacFrameInfo->pnsUsed = 0; - } else { - aacFrameInfo->bitRate = aacDecInfo->bitRate; - aacFrameInfo->nChans = aacDecInfo->nChans; - aacFrameInfo->sampRateCore = aacDecInfo->sampRate; - aacFrameInfo->sampRateOut = aacDecInfo->sampRate * (aacDecInfo->sbrEnabled ? 2 : 1); - aacFrameInfo->bitsPerSample = 16; - aacFrameInfo->outputSamps = aacDecInfo->nChans * AAC_MAX_NSAMPS * (aacDecInfo->sbrEnabled ? 2 : 1); - aacFrameInfo->profile = aacDecInfo->profile; - aacFrameInfo->tnsUsed = aacDecInfo->tnsUsed; - aacFrameInfo->pnsUsed = aacDecInfo->pnsUsed; - } +void AACGetLastFrameInfo(HAACDecoder hAACDecoder, AACFrameInfo *aacFrameInfo) { + AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder; + + if (!aacDecInfo) { + aacFrameInfo->bitRate = 0; + aacFrameInfo->nChans = 0; + aacFrameInfo->sampRateCore = 0; + aacFrameInfo->sampRateOut = 0; + aacFrameInfo->bitsPerSample = 0; + aacFrameInfo->outputSamps = 0; + aacFrameInfo->profile = 0; + aacFrameInfo->tnsUsed = 0; + aacFrameInfo->pnsUsed = 0; + } else { + aacFrameInfo->bitRate = aacDecInfo->bitRate; + aacFrameInfo->nChans = aacDecInfo->nChans; + aacFrameInfo->sampRateCore = aacDecInfo->sampRate; + aacFrameInfo->sampRateOut = aacDecInfo->sampRate * (aacDecInfo->sbrEnabled ? 2 : 1); + aacFrameInfo->bitsPerSample = 16; + aacFrameInfo->outputSamps = aacDecInfo->nChans * AAC_MAX_NSAMPS * (aacDecInfo->sbrEnabled ? 2 : 1); + aacFrameInfo->profile = aacDecInfo->profile; + aacFrameInfo->tnsUsed = aacDecInfo->tnsUsed; + aacFrameInfo->pnsUsed = aacDecInfo->pnsUsed; + } } /************************************************************************************** - * Function: AACSetRawBlockParams - * - * Description: set internal state variables for decoding a stream of raw data blocks - * - * Inputs: valid AAC decoder instance pointer (HAACDecoder) - * flag indicating source of parameters - * AACFrameInfo struct, with the members nChans, sampRate, and profile - * optionally filled-in - * - * Outputs: updated codec state - * - * Return: 0 if successful, error code (< 0) if error - * - * Notes: if copyLast == 1, then the codec sets up its internal state (for - * decoding raw blocks) based on previously-decoded ADTS header info - * if copyLast == 0, then the codec uses the values passed in - * aacFrameInfo to configure its internal state (useful when the - * source is MP4 format, for example) + Function: AACSetRawBlockParams + + Description: set internal state variables for decoding a stream of raw data blocks + + Inputs: valid AAC decoder instance pointer (HAACDecoder) + flag indicating source of parameters + AACFrameInfo struct, with the members nChans, sampRate, and profile + optionally filled-in + + Outputs: updated codec state + + Return: 0 if successful, error code (< 0) if error + + Notes: if copyLast == 1, then the codec sets up its internal state (for + decoding raw blocks) based on previously-decoded ADTS header info + if copyLast == 0, then the codec uses the values passed in + aacFrameInfo to configure its internal state (useful when the + source is MP4 format, for example) **************************************************************************************/ -int AACSetRawBlockParams(HAACDecoder hAACDecoder, int copyLast, AACFrameInfo *aacFrameInfo) -{ - AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder; - - if (!aacDecInfo) - return ERR_AAC_NULL_POINTER; - - aacDecInfo->format = AAC_FF_RAW; - if (copyLast) - return SetRawBlockParams(aacDecInfo, 1, 0, 0, 0); - else - return SetRawBlockParams(aacDecInfo, 0, aacFrameInfo->nChans, aacFrameInfo->sampRateCore, aacFrameInfo->profile); +int AACSetRawBlockParams(HAACDecoder hAACDecoder, int copyLast, AACFrameInfo *aacFrameInfo) { + AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder; + + if (!aacDecInfo) { + return ERR_AAC_NULL_POINTER; + } + + aacDecInfo->format = AAC_FF_RAW; + if (copyLast) { + return SetRawBlockParams(aacDecInfo, 1, 0, 0, 0); + } else { + return SetRawBlockParams(aacDecInfo, 0, aacFrameInfo->nChans, aacFrameInfo->sampRateCore, aacFrameInfo->profile); + } } /************************************************************************************** - * Function: AACFlushCodec - * - * Description: flush internal codec state (after seeking, for example) - * - * Inputs: valid AAC decoder instance pointer (HAACDecoder) - * - * Outputs: updated state variables in aacDecInfo - * - * Return: 0 if successful, error code (< 0) if error + Function: AACFlushCodec + + Description: flush internal codec state (after seeking, for example) + + Inputs: valid AAC decoder instance pointer (HAACDecoder) + + Outputs: updated state variables in aacDecInfo + + Return: 0 if successful, error code (< 0) if error **************************************************************************************/ -int AACFlushCodec(HAACDecoder hAACDecoder) -{ - int ch; - AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder; - - if (!aacDecInfo) - return ERR_AAC_NULL_POINTER; - - /* reset common state variables which change per-frame - * don't touch state variables which are (usually) constant for entire clip - * (nChans, sampRate, profile, format, sbrEnabled) - */ - aacDecInfo->prevBlockID = AAC_ID_INVALID; - aacDecInfo->currBlockID = AAC_ID_INVALID; - aacDecInfo->currInstTag = -1; - for (ch = 0; ch < MAX_NCHANS_ELEM; ch++) - aacDecInfo->sbDeinterleaveReqd[ch] = 0; - aacDecInfo->adtsBlocksLeft = 0; - aacDecInfo->tnsUsed = 0; - aacDecInfo->pnsUsed = 0; - - /* reset internal codec state (flush overlap buffers, etc.) */ - FlushCodec(aacDecInfo); +int AACFlushCodec(HAACDecoder hAACDecoder) { + int ch; + AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder; + + if (!aacDecInfo) { + return ERR_AAC_NULL_POINTER; + } + + /* reset common state variables which change per-frame + don't touch state variables which are (usually) constant for entire clip + (nChans, sampRate, profile, format, sbrEnabled) + */ + aacDecInfo->prevBlockID = AAC_ID_INVALID; + aacDecInfo->currBlockID = AAC_ID_INVALID; + aacDecInfo->currInstTag = -1; + for (ch = 0; ch < MAX_NCHANS_ELEM; ch++) { + aacDecInfo->sbDeinterleaveReqd[ch] = 0; + } + aacDecInfo->adtsBlocksLeft = 0; + aacDecInfo->tnsUsed = 0; + aacDecInfo->pnsUsed = 0; + + /* reset internal codec state (flush overlap buffers, etc.) */ + FlushCodec(aacDecInfo); #ifdef AAC_ENABLE_SBR - FlushCodecSBR(aacDecInfo); + FlushCodecSBR(aacDecInfo); #endif - return ERR_AAC_NONE; + return ERR_AAC_NONE; } /************************************************************************************** - * Function: AACDecode - * - * Description: decode AAC frame - * - * Inputs: valid AAC decoder instance pointer (HAACDecoder) - * double pointer to buffer of AAC data - * pointer to number of valid bytes remaining in inbuf - * pointer to outbuf, big enough to hold one frame of decoded PCM samples - * (outbuf must be double-sized if SBR enabled) - * - * Outputs: PCM data in outbuf, interleaved LRLRLR... if stereo - * number of output samples = 1024 per channel (2048 if SBR enabled) - * updated inbuf pointer - * updated bytesLeft - * - * Return: 0 if successful, error code (< 0) if error - * - * Notes: inbuf pointer and bytesLeft are not updated until whole frame is - * successfully decoded, so if ERR_AAC_INDATA_UNDERFLOW is returned - * just call AACDecode again with more data in inbuf + Function: AACDecode + + Description: decode AAC frame + + Inputs: valid AAC decoder instance pointer (HAACDecoder) + double pointer to buffer of AAC data + pointer to number of valid bytes remaining in inbuf + pointer to outbuf, big enough to hold one frame of decoded PCM samples + (outbuf must be double-sized if SBR enabled) + + Outputs: PCM data in outbuf, interleaved LRLRLR... if stereo + number of output samples = 1024 per channel (2048 if SBR enabled) + updated inbuf pointer + updated bytesLeft + + Return: 0 if successful, error code (< 0) if error + + Notes: inbuf pointer and bytesLeft are not updated until whole frame is + successfully decoded, so if ERR_AAC_INDATA_UNDERFLOW is returned + just call AACDecode again with more data in inbuf **************************************************************************************/ -int AACDecode(HAACDecoder hAACDecoder, unsigned char **inbuf, int *bytesLeft, short *outbuf) -{ - int err, offset, bitOffset, bitsAvail; - int ch, baseChan, elementChans; - unsigned char *inptr; - AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder; +int AACDecode(HAACDecoder hAACDecoder, unsigned char **inbuf, int *bytesLeft, short *outbuf) { + int err, offset, bitOffset, bitsAvail; + int ch, baseChan, elementChans; + unsigned char *inptr; + AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder; #ifdef AAC_ENABLE_SBR - int baseChanSBR, elementChansSBR; + int baseChanSBR, elementChansSBR; #endif - if (!aacDecInfo) - return ERR_AAC_NULL_POINTER; - - /* make local copies (see "Notes" above) */ - inptr = *inbuf; - bitOffset = 0; - bitsAvail = (*bytesLeft) << 3; - - /* first time through figure out what the file format is */ - if (aacDecInfo->format == AAC_FF_Unknown) { - if (bitsAvail < 32) - return ERR_AAC_INDATA_UNDERFLOW; - - if (IS_ADIF(inptr)) { - /* unpack ADIF header */ - aacDecInfo->format = AAC_FF_ADIF; - err = UnpackADIFHeader(aacDecInfo, &inptr, &bitOffset, &bitsAvail); - if (err) - return err; - } else { - /* assume ADTS by default */ - aacDecInfo->format = AAC_FF_ADTS; - } - } - - - - /* if ADTS, search for start of next frame */ - if (aacDecInfo->format == AAC_FF_ADTS) { - /* can have 1-4 raw data blocks per ADTS frame (header only present for first one) */ - if (aacDecInfo->adtsBlocksLeft == 0) { - offset = AACFindSyncWord(inptr, bitsAvail >> 3); - if (offset < 0) - return ERR_AAC_INDATA_UNDERFLOW; - inptr += offset; - bitsAvail -= (offset << 3); - - err = UnpackADTSHeader(aacDecInfo, &inptr, &bitOffset, &bitsAvail); - if (err) - return err; - - if (aacDecInfo->nChans == -1) { - /* figure out implicit channel mapping if necessary */ - err = GetADTSChannelMapping(aacDecInfo, inptr, bitOffset, bitsAvail); - if (err) - return err; - } - } - aacDecInfo->adtsBlocksLeft--; - } else if (aacDecInfo->format == AAC_FF_RAW) { - err = PrepareRawBlock(aacDecInfo); - if (err) - return err; - } - - - - /* check for valid number of channels */ - if (aacDecInfo->nChans > AAC_MAX_NCHANS || aacDecInfo->nChans <= 0) - return ERR_AAC_NCHANS_TOO_HIGH; - - /* will be set later if active in this frame */ - aacDecInfo->tnsUsed = 0; - aacDecInfo->pnsUsed = 0; - - bitOffset = 0; - baseChan = 0; -#ifdef AAC_ENABLE_SBR - baseChanSBR = 0; -#endif - do { - - - - /* parse next syntactic element */ - err = DecodeNextElement(aacDecInfo, &inptr, &bitOffset, &bitsAvail); - if (err) - return err; - - elementChans = elementNumChans[aacDecInfo->currBlockID]; - if (baseChan + elementChans > AAC_MAX_NCHANS) - return ERR_AAC_NCHANS_TOO_HIGH; - - /* noiseless decoder and dequantizer */ - for (ch = 0; ch < elementChans; ch++) { - PROFILE_START("noiseless decoder"); - err = DecodeNoiselessData(aacDecInfo, &inptr, &bitOffset, &bitsAvail, ch); - PROFILE_END(); - - if (err) - return err; - - PROFILE_START("dequant"); - if (Dequantize(aacDecInfo, ch)) - return ERR_AAC_DEQUANT; - PROFILE_END(); - } - - PROFILE_START("mid-side and intensity stereo"); - /* mid-side and intensity stereo */ - if (aacDecInfo->currBlockID == AAC_ID_CPE) { - if (StereoProcess(aacDecInfo)) - return ERR_AAC_STEREO_PROCESS; - } - PROFILE_END(); - - - /* PNS, TNS, inverse transform */ - for (ch = 0; ch < elementChans; ch++) { - PROFILE_START("PNS"); - if (PNS(aacDecInfo, ch)) - return ERR_AAC_PNS; - PROFILE_END(); - - if (aacDecInfo->sbDeinterleaveReqd[ch]) { - /* deinterleave short blocks, if required */ - if (DeinterleaveShortBlocks(aacDecInfo, ch)) - return ERR_AAC_SHORT_BLOCK_DEINT; - aacDecInfo->sbDeinterleaveReqd[ch] = 0; - } - - PROFILE_START("TNS"); - if (TNSFilter(aacDecInfo, ch)) - return ERR_AAC_TNS; - PROFILE_END(); - - PROFILE_START("IMDCT"); - if (IMDCT(aacDecInfo, ch, baseChan + ch, outbuf)) - return ERR_AAC_IMDCT; - PROFILE_END(); - } + if (!aacDecInfo) { + return ERR_AAC_NULL_POINTER; + } + + /* make local copies (see "Notes" above) */ + inptr = *inbuf; + bitOffset = 0; + bitsAvail = (*bytesLeft) << 3; + + /* first time through figure out what the file format is */ + if (aacDecInfo->format == AAC_FF_Unknown) { + if (bitsAvail < 32) { + return ERR_AAC_INDATA_UNDERFLOW; + } + + if (IS_ADIF(inptr)) { + /* unpack ADIF header */ + aacDecInfo->format = AAC_FF_ADIF; + err = UnpackADIFHeader(aacDecInfo, &inptr, &bitOffset, &bitsAvail); + if (err) { + return err; + } + } else { + /* assume ADTS by default */ + aacDecInfo->format = AAC_FF_ADTS; + } + } + + + + /* if ADTS, search for start of next frame */ + if (aacDecInfo->format == AAC_FF_ADTS) { + /* can have 1-4 raw data blocks per ADTS frame (header only present for first one) */ + if (aacDecInfo->adtsBlocksLeft == 0) { + offset = AACFindSyncWord(inptr, bitsAvail >> 3); + if (offset < 0) { + return ERR_AAC_INDATA_UNDERFLOW; + } + inptr += offset; + bitsAvail -= (offset << 3); + + err = UnpackADTSHeader(aacDecInfo, &inptr, &bitOffset, &bitsAvail); + if (err) { + return err; + } + + if (aacDecInfo->nChans == -1) { + /* figure out implicit channel mapping if necessary */ + err = GetADTSChannelMapping(aacDecInfo, inptr, bitOffset, bitsAvail); + if (err) { + return err; + } + } + } + aacDecInfo->adtsBlocksLeft--; + } else if (aacDecInfo->format == AAC_FF_RAW) { + err = PrepareRawBlock(aacDecInfo); + if (err) { + return err; + } + } + + + /* check for valid number of channels */ + if (aacDecInfo->nChans > AAC_MAX_NCHANS || aacDecInfo->nChans <= 0) { + return ERR_AAC_NCHANS_TOO_HIGH; + } + + /* will be set later if active in this frame */ + aacDecInfo->tnsUsed = 0; + aacDecInfo->pnsUsed = 0; + + bitOffset = 0; + baseChan = 0; #ifdef AAC_ENABLE_SBR - if (aacDecInfo->sbrEnabled && (aacDecInfo->currBlockID == AAC_ID_FIL || aacDecInfo->currBlockID == AAC_ID_LFE)) { - if (aacDecInfo->currBlockID == AAC_ID_LFE) - elementChansSBR = elementNumChans[AAC_ID_LFE]; - else if (aacDecInfo->currBlockID == AAC_ID_FIL && (aacDecInfo->prevBlockID == AAC_ID_SCE || aacDecInfo->prevBlockID == AAC_ID_CPE)) - elementChansSBR = elementNumChans[aacDecInfo->prevBlockID]; - else - elementChansSBR = 0; - - if (baseChanSBR + elementChansSBR > AAC_MAX_NCHANS) - return ERR_AAC_SBR_NCHANS_TOO_HIGH; - - /* parse SBR extension data if present (contained in a fill element) */ - if (DecodeSBRBitstream(aacDecInfo, baseChanSBR)) - return ERR_AAC_SBR_BITSTREAM; - - /* apply SBR */ - if (DecodeSBRData(aacDecInfo, baseChanSBR, outbuf)) - return ERR_AAC_SBR_DATA; - - baseChanSBR += elementChansSBR; - } + baseChanSBR = 0; #endif - - baseChan += elementChans; - } while (aacDecInfo->currBlockID != AAC_ID_END); - - /* byte align after each raw_data_block */ - if (bitOffset) { - inptr++; - bitsAvail -= (8-bitOffset); - bitOffset = 0; - if (bitsAvail < 0) - return ERR_AAC_INDATA_UNDERFLOW; - } - - /* update pointers */ - aacDecInfo->frameCount++; - *bytesLeft -= (inptr - *inbuf); - *inbuf = inptr; - - return ERR_AAC_NONE; + do { + + + + /* parse next syntactic element */ + err = DecodeNextElement(aacDecInfo, &inptr, &bitOffset, &bitsAvail); + if (err) { + return err; + } + + elementChans = elementNumChans[aacDecInfo->currBlockID]; + if (baseChan + elementChans > AAC_MAX_NCHANS) { + return ERR_AAC_NCHANS_TOO_HIGH; + } + + /* noiseless decoder and dequantizer */ + for (ch = 0; ch < elementChans; ch++) { + PROFILE_START("noiseless decoder"); + err = DecodeNoiselessData(aacDecInfo, &inptr, &bitOffset, &bitsAvail, ch); + PROFILE_END(); + + if (err) { + return err; + } + + PROFILE_START("dequant"); + if (Dequantize(aacDecInfo, ch)) { + return ERR_AAC_DEQUANT; + } + PROFILE_END(); + } + + PROFILE_START("mid-side and intensity stereo"); + /* mid-side and intensity stereo */ + if (aacDecInfo->currBlockID == AAC_ID_CPE) { + if (StereoProcess(aacDecInfo)) { + return ERR_AAC_STEREO_PROCESS; + } + } + PROFILE_END(); + + + /* PNS, TNS, inverse transform */ + for (ch = 0; ch < elementChans; ch++) { + PROFILE_START("PNS"); + if (PNS(aacDecInfo, ch)) { + return ERR_AAC_PNS; + } + PROFILE_END(); + + if (aacDecInfo->sbDeinterleaveReqd[ch]) { + /* deinterleave short blocks, if required */ + if (DeinterleaveShortBlocks(aacDecInfo, ch)) { + return ERR_AAC_SHORT_BLOCK_DEINT; + } + aacDecInfo->sbDeinterleaveReqd[ch] = 0; + } + + PROFILE_START("TNS"); + if (TNSFilter(aacDecInfo, ch)) { + return ERR_AAC_TNS; + } + PROFILE_END(); + + PROFILE_START("IMDCT"); + if (IMDCT(aacDecInfo, ch, baseChan + ch, outbuf)) { + return ERR_AAC_IMDCT; + } + PROFILE_END(); + } + +#ifdef AAC_ENABLE_SBR + if (aacDecInfo->sbrEnabled && (aacDecInfo->currBlockID == AAC_ID_FIL || aacDecInfo->currBlockID == AAC_ID_LFE)) { + if (aacDecInfo->currBlockID == AAC_ID_LFE) { + elementChansSBR = elementNumChans[AAC_ID_LFE]; + } else if (aacDecInfo->currBlockID == AAC_ID_FIL && (aacDecInfo->prevBlockID == AAC_ID_SCE || aacDecInfo->prevBlockID == AAC_ID_CPE)) { + elementChansSBR = elementNumChans[aacDecInfo->prevBlockID]; + } else { + elementChansSBR = 0; + } + + if (baseChanSBR + elementChansSBR > AAC_MAX_NCHANS) { + return ERR_AAC_SBR_NCHANS_TOO_HIGH; + } + + /* parse SBR extension data if present (contained in a fill element) */ + if (DecodeSBRBitstream(aacDecInfo, baseChanSBR)) { + return ERR_AAC_SBR_BITSTREAM; + } + + /* apply SBR */ + if (DecodeSBRData(aacDecInfo, baseChanSBR, outbuf)) { + return ERR_AAC_SBR_DATA; + } + + baseChanSBR += elementChansSBR; + } +#endif + + baseChan += elementChans; + } while (aacDecInfo->currBlockID != AAC_ID_END); + + /* byte align after each raw_data_block */ + if (bitOffset) { + inptr++; + bitsAvail -= (8 - bitOffset); + bitOffset = 0; + if (bitsAvail < 0) { + return ERR_AAC_INDATA_UNDERFLOW; + } + } + + /* update pointers */ + aacDecInfo->frameCount++; + *bytesLeft -= (inptr - *inbuf); + *inbuf = inptr; + + return ERR_AAC_NONE; } diff --git a/src/libhelix-aac/aacdec.h b/src/libhelix-aac/aacdec.h index 0f7d91f4..6e4dfcd8 100644 --- a/src/libhelix-aac/aacdec.h +++ b/src/libhelix-aac/aacdec.h @@ -1,46 +1,46 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: aacdec.h,v 1.8 2005/11/10 00:15:08 margotm Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: aacdec.h,v 1.8 2005/11/10 00:15:08 margotm Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * aacdec.h - public C API for AAC decoder + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + aacdec.h - public C API for AAC decoder **************************************************************************************/ #ifndef _AACDEC_H @@ -64,6 +64,8 @@ # #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__POWERPC__)) # +#elif defined(__GNUC__) && (defined(__mips__) || defined(__MIPS__)) +# #elif defined(_OPENWAVE_SIMULATOR) || defined(_OPENWAVE_ARMULATOR) # #elif defined(_SOLARIS) && !defined(__GNUC__) @@ -82,12 +84,12 @@ extern "C" { #endif -/* according to spec (13818-7 section 8.2.2, 14496-3 section 4.5.3) - * max size of input buffer = - * 6144 bits = 768 bytes per SCE or CCE-I - * 12288 bits = 1536 bytes per CPE - * 0 bits = 0 bytes per CCE-D (uses bits from the SCE/CPE/CCE-I it is coupled to) - */ +/* according to spec (13818-7 section 8.2.2, 14496-3 section 4.5.3) + max size of input buffer = + 6144 bits = 768 bytes per SCE or CCE-I + 12288 bits = 1536 bytes per CPE + 0 bits = 0 bytes per CCE-D (uses bits from the SCE/CPE/CCE-I it is coupled to) +*/ #ifndef AAC_MAX_NCHANS /* if max channels isn't set in makefile, */ #define AAC_MAX_NCHANS 2 /* set to default max number of channels */ #endif @@ -106,46 +108,46 @@ extern "C" { #define AAC_ENABLE_MPEG4 enum { - ERR_AAC_NONE = 0, - ERR_AAC_INDATA_UNDERFLOW = -1, - ERR_AAC_NULL_POINTER = -2, - ERR_AAC_INVALID_ADTS_HEADER = -3, - ERR_AAC_INVALID_ADIF_HEADER = -4, - ERR_AAC_INVALID_FRAME = -5, - ERR_AAC_MPEG4_UNSUPPORTED = -6, - ERR_AAC_CHANNEL_MAP = -7, - ERR_AAC_SYNTAX_ELEMENT = -8, - - ERR_AAC_DEQUANT = -9, - ERR_AAC_STEREO_PROCESS = -10, - ERR_AAC_PNS = -11, - ERR_AAC_SHORT_BLOCK_DEINT = -12, - ERR_AAC_TNS = -13, - ERR_AAC_IMDCT = -14, - ERR_AAC_NCHANS_TOO_HIGH = -15, - - ERR_AAC_SBR_INIT = -16, - ERR_AAC_SBR_BITSTREAM = -17, - ERR_AAC_SBR_DATA = -18, - ERR_AAC_SBR_PCM_FORMAT = -19, - ERR_AAC_SBR_NCHANS_TOO_HIGH = -20, - ERR_AAC_SBR_SINGLERATE_UNSUPPORTED = -21, - - ERR_AAC_RAWBLOCK_PARAMS = -22, - - ERR_AAC_UNKNOWN = -9999 + ERR_AAC_NONE = 0, + ERR_AAC_INDATA_UNDERFLOW = -1, + ERR_AAC_NULL_POINTER = -2, + ERR_AAC_INVALID_ADTS_HEADER = -3, + ERR_AAC_INVALID_ADIF_HEADER = -4, + ERR_AAC_INVALID_FRAME = -5, + ERR_AAC_MPEG4_UNSUPPORTED = -6, + ERR_AAC_CHANNEL_MAP = -7, + ERR_AAC_SYNTAX_ELEMENT = -8, + + ERR_AAC_DEQUANT = -9, + ERR_AAC_STEREO_PROCESS = -10, + ERR_AAC_PNS = -11, + ERR_AAC_SHORT_BLOCK_DEINT = -12, + ERR_AAC_TNS = -13, + ERR_AAC_IMDCT = -14, + ERR_AAC_NCHANS_TOO_HIGH = -15, + + ERR_AAC_SBR_INIT = -16, + ERR_AAC_SBR_BITSTREAM = -17, + ERR_AAC_SBR_DATA = -18, + ERR_AAC_SBR_PCM_FORMAT = -19, + ERR_AAC_SBR_NCHANS_TOO_HIGH = -20, + ERR_AAC_SBR_SINGLERATE_UNSUPPORTED = -21, + + ERR_AAC_RAWBLOCK_PARAMS = -22, + + ERR_AAC_UNKNOWN = -9999 }; typedef struct _AACFrameInfo { - int bitRate; - int nChans; - int sampRateCore; - int sampRateOut; - int bitsPerSample; - int outputSamps; - int profile; - int tnsUsed; - int pnsUsed; + int bitRate; + int nChans; + int sampRateCore; + int sampRateOut; + int bitsPerSample; + int outputSamps; + int profile; + int tnsUsed; + int pnsUsed; } AACFrameInfo; typedef void *HAACDecoder; diff --git a/src/libhelix-aac/aactabs.c b/src/libhelix-aac/aactabs.c index 1efa20ca..6cc70154 100644 --- a/src/libhelix-aac/aactabs.c +++ b/src/libhelix-aac/aactabs.c @@ -1,71 +1,71 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: aactabs.c,v 1.1 2005/02/26 01:47:31 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: aactabs.c,v 1.1 2005/02/26 01:47:31 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * February 2005 - * - * aactabs.c - platform-independent tables for AAC decoder (global, read-only) + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + February 2005 + + aactabs.c - platform-independent tables for AAC decoder (global, read-only) **************************************************************************************/ #include "aaccommon.h" /* sample rates (table 4.5.1) */ const int sampRateTab[NUM_SAMPLE_RATES] PROGMEM = { - 96000, 88200, 64000, 48000, 44100, 32000, - 24000, 22050, 16000, 12000, 11025, 8000 + 96000, 88200, 64000, 48000, 44100, 32000, + 24000, 22050, 16000, 12000, 11025, 8000 }; /* max scalefactor band for prediction (main profile only) */ const int predSFBMax[NUM_SAMPLE_RATES] PROGMEM = { - 33, 33, 38, 40, 40, 40, 41, 41, 37, 37, 37, 34 + 33, 33, 38, 40, 40, 40, 41, 41, 37, 37, 37, 34 }; /* channel mapping (table 1.6.3.4) (-1 = unknown, so need to determine mapping based on rules in 8.5.1) */ const int channelMapTab[NUM_DEF_CHAN_MAPS] PROGMEM = { - -1, 1, 2, 3, 4, 5, 6, 8 -}; + -1, 1, 2, 3, 4, 5, 6, 8 + }; -/* number of channels in each element (SCE, CPE, etc.) - * see AACElementID in aaccommon.h - */ +/* number of channels in each element (SCE, CPE, etc.) + see AACElementID in aaccommon.h +*/ const int elementNumChans[NUM_ELEMENTS] PROGMEM = { - 1, 2, 0, 1, 0, 0, 0, 0 + 1, 2, 0, 1, 0, 0, 0, 0 }; /* total number of scale factor bands in one window */ @@ -81,77 +81,77 @@ const unsigned int /*char*/ sfBandTotalLong[NUM_SAMPLE_RATES] PROGMEM = { const int sfBandTabShortOffset[NUM_SAMPLE_RATES] PROGMEM = {0, 0, 0, 13, 13, 13, 28, 28, 44, 44, 44, 60}; const /*short*/ int sfBandTabShort[76] PROGMEM = { - /* short block 64, 88, 96 kHz [13] (tables 4.5.24, 4.5.26) */ - 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128, + /* short block 64, 88, 96 kHz [13] (tables 4.5.24, 4.5.26) */ + 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128, - /* short block 32, 44, 48 kHz [15] (table 4.5.15) */ - 0, 4, 8, 12, 16, 20, 28, 36, 44, 56, 68, 80, 96, 112, 128, + /* short block 32, 44, 48 kHz [15] (table 4.5.15) */ + 0, 4, 8, 12, 16, 20, 28, 36, 44, 56, 68, 80, 96, 112, 128, - /* short block 22, 24 kHz [16] (table 4.5.22) */ - 0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 64, 76, 92, 108, 128, + /* short block 22, 24 kHz [16] (table 4.5.22) */ + 0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 64, 76, 92, 108, 128, - /* short block 11, 12, 16 kHz [16] (table 4.5.20) */ - 0, 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 60, 72, 88, 108, 128, + /* short block 11, 12, 16 kHz [16] (table 4.5.20) */ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 60, 72, 88, 108, 128, - /* short block 8 kHz [16] (table 4.5.18) */ - 0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 60, 72, 88, 108, 128 + /* short block 8 kHz [16] (table 4.5.18) */ + 0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 60, 72, 88, 108, 128 }; const int sfBandTabLongOffset[NUM_SAMPLE_RATES] PROGMEM = {0, 0, 42, 90, 90, 140, 192, 192, 240, 240, 240, 284}; const /*short*/ int sfBandTabLong[325] PROGMEM = { - /* long block 88, 96 kHz [42] (table 4.5.25) */ - 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, - 56, 64, 72, 80, 88, 96, 108, 120, 132, 144, 156, 172, 188, 212, - 240, 276, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024, - - /* long block 64 kHz [48] (table 4.5.13) */ - 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, - 72, 80, 88, 100, 112, 124, 140, 156, 172, 192, 216, 240, 268, 304, 344, 384, - 424, 464, 504, 544, 584, 624, 664, 704, 744, 784, 824, 864, 904, 944, 984, 1024, - - /* long block 44, 48 kHz [50] (table 4.5.14) */ - 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56, 64, 72, 80, 88, - 96, 108, 120, 132, 144, 160, 176, 196, 216, 240, 264, 292, 320, 352, 384, 416, 448, - 480, 512, 544, 576, 608, 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 1024, - - /* long block 32 kHz [52] (table 4.5.16) */ - 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56, 64, 72, 80, 88, 96, - 108, 120, 132, 144, 160, 176, 196, 216, 240, 264, 292, 320, 352, 384, 416, 448, 480, 512, - 544, 576, 608, 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 960, 992, 1024, - - /* long block 22, 24 kHz [48] (table 4.5.21) */ - 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 52, 60, 68, 76, - 84, 92, 100, 108, 116, 124, 136, 148, 160, 172, 188, 204, 220, 240, 260, 284, - 308, 336, 364, 396, 432, 468, 508, 552, 600, 652, 704, 768, 832, 896, 960, 1024, - - /* long block 11, 12, 16 kHz [44] (table 4.5.19) */ - 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 100, 112, 124, - 136, 148, 160, 172, 184, 196, 212, 228, 244, 260, 280, 300, 320, 344, 368, - 396, 424, 456, 492, 532, 572, 616, 664, 716, 772, 832, 896, 960, 1024, - - /* long block 8 kHz [41] (table 4.5.17) */ - 0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, - 172, 188, 204, 220, 236, 252, 268, 288, 308, 328, 348, 372, 396, 420, - 448, 476, 508, 544, 580, 620, 664, 712, 764, 820, 880, 944, 1024 + /* long block 88, 96 kHz [42] (table 4.5.25) */ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, + 56, 64, 72, 80, 88, 96, 108, 120, 132, 144, 156, 172, 188, 212, + 240, 276, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024, + + /* long block 64 kHz [48] (table 4.5.13) */ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, + 72, 80, 88, 100, 112, 124, 140, 156, 172, 192, 216, 240, 268, 304, 344, 384, + 424, 464, 504, 544, 584, 624, 664, 704, 744, 784, 824, 864, 904, 944, 984, 1024, + + /* long block 44, 48 kHz [50] (table 4.5.14) */ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56, 64, 72, 80, 88, + 96, 108, 120, 132, 144, 160, 176, 196, 216, 240, 264, 292, 320, 352, 384, 416, 448, + 480, 512, 544, 576, 608, 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 1024, + + /* long block 32 kHz [52] (table 4.5.16) */ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56, 64, 72, 80, 88, 96, + 108, 120, 132, 144, 160, 176, 196, 216, 240, 264, 292, 320, 352, 384, 416, 448, 480, 512, + 544, 576, 608, 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 960, 992, 1024, + + /* long block 22, 24 kHz [48] (table 4.5.21) */ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 52, 60, 68, 76, + 84, 92, 100, 108, 116, 124, 136, 148, 160, 172, 188, 204, 220, 240, 260, 284, + 308, 336, 364, 396, 432, 468, 508, 552, 600, 652, 704, 768, 832, 896, 960, 1024, + + /* long block 11, 12, 16 kHz [44] (table 4.5.19) */ + 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 100, 112, 124, + 136, 148, 160, 172, 184, 196, 212, 228, 244, 260, 280, 300, 320, 344, 368, + 396, 424, 456, 492, 532, 572, 616, 664, 716, 772, 832, 896, 960, 1024, + + /* long block 8 kHz [41] (table 4.5.17) */ + 0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, + 172, 188, 204, 220, 236, 252, 268, 288, 308, 328, 348, 372, 396, 420, + 448, 476, 508, 544, 580, 620, 664, 712, 764, 820, 880, 944, 1024 }; /* TNS max bands (table 4.139) and max order (table 4.138) */ const int tnsMaxBandsShortOffset[AAC_NUM_PROFILES] PROGMEM = {0, 0, 12}; -const unsigned /*char*/ int tnsMaxBandsShort[2*NUM_SAMPLE_RATES] PROGMEM = { - 9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, /* short block, Main/LC */ - 7, 7, 7, 6, 6, 6, 7, 7, 8, 8, 8, 7 /* short block, SSR */ +const unsigned /*char*/ int tnsMaxBandsShort[2 * NUM_SAMPLE_RATES] PROGMEM = { + 9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, /* short block, Main/LC */ + 7, 7, 7, 6, 6, 6, 7, 7, 8, 8, 8, 7 /* short block, SSR */ }; const unsigned /*char*/ int tnsMaxOrderShort[AAC_NUM_PROFILES] PROGMEM = {7, 7, 7}; const int tnsMaxBandsLongOffset[AAC_NUM_PROFILES] PROGMEM = {0, 0, 12}; -const unsigned int /*char*/ tnsMaxBandsLong[2*NUM_SAMPLE_RATES] PROGMEM = { - 31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39, /* long block, Main/LC */ - 28, 28, 27, 26, 26, 26, 29, 29, 23, 23, 23, 19, /* long block, SSR */ +const unsigned int /*char*/ tnsMaxBandsLong[2 * NUM_SAMPLE_RATES] PROGMEM = { + 31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39, /* long block, Main/LC */ + 28, 28, 27, 26, 26, 26, 29, 29, 23, 23, 23, 19, /* long block, SSR */ }; const unsigned /*char*/ int tnsMaxOrderLong[AAC_NUM_PROFILES] PROGMEM = {20, 12, 12}; diff --git a/src/libhelix-aac/assembly.h b/src/libhelix-aac/assembly.h index fc4d7673..3328f84a 100644 --- a/src/libhelix-aac/assembly.h +++ b/src/libhelix-aac/assembly.h @@ -1,115 +1,125 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: assembly.h,v 1.7 2005/11/10 00:04:40 margotm Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: assembly.h,v 1.7 2005/11/10 00:04:40 margotm Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * assembly.h - inline assembly language functions and prototypes - * - * MULSHIFT32(x, y) signed multiply of two 32-bit integers (x and y), - * returns top 32-bits of 64-bit result - * CLIPTOSHORT(x) convert 32-bit integer to 16-bit short, - * clipping to [-32768, 32767] - * FASTABS(x) branchless absolute value of signed integer x - * CLZ(x) count leading zeros on signed integer x - * MADD64(sum64, x, y) 64-bit multiply accumulate: sum64 += (x*y) + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + assembly.h - inline assembly language functions and prototypes + + MULSHIFT32(x, y) signed multiply of two 32-bit integers (x and y), + returns top 32-bits of 64-bit result + CLIPTOSHORT(x) convert 32-bit integer to 16-bit short, + clipping to [-32768, 32767] + FASTABS(x) branchless absolute value of signed integer x + CLZ(x) count leading zeros on signed integer x + MADD64(sum64, x, y) 64-bit multiply accumulate: sum64 += (x*y) **************************************************************************************/ #ifndef _ASSEMBLY_H #define _ASSEMBLY_H -/* toolchain: MSFT Visual C++ - * target architecture: x86 - */ +/* toolchain: MSFT Visual C++ + target architecture: x86 +*/ #if (defined (_WIN32) && !defined (_WIN32_WCE)) || (defined (__WINS__) && defined (_SYMBIAN)) || (defined (WINCE_EMULATOR)) || (defined (_OPENWAVE_SIMULATOR)) #pragma warning( disable : 4035 ) /* complains about inline asm not returning a value */ -static __inline int MULSHIFT32(int x, int y) -{ +static __inline int MULSHIFT32(int x, int y) { __asm { - mov eax, x - imul y - mov eax, edx - } + mov eax, x + imul y + mov eax, edx + } } -static __inline short CLIPTOSHORT(int x) -{ - int sign; +static __inline short CLIPTOSHORT(int x) { + int sign; - /* clip to [-32768, 32767] */ - sign = x >> 31; - if (sign != (x >> 15)) - x = sign ^ ((1 << 15) - 1); + /* clip to [-32768, 32767] */ + sign = x >> 31; + if (sign != (x >> 15)) { + x = sign ^ ((1 << 15) - 1); + } - return (short)x; + return (short)x; } -static __inline int FASTABS(int x) -{ - int sign; +static __inline int FASTABS(int x) { + int sign; - sign = x >> (sizeof(int) * 8 - 1); - x ^= sign; - x -= sign; + sign = x >> (sizeof(int) * 8 - 1); + x ^= sign; + x -= sign; - return x; + return x; } -static __inline int CLZ(int x) -{ - int numZeros; +static __inline int CLZ(int x) { + int numZeros; - if (!x) - return 32; + if (!x) { + return 32; + } - /* count leading zeros with binary search */ - numZeros = 1; - if (!((unsigned int)x >> 16)) { numZeros += 16; x <<= 16; } - if (!((unsigned int)x >> 24)) { numZeros += 8; x <<= 8; } - if (!((unsigned int)x >> 28)) { numZeros += 4; x <<= 4; } - if (!((unsigned int)x >> 30)) { numZeros += 2; x <<= 2; } + /* count leading zeros with binary search */ + numZeros = 1; + if (!((unsigned int)x >> 16)) { + numZeros += 16; + x <<= 16; + } + if (!((unsigned int)x >> 24)) { + numZeros += 8; + x <<= 8; + } + if (!((unsigned int)x >> 28)) { + numZeros += 4; + x <<= 4; + } + if (!((unsigned int)x >> 30)) { + numZeros += 2; + x <<= 2; + } - numZeros -= ((unsigned int)x >> 31); + numZeros -= ((unsigned int)x >> 31); - return numZeros; + return numZeros; } #ifdef __CW32__ @@ -119,20 +129,19 @@ typedef __int64 Word64; #endif typedef union _U64 { - Word64 w64; - struct { - /* x86 = little endian */ - unsigned int lo32; - signed int hi32; - } r; + Word64 w64; + struct { + /* x86 = little endian */ + unsigned int lo32; + signed int hi32; + } r; } U64; /* returns 64-bit value in [edx:eax] */ -static __inline Word64 MADD64(Word64 sum64, int x, int y) -{ +static __inline Word64 MADD64(Word64 sum64, int x, int y) { #if (defined (_SYMBIAN_61_) || defined (_SYMBIAN_70_)) && defined (__WINS__) && !defined (__CW32__) -/* Workaround for the Symbian emulator because of non existing longlong.lib and - * hence __allmul not defined. */ + /* Workaround for the Symbian emulator because of non existing longlong.lib and + hence __allmul not defined. */ __asm { mov eax, x imul y @@ -146,51 +155,62 @@ static __inline Word64 MADD64(Word64 sum64, int x, int y) return sum64; } -/* toolchain: MSFT Embedded Visual C++ - * target architecture: ARM v.4 and above (require 'M' type processor for 32x32->64 multiplier) - */ +/* toolchain: MSFT Embedded Visual C++ + target architecture: ARM v.4 and above (require 'M' type processor for 32x32->64 multiplier) +*/ #elif defined (_WIN32) && defined (_WIN32_WCE) && defined (ARM) -static __inline short CLIPTOSHORT(int x) -{ - int sign; +static __inline short CLIPTOSHORT(int x) { + int sign; - /* clip to [-32768, 32767] */ - sign = x >> 31; - if (sign != (x >> 15)) - x = sign ^ ((1 << 15) - 1); + /* clip to [-32768, 32767] */ + sign = x >> 31; + if (sign != (x >> 15)) { + x = sign ^ ((1 << 15) - 1); + } - return (short)x; + return (short)x; } -static __inline int FASTABS(int x) -{ - int sign; +static __inline int FASTABS(int x) { + int sign; - sign = x >> (sizeof(int) * 8 - 1); - x ^= sign; - x -= sign; + sign = x >> (sizeof(int) * 8 - 1); + x ^= sign; + x -= sign; - return x; + return x; } -static __inline int CLZ(int x) -{ - int numZeros; +static __inline int CLZ(int x) { + int numZeros; - if (!x) - return 32; + if (!x) { + return 32; + } - /* count leading zeros with binary search (function should be 17 ARM instructions total) */ - numZeros = 1; - if (!((unsigned int)x >> 16)) { numZeros += 16; x <<= 16; } - if (!((unsigned int)x >> 24)) { numZeros += 8; x <<= 8; } - if (!((unsigned int)x >> 28)) { numZeros += 4; x <<= 4; } - if (!((unsigned int)x >> 30)) { numZeros += 2; x <<= 2; } + /* count leading zeros with binary search (function should be 17 ARM instructions total) */ + numZeros = 1; + if (!((unsigned int)x >> 16)) { + numZeros += 16; + x <<= 16; + } + if (!((unsigned int)x >> 24)) { + numZeros += 8; + x <<= 8; + } + if (!((unsigned int)x >> 28)) { + numZeros += 4; + x <<= 4; + } + if (!((unsigned int)x >> 30)) { + numZeros += 2; + x <<= 2; + } - numZeros -= ((unsigned int)x >> 31); + numZeros -= ((unsigned int)x >> 31); - return numZeros; + return numZeros; } /* implemented in asmfunc.s */ @@ -201,12 +221,12 @@ extern "C" { typedef __int64 Word64; typedef union _U64 { - Word64 w64; - struct { - /* ARM WinCE = little endian */ - unsigned int lo32; - signed int hi32; - } r; + Word64 w64; + struct { + /* ARM WinCE = little endian */ + unsigned int lo32; + signed int hi32; + } r; } U64; /* manual name mangling for just this platform (must match labels in .s file) */ @@ -220,133 +240,141 @@ Word64 MADD64(Word64 sum64, int x, int y); } #endif -/* toolchain: ARM ADS or RealView - * target architecture: ARM v.4 and above (requires 'M' type processor for 32x32->64 multiplier) - */ -#elif defined (__arm) && defined (__ARMCC_VERSION) - -static __inline int MULSHIFT32(int x, int y) -{ - /* rules for smull RdLo, RdHi, Rm, Rs: - * RdHi != Rm - * RdLo != Rm - * RdHi != RdLo - */ +/* toolchain: ARM ADS or RealView + target architecture: ARM v.4 and above (requires 'M' type processor for 32x32->64 multiplier) +*/ +#elif defined (XXX__arm) && defined (__ARMCC_VERSION) + +static __inline int MULSHIFT32(int x, int y) { + /* rules for smull RdLo, RdHi, Rm, Rs: + RdHi != Rm + RdLo != Rm + RdHi != RdLo + */ int zlow; __asm { - smull zlow,y,x,y - } + smull zlow, y, x, y + } return y; } -static __inline short CLIPTOSHORT(int x) -{ - int sign; +static __inline short CLIPTOSHORT(int x) { + int sign; - /* clip to [-32768, 32767] */ - sign = x >> 31; - if (sign != (x >> 15)) - x = sign ^ ((1 << 15) - 1); + /* clip to [-32768, 32767] */ + sign = x >> 31; + if (sign != (x >> 15)) { + x = sign ^ ((1 << 15) - 1); + } - return (short)x; + return (short)x; } -static __inline int FASTABS(int x) -{ - int sign; +static __inline int FASTABS(int x) { + int sign; - sign = x >> (sizeof(int) * 8 - 1); - x ^= sign; - x -= sign; - - return x; -} - -static __inline int CLZ(int x) -{ - int numZeros; - - if (!x) - return 32; - - /* count leading zeros with binary search (function should be 17 ARM instructions total) */ - numZeros = 1; - if (!((unsigned int)x >> 16)) { numZeros += 16; x <<= 16; } - if (!((unsigned int)x >> 24)) { numZeros += 8; x <<= 8; } - if (!((unsigned int)x >> 28)) { numZeros += 4; x <<= 4; } - if (!((unsigned int)x >> 30)) { numZeros += 2; x <<= 2; } - - numZeros -= ((unsigned int)x >> 31); - - return numZeros; - -/* ARM code would look like this, but do NOT use inline asm in ADS for this, - because you can't safely use the status register flags intermixed with C code - - __asm { - mov numZeros, #1 - tst x, 0xffff0000 - addeq numZeros, numZeros, #16 - moveq x, x, lsl #16 - tst x, 0xff000000 - addeq numZeros, numZeros, #8 - moveq x, x, lsl #8 - tst x, 0xf0000000 - addeq numZeros, numZeros, #4 - moveq x, x, lsl #4 - tst x, 0xc0000000 - addeq numZeros, numZeros, #2 - moveq x, x, lsl #2 - sub numZeros, numZeros, x, lsr #31 - } -*/ -/* reference: - numZeros = 0; - while (!(x & 0x80000000)) { - numZeros++; - x <<= 1; - } -*/ + sign = x >> (sizeof(int) * 8 - 1); + x ^= sign; + x -= sign; + + return x; +} + +static __inline int CLZ(int x) { + int numZeros; + + if (!x) { + return 32; + } + + /* count leading zeros with binary search (function should be 17 ARM instructions total) */ + numZeros = 1; + if (!((unsigned int)x >> 16)) { + numZeros += 16; + x <<= 16; + } + if (!((unsigned int)x >> 24)) { + numZeros += 8; + x <<= 8; + } + if (!((unsigned int)x >> 28)) { + numZeros += 4; + x <<= 4; + } + if (!((unsigned int)x >> 30)) { + numZeros += 2; + x <<= 2; + } + + numZeros -= ((unsigned int)x >> 31); + + return numZeros; + + /* ARM code would look like this, but do NOT use inline asm in ADS for this, + because you can't safely use the status register flags intermixed with C code + + __asm { + mov numZeros, #1 + tst x, 0xffff0000 + addeq numZeros, numZeros, #16 + moveq x, x, lsl #16 + tst x, 0xff000000 + addeq numZeros, numZeros, #8 + moveq x, x, lsl #8 + tst x, 0xf0000000 + addeq numZeros, numZeros, #4 + moveq x, x, lsl #4 + tst x, 0xc0000000 + addeq numZeros, numZeros, #2 + moveq x, x, lsl #2 + sub numZeros, numZeros, x, lsr #31 + } + */ + /* reference: + numZeros = 0; + while (!(x & 0x80000000)) { + numZeros++; + x <<= 1; + } + */ } typedef __int64 Word64; typedef union _U64 { - Word64 w64; - struct { - /* ARM ADS = little endian */ - unsigned int lo32; - signed int hi32; - } r; + Word64 w64; + struct { + /* ARM ADS = little endian */ + unsigned int lo32; + signed int hi32; + } r; } U64; -static __inline Word64 MADD64(Word64 sum64, int x, int y) -{ - U64 u; - u.w64 = sum64; - - __asm { - smlal u.r.lo32, u.r.hi32, x, y - } +static __inline Word64 MADD64(Word64 sum64, int x, int y) { + U64 u; + u.w64 = sum64; + + __asm { + smlal u.r.lo32, u.r.hi32, x, y + } - return u.w64; + return u.w64; } -/* toolchain: ARM gcc - * target architecture: ARM v.4 and above (requires 'M' type processor for 32x32->64 multiplier) - */ -#elif defined(__GNUC__) && defined(__arm__) +/* toolchain: ARM gcc + target architecture: ARM v.4 and above (requires 'M' type processor for 32x32->64 multiplier) +*/ +#elif defined(__GNUC__) && defined(XXXX__arm__) -static inline int MULSHIFT32(int x, int y) -{ +static inline int MULSHIFT32(int x, int y) { int zlow; - asm ("smull %0,%1,%2,%3" : "=&r" (zlow), "=r" (y) : "r" (x), "1" (y) : "cc"); + asm("smull %0,%1,%2,%3" : "=&r"(zlow), "=r"(y) : "r"(x), "1"(y) : "cc"); return y; } /* -static inline short CLIPTOSHORT(int x) -{ + static inline short CLIPTOSHORT(int x) + { int sign; // clip to [-32768, 32767] // @@ -355,17 +383,16 @@ static inline short CLIPTOSHORT(int x) x = sign ^ ((1 << 15) - 1); return (short)x; -} -*/ -static inline short CLIPTOSHORT(int x) -{ - asm ("ssat %0, #16, %1" : "=r" (x) : "r" (x)); - return x; + } +*/ +static inline short CLIPTOSHORT(int x) { + asm("ssat %0, #16, %1" : "=r"(x) : "r"(x)); + return x; } -/* From coder.h, ORIGINAL: -clip to [-2^n, 2^n-1], valid range of n = [1, 30] -//TODO (FB) Is there a better way ? +/* From coder.h, ORIGINAL: + clip to [-2^n, 2^n-1], valid range of n = [1, 30] + //TODO (FB) Is there a better way ? */ #define CLIP_2N(y, n) { \ int sign = (y) >> 31; \ @@ -374,8 +401,8 @@ clip to [-2^n, 2^n-1], valid range of n = [1, 30] } \ } -/* From coder.h, ORIGINAL: - do y <<= n, clipping to range [-2^30, 2^30 - 1] (i.e. output has one guard bit) +/* From coder.h, ORIGINAL: + do y <<= n, clipping to range [-2^30, 2^30 - 1] (i.e. output has one guard bit) */ //TODO (FB) Is there a better way ? #define CLIP_2N_SHIFT(y, n) { \ @@ -393,192 +420,201 @@ clip to [-2^n, 2^n-1], valid range of n = [1, 30] #define CLZ(x) __builtin_clz(x) //FB //Reverse byte order (16 bit) //FB -static inline unsigned int REV16( unsigned int value) -{ - asm ("rev16 %0, %1" : "=r" (value) : "r" (value) ); - return(value); +static inline unsigned int REV16(unsigned int value) { + asm("rev16 %0, %1" : "=r"(value) : "r"(value)); + return (value); } //Reverse byte order (32 bit) //FB -static inline unsigned int REV32( unsigned int value) -{ - asm ("rev %0, %1" : "=r" (value) : "r" (value) ); - return(value); +static inline unsigned int REV32(unsigned int value) { + asm("rev %0, %1" : "=r"(value) : "r"(value)); + return (value); } typedef long long Word64; typedef union _U64 { - Word64 w64; - struct { - /* little endian */ - unsigned int lo32; - signed int hi32; - } r; + Word64 w64; + struct { + /* little endian */ + unsigned int lo32; + signed int hi32; + } r; } U64; -static inline Word64 MADD64(Word64 sum64, int x, int y) -{ - U64 u; - u.w64 = sum64; - asm ("smlal %0,%1,%2,%3" : "+&r" (u.r.lo32), "+&r" (u.r.hi32) : "r" (x), "r" (y) : "cc"); - return u.w64; +static inline Word64 MADD64(Word64 sum64, int x, int y) { + U64 u; + u.w64 = sum64; + asm("smlal %0,%1,%2,%3" : "+&r"(u.r.lo32), "+&r"(u.r.hi32) : "r"(x), "r"(y) : "cc"); + return u.w64; } -/* toolchain: x86 gcc - * target architecture: x86 - */ +/* toolchain: x86 gcc + target architecture: x86 +*/ #elif defined(__GNUC__) && (defined(__i386__) || defined(__amd64__)) || (defined (_SOLARIS) && !defined (__GNUC__) && defined(_SOLARISX86)) typedef long long Word64; -static __inline__ int MULSHIFT32(int x, int y) -{ +static __inline__ int MULSHIFT32(int x, int y) { int z; z = (Word64)x * (Word64)y >> 32; - - return z; + + return z; } -static __inline short CLIPTOSHORT(int x) -{ - int sign; +static __inline short CLIPTOSHORT(int x) { + int sign; - /* clip to [-32768, 32767] */ - sign = x >> 31; - if (sign != (x >> 15)) - x = sign ^ ((1 << 15) - 1); + /* clip to [-32768, 32767] */ + sign = x >> 31; + if (sign != (x >> 15)) { + x = sign ^ ((1 << 15) - 1); + } - return (short)x; + return (short)x; } -static __inline int FASTABS(int x) -{ - int sign; +static __inline int FASTABS(int x) { + int sign; - sign = x >> (sizeof(int) * 8 - 1); - x ^= sign; - x -= sign; + sign = x >> (sizeof(int) * 8 - 1); + x ^= sign; + x -= sign; - return x; + return x; } -static __inline int CLZ(int x) -{ - int numZeros; +static __inline int CLZ(int x) { + int numZeros; - if (!x) - return 32; + if (!x) { + return 32; + } - /* count leading zeros with binary search (function should be 17 ARM instructions total) */ - numZeros = 1; - if (!((unsigned int)x >> 16)) { numZeros += 16; x <<= 16; } - if (!((unsigned int)x >> 24)) { numZeros += 8; x <<= 8; } - if (!((unsigned int)x >> 28)) { numZeros += 4; x <<= 4; } - if (!((unsigned int)x >> 30)) { numZeros += 2; x <<= 2; } + /* count leading zeros with binary search (function should be 17 ARM instructions total) */ + numZeros = 1; + if (!((unsigned int)x >> 16)) { + numZeros += 16; + x <<= 16; + } + if (!((unsigned int)x >> 24)) { + numZeros += 8; + x <<= 8; + } + if (!((unsigned int)x >> 28)) { + numZeros += 4; + x <<= 4; + } + if (!((unsigned int)x >> 30)) { + numZeros += 2; + x <<= 2; + } - numZeros -= ((unsigned int)x >> 31); + numZeros -= ((unsigned int)x >> 31); - return numZeros; + return numZeros; } typedef union _U64 { - Word64 w64; - struct { - /* x86 = little endian */ - unsigned int lo32; - signed int hi32; - } r; + Word64 w64; + struct { + /* x86 = little endian */ + unsigned int lo32; + signed int hi32; + } r; } U64; -static __inline Word64 MADD64(Word64 sum64, int x, int y) -{ - sum64 += (Word64)x * (Word64)y; +static __inline Word64 MADD64(Word64 sum64, int x, int y) { + sum64 += (Word64)x * (Word64)y; - return sum64; + return sum64; } -#elif defined(ARDUINO) || defined(__GNUC__) && (defined(__powerpc__) || defined(__POWERPC__)) || (defined (_SOLARIS) && !defined (__GNUC__) && !defined (_SOLARISX86)) +#elif defined(ARDUINO) || defined(__GNUC__) && (defined(__mips__) || defined(__MIPS__)) || defined(__GNUC__) && (defined(__powerpc__) || defined(__POWERPC__)) || (defined (_SOLARIS) && !defined (__GNUC__) && !defined (_SOLARISX86)) typedef long long Word64; -static __inline__ int MULSHIFT32(int x, int y) -{ +static __inline__ int MULSHIFT32(int x, int y) { int z; z = (Word64)x * (Word64)y >> 32; - - return z; + + return z; } -static __inline short CLIPTOSHORT(int x) -{ - int sign; +static __inline short CLIPTOSHORT(int x) { + int sign; - /* clip to [-32768, 32767] */ - sign = x >> 31; - if (sign != (x >> 15)) - x = sign ^ ((1 << 15) - 1); + /* clip to [-32768, 32767] */ + sign = x >> 31; + if (sign != (x >> 15)) { + x = sign ^ ((1 << 15) - 1); + } - return (short)x; + return (short)x; } -static __inline int FASTABS(int x) -{ - int sign; +static __inline int FASTABS(int x) { + int sign; - sign = x >> (sizeof(int) * 8 - 1); - x ^= sign; - x -= sign; + sign = x >> (sizeof(int) * 8 - 1); + x ^= sign; + x -= sign; - return x; + return x; } -static __inline int CLZ(int x) -{ - int numZeros; +static __inline int CLZ(int x) { + int numZeros; - if (!x) - return 32; + if (!x) { + return 32; + } - /* count leading zeros with binary search (function should be 17 ARM instructions total) */ - numZeros = 1; - if (!((unsigned int)x >> 16)) { numZeros += 16; x <<= 16; } - if (!((unsigned int)x >> 24)) { numZeros += 8; x <<= 8; } - if (!((unsigned int)x >> 28)) { numZeros += 4; x <<= 4; } - if (!((unsigned int)x >> 30)) { numZeros += 2; x <<= 2; } + /* count leading zeros with binary search (function should be 17 ARM instructions total) */ + numZeros = 1; + if (!((unsigned int)x >> 16)) { + numZeros += 16; + x <<= 16; + } + if (!((unsigned int)x >> 24)) { + numZeros += 8; + x <<= 8; + } + if (!((unsigned int)x >> 28)) { + numZeros += 4; + x <<= 4; + } + if (!((unsigned int)x >> 30)) { + numZeros += 2; + x <<= 2; + } - numZeros -= ((unsigned int)x >> 31); + numZeros -= ((unsigned int)x >> 31); - return numZeros; + return numZeros; } typedef union _U64 { - Word64 w64; - struct { -#ifdef __XTENSA__ - unsigned int lo32; - signed int hi32; -#else - /* PowerPC = big endian */ - signed int hi32; - unsigned int lo32; -#endif - } r; + Word64 w64; + struct { + unsigned int lo32; + signed int hi32; + } r; } U64; -static __inline Word64 MADD64(Word64 sum64, int x, int y) -{ - sum64 += (Word64)x * (Word64)y; +static __inline Word64 MADD64(Word64 sum64, int x, int y) { + sum64 += (Word64)x * (Word64)y; - return sum64; + return sum64; } -/* From coder.h, ORIGINAL: -clip to [-2^n, 2^n-1], valid range of n = [1, 30] -//TODO (FB) Is there a better way ? +/* From coder.h, ORIGINAL: + clip to [-2^n, 2^n-1], valid range of n = [1, 30] + //TODO (FB) Is there a better way ? */ #define CLIP_2N(y, n) { \ int sign = (y) >> 31; \ @@ -587,8 +623,8 @@ clip to [-2^n, 2^n-1], valid range of n = [1, 30] } \ } -/* From coder.h, ORIGINAL: - do y <<= n, clipping to range [-2^30, 2^30 - 1] (i.e. output has one guard bit) +/* From coder.h, ORIGINAL: + do y <<= n, clipping to range [-2^30, 2^30 - 1] (i.e. output has one guard bit) */ //TODO (FB) Is there a better way ? #define CLIP_2N_SHIFT(y, n) { \ @@ -621,8 +657,8 @@ clip to [-2^n, 2^n-1], valid range of n = [1, 30] #endif #ifndef CLIP_2N_SHIFT -/* From coder.h, ORIGINAL: - do y <<= n, clipping to range [-2^30, 2^30 - 1] (i.e. output has one guard bit) +/* From coder.h, ORIGINAL: + do y <<= n, clipping to range [-2^30, 2^30 - 1] (i.e. output has one guard bit) */ //TODO (FB) Is there a better way ? #define CLIP_2N_SHIFT(y, n) { \ diff --git a/src/libhelix-aac/bitstream.c b/src/libhelix-aac/bitstream.c index 09cb3f65..08f6bc15 100644 --- a/src/libhelix-aac/bitstream.c +++ b/src/libhelix-aac/bitstream.c @@ -1,261 +1,255 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: bitstream.c,v 1.2 2005/09/27 20:31:11 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: bitstream.c,v 1.2 2005/09/27 20:31:11 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * bitstream.c - bitstream parsing functions + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + bitstream.c - bitstream parsing functions **************************************************************************************/ #include "bitstream.h" /************************************************************************************** - * Function: SetBitstreamPointer - * - * Description: initialize bitstream reader - * - * Inputs: pointer to BitStreamInfo struct - * number of bytes in bitstream - * pointer to byte-aligned buffer of data to read from - * - * Outputs: initialized bitstream info struct - * - * Return: none + Function: SetBitstreamPointer + + Description: initialize bitstream reader + + Inputs: pointer to BitStreamInfo struct + number of bytes in bitstream + pointer to byte-aligned buffer of data to read from + + Outputs: initialized bitstream info struct + + Return: none **************************************************************************************/ -void SetBitstreamPointer(BitStreamInfo *bsi, int nBytes, unsigned char *buf) -{ - /* init bitstream */ - bsi->bytePtr = buf; - bsi->iCache = 0; /* 4-byte unsigned int */ - bsi->cachedBits = 0; /* i.e. zero bits in cache */ - bsi->nBytes = nBytes; +void SetBitstreamPointer(BitStreamInfo *bsi, int nBytes, unsigned char *buf) { + /* init bitstream */ + bsi->bytePtr = buf; + bsi->iCache = 0; /* 4-byte unsigned int */ + bsi->cachedBits = 0; /* i.e. zero bits in cache */ + bsi->nBytes = nBytes; } /************************************************************************************** - * Function: RefillBitstreamCache - * - * Description: read new data from bitstream buffer into 32-bit cache - * - * Inputs: pointer to initialized BitStreamInfo struct - * - * Outputs: updated bitstream info struct - * - * Return: none - * - * Notes: only call when iCache is completely drained (resets bitOffset to 0) - * always loads 4 new bytes except when bsi->nBytes < 4 (end of buffer) - * stores data as big-endian in cache, regardless of machine endian-ness + Function: RefillBitstreamCache + + Description: read new data from bitstream buffer into 32-bit cache + + Inputs: pointer to initialized BitStreamInfo struct + + Outputs: updated bitstream info struct + + Return: none + + Notes: only call when iCache is completely drained (resets bitOffset to 0) + always loads 4 new bytes except when bsi->nBytes < 4 (end of buffer) + stores data as big-endian in cache, regardless of machine endian-ness **************************************************************************************/ //Optimized for REV16, REV32 (FB) -static __inline void RefillBitstreamCache(BitStreamInfo *bsi) -{ - int nBytes = bsi->nBytes; - if (nBytes >= 4) { - /* optimize for common case, independent of machine endian-ness */ - bsi->iCache = (*bsi->bytePtr++) << 24; - bsi->iCache |= (*bsi->bytePtr++) << 16; - bsi->iCache |= (*bsi->bytePtr++) << 8; - bsi->iCache |= (*bsi->bytePtr++); - - bsi->cachedBits = 32; - bsi->nBytes -= 4; - } else { - bsi->iCache = 0; - while (nBytes--) { - bsi->iCache |= (*bsi->bytePtr++); - bsi->iCache <<= 8; - } - bsi->iCache <<= ((3 - bsi->nBytes)*8); - bsi->cachedBits = 8*bsi->nBytes; - bsi->nBytes = 0; - } +static __inline void RefillBitstreamCache(BitStreamInfo *bsi) { + int nBytes = bsi->nBytes; + if (nBytes >= 4) { + /* optimize for common case, independent of machine endian-ness */ + bsi->iCache = (*bsi->bytePtr++) << 24; + bsi->iCache |= (*bsi->bytePtr++) << 16; + bsi->iCache |= (*bsi->bytePtr++) << 8; + bsi->iCache |= (*bsi->bytePtr++); + + bsi->cachedBits = 32; + bsi->nBytes -= 4; + } else { + bsi->iCache = 0; + while (nBytes--) { + bsi->iCache |= (*bsi->bytePtr++); + bsi->iCache <<= 8; + } + bsi->iCache <<= ((3 - bsi->nBytes) * 8); + bsi->cachedBits = 8 * bsi->nBytes; + bsi->nBytes = 0; + } } /************************************************************************************** - * Function: GetBits - * - * Description: get bits from bitstream, advance bitstream pointer - * - * Inputs: pointer to initialized BitStreamInfo struct - * number of bits to get from bitstream - * - * Outputs: updated bitstream info struct - * - * Return: the next nBits bits of data from bitstream buffer - * - * Notes: nBits must be in range [0, 31], nBits outside this range masked by 0x1f - * for speed, does not indicate error if you overrun bit buffer - * if nBits == 0, returns 0 + Function: GetBits + + Description: get bits from bitstream, advance bitstream pointer + + Inputs: pointer to initialized BitStreamInfo struct + number of bits to get from bitstream + + Outputs: updated bitstream info struct + + Return: the next nBits bits of data from bitstream buffer + + Notes: nBits must be in range [0, 31], nBits outside this range masked by 0x1f + for speed, does not indicate error if you overrun bit buffer + if nBits == 0, returns 0 **************************************************************************************/ -unsigned int GetBits(BitStreamInfo *bsi, int nBits) -{ - unsigned int data, lowBits; - - nBits &= 0x1f; /* nBits mod 32 to avoid unpredictable results like >> by negative amount */ - data = bsi->iCache >> (31 - nBits); /* unsigned >> so zero-extend */ - data >>= 1; /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */ - bsi->iCache <<= nBits; /* left-justify cache */ - bsi->cachedBits -= nBits; /* how many bits have we drawn from the cache so far */ - - /* if we cross an int boundary, refill the cache */ - if (bsi->cachedBits < 0) { - lowBits = -bsi->cachedBits; - RefillBitstreamCache(bsi); - data |= bsi->iCache >> (32 - lowBits); /* get the low-order bits */ - - bsi->cachedBits -= lowBits; /* how many bits have we drawn from the cache so far */ - bsi->iCache <<= lowBits; /* left-justify cache */ - } - - return data; +unsigned int GetBits(BitStreamInfo *bsi, int nBits) { + unsigned int data, lowBits; + + nBits &= 0x1f; /* nBits mod 32 to avoid unpredictable results like >> by negative amount */ + data = bsi->iCache >> (31 - nBits); /* unsigned >> so zero-extend */ + data >>= 1; /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */ + bsi->iCache <<= nBits; /* left-justify cache */ + bsi->cachedBits -= nBits; /* how many bits have we drawn from the cache so far */ + + /* if we cross an int boundary, refill the cache */ + if (bsi->cachedBits < 0) { + lowBits = -bsi->cachedBits; + RefillBitstreamCache(bsi); + data |= bsi->iCache >> (32 - lowBits); /* get the low-order bits */ + + bsi->cachedBits -= lowBits; /* how many bits have we drawn from the cache so far */ + bsi->iCache <<= lowBits; /* left-justify cache */ + } + + return data; } /************************************************************************************** - * Function: GetBitsNoAdvance - * - * Description: get bits from bitstream, do not advance bitstream pointer - * - * Inputs: pointer to initialized BitStreamInfo struct - * number of bits to get from bitstream - * - * Outputs: none (state of BitStreamInfo struct left unchanged) - * - * Return: the next nBits bits of data from bitstream buffer - * - * Notes: nBits must be in range [0, 31], nBits outside this range masked by 0x1f - * for speed, does not indicate error if you overrun bit buffer - * if nBits == 0, returns 0 + Function: GetBitsNoAdvance + + Description: get bits from bitstream, do not advance bitstream pointer + + Inputs: pointer to initialized BitStreamInfo struct + number of bits to get from bitstream + + Outputs: none (state of BitStreamInfo struct left unchanged) + + Return: the next nBits bits of data from bitstream buffer + + Notes: nBits must be in range [0, 31], nBits outside this range masked by 0x1f + for speed, does not indicate error if you overrun bit buffer + if nBits == 0, returns 0 **************************************************************************************/ -unsigned int GetBitsNoAdvance(BitStreamInfo *bsi, int nBits) -{ - unsigned char *buf; - unsigned int data, iCache; - signed int lowBits; - - nBits &= 0x1f; /* nBits mod 32 to avoid unpredictable results like >> by negative amount */ - data = bsi->iCache >> (31 - nBits); /* unsigned >> so zero-extend */ - data >>= 1; /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */ - lowBits = nBits - bsi->cachedBits; /* how many bits do we have left to read */ - - /* if we cross an int boundary, read next bytes in buffer */ - if (lowBits > 0) { - iCache = 0; - buf = bsi->bytePtr; - while (lowBits > 0) { - iCache <<= 8; - if (buf < bsi->bytePtr + bsi->nBytes) - iCache |= (unsigned int)*buf++; - lowBits -= 8; - } - lowBits = -lowBits; - data |= iCache >> lowBits; - } - - return data; +unsigned int GetBitsNoAdvance(BitStreamInfo *bsi, int nBits) { + unsigned char *buf; + unsigned int data, iCache; + signed int lowBits; + + nBits &= 0x1f; /* nBits mod 32 to avoid unpredictable results like >> by negative amount */ + data = bsi->iCache >> (31 - nBits); /* unsigned >> so zero-extend */ + data >>= 1; /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */ + lowBits = nBits - bsi->cachedBits; /* how many bits do we have left to read */ + + /* if we cross an int boundary, read next bytes in buffer */ + if (lowBits > 0) { + iCache = 0; + buf = bsi->bytePtr; + while (lowBits > 0) { + iCache <<= 8; + if (buf < bsi->bytePtr + bsi->nBytes) { + iCache |= (unsigned int) * buf++; + } + lowBits -= 8; + } + lowBits = -lowBits; + data |= iCache >> lowBits; + } + + return data; } /************************************************************************************** - * Function: AdvanceBitstream - * - * Description: move bitstream pointer ahead - * - * Inputs: pointer to initialized BitStreamInfo struct - * number of bits to advance bitstream - * - * Outputs: updated bitstream info struct - * - * Return: none - * - * Notes: generally used following GetBitsNoAdvance(bsi, maxBits) + Function: AdvanceBitstream + + Description: move bitstream pointer ahead + + Inputs: pointer to initialized BitStreamInfo struct + number of bits to advance bitstream + + Outputs: updated bitstream info struct + + Return: none + + Notes: generally used following GetBitsNoAdvance(bsi, maxBits) **************************************************************************************/ -void AdvanceBitstream(BitStreamInfo *bsi, int nBits) -{ - nBits &= 0x1f; - if (nBits > bsi->cachedBits) { - nBits -= bsi->cachedBits; - RefillBitstreamCache(bsi); - } - bsi->iCache <<= nBits; - bsi->cachedBits -= nBits; +void AdvanceBitstream(BitStreamInfo *bsi, int nBits) { + nBits &= 0x1f; + if (nBits > bsi->cachedBits) { + nBits -= bsi->cachedBits; + RefillBitstreamCache(bsi); + } + bsi->iCache <<= nBits; + bsi->cachedBits -= nBits; } /************************************************************************************** - * Function: CalcBitsUsed - * - * Description: calculate how many bits have been read from bitstream - * - * Inputs: pointer to initialized BitStreamInfo struct - * pointer to start of bitstream buffer - * bit offset into first byte of startBuf (0-7) - * - * Outputs: none - * - * Return: number of bits read from bitstream, as offset from startBuf:startOffset + Function: CalcBitsUsed + + Description: calculate how many bits have been read from bitstream + + Inputs: pointer to initialized BitStreamInfo struct + pointer to start of bitstream buffer + bit offset into first byte of startBuf (0-7) + + Outputs: none + + Return: number of bits read from bitstream, as offset from startBuf:startOffset **************************************************************************************/ -int CalcBitsUsed(BitStreamInfo *bsi, unsigned char *startBuf, int startOffset) -{ - int bitsUsed; +int CalcBitsUsed(BitStreamInfo *bsi, unsigned char *startBuf, int startOffset) { + int bitsUsed; - bitsUsed = (bsi->bytePtr - startBuf) * 8; - bitsUsed -= bsi->cachedBits; - bitsUsed -= startOffset; + bitsUsed = (bsi->bytePtr - startBuf) * 8; + bitsUsed -= bsi->cachedBits; + bitsUsed -= startOffset; - return bitsUsed; + return bitsUsed; } /************************************************************************************** - * Function: ByteAlignBitstream - * - * Description: bump bitstream pointer to start of next byte - * - * Inputs: pointer to initialized BitStreamInfo struct - * - * Outputs: byte-aligned bitstream BitStreamInfo struct - * - * Return: none - * - * Notes: if bitstream is already byte-aligned, do nothing + Function: ByteAlignBitstream + + Description: bump bitstream pointer to start of next byte + + Inputs: pointer to initialized BitStreamInfo struct + + Outputs: byte-aligned bitstream BitStreamInfo struct + + Return: none + + Notes: if bitstream is already byte-aligned, do nothing **************************************************************************************/ -void ByteAlignBitstream(BitStreamInfo *bsi) -{ - int offset; +void ByteAlignBitstream(BitStreamInfo *bsi) { + int offset; - offset = bsi->cachedBits & 0x07; - AdvanceBitstream(bsi, offset); + offset = bsi->cachedBits & 0x07; + AdvanceBitstream(bsi, offset); } diff --git a/src/libhelix-aac/bitstream.h b/src/libhelix-aac/bitstream.h index de68a989..d42343dc 100644 --- a/src/libhelix-aac/bitstream.h +++ b/src/libhelix-aac/bitstream.h @@ -1,46 +1,46 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: bitstream.h,v 1.1 2005/02/26 01:47:34 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: bitstream.h,v 1.1 2005/02/26 01:47:34 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * bitstream.h - definitions of bitstream handling functions + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + bitstream.h - definitions of bitstream handling functions **************************************************************************************/ #ifndef _BITSTREAM_H @@ -57,10 +57,10 @@ #define ByteAlignBitstream STATNAME(ByteAlignBitstream) typedef struct _BitStreamInfo { - unsigned char *bytePtr; - unsigned int iCache; - int cachedBits; - int nBytes; + unsigned char *bytePtr; + unsigned int iCache; + int cachedBits; + int nBytes; } BitStreamInfo; /* bitstream.c */ diff --git a/src/libhelix-aac/buffers.c b/src/libhelix-aac/buffers.c index 5acc61b4..a9ddf8be 100644 --- a/src/libhelix-aac/buffers.c +++ b/src/libhelix-aac/buffers.c @@ -1,46 +1,46 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: buffers.c,v 1.1 2005/02/26 01:47:34 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: buffers.c,v 1.1 2005/02/26 01:47:34 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * buffers.c - allocation and deallocation of internal AAC decoder buffers + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + buffers.c - allocation and deallocation of internal AAC decoder buffers **************************************************************************************/ #if defined(USE_DEFAULT_STDLIB) || defined(ARDUINO) @@ -52,90 +52,89 @@ #include "coder.h" /************************************************************************************** - * Function: ClearBuffer - * - * Description: fill buffer with 0's - * - * Inputs: pointer to buffer - * number of bytes to fill with 0 - * - * Outputs: cleared buffer - * - * Return: none - * - * Notes: slow, platform-independent equivalent to memset(buf, 0, nBytes) + Function: ClearBuffer + + Description: fill buffer with 0's + + Inputs: pointer to buffer + number of bytes to fill with 0 + + Outputs: cleared buffer + + Return: none + + Notes: slow, platform-independent equivalent to memset(buf, 0, nBytes) **************************************************************************************/ #include - void ClearBuffer(void *buf, int nBytes) -{ -/* int i; - unsigned char *cbuf = (unsigned char *)buf; +void ClearBuffer(void *buf, int nBytes) { + /* int i; + unsigned char *cbuf = (unsigned char *)buf; - for (i = 0; i < nBytes; i++) - cbuf[i] = 0; + for (i = 0; i < nBytes; i++) + cbuf[i] = 0; - return; - */ - memset(buf, 0, nBytes); + return; + */ + memset(buf, 0, nBytes); } /************************************************************************************** - * Function: AllocateBuffers - * - * Description: allocate all the memory needed for the AAC decoder - * - * Inputs: none - * - * Outputs: none - * - * Return: pointer to AACDecInfo structure, cleared to all 0's (except for - * pointer to platform-specific data structure) - * - * Notes: if one or more mallocs fail, function frees any buffers already - * allocated before returning + Function: AllocateBuffers + + Description: allocate all the memory needed for the AAC decoder + + Inputs: none + + Outputs: none + + Return: pointer to AACDecInfo structure, cleared to all 0's (except for + pointer to platform-specific data structure) + + Notes: if one or more mallocs fail, function frees any buffers already + allocated before returning **************************************************************************************/ -AACDecInfo *AllocateBuffers(void) -{ - AACDecInfo *aacDecInfo; - - aacDecInfo = (AACDecInfo *)malloc(sizeof(AACDecInfo)); - if (!aacDecInfo) - return 0; - ClearBuffer(aacDecInfo, sizeof(AACDecInfo)); - - aacDecInfo->psInfoBase = malloc(sizeof(PSInfoBase)); - if (!aacDecInfo->psInfoBase) { - FreeBuffers(aacDecInfo); - return 0; - } - ClearBuffer(aacDecInfo->psInfoBase, sizeof(PSInfoBase)); - - return aacDecInfo; +AACDecInfo *AllocateBuffers(void) { + AACDecInfo *aacDecInfo; + + aacDecInfo = (AACDecInfo *)malloc(sizeof(AACDecInfo)); + if (!aacDecInfo) { + return 0; + } + ClearBuffer(aacDecInfo, sizeof(AACDecInfo)); + + aacDecInfo->psInfoBase = malloc(sizeof(PSInfoBase)); + if (!aacDecInfo->psInfoBase) { + FreeBuffers(aacDecInfo); + return 0; + } + ClearBuffer(aacDecInfo->psInfoBase, sizeof(PSInfoBase)); + + return aacDecInfo; } -AACDecInfo *AllocateBuffersPre(void **ptr, int *sz) -{ - AACDecInfo *aacDecInfo; - - char *p = (char*)*ptr; - aacDecInfo = (AACDecInfo *)p; - p += (sizeof(AACDecInfo) +7 ) & ~7; - *sz -= (sizeof(AACDecInfo) +7 ) & ~7; - if (*sz < 0) - return 0; - ClearBuffer(aacDecInfo, sizeof(AACDecInfo)); - - aacDecInfo->psInfoBase = (PSInfoBase*)p; - p += (sizeof(PSInfoBase) + 7) & ~7; - *sz -= (sizeof(PSInfoBase) + 7) & ~7; - if (*sz <0) { - return 0; - } - ClearBuffer(aacDecInfo->psInfoBase, sizeof(PSInfoBase)); - - *ptr = p; - - return aacDecInfo; +AACDecInfo *AllocateBuffersPre(void **ptr, int *sz) { + AACDecInfo *aacDecInfo; + + char *p = (char*)*ptr; + aacDecInfo = (AACDecInfo *)p; + p += (sizeof(AACDecInfo) + 7) & ~7; + *sz -= (sizeof(AACDecInfo) + 7) & ~7; + if (*sz < 0) { + return 0; + } + ClearBuffer(aacDecInfo, sizeof(AACDecInfo)); + + aacDecInfo->psInfoBase = (PSInfoBase*)p; + p += (sizeof(PSInfoBase) + 7) & ~7; + *sz -= (sizeof(PSInfoBase) + 7) & ~7; + if (*sz < 0) { + return 0; + } + ClearBuffer(aacDecInfo->psInfoBase, sizeof(PSInfoBase)); + + *ptr = p; + + return aacDecInfo; } #ifndef SAFE_FREE @@ -143,23 +142,23 @@ AACDecInfo *AllocateBuffersPre(void **ptr, int *sz) #endif /************************************************************************************** - * Function: FreeBuffers - * - * Description: frees all the memory used by the AAC decoder - * - * Inputs: pointer to initialized AACDecInfo structure - * - * Outputs: none - * - * Return: none - * - * Notes: safe to call even if some buffers were not allocated (uses SAFE_FREE) + Function: FreeBuffers + + Description: frees all the memory used by the AAC decoder + + Inputs: pointer to initialized AACDecInfo structure + + Outputs: none + + Return: none + + Notes: safe to call even if some buffers were not allocated (uses SAFE_FREE) **************************************************************************************/ -void FreeBuffers(AACDecInfo *aacDecInfo) -{ - if (!aacDecInfo) - return; +void FreeBuffers(AACDecInfo *aacDecInfo) { + if (!aacDecInfo) { + return; + } - SAFE_FREE(aacDecInfo->psInfoBase); - SAFE_FREE(aacDecInfo); + SAFE_FREE(aacDecInfo->psInfoBase); + SAFE_FREE(aacDecInfo); } diff --git a/src/libhelix-aac/coder.h b/src/libhelix-aac/coder.h index 9609e393..05628374 100644 --- a/src/libhelix-aac/coder.h +++ b/src/libhelix-aac/coder.h @@ -1,46 +1,46 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: coder.h,v 1.2 2005/06/27 21:06:00 gwright Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: coder.h,v 1.2 2005/06/27 21:06:00 gwright Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * coder.h - definitions of platform-specific data structures, functions, and tables + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + coder.h - definitions of platform-specific data structures, functions, and tables **************************************************************************************/ #ifndef _CODER_H @@ -91,7 +91,7 @@ /* do y <<= n, clipping to range [-2^30, 2^30 - 1] (i.e. output has one guard bit) */ /* -#define CLIP_2N_SHIFT(y, n) { \ + #define CLIP_2N_SHIFT(y, n) { \ int sign = (y) >> 31; \ if (sign != (y) >> (30 - (n))) { \ (y) = sign ^ (0x3fffffff); \ @@ -102,12 +102,12 @@ */ /* clip to [-2^n, 2^n-1], valid range of n = [1, 30] */ /* -#define CLIP_2N(val, n) { \ + #define CLIP_2N(val, n) { \ if ((val) >> 31 != (val) >> (n)) \ (val) = ((val) >> 31) ^ ((1 << (n)) - 1); \ } */ - + #define SF_DQ_OFFSET 15 #define FBITS_OUT_DQ 20 @@ -247,7 +247,7 @@ typedef struct _ProgConfigElement { unsigned char numCCE; /* number of valid channel coupling elements (max = 15) */ unsigned char monoMixdown; /* mono mixdown: bit 4 = present flag, bits 3-0 = element number */ unsigned char stereoMixdown; /* stereo mixdown: bit 4 = present flag, bits 3-0 = element number */ - unsigned char matrixMixdown; /* matrix mixdown: bit 4 = present flag, bit 3 = unused, + unsigned char matrixMixdown; /* matrix mixdown: bit 4 = present flag, bit 3 = unused, bits 2-1 = index, bit 0 = pseudo-surround enable */ unsigned char fce[MAX_NUM_FCE]; /* front element channel pair: bit 4 = SCE/CPE flag, bits 3-0 = inst tag */ unsigned char sce[MAX_NUM_SCE]; /* side element channel pair: bit 4 = SCE/CPE flag, bits 3-0 = inst tag */ @@ -341,7 +341,7 @@ void DecWindowOverlapShortNoClip(int *buf0, int *over0, int *out0, int winTypeCu /* hufftabs.c */ extern const HuffInfo huffTabSpecInfo[11]; extern const signed short huffTabSpec[1241]; -extern const HuffInfo huffTabScaleFactInfo; +extern const HuffInfo huffTabScaleFactInfo; extern const signed short huffTabScaleFact[121]; /* trigtabs.c */ @@ -357,16 +357,16 @@ extern int cos4sin4tab[128 + 1024]; extern int cos1sin1tab[514]; extern int sinWindow[128 + 1024]; extern int kbdWindow[128 + 1024]; -extern int twidTabEven[4*6 + 16*6 + 64*6]; -extern int twidTabOdd[8*6 + 32*6 + 128*6]; +extern int twidTabEven[4 * 6 + 16 * 6 + 64 * 6]; +extern int twidTabOdd[8 * 6 + 32 * 6 + 128 * 6]; #else /* trigtabs.c */ extern const int cos4sin4tab[128 + 1024]; extern const int cos1sin1tab[514]; extern const int sinWindow[128 + 1024]; extern const int kbdWindow[128 + 1024]; -extern const int twidTabEven[4*6 + 16*6 + 64*6]; -extern const int twidTabOdd[8*6 + 32*6 + 128*6]; +extern const int twidTabEven[4 * 6 + 16 * 6 + 64 * 6]; +extern const int twidTabOdd[8 * 6 + 32 * 6 + 128 * 6]; #endif #endif /* _CODER_H */ diff --git a/src/libhelix-aac/dct4.c b/src/libhelix-aac/dct4.c index 698f54b6..0b8d22eb 100644 --- a/src/libhelix-aac/dct4.c +++ b/src/libhelix-aac/dct4.c @@ -1,46 +1,46 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: dct4.c,v 1.1 2005/02/26 01:47:34 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: dct4.c,v 1.1 2005/02/26 01:47:34 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * February 2005 - * - * dct4.c - optimized DCT-IV + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + February 2005 + + dct4.c - optimized DCT-IV **************************************************************************************/ #include "coder.h" @@ -50,288 +50,283 @@ static const int nmdctTab[NUM_IMDCT_SIZES] PROGMEM = {128, 1024}; static const int postSkip[NUM_IMDCT_SIZES] PROGMEM = {15, 1}; /************************************************************************************** - * Function: PreMultiply - * - * Description: pre-twiddle stage of DCT4 - * - * Inputs: table index (for transform size) - * buffer of nmdct samples - * - * Outputs: processed samples in same buffer - * - * Return: none - * - * Notes: minimum 1 GB in, 2 GB out, gains 5 (short) or 8 (long) frac bits - * i.e. gains 2-7= -5 int bits (short) or 2-10 = -8 int bits (long) - * normalization by -1/N is rolled into tables here (see trigtabs.c) - * uses 3-mul, 3-add butterflies instead of 4-mul, 2-add + Function: PreMultiply + + Description: pre-twiddle stage of DCT4 + + Inputs: table index (for transform size) + buffer of nmdct samples + + Outputs: processed samples in same buffer + + Return: none + + Notes: minimum 1 GB in, 2 GB out, gains 5 (short) or 8 (long) frac bits + i.e. gains 2-7= -5 int bits (short) or 2-10 = -8 int bits (long) + normalization by -1/N is rolled into tables here (see trigtabs.c) + uses 3-mul, 3-add butterflies instead of 4-mul, 2-add **************************************************************************************/ -static void PreMultiply(int tabidx, int *zbuf1) -{ - int i, nmdct, ar1, ai1, ar2, ai2, z1, z2; - int t, cms2, cps2a, sin2a, cps2b, sin2b; - int *zbuf2; - const int *csptr; - - nmdct = nmdctTab[tabidx]; - zbuf2 = zbuf1 + nmdct - 1; - csptr = cos4sin4tab + cos4sin4tabOffset[tabidx]; - - /* whole thing should fit in registers - verify that compiler does this */ - for (i = nmdct >> 2; i != 0; i--) { - /* cps2 = (cos+sin), sin2 = sin, cms2 = (cos-sin) */ - cps2a = *csptr++; - sin2a = *csptr++; - cps2b = *csptr++; - sin2b = *csptr++; - - ar1 = *(zbuf1 + 0); - ai2 = *(zbuf1 + 1); - ai1 = *(zbuf2 + 0); - ar2 = *(zbuf2 - 1); - - /* gain 2 ints bit from MULSHIFT32 by Q30, but drop 7 or 10 int bits from table scaling of 1/M - * max per-sample gain (ignoring implicit scaling) = MAX(sin(angle)+cos(angle)) = 1.414 - * i.e. gain 1 GB since worst case is sin(angle) = cos(angle) = 0.707 (Q30), gain 2 from - * extra sign bits, and eat one in adding - */ - t = MULSHIFT32(sin2a, ar1 + ai1); - z2 = MULSHIFT32(cps2a, ai1) - t; - cms2 = cps2a - 2*sin2a; - z1 = MULSHIFT32(cms2, ar1) + t; - *zbuf1++ = z1; /* cos*ar1 + sin*ai1 */ - *zbuf1++ = z2; /* cos*ai1 - sin*ar1 */ - - t = MULSHIFT32(sin2b, ar2 + ai2); - z2 = MULSHIFT32(cps2b, ai2) - t; - cms2 = cps2b - 2*sin2b; - z1 = MULSHIFT32(cms2, ar2) + t; - *zbuf2-- = z2; /* cos*ai2 - sin*ar2 */ - *zbuf2-- = z1; /* cos*ar2 + sin*ai2 */ - } +static void PreMultiply(int tabidx, int *zbuf1) { + int i, nmdct, ar1, ai1, ar2, ai2, z1, z2; + int t, cms2, cps2a, sin2a, cps2b, sin2b; + int *zbuf2; + const int *csptr; + + nmdct = nmdctTab[tabidx]; + zbuf2 = zbuf1 + nmdct - 1; + csptr = cos4sin4tab + cos4sin4tabOffset[tabidx]; + + /* whole thing should fit in registers - verify that compiler does this */ + for (i = nmdct >> 2; i != 0; i--) { + /* cps2 = (cos+sin), sin2 = sin, cms2 = (cos-sin) */ + cps2a = *csptr++; + sin2a = *csptr++; + cps2b = *csptr++; + sin2b = *csptr++; + + ar1 = *(zbuf1 + 0); + ai2 = *(zbuf1 + 1); + ai1 = *(zbuf2 + 0); + ar2 = *(zbuf2 - 1); + + /* gain 2 ints bit from MULSHIFT32 by Q30, but drop 7 or 10 int bits from table scaling of 1/M + max per-sample gain (ignoring implicit scaling) = MAX(sin(angle)+cos(angle)) = 1.414 + i.e. gain 1 GB since worst case is sin(angle) = cos(angle) = 0.707 (Q30), gain 2 from + extra sign bits, and eat one in adding + */ + t = MULSHIFT32(sin2a, ar1 + ai1); + z2 = MULSHIFT32(cps2a, ai1) - t; + cms2 = cps2a - 2 * sin2a; + z1 = MULSHIFT32(cms2, ar1) + t; + *zbuf1++ = z1; /* cos*ar1 + sin*ai1 */ + *zbuf1++ = z2; /* cos*ai1 - sin*ar1 */ + + t = MULSHIFT32(sin2b, ar2 + ai2); + z2 = MULSHIFT32(cps2b, ai2) - t; + cms2 = cps2b - 2 * sin2b; + z1 = MULSHIFT32(cms2, ar2) + t; + *zbuf2-- = z2; /* cos*ai2 - sin*ar2 */ + *zbuf2-- = z1; /* cos*ar2 + sin*ai2 */ + } } /************************************************************************************** - * Function: PostMultiply - * - * Description: post-twiddle stage of DCT4 - * - * Inputs: table index (for transform size) - * buffer of nmdct samples - * - * Outputs: processed samples in same buffer - * - * Return: none - * - * Notes: minimum 1 GB in, 2 GB out - gains 2 int bits - * uses 3-mul, 3-add butterflies instead of 4-mul, 2-add + Function: PostMultiply + + Description: post-twiddle stage of DCT4 + + Inputs: table index (for transform size) + buffer of nmdct samples + + Outputs: processed samples in same buffer + + Return: none + + Notes: minimum 1 GB in, 2 GB out - gains 2 int bits + uses 3-mul, 3-add butterflies instead of 4-mul, 2-add **************************************************************************************/ -static void PostMultiply(int tabidx, int *fft1) -{ - int i, nmdct, ar1, ai1, ar2, ai2, skipFactor; - int t, cms2, cps2, sin2; - int *fft2; - const int *csptr; - - nmdct = nmdctTab[tabidx]; - csptr = cos1sin1tab; - skipFactor = postSkip[tabidx]; - fft2 = fft1 + nmdct - 1; - - /* load coeffs for first pass - * cps2 = (cos+sin), sin2 = sin, cms2 = (cos-sin) - */ - cps2 = *csptr++; - sin2 = *csptr; - csptr += skipFactor; - cms2 = cps2 - 2*sin2; - - for (i = nmdct >> 2; i != 0; i--) { - ar1 = *(fft1 + 0); - ai1 = *(fft1 + 1); - ar2 = *(fft2 - 1); - ai2 = *(fft2 + 0); - - /* gain 2 ints bit from MULSHIFT32 by Q30 - * max per-sample gain = MAX(sin(angle)+cos(angle)) = 1.414 - * i.e. gain 1 GB since worst case is sin(angle) = cos(angle) = 0.707 (Q30), gain 2 from - * extra sign bits, and eat one in adding - */ - t = MULSHIFT32(sin2, ar1 + ai1); - *fft2-- = t - MULSHIFT32(cps2, ai1); /* sin*ar1 - cos*ai1 */ - *fft1++ = t + MULSHIFT32(cms2, ar1); /* cos*ar1 + sin*ai1 */ - cps2 = *csptr++; - sin2 = *csptr; - csptr += skipFactor; - - ai2 = -ai2; - t = MULSHIFT32(sin2, ar2 + ai2); - *fft2-- = t - MULSHIFT32(cps2, ai2); /* sin*ar1 - cos*ai1 */ - cms2 = cps2 - 2*sin2; - *fft1++ = t + MULSHIFT32(cms2, ar2); /* cos*ar1 + sin*ai1 */ - } +static void PostMultiply(int tabidx, int *fft1) { + int i, nmdct, ar1, ai1, ar2, ai2, skipFactor; + int t, cms2, cps2, sin2; + int *fft2; + const int *csptr; + + nmdct = nmdctTab[tabidx]; + csptr = cos1sin1tab; + skipFactor = postSkip[tabidx]; + fft2 = fft1 + nmdct - 1; + + /* load coeffs for first pass + cps2 = (cos+sin), sin2 = sin, cms2 = (cos-sin) + */ + cps2 = *csptr++; + sin2 = *csptr; + csptr += skipFactor; + cms2 = cps2 - 2 * sin2; + + for (i = nmdct >> 2; i != 0; i--) { + ar1 = *(fft1 + 0); + ai1 = *(fft1 + 1); + ar2 = *(fft2 - 1); + ai2 = *(fft2 + 0); + + /* gain 2 ints bit from MULSHIFT32 by Q30 + max per-sample gain = MAX(sin(angle)+cos(angle)) = 1.414 + i.e. gain 1 GB since worst case is sin(angle) = cos(angle) = 0.707 (Q30), gain 2 from + extra sign bits, and eat one in adding + */ + t = MULSHIFT32(sin2, ar1 + ai1); + *fft2-- = t - MULSHIFT32(cps2, ai1); /* sin*ar1 - cos*ai1 */ + *fft1++ = t + MULSHIFT32(cms2, ar1); /* cos*ar1 + sin*ai1 */ + cps2 = *csptr++; + sin2 = *csptr; + csptr += skipFactor; + + ai2 = -ai2; + t = MULSHIFT32(sin2, ar2 + ai2); + *fft2-- = t - MULSHIFT32(cps2, ai2); /* sin*ar1 - cos*ai1 */ + cms2 = cps2 - 2 * sin2; + *fft1++ = t + MULSHIFT32(cms2, ar2); /* cos*ar1 + sin*ai1 */ + } } /************************************************************************************** - * Function: PreMultiplyRescale - * - * Description: pre-twiddle stage of DCT4, with rescaling for extra guard bits - * - * Inputs: table index (for transform size) - * buffer of nmdct samples - * number of guard bits to add to input before processing - * - * Outputs: processed samples in same buffer - * - * Return: none - * - * Notes: see notes on PreMultiply(), above + Function: PreMultiplyRescale + + Description: pre-twiddle stage of DCT4, with rescaling for extra guard bits + + Inputs: table index (for transform size) + buffer of nmdct samples + number of guard bits to add to input before processing + + Outputs: processed samples in same buffer + + Return: none + + Notes: see notes on PreMultiply(), above **************************************************************************************/ - /* __attribute__ ((section (".data"))) */ static void PreMultiplyRescale(int tabidx, int *zbuf1, int es) -{ - int i, nmdct, ar1, ai1, ar2, ai2, z1, z2; - int t, cms2, cps2a, sin2a, cps2b, sin2b; - int *zbuf2; - const int *csptr; - - nmdct = nmdctTab[tabidx]; - zbuf2 = zbuf1 + nmdct - 1; - csptr = cos4sin4tab + cos4sin4tabOffset[tabidx]; - - /* whole thing should fit in registers - verify that compiler does this */ - for (i = nmdct >> 2; i != 0; i--) { - /* cps2 = (cos+sin), sin2 = sin, cms2 = (cos-sin) */ - cps2a = *csptr++; - sin2a = *csptr++; - cps2b = *csptr++; - sin2b = *csptr++; - - ar1 = *(zbuf1 + 0) >> es; - ai1 = *(zbuf2 + 0) >> es; - ai2 = *(zbuf1 + 1) >> es; - - t = MULSHIFT32(sin2a, ar1 + ai1); - z2 = MULSHIFT32(cps2a, ai1) - t; - cms2 = cps2a - 2*sin2a; - z1 = MULSHIFT32(cms2, ar1) + t; - *zbuf1++ = z1; - *zbuf1++ = z2; - - ar2 = *(zbuf2 - 1) >> es; /* do here to free up register used for es */ - - t = MULSHIFT32(sin2b, ar2 + ai2); - z2 = MULSHIFT32(cps2b, ai2) - t; - cms2 = cps2b - 2*sin2b; - z1 = MULSHIFT32(cms2, ar2) + t; - *zbuf2-- = z2; - *zbuf2-- = z1; - - } +/* __attribute__ ((section (".data"))) */ static void PreMultiplyRescale(int tabidx, int *zbuf1, int es) { + int i, nmdct, ar1, ai1, ar2, ai2, z1, z2; + int t, cms2, cps2a, sin2a, cps2b, sin2b; + int *zbuf2; + const int *csptr; + + nmdct = nmdctTab[tabidx]; + zbuf2 = zbuf1 + nmdct - 1; + csptr = cos4sin4tab + cos4sin4tabOffset[tabidx]; + + /* whole thing should fit in registers - verify that compiler does this */ + for (i = nmdct >> 2; i != 0; i--) { + /* cps2 = (cos+sin), sin2 = sin, cms2 = (cos-sin) */ + cps2a = *csptr++; + sin2a = *csptr++; + cps2b = *csptr++; + sin2b = *csptr++; + + ar1 = *(zbuf1 + 0) >> es; + ai1 = *(zbuf2 + 0) >> es; + ai2 = *(zbuf1 + 1) >> es; + + t = MULSHIFT32(sin2a, ar1 + ai1); + z2 = MULSHIFT32(cps2a, ai1) - t; + cms2 = cps2a - 2 * sin2a; + z1 = MULSHIFT32(cms2, ar1) + t; + *zbuf1++ = z1; + *zbuf1++ = z2; + + ar2 = *(zbuf2 - 1) >> es; /* do here to free up register used for es */ + + t = MULSHIFT32(sin2b, ar2 + ai2); + z2 = MULSHIFT32(cps2b, ai2) - t; + cms2 = cps2b - 2 * sin2b; + z1 = MULSHIFT32(cms2, ar2) + t; + *zbuf2-- = z2; + *zbuf2-- = z1; + + } } /************************************************************************************** - * Function: PostMultiplyRescale - * - * Description: post-twiddle stage of DCT4, with rescaling for extra guard bits - * - * Inputs: table index (for transform size) - * buffer of nmdct samples - * number of guard bits to remove from output - * - * Outputs: processed samples in same buffer - * - * Return: none - * - * Notes: clips output to [-2^30, 2^30 - 1], guaranteeing at least 1 guard bit - * see notes on PostMultiply(), above + Function: PostMultiplyRescale + + Description: post-twiddle stage of DCT4, with rescaling for extra guard bits + + Inputs: table index (for transform size) + buffer of nmdct samples + number of guard bits to remove from output + + Outputs: processed samples in same buffer + + Return: none + + Notes: clips output to [-2^30, 2^30 - 1], guaranteeing at least 1 guard bit + see notes on PostMultiply(), above **************************************************************************************/ - /* __attribute__ ((section (".data"))) */ static void PostMultiplyRescale(int tabidx, int *fft1, int es) -{ - int i, nmdct, ar1, ai1, ar2, ai2, skipFactor, z; - int t, cs2, sin2; - int *fft2; - const int *csptr; - - nmdct = nmdctTab[tabidx]; - csptr = cos1sin1tab; - skipFactor = postSkip[tabidx]; - fft2 = fft1 + nmdct - 1; - - /* load coeffs for first pass - * cps2 = (cos+sin), sin2 = sin, cms2 = (cos-sin) - */ - cs2 = *csptr++; - sin2 = *csptr; - csptr += skipFactor; - - for (i = nmdct >> 2; i != 0; i--) { - ar1 = *(fft1 + 0); - ai1 = *(fft1 + 1); - ai2 = *(fft2 + 0); - - t = MULSHIFT32(sin2, ar1 + ai1); - z = t - MULSHIFT32(cs2, ai1); - CLIP_2N_SHIFT(z, es); - *fft2-- = z; - cs2 -= 2*sin2; - z = t + MULSHIFT32(cs2, ar1); - CLIP_2N_SHIFT(z, es); - *fft1++ = z; - - cs2 = *csptr++; - sin2 = *csptr; - csptr += skipFactor; - - ar2 = *fft2; - ai2 = -ai2; - t = MULSHIFT32(sin2, ar2 + ai2); - z = t - MULSHIFT32(cs2, ai2); - CLIP_2N_SHIFT(z, es); - *fft2-- = z; - cs2 -= 2*sin2; - z = t + MULSHIFT32(cs2, ar2); - CLIP_2N_SHIFT(z, es); - *fft1++ = z; - cs2 += 2*sin2; - } +/* __attribute__ ((section (".data"))) */ static void PostMultiplyRescale(int tabidx, int *fft1, int es) { + int i, nmdct, ar1, ai1, ar2, ai2, skipFactor, z; + int t, cs2, sin2; + int *fft2; + const int *csptr; + + nmdct = nmdctTab[tabidx]; + csptr = cos1sin1tab; + skipFactor = postSkip[tabidx]; + fft2 = fft1 + nmdct - 1; + + /* load coeffs for first pass + cps2 = (cos+sin), sin2 = sin, cms2 = (cos-sin) + */ + cs2 = *csptr++; + sin2 = *csptr; + csptr += skipFactor; + + for (i = nmdct >> 2; i != 0; i--) { + ar1 = *(fft1 + 0); + ai1 = *(fft1 + 1); + ai2 = *(fft2 + 0); + + t = MULSHIFT32(sin2, ar1 + ai1); + z = t - MULSHIFT32(cs2, ai1); + CLIP_2N_SHIFT(z, es); + *fft2-- = z; + cs2 -= 2 * sin2; + z = t + MULSHIFT32(cs2, ar1); + CLIP_2N_SHIFT(z, es); + *fft1++ = z; + + cs2 = *csptr++; + sin2 = *csptr; + csptr += skipFactor; + + ar2 = *fft2; + ai2 = -ai2; + t = MULSHIFT32(sin2, ar2 + ai2); + z = t - MULSHIFT32(cs2, ai2); + CLIP_2N_SHIFT(z, es); + *fft2-- = z; + cs2 -= 2 * sin2; + z = t + MULSHIFT32(cs2, ar2); + CLIP_2N_SHIFT(z, es); + *fft1++ = z; + cs2 += 2 * sin2; + } } /************************************************************************************** - * Function: DCT4 - * - * Description: type-IV DCT - * - * Inputs: table index (for transform size) - * buffer of nmdct samples - * number of guard bits in the input buffer - * - * Outputs: processed samples in same buffer - * - * Return: none - * - * Notes: operates in-place - * if number of guard bits in input is < GBITS_IN_DCT4, the input is - * scaled (>>) before the DCT4 and rescaled (<<, with clipping) after - * the DCT4 (rare) - * the output has FBITS_LOST_DCT4 fewer fraction bits than the input - * the output will always have at least 1 guard bit (GBITS_IN_DCT4 >= 4) - * int bits gained per stage (PreMul + FFT + PostMul) - * short blocks = (-5 + 4 + 2) = 1 total - * long blocks = (-8 + 7 + 2) = 1 total + Function: DCT4 + + Description: type-IV DCT + + Inputs: table index (for transform size) + buffer of nmdct samples + number of guard bits in the input buffer + + Outputs: processed samples in same buffer + + Return: none + + Notes: operates in-place + if number of guard bits in input is < GBITS_IN_DCT4, the input is + scaled (>>) before the DCT4 and rescaled (<<, with clipping) after + the DCT4 (rare) + the output has FBITS_LOST_DCT4 fewer fraction bits than the input + the output will always have at least 1 guard bit (GBITS_IN_DCT4 >= 4) + int bits gained per stage (PreMul + FFT + PostMul) + short blocks = (-5 + 4 + 2) = 1 total + long blocks = (-8 + 7 + 2) = 1 total **************************************************************************************/ -void DCT4(int tabidx, int *coef, int gb) -{ - int es; - - /* fast in-place DCT-IV - adds guard bits if necessary */ - if (gb < GBITS_IN_DCT4) { - es = GBITS_IN_DCT4 - gb; - PreMultiplyRescale(tabidx, coef, es); - R4FFT(tabidx, coef); - PostMultiplyRescale(tabidx, coef, es); - } else { - PreMultiply(tabidx, coef); - R4FFT(tabidx, coef); - PostMultiply(tabidx, coef); - } +void DCT4(int tabidx, int *coef, int gb) { + int es; + + /* fast in-place DCT-IV - adds guard bits if necessary */ + if (gb < GBITS_IN_DCT4) { + es = GBITS_IN_DCT4 - gb; + PreMultiplyRescale(tabidx, coef, es); + R4FFT(tabidx, coef); + PostMultiplyRescale(tabidx, coef, es); + } else { + PreMultiply(tabidx, coef); + R4FFT(tabidx, coef); + PostMultiply(tabidx, coef); + } } diff --git a/src/libhelix-aac/decelmnt.c b/src/libhelix-aac/decelmnt.c index 8c319121..7167cd44 100644 --- a/src/libhelix-aac/decelmnt.c +++ b/src/libhelix-aac/decelmnt.c @@ -1,425 +1,438 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: decelmnt.c,v 1.1 2005/02/26 01:47:34 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: decelmnt.c,v 1.1 2005/02/26 01:47:34 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * decelmnt.c - syntactic element decoding + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + decelmnt.c - syntactic element decoding **************************************************************************************/ #include "coder.h" /************************************************************************************** - * Function: DecodeSingleChannelElement - * - * Description: decode one SCE - * - * Inputs: BitStreamInfo struct pointing to start of SCE (14496-3, table 4.4.4) - * - * Outputs: updated element instance tag - * - * Return: 0 if successful, -1 if error - * - * Notes: doesn't decode individual channel stream (part of DecodeNoiselessData) + Function: DecodeSingleChannelElement + + Description: decode one SCE + + Inputs: BitStreamInfo struct pointing to start of SCE (14496-3, table 4.4.4) + + Outputs: updated element instance tag + + Return: 0 if successful, -1 if error + + Notes: doesn't decode individual channel stream (part of DecodeNoiselessData) **************************************************************************************/ -static int DecodeSingleChannelElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) -{ - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return -1; +static int DecodeSingleChannelElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) { + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return -1; + } - /* read instance tag */ - aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS); + /* read instance tag */ + aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS); - return 0; + return 0; } /************************************************************************************** - * Function: DecodeChannelPairElement - * - * Description: decode one CPE - * - * Inputs: BitStreamInfo struct pointing to start of CPE (14496-3, table 4.4.5) - * - * Outputs: updated element instance tag - * updated commonWin - * updated ICS info, if commonWin == 1 - * updated mid-side stereo info, if commonWin == 1 - * - * Return: 0 if successful, -1 if error - * - * Notes: doesn't decode individual channel stream (part of DecodeNoiselessData) + Function: DecodeChannelPairElement + + Description: decode one CPE + + Inputs: BitStreamInfo struct pointing to start of CPE (14496-3, table 4.4.5) + + Outputs: updated element instance tag + updated commonWin + updated ICS info, if commonWin == 1 + updated mid-side stereo info, if commonWin == 1 + + Return: 0 if successful, -1 if error + + Notes: doesn't decode individual channel stream (part of DecodeNoiselessData) **************************************************************************************/ -static int DecodeChannelPairElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) -{ - int sfb, gp, maskOffset; - unsigned char currBit, *maskPtr; - PSInfoBase *psi; - ICSInfo *icsInfo; - - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return -1; - psi = (PSInfoBase *)(aacDecInfo->psInfoBase); - icsInfo = psi->icsInfo; - - /* read instance tag */ - aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS); - - /* read common window flag and mid-side info (if present) - * store msMask bits in psi->msMaskBits[] as follows: - * long blocks - pack bits for each SFB in range [0, maxSFB) starting with lsb of msMaskBits[0] - * short blocks - pack bits for each SFB in range [0, maxSFB), for each group [0, 7] - * msMaskPresent = 0 means no M/S coding - * = 1 means psi->msMaskBits contains 1 bit per SFB to toggle M/S coding - * = 2 means all SFB's are M/S coded (so psi->msMaskBits is not needed) - */ - psi->commonWin = GetBits(bsi, 1); - if (psi->commonWin) { - DecodeICSInfo(bsi, icsInfo, psi->sampRateIdx); - psi->msMaskPresent = GetBits(bsi, 2); - if (psi->msMaskPresent == 1) { - maskPtr = psi->msMaskBits; - *maskPtr = 0; - maskOffset = 0; - for (gp = 0; gp < icsInfo->numWinGroup; gp++) { - for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) { - currBit = (unsigned char)GetBits(bsi, 1); - *maskPtr |= currBit << maskOffset; - if (++maskOffset == 8) { - maskPtr++; - *maskPtr = 0; - maskOffset = 0; - } - } - } - } - } - - return 0; +static int DecodeChannelPairElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) { + int sfb, gp, maskOffset; + unsigned char currBit, *maskPtr; + PSInfoBase *psi; + ICSInfo *icsInfo; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return -1; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + icsInfo = psi->icsInfo; + + /* read instance tag */ + aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS); + + /* read common window flag and mid-side info (if present) + store msMask bits in psi->msMaskBits[] as follows: + long blocks - pack bits for each SFB in range [0, maxSFB) starting with lsb of msMaskBits[0] + short blocks - pack bits for each SFB in range [0, maxSFB), for each group [0, 7] + msMaskPresent = 0 means no M/S coding + = 1 means psi->msMaskBits contains 1 bit per SFB to toggle M/S coding + = 2 means all SFB's are M/S coded (so psi->msMaskBits is not needed) + */ + psi->commonWin = GetBits(bsi, 1); + if (psi->commonWin) { + DecodeICSInfo(bsi, icsInfo, psi->sampRateIdx); + psi->msMaskPresent = GetBits(bsi, 2); + if (psi->msMaskPresent == 1) { + maskPtr = psi->msMaskBits; + *maskPtr = 0; + maskOffset = 0; + for (gp = 0; gp < icsInfo->numWinGroup; gp++) { + for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) { + currBit = (unsigned char)GetBits(bsi, 1); + *maskPtr |= currBit << maskOffset; + if (++maskOffset == 8) { + maskPtr++; + *maskPtr = 0; + maskOffset = 0; + } + } + } + } + } + + return 0; } /************************************************************************************** - * Function: DecodeLFEChannelElement - * - * Description: decode one LFE - * - * Inputs: BitStreamInfo struct pointing to start of LFE (14496-3, table 4.4.9) - * - * Outputs: updated element instance tag - * - * Return: 0 if successful, -1 if error - * - * Notes: doesn't decode individual channel stream (part of DecodeNoiselessData) + Function: DecodeLFEChannelElement + + Description: decode one LFE + + Inputs: BitStreamInfo struct pointing to start of LFE (14496-3, table 4.4.9) + + Outputs: updated element instance tag + + Return: 0 if successful, -1 if error + + Notes: doesn't decode individual channel stream (part of DecodeNoiselessData) **************************************************************************************/ -static int DecodeLFEChannelElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) -{ - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return -1; +static int DecodeLFEChannelElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) { + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return -1; + } - /* read instance tag */ - aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS); + /* read instance tag */ + aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS); - return 0; + return 0; } /************************************************************************************** - * Function: DecodeDataStreamElement - * - * Description: decode one DSE - * - * Inputs: BitStreamInfo struct pointing to start of DSE (14496-3, table 4.4.10) - * - * Outputs: updated element instance tag - * filled in data stream buffer - * - * Return: 0 if successful, -1 if error + Function: DecodeDataStreamElement + + Description: decode one DSE + + Inputs: BitStreamInfo struct pointing to start of DSE (14496-3, table 4.4.10) + + Outputs: updated element instance tag + filled in data stream buffer + + Return: 0 if successful, -1 if error **************************************************************************************/ -static int DecodeDataStreamElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) -{ - unsigned int byteAlign, dataCount; - unsigned char *dataBuf; - PSInfoBase *psi; - - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return -1; - psi = (PSInfoBase *)(aacDecInfo->psInfoBase); - - aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS); - byteAlign = GetBits(bsi, 1); - dataCount = GetBits(bsi, 8); - if (dataCount == 255) - dataCount += GetBits(bsi, 8); - - if (byteAlign) - ByteAlignBitstream(bsi); - - psi->dataCount = dataCount; - dataBuf = psi->dataBuf; - while (dataCount--) - *dataBuf++ = GetBits(bsi, 8); - - return 0; +static int DecodeDataStreamElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) { + unsigned int byteAlign, dataCount; + unsigned char *dataBuf; + PSInfoBase *psi; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return -1; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + + aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS); + byteAlign = GetBits(bsi, 1); + dataCount = GetBits(bsi, 8); + if (dataCount == 255) { + dataCount += GetBits(bsi, 8); + } + + if (byteAlign) { + ByteAlignBitstream(bsi); + } + + psi->dataCount = dataCount; + dataBuf = psi->dataBuf; + while (dataCount--) { + *dataBuf++ = GetBits(bsi, 8); + } + + return 0; } /************************************************************************************** - * Function: DecodeProgramConfigElement - * - * Description: decode one PCE - * - * Inputs: BitStreamInfo struct pointing to start of PCE (14496-3, table 4.4.2) - * - * Outputs: filled-in ProgConfigElement struct - * updated BitStreamInfo struct - * - * Return: 0 if successful, error code (< 0) if error - * - * Notes: #define KEEP_PCE_COMMENTS to save the comment field of the PCE - * (otherwise we just skip it in the bitstream, to save memory) + Function: DecodeProgramConfigElement + + Description: decode one PCE + + Inputs: BitStreamInfo struct pointing to start of PCE (14496-3, table 4.4.2) + + Outputs: filled-in ProgConfigElement struct + updated BitStreamInfo struct + + Return: 0 if successful, error code (< 0) if error + + Notes: #define KEEP_PCE_COMMENTS to save the comment field of the PCE + (otherwise we just skip it in the bitstream, to save memory) **************************************************************************************/ -int DecodeProgramConfigElement(ProgConfigElement *pce, BitStreamInfo *bsi) -{ - int i; - - pce->elemInstTag = GetBits(bsi, 4); - pce->profile = GetBits(bsi, 2); - pce->sampRateIdx = GetBits(bsi, 4); - pce->numFCE = GetBits(bsi, 4); - pce->numSCE = GetBits(bsi, 4); - pce->numBCE = GetBits(bsi, 4); - pce->numLCE = GetBits(bsi, 2); - pce->numADE = GetBits(bsi, 3); - pce->numCCE = GetBits(bsi, 4); - - pce->monoMixdown = GetBits(bsi, 1) << 4; /* present flag */ - if (pce->monoMixdown) - pce->monoMixdown |= GetBits(bsi, 4); /* element number */ - - pce->stereoMixdown = GetBits(bsi, 1) << 4; /* present flag */ - if (pce->stereoMixdown) - pce->stereoMixdown |= GetBits(bsi, 4); /* element number */ - - pce->matrixMixdown = GetBits(bsi, 1) << 4; /* present flag */ - if (pce->matrixMixdown) { - pce->matrixMixdown |= GetBits(bsi, 2) << 1; /* index */ - pce->matrixMixdown |= GetBits(bsi, 1); /* pseudo-surround enable */ - } - - for (i = 0; i < pce->numFCE; i++) { - pce->fce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */ - pce->fce[i] |= GetBits(bsi, 4); /* tag select */ - } - - for (i = 0; i < pce->numSCE; i++) { - pce->sce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */ - pce->sce[i] |= GetBits(bsi, 4); /* tag select */ - } - - for (i = 0; i < pce->numBCE; i++) { - pce->bce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */ - pce->bce[i] |= GetBits(bsi, 4); /* tag select */ - } - - for (i = 0; i < pce->numLCE; i++) - pce->lce[i] = GetBits(bsi, 4); /* tag select */ - - for (i = 0; i < pce->numADE; i++) - pce->ade[i] = GetBits(bsi, 4); /* tag select */ - - for (i = 0; i < pce->numCCE; i++) { - pce->cce[i] = GetBits(bsi, 1) << 4; /* independent/dependent flag */ - pce->cce[i] |= GetBits(bsi, 4); /* tag select */ - } - - - ByteAlignBitstream(bsi); +int DecodeProgramConfigElement(ProgConfigElement *pce, BitStreamInfo *bsi) { + int i; + + pce->elemInstTag = GetBits(bsi, 4); + pce->profile = GetBits(bsi, 2); + pce->sampRateIdx = GetBits(bsi, 4); + pce->numFCE = GetBits(bsi, 4); + pce->numSCE = GetBits(bsi, 4); + pce->numBCE = GetBits(bsi, 4); + pce->numLCE = GetBits(bsi, 2); + pce->numADE = GetBits(bsi, 3); + pce->numCCE = GetBits(bsi, 4); + + pce->monoMixdown = GetBits(bsi, 1) << 4; /* present flag */ + if (pce->monoMixdown) { + pce->monoMixdown |= GetBits(bsi, 4); /* element number */ + } + + pce->stereoMixdown = GetBits(bsi, 1) << 4; /* present flag */ + if (pce->stereoMixdown) { + pce->stereoMixdown |= GetBits(bsi, 4); /* element number */ + } + + pce->matrixMixdown = GetBits(bsi, 1) << 4; /* present flag */ + if (pce->matrixMixdown) { + pce->matrixMixdown |= GetBits(bsi, 2) << 1; /* index */ + pce->matrixMixdown |= GetBits(bsi, 1); /* pseudo-surround enable */ + } + + for (i = 0; i < pce->numFCE; i++) { + pce->fce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */ + pce->fce[i] |= GetBits(bsi, 4); /* tag select */ + } + + for (i = 0; i < pce->numSCE; i++) { + pce->sce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */ + pce->sce[i] |= GetBits(bsi, 4); /* tag select */ + } + + for (i = 0; i < pce->numBCE; i++) { + pce->bce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */ + pce->bce[i] |= GetBits(bsi, 4); /* tag select */ + } + + for (i = 0; i < pce->numLCE && i < MAX_NUM_LCE; i++) { + pce->lce[i] = GetBits(bsi, 4); /* tag select */ + } + + for (i = 0; i < pce->numADE && i < MAX_NUM_ADE; i++) { + pce->ade[i] = GetBits(bsi, 4); /* tag select */ + } + + for (i = 0; i < pce->numCCE; i++) { + pce->cce[i] = GetBits(bsi, 1) << 4; /* independent/dependent flag */ + pce->cce[i] |= GetBits(bsi, 4); /* tag select */ + } + + + ByteAlignBitstream(bsi); #ifdef KEEP_PCE_COMMENTS - pce->commentBytes = GetBits(bsi, 8); - for (i = 0; i < pce->commentBytes; i++) - pce->commentField[i] = GetBits(bsi, 8); + pce->commentBytes = GetBits(bsi, 8); + for (i = 0; i < pce->commentBytes; i++) { + pce->commentField[i] = GetBits(bsi, 8); + } #else - /* eat comment bytes and throw away */ - i = GetBits(bsi, 8); - while (i--) - GetBits(bsi, 8); + /* eat comment bytes and throw away */ + i = GetBits(bsi, 8); + while (i--) { + GetBits(bsi, 8); + } #endif - return 0; + return 0; } /************************************************************************************** - * Function: DecodeFillElement - * - * Description: decode one fill element - * - * Inputs: BitStreamInfo struct pointing to start of fill element - * (14496-3, table 4.4.11) - * - * Outputs: updated element instance tag - * unpacked extension payload - * - * Return: 0 if successful, -1 if error - **************************************************************************************/ -static int DecodeFillElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) -{ - unsigned int fillCount; - unsigned char *fillBuf; - PSInfoBase *psi; + Function: DecodeFillElement - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return -1; - psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + Description: decode one fill element - fillCount = GetBits(bsi, 4); - if (fillCount == 15) - fillCount += (GetBits(bsi, 8) - 1); + Inputs: BitStreamInfo struct pointing to start of fill element + (14496-3, table 4.4.11) - psi->fillCount = fillCount; - fillBuf = psi->fillBuf; - while (fillCount--) - *fillBuf++ = GetBits(bsi, 8); + Outputs: updated element instance tag + unpacked extension payload - aacDecInfo->currInstTag = -1; /* fill elements don't have instance tag */ - aacDecInfo->fillExtType = 0; + Return: 0 if successful, -1 if error + **************************************************************************************/ +static int DecodeFillElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) { + unsigned int fillCount; + unsigned char *fillBuf; + PSInfoBase *psi; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return -1; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + + fillCount = GetBits(bsi, 4); + if (fillCount == 15) { + fillCount += (GetBits(bsi, 8) - 1); + } + + psi->fillCount = fillCount; + fillBuf = psi->fillBuf; + while (fillCount--) { + *fillBuf++ = GetBits(bsi, 8); + } + + aacDecInfo->currInstTag = -1; /* fill elements don't have instance tag */ + aacDecInfo->fillExtType = 0; #ifdef AAC_ENABLE_SBR - /* check for SBR - * aacDecInfo->sbrEnabled is sticky (reset each raw_data_block), so for multichannel - * need to verify that all SCE/CPE/ICCE have valid SBR fill element following, and - * must upsample by 2 for LFE - */ - if (psi->fillCount > 0) { - aacDecInfo->fillExtType = (int)((psi->fillBuf[0] >> 4) & 0x0f); - if (aacDecInfo->fillExtType == EXT_SBR_DATA || aacDecInfo->fillExtType == EXT_SBR_DATA_CRC) - aacDecInfo->sbrEnabled = 1; - } + /* check for SBR + aacDecInfo->sbrEnabled is sticky (reset each raw_data_block), so for multichannel + need to verify that all SCE/CPE/ICCE have valid SBR fill element following, and + must upsample by 2 for LFE + */ + if (psi->fillCount > 0) { + aacDecInfo->fillExtType = (int)((psi->fillBuf[0] >> 4) & 0x0f); + if (aacDecInfo->fillExtType == EXT_SBR_DATA || aacDecInfo->fillExtType == EXT_SBR_DATA_CRC) { + aacDecInfo->sbrEnabled = 1; + } + } #endif - aacDecInfo->fillBuf = psi->fillBuf; - aacDecInfo->fillCount = psi->fillCount; + aacDecInfo->fillBuf = psi->fillBuf; + aacDecInfo->fillCount = psi->fillCount; - return 0; + return 0; } /************************************************************************************** - * Function: DecodeNextElement - * - * Description: decode next syntactic element in AAC frame - * - * Inputs: valid AACDecInfo struct - * double pointer to buffer containing next element - * pointer to bit offset - * pointer to number of valid bits remaining in buf - * - * Outputs: type of element decoded (aacDecInfo->currBlockID) - * type of element decoded last time (aacDecInfo->prevBlockID) - * updated aacDecInfo state, depending on which element was decoded - * updated buffer pointer - * updated bit offset - * updated number of available bits - * - * Return: 0 if successful, error code (< 0) if error + Function: DecodeNextElement + + Description: decode next syntactic element in AAC frame + + Inputs: valid AACDecInfo struct + double pointer to buffer containing next element + pointer to bit offset + pointer to number of valid bits remaining in buf + + Outputs: type of element decoded (aacDecInfo->currBlockID) + type of element decoded last time (aacDecInfo->prevBlockID) + updated aacDecInfo state, depending on which element was decoded + updated buffer pointer + updated bit offset + updated number of available bits + + Return: 0 if successful, error code (< 0) if error **************************************************************************************/ -int DecodeNextElement(AACDecInfo *aacDecInfo, unsigned char **buf, int *bitOffset, int *bitsAvail) -{ - int err, bitsUsed; - PSInfoBase *psi; - BitStreamInfo bsi; - - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return ERR_AAC_NULL_POINTER; - psi = (PSInfoBase *)(aacDecInfo->psInfoBase); - - /* init bitstream reader */ - SetBitstreamPointer(&bsi, (*bitsAvail + 7) >> 3, *buf); - GetBits(&bsi, *bitOffset); - - /* read element ID (save last ID for SBR purposes) */ - aacDecInfo->prevBlockID = aacDecInfo->currBlockID; - aacDecInfo->currBlockID = GetBits(&bsi, NUM_SYN_ID_BITS); - - /* set defaults (could be overwritten by DecodeXXXElement(), depending on currBlockID) */ - psi->commonWin = 0; - - err = 0; - switch (aacDecInfo->currBlockID) { - case AAC_ID_SCE: - err = DecodeSingleChannelElement(aacDecInfo, &bsi); - break; - case AAC_ID_CPE: - err = DecodeChannelPairElement(aacDecInfo, &bsi); - break; - case AAC_ID_CCE: - /* TODO - implement CCE decoding */ - break; - case AAC_ID_LFE: - err = DecodeLFEChannelElement(aacDecInfo, &bsi); - break; - case AAC_ID_DSE: - err = DecodeDataStreamElement(aacDecInfo, &bsi); - break; - case AAC_ID_PCE: - err = DecodeProgramConfigElement(psi->pce + 0, &bsi); - break; - case AAC_ID_FIL: - err = DecodeFillElement(aacDecInfo, &bsi); - break; - case AAC_ID_END: - break; - } - if (err) - return ERR_AAC_SYNTAX_ELEMENT; - - /* update bitstream reader */ - bitsUsed = CalcBitsUsed(&bsi, *buf, *bitOffset); - *buf += (bitsUsed + *bitOffset) >> 3; - *bitOffset = (bitsUsed + *bitOffset) & 0x07; - *bitsAvail -= bitsUsed; - - if (*bitsAvail < 0) - return ERR_AAC_INDATA_UNDERFLOW; - - return ERR_AAC_NONE; +int DecodeNextElement(AACDecInfo *aacDecInfo, unsigned char **buf, int *bitOffset, int *bitsAvail) { + int err, bitsUsed; + PSInfoBase *psi; + BitStreamInfo bsi; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return ERR_AAC_NULL_POINTER; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + + /* init bitstream reader */ + SetBitstreamPointer(&bsi, (*bitsAvail + 7) >> 3, *buf); + GetBits(&bsi, *bitOffset); + + /* read element ID (save last ID for SBR purposes) */ + aacDecInfo->prevBlockID = aacDecInfo->currBlockID; + aacDecInfo->currBlockID = GetBits(&bsi, NUM_SYN_ID_BITS); + + /* set defaults (could be overwritten by DecodeXXXElement(), depending on currBlockID) */ + psi->commonWin = 0; + + err = 0; + switch (aacDecInfo->currBlockID) { + case AAC_ID_SCE: + err = DecodeSingleChannelElement(aacDecInfo, &bsi); + break; + case AAC_ID_CPE: + err = DecodeChannelPairElement(aacDecInfo, &bsi); + break; + case AAC_ID_CCE: + /* TODO - implement CCE decoding */ + break; + case AAC_ID_LFE: + err = DecodeLFEChannelElement(aacDecInfo, &bsi); + break; + case AAC_ID_DSE: + err = DecodeDataStreamElement(aacDecInfo, &bsi); + break; + case AAC_ID_PCE: + err = DecodeProgramConfigElement(psi->pce + 0, &bsi); + break; + case AAC_ID_FIL: + err = DecodeFillElement(aacDecInfo, &bsi); + break; + case AAC_ID_END: + break; + } + if (err) { + return ERR_AAC_SYNTAX_ELEMENT; + } + + /* update bitstream reader */ + bitsUsed = CalcBitsUsed(&bsi, *buf, *bitOffset); + *buf += (bitsUsed + *bitOffset) >> 3; + *bitOffset = (bitsUsed + *bitOffset) & 0x07; + *bitsAvail -= bitsUsed; + + if (*bitsAvail < 0) { + return ERR_AAC_INDATA_UNDERFLOW; + } + + return ERR_AAC_NONE; } diff --git a/src/libhelix-aac/dequant.c b/src/libhelix-aac/dequant.c index 5f511664..c66c8a4f 100644 --- a/src/libhelix-aac/dequant.c +++ b/src/libhelix-aac/dequant.c @@ -1,46 +1,46 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: dequant.c,v 1.2 2005/05/20 18:05:41 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: dequant.c,v 1.2 2005/05/20 18:05:41 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * February 2005 - * - * dequant.c - transform coefficient dequantization and short-block deinterleaving + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + February 2005 + + dequant.c - transform coefficient dequantization and short-block deinterleaving **************************************************************************************/ #include "coder.h" @@ -49,67 +49,67 @@ #define SF_OFFSET 100 /* pow(2, i/4.0) for i = [0,1,2,3], format = Q30 */ -static const int pow14[4] PROGMEM = { - 0x40000000, 0x4c1bf829, 0x5a82799a, 0x6ba27e65 +static const int pow14[4] PROGMEM = { + 0x40000000, 0x4c1bf829, 0x5a82799a, 0x6ba27e65 }; -/* pow(2, i/4.0) * pow(j, 4.0/3.0) for i = [0,1,2,3], j = [0,1,2,...,15] - * format = Q28 for j = [0-3], Q25 for j = [4-15] - */ +/* pow(2, i/4.0) * pow(j, 4.0/3.0) for i = [0,1,2,3], j = [0,1,2,...,15] + format = Q28 for j = [0-3], Q25 for j = [4-15] +*/ static const int pow43_14[4][16] PROGMEM = { - { - 0x00000000, 0x10000000, 0x285145f3, 0x453a5cdb, /* Q28 */ - 0x0cb2ff53, 0x111989d6, 0x15ce31c8, 0x1ac7f203, /* Q25 */ - 0x20000000, 0x257106b9, 0x2b16b4a3, 0x30ed74b4, /* Q25 */ - 0x36f23fa5, 0x3d227bd3, 0x437be656, 0x49fc823c, /* Q25 */ - }, - { - 0x00000000, 0x1306fe0a, 0x2ff221af, 0x52538f52, - 0x0f1a1bf4, 0x1455ccc2, 0x19ee62a8, 0x1fd92396, - 0x260dfc14, 0x2c8694d8, 0x333dcb29, 0x3a2f5c7a, - 0x4157aed5, 0x48b3aaa3, 0x50409f76, 0x57fc3010, - }, - { - 0x00000000, 0x16a09e66, 0x39047c0f, 0x61e734aa, - 0x11f59ac4, 0x182ec633, 0x1ed66a45, 0x25dfc55a, - 0x2d413ccd, 0x34f3462d, 0x3cefc603, 0x4531ab69, - 0x4db4adf8, 0x56752054, 0x5f6fcfcd, 0x68a1eca1, - }, - { - 0x00000000, 0x1ae89f99, 0x43ce3e4b, 0x746d57b2, - 0x155b8109, 0x1cc21cdc, 0x24ac1839, 0x2d0a479e, - 0x35d13f33, 0x3ef80748, 0x48775c93, 0x524938cd, - 0x5c68841d, 0x66d0df0a, 0x717e7bfe, 0x7c6e0305, - }, + { + 0x00000000, 0x10000000, 0x285145f3, 0x453a5cdb, /* Q28 */ + 0x0cb2ff53, 0x111989d6, 0x15ce31c8, 0x1ac7f203, /* Q25 */ + 0x20000000, 0x257106b9, 0x2b16b4a3, 0x30ed74b4, /* Q25 */ + 0x36f23fa5, 0x3d227bd3, 0x437be656, 0x49fc823c, /* Q25 */ + }, + { + 0x00000000, 0x1306fe0a, 0x2ff221af, 0x52538f52, + 0x0f1a1bf4, 0x1455ccc2, 0x19ee62a8, 0x1fd92396, + 0x260dfc14, 0x2c8694d8, 0x333dcb29, 0x3a2f5c7a, + 0x4157aed5, 0x48b3aaa3, 0x50409f76, 0x57fc3010, + }, + { + 0x00000000, 0x16a09e66, 0x39047c0f, 0x61e734aa, + 0x11f59ac4, 0x182ec633, 0x1ed66a45, 0x25dfc55a, + 0x2d413ccd, 0x34f3462d, 0x3cefc603, 0x4531ab69, + 0x4db4adf8, 0x56752054, 0x5f6fcfcd, 0x68a1eca1, + }, + { + 0x00000000, 0x1ae89f99, 0x43ce3e4b, 0x746d57b2, + 0x155b8109, 0x1cc21cdc, 0x24ac1839, 0x2d0a479e, + 0x35d13f33, 0x3ef80748, 0x48775c93, 0x524938cd, + 0x5c68841d, 0x66d0df0a, 0x717e7bfe, 0x7c6e0305, + }, }; /* pow(j, 4.0 / 3.0) for j = [16,17,18,...,63], format = Q23 */ static const int pow43[48] PROGMEM = { - 0x1428a2fa, 0x15db1bd6, 0x1796302c, 0x19598d85, - 0x1b24e8bb, 0x1cf7fcfa, 0x1ed28af2, 0x20b4582a, - 0x229d2e6e, 0x248cdb55, 0x26832fda, 0x28800000, - 0x2a832287, 0x2c8c70a8, 0x2e9bc5d8, 0x30b0ff99, - 0x32cbfd4a, 0x34eca001, 0x3712ca62, 0x393e6088, - 0x3b6f47e0, 0x3da56717, 0x3fe0a5fc, 0x4220ed72, - 0x44662758, 0x46b03e7c, 0x48ff1e87, 0x4b52b3f3, - 0x4daaebfd, 0x5007b497, 0x5268fc62, 0x54ceb29c, - 0x5738c721, 0x59a72a59, 0x5c19cd35, 0x5e90a129, - 0x610b9821, 0x638aa47f, 0x660db90f, 0x6894c90b, - 0x6b1fc80c, 0x6daeaa0d, 0x70416360, 0x72d7e8b0, - 0x75722ef9, 0x78102b85, 0x7ab1d3ec, 0x7d571e09, + 0x1428a2fa, 0x15db1bd6, 0x1796302c, 0x19598d85, + 0x1b24e8bb, 0x1cf7fcfa, 0x1ed28af2, 0x20b4582a, + 0x229d2e6e, 0x248cdb55, 0x26832fda, 0x28800000, + 0x2a832287, 0x2c8c70a8, 0x2e9bc5d8, 0x30b0ff99, + 0x32cbfd4a, 0x34eca001, 0x3712ca62, 0x393e6088, + 0x3b6f47e0, 0x3da56717, 0x3fe0a5fc, 0x4220ed72, + 0x44662758, 0x46b03e7c, 0x48ff1e87, 0x4b52b3f3, + 0x4daaebfd, 0x5007b497, 0x5268fc62, 0x54ceb29c, + 0x5738c721, 0x59a72a59, 0x5c19cd35, 0x5e90a129, + 0x610b9821, 0x638aa47f, 0x660db90f, 0x6894c90b, + 0x6b1fc80c, 0x6daeaa0d, 0x70416360, 0x72d7e8b0, + 0x75722ef9, 0x78102b85, 0x7ab1d3ec, 0x7d571e09, }; /* sqrt(0.5), format = Q31 */ #define SQRTHALF 0x5a82799a -/* Minimax polynomial approximation to pow(x, 4/3), over the range - * poly43lo: x = [0.5, 0.7071] - * poly43hi: x = [0.7071, 1.0] - * - * Relative error < 1E-7 - * Coefs are scaled by 4, 2, 1, 0.5, 0.25 - */ - +/* Minimax polynomial approximation to pow(x, 4/3), over the range + poly43lo: x = [0.5, 0.7071] + poly43hi: x = [0.7071, 1.0] + + Relative error < 1E-7 + Coefs are scaled by 4, 2, 1, 0.5, 0.25 +*/ + //fb #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnarrowing" @@ -122,252 +122,260 @@ static const int pow2exp[8] PROGMEM = { 14, 13, 11, 10, 9, 7, 6, 5 }; /* pow2exp[i] = pow(2, i*4/3) fraction */ static const int pow2frac[8] PROGMEM = { - 0x6597fa94, 0x50a28be6, 0x7fffffff, 0x6597fa94, - 0x50a28be6, 0x7fffffff, 0x6597fa94, 0x50a28be6 + 0x6597fa94, 0x50a28be6, 0x7fffffff, 0x6597fa94, + 0x50a28be6, 0x7fffffff, 0x6597fa94, 0x50a28be6 }; /************************************************************************************** - * Function: DequantBlock - * - * Description: dequantize one block of transform coefficients (in-place) - * - * Inputs: quantized transform coefficients, range = [0, 8191] - * number of samples to dequantize - * scalefactor for this block of data, range = [0, 256] - * - * Outputs: dequantized transform coefficients in Q(FBITS_OUT_DQ_OFF) - * - * Return: guard bit mask (OR of abs value of all dequantized coefs) - * - * Notes: applies dequant formula y = pow(x, 4.0/3.0) * pow(2, (scale - 100)/4.0) + Function: DequantBlock + + Description: dequantize one block of transform coefficients (in-place) + + Inputs: quantized transform coefficients, range = [0, 8191] + number of samples to dequantize + scalefactor for this block of data, range = [0, 256] + + Outputs: dequantized transform coefficients in Q(FBITS_OUT_DQ_OFF) + + Return: guard bit mask (OR of abs value of all dequantized coefs) + + Notes: applies dequant formula y = pow(x, 4.0/3.0) * pow(2, (scale - 100)/4.0) * * pow(2, FBITS_OUT_DQ_OFF) - * clips outputs to Q(FBITS_OUT_DQ_OFF) - * output has no minimum number of guard bits + clips outputs to Q(FBITS_OUT_DQ_OFF) + output has no minimum number of guard bits **************************************************************************************/ -static int DequantBlock(int *inbuf, int nSamps, int scale) -{ - int iSamp, scalef, scalei, x, y, gbMask, shift, tab4[4]; - const int *tab16, *coef; - - if (nSamps <= 0) - return 0; - - scale -= SF_OFFSET; /* new range = [-100, 156] */ - - /* with two's complement numbers, scalei/scalef factorization works for pos and neg values of scale: - * [+4...+7] >> 2 = +1, [ 0...+3] >> 2 = 0, [-4...-1] >> 2 = -1, [-8...-5] >> 2 = -2 ... - * (-1 & 0x3) = 3, (-2 & 0x3) = 2, (-3 & 0x3) = 1, (0 & 0x3) = 0 - * - * Example: 2^(-5/4) = 2^(-1) * 2^(-1/4) = 2^-2 * 2^(3/4) - */ - tab16 = pow43_14[scale & 0x3]; - scalef = pow14[scale & 0x3]; - scalei = (scale >> 2) + FBITS_OUT_DQ_OFF; - - /* cache first 4 values: - * tab16[j] = Q28 for j = [0,3] - * tab4[x] = x^(4.0/3.0) * 2^(0.25*scale), Q(FBITS_OUT_DQ_OFF) - */ - shift = 28 - scalei; - if (shift > 31) { - tab4[0] = tab4[1] = tab4[2] = tab4[3] = 0; - } else if (shift <= 0) { - shift = -shift; - if (shift > 31) - shift = 31; - for (x = 0; x < 4; x++) { - y = tab16[x]; - if (y > (0x7fffffff >> shift)) - y = 0x7fffffff; /* clip (rare) */ - else - y <<= shift; - tab4[x] = y; - } - } else { - tab4[0] = 0; - tab4[1] = tab16[1] >> shift; - tab4[2] = tab16[2] >> shift; - tab4[3] = tab16[3] >> shift; - } - - gbMask = 0; - do { - iSamp = *inbuf; - x = FASTABS(iSamp); - - if (x < 4) { - y = tab4[x]; - } else { - - if (x < 16) { - /* result: y = Q25 (tab16 = Q25) */ - y = tab16[x]; - shift = 25 - scalei; - } else if (x < 64) { - /* result: y = Q21 (pow43tab[j] = Q23, scalef = Q30) */ - y = pow43[x-16]; - shift = 21 - scalei; - y = MULSHIFT32(y, scalef); - } else { - /* normalize to [0x40000000, 0x7fffffff] - * input x = [64, 8191] = [64, 2^13-1] - * ranges: - * shift = 7: 64 - 127 - * shift = 6: 128 - 255 - * shift = 5: 256 - 511 - * shift = 4: 512 - 1023 - * shift = 3: 1024 - 2047 - * shift = 2: 2048 - 4095 - * shift = 1: 4096 - 8191 - */ - x <<= 17; - shift = 0; - if (x < 0x08000000) - x <<= 4, shift += 4; - if (x < 0x20000000) - x <<= 2, shift += 2; - if (x < 0x40000000) - x <<= 1, shift += 1; - - coef = (x < SQRTHALF) ? poly43lo : poly43hi; - - /* polynomial */ - y = coef[0]; - y = MULSHIFT32(y, x) + coef[1]; - y = MULSHIFT32(y, x) + coef[2]; - y = MULSHIFT32(y, x) + coef[3]; - y = MULSHIFT32(y, x) + coef[4]; - y = MULSHIFT32(y, pow2frac[shift]) << 3; - - /* fractional scale - * result: y = Q21 (pow43tab[j] = Q23, scalef = Q30) - */ - y = MULSHIFT32(y, scalef); /* now y is Q24 */ - shift = 24 - scalei - pow2exp[shift]; - } - - /* integer scale */ - if (shift <= 0) { - shift = -shift; - if (shift > 31) - shift = 31; - - if (y > (0x7fffffff >> shift)) - y = 0x7fffffff; /* clip (rare) */ - else - y <<= shift; - } else { - if (shift > 31) - shift = 31; - y >>= shift; - } - } - - /* sign and store (gbMask used to count GB's) */ - gbMask |= y; - - /* apply sign */ - iSamp >>= 31; - y ^= iSamp; - y -= iSamp; - - *inbuf++ = y; - } while (--nSamps); - - return gbMask; +static int DequantBlock(int *inbuf, int nSamps, int scale) { + int iSamp, scalef, scalei, x, y, gbMask, shift, tab4[4]; + const int *tab16, *coef; + + if (nSamps <= 0) { + return 0; + } + + scale -= SF_OFFSET; /* new range = [-100, 156] */ + + /* with two's complement numbers, scalei/scalef factorization works for pos and neg values of scale: + [+4...+7] >> 2 = +1, [ 0...+3] >> 2 = 0, [-4...-1] >> 2 = -1, [-8...-5] >> 2 = -2 ... + (-1 & 0x3) = 3, (-2 & 0x3) = 2, (-3 & 0x3) = 1, (0 & 0x3) = 0 + + Example: 2^(-5/4) = 2^(-1) * 2^(-1/4) = 2^-2 * 2^(3/4) + */ + tab16 = pow43_14[scale & 0x3]; + scalef = pow14[scale & 0x3]; + scalei = (scale >> 2) + FBITS_OUT_DQ_OFF; + + /* cache first 4 values: + tab16[j] = Q28 for j = [0,3] + tab4[x] = x^(4.0/3.0) * 2^(0.25*scale), Q(FBITS_OUT_DQ_OFF) + */ + shift = 28 - scalei; + if (shift > 31) { + tab4[0] = tab4[1] = tab4[2] = tab4[3] = 0; + } else if (shift <= 0) { + shift = -shift; + if (shift > 31) { + shift = 31; + } + for (x = 0; x < 4; x++) { + y = tab16[x]; + if (y > (0x7fffffff >> shift)) { + y = 0x7fffffff; /* clip (rare) */ + } else { + y <<= shift; + } + tab4[x] = y; + } + } else { + tab4[0] = 0; + tab4[1] = tab16[1] >> shift; + tab4[2] = tab16[2] >> shift; + tab4[3] = tab16[3] >> shift; + } + + gbMask = 0; + do { + iSamp = *inbuf; + x = FASTABS(iSamp); + + if (x < 4) { + y = tab4[x]; + } else { + + if (x < 16) { + /* result: y = Q25 (tab16 = Q25) */ + y = tab16[x]; + shift = 25 - scalei; + } else if (x < 64) { + /* result: y = Q21 (pow43tab[j] = Q23, scalef = Q30) */ + y = pow43[x - 16]; + shift = 21 - scalei; + y = MULSHIFT32(y, scalef); + } else { + /* normalize to [0x40000000, 0x7fffffff] + input x = [64, 8191] = [64, 2^13-1] + ranges: + shift = 7: 64 - 127 + shift = 6: 128 - 255 + shift = 5: 256 - 511 + shift = 4: 512 - 1023 + shift = 3: 1024 - 2047 + shift = 2: 2048 - 4095 + shift = 1: 4096 - 8191 + */ + x <<= 17; + shift = 0; + if (x < 0x08000000) { + x <<= 4, shift += 4; + } + if (x < 0x20000000) { + x <<= 2, shift += 2; + } + if (x < 0x40000000) { + x <<= 1, shift += 1; + } + + coef = (x < SQRTHALF) ? poly43lo : poly43hi; + + /* polynomial */ + y = coef[0]; + y = MULSHIFT32(y, x) + coef[1]; + y = MULSHIFT32(y, x) + coef[2]; + y = MULSHIFT32(y, x) + coef[3]; + y = MULSHIFT32(y, x) + coef[4]; + y = MULSHIFT32(y, pow2frac[shift]) << 3; + + /* fractional scale + result: y = Q21 (pow43tab[j] = Q23, scalef = Q30) + */ + y = MULSHIFT32(y, scalef); /* now y is Q24 */ + shift = 24 - scalei - pow2exp[shift]; + } + + /* integer scale */ + if (shift <= 0) { + shift = -shift; + if (shift > 31) { + shift = 31; + } + + if (y > (0x7fffffff >> shift)) { + y = 0x7fffffff; /* clip (rare) */ + } else { + y <<= shift; + } + } else { + if (shift > 31) { + shift = 31; + } + y >>= shift; + } + } + + /* sign and store (gbMask used to count GB's) */ + gbMask |= y; + + /* apply sign */ + iSamp >>= 31; + y ^= iSamp; + y -= iSamp; + + *inbuf++ = y; + } while (--nSamps); + + return gbMask; } /************************************************************************************** - * Function: Dequantize - * - * Description: dequantize all transform coefficients for one channel - * - * Inputs: valid AACDecInfo struct (including unpacked, quantized coefficients) - * index of current channel - * - * Outputs: dequantized coefficients, including short-block deinterleaving - * flags indicating if intensity and/or PNS is active - * minimum guard bit count for dequantized coefficients - * - * Return: 0 if successful, error code (< 0) if error + Function: Dequantize + + Description: dequantize all transform coefficients for one channel + + Inputs: valid AACDecInfo struct (including unpacked, quantized coefficients) + index of current channel + + Outputs: dequantized coefficients, including short-block deinterleaving + flags indicating if intensity and/or PNS is active + minimum guard bit count for dequantized coefficients + + Return: 0 if successful, error code (< 0) if error **************************************************************************************/ -int Dequantize(AACDecInfo *aacDecInfo, int ch) -{ - int gp, cb, sfb, win, width, nSamps, gbMask; - int *coef; - const int /*short*/ *sfbTab; - unsigned char *sfbCodeBook; - short *scaleFactors; - PSInfoBase *psi; - ICSInfo *icsInfo; - - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return ERR_AAC_NULL_POINTER; - psi = (PSInfoBase *)(aacDecInfo->psInfoBase); - icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]); - - if (icsInfo->winSequence == 2) { - sfbTab = sfBandTabShort + sfBandTabShortOffset[psi->sampRateIdx]; - nSamps = NSAMPS_SHORT; - } else { - sfbTab = sfBandTabLong + sfBandTabLongOffset[psi->sampRateIdx]; - nSamps = NSAMPS_LONG; - } - coef = psi->coef[ch]; - sfbCodeBook = psi->sfbCodeBook[ch]; - scaleFactors = psi->scaleFactors[ch]; - - psi->intensityUsed[ch] = 0; - psi->pnsUsed[ch] = 0; - gbMask = 0; - for (gp = 0; gp < icsInfo->numWinGroup; gp++) { - for (win = 0; win < icsInfo->winGroupLen[gp]; win++) { - for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) { - /* dequantize one scalefactor band (not necessary if codebook is intensity or PNS) - * for zero codebook, still run dequantizer in case non-zero pulse data was added - */ - cb = (int)(sfbCodeBook[sfb]); - width = sfbTab[sfb+1] - sfbTab[sfb]; - if (cb >= 0 && cb <= 11) - gbMask |= DequantBlock(coef, width, scaleFactors[sfb]); - else if (cb == 13) - psi->pnsUsed[ch] = 1; - else if (cb == 14 || cb == 15) - psi->intensityUsed[ch] = 1; /* should only happen if ch == 1 */ - coef += width; - } - coef += (nSamps - sfbTab[icsInfo->maxSFB]); - } - sfbCodeBook += icsInfo->maxSFB; - scaleFactors += icsInfo->maxSFB; - } - aacDecInfo->pnsUsed |= psi->pnsUsed[ch]; /* set flag if PNS used for any channel */ - - /* calculate number of guard bits in dequantized data */ - psi->gbCurrent[ch] = CLZ(gbMask) - 1; - - return ERR_AAC_NONE; +int Dequantize(AACDecInfo *aacDecInfo, int ch) { + int gp, cb, sfb, win, width, nSamps, gbMask; + int *coef; + const int /*short*/ *sfbTab; + unsigned char *sfbCodeBook; + short *scaleFactors; + PSInfoBase *psi; + ICSInfo *icsInfo; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return ERR_AAC_NULL_POINTER; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]); + + if (icsInfo->winSequence == 2) { + sfbTab = sfBandTabShort + sfBandTabShortOffset[psi->sampRateIdx]; + nSamps = NSAMPS_SHORT; + } else { + sfbTab = sfBandTabLong + sfBandTabLongOffset[psi->sampRateIdx]; + nSamps = NSAMPS_LONG; + } + coef = psi->coef[ch]; + sfbCodeBook = psi->sfbCodeBook[ch]; + scaleFactors = psi->scaleFactors[ch]; + + psi->intensityUsed[ch] = 0; + psi->pnsUsed[ch] = 0; + gbMask = 0; + for (gp = 0; gp < icsInfo->numWinGroup; gp++) { + for (win = 0; win < icsInfo->winGroupLen[gp]; win++) { + for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) { + /* dequantize one scalefactor band (not necessary if codebook is intensity or PNS) + for zero codebook, still run dequantizer in case non-zero pulse data was added + */ + cb = (int)(sfbCodeBook[sfb]); + width = sfbTab[sfb + 1] - sfbTab[sfb]; + if (cb >= 0 && cb <= 11) { + gbMask |= DequantBlock(coef, width, scaleFactors[sfb]); + } else if (cb == 13) { + psi->pnsUsed[ch] = 1; + } else if (cb == 14 || cb == 15) { + psi->intensityUsed[ch] = 1; /* should only happen if ch == 1 */ + } + coef += width; + } + coef += (nSamps - sfbTab[icsInfo->maxSFB]); + } + sfbCodeBook += icsInfo->maxSFB; + scaleFactors += icsInfo->maxSFB; + } + aacDecInfo->pnsUsed |= psi->pnsUsed[ch]; /* set flag if PNS used for any channel */ + + /* calculate number of guard bits in dequantized data */ + psi->gbCurrent[ch] = CLZ(gbMask) - 1; + + return ERR_AAC_NONE; } /************************************************************************************** - * Function: DeinterleaveShortBlocks - * - * Description: deinterleave transform coefficients in short blocks for one channel - * - * Inputs: valid AACDecInfo struct (including unpacked, quantized coefficients) - * index of current channel - * - * Outputs: deinterleaved coefficients (window groups into 8 separate windows) - * - * Return: 0 if successful, error code (< 0) if error - * - * Notes: only necessary if deinterleaving not part of Huffman decoding + Function: DeinterleaveShortBlocks + + Description: deinterleave transform coefficients in short blocks for one channel + + Inputs: valid AACDecInfo struct (including unpacked, quantized coefficients) + index of current channel + + Outputs: deinterleaved coefficients (window groups into 8 separate windows) + + Return: 0 if successful, error code (< 0) if error + + Notes: only necessary if deinterleaving not part of Huffman decoding **************************************************************************************/ -int DeinterleaveShortBlocks(AACDecInfo *aacDecInfo, int ch) -{ - (void)aacDecInfo; - (void)ch; - /* not used for this implementation - short block deinterleaving performed during Huffman decoding */ - return ERR_AAC_NONE; +int DeinterleaveShortBlocks(AACDecInfo *aacDecInfo, int ch) { + (void)aacDecInfo; + (void)ch; + /* not used for this implementation - short block deinterleaving performed during Huffman decoding */ + return ERR_AAC_NONE; } diff --git a/src/libhelix-aac/fft.c b/src/libhelix-aac/fft.c index 0fc934ca..b60d6e4a 100644 --- a/src/libhelix-aac/fft.c +++ b/src/libhelix-aac/fft.c @@ -1,53 +1,54 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: fft.c,v 1.1 2005/02/26 01:47:34 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +#pragma GCC optimize ("O3") +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: fft.c,v 1.1 2005/02/26 01:47:34 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * February 2005 - * - * fft.c - Ken's optimized radix-4 DIT FFT, optional radix-8 first pass for odd log2(N) + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + February 2005 + + fft.c - Ken's optimized radix-4 DIT FFT, optional radix-8 first pass for odd log2(N) **************************************************************************************/ #include "coder.h" #include "assembly.h" #define NUM_FFT_SIZES 2 -static const int nfftTab[NUM_FFT_SIZES] PROGMEM ={64, 512}; +static const int nfftTab[NUM_FFT_SIZES] PROGMEM = {64, 512}; static const int nfftlog2Tab[NUM_FFT_SIZES] PROGMEM = {6, 9}; #define SQRT1_2 0x5a82799a /* sqrt(1/2) in Q31 */ @@ -56,338 +57,341 @@ static const int nfftlog2Tab[NUM_FFT_SIZES] PROGMEM = {6, 9}; t = p0; t1 = *(&(p0)+1); p0 = p1; *(&(p0)+1) = *(&(p1)+1); p1 = t; *(&(p1)+1) = t1 /************************************************************************************** - * Function: BitReverse - * - * Description: Ken's fast in-place bit reverse, using super-small table - * - * Inputs: buffer of samples - * table index (for transform size) - * - * Outputs: bit-reversed samples in same buffer - * - * Return: none + Function: BitReverse + + Description: Ken's fast in-place bit reverse, using super-small table + + Inputs: buffer of samples + table index (for transform size) + + Outputs: bit-reversed samples in same buffer + + Return: none **************************************************************************************/ - /*__attribute__ ((section (".data"))) */ static void BitReverse(int *inout, int tabidx) -{ +/*__attribute__ ((section (".data"))) */ static void BitReverse(int *inout, int tabidx) { int *part0, *part1; - int a,b, t,t1; - const unsigned char* tab = bitrevtab + bitrevtabOffset[tabidx]; - int nbits = nfftlog2Tab[tabidx]; + int a, b, t, t1; + const unsigned char* tab = bitrevtab + bitrevtabOffset[tabidx]; + int nbits = nfftlog2Tab[tabidx]; - part0 = inout; + part0 = inout; part1 = inout + (1 << nbits); - - while ((a = pgm_read_byte(tab++)) != 0) { - b = pgm_read_byte(tab++); - swapcplx(part0[4*a+0], part0[4*b+0]); /* 0xxx0 <-> 0yyy0 */ - swapcplx(part0[4*a+2], part1[4*b+0]); /* 0xxx1 <-> 1yyy0 */ - swapcplx(part1[4*a+0], part0[4*b+2]); /* 1xxx0 <-> 0yyy1 */ - swapcplx(part1[4*a+2], part1[4*b+2]); /* 1xxx1 <-> 1yyy1 */ +#ifdef ESP8266 + while ((a = pgm_read_byte(tab++)) != 0) { + b = pgm_read_byte(tab++); +#else + while ((a = *(tab++)) != 0) { + b = *(tab++); +#endif + + swapcplx(part0[4 * a + 0], part0[4 * b + 0]); /* 0xxx0 <-> 0yyy0 */ + swapcplx(part0[4 * a + 2], part1[4 * b + 0]); /* 0xxx1 <-> 1yyy0 */ + swapcplx(part1[4 * a + 0], part0[4 * b + 2]); /* 1xxx0 <-> 0yyy1 */ + swapcplx(part1[4 * a + 2], part1[4 * b + 2]); /* 1xxx1 <-> 1yyy1 */ } do { - swapcplx(part0[4*a+2], part1[4*a+0]); /* 0xxx1 <-> 1xxx0 */ + swapcplx(part0[4 * a + 2], part1[4 * a + 0]); /* 0xxx1 <-> 1xxx0 */ +#ifdef ESP8266 } while ((a = pgm_read_byte(tab++)) != 0); - - +#else + } while ((a = *(tab++)) != 0); +#endif + } /************************************************************************************** - * Function: R4FirstPass - * - * Description: radix-4 trivial pass for decimation-in-time FFT - * - * Inputs: buffer of (bit-reversed) samples - * number of R4 butterflies per group (i.e. nfft / 4) - * - * Outputs: processed samples in same buffer - * - * Return: none - * - * Notes: assumes 2 guard bits, gains no integer bits, - * guard bits out = guard bits in - 2 + Function: R4FirstPass + + Description: radix-4 trivial pass for decimation-in-time FFT + + Inputs: buffer of (bit-reversed) samples + number of R4 butterflies per group (i.e. nfft / 4) + + Outputs: processed samples in same buffer + + Return: none + + Notes: assumes 2 guard bits, gains no integer bits, + guard bits out = guard bits in - 2 **************************************************************************************/ - /* __attribute__ ((section (".data"))) */ static void R4FirstPass(int *x, int bg) -{ +/* __attribute__ ((section (".data"))) */ static void R4FirstPass(int *x, int bg) { int ar, ai, br, bi, cr, ci, dr, di; - - for (; bg != 0; bg--) { - - ar = x[0] + x[2]; - br = x[0] - x[2]; - ai = x[1] + x[3]; - bi = x[1] - x[3]; - cr = x[4] + x[6]; - dr = x[4] - x[6]; - ci = x[5] + x[7]; - di = x[5] - x[7]; - - /* max per-sample gain = 4.0 (adding 4 inputs together) */ - x[0] = ar + cr; - x[4] = ar - cr; - x[1] = ai + ci; - x[5] = ai - ci; - x[2] = br + di; - x[6] = br - di; - x[3] = bi - dr; - x[7] = bi + dr; - - x += 8; - } + + for (; bg != 0; bg--) { + + ar = x[0] + x[2]; + br = x[0] - x[2]; + ai = x[1] + x[3]; + bi = x[1] - x[3]; + cr = x[4] + x[6]; + dr = x[4] - x[6]; + ci = x[5] + x[7]; + di = x[5] - x[7]; + + /* max per-sample gain = 4.0 (adding 4 inputs together) */ + x[0] = ar + cr; + x[4] = ar - cr; + x[1] = ai + ci; + x[5] = ai - ci; + x[2] = br + di; + x[6] = br - di; + x[3] = bi - dr; + x[7] = bi + dr; + + x += 8; + } } /************************************************************************************** - * Function: R8FirstPass - * - * Description: radix-8 trivial pass for decimation-in-time FFT - * - * Inputs: buffer of (bit-reversed) samples - * number of R8 butterflies per group (i.e. nfft / 8) - * - * Outputs: processed samples in same buffer - * - * Return: none - * - * Notes: assumes 3 guard bits, gains 1 integer bit - * guard bits out = guard bits in - 3 (if inputs are full scale) - * or guard bits in - 2 (if inputs bounded to +/- sqrt(2)/2) - * see scaling comments in code + Function: R8FirstPass + + Description: radix-8 trivial pass for decimation-in-time FFT + + Inputs: buffer of (bit-reversed) samples + number of R8 butterflies per group (i.e. nfft / 8) + + Outputs: processed samples in same buffer + + Return: none + + Notes: assumes 3 guard bits, gains 1 integer bit + guard bits out = guard bits in - 3 (if inputs are full scale) + or guard bits in - 2 (if inputs bounded to +/- sqrt(2)/2) + see scaling comments in code **************************************************************************************/ - /* __attribute__ ((section (".data"))) */ static void R8FirstPass(int *x, int bg) -{ +/* __attribute__ ((section (".data"))) */ static void R8FirstPass(int *x, int bg) { int ar, ai, br, bi, cr, ci, dr, di; - int sr, si, tr, ti, ur, ui, vr, vi; - int wr, wi, xr, xi, yr, yi, zr, zi; - - for (; bg != 0; bg--) { - - ar = x[0] + x[2]; - br = x[0] - x[2]; - ai = x[1] + x[3]; - bi = x[1] - x[3]; - cr = x[4] + x[6]; - dr = x[4] - x[6]; - ci = x[5] + x[7]; - di = x[5] - x[7]; - - sr = ar + cr; - ur = ar - cr; - si = ai + ci; - ui = ai - ci; - tr = br - di; - vr = br + di; - ti = bi + dr; - vi = bi - dr; - - ar = x[ 8] + x[10]; - br = x[ 8] - x[10]; - ai = x[ 9] + x[11]; - bi = x[ 9] - x[11]; - cr = x[12] + x[14]; - dr = x[12] - x[14]; - ci = x[13] + x[15]; - di = x[13] - x[15]; - - /* max gain of wr/wi/yr/yi vs input = 2 - * (sum of 4 samples >> 1) - */ - wr = (ar + cr) >> 1; - yr = (ar - cr) >> 1; - wi = (ai + ci) >> 1; - yi = (ai - ci) >> 1; - - /* max gain of output vs input = 4 - * (sum of 4 samples >> 1 + sum of 4 samples >> 1) - */ - x[ 0] = (sr >> 1) + wr; - x[ 8] = (sr >> 1) - wr; - x[ 1] = (si >> 1) + wi; - x[ 9] = (si >> 1) - wi; - x[ 4] = (ur >> 1) + yi; - x[12] = (ur >> 1) - yi; - x[ 5] = (ui >> 1) - yr; - x[13] = (ui >> 1) + yr; - - ar = br - di; - cr = br + di; - ai = bi + dr; - ci = bi - dr; - - /* max gain of xr/xi/zr/zi vs input = 4*sqrt(2)/2 = 2*sqrt(2) - * (sum of 8 samples, multiply by sqrt(2)/2, implicit >> 1 from Q31) - */ - xr = MULSHIFT32(SQRT1_2, ar - ai); - xi = MULSHIFT32(SQRT1_2, ar + ai); - zr = MULSHIFT32(SQRT1_2, cr - ci); - zi = MULSHIFT32(SQRT1_2, cr + ci); - - /* max gain of output vs input = (2 + 2*sqrt(2) ~= 4.83) - * (sum of 4 samples >> 1, plus xr/xi/zr/zi with gain of 2*sqrt(2)) - * in absolute terms, we have max gain of appx 9.656 (4 + 0.707*8) - * but we also gain 1 int bit (from MULSHIFT32 or from explicit >> 1) - */ - x[ 6] = (tr >> 1) - xr; - x[14] = (tr >> 1) + xr; - x[ 7] = (ti >> 1) - xi; - x[15] = (ti >> 1) + xi; - x[ 2] = (vr >> 1) + zi; - x[10] = (vr >> 1) - zi; - x[ 3] = (vi >> 1) - zr; - x[11] = (vi >> 1) + zr; - - x += 16; - } + int sr, si, tr, ti, ur, ui, vr, vi; + int wr, wi, xr, xi, yr, yi, zr, zi; + + for (; bg != 0; bg--) { + + ar = x[0] + x[2]; + br = x[0] - x[2]; + ai = x[1] + x[3]; + bi = x[1] - x[3]; + cr = x[4] + x[6]; + dr = x[4] - x[6]; + ci = x[5] + x[7]; + di = x[5] - x[7]; + + sr = ar + cr; + ur = ar - cr; + si = ai + ci; + ui = ai - ci; + tr = br - di; + vr = br + di; + ti = bi + dr; + vi = bi - dr; + + ar = x[ 8] + x[10]; + br = x[ 8] - x[10]; + ai = x[ 9] + x[11]; + bi = x[ 9] - x[11]; + cr = x[12] + x[14]; + dr = x[12] - x[14]; + ci = x[13] + x[15]; + di = x[13] - x[15]; + + /* max gain of wr/wi/yr/yi vs input = 2 + (sum of 4 samples >> 1) + */ + wr = (ar + cr) >> 1; + yr = (ar - cr) >> 1; + wi = (ai + ci) >> 1; + yi = (ai - ci) >> 1; + + /* max gain of output vs input = 4 + (sum of 4 samples >> 1 + sum of 4 samples >> 1) + */ + x[ 0] = (sr >> 1) + wr; + x[ 8] = (sr >> 1) - wr; + x[ 1] = (si >> 1) + wi; + x[ 9] = (si >> 1) - wi; + x[ 4] = (ur >> 1) + yi; + x[12] = (ur >> 1) - yi; + x[ 5] = (ui >> 1) - yr; + x[13] = (ui >> 1) + yr; + + ar = br - di; + cr = br + di; + ai = bi + dr; + ci = bi - dr; + + /* max gain of xr/xi/zr/zi vs input = 4*sqrt(2)/2 = 2*sqrt(2) + (sum of 8 samples, multiply by sqrt(2)/2, implicit >> 1 from Q31) + */ + xr = MULSHIFT32(SQRT1_2, ar - ai); + xi = MULSHIFT32(SQRT1_2, ar + ai); + zr = MULSHIFT32(SQRT1_2, cr - ci); + zi = MULSHIFT32(SQRT1_2, cr + ci); + + /* max gain of output vs input = (2 + 2*sqrt(2) ~= 4.83) + (sum of 4 samples >> 1, plus xr/xi/zr/zi with gain of 2*sqrt(2)) + in absolute terms, we have max gain of appx 9.656 (4 + 0.707*8) + but we also gain 1 int bit (from MULSHIFT32 or from explicit >> 1) + */ + x[ 6] = (tr >> 1) - xr; + x[14] = (tr >> 1) + xr; + x[ 7] = (ti >> 1) - xi; + x[15] = (ti >> 1) + xi; + x[ 2] = (vr >> 1) + zi; + x[10] = (vr >> 1) - zi; + x[ 3] = (vi >> 1) - zr; + x[11] = (vi >> 1) + zr; + + x += 16; + } } /************************************************************************************** - * Function: R4Core - * - * Description: radix-4 pass for decimation-in-time FFT - * - * Inputs: buffer of samples - * number of R4 butterflies per group - * number of R4 groups per pass - * pointer to twiddle factors tables - * - * Outputs: processed samples in same buffer - * - * Return: none - * - * Notes: gain 2 integer bits per pass (see scaling comments in code) - * min 1 GB in - * gbOut = gbIn - 1 (short block) or gbIn - 2 (long block) - * uses 3-mul, 3-add butterflies instead of 4-mul, 2-add + Function: R4Core + + Description: radix-4 pass for decimation-in-time FFT + + Inputs: buffer of samples + number of R4 butterflies per group + number of R4 groups per pass + pointer to twiddle factors tables + + Outputs: processed samples in same buffer + + Return: none + + Notes: gain 2 integer bits per pass (see scaling comments in code) + min 1 GB in + gbOut = gbIn - 1 (short block) or gbIn - 2 (long block) + uses 3-mul, 3-add butterflies instead of 4-mul, 2-add **************************************************************************************/ - /* __attribute__ ((section (".data"))) */ static void R4Core(int *x, int bg, int gp, int *wtab) -{ - int ar, ai, br, bi, cr, ci, dr, di, tr, ti; - int wd, ws, wi; - int i, j, step; - int *xptr, *wptr; - - for (; bg != 0; gp <<= 2, bg >>= 2) { - - step = 2*gp; - xptr = x; - - /* max per-sample gain, per group < 1 + 3*sqrt(2) ~= 5.25 if inputs x are full-scale - * do 3 groups for long block, 2 groups for short block (gain 2 int bits per group) - * - * very conservative scaling: - * group 1: max gain = 5.25, int bits gained = 2, gb used = 1 (2^3 = 8) - * group 2: max gain = 5.25^2 = 27.6, int bits gained = 4, gb used = 1 (2^5 = 32) - * group 3: max gain = 5.25^3 = 144.7, int bits gained = 6, gb used = 2 (2^8 = 256) - */ - for (i = bg; i != 0; i--) { - - wptr = wtab; - - for (j = gp; j != 0; j--) { - - ar = xptr[0]; - ai = xptr[1]; - xptr += step; - - /* gain 2 int bits for br/bi, cr/ci, dr/di (MULSHIFT32 by Q30) - * gain 1 net GB - */ - ws = wptr[0]; - wi = wptr[1]; - br = xptr[0]; - bi = xptr[1]; - wd = ws + 2*wi; - tr = MULSHIFT32(wi, br + bi); - br = MULSHIFT32(wd, br) - tr; /* cos*br + sin*bi */ - bi = MULSHIFT32(ws, bi) + tr; /* cos*bi - sin*br */ - xptr += step; - - ws = wptr[2]; - wi = wptr[3]; - cr = xptr[0]; - ci = xptr[1]; - wd = ws + 2*wi; - tr = MULSHIFT32(wi, cr + ci); - cr = MULSHIFT32(wd, cr) - tr; - ci = MULSHIFT32(ws, ci) + tr; - xptr += step; - - ws = wptr[4]; - wi = wptr[5]; - dr = xptr[0]; - di = xptr[1]; - wd = ws + 2*wi; - tr = MULSHIFT32(wi, dr + di); - dr = MULSHIFT32(wd, dr) - tr; - di = MULSHIFT32(ws, di) + tr; - wptr += 6; - - tr = ar; - ti = ai; - ar = (tr >> 2) - br; - ai = (ti >> 2) - bi; - br = (tr >> 2) + br; - bi = (ti >> 2) + bi; - - tr = cr; - ti = ci; - cr = tr + dr; - ci = di - ti; - dr = tr - dr; - di = di + ti; - - xptr[0] = ar + ci; - xptr[1] = ai + dr; - xptr -= step; - xptr[0] = br - cr; - xptr[1] = bi - di; - xptr -= step; - xptr[0] = ar - ci; - xptr[1] = ai - dr; - xptr -= step; - xptr[0] = br + cr; - xptr[1] = bi + di; - xptr += 2; - } - xptr += 3*step; - } - wtab += 3*step; - } +/* __attribute__ ((section (".data"))) */ static void R4Core(int *x, int bg, int gp, int *wtab) { + int ar, ai, br, bi, cr, ci, dr, di, tr, ti; + int wd, ws, wi; + int i, j, step; + int *xptr, *wptr; + + for (; bg != 0; gp <<= 2, bg >>= 2) { + + step = 2 * gp; + xptr = x; + + /* max per-sample gain, per group < 1 + 3*sqrt(2) ~= 5.25 if inputs x are full-scale + do 3 groups for long block, 2 groups for short block (gain 2 int bits per group) + + very conservative scaling: + group 1: max gain = 5.25, int bits gained = 2, gb used = 1 (2^3 = 8) + group 2: max gain = 5.25^2 = 27.6, int bits gained = 4, gb used = 1 (2^5 = 32) + group 3: max gain = 5.25^3 = 144.7, int bits gained = 6, gb used = 2 (2^8 = 256) + */ + for (i = bg; i != 0; i--) { + + wptr = wtab; + + for (j = gp; j != 0; j--) { + + ar = xptr[0]; + ai = xptr[1]; + xptr += step; + + /* gain 2 int bits for br/bi, cr/ci, dr/di (MULSHIFT32 by Q30) + gain 1 net GB + */ + ws = wptr[0]; + wi = wptr[1]; + br = xptr[0]; + bi = xptr[1]; + wd = ws + 2 * wi; + tr = MULSHIFT32(wi, br + bi); + br = MULSHIFT32(wd, br) - tr; /* cos*br + sin*bi */ + bi = MULSHIFT32(ws, bi) + tr; /* cos*bi - sin*br */ + xptr += step; + + ws = wptr[2]; + wi = wptr[3]; + cr = xptr[0]; + ci = xptr[1]; + wd = ws + 2 * wi; + tr = MULSHIFT32(wi, cr + ci); + cr = MULSHIFT32(wd, cr) - tr; + ci = MULSHIFT32(ws, ci) + tr; + xptr += step; + + ws = wptr[4]; + wi = wptr[5]; + dr = xptr[0]; + di = xptr[1]; + wd = ws + 2 * wi; + tr = MULSHIFT32(wi, dr + di); + dr = MULSHIFT32(wd, dr) - tr; + di = MULSHIFT32(ws, di) + tr; + wptr += 6; + + tr = ar; + ti = ai; + ar = (tr >> 2) - br; + ai = (ti >> 2) - bi; + br = (tr >> 2) + br; + bi = (ti >> 2) + bi; + + tr = cr; + ti = ci; + cr = tr + dr; + ci = di - ti; + dr = tr - dr; + di = di + ti; + + xptr[0] = ar + ci; + xptr[1] = ai + dr; + xptr -= step; + xptr[0] = br - cr; + xptr[1] = bi - di; + xptr -= step; + xptr[0] = ar - ci; + xptr[1] = ai - dr; + xptr -= step; + xptr[0] = br + cr; + xptr[1] = bi + di; + xptr += 2; + } + xptr += 3 * step; + } + wtab += 3 * step; + } } /************************************************************************************** - * Function: R4FFT - * - * Description: Ken's very fast in-place radix-4 decimation-in-time FFT - * - * Inputs: table index (for transform size) - * buffer of samples (non bit-reversed) - * - * Outputs: processed samples in same buffer - * - * Return: none - * - * Notes: assumes 5 guard bits in for nfft <= 512 - * gbOut = gbIn - 4 (assuming input is from PreMultiply) - * gains log2(nfft) - 2 int bits total - * so gain 7 int bits (LONG), 4 int bits (SHORT) + Function: R4FFT + + Description: Ken's very fast in-place radix-4 decimation-in-time FFT + + Inputs: table index (for transform size) + buffer of samples (non bit-reversed) + + Outputs: processed samples in same buffer + + Return: none + + Notes: assumes 5 guard bits in for nfft <= 512 + gbOut = gbIn - 4 (assuming input is from PreMultiply) + gains log2(nfft) - 2 int bits total + so gain 7 int bits (LONG), 4 int bits (SHORT) **************************************************************************************/ -void R4FFT(int tabidx, int *x) -{ - int order = nfftlog2Tab[tabidx]; - int nfft = nfftTab[tabidx]; - - /* decimation in time */ - BitReverse(x, tabidx); - - if (order & 0x1) { - /* long block: order = 9, nfft = 512 */ - R8FirstPass(x, nfft >> 3); /* gain 1 int bit, lose 2 GB */ - R4Core(x, nfft >> 5, 8, (int *)twidTabOdd); /* gain 6 int bits, lose 2 GB */ - } else { - /* short block: order = 6, nfft = 64 */ - R4FirstPass(x, nfft >> 2); /* gain 0 int bits, lose 2 GB */ - R4Core(x, nfft >> 4, 4, (int *)twidTabEven); /* gain 4 int bits, lose 1 GB */ - } +void R4FFT(int tabidx, int *x) { + int order = nfftlog2Tab[tabidx]; + int nfft = nfftTab[tabidx]; + + /* decimation in time */ + BitReverse(x, tabidx); + + if (order & 0x1) { + /* long block: order = 9, nfft = 512 */ + R8FirstPass(x, nfft >> 3); /* gain 1 int bit, lose 2 GB */ + R4Core(x, nfft >> 5, 8, (int *)twidTabOdd); /* gain 6 int bits, lose 2 GB */ + } else { + /* short block: order = 6, nfft = 64 */ + R4FirstPass(x, nfft >> 2); /* gain 0 int bits, lose 2 GB */ + R4Core(x, nfft >> 4, 4, (int *)twidTabEven); /* gain 4 int bits, lose 1 GB */ + } } diff --git a/src/libhelix-aac/filefmt.c b/src/libhelix-aac/filefmt.c index ccfac596..7f6e8831 100644 --- a/src/libhelix-aac/filefmt.c +++ b/src/libhelix-aac/filefmt.c @@ -1,496 +1,517 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: filefmt.c,v 1.1 2005/02/26 01:47:34 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: filefmt.c,v 1.1 2005/02/26 01:47:34 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * filefmt.c - ADIF and ADTS header decoding, raw block handling + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + filefmt.c - ADIF and ADTS header decoding, raw block handling **************************************************************************************/ #include "coder.h" - /************************************************************************************** - * Function: UnpackADTSHeader - * - * Description: parse the ADTS frame header and initialize decoder state - * - * Inputs: valid AACDecInfo struct - * double pointer to buffer with complete ADTS frame header (byte aligned) - * header size = 7 bytes, plus 2 if CRC - * - * Outputs: filled in ADTS struct - * updated buffer pointer - * updated bit offset - * updated number of available bits - * - * Return: 0 if successful, error code (< 0) if error - * - * TODO: test CRC - * verify that fixed fields don't change between frames - **************************************************************************************/ -int UnpackADTSHeader(AACDecInfo *aacDecInfo, unsigned char **buf, int *bitOffset, int *bitsAvail) -{ - int bitsUsed; - PSInfoBase *psi; - BitStreamInfo bsi; - ADTSHeader *fhADTS; - - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return ERR_AAC_NULL_POINTER; - psi = (PSInfoBase *)(aacDecInfo->psInfoBase); - fhADTS = &(psi->fhADTS); - - /* init bitstream reader */ - SetBitstreamPointer(&bsi, (*bitsAvail + 7) >> 3, *buf); - GetBits(&bsi, *bitOffset); - - /* verify that first 12 bits of header are syncword */ - if (GetBits(&bsi, 12) != 0x0fff) { - return ERR_AAC_INVALID_ADTS_HEADER; - } - - /* fixed fields - should not change from frame to frame */ - fhADTS->id = GetBits(&bsi, 1); - fhADTS->layer = GetBits(&bsi, 2); - fhADTS->protectBit = GetBits(&bsi, 1); - fhADTS->profile = GetBits(&bsi, 2); - fhADTS->sampRateIdx = GetBits(&bsi, 4); - fhADTS->privateBit = GetBits(&bsi, 1); - fhADTS->channelConfig = GetBits(&bsi, 3); - fhADTS->origCopy = GetBits(&bsi, 1); - fhADTS->home = GetBits(&bsi, 1); - - /* variable fields - can change from frame to frame */ - fhADTS->copyBit = GetBits(&bsi, 1); - fhADTS->copyStart = GetBits(&bsi, 1); - fhADTS->frameLength = GetBits(&bsi, 13); - fhADTS->bufferFull = GetBits(&bsi, 11); - fhADTS->numRawDataBlocks = GetBits(&bsi, 2) + 1; - - /* note - MPEG4 spec, correction 1 changes how CRC is handled when protectBit == 0 and numRawDataBlocks > 1 */ - if (fhADTS->protectBit == 0) - fhADTS->crcCheckWord = GetBits(&bsi, 16); - - /* byte align */ - ByteAlignBitstream(&bsi); /* should always be aligned anyway */ - - /* check validity of header */ - if (fhADTS->layer != 0 || fhADTS->profile != AAC_PROFILE_LC || - fhADTS->sampRateIdx >= NUM_SAMPLE_RATES || fhADTS->channelConfig >= NUM_DEF_CHAN_MAPS) - return ERR_AAC_INVALID_ADTS_HEADER; +/************************************************************************************** + Function: UnpackADTSHeader + + Description: parse the ADTS frame header and initialize decoder state + + Inputs: valid AACDecInfo struct + double pointer to buffer with complete ADTS frame header (byte aligned) + header size = 7 bytes, plus 2 if CRC + + Outputs: filled in ADTS struct + updated buffer pointer + updated bit offset + updated number of available bits + + Return: 0 if successful, error code (< 0) if error + + TODO: test CRC + verify that fixed fields don't change between frames +**************************************************************************************/ +int UnpackADTSHeader(AACDecInfo *aacDecInfo, unsigned char **buf, int *bitOffset, int *bitsAvail) { + int bitsUsed; + PSInfoBase *psi; + BitStreamInfo bsi; + ADTSHeader *fhADTS; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return ERR_AAC_NULL_POINTER; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + fhADTS = &(psi->fhADTS); + + /* init bitstream reader */ + SetBitstreamPointer(&bsi, (*bitsAvail + 7) >> 3, *buf); + GetBits(&bsi, *bitOffset); + + /* verify that first 12 bits of header are syncword */ + if (GetBits(&bsi, 12) != 0x0fff) { + return ERR_AAC_INVALID_ADTS_HEADER; + } + + /* fixed fields - should not change from frame to frame */ + fhADTS->id = GetBits(&bsi, 1); + fhADTS->layer = GetBits(&bsi, 2); + fhADTS->protectBit = GetBits(&bsi, 1); + fhADTS->profile = GetBits(&bsi, 2); + fhADTS->sampRateIdx = GetBits(&bsi, 4); + fhADTS->privateBit = GetBits(&bsi, 1); + fhADTS->channelConfig = GetBits(&bsi, 3); + fhADTS->origCopy = GetBits(&bsi, 1); + fhADTS->home = GetBits(&bsi, 1); + + /* variable fields - can change from frame to frame */ + fhADTS->copyBit = GetBits(&bsi, 1); + fhADTS->copyStart = GetBits(&bsi, 1); + fhADTS->frameLength = GetBits(&bsi, 13); + fhADTS->bufferFull = GetBits(&bsi, 11); + fhADTS->numRawDataBlocks = GetBits(&bsi, 2) + 1; + + /* note - MPEG4 spec, correction 1 changes how CRC is handled when protectBit == 0 and numRawDataBlocks > 1 */ + if (fhADTS->protectBit == 0) { + fhADTS->crcCheckWord = GetBits(&bsi, 16); + } + + /* byte align */ + ByteAlignBitstream(&bsi); /* should always be aligned anyway */ + + /* check validity of header */ + if (fhADTS->layer != 0 || fhADTS->profile != AAC_PROFILE_LC || + fhADTS->sampRateIdx >= NUM_SAMPLE_RATES || fhADTS->channelConfig >= NUM_DEF_CHAN_MAPS) { + return ERR_AAC_INVALID_ADTS_HEADER; + } #ifndef AAC_ENABLE_MPEG4 - if (fhADTS->id != 1) - return ERR_AAC_MPEG4_UNSUPPORTED; + if (fhADTS->id != 1) { + return ERR_AAC_MPEG4_UNSUPPORTED; + } #endif - /* update codec info */ - psi->sampRateIdx = fhADTS->sampRateIdx; - if (!psi->useImpChanMap) - psi->nChans = channelMapTab[fhADTS->channelConfig]; - - /* syntactic element fields will be read from bitstream for each element */ - aacDecInfo->prevBlockID = AAC_ID_INVALID; - aacDecInfo->currBlockID = AAC_ID_INVALID; - aacDecInfo->currInstTag = -1; - - /* fill in user-accessible data (TODO - calc bitrate, handle tricky channel config cases) */ - aacDecInfo->bitRate = 0; - aacDecInfo->nChans = psi->nChans; - aacDecInfo->sampRate = sampRateTab[psi->sampRateIdx]; - aacDecInfo->profile = fhADTS->profile; - aacDecInfo->sbrEnabled = 0; - aacDecInfo->adtsBlocksLeft = fhADTS->numRawDataBlocks; - - /* update bitstream reader */ - bitsUsed = CalcBitsUsed(&bsi, *buf, *bitOffset); - *buf += (bitsUsed + *bitOffset) >> 3; - *bitOffset = (bitsUsed + *bitOffset) & 0x07; - *bitsAvail -= bitsUsed ; - if (*bitsAvail < 0) - return ERR_AAC_INDATA_UNDERFLOW; - - return ERR_AAC_NONE; + /* update codec info */ + psi->sampRateIdx = fhADTS->sampRateIdx; + if (!psi->useImpChanMap) { + psi->nChans = channelMapTab[fhADTS->channelConfig]; + } + + /* syntactic element fields will be read from bitstream for each element */ + aacDecInfo->prevBlockID = AAC_ID_INVALID; + aacDecInfo->currBlockID = AAC_ID_INVALID; + aacDecInfo->currInstTag = -1; + + /* fill in user-accessible data (TODO - calc bitrate, handle tricky channel config cases) */ + aacDecInfo->bitRate = 0; + aacDecInfo->nChans = psi->nChans; + aacDecInfo->sampRate = sampRateTab[psi->sampRateIdx]; + aacDecInfo->profile = fhADTS->profile; + aacDecInfo->sbrEnabled = 0; + aacDecInfo->adtsBlocksLeft = fhADTS->numRawDataBlocks; + + /* update bitstream reader */ + bitsUsed = CalcBitsUsed(&bsi, *buf, *bitOffset); + *buf += (bitsUsed + *bitOffset) >> 3; + *bitOffset = (bitsUsed + *bitOffset) & 0x07; + *bitsAvail -= bitsUsed ; + if (*bitsAvail < 0) { + return ERR_AAC_INDATA_UNDERFLOW; + } + + return ERR_AAC_NONE; } /************************************************************************************** - * Function: GetADTSChannelMapping - * - * Description: determine the number of channels from implicit mapping rules - * - * Inputs: valid AACDecInfo struct - * pointer to start of raw_data_block - * bit offset - * bits available - * - * Outputs: updated number of channels - * - * Return: 0 if successful, error code (< 0) if error - * - * Notes: calculates total number of channels using rules in 14496-3, 4.5.1.2.1 - * does not attempt to deduce speaker geometry + Function: GetADTSChannelMapping + + Description: determine the number of channels from implicit mapping rules + + Inputs: valid AACDecInfo struct + pointer to start of raw_data_block + bit offset + bits available + + Outputs: updated number of channels + + Return: 0 if successful, error code (< 0) if error + + Notes: calculates total number of channels using rules in 14496-3, 4.5.1.2.1 + does not attempt to deduce speaker geometry **************************************************************************************/ -int GetADTSChannelMapping(AACDecInfo *aacDecInfo, unsigned char *buf, int bitOffset, int bitsAvail) -{ - int ch, nChans, elementChans, err; - PSInfoBase *psi; - - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return ERR_AAC_NULL_POINTER; - psi = (PSInfoBase *)(aacDecInfo->psInfoBase); - - nChans = 0; - do { - /* parse next syntactic element */ - err = DecodeNextElement(aacDecInfo, &buf, &bitOffset, &bitsAvail); - if (err) - return err; - - elementChans = elementNumChans[aacDecInfo->currBlockID]; - nChans += elementChans; - - for (ch = 0; ch < elementChans; ch++) { - err = DecodeNoiselessData(aacDecInfo, &buf, &bitOffset, &bitsAvail, ch); - if (err) - return err; - } - } while (aacDecInfo->currBlockID != AAC_ID_END); - - if (nChans <= 0) - return ERR_AAC_CHANNEL_MAP; - - /* update number of channels in codec state and user-accessible info structs */ - psi->nChans = nChans; - aacDecInfo->nChans = psi->nChans; - psi->useImpChanMap = 1; - - return ERR_AAC_NONE; +int GetADTSChannelMapping(AACDecInfo *aacDecInfo, unsigned char *buf, int bitOffset, int bitsAvail) { + int ch, nChans, elementChans, err; + PSInfoBase *psi; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return ERR_AAC_NULL_POINTER; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + + nChans = 0; + do { + /* parse next syntactic element */ + err = DecodeNextElement(aacDecInfo, &buf, &bitOffset, &bitsAvail); + if (err) { + return err; + } + + elementChans = elementNumChans[aacDecInfo->currBlockID]; + nChans += elementChans; + + for (ch = 0; ch < elementChans; ch++) { + err = DecodeNoiselessData(aacDecInfo, &buf, &bitOffset, &bitsAvail, ch); + if (err) { + return err; + } + } + } while (aacDecInfo->currBlockID != AAC_ID_END); + + if (nChans <= 0) { + return ERR_AAC_CHANNEL_MAP; + } + + /* update number of channels in codec state and user-accessible info structs */ + psi->nChans = nChans; + aacDecInfo->nChans = psi->nChans; + psi->useImpChanMap = 1; + + return ERR_AAC_NONE; } /************************************************************************************** - * Function: GetNumChannelsADIF - * - * Description: get number of channels from program config elements in an ADIF file - * - * Inputs: array of filled-in program config element structures - * number of PCE's - * - * Outputs: none - * - * Return: total number of channels in file - * -1 if error (invalid number of PCE's or unsupported mode) - **************************************************************************************/ -static int GetNumChannelsADIF(ProgConfigElement *fhPCE, int nPCE) -{ - int i, j, nChans; + Function: GetNumChannelsADIF + + Description: get number of channels from program config elements in an ADIF file - if (nPCE < 1 || nPCE > MAX_NUM_PCE_ADIF) - return -1; + Inputs: array of filled-in program config element structures + number of PCE's - nChans = 0; - for (i = 0; i < nPCE; i++) { - /* for now: only support LC, no channel coupling */ - if (fhPCE[i].profile != AAC_PROFILE_LC || fhPCE[i].numCCE > 0) - return -1; + Outputs: none + + Return: total number of channels in file + -1 if error (invalid number of PCE's or unsupported mode) + **************************************************************************************/ +static int GetNumChannelsADIF(ProgConfigElement *fhPCE, int nPCE) { + int i, j, nChans; + + if (nPCE < 1 || nPCE > MAX_NUM_PCE_ADIF) { + return -1; + } + + nChans = 0; + for (i = 0; i < nPCE; i++) { + /* for now: only support LC, no channel coupling */ + if (fhPCE[i].profile != AAC_PROFILE_LC || fhPCE[i].numCCE > 0) { + return -1; + } - /* add up number of channels in all channel elements (assume all single-channel) */ + /* add up number of channels in all channel elements (assume all single-channel) */ nChans += fhPCE[i].numFCE; nChans += fhPCE[i].numSCE; nChans += fhPCE[i].numBCE; nChans += fhPCE[i].numLCE; - /* add one more for every element which is a channel pair */ + /* add one more for every element which is a channel pair */ for (j = 0; j < fhPCE[i].numFCE; j++) { - if (CHAN_ELEM_IS_CPE(fhPCE[i].fce[j])) + if (CHAN_ELEM_IS_CPE(fhPCE[i].fce[j])) { nChans++; + } } for (j = 0; j < fhPCE[i].numSCE; j++) { - if (CHAN_ELEM_IS_CPE(fhPCE[i].sce[j])) + if (CHAN_ELEM_IS_CPE(fhPCE[i].sce[j])) { nChans++; + } } for (j = 0; j < fhPCE[i].numBCE; j++) { - if (CHAN_ELEM_IS_CPE(fhPCE[i].bce[j])) + if (CHAN_ELEM_IS_CPE(fhPCE[i].bce[j])) { nChans++; + } } - } + } - return nChans; + return nChans; } /************************************************************************************** - * Function: GetSampleRateIdxADIF - * - * Description: get sampling rate index from program config elements in an ADIF file - * - * Inputs: array of filled-in program config element structures - * number of PCE's - * - * Outputs: none - * - * Return: sample rate of file - * -1 if error (invalid number of PCE's or sample rate mismatch) - **************************************************************************************/ -static int GetSampleRateIdxADIF(ProgConfigElement *fhPCE, int nPCE) -{ - int i, idx; + Function: GetSampleRateIdxADIF + + Description: get sampling rate index from program config elements in an ADIF file + + Inputs: array of filled-in program config element structures + number of PCE's - if (nPCE < 1 || nPCE > MAX_NUM_PCE_ADIF) - return -1; + Outputs: none - /* make sure all PCE's have the same sample rate */ - idx = fhPCE[0].sampRateIdx; - for (i = 1; i < nPCE; i++) { - if (fhPCE[i].sampRateIdx != idx) - return -1; - } + Return: sample rate of file + -1 if error (invalid number of PCE's or sample rate mismatch) + **************************************************************************************/ +static int GetSampleRateIdxADIF(ProgConfigElement *fhPCE, int nPCE) { + int i, idx; + + if (nPCE < 1 || nPCE > MAX_NUM_PCE_ADIF) { + return -1; + } + + /* make sure all PCE's have the same sample rate */ + idx = fhPCE[0].sampRateIdx; + for (i = 1; i < nPCE; i++) { + if (fhPCE[i].sampRateIdx != idx) { + return -1; + } + } - return idx; + return idx; } /************************************************************************************** - * Function: UnpackADIFHeader - * - * Description: parse the ADIF file header and initialize decoder state - * - * Inputs: valid AACDecInfo struct - * double pointer to buffer with complete ADIF header - * (starting at 'A' in 'ADIF' tag) - * pointer to bit offset - * pointer to number of valid bits remaining in inbuf - * - * Outputs: filled-in ADIF struct - * updated buffer pointer - * updated bit offset - * updated number of available bits - * - * Return: 0 if successful, error code (< 0) if error + Function: UnpackADIFHeader + + Description: parse the ADIF file header and initialize decoder state + + Inputs: valid AACDecInfo struct + double pointer to buffer with complete ADIF header + (starting at 'A' in 'ADIF' tag) + pointer to bit offset + pointer to number of valid bits remaining in inbuf + + Outputs: filled-in ADIF struct + updated buffer pointer + updated bit offset + updated number of available bits + + Return: 0 if successful, error code (< 0) if error **************************************************************************************/ -int UnpackADIFHeader(AACDecInfo *aacDecInfo, unsigned char **buf, int *bitOffset, int *bitsAvail) -{ - int i, bitsUsed; - PSInfoBase *psi; - BitStreamInfo bsi; - ADIFHeader *fhADIF; - ProgConfigElement *pce; - - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return ERR_AAC_NULL_POINTER; - psi = (PSInfoBase *)(aacDecInfo->psInfoBase); - - /* init bitstream reader */ - SetBitstreamPointer(&bsi, (*bitsAvail + 7) >> 3, *buf); - GetBits(&bsi, *bitOffset); - - /* unpack ADIF file header */ - fhADIF = &(psi->fhADIF); - pce = psi->pce; - - /* verify that first 32 bits of header are "ADIF" */ - if (GetBits(&bsi, 8) != 'A' || GetBits(&bsi, 8) != 'D' || GetBits(&bsi, 8) != 'I' || GetBits(&bsi, 8) != 'F') - return ERR_AAC_INVALID_ADIF_HEADER; - - /* read ADIF header fields */ - fhADIF->copyBit = GetBits(&bsi, 1); - if (fhADIF->copyBit) { - for (i = 0; i < ADIF_COPYID_SIZE; i++) - fhADIF->copyID[i] = GetBits(&bsi, 8); - } - fhADIF->origCopy = GetBits(&bsi, 1); - fhADIF->home = GetBits(&bsi, 1); - fhADIF->bsType = GetBits(&bsi, 1); - fhADIF->bitRate = GetBits(&bsi, 23); - fhADIF->numPCE = GetBits(&bsi, 4) + 1; /* add 1 (so range = [1, 16]) */ - if (fhADIF->bsType == 0) - fhADIF->bufferFull = GetBits(&bsi, 20); - - /* parse all program config elements */ - for (i = 0; i < fhADIF->numPCE; i++) - DecodeProgramConfigElement(pce + i, &bsi); - - /* byte align */ - ByteAlignBitstream(&bsi); - - /* update codec info */ - psi->nChans = GetNumChannelsADIF(pce, fhADIF->numPCE); - psi->sampRateIdx = GetSampleRateIdxADIF(pce, fhADIF->numPCE); - - /* check validity of header */ - if (psi->nChans < 0 || psi->sampRateIdx < 0 || psi->sampRateIdx >= NUM_SAMPLE_RATES) - return ERR_AAC_INVALID_ADIF_HEADER; - - /* syntactic element fields will be read from bitstream for each element */ - aacDecInfo->prevBlockID = AAC_ID_INVALID; - aacDecInfo->currBlockID = AAC_ID_INVALID; - aacDecInfo->currInstTag = -1; - - /* fill in user-accessible data */ - aacDecInfo->bitRate = 0; - aacDecInfo->nChans = psi->nChans; - aacDecInfo->sampRate = sampRateTab[psi->sampRateIdx]; - aacDecInfo->profile = pce[0].profile; - aacDecInfo->sbrEnabled = 0; - - /* update bitstream reader */ - bitsUsed = CalcBitsUsed(&bsi, *buf, *bitOffset); - *buf += (bitsUsed + *bitOffset) >> 3; - *bitOffset = (bitsUsed + *bitOffset) & 0x07; - *bitsAvail -= bitsUsed ; - if (*bitsAvail < 0) - return ERR_AAC_INDATA_UNDERFLOW; - - return ERR_AAC_NONE; +int UnpackADIFHeader(AACDecInfo *aacDecInfo, unsigned char **buf, int *bitOffset, int *bitsAvail) { + int i, bitsUsed; + PSInfoBase *psi; + BitStreamInfo bsi; + ADIFHeader *fhADIF; + ProgConfigElement *pce; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return ERR_AAC_NULL_POINTER; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + + /* init bitstream reader */ + SetBitstreamPointer(&bsi, (*bitsAvail + 7) >> 3, *buf); + GetBits(&bsi, *bitOffset); + + /* unpack ADIF file header */ + fhADIF = &(psi->fhADIF); + pce = psi->pce; + + /* verify that first 32 bits of header are "ADIF" */ + if (GetBits(&bsi, 8) != 'A' || GetBits(&bsi, 8) != 'D' || GetBits(&bsi, 8) != 'I' || GetBits(&bsi, 8) != 'F') { + return ERR_AAC_INVALID_ADIF_HEADER; + } + + /* read ADIF header fields */ + fhADIF->copyBit = GetBits(&bsi, 1); + if (fhADIF->copyBit) { + for (i = 0; i < ADIF_COPYID_SIZE; i++) { + fhADIF->copyID[i] = GetBits(&bsi, 8); + } + } + fhADIF->origCopy = GetBits(&bsi, 1); + fhADIF->home = GetBits(&bsi, 1); + fhADIF->bsType = GetBits(&bsi, 1); + fhADIF->bitRate = GetBits(&bsi, 23); + fhADIF->numPCE = GetBits(&bsi, 4) + 1; /* add 1 (so range = [1, 16]) */ + if (fhADIF->bsType == 0) { + fhADIF->bufferFull = GetBits(&bsi, 20); + } + + /* parse all program config elements */ + for (i = 0; i < fhADIF->numPCE; i++) { + DecodeProgramConfigElement(pce + i, &bsi); + } + + /* byte align */ + ByteAlignBitstream(&bsi); + + /* update codec info */ + psi->nChans = GetNumChannelsADIF(pce, fhADIF->numPCE); + psi->sampRateIdx = GetSampleRateIdxADIF(pce, fhADIF->numPCE); + + /* check validity of header */ + if (psi->nChans < 0 || psi->sampRateIdx < 0 || psi->sampRateIdx >= NUM_SAMPLE_RATES) { + return ERR_AAC_INVALID_ADIF_HEADER; + } + + /* syntactic element fields will be read from bitstream for each element */ + aacDecInfo->prevBlockID = AAC_ID_INVALID; + aacDecInfo->currBlockID = AAC_ID_INVALID; + aacDecInfo->currInstTag = -1; + + /* fill in user-accessible data */ + aacDecInfo->bitRate = 0; + aacDecInfo->nChans = psi->nChans; + aacDecInfo->sampRate = sampRateTab[psi->sampRateIdx]; + aacDecInfo->profile = pce[0].profile; + aacDecInfo->sbrEnabled = 0; + + /* update bitstream reader */ + bitsUsed = CalcBitsUsed(&bsi, *buf, *bitOffset); + *buf += (bitsUsed + *bitOffset) >> 3; + *bitOffset = (bitsUsed + *bitOffset) & 0x07; + *bitsAvail -= bitsUsed ; + if (*bitsAvail < 0) { + return ERR_AAC_INDATA_UNDERFLOW; + } + + return ERR_AAC_NONE; } /************************************************************************************** - * Function: SetRawBlockParams - * - * Description: set internal state variables for decoding a stream of raw data blocks - * - * Inputs: valid AACDecInfo struct - * flag indicating source of parameters (from previous headers or passed - * explicitly by caller) - * number of channels - * sample rate - * profile ID - * - * Outputs: updated state variables in aacDecInfo - * - * Return: 0 if successful, error code (< 0) if error - * - * Notes: if copyLast == 1, then psi->nChans, psi->sampRateIdx, and - * aacDecInfo->profile are not changed (it's assumed that we already - * set them, such as by a previous call to UnpackADTSHeader()) - * if copyLast == 0, then the parameters we passed in are used instead + Function: SetRawBlockParams + + Description: set internal state variables for decoding a stream of raw data blocks + + Inputs: valid AACDecInfo struct + flag indicating source of parameters (from previous headers or passed + explicitly by caller) + number of channels + sample rate + profile ID + + Outputs: updated state variables in aacDecInfo + + Return: 0 if successful, error code (< 0) if error + + Notes: if copyLast == 1, then psi->nChans, psi->sampRateIdx, and + aacDecInfo->profile are not changed (it's assumed that we already + set them, such as by a previous call to UnpackADTSHeader()) + if copyLast == 0, then the parameters we passed in are used instead **************************************************************************************/ -int SetRawBlockParams(AACDecInfo *aacDecInfo, int copyLast, int nChans, int sampRate, int profile) -{ - int idx; - PSInfoBase *psi; - - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return ERR_AAC_NULL_POINTER; - psi = (PSInfoBase *)(aacDecInfo->psInfoBase); - - if (!copyLast) { - aacDecInfo->profile = profile; - psi->nChans = nChans; - for (idx = 0; idx < NUM_SAMPLE_RATES; idx++) { - if (sampRate == sampRateTab[idx]) { - psi->sampRateIdx = idx; - break; - } - } - if (idx == NUM_SAMPLE_RATES) - return ERR_AAC_INVALID_FRAME; - } - aacDecInfo->nChans = psi->nChans; - aacDecInfo->sampRate = sampRateTab[psi->sampRateIdx]; - - /* check validity of header */ - if (psi->sampRateIdx >= NUM_SAMPLE_RATES || psi->sampRateIdx < 0 || aacDecInfo->profile != AAC_PROFILE_LC) - return ERR_AAC_RAWBLOCK_PARAMS; - - return ERR_AAC_NONE; +int SetRawBlockParams(AACDecInfo *aacDecInfo, int copyLast, int nChans, int sampRate, int profile) { + int idx; + PSInfoBase *psi; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return ERR_AAC_NULL_POINTER; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + + if (!copyLast) { + aacDecInfo->profile = profile; + psi->nChans = nChans; + for (idx = 0; idx < NUM_SAMPLE_RATES; idx++) { + if (sampRate == sampRateTab[idx]) { + psi->sampRateIdx = idx; + break; + } + } + if (idx == NUM_SAMPLE_RATES) { + return ERR_AAC_INVALID_FRAME; + } + } + aacDecInfo->nChans = psi->nChans; + aacDecInfo->sampRate = sampRateTab[psi->sampRateIdx]; + + /* check validity of header */ + if (psi->sampRateIdx >= NUM_SAMPLE_RATES || psi->sampRateIdx < 0 || aacDecInfo->profile != AAC_PROFILE_LC) { + return ERR_AAC_RAWBLOCK_PARAMS; + } + + return ERR_AAC_NONE; } /************************************************************************************** - * Function: PrepareRawBlock - * - * Description: reset per-block state variables for raw blocks (no ADTS/ADIF headers) - * - * Inputs: valid AACDecInfo struct - * - * Outputs: updated state variables in aacDecInfo - * - * Return: 0 if successful, error code (< 0) if error + Function: PrepareRawBlock + + Description: reset per-block state variables for raw blocks (no ADTS/ADIF headers) + + Inputs: valid AACDecInfo struct + + Outputs: updated state variables in aacDecInfo + + Return: 0 if successful, error code (< 0) if error **************************************************************************************/ -int PrepareRawBlock(AACDecInfo *aacDecInfo) -{ -// PSInfoBase *psi; +int PrepareRawBlock(AACDecInfo *aacDecInfo) { + // PSInfoBase *psi; - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return ERR_AAC_NULL_POINTER; -// psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return ERR_AAC_NULL_POINTER; + } + // psi = (PSInfoBase *)(aacDecInfo->psInfoBase); - /* syntactic element fields will be read from bitstream for each element */ - aacDecInfo->prevBlockID = AAC_ID_INVALID; - aacDecInfo->currBlockID = AAC_ID_INVALID; - aacDecInfo->currInstTag = -1; + /* syntactic element fields will be read from bitstream for each element */ + aacDecInfo->prevBlockID = AAC_ID_INVALID; + aacDecInfo->currBlockID = AAC_ID_INVALID; + aacDecInfo->currInstTag = -1; - /* fill in user-accessible data */ - aacDecInfo->bitRate = 0; - aacDecInfo->sbrEnabled = 0; + /* fill in user-accessible data */ + aacDecInfo->bitRate = 0; + aacDecInfo->sbrEnabled = 0; - return ERR_AAC_NONE; + return ERR_AAC_NONE; } /************************************************************************************** - * Function: FlushCodec - * - * Description: flush internal codec state (after seeking, for example) - * - * Inputs: valid AACDecInfo struct - * - * Outputs: updated state variables in aacDecInfo - * - * Return: 0 if successful, error code (< 0) if error - * - * Notes: only need to clear data which is persistent between frames - * (such as overlap buffer) + Function: FlushCodec + + Description: flush internal codec state (after seeking, for example) + + Inputs: valid AACDecInfo struct + + Outputs: updated state variables in aacDecInfo + + Return: 0 if successful, error code (< 0) if error + + Notes: only need to clear data which is persistent between frames + (such as overlap buffer) **************************************************************************************/ -int FlushCodec(AACDecInfo *aacDecInfo) -{ - PSInfoBase *psi; - - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return ERR_AAC_NULL_POINTER; - psi = (PSInfoBase *)(aacDecInfo->psInfoBase); - - ClearBuffer(psi->overlap, AAC_MAX_NCHANS * AAC_MAX_NSAMPS * sizeof(int)); - ClearBuffer(psi->prevWinShape, AAC_MAX_NCHANS * sizeof(int)); - - return ERR_AAC_NONE; +int FlushCodec(AACDecInfo *aacDecInfo) { + PSInfoBase *psi; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return ERR_AAC_NULL_POINTER; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + + ClearBuffer(psi->overlap, AAC_MAX_NCHANS * AAC_MAX_NSAMPS * sizeof(int)); + ClearBuffer(psi->prevWinShape, AAC_MAX_NCHANS * sizeof(int)); + + return ERR_AAC_NONE; } diff --git a/src/libhelix-aac/huffman.c b/src/libhelix-aac/huffman.c deleted file mode 100644 index 57cc45c9..00000000 --- a/src/libhelix-aac/huffman.c +++ /dev/null @@ -1,415 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: huffman.c,v 1.2 2005/05/24 16:01:55 albertofloyd Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ - -/************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * huffman.c - Huffman decoding - **************************************************************************************/ - -#include "coder.h" - -/************************************************************************************** - * Function: DecodeHuffmanScalar - * - * Description: decode one Huffman symbol from bitstream - * - * Inputs: pointers to Huffman table and info struct - * left-aligned bit buffer with >= huffTabInfo->maxBits bits - * - * Outputs: decoded symbol in *val - * - * Return: number of bits in symbol - * - * Notes: assumes canonical Huffman codes: - * first CW always 0, we have "count" CW's of length "nBits" bits - * starting CW for codes of length nBits+1 = - * (startCW[nBits] + count[nBits]) << 1 - * if there are no codes at nBits, then we just keep << 1 each time - * (since count[nBits] = 0) - **************************************************************************************/ -/* __attribute__ ((section (".data"))) */ int DecodeHuffmanScalar(const signed short *huffTab, const HuffInfo *huffTabInfo, unsigned int bitBuf, signed int *val) -{ - unsigned int count, start, shift, t; - const unsigned /*char*/ int *countPtr; - const signed short *map; - - map = huffTab + huffTabInfo->offset; - countPtr = huffTabInfo->count; - - start = 0; - count = 0; - shift = 32; - do { - start += count; - start <<= 1; - map += count; - count = *countPtr++; - shift--; - t = (bitBuf >> shift) - start; - } while (t >= count); - - *val = (signed int)pgm_read_word(&map[t]); - return (countPtr - huffTabInfo->count); -} - -#define APPLY_SIGN(v, s) {(v) ^= ((signed int)(s) >> 31); (v) -= ((signed int)(s) >> 31);} - -#define GET_QUAD_SIGNBITS(v) (((unsigned int)(v) << 17) >> 29) /* bits 14-12, unsigned */ -#define GET_QUAD_W(v) (((signed int)(v) << 20) >> 29) /* bits 11-9, sign-extend */ -#define GET_QUAD_X(v) (((signed int)(v) << 23) >> 29) /* bits 8-6, sign-extend */ -#define GET_QUAD_Y(v) (((signed int)(v) << 26) >> 29) /* bits 5-3, sign-extend */ -#define GET_QUAD_Z(v) (((signed int)(v) << 29) >> 29) /* bits 2-0, sign-extend */ - -#define GET_PAIR_SIGNBITS(v) (((unsigned int)(v) << 20) >> 30) /* bits 11-10, unsigned */ -#define GET_PAIR_Y(v) (((signed int)(v) << 22) >> 27) /* bits 9-5, sign-extend */ -#define GET_PAIR_Z(v) (((signed int)(v) << 27) >> 27) /* bits 4-0, sign-extend */ - -#define GET_ESC_SIGNBITS(v) (((unsigned int)(v) << 18) >> 30) /* bits 13-12, unsigned */ -#define GET_ESC_Y(v) (((signed int)(v) << 20) >> 26) /* bits 11-6, sign-extend */ -#define GET_ESC_Z(v) (((signed int)(v) << 26) >> 26) /* bits 5-0, sign-extend */ - -/************************************************************************************** - * Function: UnpackZeros - * - * Description: fill a section of coefficients with zeros - * - * Inputs: number of coefficients - * - * Outputs: nVals zeros, starting at coef - * - * Return: none - * - * Notes: assumes nVals is always a multiple of 4 because all scalefactor bands - * are a multiple of 4 coefficients long - **************************************************************************************/ -static void UnpackZeros(int nVals, int *coef) -{ - while (nVals > 0) { - *coef++ = 0; - *coef++ = 0; - *coef++ = 0; - *coef++ = 0; - nVals -= 4; - } -} - -/************************************************************************************** - * Function: UnpackQuads - * - * Description: decode a section of 4-way vector Huffman coded coefficients - * - * Inputs BitStreamInfo struct pointing to start of codewords for this section - * index of Huffman codebook - * number of coefficients - * - * Outputs: nVals coefficients, starting at coef - * - * Return: none - * - * Notes: assumes nVals is always a multiple of 4 because all scalefactor bands - * are a multiple of 4 coefficients long - **************************************************************************************/ -/* __attribute__ ((section (".data"))) */ static void UnpackQuads(BitStreamInfo *bsi, int cb, int nVals, int *coef) -{ - int w, x, y, z, maxBits, nCodeBits, nSignBits, val; - unsigned int bitBuf; - - maxBits = huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET].maxBits + 4; - while (nVals > 0) { - /* decode quad */ - bitBuf = GetBitsNoAdvance(bsi, maxBits) << (32 - maxBits); - nCodeBits = DecodeHuffmanScalar(huffTabSpec, &huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET], bitBuf, &val); - - w = GET_QUAD_W(val); - x = GET_QUAD_X(val); - y = GET_QUAD_Y(val); - z = GET_QUAD_Z(val); - - bitBuf <<= nCodeBits; - nSignBits = (int)GET_QUAD_SIGNBITS(val); - AdvanceBitstream(bsi, nCodeBits + nSignBits); - if (nSignBits) { - if (w) {APPLY_SIGN(w, bitBuf); bitBuf <<= 1;} - if (x) {APPLY_SIGN(x, bitBuf); bitBuf <<= 1;} - if (y) {APPLY_SIGN(y, bitBuf); bitBuf <<= 1;} - if (z) {APPLY_SIGN(z, bitBuf); bitBuf <<= 1;} - } - *coef++ = w; *coef++ = x; *coef++ = y; *coef++ = z; - nVals -= 4; - } -} - -/************************************************************************************** - * Function: UnpackPairsNoEsc - * - * Description: decode a section of 2-way vector Huffman coded coefficients, - * using non-esc tables (5 through 10) - * - * Inputs BitStreamInfo struct pointing to start of codewords for this section - * index of Huffman codebook (must not be the escape codebook) - * number of coefficients - * - * Outputs: nVals coefficients, starting at coef - * - * Return: none - * - * Notes: assumes nVals is always a multiple of 2 because all scalefactor bands - * are a multiple of 4 coefficients long - **************************************************************************************/ -/* __attribute__ ((section (".data"))) */ static void UnpackPairsNoEsc(BitStreamInfo *bsi, int cb, int nVals, int *coef) -{ - int y, z, maxBits, nCodeBits, nSignBits, val; - unsigned int bitBuf; - - maxBits = huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET].maxBits + 2; - while (nVals > 0) { - /* decode pair */ - bitBuf = GetBitsNoAdvance(bsi, maxBits) << (32 - maxBits); - nCodeBits = DecodeHuffmanScalar(huffTabSpec, &huffTabSpecInfo[cb-HUFFTAB_SPEC_OFFSET], bitBuf, &val); - - y = GET_PAIR_Y(val); - z = GET_PAIR_Z(val); - - bitBuf <<= nCodeBits; - nSignBits = GET_PAIR_SIGNBITS(val); - AdvanceBitstream(bsi, nCodeBits + nSignBits); - if (nSignBits) { - if (y) {APPLY_SIGN(y, bitBuf); bitBuf <<= 1;} - if (z) {APPLY_SIGN(z, bitBuf); bitBuf <<= 1;} - } - *coef++ = y; *coef++ = z; - nVals -= 2; - } -} - -/************************************************************************************** - * Function: UnpackPairsEsc - * - * Description: decode a section of 2-way vector Huffman coded coefficients, - * using esc table (11) - * - * Inputs BitStreamInfo struct pointing to start of codewords for this section - * index of Huffman codebook (must be the escape codebook) - * number of coefficients - * - * Outputs: nVals coefficients, starting at coef - * - * Return: none - * - * Notes: assumes nVals is always a multiple of 2 because all scalefactor bands - * are a multiple of 4 coefficients long - **************************************************************************************/ -/* __attribute__ ((section (".data"))) */ static void UnpackPairsEsc(BitStreamInfo *bsi, int cb, int nVals, int *coef) -{ - int y, z, maxBits, nCodeBits, nSignBits, n, val; - unsigned int bitBuf; - - maxBits = huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET].maxBits + 2; - while (nVals > 0) { - /* decode pair with escape value */ - bitBuf = GetBitsNoAdvance(bsi, maxBits) << (32 - maxBits); - nCodeBits = DecodeHuffmanScalar(huffTabSpec, &huffTabSpecInfo[cb-HUFFTAB_SPEC_OFFSET], bitBuf, &val); - - y = GET_ESC_Y(val); - z = GET_ESC_Z(val); - - bitBuf <<= nCodeBits; - nSignBits = GET_ESC_SIGNBITS(val); - AdvanceBitstream(bsi, nCodeBits + nSignBits); - - if (y == 16) { - n = 4; - while (GetBits(bsi, 1) == 1) - n++; - y = (1 << n) + GetBits(bsi, n); - } - if (z == 16) { - n = 4; - while (GetBits(bsi, 1) == 1) - n++; - z = (1 << n) + GetBits(bsi, n); - } - - if (nSignBits) { - if (y) {APPLY_SIGN(y, bitBuf); bitBuf <<= 1;} - if (z) {APPLY_SIGN(z, bitBuf); bitBuf <<= 1;} - } - - *coef++ = y; *coef++ = z; - nVals -= 2; - } -} - -/************************************************************************************** - * Function: DecodeSpectrumLong - * - * Description: decode transform coefficients for frame with one long block - * - * Inputs: platform specific info struct - * BitStreamInfo struct pointing to start of spectral data - * (14496-3, table 4.4.29) - * index of current channel - * - * Outputs: decoded, quantized coefficients for this channel - * - * Return: none - * - * Notes: adds in pulse data if present - * fills coefficient buffer with zeros in any region not coded with - * codebook in range [1, 11] (including sfb's above sfbMax) - **************************************************************************************/ -/* __attribute__ ((section (".data"))) */ void DecodeSpectrumLong(PSInfoBase *psi, BitStreamInfo *bsi, int ch) -{ - int i, sfb, cb, nVals, offset; - const /*short*/ int *sfbTab; - unsigned char *sfbCodeBook; - int *coef; - ICSInfo *icsInfo; - PulseInfo *pi; - - coef = psi->coef[ch]; - icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]); - - /* decode long block */ - sfbTab = sfBandTabLong + sfBandTabLongOffset[psi->sampRateIdx]; - sfbCodeBook = psi->sfbCodeBook[ch]; - for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) { - cb = *sfbCodeBook++; - nVals = sfbTab[sfb+1] - sfbTab[sfb]; - - if (cb == 0) - UnpackZeros(nVals, coef); - else if (cb <= 4) - UnpackQuads(bsi, cb, nVals, coef); - else if (cb <= 10) - UnpackPairsNoEsc(bsi, cb, nVals, coef); - else if (cb == 11) - UnpackPairsEsc(bsi, cb, nVals, coef); - else - UnpackZeros(nVals, coef); - - coef += nVals; - } - - /* fill with zeros above maxSFB */ - nVals = NSAMPS_LONG - sfbTab[sfb]; - UnpackZeros(nVals, coef); - - /* add pulse data, if present */ - pi = &psi->pulseInfo[ch]; - if (pi->pulseDataPresent) { - coef = psi->coef[ch]; - offset = sfbTab[pi->startSFB]; - for (i = 0; i < pi->numPulse; i++) { - offset += pi->offset[i]; - if (coef[offset] > 0) - coef[offset] += pi->amp[i]; - else - coef[offset] -= pi->amp[i]; - } - ASSERT(offset < NSAMPS_LONG); - } -} - -/************************************************************************************** - * Function: DecodeSpectrumShort - * - * Description: decode transform coefficients for frame with eight short blocks - * - * Inputs: platform specific info struct - * BitStreamInfo struct pointing to start of spectral data - * (14496-3, table 4.4.29) - * index of current channel - * - * Outputs: decoded, quantized coefficients for this channel - * - * Return: none - * - * Notes: fills coefficient buffer with zeros in any region not coded with - * codebook in range [1, 11] (including sfb's above sfbMax) - * deinterleaves window groups into 8 windows - **************************************************************************************/ -/* __attribute__ ((section (".data"))) */ void DecodeSpectrumShort(PSInfoBase *psi, BitStreamInfo *bsi, int ch) -{ - int gp, cb, nVals=0, win, offset, sfb; - const /*short*/ int *sfbTab; - unsigned char *sfbCodeBook; - int *coef; - ICSInfo *icsInfo; - - coef = psi->coef[ch]; - icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]); - - /* decode short blocks, deinterleaving in-place */ - sfbTab = sfBandTabShort + sfBandTabShortOffset[psi->sampRateIdx]; - sfbCodeBook = psi->sfbCodeBook[ch]; - for (gp = 0; gp < icsInfo->numWinGroup; gp++) { - for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) { - nVals = sfbTab[sfb+1] - sfbTab[sfb]; - cb = *sfbCodeBook++; - - for (win = 0; win < icsInfo->winGroupLen[gp]; win++) { - offset = win*NSAMPS_SHORT; - if (cb == 0) - UnpackZeros(nVals, coef + offset); - else if (cb <= 4) - UnpackQuads(bsi, cb, nVals, coef + offset); - else if (cb <= 10) - UnpackPairsNoEsc(bsi, cb, nVals, coef + offset); - else if (cb == 11) - UnpackPairsEsc(bsi, cb, nVals, coef + offset); - else - UnpackZeros(nVals, coef + offset); - } - coef += nVals; - } - - /* fill with zeros above maxSFB */ - for (win = 0; win < icsInfo->winGroupLen[gp]; win++) { - offset = win*NSAMPS_SHORT; - nVals = NSAMPS_SHORT - sfbTab[sfb]; - UnpackZeros(nVals, coef + offset); - } - coef += nVals; - coef += (icsInfo->winGroupLen[gp] - 1)*NSAMPS_SHORT; - } - - ASSERT(coef == psi->coef[ch] + NSAMPS_LONG); -} diff --git a/src/libhelix-aac/huffmanaac.c b/src/libhelix-aac/huffmanaac.c new file mode 100644 index 00000000..ceb9712d --- /dev/null +++ b/src/libhelix-aac/huffmanaac.c @@ -0,0 +1,441 @@ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: huffman.c,v 1.2 2005/05/24 16:01:55 albertofloyd Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ + +/************************************************************************************** + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + huffman.c - Huffman decoding + **************************************************************************************/ + +#include "coder.h" + +/************************************************************************************** + Function: DecodeHuffmanScalar + + Description: decode one Huffman symbol from bitstream + + Inputs: pointers to Huffman table and info struct + left-aligned bit buffer with >= huffTabInfo->maxBits bits + + Outputs: decoded symbol in *val + + Return: number of bits in symbol + + Notes: assumes canonical Huffman codes: + first CW always 0, we have "count" CW's of length "nBits" bits + starting CW for codes of length nBits+1 = + (startCW[nBits] + count[nBits]) << 1 + if there are no codes at nBits, then we just keep << 1 each time + (since count[nBits] = 0) + **************************************************************************************/ +/* __attribute__ ((section (".data"))) */ int DecodeHuffmanScalar(const signed short *huffTab, const HuffInfo *huffTabInfo, unsigned int bitBuf, signed int *val) { + unsigned int count, start, shift, t; + const unsigned /*char*/ int *countPtr; + const signed short *map; + + map = huffTab + huffTabInfo->offset; + countPtr = huffTabInfo->count; + + start = 0; + count = 0; + shift = 32; + do { + start += count; + start <<= 1; + map += count; + count = *countPtr++; + shift--; + t = (bitBuf >> shift) - start; + } while (t >= count); + +#ifdef ESP8266 + *val = (signed int)pgm_read_word(&map[t]); +#else + *val = map[t]; +#endif + return (countPtr - huffTabInfo->count); +} + +#define APPLY_SIGN(v, s) {(v) ^= ((signed int)(s) >> 31); (v) -= ((signed int)(s) >> 31);} + +#define GET_QUAD_SIGNBITS(v) (((unsigned int)(v) << 17) >> 29) /* bits 14-12, unsigned */ +#define GET_QUAD_W(v) (((signed int)(v) << 20) >> 29) /* bits 11-9, sign-extend */ +#define GET_QUAD_X(v) (((signed int)(v) << 23) >> 29) /* bits 8-6, sign-extend */ +#define GET_QUAD_Y(v) (((signed int)(v) << 26) >> 29) /* bits 5-3, sign-extend */ +#define GET_QUAD_Z(v) (((signed int)(v) << 29) >> 29) /* bits 2-0, sign-extend */ + +#define GET_PAIR_SIGNBITS(v) (((unsigned int)(v) << 20) >> 30) /* bits 11-10, unsigned */ +#define GET_PAIR_Y(v) (((signed int)(v) << 22) >> 27) /* bits 9-5, sign-extend */ +#define GET_PAIR_Z(v) (((signed int)(v) << 27) >> 27) /* bits 4-0, sign-extend */ + +#define GET_ESC_SIGNBITS(v) (((unsigned int)(v) << 18) >> 30) /* bits 13-12, unsigned */ +#define GET_ESC_Y(v) (((signed int)(v) << 20) >> 26) /* bits 11-6, sign-extend */ +#define GET_ESC_Z(v) (((signed int)(v) << 26) >> 26) /* bits 5-0, sign-extend */ + +/************************************************************************************** + Function: UnpackZeros + + Description: fill a section of coefficients with zeros + + Inputs: number of coefficients + + Outputs: nVals zeros, starting at coef + + Return: none + + Notes: assumes nVals is always a multiple of 4 because all scalefactor bands + are a multiple of 4 coefficients long + **************************************************************************************/ +static void UnpackZeros(int nVals, int *coef) { + while (nVals > 0) { + *coef++ = 0; + *coef++ = 0; + *coef++ = 0; + *coef++ = 0; + nVals -= 4; + } +} + +/************************************************************************************** + Function: UnpackQuads + + Description: decode a section of 4-way vector Huffman coded coefficients + + Inputs BitStreamInfo struct pointing to start of codewords for this section + index of Huffman codebook + number of coefficients + + Outputs: nVals coefficients, starting at coef + + Return: none + + Notes: assumes nVals is always a multiple of 4 because all scalefactor bands + are a multiple of 4 coefficients long + **************************************************************************************/ +/* __attribute__ ((section (".data"))) */ static void UnpackQuads(BitStreamInfo *bsi, int cb, int nVals, int *coef) { + int w, x, y, z, maxBits, nCodeBits, nSignBits, val; + unsigned int bitBuf; + + maxBits = huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET].maxBits + 4; + while (nVals > 0) { + /* decode quad */ + bitBuf = GetBitsNoAdvance(bsi, maxBits) << (32 - maxBits); + nCodeBits = DecodeHuffmanScalar(huffTabSpec, &huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET], bitBuf, &val); + + w = GET_QUAD_W(val); + x = GET_QUAD_X(val); + y = GET_QUAD_Y(val); + z = GET_QUAD_Z(val); + + bitBuf <<= nCodeBits; + nSignBits = (int)GET_QUAD_SIGNBITS(val); + AdvanceBitstream(bsi, nCodeBits + nSignBits); + if (nSignBits) { + if (w) { + APPLY_SIGN(w, bitBuf); + bitBuf <<= 1; + } + if (x) { + APPLY_SIGN(x, bitBuf); + bitBuf <<= 1; + } + if (y) { + APPLY_SIGN(y, bitBuf); + bitBuf <<= 1; + } + if (z) { + APPLY_SIGN(z, bitBuf); + bitBuf <<= 1; + } + } + *coef++ = w; *coef++ = x; *coef++ = y; *coef++ = z; + nVals -= 4; + } +} + +/************************************************************************************** + Function: UnpackPairsNoEsc + + Description: decode a section of 2-way vector Huffman coded coefficients, + using non-esc tables (5 through 10) + + Inputs BitStreamInfo struct pointing to start of codewords for this section + index of Huffman codebook (must not be the escape codebook) + number of coefficients + + Outputs: nVals coefficients, starting at coef + + Return: none + + Notes: assumes nVals is always a multiple of 2 because all scalefactor bands + are a multiple of 4 coefficients long + **************************************************************************************/ +/* __attribute__ ((section (".data"))) */ static void UnpackPairsNoEsc(BitStreamInfo *bsi, int cb, int nVals, int *coef) { + int y, z, maxBits, nCodeBits, nSignBits, val; + unsigned int bitBuf; + + maxBits = huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET].maxBits + 2; + while (nVals > 0) { + /* decode pair */ + bitBuf = GetBitsNoAdvance(bsi, maxBits) << (32 - maxBits); + nCodeBits = DecodeHuffmanScalar(huffTabSpec, &huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET], bitBuf, &val); + + y = GET_PAIR_Y(val); + z = GET_PAIR_Z(val); + + bitBuf <<= nCodeBits; + nSignBits = GET_PAIR_SIGNBITS(val); + AdvanceBitstream(bsi, nCodeBits + nSignBits); + if (nSignBits) { + if (y) { + APPLY_SIGN(y, bitBuf); + bitBuf <<= 1; + } + if (z) { + APPLY_SIGN(z, bitBuf); + bitBuf <<= 1; + } + } + *coef++ = y; *coef++ = z; + nVals -= 2; + } +} + +/************************************************************************************** + Function: UnpackPairsEsc + + Description: decode a section of 2-way vector Huffman coded coefficients, + using esc table (11) + + Inputs BitStreamInfo struct pointing to start of codewords for this section + index of Huffman codebook (must be the escape codebook) + number of coefficients + + Outputs: nVals coefficients, starting at coef + + Return: none + + Notes: assumes nVals is always a multiple of 2 because all scalefactor bands + are a multiple of 4 coefficients long + **************************************************************************************/ +/* __attribute__ ((section (".data"))) */ static void UnpackPairsEsc(BitStreamInfo *bsi, int cb, int nVals, int *coef) { + int y, z, maxBits, nCodeBits, nSignBits, n, val; + unsigned int bitBuf; + + maxBits = huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET].maxBits + 2; + while (nVals > 0) { + /* decode pair with escape value */ + bitBuf = GetBitsNoAdvance(bsi, maxBits) << (32 - maxBits); + nCodeBits = DecodeHuffmanScalar(huffTabSpec, &huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET], bitBuf, &val); + + y = GET_ESC_Y(val); + z = GET_ESC_Z(val); + + bitBuf <<= nCodeBits; + nSignBits = GET_ESC_SIGNBITS(val); + AdvanceBitstream(bsi, nCodeBits + nSignBits); + + if (y == 16) { + n = 4; + while (GetBits(bsi, 1) == 1) { + n++; + } + y = (1 << n) + GetBits(bsi, n); + } + if (z == 16) { + n = 4; + while (GetBits(bsi, 1) == 1) { + n++; + } + z = (1 << n) + GetBits(bsi, n); + } + + if (nSignBits) { + if (y) { + APPLY_SIGN(y, bitBuf); + bitBuf <<= 1; + } + if (z) { + APPLY_SIGN(z, bitBuf); + bitBuf <<= 1; + } + } + + *coef++ = y; *coef++ = z; + nVals -= 2; + } +} + +/************************************************************************************** + Function: DecodeSpectrumLong + + Description: decode transform coefficients for frame with one long block + + Inputs: platform specific info struct + BitStreamInfo struct pointing to start of spectral data + (14496-3, table 4.4.29) + index of current channel + + Outputs: decoded, quantized coefficients for this channel + + Return: none + + Notes: adds in pulse data if present + fills coefficient buffer with zeros in any region not coded with + codebook in range [1, 11] (including sfb's above sfbMax) + **************************************************************************************/ +/* __attribute__ ((section (".data"))) */ void DecodeSpectrumLong(PSInfoBase *psi, BitStreamInfo *bsi, int ch) { + int i, sfb, cb, nVals, offset; + const /*short*/ int *sfbTab; + unsigned char *sfbCodeBook; + int *coef; + ICSInfo *icsInfo; + PulseInfo *pi; + + coef = psi->coef[ch]; + icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]); + + /* decode long block */ + sfbTab = sfBandTabLong + sfBandTabLongOffset[psi->sampRateIdx]; + sfbCodeBook = psi->sfbCodeBook[ch]; + for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) { + cb = *sfbCodeBook++; + nVals = sfbTab[sfb + 1] - sfbTab[sfb]; + + if (cb == 0) { + UnpackZeros(nVals, coef); + } else if (cb <= 4) { + UnpackQuads(bsi, cb, nVals, coef); + } else if (cb <= 10) { + UnpackPairsNoEsc(bsi, cb, nVals, coef); + } else if (cb == 11) { + UnpackPairsEsc(bsi, cb, nVals, coef); + } else { + UnpackZeros(nVals, coef); + } + + coef += nVals; + } + + /* fill with zeros above maxSFB */ + nVals = NSAMPS_LONG - sfbTab[sfb]; + UnpackZeros(nVals, coef); + + /* add pulse data, if present */ + pi = &psi->pulseInfo[ch]; + if (pi->pulseDataPresent) { + coef = psi->coef[ch]; + offset = sfbTab[pi->startSFB]; + for (i = 0; i < pi->numPulse; i++) { + offset += pi->offset[i]; + if (coef[offset] > 0) { + coef[offset] += pi->amp[i]; + } else { + coef[offset] -= pi->amp[i]; + } + } + ASSERT(offset < NSAMPS_LONG); + } +} + +/************************************************************************************** + Function: DecodeSpectrumShort + + Description: decode transform coefficients for frame with eight short blocks + + Inputs: platform specific info struct + BitStreamInfo struct pointing to start of spectral data + (14496-3, table 4.4.29) + index of current channel + + Outputs: decoded, quantized coefficients for this channel + + Return: none + + Notes: fills coefficient buffer with zeros in any region not coded with + codebook in range [1, 11] (including sfb's above sfbMax) + deinterleaves window groups into 8 windows + **************************************************************************************/ +/* __attribute__ ((section (".data"))) */ void DecodeSpectrumShort(PSInfoBase *psi, BitStreamInfo *bsi, int ch) { + int gp, cb, nVals = 0, win, offset, sfb; + const /*short*/ int *sfbTab; + unsigned char *sfbCodeBook; + int *coef; + ICSInfo *icsInfo; + + coef = psi->coef[ch]; + icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]); + + /* decode short blocks, deinterleaving in-place */ + sfbTab = sfBandTabShort + sfBandTabShortOffset[psi->sampRateIdx]; + sfbCodeBook = psi->sfbCodeBook[ch]; + for (gp = 0; gp < icsInfo->numWinGroup; gp++) { + for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) { + nVals = sfbTab[sfb + 1] - sfbTab[sfb]; + cb = *sfbCodeBook++; + + for (win = 0; win < icsInfo->winGroupLen[gp]; win++) { + offset = win * NSAMPS_SHORT; + if (cb == 0) { + UnpackZeros(nVals, coef + offset); + } else if (cb <= 4) { + UnpackQuads(bsi, cb, nVals, coef + offset); + } else if (cb <= 10) { + UnpackPairsNoEsc(bsi, cb, nVals, coef + offset); + } else if (cb == 11) { + UnpackPairsEsc(bsi, cb, nVals, coef + offset); + } else { + UnpackZeros(nVals, coef + offset); + } + } + coef += nVals; + } + + /* fill with zeros above maxSFB */ + for (win = 0; win < icsInfo->winGroupLen[gp]; win++) { + offset = win * NSAMPS_SHORT; + nVals = NSAMPS_SHORT - sfbTab[sfb]; + UnpackZeros(nVals, coef + offset); + } + coef += nVals; + coef += (icsInfo->winGroupLen[gp] - 1) * NSAMPS_SHORT; + } + + ASSERT(coef == psi->coef[ch] + NSAMPS_LONG); +} diff --git a/src/libhelix-aac/hufftabs.c b/src/libhelix-aac/hufftabs.c index 91cc50ce..b8a3a7a4 100644 --- a/src/libhelix-aac/hufftabs.c +++ b/src/libhelix-aac/hufftabs.c @@ -1,177 +1,177 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: hufftabs.c,v 1.1 2005/02/26 01:47:34 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: hufftabs.c,v 1.1 2005/02/26 01:47:34 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * hufftabs.c - Huffman symbol tables + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + hufftabs.c - Huffman symbol tables **************************************************************************************/ #include "coder.h" const HuffInfo huffTabSpecInfo[11] PROGMEM = { - /* table 0 not used */ - {11, { 1, 0, 0, 0, 8, 0, 24, 0, 24, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0}, - { 9, { 0, 0, 1, 1, 7, 24, 15, 19, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 81}, - {16, { 1, 0, 0, 4, 2, 6, 3, 5, 15, 15, 8, 9, 3, 3, 5, 2, 0, 0, 0, 0}, 162}, - {12, { 0, 0, 0, 10, 6, 0, 9, 21, 8, 14, 11, 2, 0, 0, 0, 0, 0, 0, 0, 0}, 243}, - {13, { 1, 0, 0, 4, 4, 0, 4, 12, 12, 12, 18, 10, 4, 0, 0, 0, 0, 0, 0, 0}, 324}, - {11, { 0, 0, 0, 9, 0, 16, 13, 8, 23, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 405}, - {12, { 1, 0, 2, 1, 0, 4, 5, 10, 14, 15, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0}, 486}, - {10, { 0, 0, 1, 5, 7, 10, 14, 15, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 550}, - {15, { 1, 0, 2, 1, 0, 4, 3, 8, 11, 20, 31, 38, 32, 14, 4, 0, 0, 0, 0, 0}, 614}, - {12, { 0, 0, 0, 3, 8, 14, 17, 25, 31, 41, 22, 8, 0, 0, 0, 0, 0, 0, 0, 0}, 783}, - {12, { 0, 0, 0, 2, 6, 7, 16, 59, 55, 95, 43, 6, 0, 0, 0, 0, 0, 0, 0, 0}, 952}, + /* table 0 not used */ + {11, { 1, 0, 0, 0, 8, 0, 24, 0, 24, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0}, + { 9, { 0, 0, 1, 1, 7, 24, 15, 19, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 81}, + {16, { 1, 0, 0, 4, 2, 6, 3, 5, 15, 15, 8, 9, 3, 3, 5, 2, 0, 0, 0, 0}, 162}, + {12, { 0, 0, 0, 10, 6, 0, 9, 21, 8, 14, 11, 2, 0, 0, 0, 0, 0, 0, 0, 0}, 243}, + {13, { 1, 0, 0, 4, 4, 0, 4, 12, 12, 12, 18, 10, 4, 0, 0, 0, 0, 0, 0, 0}, 324}, + {11, { 0, 0, 0, 9, 0, 16, 13, 8, 23, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 405}, + {12, { 1, 0, 2, 1, 0, 4, 5, 10, 14, 15, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0}, 486}, + {10, { 0, 0, 1, 5, 7, 10, 14, 15, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 550}, + {15, { 1, 0, 2, 1, 0, 4, 3, 8, 11, 20, 31, 38, 32, 14, 4, 0, 0, 0, 0, 0}, 614}, + {12, { 0, 0, 0, 3, 8, 14, 17, 25, 31, 41, 22, 8, 0, 0, 0, 0, 0, 0, 0, 0}, 783}, + {12, { 0, 0, 0, 2, 6, 7, 16, 59, 55, 95, 43, 6, 0, 0, 0, 0, 0, 0, 0, 0}, 952}, }; const signed short huffTabSpec[1241] PROGMEM = { - /* spectrum table 1 [81] (signed) */ - 0x0000, 0x0200, 0x0e00, 0x0007, 0x0040, 0x0001, 0x0038, 0x0008, 0x01c0, 0x03c0, 0x0e40, 0x0039, 0x0078, 0x01c8, 0x000f, 0x0240, - 0x003f, 0x0fc0, 0x01f8, 0x0238, 0x0047, 0x0e08, 0x0009, 0x0208, 0x01c1, 0x0048, 0x0041, 0x0e38, 0x0201, 0x0e07, 0x0207, 0x0e01, - 0x01c7, 0x0278, 0x0e78, 0x03c8, 0x004f, 0x0079, 0x01c9, 0x01cf, 0x03f8, 0x0239, 0x007f, 0x0e48, 0x0e0f, 0x0fc8, 0x01f9, 0x03c1, - 0x03c7, 0x0e47, 0x0ff8, 0x01ff, 0x0049, 0x020f, 0x0241, 0x0e41, 0x0248, 0x0fc1, 0x0e3f, 0x0247, 0x023f, 0x0e39, 0x0fc7, 0x0e09, - 0x0209, 0x03cf, 0x0e79, 0x0e4f, 0x03f9, 0x0249, 0x0fc9, 0x027f, 0x0fcf, 0x0fff, 0x0279, 0x03c9, 0x0e49, 0x0e7f, 0x0ff9, 0x03ff, - 0x024f, - /* spectrum table 2 [81] (signed) */ - 0x0000, 0x0200, 0x0e00, 0x0001, 0x0038, 0x0007, 0x01c0, 0x0008, 0x0040, 0x01c8, 0x0e40, 0x0078, 0x000f, 0x0047, 0x0039, 0x0e07, - 0x03c0, 0x0238, 0x0fc0, 0x003f, 0x0208, 0x0201, 0x01c1, 0x0e08, 0x0041, 0x01f8, 0x0e01, 0x01c7, 0x0e38, 0x0240, 0x0048, 0x0009, - 0x0207, 0x0079, 0x0239, 0x0e78, 0x01cf, 0x03c8, 0x0247, 0x0209, 0x0e48, 0x01f9, 0x0248, 0x0e0f, 0x0ff8, 0x0e39, 0x03f8, 0x0278, - 0x03c1, 0x0e47, 0x0fc8, 0x0e09, 0x0fc1, 0x0fc7, 0x01ff, 0x020f, 0x023f, 0x007f, 0x0049, 0x0e41, 0x0e3f, 0x004f, 0x03c7, 0x01c9, - 0x0241, 0x03cf, 0x0e79, 0x03f9, 0x0fff, 0x0e4f, 0x0e49, 0x0249, 0x0fcf, 0x03c9, 0x0e7f, 0x0fc9, 0x027f, 0x03ff, 0x0ff9, 0x0279, - 0x024f, - /* spectrum table 3 [81] (unsigned) */ - 0x0000, 0x1200, 0x1001, 0x1040, 0x1008, 0x2240, 0x2009, 0x2048, 0x2041, 0x2208, 0x3049, 0x2201, 0x3248, 0x4249, 0x3209, 0x3241, - 0x1400, 0x1002, 0x200a, 0x2440, 0x3288, 0x2011, 0x3051, 0x2280, 0x304a, 0x3448, 0x1010, 0x2088, 0x2050, 0x1080, 0x2042, 0x2408, - 0x4289, 0x3089, 0x3250, 0x4251, 0x3281, 0x2210, 0x3211, 0x2081, 0x4449, 0x424a, 0x3441, 0x320a, 0x2012, 0x3052, 0x3488, 0x3290, - 0x2202, 0x2401, 0x3091, 0x2480, 0x4291, 0x3242, 0x3409, 0x4252, 0x4489, 0x2090, 0x308a, 0x3212, 0x3481, 0x3450, 0x3490, 0x3092, - 0x4491, 0x4451, 0x428a, 0x4292, 0x2082, 0x2410, 0x3282, 0x3411, 0x444a, 0x3442, 0x4492, 0x448a, 0x4452, 0x340a, 0x2402, 0x3482, - 0x3412, - /* spectrum table 4 [81] (unsigned) */ - 0x4249, 0x3049, 0x3241, 0x3248, 0x3209, 0x1200, 0x2240, 0x0000, 0x2009, 0x2208, 0x2201, 0x2048, 0x1001, 0x2041, 0x1008, 0x1040, - 0x4449, 0x4251, 0x4289, 0x424a, 0x3448, 0x3441, 0x3288, 0x3409, 0x3051, 0x304a, 0x3250, 0x3089, 0x320a, 0x3281, 0x3242, 0x3211, - 0x2440, 0x2408, 0x2280, 0x2401, 0x2042, 0x2088, 0x200a, 0x2050, 0x2081, 0x2202, 0x2011, 0x2210, 0x1400, 0x1002, 0x1080, 0x1010, - 0x4291, 0x4489, 0x4451, 0x4252, 0x428a, 0x444a, 0x3290, 0x3488, 0x3450, 0x3091, 0x3052, 0x3481, 0x308a, 0x3411, 0x3212, 0x4491, - 0x3282, 0x340a, 0x3442, 0x4292, 0x4452, 0x448a, 0x2090, 0x2480, 0x2012, 0x2410, 0x2082, 0x2402, 0x4492, 0x3092, 0x3490, 0x3482, - 0x3412, - /* spectrum table 5 [81] (signed) */ - 0x0000, 0x03e0, 0x0020, 0x0001, 0x001f, 0x003f, 0x03e1, 0x03ff, 0x0021, 0x03c0, 0x0002, 0x0040, 0x001e, 0x03df, 0x0041, 0x03fe, - 0x0022, 0x03c1, 0x005f, 0x03e2, 0x003e, 0x03a0, 0x0060, 0x001d, 0x0003, 0x03bf, 0x0023, 0x0061, 0x03fd, 0x03a1, 0x007f, 0x003d, - 0x03e3, 0x03c2, 0x0042, 0x03de, 0x005e, 0x03be, 0x007e, 0x03c3, 0x005d, 0x0062, 0x0043, 0x03a2, 0x03dd, 0x001c, 0x0380, 0x0081, - 0x0080, 0x039f, 0x0004, 0x009f, 0x03fc, 0x0024, 0x03e4, 0x0381, 0x003c, 0x007d, 0x03bd, 0x03a3, 0x03c4, 0x039e, 0x0082, 0x005c, - 0x0044, 0x0063, 0x0382, 0x03dc, 0x009e, 0x007c, 0x039d, 0x0383, 0x0064, 0x03a4, 0x0083, 0x009d, 0x03bc, 0x009c, 0x0384, 0x0084, - 0x039c, - /* spectrum table 6 [81] (signed) */ - 0x0000, 0x0020, 0x001f, 0x0001, 0x03e0, 0x0021, 0x03e1, 0x003f, 0x03ff, 0x005f, 0x0041, 0x03c1, 0x03df, 0x03c0, 0x03e2, 0x0040, - 0x003e, 0x0022, 0x001e, 0x03fe, 0x0002, 0x005e, 0x03c2, 0x03de, 0x0042, 0x03a1, 0x0061, 0x007f, 0x03e3, 0x03bf, 0x0023, 0x003d, - 0x03fd, 0x0060, 0x03a0, 0x001d, 0x0003, 0x0062, 0x03be, 0x03c3, 0x0043, 0x007e, 0x005d, 0x03dd, 0x03a2, 0x0063, 0x007d, 0x03bd, - 0x03a3, 0x003c, 0x03fc, 0x0081, 0x0381, 0x039f, 0x0024, 0x009f, 0x03e4, 0x001c, 0x0382, 0x039e, 0x0044, 0x03dc, 0x0380, 0x0082, - 0x009e, 0x03c4, 0x0080, 0x005c, 0x0004, 0x03bc, 0x03a4, 0x007c, 0x009d, 0x0064, 0x0083, 0x0383, 0x039d, 0x0084, 0x0384, 0x039c, - 0x009c, - /* spectrum table 7 [64] (unsigned) */ - 0x0000, 0x0420, 0x0401, 0x0821, 0x0841, 0x0822, 0x0440, 0x0402, 0x0861, 0x0823, 0x0842, 0x0460, 0x0403, 0x0843, 0x0862, 0x0824, - 0x0881, 0x0825, 0x08a1, 0x0863, 0x0844, 0x0404, 0x0480, 0x0882, 0x0845, 0x08a2, 0x0405, 0x08c1, 0x04a0, 0x0826, 0x0883, 0x0865, - 0x0864, 0x08a3, 0x0846, 0x08c2, 0x0827, 0x0866, 0x0406, 0x04c0, 0x0884, 0x08e1, 0x0885, 0x08e2, 0x08a4, 0x08c3, 0x0847, 0x08e3, - 0x08c4, 0x08a5, 0x0886, 0x0867, 0x04e0, 0x0407, 0x08c5, 0x08a6, 0x08e4, 0x0887, 0x08a7, 0x08e5, 0x08e6, 0x08c6, 0x08c7, 0x08e7, - /* spectrum table 8 [64] (unsigned) */ - 0x0821, 0x0841, 0x0420, 0x0822, 0x0401, 0x0842, 0x0000, 0x0440, 0x0402, 0x0861, 0x0823, 0x0862, 0x0843, 0x0863, 0x0881, 0x0824, - 0x0882, 0x0844, 0x0460, 0x0403, 0x0883, 0x0864, 0x08a2, 0x08a1, 0x0845, 0x0825, 0x08a3, 0x0865, 0x0884, 0x08a4, 0x0404, 0x0885, - 0x0480, 0x0846, 0x08c2, 0x08c1, 0x0826, 0x0866, 0x08c3, 0x08a5, 0x04a0, 0x08c4, 0x0405, 0x0886, 0x08e1, 0x08e2, 0x0847, 0x08c5, - 0x08e3, 0x0827, 0x08a6, 0x0867, 0x08c6, 0x08e4, 0x04c0, 0x0887, 0x0406, 0x08e5, 0x08e6, 0x08c7, 0x08a7, 0x04e0, 0x0407, 0x08e7, - /* spectrum table 9 [169] (unsigned) */ - 0x0000, 0x0420, 0x0401, 0x0821, 0x0841, 0x0822, 0x0440, 0x0402, 0x0861, 0x0842, 0x0823, 0x0460, 0x0403, 0x0843, 0x0862, 0x0824, - 0x0881, 0x0844, 0x0825, 0x0882, 0x0863, 0x0404, 0x0480, 0x08a1, 0x0845, 0x0826, 0x0864, 0x08a2, 0x08c1, 0x0883, 0x0405, 0x0846, - 0x04a0, 0x0827, 0x0865, 0x0828, 0x0901, 0x0884, 0x08a3, 0x08c2, 0x08e1, 0x0406, 0x0902, 0x0848, 0x0866, 0x0847, 0x0885, 0x0921, - 0x0829, 0x08e2, 0x04c0, 0x08a4, 0x08c3, 0x0903, 0x0407, 0x0922, 0x0868, 0x0886, 0x0867, 0x0408, 0x0941, 0x08c4, 0x0849, 0x08a5, - 0x0500, 0x04e0, 0x08e3, 0x0942, 0x0923, 0x0904, 0x082a, 0x08e4, 0x08c5, 0x08a6, 0x0888, 0x0887, 0x0869, 0x0961, 0x08a8, 0x0520, - 0x0905, 0x0943, 0x084a, 0x0409, 0x0962, 0x0924, 0x08c6, 0x0981, 0x0889, 0x0906, 0x082b, 0x0925, 0x0944, 0x08a7, 0x08e5, 0x084b, - 0x082c, 0x0982, 0x0963, 0x086a, 0x08a9, 0x08c7, 0x0907, 0x0964, 0x040a, 0x08e6, 0x0983, 0x0540, 0x0945, 0x088a, 0x08c8, 0x084c, - 0x0926, 0x0927, 0x088b, 0x0560, 0x08c9, 0x086b, 0x08aa, 0x0908, 0x08e8, 0x0985, 0x086c, 0x0965, 0x08e7, 0x0984, 0x0966, 0x0946, - 0x088c, 0x08e9, 0x08ab, 0x040b, 0x0986, 0x08ca, 0x0580, 0x0947, 0x08ac, 0x08ea, 0x0928, 0x040c, 0x0967, 0x0909, 0x0929, 0x0948, - 0x08eb, 0x0987, 0x08cb, 0x090b, 0x0968, 0x08ec, 0x08cc, 0x090a, 0x0949, 0x090c, 0x092a, 0x092b, 0x092c, 0x094b, 0x0989, 0x094a, - 0x0969, 0x0988, 0x096a, 0x098a, 0x098b, 0x094c, 0x096b, 0x096c, 0x098c, - /* spectrum table 10 [169] (unsigned) */ - 0x0821, 0x0822, 0x0841, 0x0842, 0x0420, 0x0401, 0x0823, 0x0862, 0x0861, 0x0843, 0x0863, 0x0440, 0x0402, 0x0844, 0x0882, 0x0824, - 0x0881, 0x0000, 0x0883, 0x0864, 0x0460, 0x0403, 0x0884, 0x0845, 0x08a2, 0x0825, 0x08a1, 0x08a3, 0x0865, 0x08a4, 0x0885, 0x08c2, - 0x0846, 0x08c3, 0x0480, 0x08c1, 0x0404, 0x0826, 0x0866, 0x08a5, 0x08c4, 0x0886, 0x08c5, 0x08e2, 0x0867, 0x0847, 0x08a6, 0x0902, - 0x08e3, 0x04a0, 0x08e1, 0x0405, 0x0901, 0x0827, 0x0903, 0x08e4, 0x0887, 0x0848, 0x08c6, 0x08e5, 0x0828, 0x0868, 0x0904, 0x0888, - 0x08a7, 0x0905, 0x08a8, 0x08e6, 0x08c7, 0x0922, 0x04c0, 0x08c8, 0x0923, 0x0869, 0x0921, 0x0849, 0x0406, 0x0906, 0x0924, 0x0889, - 0x0942, 0x0829, 0x08e7, 0x0907, 0x0925, 0x08e8, 0x0943, 0x08a9, 0x0944, 0x084a, 0x0941, 0x086a, 0x0926, 0x08c9, 0x0500, 0x088a, - 0x04e0, 0x0962, 0x08e9, 0x0963, 0x0946, 0x082a, 0x0961, 0x0927, 0x0407, 0x0908, 0x0945, 0x086b, 0x08aa, 0x0909, 0x0965, 0x0408, - 0x0964, 0x084b, 0x08ea, 0x08ca, 0x0947, 0x088b, 0x082b, 0x0982, 0x0928, 0x0983, 0x0966, 0x08ab, 0x0984, 0x0967, 0x0985, 0x086c, - 0x08cb, 0x0520, 0x0948, 0x0540, 0x0981, 0x0409, 0x088c, 0x0929, 0x0986, 0x084c, 0x090a, 0x092a, 0x082c, 0x0968, 0x0987, 0x08eb, - 0x08ac, 0x08cc, 0x0949, 0x090b, 0x0988, 0x040a, 0x08ec, 0x0560, 0x094a, 0x0969, 0x096a, 0x040b, 0x096b, 0x092b, 0x094b, 0x0580, - 0x090c, 0x0989, 0x094c, 0x092c, 0x096c, 0x098b, 0x040c, 0x098a, 0x098c, - /* spectrum table 11 [289] (unsigned) */ - 0x0000, 0x2041, 0x2410, 0x1040, 0x1001, 0x2081, 0x2042, 0x2082, 0x2043, 0x20c1, 0x20c2, 0x1080, 0x2083, 0x1002, 0x20c3, 0x2101, - 0x2044, 0x2102, 0x2084, 0x2103, 0x20c4, 0x10c0, 0x1003, 0x2141, 0x2142, 0x2085, 0x2104, 0x2045, 0x2143, 0x20c5, 0x2144, 0x2105, - 0x2182, 0x2086, 0x2181, 0x2183, 0x20c6, 0x2046, 0x2110, 0x20d0, 0x2405, 0x2403, 0x2404, 0x2184, 0x2406, 0x1100, 0x2106, 0x1004, - 0x2090, 0x2145, 0x2150, 0x2407, 0x2402, 0x2408, 0x2087, 0x21c2, 0x20c7, 0x2185, 0x2146, 0x2190, 0x240a, 0x21c3, 0x21c1, 0x2409, - 0x21d0, 0x2050, 0x2047, 0x2107, 0x240b, 0x21c4, 0x240c, 0x2210, 0x2401, 0x2186, 0x2250, 0x2088, 0x2147, 0x2290, 0x240d, 0x2203, - 0x2202, 0x20c8, 0x1140, 0x240e, 0x22d0, 0x21c5, 0x2108, 0x2187, 0x21c6, 0x1005, 0x2204, 0x240f, 0x2310, 0x2048, 0x2201, 0x2390, - 0x2148, 0x2350, 0x20c9, 0x2205, 0x21c7, 0x2089, 0x2206, 0x2242, 0x2243, 0x23d0, 0x2109, 0x2188, 0x1180, 0x2244, 0x2149, 0x2207, - 0x21c8, 0x2049, 0x2283, 0x1006, 0x2282, 0x2241, 0x2245, 0x210a, 0x208a, 0x2246, 0x20ca, 0x2189, 0x2284, 0x2208, 0x2285, 0x2247, - 0x22c3, 0x204a, 0x11c0, 0x2286, 0x21c9, 0x20cb, 0x214a, 0x2281, 0x210b, 0x22c2, 0x2342, 0x218a, 0x2343, 0x208b, 0x1400, 0x214b, - 0x22c5, 0x22c4, 0x2248, 0x21ca, 0x2209, 0x1010, 0x210d, 0x1007, 0x20cd, 0x22c6, 0x2341, 0x2344, 0x2303, 0x208d, 0x2345, 0x220a, - 0x218b, 0x2288, 0x2287, 0x2382, 0x2304, 0x204b, 0x210c, 0x22c1, 0x20cc, 0x204d, 0x2302, 0x21cb, 0x20ce, 0x214c, 0x214d, 0x2384, - 0x210e, 0x22c7, 0x2383, 0x2305, 0x2346, 0x2306, 0x1200, 0x22c8, 0x208c, 0x2249, 0x2385, 0x218d, 0x228a, 0x23c2, 0x220b, 0x224a, - 0x2386, 0x2289, 0x214e, 0x22c9, 0x2381, 0x208e, 0x218c, 0x204c, 0x2348, 0x1008, 0x2347, 0x21cc, 0x2307, 0x21cd, 0x23c3, 0x2301, - 0x218e, 0x208f, 0x23c5, 0x23c4, 0x204e, 0x224b, 0x210f, 0x2387, 0x220d, 0x2349, 0x220c, 0x214f, 0x20cf, 0x228b, 0x22ca, 0x2308, - 0x23c6, 0x23c7, 0x220e, 0x23c1, 0x21ce, 0x1240, 0x1009, 0x224d, 0x224c, 0x2309, 0x2388, 0x228d, 0x2389, 0x230a, 0x218f, 0x21cf, - 0x224e, 0x23c8, 0x22cb, 0x22ce, 0x204f, 0x228c, 0x228e, 0x234b, 0x234a, 0x22cd, 0x22cc, 0x220f, 0x238b, 0x234c, 0x230d, 0x23c9, - 0x238a, 0x1280, 0x230b, 0x224f, 0x100a, 0x230c, 0x12c0, 0x230e, 0x228f, 0x234d, 0x100d, 0x238c, 0x23ca, 0x23cb, 0x22cf, 0x238d, - 0x1340, 0x100b, 0x234e, 0x23cc, 0x23cd, 0x230f, 0x1380, 0x238e, 0x234f, 0x1300, 0x238f, 0x100e, 0x100c, 0x23ce, 0x13c0, 0x100f, - 0x23cf, + /* spectrum table 1 [81] (signed) */ + 0x0000, 0x0200, 0x0e00, 0x0007, 0x0040, 0x0001, 0x0038, 0x0008, 0x01c0, 0x03c0, 0x0e40, 0x0039, 0x0078, 0x01c8, 0x000f, 0x0240, + 0x003f, 0x0fc0, 0x01f8, 0x0238, 0x0047, 0x0e08, 0x0009, 0x0208, 0x01c1, 0x0048, 0x0041, 0x0e38, 0x0201, 0x0e07, 0x0207, 0x0e01, + 0x01c7, 0x0278, 0x0e78, 0x03c8, 0x004f, 0x0079, 0x01c9, 0x01cf, 0x03f8, 0x0239, 0x007f, 0x0e48, 0x0e0f, 0x0fc8, 0x01f9, 0x03c1, + 0x03c7, 0x0e47, 0x0ff8, 0x01ff, 0x0049, 0x020f, 0x0241, 0x0e41, 0x0248, 0x0fc1, 0x0e3f, 0x0247, 0x023f, 0x0e39, 0x0fc7, 0x0e09, + 0x0209, 0x03cf, 0x0e79, 0x0e4f, 0x03f9, 0x0249, 0x0fc9, 0x027f, 0x0fcf, 0x0fff, 0x0279, 0x03c9, 0x0e49, 0x0e7f, 0x0ff9, 0x03ff, + 0x024f, + /* spectrum table 2 [81] (signed) */ + 0x0000, 0x0200, 0x0e00, 0x0001, 0x0038, 0x0007, 0x01c0, 0x0008, 0x0040, 0x01c8, 0x0e40, 0x0078, 0x000f, 0x0047, 0x0039, 0x0e07, + 0x03c0, 0x0238, 0x0fc0, 0x003f, 0x0208, 0x0201, 0x01c1, 0x0e08, 0x0041, 0x01f8, 0x0e01, 0x01c7, 0x0e38, 0x0240, 0x0048, 0x0009, + 0x0207, 0x0079, 0x0239, 0x0e78, 0x01cf, 0x03c8, 0x0247, 0x0209, 0x0e48, 0x01f9, 0x0248, 0x0e0f, 0x0ff8, 0x0e39, 0x03f8, 0x0278, + 0x03c1, 0x0e47, 0x0fc8, 0x0e09, 0x0fc1, 0x0fc7, 0x01ff, 0x020f, 0x023f, 0x007f, 0x0049, 0x0e41, 0x0e3f, 0x004f, 0x03c7, 0x01c9, + 0x0241, 0x03cf, 0x0e79, 0x03f9, 0x0fff, 0x0e4f, 0x0e49, 0x0249, 0x0fcf, 0x03c9, 0x0e7f, 0x0fc9, 0x027f, 0x03ff, 0x0ff9, 0x0279, + 0x024f, + /* spectrum table 3 [81] (unsigned) */ + 0x0000, 0x1200, 0x1001, 0x1040, 0x1008, 0x2240, 0x2009, 0x2048, 0x2041, 0x2208, 0x3049, 0x2201, 0x3248, 0x4249, 0x3209, 0x3241, + 0x1400, 0x1002, 0x200a, 0x2440, 0x3288, 0x2011, 0x3051, 0x2280, 0x304a, 0x3448, 0x1010, 0x2088, 0x2050, 0x1080, 0x2042, 0x2408, + 0x4289, 0x3089, 0x3250, 0x4251, 0x3281, 0x2210, 0x3211, 0x2081, 0x4449, 0x424a, 0x3441, 0x320a, 0x2012, 0x3052, 0x3488, 0x3290, + 0x2202, 0x2401, 0x3091, 0x2480, 0x4291, 0x3242, 0x3409, 0x4252, 0x4489, 0x2090, 0x308a, 0x3212, 0x3481, 0x3450, 0x3490, 0x3092, + 0x4491, 0x4451, 0x428a, 0x4292, 0x2082, 0x2410, 0x3282, 0x3411, 0x444a, 0x3442, 0x4492, 0x448a, 0x4452, 0x340a, 0x2402, 0x3482, + 0x3412, + /* spectrum table 4 [81] (unsigned) */ + 0x4249, 0x3049, 0x3241, 0x3248, 0x3209, 0x1200, 0x2240, 0x0000, 0x2009, 0x2208, 0x2201, 0x2048, 0x1001, 0x2041, 0x1008, 0x1040, + 0x4449, 0x4251, 0x4289, 0x424a, 0x3448, 0x3441, 0x3288, 0x3409, 0x3051, 0x304a, 0x3250, 0x3089, 0x320a, 0x3281, 0x3242, 0x3211, + 0x2440, 0x2408, 0x2280, 0x2401, 0x2042, 0x2088, 0x200a, 0x2050, 0x2081, 0x2202, 0x2011, 0x2210, 0x1400, 0x1002, 0x1080, 0x1010, + 0x4291, 0x4489, 0x4451, 0x4252, 0x428a, 0x444a, 0x3290, 0x3488, 0x3450, 0x3091, 0x3052, 0x3481, 0x308a, 0x3411, 0x3212, 0x4491, + 0x3282, 0x340a, 0x3442, 0x4292, 0x4452, 0x448a, 0x2090, 0x2480, 0x2012, 0x2410, 0x2082, 0x2402, 0x4492, 0x3092, 0x3490, 0x3482, + 0x3412, + /* spectrum table 5 [81] (signed) */ + 0x0000, 0x03e0, 0x0020, 0x0001, 0x001f, 0x003f, 0x03e1, 0x03ff, 0x0021, 0x03c0, 0x0002, 0x0040, 0x001e, 0x03df, 0x0041, 0x03fe, + 0x0022, 0x03c1, 0x005f, 0x03e2, 0x003e, 0x03a0, 0x0060, 0x001d, 0x0003, 0x03bf, 0x0023, 0x0061, 0x03fd, 0x03a1, 0x007f, 0x003d, + 0x03e3, 0x03c2, 0x0042, 0x03de, 0x005e, 0x03be, 0x007e, 0x03c3, 0x005d, 0x0062, 0x0043, 0x03a2, 0x03dd, 0x001c, 0x0380, 0x0081, + 0x0080, 0x039f, 0x0004, 0x009f, 0x03fc, 0x0024, 0x03e4, 0x0381, 0x003c, 0x007d, 0x03bd, 0x03a3, 0x03c4, 0x039e, 0x0082, 0x005c, + 0x0044, 0x0063, 0x0382, 0x03dc, 0x009e, 0x007c, 0x039d, 0x0383, 0x0064, 0x03a4, 0x0083, 0x009d, 0x03bc, 0x009c, 0x0384, 0x0084, + 0x039c, + /* spectrum table 6 [81] (signed) */ + 0x0000, 0x0020, 0x001f, 0x0001, 0x03e0, 0x0021, 0x03e1, 0x003f, 0x03ff, 0x005f, 0x0041, 0x03c1, 0x03df, 0x03c0, 0x03e2, 0x0040, + 0x003e, 0x0022, 0x001e, 0x03fe, 0x0002, 0x005e, 0x03c2, 0x03de, 0x0042, 0x03a1, 0x0061, 0x007f, 0x03e3, 0x03bf, 0x0023, 0x003d, + 0x03fd, 0x0060, 0x03a0, 0x001d, 0x0003, 0x0062, 0x03be, 0x03c3, 0x0043, 0x007e, 0x005d, 0x03dd, 0x03a2, 0x0063, 0x007d, 0x03bd, + 0x03a3, 0x003c, 0x03fc, 0x0081, 0x0381, 0x039f, 0x0024, 0x009f, 0x03e4, 0x001c, 0x0382, 0x039e, 0x0044, 0x03dc, 0x0380, 0x0082, + 0x009e, 0x03c4, 0x0080, 0x005c, 0x0004, 0x03bc, 0x03a4, 0x007c, 0x009d, 0x0064, 0x0083, 0x0383, 0x039d, 0x0084, 0x0384, 0x039c, + 0x009c, + /* spectrum table 7 [64] (unsigned) */ + 0x0000, 0x0420, 0x0401, 0x0821, 0x0841, 0x0822, 0x0440, 0x0402, 0x0861, 0x0823, 0x0842, 0x0460, 0x0403, 0x0843, 0x0862, 0x0824, + 0x0881, 0x0825, 0x08a1, 0x0863, 0x0844, 0x0404, 0x0480, 0x0882, 0x0845, 0x08a2, 0x0405, 0x08c1, 0x04a0, 0x0826, 0x0883, 0x0865, + 0x0864, 0x08a3, 0x0846, 0x08c2, 0x0827, 0x0866, 0x0406, 0x04c0, 0x0884, 0x08e1, 0x0885, 0x08e2, 0x08a4, 0x08c3, 0x0847, 0x08e3, + 0x08c4, 0x08a5, 0x0886, 0x0867, 0x04e0, 0x0407, 0x08c5, 0x08a6, 0x08e4, 0x0887, 0x08a7, 0x08e5, 0x08e6, 0x08c6, 0x08c7, 0x08e7, + /* spectrum table 8 [64] (unsigned) */ + 0x0821, 0x0841, 0x0420, 0x0822, 0x0401, 0x0842, 0x0000, 0x0440, 0x0402, 0x0861, 0x0823, 0x0862, 0x0843, 0x0863, 0x0881, 0x0824, + 0x0882, 0x0844, 0x0460, 0x0403, 0x0883, 0x0864, 0x08a2, 0x08a1, 0x0845, 0x0825, 0x08a3, 0x0865, 0x0884, 0x08a4, 0x0404, 0x0885, + 0x0480, 0x0846, 0x08c2, 0x08c1, 0x0826, 0x0866, 0x08c3, 0x08a5, 0x04a0, 0x08c4, 0x0405, 0x0886, 0x08e1, 0x08e2, 0x0847, 0x08c5, + 0x08e3, 0x0827, 0x08a6, 0x0867, 0x08c6, 0x08e4, 0x04c0, 0x0887, 0x0406, 0x08e5, 0x08e6, 0x08c7, 0x08a7, 0x04e0, 0x0407, 0x08e7, + /* spectrum table 9 [169] (unsigned) */ + 0x0000, 0x0420, 0x0401, 0x0821, 0x0841, 0x0822, 0x0440, 0x0402, 0x0861, 0x0842, 0x0823, 0x0460, 0x0403, 0x0843, 0x0862, 0x0824, + 0x0881, 0x0844, 0x0825, 0x0882, 0x0863, 0x0404, 0x0480, 0x08a1, 0x0845, 0x0826, 0x0864, 0x08a2, 0x08c1, 0x0883, 0x0405, 0x0846, + 0x04a0, 0x0827, 0x0865, 0x0828, 0x0901, 0x0884, 0x08a3, 0x08c2, 0x08e1, 0x0406, 0x0902, 0x0848, 0x0866, 0x0847, 0x0885, 0x0921, + 0x0829, 0x08e2, 0x04c0, 0x08a4, 0x08c3, 0x0903, 0x0407, 0x0922, 0x0868, 0x0886, 0x0867, 0x0408, 0x0941, 0x08c4, 0x0849, 0x08a5, + 0x0500, 0x04e0, 0x08e3, 0x0942, 0x0923, 0x0904, 0x082a, 0x08e4, 0x08c5, 0x08a6, 0x0888, 0x0887, 0x0869, 0x0961, 0x08a8, 0x0520, + 0x0905, 0x0943, 0x084a, 0x0409, 0x0962, 0x0924, 0x08c6, 0x0981, 0x0889, 0x0906, 0x082b, 0x0925, 0x0944, 0x08a7, 0x08e5, 0x084b, + 0x082c, 0x0982, 0x0963, 0x086a, 0x08a9, 0x08c7, 0x0907, 0x0964, 0x040a, 0x08e6, 0x0983, 0x0540, 0x0945, 0x088a, 0x08c8, 0x084c, + 0x0926, 0x0927, 0x088b, 0x0560, 0x08c9, 0x086b, 0x08aa, 0x0908, 0x08e8, 0x0985, 0x086c, 0x0965, 0x08e7, 0x0984, 0x0966, 0x0946, + 0x088c, 0x08e9, 0x08ab, 0x040b, 0x0986, 0x08ca, 0x0580, 0x0947, 0x08ac, 0x08ea, 0x0928, 0x040c, 0x0967, 0x0909, 0x0929, 0x0948, + 0x08eb, 0x0987, 0x08cb, 0x090b, 0x0968, 0x08ec, 0x08cc, 0x090a, 0x0949, 0x090c, 0x092a, 0x092b, 0x092c, 0x094b, 0x0989, 0x094a, + 0x0969, 0x0988, 0x096a, 0x098a, 0x098b, 0x094c, 0x096b, 0x096c, 0x098c, + /* spectrum table 10 [169] (unsigned) */ + 0x0821, 0x0822, 0x0841, 0x0842, 0x0420, 0x0401, 0x0823, 0x0862, 0x0861, 0x0843, 0x0863, 0x0440, 0x0402, 0x0844, 0x0882, 0x0824, + 0x0881, 0x0000, 0x0883, 0x0864, 0x0460, 0x0403, 0x0884, 0x0845, 0x08a2, 0x0825, 0x08a1, 0x08a3, 0x0865, 0x08a4, 0x0885, 0x08c2, + 0x0846, 0x08c3, 0x0480, 0x08c1, 0x0404, 0x0826, 0x0866, 0x08a5, 0x08c4, 0x0886, 0x08c5, 0x08e2, 0x0867, 0x0847, 0x08a6, 0x0902, + 0x08e3, 0x04a0, 0x08e1, 0x0405, 0x0901, 0x0827, 0x0903, 0x08e4, 0x0887, 0x0848, 0x08c6, 0x08e5, 0x0828, 0x0868, 0x0904, 0x0888, + 0x08a7, 0x0905, 0x08a8, 0x08e6, 0x08c7, 0x0922, 0x04c0, 0x08c8, 0x0923, 0x0869, 0x0921, 0x0849, 0x0406, 0x0906, 0x0924, 0x0889, + 0x0942, 0x0829, 0x08e7, 0x0907, 0x0925, 0x08e8, 0x0943, 0x08a9, 0x0944, 0x084a, 0x0941, 0x086a, 0x0926, 0x08c9, 0x0500, 0x088a, + 0x04e0, 0x0962, 0x08e9, 0x0963, 0x0946, 0x082a, 0x0961, 0x0927, 0x0407, 0x0908, 0x0945, 0x086b, 0x08aa, 0x0909, 0x0965, 0x0408, + 0x0964, 0x084b, 0x08ea, 0x08ca, 0x0947, 0x088b, 0x082b, 0x0982, 0x0928, 0x0983, 0x0966, 0x08ab, 0x0984, 0x0967, 0x0985, 0x086c, + 0x08cb, 0x0520, 0x0948, 0x0540, 0x0981, 0x0409, 0x088c, 0x0929, 0x0986, 0x084c, 0x090a, 0x092a, 0x082c, 0x0968, 0x0987, 0x08eb, + 0x08ac, 0x08cc, 0x0949, 0x090b, 0x0988, 0x040a, 0x08ec, 0x0560, 0x094a, 0x0969, 0x096a, 0x040b, 0x096b, 0x092b, 0x094b, 0x0580, + 0x090c, 0x0989, 0x094c, 0x092c, 0x096c, 0x098b, 0x040c, 0x098a, 0x098c, + /* spectrum table 11 [289] (unsigned) */ + 0x0000, 0x2041, 0x2410, 0x1040, 0x1001, 0x2081, 0x2042, 0x2082, 0x2043, 0x20c1, 0x20c2, 0x1080, 0x2083, 0x1002, 0x20c3, 0x2101, + 0x2044, 0x2102, 0x2084, 0x2103, 0x20c4, 0x10c0, 0x1003, 0x2141, 0x2142, 0x2085, 0x2104, 0x2045, 0x2143, 0x20c5, 0x2144, 0x2105, + 0x2182, 0x2086, 0x2181, 0x2183, 0x20c6, 0x2046, 0x2110, 0x20d0, 0x2405, 0x2403, 0x2404, 0x2184, 0x2406, 0x1100, 0x2106, 0x1004, + 0x2090, 0x2145, 0x2150, 0x2407, 0x2402, 0x2408, 0x2087, 0x21c2, 0x20c7, 0x2185, 0x2146, 0x2190, 0x240a, 0x21c3, 0x21c1, 0x2409, + 0x21d0, 0x2050, 0x2047, 0x2107, 0x240b, 0x21c4, 0x240c, 0x2210, 0x2401, 0x2186, 0x2250, 0x2088, 0x2147, 0x2290, 0x240d, 0x2203, + 0x2202, 0x20c8, 0x1140, 0x240e, 0x22d0, 0x21c5, 0x2108, 0x2187, 0x21c6, 0x1005, 0x2204, 0x240f, 0x2310, 0x2048, 0x2201, 0x2390, + 0x2148, 0x2350, 0x20c9, 0x2205, 0x21c7, 0x2089, 0x2206, 0x2242, 0x2243, 0x23d0, 0x2109, 0x2188, 0x1180, 0x2244, 0x2149, 0x2207, + 0x21c8, 0x2049, 0x2283, 0x1006, 0x2282, 0x2241, 0x2245, 0x210a, 0x208a, 0x2246, 0x20ca, 0x2189, 0x2284, 0x2208, 0x2285, 0x2247, + 0x22c3, 0x204a, 0x11c0, 0x2286, 0x21c9, 0x20cb, 0x214a, 0x2281, 0x210b, 0x22c2, 0x2342, 0x218a, 0x2343, 0x208b, 0x1400, 0x214b, + 0x22c5, 0x22c4, 0x2248, 0x21ca, 0x2209, 0x1010, 0x210d, 0x1007, 0x20cd, 0x22c6, 0x2341, 0x2344, 0x2303, 0x208d, 0x2345, 0x220a, + 0x218b, 0x2288, 0x2287, 0x2382, 0x2304, 0x204b, 0x210c, 0x22c1, 0x20cc, 0x204d, 0x2302, 0x21cb, 0x20ce, 0x214c, 0x214d, 0x2384, + 0x210e, 0x22c7, 0x2383, 0x2305, 0x2346, 0x2306, 0x1200, 0x22c8, 0x208c, 0x2249, 0x2385, 0x218d, 0x228a, 0x23c2, 0x220b, 0x224a, + 0x2386, 0x2289, 0x214e, 0x22c9, 0x2381, 0x208e, 0x218c, 0x204c, 0x2348, 0x1008, 0x2347, 0x21cc, 0x2307, 0x21cd, 0x23c3, 0x2301, + 0x218e, 0x208f, 0x23c5, 0x23c4, 0x204e, 0x224b, 0x210f, 0x2387, 0x220d, 0x2349, 0x220c, 0x214f, 0x20cf, 0x228b, 0x22ca, 0x2308, + 0x23c6, 0x23c7, 0x220e, 0x23c1, 0x21ce, 0x1240, 0x1009, 0x224d, 0x224c, 0x2309, 0x2388, 0x228d, 0x2389, 0x230a, 0x218f, 0x21cf, + 0x224e, 0x23c8, 0x22cb, 0x22ce, 0x204f, 0x228c, 0x228e, 0x234b, 0x234a, 0x22cd, 0x22cc, 0x220f, 0x238b, 0x234c, 0x230d, 0x23c9, + 0x238a, 0x1280, 0x230b, 0x224f, 0x100a, 0x230c, 0x12c0, 0x230e, 0x228f, 0x234d, 0x100d, 0x238c, 0x23ca, 0x23cb, 0x22cf, 0x238d, + 0x1340, 0x100b, 0x234e, 0x23cc, 0x23cd, 0x230f, 0x1380, 0x238e, 0x234f, 0x1300, 0x238f, 0x100e, 0x100c, 0x23ce, 0x13c0, 0x100f, + 0x23cf, }; const HuffInfo huffTabScaleFactInfo PROGMEM = - {19, { 1, 0, 1, 3, 2, 4, 3, 5, 4, 6, 6, 6, 5, 8, 4, 7, 3, 7, 46, 0}, 0}; +{19, { 1, 0, 1, 3, 2, 4, 3, 5, 4, 6, 6, 6, 5, 8, 4, 7, 3, 7, 46, 0}, 0}; /* note - includes offset of -60 (4.6.2.3 in spec) */ const signed short huffTabScaleFact[121] PROGMEM = { - /* scale factor table [121] */ - 0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, 6, -6, 7, -7, 8, - -8, 9, -9, 10, -10, -11, 11, 12, -12, 13, -13, 14, -14, 16, 15, 17, - 18, -15, -17, -16, 19, -18, -19, 20, -20, 21, -21, 22, -22, 23, -23, -25, - 25, -27, -24, -26, 24, -28, 27, 29, -30, -29, 26, -31, -34, -33, -32, -36, - 28, -35, -38, -37, 30, -39, -41, -57, -59, -58, -60, 38, 39, 40, 41, 42, - 57, 37, 31, 32, 33, 34, 35, 36, 44, 51, 52, 53, 54, 55, 56, 50, - 45, 46, 47, 48, 49, 58, -54, -52, -51, -50, -55, 43, 60, 59, -56, -53, - -45, -44, -42, -40, -43, -49, -48, -46, -47, + /* scale factor table [121] */ + 0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, 6, -6, 7, -7, 8, + -8, 9, -9, 10, -10, -11, 11, 12, -12, 13, -13, 14, -14, 16, 15, 17, + 18, -15, -17, -16, 19, -18, -19, 20, -20, 21, -21, 22, -22, 23, -23, -25, + 25, -27, -24, -26, 24, -28, 27, 29, -30, -29, 26, -31, -34, -33, -32, -36, + 28, -35, -38, -37, 30, -39, -41, -57, -59, -58, -60, 38, 39, 40, 41, 42, + 57, 37, 31, 32, 33, 34, 35, 36, 44, 51, 52, 53, 54, 55, 56, 50, + 45, 46, 47, 48, 49, 58, -54, -52, -51, -50, -55, 43, 60, 59, -56, -53, + -45, -44, -42, -40, -43, -49, -48, -46, -47, }; diff --git a/src/libhelix-aac/imdct.c b/src/libhelix-aac/imdct.c index 1ff9e4ab..bb45beb0 100644 --- a/src/libhelix-aac/imdct.c +++ b/src/libhelix-aac/imdct.c @@ -1,46 +1,46 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: imdct.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: imdct.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * imdct.c - inverse MDCT + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + imdct.c - inverse MDCT **************************************************************************************/ #include "coder.h" @@ -51,539 +51,538 @@ #ifndef AAC_ENABLE_SBR /************************************************************************************** - * Function: DecWindowOverlap - * - * Description: apply synthesis window, do overlap-add, clip to 16-bit PCM, - * for winSequence LONG-LONG - * - * Inputs: input buffer (output of type-IV DCT) - * overlap buffer (saved from last time) - * number of channels - * window type (sin or KBD) for input buffer - * window type (sin or KBD) for overlap buffer - * - * Outputs: one channel, one frame of 16-bit PCM, interleaved by nChans - * - * Return: none - * - * Notes: this processes one channel at a time, but skips every other sample in - * the output buffer (pcm) for stereo interleaving - * this should fit in registers on ARM - * - * TODO: ARM5E version with saturating overlap/add (QADD) - * asm code with free pointer updates, better load scheduling + Function: DecWindowOverlap + + Description: apply synthesis window, do overlap-add, clip to 16-bit PCM, + for winSequence LONG-LONG + + Inputs: input buffer (output of type-IV DCT) + overlap buffer (saved from last time) + number of channels + window type (sin or KBD) for input buffer + window type (sin or KBD) for overlap buffer + + Outputs: one channel, one frame of 16-bit PCM, interleaved by nChans + + Return: none + + Notes: this processes one channel at a time, but skips every other sample in + the output buffer (pcm) for stereo interleaving + this should fit in registers on ARM + + TODO: ARM5E version with saturating overlap/add (QADD) + asm code with free pointer updates, better load scheduling **************************************************************************************/ -/*__attribute__ ((section (".data")))*/ static void DecWindowOverlap(int *buf0, int *over0, short *pcm0, int nChans, int winTypeCurr, int winTypePrev) -{ - int in, w0, w1, f0, f1; - int *buf1, *over1; - short *pcm1; - const int *wndPrev, *wndCurr; - - buf0 += (1024 >> 1); - buf1 = buf0 - 1; - pcm1 = pcm0 + (1024 - 1) * nChans; - over1 = over0 + 1024 - 1; - - wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]); - if (winTypeCurr == winTypePrev) { - /* cut window loads in half since current and overlap sections use same symmetric window */ - do { - w0 = *wndPrev++; - w1 = *wndPrev++; - in = *buf0++; - - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); - - in = *over0; - *pcm0 = CLIPTOSHORT( (in - f0 + RND_VAL) >> FBITS_OUT_IMDCT ); - pcm0 += nChans; - - in = *over1; - *pcm1 = CLIPTOSHORT( (in + f1 + RND_VAL) >> FBITS_OUT_IMDCT ); - pcm1 -= nChans; - - in = *buf1--; - *over1-- = MULSHIFT32(w0, in); - *over0++ = MULSHIFT32(w1, in); - } while (over0 < over1); - } else { - /* different windows for current and overlap parts - should still fit in registers on ARM w/o stack spill */ - wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]); - do { - w0 = *wndPrev++; - w1 = *wndPrev++; - in = *buf0++; - - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); - - in = *over0; - *pcm0 = CLIPTOSHORT( (in - f0 + RND_VAL) >> FBITS_OUT_IMDCT ); - pcm0 += nChans; - - in = *over1; - *pcm1 = CLIPTOSHORT( (in + f1 + RND_VAL) >> FBITS_OUT_IMDCT ); - pcm1 -= nChans; - - w0 = *wndCurr++; - w1 = *wndCurr++; - in = *buf1--; - - *over1-- = MULSHIFT32(w0, in); - *over0++ = MULSHIFT32(w1, in); - } while (over0 < over1); - } +/*__attribute__ ((section (".data")))*/ static void DecWindowOverlap(int *buf0, int *over0, short *pcm0, int nChans, int winTypeCurr, int winTypePrev) { + int in, w0, w1, f0, f1; + int *buf1, *over1; + short *pcm1; + const int *wndPrev, *wndCurr; + + buf0 += (1024 >> 1); + buf1 = buf0 - 1; + pcm1 = pcm0 + (1024 - 1) * nChans; + over1 = over0 + 1024 - 1; + + wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]); + if (winTypeCurr == winTypePrev) { + /* cut window loads in half since current and overlap sections use same symmetric window */ + do { + w0 = *wndPrev++; + w1 = *wndPrev++; + in = *buf0++; + + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); + + in = *over0; + *pcm0 = CLIPTOSHORT((in - f0 + RND_VAL) >> FBITS_OUT_IMDCT); + pcm0 += nChans; + + in = *over1; + *pcm1 = CLIPTOSHORT((in + f1 + RND_VAL) >> FBITS_OUT_IMDCT); + pcm1 -= nChans; + + in = *buf1--; + *over1-- = MULSHIFT32(w0, in); + *over0++ = MULSHIFT32(w1, in); + } while (over0 < over1); + } else { + /* different windows for current and overlap parts - should still fit in registers on ARM w/o stack spill */ + wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]); + do { + w0 = *wndPrev++; + w1 = *wndPrev++; + in = *buf0++; + + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); + + in = *over0; + *pcm0 = CLIPTOSHORT((in - f0 + RND_VAL) >> FBITS_OUT_IMDCT); + pcm0 += nChans; + + in = *over1; + *pcm1 = CLIPTOSHORT((in + f1 + RND_VAL) >> FBITS_OUT_IMDCT); + pcm1 -= nChans; + + w0 = *wndCurr++; + w1 = *wndCurr++; + in = *buf1--; + + *over1-- = MULSHIFT32(w0, in); + *over0++ = MULSHIFT32(w1, in); + } while (over0 < over1); + } } /************************************************************************************** - * Function: DecWindowOverlapLongStart - * - * Description: apply synthesis window, do overlap-add, clip to 16-bit PCM, - * for winSequence LONG-START - * - * Inputs: input buffer (output of type-IV DCT) - * overlap buffer (saved from last time) - * number of channels - * window type (sin or KBD) for input buffer - * window type (sin or KBD) for overlap buffer - * - * Outputs: one channel, one frame of 16-bit PCM, interleaved by nChans - * - * Return: none - * - * Notes: this processes one channel at a time, but skips every other sample in - * the output buffer (pcm) for stereo interleaving - * this should fit in registers on ARM - * - * TODO: ARM5E version with saturating overlap/add (QADD) - * asm code with free pointer updates, better load scheduling + Function: DecWindowOverlapLongStart + + Description: apply synthesis window, do overlap-add, clip to 16-bit PCM, + for winSequence LONG-START + + Inputs: input buffer (output of type-IV DCT) + overlap buffer (saved from last time) + number of channels + window type (sin or KBD) for input buffer + window type (sin or KBD) for overlap buffer + + Outputs: one channel, one frame of 16-bit PCM, interleaved by nChans + + Return: none + + Notes: this processes one channel at a time, but skips every other sample in + the output buffer (pcm) for stereo interleaving + this should fit in registers on ARM + + TODO: ARM5E version with saturating overlap/add (QADD) + asm code with free pointer updates, better load scheduling **************************************************************************************/ - /*__attribute__ ((section (".data")))*/ static void DecWindowOverlapLongStart(int *buf0, int *over0, short *pcm0, int nChans, int winTypeCurr, int winTypePrev) -{ - int i, in, w0, w1, f0, f1; - int *buf1, *over1; - short *pcm1; - const int *wndPrev, *wndCurr; - - buf0 += (1024 >> 1); - buf1 = buf0 - 1; - pcm1 = pcm0 + (1024 - 1) * nChans; - over1 = over0 + 1024 - 1; - - wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]); - i = 448; /* 2 outputs, 2 overlaps per loop */ - do { - w0 = *wndPrev++; - w1 = *wndPrev++; - in = *buf0++; - - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); - - in = *over0; - *pcm0 = CLIPTOSHORT( (in - f0 + RND_VAL) >> FBITS_OUT_IMDCT ); - pcm0 += nChans; - - in = *over1; - *pcm1 = CLIPTOSHORT( (in + f1 + RND_VAL) >> FBITS_OUT_IMDCT ); - pcm1 -= nChans; - - in = *buf1--; - - *over1-- = 0; /* Wn = 0 for n = (2047, 2046, ... 1600) */ - *over0++ = in >> 1; /* Wn = 1 for n = (1024, 1025, ... 1471) */ - } while (--i); - - wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]); - - /* do 64 more loops - 2 outputs, 2 overlaps per loop */ - do { - w0 = *wndPrev++; - w1 = *wndPrev++; - in = *buf0++; - - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); - - in = *over0; - *pcm0 = CLIPTOSHORT( (in - f0 + RND_VAL) >> FBITS_OUT_IMDCT ); - pcm0 += nChans; - - in = *over1; - *pcm1 = CLIPTOSHORT( (in + f1 + RND_VAL) >> FBITS_OUT_IMDCT ); - pcm1 -= nChans; - - w0 = *wndCurr++; /* W[0], W[1], ... --> W[255], W[254], ... */ - w1 = *wndCurr++; /* W[127], W[126], ... --> W[128], W[129], ... */ - in = *buf1--; - - *over1-- = MULSHIFT32(w0, in); /* Wn = short window for n = (1599, 1598, ... , 1536) */ - *over0++ = MULSHIFT32(w1, in); /* Wn = short window for n = (1472, 1473, ... , 1535) */ - } while (over0 < over1); +/*__attribute__ ((section (".data")))*/ static void DecWindowOverlapLongStart(int *buf0, int *over0, short *pcm0, int nChans, int winTypeCurr, int winTypePrev) { + int i, in, w0, w1, f0, f1; + int *buf1, *over1; + short *pcm1; + const int *wndPrev, *wndCurr; + + buf0 += (1024 >> 1); + buf1 = buf0 - 1; + pcm1 = pcm0 + (1024 - 1) * nChans; + over1 = over0 + 1024 - 1; + + wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]); + i = 448; /* 2 outputs, 2 overlaps per loop */ + do { + w0 = *wndPrev++; + w1 = *wndPrev++; + in = *buf0++; + + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); + + in = *over0; + *pcm0 = CLIPTOSHORT((in - f0 + RND_VAL) >> FBITS_OUT_IMDCT); + pcm0 += nChans; + + in = *over1; + *pcm1 = CLIPTOSHORT((in + f1 + RND_VAL) >> FBITS_OUT_IMDCT); + pcm1 -= nChans; + + in = *buf1--; + + *over1-- = 0; /* Wn = 0 for n = (2047, 2046, ... 1600) */ + *over0++ = in >> 1; /* Wn = 1 for n = (1024, 1025, ... 1471) */ + } while (--i); + + wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]); + + /* do 64 more loops - 2 outputs, 2 overlaps per loop */ + do { + w0 = *wndPrev++; + w1 = *wndPrev++; + in = *buf0++; + + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); + + in = *over0; + *pcm0 = CLIPTOSHORT((in - f0 + RND_VAL) >> FBITS_OUT_IMDCT); + pcm0 += nChans; + + in = *over1; + *pcm1 = CLIPTOSHORT((in + f1 + RND_VAL) >> FBITS_OUT_IMDCT); + pcm1 -= nChans; + + w0 = *wndCurr++; /* W[0], W[1], ... --> W[255], W[254], ... */ + w1 = *wndCurr++; /* W[127], W[126], ... --> W[128], W[129], ... */ + in = *buf1--; + + *over1-- = MULSHIFT32(w0, in); /* Wn = short window for n = (1599, 1598, ... , 1536) */ + *over0++ = MULSHIFT32(w1, in); /* Wn = short window for n = (1472, 1473, ... , 1535) */ + } while (over0 < over1); } /************************************************************************************** - * Function: DecWindowOverlapLongStop - * - * Description: apply synthesis window, do overlap-add, clip to 16-bit PCM, - * for winSequence LONG-STOP - * - * Inputs: input buffer (output of type-IV DCT) - * overlap buffer (saved from last time) - * number of channels - * window type (sin or KBD) for input buffer - * window type (sin or KBD) for overlap buffer - * - * Outputs: one channel, one frame of 16-bit PCM, interleaved by nChans - * - * Return: none - * - * Notes: this processes one channel at a time, but skips every other sample in - * the output buffer (pcm) for stereo interleaving - * this should fit in registers on ARM - * - * TODO: ARM5E version with saturating overlap/add (QADD) - * asm code with free pointer updates, better load scheduling + Function: DecWindowOverlapLongStop + + Description: apply synthesis window, do overlap-add, clip to 16-bit PCM, + for winSequence LONG-STOP + + Inputs: input buffer (output of type-IV DCT) + overlap buffer (saved from last time) + number of channels + window type (sin or KBD) for input buffer + window type (sin or KBD) for overlap buffer + + Outputs: one channel, one frame of 16-bit PCM, interleaved by nChans + + Return: none + + Notes: this processes one channel at a time, but skips every other sample in + the output buffer (pcm) for stereo interleaving + this should fit in registers on ARM + + TODO: ARM5E version with saturating overlap/add (QADD) + asm code with free pointer updates, better load scheduling **************************************************************************************/ - /*__attribute__ ((section (".data")))*/ static void DecWindowOverlapLongStop(int *buf0, int *over0, short *pcm0, int nChans, int winTypeCurr, int winTypePrev) -{ - int i, in, w0, w1, f0, f1; - int *buf1, *over1; - short *pcm1; - const int *wndPrev, *wndCurr; - - buf0 += (1024 >> 1); - buf1 = buf0 - 1; - pcm1 = pcm0 + (1024 - 1) * nChans; - over1 = over0 + 1024 - 1; - - wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]); - wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]); - - i = 448; /* 2 outputs, 2 overlaps per loop */ - do { - /* Wn = 0 for n = (0, 1, ... 447) */ - /* Wn = 1 for n = (576, 577, ... 1023) */ - in = *buf0++; - f1 = in >> 1; /* scale since skipping multiply by Q31 */ - - in = *over0; - *pcm0 = CLIPTOSHORT( (in + RND_VAL) >> FBITS_OUT_IMDCT ); - pcm0 += nChans; - - in = *over1; - *pcm1 = CLIPTOSHORT( (in + f1 + RND_VAL) >> FBITS_OUT_IMDCT ); - pcm1 -= nChans; - - w0 = *wndCurr++; - w1 = *wndCurr++; - in = *buf1--; - - *over1-- = MULSHIFT32(w0, in); - *over0++ = MULSHIFT32(w1, in); - } while (--i); - - /* do 64 more loops - 2 outputs, 2 overlaps per loop */ - do { - w0 = *wndPrev++; /* W[0], W[1], ...W[63] */ - w1 = *wndPrev++; /* W[127], W[126], ... W[64] */ - in = *buf0++; - - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); - - in = *over0; - *pcm0 = CLIPTOSHORT( (in - f0 + RND_VAL) >> FBITS_OUT_IMDCT ); - pcm0 += nChans; - - in = *over1; - *pcm1 = CLIPTOSHORT( (in + f1 + RND_VAL) >> FBITS_OUT_IMDCT ); - pcm1 -= nChans; - - w0 = *wndCurr++; - w1 = *wndCurr++; - in = *buf1--; - - *over1-- = MULSHIFT32(w0, in); - *over0++ = MULSHIFT32(w1, in); - } while (over0 < over1); +/*__attribute__ ((section (".data")))*/ static void DecWindowOverlapLongStop(int *buf0, int *over0, short *pcm0, int nChans, int winTypeCurr, int winTypePrev) { + int i, in, w0, w1, f0, f1; + int *buf1, *over1; + short *pcm1; + const int *wndPrev, *wndCurr; + + buf0 += (1024 >> 1); + buf1 = buf0 - 1; + pcm1 = pcm0 + (1024 - 1) * nChans; + over1 = over0 + 1024 - 1; + + wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]); + wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]); + + i = 448; /* 2 outputs, 2 overlaps per loop */ + do { + /* Wn = 0 for n = (0, 1, ... 447) */ + /* Wn = 1 for n = (576, 577, ... 1023) */ + in = *buf0++; + f1 = in >> 1; /* scale since skipping multiply by Q31 */ + + in = *over0; + *pcm0 = CLIPTOSHORT((in + RND_VAL) >> FBITS_OUT_IMDCT); + pcm0 += nChans; + + in = *over1; + *pcm1 = CLIPTOSHORT((in + f1 + RND_VAL) >> FBITS_OUT_IMDCT); + pcm1 -= nChans; + + w0 = *wndCurr++; + w1 = *wndCurr++; + in = *buf1--; + + *over1-- = MULSHIFT32(w0, in); + *over0++ = MULSHIFT32(w1, in); + } while (--i); + + /* do 64 more loops - 2 outputs, 2 overlaps per loop */ + do { + w0 = *wndPrev++; /* W[0], W[1], ...W[63] */ + w1 = *wndPrev++; /* W[127], W[126], ... W[64] */ + in = *buf0++; + + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); + + in = *over0; + *pcm0 = CLIPTOSHORT((in - f0 + RND_VAL) >> FBITS_OUT_IMDCT); + pcm0 += nChans; + + in = *over1; + *pcm1 = CLIPTOSHORT((in + f1 + RND_VAL) >> FBITS_OUT_IMDCT); + pcm1 -= nChans; + + w0 = *wndCurr++; + w1 = *wndCurr++; + in = *buf1--; + + *over1-- = MULSHIFT32(w0, in); + *over0++ = MULSHIFT32(w1, in); + } while (over0 < over1); } /************************************************************************************** - * Function: DecWindowOverlapShort - * - * Description: apply synthesis window, do overlap-add, clip to 16-bit PCM, - * for winSequence EIGHT-SHORT (does all 8 short blocks) - * - * Inputs: input buffer (output of type-IV DCT) - * overlap buffer (saved from last time) - * number of channels - * window type (sin or KBD) for input buffer - * window type (sin or KBD) for overlap buffer - * - * Outputs: one channel, one frame of 16-bit PCM, interleaved by nChans - * - * Return: none - * - * Notes: this processes one channel at a time, but skips every other sample in - * the output buffer (pcm) for stereo interleaving - * this should fit in registers on ARM - * - * TODO: ARM5E version with saturating overlap/add (QADD) - * asm code with free pointer updates, better load scheduling + Function: DecWindowOverlapShort + + Description: apply synthesis window, do overlap-add, clip to 16-bit PCM, + for winSequence EIGHT-SHORT (does all 8 short blocks) + + Inputs: input buffer (output of type-IV DCT) + overlap buffer (saved from last time) + number of channels + window type (sin or KBD) for input buffer + window type (sin or KBD) for overlap buffer + + Outputs: one channel, one frame of 16-bit PCM, interleaved by nChans + + Return: none + + Notes: this processes one channel at a time, but skips every other sample in + the output buffer (pcm) for stereo interleaving + this should fit in registers on ARM + + TODO: ARM5E version with saturating overlap/add (QADD) + asm code with free pointer updates, better load scheduling **************************************************************************************/ - /*__attribute__ ((section (".data"))) */ static void DecWindowOverlapShort(int *buf0, int *over0, short *pcm0, int nChans, int winTypeCurr, int winTypePrev) -{ - int i, in, w0, w1, f0, f1; - int *buf1, *over1; - short *pcm1; - const int *wndPrev, *wndCurr; - - wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]); - wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]); - - /* pcm[0-447] = 0 + overlap[0-447] */ - i = 448; - do { - f0 = *over0++; - f1 = *over0++; - *pcm0 = CLIPTOSHORT( (f0 + RND_VAL) >> FBITS_OUT_IMDCT ); pcm0 += nChans; - *pcm0 = CLIPTOSHORT( (f1 + RND_VAL) >> FBITS_OUT_IMDCT ); pcm0 += nChans; - i -= 2; - } while (i); - - /* pcm[448-575] = Wp[0-127] * block0[0-127] + overlap[448-575] */ - pcm1 = pcm0 + (128 - 1) * nChans; - over1 = over0 + 128 - 1; - buf0 += 64; - buf1 = buf0 - 1; - do { - w0 = *wndPrev++; /* W[0], W[1], ...W[63] */ - w1 = *wndPrev++; /* W[127], W[126], ... W[64] */ - in = *buf0++; - - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); - - in = *over0; - *pcm0 = CLIPTOSHORT( (in - f0 + RND_VAL) >> FBITS_OUT_IMDCT ); - pcm0 += nChans; - - in = *over1; - *pcm1 = CLIPTOSHORT( (in + f1 + RND_VAL) >> FBITS_OUT_IMDCT ); - pcm1 -= nChans; - - w0 = *wndCurr++; - w1 = *wndCurr++; - in = *buf1--; - - /* save over0/over1 for next short block, in the slots just vacated */ - *over1-- = MULSHIFT32(w0, in); - *over0++ = MULSHIFT32(w1, in); - } while (over0 < over1); - - /* pcm[576-703] = Wc[128-255] * block0[128-255] + Wc[0-127] * block1[0-127] + overlap[576-703] - * pcm[704-831] = Wc[128-255] * block1[128-255] + Wc[0-127] * block2[0-127] + overlap[704-831] - * pcm[832-959] = Wc[128-255] * block2[128-255] + Wc[0-127] * block3[0-127] + overlap[832-959] - */ - for (i = 0; i < 3; i++) { - pcm0 += 64 * nChans; - pcm1 = pcm0 + (128 - 1) * nChans; - over0 += 64; - over1 = over0 + 128 - 1; - buf0 += 64; - buf1 = buf0 - 1; - wndCurr -= 128; - - do { - w0 = *wndCurr++; /* W[0], W[1], ...W[63] */ - w1 = *wndCurr++; /* W[127], W[126], ... W[64] */ - in = *buf0++; - - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); - - in = *(over0 - 128); /* from last short block */ - in += *(over0 + 0); /* from last full frame */ - *pcm0 = CLIPTOSHORT( (in - f0 + RND_VAL) >> FBITS_OUT_IMDCT ); - pcm0 += nChans; - - in = *(over1 - 128); /* from last short block */ - in += *(over1 + 0); /* from last full frame */ - *pcm1 = CLIPTOSHORT( (in + f1 + RND_VAL) >> FBITS_OUT_IMDCT ); - pcm1 -= nChans; - - /* save over0/over1 for next short block, in the slots just vacated */ - in = *buf1--; - *over1-- = MULSHIFT32(w0, in); - *over0++ = MULSHIFT32(w1, in); - } while (over0 < over1); - } - - /* pcm[960-1023] = Wc[128-191] * block3[128-191] + Wc[0-63] * block4[0-63] + overlap[960-1023] - * over[0-63] = Wc[192-255] * block3[192-255] + Wc[64-127] * block4[64-127] - */ - pcm0 += 64 * nChans; - over0 -= 832; /* points at overlap[64] */ - over1 = over0 + 128 - 1; /* points at overlap[191] */ - buf0 += 64; - buf1 = buf0 - 1; - wndCurr -= 128; - do { - w0 = *wndCurr++; /* W[0], W[1], ...W[63] */ - w1 = *wndCurr++; /* W[127], W[126], ... W[64] */ - in = *buf0++; - - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); - - in = *(over0 + 768); /* from last short block */ - in += *(over0 + 896); /* from last full frame */ - *pcm0 = CLIPTOSHORT( (in - f0 + RND_VAL) >> FBITS_OUT_IMDCT ); - pcm0 += nChans; - - in = *(over1 + 768); /* from last short block */ - *(over1 - 128) = in + f1; - - in = *buf1--; - *over1-- = MULSHIFT32(w0, in); /* save in overlap[128-191] */ - *over0++ = MULSHIFT32(w1, in); /* save in overlap[64-127] */ - } while (over0 < over1); - - /* over0 now points at overlap[128] */ - - /* over[64-191] = Wc[128-255] * block4[128-255] + Wc[0-127] * block5[0-127] - * over[192-319] = Wc[128-255] * block5[128-255] + Wc[0-127] * block6[0-127] - * over[320-447] = Wc[128-255] * block6[128-255] + Wc[0-127] * block7[0-127] - * over[448-576] = Wc[128-255] * block7[128-255] - */ - for (i = 0; i < 3; i++) { - over0 += 64; - over1 = over0 + 128 - 1; - buf0 += 64; - buf1 = buf0 - 1; - wndCurr -= 128; - do { - w0 = *wndCurr++; /* W[0], W[1], ...W[63] */ - w1 = *wndCurr++; /* W[127], W[126], ... W[64] */ - in = *buf0++; - - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); - - /* from last short block */ - *(over0 - 128) -= f0; - *(over1 - 128)+= f1; - - in = *buf1--; - *over1-- = MULSHIFT32(w0, in); - *over0++ = MULSHIFT32(w1, in); - } while (over0 < over1); - } - - /* over[576-1024] = 0 */ - i = 448; - over0 += 64; - do { - *over0++ = 0; - *over0++ = 0; - *over0++ = 0; - *over0++ = 0; - i -= 4; - } while (i); +/*__attribute__ ((section (".data"))) */ static void DecWindowOverlapShort(int *buf0, int *over0, short *pcm0, int nChans, int winTypeCurr, int winTypePrev) { + int i, in, w0, w1, f0, f1; + int *buf1, *over1; + short *pcm1; + const int *wndPrev, *wndCurr; + + wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]); + wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]); + + /* pcm[0-447] = 0 + overlap[0-447] */ + i = 448; + do { + f0 = *over0++; + f1 = *over0++; + *pcm0 = CLIPTOSHORT((f0 + RND_VAL) >> FBITS_OUT_IMDCT); pcm0 += nChans; + *pcm0 = CLIPTOSHORT((f1 + RND_VAL) >> FBITS_OUT_IMDCT); pcm0 += nChans; + i -= 2; + } while (i); + + /* pcm[448-575] = Wp[0-127] * block0[0-127] + overlap[448-575] */ + pcm1 = pcm0 + (128 - 1) * nChans; + over1 = over0 + 128 - 1; + buf0 += 64; + buf1 = buf0 - 1; + do { + w0 = *wndPrev++; /* W[0], W[1], ...W[63] */ + w1 = *wndPrev++; /* W[127], W[126], ... W[64] */ + in = *buf0++; + + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); + + in = *over0; + *pcm0 = CLIPTOSHORT((in - f0 + RND_VAL) >> FBITS_OUT_IMDCT); + pcm0 += nChans; + + in = *over1; + *pcm1 = CLIPTOSHORT((in + f1 + RND_VAL) >> FBITS_OUT_IMDCT); + pcm1 -= nChans; + + w0 = *wndCurr++; + w1 = *wndCurr++; + in = *buf1--; + + /* save over0/over1 for next short block, in the slots just vacated */ + *over1-- = MULSHIFT32(w0, in); + *over0++ = MULSHIFT32(w1, in); + } while (over0 < over1); + + /* pcm[576-703] = Wc[128-255] * block0[128-255] + Wc[0-127] * block1[0-127] + overlap[576-703] + pcm[704-831] = Wc[128-255] * block1[128-255] + Wc[0-127] * block2[0-127] + overlap[704-831] + pcm[832-959] = Wc[128-255] * block2[128-255] + Wc[0-127] * block3[0-127] + overlap[832-959] + */ + for (i = 0; i < 3; i++) { + pcm0 += 64 * nChans; + pcm1 = pcm0 + (128 - 1) * nChans; + over0 += 64; + over1 = over0 + 128 - 1; + buf0 += 64; + buf1 = buf0 - 1; + wndCurr -= 128; + + do { + w0 = *wndCurr++; /* W[0], W[1], ...W[63] */ + w1 = *wndCurr++; /* W[127], W[126], ... W[64] */ + in = *buf0++; + + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); + + in = *(over0 - 128); /* from last short block */ + in += *(over0 + 0); /* from last full frame */ + *pcm0 = CLIPTOSHORT((in - f0 + RND_VAL) >> FBITS_OUT_IMDCT); + pcm0 += nChans; + + in = *(over1 - 128); /* from last short block */ + in += *(over1 + 0); /* from last full frame */ + *pcm1 = CLIPTOSHORT((in + f1 + RND_VAL) >> FBITS_OUT_IMDCT); + pcm1 -= nChans; + + /* save over0/over1 for next short block, in the slots just vacated */ + in = *buf1--; + *over1-- = MULSHIFT32(w0, in); + *over0++ = MULSHIFT32(w1, in); + } while (over0 < over1); + } + + /* pcm[960-1023] = Wc[128-191] * block3[128-191] + Wc[0-63] * block4[0-63] + overlap[960-1023] + over[0-63] = Wc[192-255] * block3[192-255] + Wc[64-127] * block4[64-127] + */ + pcm0 += 64 * nChans; + over0 -= 832; /* points at overlap[64] */ + over1 = over0 + 128 - 1; /* points at overlap[191] */ + buf0 += 64; + buf1 = buf0 - 1; + wndCurr -= 128; + do { + w0 = *wndCurr++; /* W[0], W[1], ...W[63] */ + w1 = *wndCurr++; /* W[127], W[126], ... W[64] */ + in = *buf0++; + + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); + + in = *(over0 + 768); /* from last short block */ + in += *(over0 + 896); /* from last full frame */ + *pcm0 = CLIPTOSHORT((in - f0 + RND_VAL) >> FBITS_OUT_IMDCT); + pcm0 += nChans; + + in = *(over1 + 768); /* from last short block */ + *(over1 - 128) = in + f1; + + in = *buf1--; + *over1-- = MULSHIFT32(w0, in); /* save in overlap[128-191] */ + *over0++ = MULSHIFT32(w1, in); /* save in overlap[64-127] */ + } while (over0 < over1); + + /* over0 now points at overlap[128] */ + + /* over[64-191] = Wc[128-255] * block4[128-255] + Wc[0-127] * block5[0-127] + over[192-319] = Wc[128-255] * block5[128-255] + Wc[0-127] * block6[0-127] + over[320-447] = Wc[128-255] * block6[128-255] + Wc[0-127] * block7[0-127] + over[448-576] = Wc[128-255] * block7[128-255] + */ + for (i = 0; i < 3; i++) { + over0 += 64; + over1 = over0 + 128 - 1; + buf0 += 64; + buf1 = buf0 - 1; + wndCurr -= 128; + do { + w0 = *wndCurr++; /* W[0], W[1], ...W[63] */ + w1 = *wndCurr++; /* W[127], W[126], ... W[64] */ + in = *buf0++; + + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); + + /* from last short block */ + *(over0 - 128) -= f0; + *(over1 - 128) += f1; + + in = *buf1--; + *over1-- = MULSHIFT32(w0, in); + *over0++ = MULSHIFT32(w1, in); + } while (over0 < over1); + } + + /* over[576-1024] = 0 */ + i = 448; + over0 += 64; + do { + *over0++ = 0; + *over0++ = 0; + *over0++ = 0; + *over0++ = 0; + i -= 4; + } while (i); } #endif /* !AAC_ENABLE_SBR */ /************************************************************************************** - * Function: IMDCT - * - * Description: inverse transform and convert to 16-bit PCM - * - * Inputs: valid AACDecInfo struct - * index of current channel (0 for SCE/LFE, 0 or 1 for CPE) - * output channel (range = [0, nChans-1]) - * - * Outputs: complete frame of decoded PCM, after inverse transform - * - * Return: 0 if successful, -1 if error - * - * Notes: If AAC_ENABLE_SBR is defined at compile time then window + overlap - * does NOT clip to 16-bit PCM and does NOT interleave channels - * If AAC_ENABLE_SBR is NOT defined at compile time, then window + overlap - * does clip to 16-bit PCM and interleaves channels - * If SBR is enabled at compile time, but we don't know whether it is - * actually used for this frame (e.g. the first frame of a stream), - * we need to produce both clipped 16-bit PCM in outbuf AND - * unclipped 32-bit PCM in the SBR input buffer. In this case we make - * a separate pass over the 32-bit PCM to produce 16-bit PCM output. - * This inflicts a slight performance hit when decoding non-SBR files. + Function: IMDCT + + Description: inverse transform and convert to 16-bit PCM + + Inputs: valid AACDecInfo struct + index of current channel (0 for SCE/LFE, 0 or 1 for CPE) + output channel (range = [0, nChans-1]) + + Outputs: complete frame of decoded PCM, after inverse transform + + Return: 0 if successful, -1 if error + + Notes: If AAC_ENABLE_SBR is defined at compile time then window + overlap + does NOT clip to 16-bit PCM and does NOT interleave channels + If AAC_ENABLE_SBR is NOT defined at compile time, then window + overlap + does clip to 16-bit PCM and interleaves channels + If SBR is enabled at compile time, but we don't know whether it is + actually used for this frame (e.g. the first frame of a stream), + we need to produce both clipped 16-bit PCM in outbuf AND + unclipped 32-bit PCM in the SBR input buffer. In this case we make + a separate pass over the 32-bit PCM to produce 16-bit PCM output. + This inflicts a slight performance hit when decoding non-SBR files. **************************************************************************************/ -int IMDCT(AACDecInfo *aacDecInfo, int ch, int chOut, short *outbuf) -{ - int i; - PSInfoBase *psi; - ICSInfo *icsInfo; - - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return -1; - psi = (PSInfoBase *)(aacDecInfo->psInfoBase); - icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]); - outbuf += chOut; - - /* optimized type-IV DCT (operates inplace) */ - if (icsInfo->winSequence == 2) { - /* 8 short blocks */ - for (i = 0; i < 8; i++) - DCT4(0, psi->coef[ch] + i*128, psi->gbCurrent[ch]); - } else { - /* 1 long block */ - DCT4(1, psi->coef[ch], psi->gbCurrent[ch]); - } +int IMDCT(AACDecInfo *aacDecInfo, int ch, int chOut, short *outbuf) { + int i; + PSInfoBase *psi; + ICSInfo *icsInfo; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return -1; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]); + outbuf += chOut; + + /* optimized type-IV DCT (operates inplace) */ + if (icsInfo->winSequence == 2) { + /* 8 short blocks */ + for (i = 0; i < 8; i++) { + DCT4(0, psi->coef[ch] + i * 128, psi->gbCurrent[ch]); + } + } else { + /* 1 long block */ + DCT4(1, psi->coef[ch], psi->gbCurrent[ch]); + } #ifdef AAC_ENABLE_SBR - /* window, overlap-add, don't clip to short (send to SBR decoder) - * store the decoded 32-bit samples in top half (second AAC_MAX_NSAMPS samples) of coef buffer - */ - if (icsInfo->winSequence == 0) - DecWindowOverlapNoClip(psi->coef[ch], psi->overlap[chOut], psi->sbrWorkBuf[ch], icsInfo->winShape, psi->prevWinShape[chOut]); - else if (icsInfo->winSequence == 1) - DecWindowOverlapLongStartNoClip(psi->coef[ch], psi->overlap[chOut], psi->sbrWorkBuf[ch], icsInfo->winShape, psi->prevWinShape[chOut]); - else if (icsInfo->winSequence == 2) - DecWindowOverlapShortNoClip(psi->coef[ch], psi->overlap[chOut], psi->sbrWorkBuf[ch], icsInfo->winShape, psi->prevWinShape[chOut]); - else if (icsInfo->winSequence == 3) - DecWindowOverlapLongStopNoClip(psi->coef[ch], psi->overlap[chOut], psi->sbrWorkBuf[ch], icsInfo->winShape, psi->prevWinShape[chOut]); - - if (!aacDecInfo->sbrEnabled) { - for (i = 0; i < AAC_MAX_NSAMPS; i++) { - *outbuf = CLIPTOSHORT((psi->sbrWorkBuf[ch][i] + RND_VAL) >> FBITS_OUT_IMDCT); - outbuf += aacDecInfo->nChans; - } - } - - aacDecInfo->rawSampleBuf[ch] = psi->sbrWorkBuf[ch]; - aacDecInfo->rawSampleBytes = sizeof(int); - aacDecInfo->rawSampleFBits = FBITS_OUT_IMDCT; + /* window, overlap-add, don't clip to short (send to SBR decoder) + store the decoded 32-bit samples in top half (second AAC_MAX_NSAMPS samples) of coef buffer + */ + if (icsInfo->winSequence == 0) { + DecWindowOverlapNoClip(psi->coef[ch], psi->overlap[chOut], psi->sbrWorkBuf[ch], icsInfo->winShape, psi->prevWinShape[chOut]); + } else if (icsInfo->winSequence == 1) { + DecWindowOverlapLongStartNoClip(psi->coef[ch], psi->overlap[chOut], psi->sbrWorkBuf[ch], icsInfo->winShape, psi->prevWinShape[chOut]); + } else if (icsInfo->winSequence == 2) { + DecWindowOverlapShortNoClip(psi->coef[ch], psi->overlap[chOut], psi->sbrWorkBuf[ch], icsInfo->winShape, psi->prevWinShape[chOut]); + } else if (icsInfo->winSequence == 3) { + DecWindowOverlapLongStopNoClip(psi->coef[ch], psi->overlap[chOut], psi->sbrWorkBuf[ch], icsInfo->winShape, psi->prevWinShape[chOut]); + } + + if (!aacDecInfo->sbrEnabled) { + for (i = 0; i < AAC_MAX_NSAMPS; i++) { + *outbuf = CLIPTOSHORT((psi->sbrWorkBuf[ch][i] + RND_VAL) >> FBITS_OUT_IMDCT); + outbuf += aacDecInfo->nChans; + } + } + + aacDecInfo->rawSampleBuf[ch] = psi->sbrWorkBuf[ch]; + aacDecInfo->rawSampleBytes = sizeof(int); + aacDecInfo->rawSampleFBits = FBITS_OUT_IMDCT; #else - /* window, overlap-add, round to PCM - optimized for each window sequence */ - if (icsInfo->winSequence == 0) - DecWindowOverlap(psi->coef[ch], psi->overlap[chOut], outbuf, aacDecInfo->nChans, icsInfo->winShape, psi->prevWinShape[chOut]); - else if (icsInfo->winSequence == 1) - DecWindowOverlapLongStart(psi->coef[ch], psi->overlap[chOut], outbuf, aacDecInfo->nChans, icsInfo->winShape, psi->prevWinShape[chOut]); - else if (icsInfo->winSequence == 2) - DecWindowOverlapShort(psi->coef[ch], psi->overlap[chOut], outbuf, aacDecInfo->nChans, icsInfo->winShape, psi->prevWinShape[chOut]); - else if (icsInfo->winSequence == 3) - DecWindowOverlapLongStop(psi->coef[ch], psi->overlap[chOut], outbuf, aacDecInfo->nChans, icsInfo->winShape, psi->prevWinShape[chOut]); - - aacDecInfo->rawSampleBuf[ch] = 0; - aacDecInfo->rawSampleBytes = 0; - aacDecInfo->rawSampleFBits = 0; + /* window, overlap-add, round to PCM - optimized for each window sequence */ + if (icsInfo->winSequence == 0) { + DecWindowOverlap(psi->coef[ch], psi->overlap[chOut], outbuf, aacDecInfo->nChans, icsInfo->winShape, psi->prevWinShape[chOut]); + } else if (icsInfo->winSequence == 1) { + DecWindowOverlapLongStart(psi->coef[ch], psi->overlap[chOut], outbuf, aacDecInfo->nChans, icsInfo->winShape, psi->prevWinShape[chOut]); + } else if (icsInfo->winSequence == 2) { + DecWindowOverlapShort(psi->coef[ch], psi->overlap[chOut], outbuf, aacDecInfo->nChans, icsInfo->winShape, psi->prevWinShape[chOut]); + } else if (icsInfo->winSequence == 3) { + DecWindowOverlapLongStop(psi->coef[ch], psi->overlap[chOut], outbuf, aacDecInfo->nChans, icsInfo->winShape, psi->prevWinShape[chOut]); + } + + aacDecInfo->rawSampleBuf[ch] = 0; + aacDecInfo->rawSampleBytes = 0; + aacDecInfo->rawSampleFBits = 0; #endif - psi->prevWinShape[chOut] = icsInfo->winShape; + psi->prevWinShape[chOut] = icsInfo->winShape; - return 0; + return 0; } diff --git a/src/libhelix-aac/noiseless.c b/src/libhelix-aac/noiseless.c index 5d3a65df..525adf04 100644 --- a/src/libhelix-aac/noiseless.c +++ b/src/libhelix-aac/noiseless.c @@ -1,47 +1,47 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: noiseless.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: noiseless.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * noiseless.c - decode channel info, scalefactors, quantized coefficients, - * scalefactor band codebook, and TNS coefficients from bitstream + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + noiseless.c - decode channel info, scalefactors, quantized coefficients, + scalefactor band codebook, and TNS coefficients from bitstream **************************************************************************************/ #include "coder.h" @@ -52,433 +52,438 @@ //#define PROFILE_END() /************************************************************************************** - * Function: DecodeICSInfo - * - * Description: decode individual channel stream info - * - * Inputs: BitStreamInfo struct pointing to start of ICS info - * (14496-3, table 4.4.6) - * sample rate index - * - * Outputs: updated icsInfo struct - * - * Return: none + Function: DecodeICSInfo + + Description: decode individual channel stream info + + Inputs: BitStreamInfo struct pointing to start of ICS info + (14496-3, table 4.4.6) + sample rate index + + Outputs: updated icsInfo struct + + Return: none **************************************************************************************/ -/* __attribute__ ((section (".data"))) */ void DecodeICSInfo(BitStreamInfo *bsi, ICSInfo *icsInfo, int sampRateIdx) -{ - int sfb, g, mask; - - icsInfo->icsResBit = GetBits(bsi, 1); - icsInfo->winSequence = GetBits(bsi, 2); - icsInfo->winShape = GetBits(bsi, 1); - if (icsInfo->winSequence == 2) { - /* short block */ - icsInfo->maxSFB = GetBits(bsi, 4); - icsInfo->sfGroup = GetBits(bsi, 7); - icsInfo->numWinGroup = 1; - icsInfo->winGroupLen[0] = 1; - mask = 0x40; /* start with bit 6 */ - for (g = 0; g < 7; g++) { - if (icsInfo->sfGroup & mask) { - icsInfo->winGroupLen[icsInfo->numWinGroup - 1]++; - } else { - icsInfo->numWinGroup++; - icsInfo->winGroupLen[icsInfo->numWinGroup - 1] = 1; - } - mask >>= 1; - } - } else { - /* long block */ - icsInfo->maxSFB = GetBits(bsi, 6); - icsInfo->predictorDataPresent = GetBits(bsi, 1); - if (icsInfo->predictorDataPresent) { - icsInfo->predictorReset = GetBits(bsi, 1); - if (icsInfo->predictorReset) - icsInfo->predictorResetGroupNum = GetBits(bsi, 5); - for (sfb = 0; sfb < MIN(icsInfo->maxSFB, predSFBMax[sampRateIdx]); sfb++) - icsInfo->predictionUsed[sfb] = GetBits(bsi, 1); - } - icsInfo->numWinGroup = 1; - icsInfo->winGroupLen[0] = 1; - } +/* __attribute__ ((section (".data"))) */ void DecodeICSInfo(BitStreamInfo *bsi, ICSInfo *icsInfo, int sampRateIdx) { + int sfb, g, mask; + + icsInfo->icsResBit = GetBits(bsi, 1); + icsInfo->winSequence = GetBits(bsi, 2); + icsInfo->winShape = GetBits(bsi, 1); + if (icsInfo->winSequence == 2) { + /* short block */ + icsInfo->maxSFB = GetBits(bsi, 4); + icsInfo->sfGroup = GetBits(bsi, 7); + icsInfo->numWinGroup = 1; + icsInfo->winGroupLen[0] = 1; + mask = 0x40; /* start with bit 6 */ + for (g = 0; g < 7; g++) { + if (icsInfo->sfGroup & mask) { + icsInfo->winGroupLen[icsInfo->numWinGroup - 1]++; + } else { + icsInfo->numWinGroup++; + icsInfo->winGroupLen[icsInfo->numWinGroup - 1] = 1; + } + mask >>= 1; + } + } else { + /* long block */ + icsInfo->maxSFB = GetBits(bsi, 6); + icsInfo->predictorDataPresent = GetBits(bsi, 1); + if (icsInfo->predictorDataPresent) { + icsInfo->predictorReset = GetBits(bsi, 1); + if (icsInfo->predictorReset) { + icsInfo->predictorResetGroupNum = GetBits(bsi, 5); + } + for (sfb = 0; sfb < MIN(icsInfo->maxSFB, predSFBMax[sampRateIdx]); sfb++) { + icsInfo->predictionUsed[sfb] = GetBits(bsi, 1); + } + } + icsInfo->numWinGroup = 1; + icsInfo->winGroupLen[0] = 1; + } } /************************************************************************************** - * Function: DecodeSectionData - * - * Description: decode section data (scale factor band groupings and - * associated Huffman codebooks) - * - * Inputs: BitStreamInfo struct pointing to start of ICS info - * (14496-3, table 4.4.25) - * window sequence (short or long blocks) - * number of window groups (1 for long blocks, 1-8 for short blocks) - * max coded scalefactor band - * - * Outputs: index of Huffman codebook for each scalefactor band in each section - * - * Return: none - * - * Notes: sectCB, sectEnd, sfbCodeBook, ordered by window groups for short blocks + Function: DecodeSectionData + + Description: decode section data (scale factor band groupings and + associated Huffman codebooks) + + Inputs: BitStreamInfo struct pointing to start of ICS info + (14496-3, table 4.4.25) + window sequence (short or long blocks) + number of window groups (1 for long blocks, 1-8 for short blocks) + max coded scalefactor band + + Outputs: index of Huffman codebook for each scalefactor band in each section + + Return: none + + Notes: sectCB, sectEnd, sfbCodeBook, ordered by window groups for short blocks **************************************************************************************/ -/* __attribute__ ((section (".data"))) */ static void DecodeSectionData(BitStreamInfo *bsi, int winSequence, int numWinGrp, int maxSFB, unsigned char *sfbCodeBook) -{ - int g, cb, sfb; - int sectLen, sectLenBits, sectLenIncr, sectEscapeVal; - - sectLenBits = (winSequence == 2 ? 3 : 5); - sectEscapeVal = (1 << sectLenBits) - 1; - - for (g = 0; g < numWinGrp; g++) { - sfb = 0; - while (sfb < maxSFB) { - cb = GetBits(bsi, 4); /* next section codebook */ - sectLen = 0; - do { - sectLenIncr = GetBits(bsi, sectLenBits); - sectLen += sectLenIncr; - } while (sectLenIncr == sectEscapeVal); - - sfb += sectLen; - while (sectLen--) - *sfbCodeBook++ = (unsigned char)cb; - } - ASSERT(sfb == maxSFB); - } +/* __attribute__ ((section (".data"))) */ static void DecodeSectionData(BitStreamInfo *bsi, int winSequence, int numWinGrp, int maxSFB, unsigned char *sfbCodeBook) { + int g, cb, sfb; + int sectLen, sectLenBits, sectLenIncr, sectEscapeVal; + + sectLenBits = (winSequence == 2 ? 3 : 5); + sectEscapeVal = (1 << sectLenBits) - 1; + + for (g = 0; g < numWinGrp; g++) { + sfb = 0; + while (sfb < maxSFB) { + cb = GetBits(bsi, 4); /* next section codebook */ + sectLen = 0; + do { + sectLenIncr = GetBits(bsi, sectLenBits); + sectLen += sectLenIncr; + } while (sectLenIncr == sectEscapeVal); + + sfb += sectLen; + while (sectLen--) { + *sfbCodeBook++ = (unsigned char)cb; + } + } + ASSERT(sfb == maxSFB); + } } /************************************************************************************** - * Function: DecodeOneScaleFactor - * - * Description: decode one scalefactor using scalefactor Huffman codebook - * - * Inputs: BitStreamInfo struct pointing to start of next coded scalefactor - * - * Outputs: updated BitstreamInfo struct - * - * Return: one decoded scalefactor, including index_offset of -60 + Function: DecodeOneScaleFactor + + Description: decode one scalefactor using scalefactor Huffman codebook + + Inputs: BitStreamInfo struct pointing to start of next coded scalefactor + + Outputs: updated BitstreamInfo struct + + Return: one decoded scalefactor, including index_offset of -60 **************************************************************************************/ -static int DecodeOneScaleFactor(BitStreamInfo *bsi) -{ - int nBits, val; - unsigned int bitBuf; - - /* decode next scalefactor from bitstream */ - bitBuf = GetBitsNoAdvance(bsi, huffTabScaleFactInfo.maxBits) << (32 - huffTabScaleFactInfo.maxBits); - //PROFILE_START("DecodeHuffmanScalar"); - nBits = DecodeHuffmanScalar(huffTabScaleFact, &huffTabScaleFactInfo, bitBuf, &val); - AdvanceBitstream(bsi, nBits); - //PROFILE_END(); - return val; +static int DecodeOneScaleFactor(BitStreamInfo *bsi) { + int nBits, val; + unsigned int bitBuf; + + /* decode next scalefactor from bitstream */ + bitBuf = GetBitsNoAdvance(bsi, huffTabScaleFactInfo.maxBits) << (32 - huffTabScaleFactInfo.maxBits); + //PROFILE_START("DecodeHuffmanScalar"); + nBits = DecodeHuffmanScalar(huffTabScaleFact, &huffTabScaleFactInfo, bitBuf, &val); + AdvanceBitstream(bsi, nBits); + //PROFILE_END(); + return val; } /************************************************************************************** - * Function: DecodeScaleFactors - * - * Description: decode scalefactors, PNS energy, and intensity stereo weights - * - * Inputs: BitStreamInfo struct pointing to start of ICS info - * (14496-3, table 4.4.26) - * number of window groups (1 for long blocks, 1-8 for short blocks) - * max coded scalefactor band - * global gain (starting value for differential scalefactor coding) - * index of Huffman codebook for each scalefactor band in each section - * - * Outputs: decoded scalefactor for each section - * - * Return: none - * - * Notes: sfbCodeBook, scaleFactors ordered by window groups for short blocks - * for section with codebook 13, scaleFactors buffer has decoded PNS - * energy instead of regular scalefactor - * for section with codebook 14 or 15, scaleFactors buffer has intensity - * stereo weight instead of regular scalefactor + Function: DecodeScaleFactors + + Description: decode scalefactors, PNS energy, and intensity stereo weights + + Inputs: BitStreamInfo struct pointing to start of ICS info + (14496-3, table 4.4.26) + number of window groups (1 for long blocks, 1-8 for short blocks) + max coded scalefactor band + global gain (starting value for differential scalefactor coding) + index of Huffman codebook for each scalefactor band in each section + + Outputs: decoded scalefactor for each section + + Return: none + + Notes: sfbCodeBook, scaleFactors ordered by window groups for short blocks + for section with codebook 13, scaleFactors buffer has decoded PNS + energy instead of regular scalefactor + for section with codebook 14 or 15, scaleFactors buffer has intensity + stereo weight instead of regular scalefactor **************************************************************************************/ /* __attribute__ ((section (".data"))) */ static void DecodeScaleFactors(BitStreamInfo *bsi, int numWinGrp, int maxSFB, int globalGain, - unsigned char *sfbCodeBook, short *scaleFactors) -{ - int g, sfbCB, nrg, npf, val, sf, is; - - /* starting values for differential coding */ - sf = globalGain; - is = 0; - nrg = globalGain - 90 - 256; - npf = 1; - - for (g = 0; g < numWinGrp * maxSFB; g++) { - sfbCB = *sfbCodeBook++; - - if (sfbCB == 14 || sfbCB == 15) { - /* intensity stereo - differential coding */ - val = DecodeOneScaleFactor(bsi); - is += val; - *scaleFactors++ = (short)is; - } else if (sfbCB == 13) { - /* PNS - first energy is directly coded, rest are Huffman coded (npf = noise_pcm_flag) */ - if (npf) { - val = GetBits(bsi, 9); - npf = 0; - } else { - val = DecodeOneScaleFactor(bsi); - } - nrg += val; - *scaleFactors++ = (short)nrg; - } else if (sfbCB >= 1 && sfbCB <= 11) { - /* regular (non-zero) region - differential coding */ - val = DecodeOneScaleFactor(bsi); - sf += val; - *scaleFactors++ = (short)sf; - } else { - /* inactive scalefactor band if codebook 0 */ - *scaleFactors++ = 0; - } - } + unsigned char *sfbCodeBook, short *scaleFactors) { + int g, sfbCB, nrg, npf, val, sf, is; + + /* starting values for differential coding */ + sf = globalGain; + is = 0; + nrg = globalGain - 90 - 256; + npf = 1; + + for (g = 0; g < numWinGrp * maxSFB; g++) { + sfbCB = *sfbCodeBook++; + + if (sfbCB == 14 || sfbCB == 15) { + /* intensity stereo - differential coding */ + val = DecodeOneScaleFactor(bsi); + is += val; + *scaleFactors++ = (short)is; + } else if (sfbCB == 13) { + /* PNS - first energy is directly coded, rest are Huffman coded (npf = noise_pcm_flag) */ + if (npf) { + val = GetBits(bsi, 9); + npf = 0; + } else { + val = DecodeOneScaleFactor(bsi); + } + nrg += val; + *scaleFactors++ = (short)nrg; + } else if (sfbCB >= 1 && sfbCB <= 11) { + /* regular (non-zero) region - differential coding */ + val = DecodeOneScaleFactor(bsi); + sf += val; + *scaleFactors++ = (short)sf; + } else { + /* inactive scalefactor band if codebook 0 */ + *scaleFactors++ = 0; + } + } } /************************************************************************************** - * Function: DecodePulseInfo - * - * Description: decode pulse information - * - * Inputs: BitStreamInfo struct pointing to start of pulse info - * (14496-3, table 4.4.7) - * - * Outputs: updated PulseInfo struct - * - * Return: none + Function: DecodePulseInfo + + Description: decode pulse information + + Inputs: BitStreamInfo struct pointing to start of pulse info + (14496-3, table 4.4.7) + + Outputs: updated PulseInfo struct + + Return: none **************************************************************************************/ -/* __attribute__ ((section (".data"))) */ static void DecodePulseInfo(BitStreamInfo *bsi, PulseInfo *pi) -{ - int i; - - pi->numPulse = GetBits(bsi, 2) + 1; /* add 1 here */ - pi->startSFB = GetBits(bsi, 6); - for (i = 0; i < pi->numPulse; i++) { - pi->offset[i] = GetBits(bsi, 5); - pi->amp[i] = GetBits(bsi, 4); - } +/* __attribute__ ((section (".data"))) */ static void DecodePulseInfo(BitStreamInfo *bsi, PulseInfo *pi) { + int i; + + pi->numPulse = GetBits(bsi, 2) + 1; /* add 1 here */ + pi->startSFB = GetBits(bsi, 6); + for (i = 0; i < pi->numPulse && i < MAX_PULSES; i++) { + pi->offset[i] = GetBits(bsi, 5); + pi->amp[i] = GetBits(bsi, 4); + } } /************************************************************************************** - * Function: DecodeTNSInfo - * - * Description: decode TNS filter information - * - * Inputs: BitStreamInfo struct pointing to start of TNS info - * (14496-3, table 4.4.27) - * window sequence (short or long blocks) - * - * Outputs: updated TNSInfo struct - * buffer of decoded (signed) TNS filter coefficients - * - * Return: none + Function: DecodeTNSInfo + + Description: decode TNS filter information + + Inputs: BitStreamInfo struct pointing to start of TNS info + (14496-3, table 4.4.27) + window sequence (short or long blocks) + + Outputs: updated TNSInfo struct + buffer of decoded (signed) TNS filter coefficients + + Return: none **************************************************************************************/ static const signed char sgnMask[3] = {0x02, 0x04, 0x08}; static const signed char negMask[3] = {~0x03, ~0x07, ~0x0f}; -static void DecodeTNSInfo(BitStreamInfo *bsi, int winSequence, TNSInfo *ti, signed char *tnsCoef) -{ - int i, w, f, coefBits, compress; - signed char c, s, n; - - unsigned char *filtLength, *filtOrder, *filtDir; - - filtLength = ti->length; - filtOrder = ti->order; - filtDir = ti->dir; - - if (winSequence == 2) { - /* short blocks */ - for (w = 0; w < NWINDOWS_SHORT; w++) { - ti->numFilt[w] = GetBits(bsi, 1); - if (ti->numFilt[w]) { - ti->coefRes[w] = GetBits(bsi, 1) + 3; - *filtLength = GetBits(bsi, 4); - *filtOrder = GetBits(bsi, 3); - if (*filtOrder) { - *filtDir++ = GetBits(bsi, 1); - compress = GetBits(bsi, 1); - coefBits = (int)ti->coefRes[w] - compress; /* 2, 3, or 4 */ - s = sgnMask[coefBits - 2]; - n = negMask[coefBits - 2]; - for (i = 0; i < *filtOrder; i++) { - c = GetBits(bsi, coefBits); - if (c & s) c |= n; - *tnsCoef++ = c; - } - } - filtLength++; - filtOrder++; - } - } - } else { - /* long blocks */ - ti->numFilt[0] = GetBits(bsi, 2); - if (ti->numFilt[0]) - ti->coefRes[0] = GetBits(bsi, 1) + 3; - for (f = 0; f < ti->numFilt[0]; f++) { - *filtLength = GetBits(bsi, 6); - *filtOrder = GetBits(bsi, 5); - if (*filtOrder) { - *filtDir++ = GetBits(bsi, 1); - compress = GetBits(bsi, 1); - coefBits = (int)ti->coefRes[0] - compress; /* 2, 3, or 4 */ - s = sgnMask[coefBits - 2]; - n = negMask[coefBits - 2]; - for (i = 0; i < *filtOrder; i++) { - c = GetBits(bsi, coefBits); - if (c & s) c |= n; - *tnsCoef++ = c; - } - } - filtLength++; - filtOrder++; - } - } +static void DecodeTNSInfo(BitStreamInfo *bsi, int winSequence, TNSInfo *ti, signed char *tnsCoef) { + int i, w, f, coefBits, compress; + signed char c, s, n; + + unsigned char *filtLength, *filtOrder, *filtDir; + + filtLength = ti->length; + filtOrder = ti->order; + filtDir = ti->dir; + + if (winSequence == 2) { + /* short blocks */ + for (w = 0; w < NWINDOWS_SHORT; w++) { + ti->numFilt[w] = GetBits(bsi, 1); + if (ti->numFilt[w]) { + ti->coefRes[w] = GetBits(bsi, 1) + 3; + *filtLength = GetBits(bsi, 4); + *filtOrder = GetBits(bsi, 3); + if (*filtOrder) { + *filtDir++ = GetBits(bsi, 1); + compress = GetBits(bsi, 1); + coefBits = (int)ti->coefRes[w] - compress; /* 2, 3, or 4 */ + s = sgnMask[coefBits - 2]; + n = negMask[coefBits - 2]; + for (i = 0; i < *filtOrder; i++) { + c = GetBits(bsi, coefBits); + if (c & s) { + c |= n; + } + *tnsCoef++ = c; + } + } + filtLength++; + filtOrder++; + } + } + } else { + /* long blocks */ + ti->numFilt[0] = GetBits(bsi, 2); + if (ti->numFilt[0]) { + ti->coefRes[0] = GetBits(bsi, 1) + 3; + } + for (f = 0; f < ti->numFilt[0]; f++) { + *filtLength = GetBits(bsi, 6); + *filtOrder = GetBits(bsi, 5); + if (*filtOrder) { + *filtDir++ = GetBits(bsi, 1); + compress = GetBits(bsi, 1); + coefBits = (int)ti->coefRes[0] - compress; /* 2, 3, or 4 */ + s = sgnMask[coefBits - 2]; + n = negMask[coefBits - 2]; + for (i = 0; i < *filtOrder; i++) { + c = GetBits(bsi, coefBits); + if (c & s) { + c |= n; + } + *tnsCoef++ = c; + } + } + filtLength++; + filtOrder++; + } + } } -/* bitstream field lengths for gain control data: - * gainBits[winSequence][0] = maxWindow (how many gain windows there are) - * gainBits[winSequence][1] = locBitsZero (bits for alocCode if window == 0) - * gainBits[winSequence][2] = locBits (bits for alocCode if window != 0) - */ +/* bitstream field lengths for gain control data: + gainBits[winSequence][0] = maxWindow (how many gain windows there are) + gainBits[winSequence][1] = locBitsZero (bits for alocCode if window == 0) + gainBits[winSequence][2] = locBits (bits for alocCode if window != 0) +*/ static const unsigned char gainBits[4][3] = { - {1, 5, 5}, /* long */ - {2, 4, 2}, /* start */ - {8, 2, 2}, /* short */ - {2, 4, 5}, /* stop */ + {1, 5, 5}, /* long */ + {2, 4, 2}, /* start */ + {8, 2, 2}, /* short */ + {2, 4, 5}, /* stop */ }; /************************************************************************************** - * Function: DecodeGainControlInfo - * - * Description: decode gain control information (SSR profile only) - * - * Inputs: BitStreamInfo struct pointing to start of gain control info - * (14496-3, table 4.4.12) - * window sequence (short or long blocks) - * - * Outputs: updated GainControlInfo struct - * - * Return: none + Function: DecodeGainControlInfo + + Description: decode gain control information (SSR profile only) + + Inputs: BitStreamInfo struct pointing to start of gain control info + (14496-3, table 4.4.12) + window sequence (short or long blocks) + + Outputs: updated GainControlInfo struct + + Return: none **************************************************************************************/ -static void DecodeGainControlInfo(BitStreamInfo *bsi, int winSequence, GainControlInfo *gi) -{ - int bd, wd, ad; - int locBits, locBitsZero, maxWin; - - gi->maxBand = GetBits(bsi, 2); - maxWin = (int)gainBits[winSequence][0]; - locBitsZero = (int)gainBits[winSequence][1]; - locBits = (int)gainBits[winSequence][2]; - - for (bd = 1; bd <= gi->maxBand; bd++) { - for (wd = 0; wd < maxWin; wd++) { - gi->adjNum[bd][wd] = GetBits(bsi, 3); - for (ad = 0; ad < gi->adjNum[bd][wd]; ad++) { - gi->alevCode[bd][wd][ad] = GetBits(bsi, 4); - gi->alocCode[bd][wd][ad] = GetBits(bsi, (wd == 0 ? locBitsZero : locBits)); - } - } - } +static void DecodeGainControlInfo(BitStreamInfo *bsi, int winSequence, GainControlInfo *gi) { + int bd, wd, ad; + int locBits, locBitsZero, maxWin; + + gi->maxBand = GetBits(bsi, 2); + maxWin = (int)gainBits[winSequence][0]; + locBitsZero = (int)gainBits[winSequence][1]; + locBits = (int)gainBits[winSequence][2]; + + for (bd = 1; bd <= gi->maxBand; bd++) { + for (wd = 0; wd < maxWin; wd++) { + gi->adjNum[bd][wd] = GetBits(bsi, 3); + for (ad = 0; ad < gi->adjNum[bd][wd]; ad++) { + gi->alevCode[bd][wd][ad] = GetBits(bsi, 4); + gi->alocCode[bd][wd][ad] = GetBits(bsi, (wd == 0 ? locBitsZero : locBits)); + } + } + } } /************************************************************************************** - * Function: DecodeICS - * - * Description: decode individual channel stream - * - * Inputs: platform specific info struct - * BitStreamInfo struct pointing to start of individual channel stream - * (14496-3, table 4.4.24) - * index of current channel - * - * Outputs: updated section data, scale factor data, pulse data, TNS data, - * and gain control data - * - * Return: none + Function: DecodeICS + + Description: decode individual channel stream + + Inputs: platform specific info struct + BitStreamInfo struct pointing to start of individual channel stream + (14496-3, table 4.4.24) + index of current channel + + Outputs: updated section data, scale factor data, pulse data, TNS data, + and gain control data + + Return: none **************************************************************************************/ -static void DecodeICS(PSInfoBase *psi, BitStreamInfo *bsi, int ch) -{ - int globalGain; - ICSInfo *icsInfo; - PulseInfo *pi; - TNSInfo *ti; - GainControlInfo *gi; - - icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]); - - globalGain = GetBits(bsi, 8); - if (!psi->commonWin) - DecodeICSInfo(bsi, icsInfo, psi->sampRateIdx); - - DecodeSectionData(bsi, icsInfo->winSequence, icsInfo->numWinGroup, icsInfo->maxSFB, psi->sfbCodeBook[ch]); - - DecodeScaleFactors(bsi, icsInfo->numWinGroup, icsInfo->maxSFB, globalGain, psi->sfbCodeBook[ch], psi->scaleFactors[ch]); - - pi = &psi->pulseInfo[ch]; - pi->pulseDataPresent = GetBits(bsi, 1); - if (pi->pulseDataPresent) - DecodePulseInfo(bsi, pi); - - ti = &psi->tnsInfo[ch]; - ti->tnsDataPresent = GetBits(bsi, 1); - if (ti->tnsDataPresent) - DecodeTNSInfo(bsi, icsInfo->winSequence, ti, ti->coef); - - gi = &psi->gainControlInfo[ch]; - gi->gainControlDataPresent = GetBits(bsi, 1); - if (gi->gainControlDataPresent) - DecodeGainControlInfo(bsi, icsInfo->winSequence, gi); +static void DecodeICS(PSInfoBase *psi, BitStreamInfo *bsi, int ch) { + int globalGain; + ICSInfo *icsInfo; + PulseInfo *pi; + TNSInfo *ti; + GainControlInfo *gi; + + icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]); + + globalGain = GetBits(bsi, 8); + if (!psi->commonWin) { + DecodeICSInfo(bsi, icsInfo, psi->sampRateIdx); + } + + DecodeSectionData(bsi, icsInfo->winSequence, icsInfo->numWinGroup, icsInfo->maxSFB, psi->sfbCodeBook[ch]); + + DecodeScaleFactors(bsi, icsInfo->numWinGroup, icsInfo->maxSFB, globalGain, psi->sfbCodeBook[ch], psi->scaleFactors[ch]); + + pi = &psi->pulseInfo[ch]; + pi->pulseDataPresent = GetBits(bsi, 1); + if (pi->pulseDataPresent) { + DecodePulseInfo(bsi, pi); + } + + ti = &psi->tnsInfo[ch]; + ti->tnsDataPresent = GetBits(bsi, 1); + if (ti->tnsDataPresent) { + DecodeTNSInfo(bsi, icsInfo->winSequence, ti, ti->coef); + } + + gi = &psi->gainControlInfo[ch]; + gi->gainControlDataPresent = GetBits(bsi, 1); + if (gi->gainControlDataPresent) { + DecodeGainControlInfo(bsi, icsInfo->winSequence, gi); + } } /************************************************************************************** - * Function: DecodeNoiselessData - * - * Description: decode noiseless data (side info and transform coefficients) - * - * Inputs: valid AACDecInfo struct - * double pointer to buffer pointing to start of individual channel stream - * (14496-3, table 4.4.24) - * pointer to bit offset - * pointer to number of valid bits remaining in buf - * index of current channel - * - * Outputs: updated global gain, section data, scale factor data, pulse data, - * TNS data, gain control data, and spectral data - * - * Return: 0 if successful, error code (< 0) if error + Function: DecodeNoiselessData + + Description: decode noiseless data (side info and transform coefficients) + + Inputs: valid AACDecInfo struct + double pointer to buffer pointing to start of individual channel stream + (14496-3, table 4.4.24) + pointer to bit offset + pointer to number of valid bits remaining in buf + index of current channel + + Outputs: updated global gain, section data, scale factor data, pulse data, + TNS data, gain control data, and spectral data + + Return: 0 if successful, error code (< 0) if error **************************************************************************************/ -int DecodeNoiselessData(AACDecInfo *aacDecInfo, unsigned char **buf, int *bitOffset, int *bitsAvail, int ch) -{ - int bitsUsed; - BitStreamInfo bsi; - PSInfoBase *psi; - ICSInfo *icsInfo; - - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return ERR_AAC_NULL_POINTER; - psi = (PSInfoBase *)(aacDecInfo->psInfoBase); - icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]); - - SetBitstreamPointer(&bsi, (*bitsAvail+7) >> 3, *buf); - GetBits(&bsi, *bitOffset); - - DecodeICS(psi, &bsi, ch); - - if (icsInfo->winSequence == 2) - DecodeSpectrumShort(psi, &bsi, ch); - else - DecodeSpectrumLong(psi, &bsi, ch); - - bitsUsed = CalcBitsUsed(&bsi, *buf, *bitOffset); - *buf += ((bitsUsed + *bitOffset) >> 3); - *bitOffset = ((bitsUsed + *bitOffset) & 0x07); - *bitsAvail -= bitsUsed; - - aacDecInfo->sbDeinterleaveReqd[ch] = 0; - aacDecInfo->tnsUsed |= psi->tnsInfo[ch].tnsDataPresent; /* set flag if TNS used for any channel */ - - return ERR_AAC_NONE; +int DecodeNoiselessData(AACDecInfo *aacDecInfo, unsigned char **buf, int *bitOffset, int *bitsAvail, int ch) { + int bitsUsed; + BitStreamInfo bsi; + PSInfoBase *psi; + ICSInfo *icsInfo; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return ERR_AAC_NULL_POINTER; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]); + + SetBitstreamPointer(&bsi, (*bitsAvail + 7) >> 3, *buf); + GetBits(&bsi, *bitOffset); + + DecodeICS(psi, &bsi, ch); + + if (icsInfo->winSequence == 2) { + DecodeSpectrumShort(psi, &bsi, ch); + } else { + DecodeSpectrumLong(psi, &bsi, ch); + } + + bitsUsed = CalcBitsUsed(&bsi, *buf, *bitOffset); + *buf += ((bitsUsed + *bitOffset) >> 3); + *bitOffset = ((bitsUsed + *bitOffset) & 0x07); + *bitsAvail -= bitsUsed; + + aacDecInfo->sbDeinterleaveReqd[ch] = 0; + aacDecInfo->tnsUsed |= psi->tnsInfo[ch].tnsDataPresent; /* set flag if TNS used for any channel */ + + return ERR_AAC_NONE; } diff --git a/src/libhelix-aac/pns.c b/src/libhelix-aac/pns.c index 3594c76d..8b887a9c 100644 --- a/src/libhelix-aac/pns.c +++ b/src/libhelix-aac/pns.c @@ -1,75 +1,74 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: pns.c,v 1.2 2005/03/10 17:01:56 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: pns.c,v 1.2 2005/03/10 17:01:56 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * pns.c - perceptual noise substitution + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + pns.c - perceptual noise substitution **************************************************************************************/ #include "coder.h" #include "assembly.h" /************************************************************************************** - * Function: Get32BitVal - * - * Description: generate 32-bit unsigned random number - * - * Inputs: last number calculated (seed, first time through) - * - * Outputs: new number, saved in *last - * - * Return: 32-bit number, uniformly distributed between [0, 2^32) - * - * Notes: uses simple linear congruential generator + Function: Get32BitVal + + Description: generate 32-bit unsigned random number + + Inputs: last number calculated (seed, first time through) + + Outputs: new number, saved in *last + + Return: 32-bit number, uniformly distributed between [0, 2^32) + + Notes: uses simple linear congruential generator **************************************************************************************/ -static unsigned int Get32BitVal(unsigned int *last) -{ - unsigned int r = *last; +static unsigned int Get32BitVal(unsigned int *last) { + unsigned int r = *last; - /* use same coefs as MPEG reference code (classic LCG) - * use unsigned multiply to force reliable wraparound behavior in C (mod 2^32) - */ - r = (1664525U * r) + 1013904223U; - *last = r; + /* use same coefs as MPEG reference code (classic LCG) + use unsigned multiply to force reliable wraparound behavior in C (mod 2^32) + */ + r = (1664525U * r) + 1013904223U; + *last = r; - return r; + return r; } @@ -80,278 +79,285 @@ static unsigned int Get32BitVal(unsigned int *last) #define Q26_3 0x0c000000 /* Q26: 3.0 */ /************************************************************************************** - * Function: InvRootR - * - * Description: use Newton's method to solve for x = 1/sqrt(r) - * - * Inputs: r in Q30 format, range = [0.25, 1] (normalize inputs to this range) - * - * Outputs: none - * - * Return: x = Q29, range = (1, 2) - * - * Notes: guaranteed to converge and not overflow for any r in this range - * - * xn+1 = xn - f(xn)/f'(xn) - * f(x) = 1/sqrt(r) - x = 0 (find root) - * = 1/x^2 - r - * f'(x) = -2/x^3 - * - * so xn+1 = xn/2 * (3 - r*xn^2) - * - * NUM_ITER_INVSQRT = 3, maxDiff = 1.3747e-02 - * NUM_ITER_INVSQRT = 4, maxDiff = 3.9832e-04 + Function: InvRootR + + Description: use Newton's method to solve for x = 1/sqrt(r) + + Inputs: r in Q30 format, range = [0.25, 1] (normalize inputs to this range) + + Outputs: none + + Return: x = Q29, range = (1, 2) + + Notes: guaranteed to converge and not overflow for any r in this range + + xn+1 = xn - f(xn)/f'(xn) + f(x) = 1/sqrt(r) - x = 0 (find root) + = 1/x^2 - r + f'(x) = -2/x^3 + + so xn+1 = xn/2 * (3 - r*xn^2) + + NUM_ITER_INVSQRT = 3, maxDiff = 1.3747e-02 + NUM_ITER_INVSQRT = 4, maxDiff = 3.9832e-04 **************************************************************************************/ -static int InvRootR(int r) -{ - int i, xn, t; - - /* use linear equation for initial guess - * x0 = -2*r + 3 (so x0 always >= correct answer in range [0.25, 1)) - * xn = Q29 (at every step) - */ - xn = (MULSHIFT32(r, X0_COEF_2) << 2) + X0_OFF_2; - - for (i = 0; i < NUM_ITER_INVSQRT; i++) { - t = MULSHIFT32(xn, xn); /* Q26 = Q29*Q29 */ - t = Q26_3 - (MULSHIFT32(r, t) << 2); /* Q26 = Q26 - (Q31*Q26 << 1) */ - xn = MULSHIFT32(xn, t) << (6 - 1); /* Q29 = (Q29*Q26 << 6), and -1 for division by 2 */ - } - - /* clip to range (1.0, 2.0) - * (because of rounding, this can converge to xn slightly > 2.0 when r is near 0.25) - */ - if (xn >> 30) - xn = (1 << 30) - 1; - - return xn; +static int InvRootR(int r) { + int i, xn, t; + + /* use linear equation for initial guess + x0 = -2*r + 3 (so x0 always >= correct answer in range [0.25, 1)) + xn = Q29 (at every step) + */ + xn = (MULSHIFT32(r, X0_COEF_2) << 2) + X0_OFF_2; + + for (i = 0; i < NUM_ITER_INVSQRT; i++) { + t = MULSHIFT32(xn, xn); /* Q26 = Q29*Q29 */ + t = Q26_3 - (MULSHIFT32(r, t) << 2); /* Q26 = Q26 - (Q31*Q26 << 1) */ + xn = MULSHIFT32(xn, t) << (6 - 1); /* Q29 = (Q29*Q26 << 6), and -1 for division by 2 */ + } + + /* clip to range (1.0, 2.0) + (because of rounding, this can converge to xn slightly > 2.0 when r is near 0.25) + */ + if (xn >> 30) { + xn = (1 << 30) - 1; + } + + return xn; } /************************************************************************************** - * Function: ScaleNoiseVector - * - * Description: apply scaling to vector of noise coefficients for one scalefactor band - * - * Inputs: unscaled coefficients - * number of coefficients in vector (one scalefactor band of coefs) - * scalefactor for this band (i.e. noise energy) - * - * Outputs: nVals coefficients in Q(FBITS_OUT_DQ_OFF) - * - * Return: guard bit mask (OR of abs value of all noise coefs) + Function: ScaleNoiseVector + + Description: apply scaling to vector of noise coefficients for one scalefactor band + + Inputs: unscaled coefficients + number of coefficients in vector (one scalefactor band of coefs) + scalefactor for this band (i.e. noise energy) + + Outputs: nVals coefficients in Q(FBITS_OUT_DQ_OFF) + + Return: guard bit mask (OR of abs value of all noise coefs) **************************************************************************************/ -static int ScaleNoiseVector(int *coef, int nVals, int sf) -{ - -/* pow(2, i/4.0) for i = [0,1,2,3], format = Q30 */ -static const int pow14[4] PROGMEM = { - 0x40000000, 0x4c1bf829, 0x5a82799a, 0x6ba27e65 -}; - - int i, c, spec, energy, sq, scalef, scalei, invSqrtEnergy, z, gbMask; - - energy = 0; - for (i = 0; i < nVals; i++) { - spec = coef[i]; - - /* max nVals = max SFB width = 96, so energy can gain < 2^7 bits in accumulation */ - sq = (spec * spec) >> 8; /* spec*spec range = (-2^30, 2^30) */ - energy += sq; - } - - /* unless nVals == 1 (or the number generator is broken...), this should not happen */ - if (energy == 0) - return 0; /* coef[i] must = 0 for i = [0, nVals-1], so gbMask = 0 */ - - /* pow(2, sf/4) * pow(2, FBITS_OUT_DQ_OFF) */ - scalef = pow14[sf & 0x3]; - scalei = (sf >> 2) + FBITS_OUT_DQ_OFF; - - /* energy has implied factor of 2^-8 since we shifted the accumulator - * normalize energy to range [0.25, 1.0), calculate 1/sqrt(1), and denormalize - * i.e. divide input by 2^(30-z) and convert to Q30 - * output of 1/sqrt(i) now has extra factor of 2^((30-z)/2) - * for energy > 0, z is an even number between 0 and 28 - * final scaling of invSqrtEnergy: - * 2^(15 - z/2) to compensate for implicit 2^(30-z) factor in input - * +4 to compensate for implicit 2^-8 factor in input - */ - z = CLZ(energy) - 2; /* energy has at least 2 leading zeros (see acc loop) */ - z &= 0xfffffffe; /* force even */ - invSqrtEnergy = InvRootR(energy << z); /* energy << z must be in range [0x10000000, 0x40000000] */ - scalei -= (15 - z/2 + 4); /* nInt = 1/sqrt(energy) in Q29 */ - - /* normalize for final scaling */ - z = CLZ(invSqrtEnergy) - 1; - invSqrtEnergy <<= z; - scalei -= (z - 3 - 2); /* -2 for scalef, z-3 for invSqrtEnergy */ - scalef = MULSHIFT32(scalef, invSqrtEnergy); /* scalef (input) = Q30, invSqrtEnergy = Q29 * 2^z */ - gbMask = 0; - - if (scalei < 0) { - scalei = -scalei; - if (scalei > 31) - scalei = 31; - for (i = 0; i < nVals; i++) { - c = MULSHIFT32(coef[i], scalef) >> scalei; - gbMask |= FASTABS(c); - coef[i] = c; - } - } else { - /* for scalei <= 16, no clipping possible (coef[i] is < 2^15 before scaling) - * for scalei > 16, just saturate exponent (rare) - * scalef is close to full-scale (since we normalized invSqrtEnergy) - * remember, we are just producing noise here - */ - if (scalei > 16) - scalei = 16; - for (i = 0; i < nVals; i++) { - c = MULSHIFT32(coef[i] << scalei, scalef); - coef[i] = c; - gbMask |= FASTABS(c); - } - } - - return gbMask; +static int ScaleNoiseVector(int *coef, int nVals, int sf) { + + /* pow(2, i/4.0) for i = [0,1,2,3], format = Q30 */ + static const int pow14[4] PROGMEM = { + 0x40000000, 0x4c1bf829, 0x5a82799a, 0x6ba27e65 + }; + + int i, c, spec, energy, sq, scalef, scalei, invSqrtEnergy, z, gbMask; + + energy = 0; + for (i = 0; i < nVals; i++) { + spec = coef[i]; + + /* max nVals = max SFB width = 96, so energy can gain < 2^7 bits in accumulation */ + sq = (spec * spec) >> 8; /* spec*spec range = (-2^30, 2^30) */ + energy += sq; + } + + /* unless nVals == 1 (or the number generator is broken...), this should not happen */ + if (energy == 0) { + return 0; /* coef[i] must = 0 for i = [0, nVals-1], so gbMask = 0 */ + } + + /* pow(2, sf/4) * pow(2, FBITS_OUT_DQ_OFF) */ + scalef = pow14[sf & 0x3]; + scalei = (sf >> 2) + FBITS_OUT_DQ_OFF; + + /* energy has implied factor of 2^-8 since we shifted the accumulator + normalize energy to range [0.25, 1.0), calculate 1/sqrt(1), and denormalize + i.e. divide input by 2^(30-z) and convert to Q30 + output of 1/sqrt(i) now has extra factor of 2^((30-z)/2) + for energy > 0, z is an even number between 0 and 28 + final scaling of invSqrtEnergy: + 2^(15 - z/2) to compensate for implicit 2^(30-z) factor in input + +4 to compensate for implicit 2^-8 factor in input + */ + z = CLZ(energy) - 2; /* energy has at least 2 leading zeros (see acc loop) */ + z &= 0xfffffffe; /* force even */ + invSqrtEnergy = InvRootR(energy << z); /* energy << z must be in range [0x10000000, 0x40000000] */ + scalei -= (15 - z / 2 + 4); /* nInt = 1/sqrt(energy) in Q29 */ + + /* normalize for final scaling */ + z = CLZ(invSqrtEnergy) - 1; + invSqrtEnergy <<= z; + scalei -= (z - 3 - 2); /* -2 for scalef, z-3 for invSqrtEnergy */ + scalef = MULSHIFT32(scalef, invSqrtEnergy); /* scalef (input) = Q30, invSqrtEnergy = Q29 * 2^z */ + gbMask = 0; + + if (scalei < 0) { + scalei = -scalei; + if (scalei > 31) { + scalei = 31; + } + for (i = 0; i < nVals; i++) { + c = MULSHIFT32(coef[i], scalef) >> scalei; + gbMask |= FASTABS(c); + coef[i] = c; + } + } else { + /* for scalei <= 16, no clipping possible (coef[i] is < 2^15 before scaling) + for scalei > 16, just saturate exponent (rare) + scalef is close to full-scale (since we normalized invSqrtEnergy) + remember, we are just producing noise here + */ + if (scalei > 16) { + scalei = 16; + } + for (i = 0; i < nVals; i++) { + c = MULSHIFT32(coef[i] << scalei, scalef); + coef[i] = c; + gbMask |= FASTABS(c); + } + } + + return gbMask; } /************************************************************************************** - * Function: GenerateNoiseVector - * - * Description: create vector of noise coefficients for one scalefactor band - * - * Inputs: seed for number generator - * number of coefficients to generate - * - * Outputs: buffer of nVals coefficients, range = [-2^15, 2^15) - * updated seed for number generator - * - * Return: none + Function: GenerateNoiseVector + + Description: create vector of noise coefficients for one scalefactor band + + Inputs: seed for number generator + number of coefficients to generate + + Outputs: buffer of nVals coefficients, range = [-2^15, 2^15) + updated seed for number generator + + Return: none **************************************************************************************/ -static void GenerateNoiseVector(int *coef, int *last, int nVals) -{ - int i; - - for (i = 0; i < nVals; i++) - coef[i] = ((signed int)Get32BitVal((unsigned int *)last)) >> 16; +static void GenerateNoiseVector(int *coef, int *last, int nVals) { + int i; + + for (i = 0; i < nVals; i++) { + coef[i] = ((signed int)Get32BitVal((unsigned int *)last)) >> 16; + } } /************************************************************************************** - * Function: CopyNoiseVector - * - * Description: copy vector of noise coefficients for one scalefactor band from L to R - * - * Inputs: buffer of left coefficients - * number of coefficients to copy - * - * Outputs: buffer of right coefficients - * - * Return: none + Function: CopyNoiseVector + + Description: copy vector of noise coefficients for one scalefactor band from L to R + + Inputs: buffer of left coefficients + number of coefficients to copy + + Outputs: buffer of right coefficients + + Return: none **************************************************************************************/ -static void CopyNoiseVector(int *coefL, int *coefR, int nVals) -{ - int i; +static void CopyNoiseVector(int *coefL, int *coefR, int nVals) { + int i; - for (i = 0; i < nVals; i++) - coefR[i] = coefL[i]; + for (i = 0; i < nVals; i++) { + coefR[i] = coefL[i]; + } } /************************************************************************************** - * Function: PNS - * - * Description: apply perceptual noise substitution, if enabled (MPEG-4 only) - * - * Inputs: valid AACDecInfo struct - * index of current channel - * - * Outputs: shaped noise in scalefactor bands where PNS is active - * updated minimum guard bit count for this channel - * - * Return: 0 if successful, -1 if error + Function: PNS + + Description: apply perceptual noise substitution, if enabled (MPEG-4 only) + + Inputs: valid AACDecInfo struct + index of current channel + + Outputs: shaped noise in scalefactor bands where PNS is active + updated minimum guard bit count for this channel + + Return: 0 if successful, -1 if error **************************************************************************************/ -int PNS(AACDecInfo *aacDecInfo, int ch) -{ - int gp, sfb, win, width, nSamps, gb, gbMask; - int *coef; - const /*short*/ int *sfbTab; - unsigned char *sfbCodeBook; - short *scaleFactors; - int msMaskOffset, checkCorr, genNew; - unsigned char msMask; - unsigned char *msMaskPtr; - PSInfoBase *psi; - ICSInfo *icsInfo; - - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return -1; - psi = (PSInfoBase *)(aacDecInfo->psInfoBase); - icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]); - - if (!psi->pnsUsed[ch]) - return 0; - - if (icsInfo->winSequence == 2) { - sfbTab = sfBandTabShort + sfBandTabShortOffset[psi->sampRateIdx]; - nSamps = NSAMPS_SHORT; - } else { - sfbTab = sfBandTabLong + sfBandTabLongOffset[psi->sampRateIdx]; - nSamps = NSAMPS_LONG; - } - coef = psi->coef[ch]; - sfbCodeBook = psi->sfbCodeBook[ch]; - scaleFactors = psi->scaleFactors[ch]; - checkCorr = (aacDecInfo->currBlockID == AAC_ID_CPE && psi->commonWin == 1 ? 1 : 0); - - gbMask = 0; - for (gp = 0; gp < icsInfo->numWinGroup; gp++) { - for (win = 0; win < icsInfo->winGroupLen[gp]; win++) { - msMaskPtr = psi->msMaskBits + ((gp*icsInfo->maxSFB) >> 3); - msMaskOffset = ((gp*icsInfo->maxSFB) & 0x07); - msMask = (*msMaskPtr++) >> msMaskOffset; - - for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) { - width = sfbTab[sfb+1] - sfbTab[sfb]; - if (sfbCodeBook[sfb] == 13) { - if (ch == 0) { - /* generate new vector, copy into ch 1 if it's possible that the channels will be correlated - * if ch 1 has PNS enabled for this SFB but it's uncorrelated (i.e. ms_used == 0), - * the copied values will be overwritten when we process ch 1 - */ - GenerateNoiseVector(coef, &psi->pnsLastVal, width); - if (checkCorr && psi->sfbCodeBook[1][gp*icsInfo->maxSFB + sfb] == 13) - CopyNoiseVector(coef, psi->coef[1] + (coef - psi->coef[0]), width); - } else { - /* generate new vector if no correlation between channels */ - genNew = 1; - if (checkCorr && psi->sfbCodeBook[0][gp*icsInfo->maxSFB + sfb] == 13) { - if ( (psi->msMaskPresent == 1 && (msMask & 0x01)) || psi->msMaskPresent == 2 ) - genNew = 0; - } - if (genNew) - GenerateNoiseVector(coef, &psi->pnsLastVal, width); - } - gbMask |= ScaleNoiseVector(coef, width, psi->scaleFactors[ch][gp*icsInfo->maxSFB + sfb]); - } - coef += width; - - /* get next mask bit (should be branchless on ARM) */ - msMask >>= 1; - if (++msMaskOffset == 8) { - msMask = *msMaskPtr++; - msMaskOffset = 0; - } - } - coef += (nSamps - sfbTab[icsInfo->maxSFB]); - } - sfbCodeBook += icsInfo->maxSFB; - scaleFactors += icsInfo->maxSFB; - } - - /* update guard bit count if necessary */ - gb = CLZ(gbMask) - 1; - if (psi->gbCurrent[ch] > gb) - psi->gbCurrent[ch] = gb; - - return 0; +int PNS(AACDecInfo *aacDecInfo, int ch) { + int gp, sfb, win, width, nSamps, gb, gbMask; + int *coef; + const /*short*/ int *sfbTab; + unsigned char *sfbCodeBook; + short *scaleFactors; + int msMaskOffset, checkCorr, genNew; + unsigned char msMask; + unsigned char *msMaskPtr; + PSInfoBase *psi; + ICSInfo *icsInfo; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return -1; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]); + + if (!psi->pnsUsed[ch]) { + return 0; + } + + if (icsInfo->winSequence == 2) { + sfbTab = sfBandTabShort + sfBandTabShortOffset[psi->sampRateIdx]; + nSamps = NSAMPS_SHORT; + } else { + sfbTab = sfBandTabLong + sfBandTabLongOffset[psi->sampRateIdx]; + nSamps = NSAMPS_LONG; + } + coef = psi->coef[ch]; + sfbCodeBook = psi->sfbCodeBook[ch]; + scaleFactors = psi->scaleFactors[ch]; + checkCorr = (aacDecInfo->currBlockID == AAC_ID_CPE && psi->commonWin == 1 ? 1 : 0); + + gbMask = 0; + for (gp = 0; gp < icsInfo->numWinGroup; gp++) { + for (win = 0; win < icsInfo->winGroupLen[gp]; win++) { + msMaskPtr = psi->msMaskBits + ((gp * icsInfo->maxSFB) >> 3); + msMaskOffset = ((gp * icsInfo->maxSFB) & 0x07); + msMask = (*msMaskPtr++) >> msMaskOffset; + + for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) { + width = sfbTab[sfb + 1] - sfbTab[sfb]; + if (sfbCodeBook[sfb] == 13) { + if (ch == 0) { + /* generate new vector, copy into ch 1 if it's possible that the channels will be correlated + if ch 1 has PNS enabled for this SFB but it's uncorrelated (i.e. ms_used == 0), + the copied values will be overwritten when we process ch 1 + */ + GenerateNoiseVector(coef, &psi->pnsLastVal, width); + if (checkCorr && psi->sfbCodeBook[1][gp * icsInfo->maxSFB + sfb] == 13) { + CopyNoiseVector(coef, psi->coef[1] + (coef - psi->coef[0]), width); + } + } else { + /* generate new vector if no correlation between channels */ + genNew = 1; + if (checkCorr && psi->sfbCodeBook[0][gp * icsInfo->maxSFB + sfb] == 13) { + if ((psi->msMaskPresent == 1 && (msMask & 0x01)) || psi->msMaskPresent == 2) { + genNew = 0; + } + } + if (genNew) { + GenerateNoiseVector(coef, &psi->pnsLastVal, width); + } + } + gbMask |= ScaleNoiseVector(coef, width, psi->scaleFactors[ch][gp * icsInfo->maxSFB + sfb]); + } + coef += width; + + /* get next mask bit (should be branchless on ARM) */ + msMask >>= 1; + if (++msMaskOffset == 8) { + msMask = *msMaskPtr++; + msMaskOffset = 0; + } + } + coef += (nSamps - sfbTab[icsInfo->maxSFB]); + } + sfbCodeBook += icsInfo->maxSFB; + scaleFactors += icsInfo->maxSFB; + } + + /* update guard bit count if necessary */ + gb = CLZ(gbMask) - 1; + if (psi->gbCurrent[ch] > gb) { + psi->gbCurrent[ch] = gb; + } + + return 0; } diff --git a/src/libhelix-aac/sbr.c b/src/libhelix-aac/sbr.c index ec046720..ccaf6114 100644 --- a/src/libhelix-aac/sbr.c +++ b/src/libhelix-aac/sbr.c @@ -1,49 +1,50 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: sbr.c,v 1.3 2005/05/24 16:01:55 albertofloyd Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: sbr.c,v 1.3 2005/05/24 16:01:55 albertofloyd Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * sbr.c - top level functions for SBR + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + sbr.c - top level functions for SBR **************************************************************************************/ #if defined(USE_DEFAULT_STDLIB) || defined(ARDUINO) +#include #include #else #include "hlxclib/stdlib.h" @@ -52,379 +53,393 @@ #include "sbr.h" /************************************************************************************** - * Function: InitSBRState - * - * Description: initialize PSInfoSBR struct at start of stream or after flush - * - * Inputs: valid AACDecInfo struct - * - * Outputs: PSInfoSBR struct with proper initial state - * - * Return: none + Function: InitSBRState + + Description: initialize PSInfoSBR struct at start of stream or after flush + + Inputs: valid AACDecInfo struct + + Outputs: PSInfoSBR struct with proper initial state + + Return: none **************************************************************************************/ -static void InitSBRState(PSInfoSBR *psi) -{ - int i, ch; - unsigned char *c; - - if (!psi) - return; - - /* clear SBR state structure */ - c = (unsigned char *)psi; - for (i = 0; i < (int)sizeof(PSInfoSBR); i++) - *c++ = 0; - - /* initialize non-zero state variables */ - for (ch = 0; ch < AAC_MAX_NCHANS; ch++) { - psi->sbrChan[ch].reset = 1; - psi->sbrChan[ch].laPrev = -1; - } +static void InitSBRState(PSInfoSBR *psi) { + int i, ch; + unsigned char *c; + + if (!psi) { + return; + } + + /* clear SBR state structure */ + c = (unsigned char *)psi; + for (i = 0; i < (int)sizeof(PSInfoSBR); i++) { + *c++ = 0; + } + + /* initialize non-zero state variables */ + for (ch = 0; ch < AAC_MAX_NCHANS; ch++) { + psi->sbrChan[ch].reset = 1; + psi->sbrChan[ch].laPrev = -1; + } } - + /************************************************************************************** - * Function: InitSBR - * - * Description: initialize SBR decoder - * - * Inputs: valid AACDecInfo struct - * - * Outputs: PSInfoSBR struct to hold SBR state information - * - * Return: 0 if successful, error code (< 0) if error - * - * Note: memory allocation for SBR is only done here - **************************************************************************************/ -int InitSBR(AACDecInfo *aacDecInfo) -{ - PSInfoSBR *psi; - - if (!aacDecInfo) - return ERR_AAC_NULL_POINTER; - - /* allocate SBR state structure */ - psi = (PSInfoSBR *)malloc(sizeof(PSInfoSBR)); - if (!psi) { - printf("OOM in SBR, can't allocate %d bytes\n", sizeof(PSInfoSBR)); - return ERR_AAC_SBR_INIT; - } - InitSBRState(psi); - - aacDecInfo->psInfoSBR = psi; - return ERR_AAC_NONE; -} + Function: InitSBR -int InitSBRPre(AACDecInfo *aacDecInfo, void **ptr, int *sz) -{ - PSInfoSBR *psi; + Description: initialize SBR decoder - if (!aacDecInfo) - return ERR_AAC_NULL_POINTER; + Inputs: valid AACDecInfo struct - /* allocate SBR state structure */ - psi = (PSInfoSBR *)*ptr; - *sz -= sizeof(PSInfoSBR); - if (*sz < 0) { - printf("OOM in SBR, can't allocate %d bytes\n", sizeof(PSInfoSBR)); - return ERR_AAC_SBR_INIT; - } - InitSBRState(psi); + Outputs: PSInfoSBR struct to hold SBR state information - *ptr = (void*)((char*)(*ptr) + sizeof(PSInfoSBR)); - aacDecInfo->psInfoSBR = psi; - return ERR_AAC_NONE; + Return: 0 if successful, error code (< 0) if error + + Note: memory allocation for SBR is only done here + **************************************************************************************/ +int InitSBR(AACDecInfo *aacDecInfo) { + PSInfoSBR *psi; + + if (!aacDecInfo) { + return ERR_AAC_NULL_POINTER; + } + + /* allocate SBR state structure */ + psi = (PSInfoSBR *)malloc(sizeof(PSInfoSBR)); + if (!psi) { + printf("OOM in SBR, can't allocate %d bytes\n", sizeof(PSInfoSBR)); + return ERR_AAC_SBR_INIT; + } + InitSBRState(psi); + + aacDecInfo->psInfoSBR = psi; + return ERR_AAC_NONE; +} + +int InitSBRPre(AACDecInfo *aacDecInfo, void **ptr, int *sz) { + PSInfoSBR *psi; + + if (!aacDecInfo) { + return ERR_AAC_NULL_POINTER; + } + + /* allocate SBR state structure */ + psi = (PSInfoSBR *)*ptr; + *sz -= sizeof(PSInfoSBR); + if (*sz < 0) { + printf("OOM in SBR, can't allocate %d bytes\n", sizeof(PSInfoSBR)); + return ERR_AAC_SBR_INIT; + } + InitSBRState(psi); + + *ptr = (void*)((char*)(*ptr) + sizeof(PSInfoSBR)); + aacDecInfo->psInfoSBR = psi; + return ERR_AAC_NONE; } /************************************************************************************** - * Function: FreeSBR - * - * Description: free SBR decoder - * - * Inputs: valid AACDecInfo struct - * - * Outputs: none - * - * Return: none - * - * Note: memory deallocation for SBR is only done here + Function: FreeSBR + + Description: free SBR decoder + + Inputs: valid AACDecInfo struct + + Outputs: none + + Return: none + + Note: memory deallocation for SBR is only done here **************************************************************************************/ -void FreeSBR(AACDecInfo *aacDecInfo) -{ - if (aacDecInfo && aacDecInfo->psInfoSBR) - free(aacDecInfo->psInfoSBR); +void FreeSBR(AACDecInfo *aacDecInfo) { + if (aacDecInfo && aacDecInfo->psInfoSBR) { + free(aacDecInfo->psInfoSBR); + } - return; + return; } /************************************************************************************** - * Function: DecodeSBRBitstream - * - * Description: decode sideband information for SBR - * - * Inputs: valid AACDecInfo struct - * fill buffer with SBR extension block - * number of bytes in fill buffer - * base output channel (range = [0, nChans-1]) - * - * Outputs: initialized state structs (SBRHdr, SBRGrid, SBRFreq, SBRChan) - * - * Return: 0 if successful, error code (< 0) if error - * - * Notes: SBR payload should be in aacDecInfo->fillBuf - * returns with no error if fill buffer is not an SBR extension block, - * or if current block is not a fill block (e.g. for LFE upsampling) + Function: DecodeSBRBitstream + + Description: decode sideband information for SBR + + Inputs: valid AACDecInfo struct + fill buffer with SBR extension block + number of bytes in fill buffer + base output channel (range = [0, nChans-1]) + + Outputs: initialized state structs (SBRHdr, SBRGrid, SBRFreq, SBRChan) + + Return: 0 if successful, error code (< 0) if error + + Notes: SBR payload should be in aacDecInfo->fillBuf + returns with no error if fill buffer is not an SBR extension block, + or if current block is not a fill block (e.g. for LFE upsampling) **************************************************************************************/ -int DecodeSBRBitstream(AACDecInfo *aacDecInfo, int chBase) -{ - int headerFlag; - BitStreamInfo bsi; - PSInfoSBR *psi; - - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoSBR) - return ERR_AAC_NULL_POINTER; - psi = (PSInfoSBR *)(aacDecInfo->psInfoSBR); - - if (aacDecInfo->currBlockID != AAC_ID_FIL || (aacDecInfo->fillExtType != EXT_SBR_DATA && aacDecInfo->fillExtType != EXT_SBR_DATA_CRC)) - return ERR_AAC_NONE; - - SetBitstreamPointer(&bsi, aacDecInfo->fillCount, aacDecInfo->fillBuf); - if (GetBits(&bsi, 4) != (unsigned int)aacDecInfo->fillExtType) - return ERR_AAC_SBR_BITSTREAM; - - if (aacDecInfo->fillExtType == EXT_SBR_DATA_CRC) - psi->crcCheckWord = GetBits(&bsi, 10); - - headerFlag = GetBits(&bsi, 1); - if (headerFlag) { - /* get sample rate index for output sample rate (2x base rate) */ - psi->sampRateIdx = GetSampRateIdx(2 * aacDecInfo->sampRate); - if (psi->sampRateIdx < 0 || psi->sampRateIdx >= NUM_SAMPLE_RATES) - return ERR_AAC_SBR_BITSTREAM; - else if (psi->sampRateIdx >= NUM_SAMPLE_RATES_SBR) - return ERR_AAC_SBR_SINGLERATE_UNSUPPORTED; - - /* reset flag = 1 if header values changed */ - if (UnpackSBRHeader(&bsi, &(psi->sbrHdr[chBase]))) - psi->sbrChan[chBase].reset = 1; - - /* first valid SBR header should always trigger CalcFreqTables(), since psi->reset was set in InitSBR() */ - if (psi->sbrChan[chBase].reset) - CalcFreqTables(&(psi->sbrHdr[chBase+0]), &(psi->sbrFreq[chBase]), psi->sampRateIdx); - - /* copy and reset state to right channel for CPE */ - if (aacDecInfo->prevBlockID == AAC_ID_CPE) - psi->sbrChan[chBase+1].reset = psi->sbrChan[chBase+0].reset; - } - - - /* if no header has been received, upsample only */ - if (psi->sbrHdr[chBase].count == 0) - return ERR_AAC_NONE; - - if (aacDecInfo->prevBlockID == AAC_ID_SCE) { - UnpackSBRSingleChannel(&bsi, psi, chBase); - } else if (aacDecInfo->prevBlockID == AAC_ID_CPE) { - UnpackSBRChannelPair(&bsi, psi, chBase); - } else { - return ERR_AAC_SBR_BITSTREAM; - } - - ByteAlignBitstream(&bsi); - - return ERR_AAC_NONE; +int DecodeSBRBitstream(AACDecInfo *aacDecInfo, int chBase) { + int headerFlag; + BitStreamInfo bsi; + PSInfoSBR *psi; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoSBR) { + return ERR_AAC_NULL_POINTER; + } + psi = (PSInfoSBR *)(aacDecInfo->psInfoSBR); + + if (aacDecInfo->currBlockID != AAC_ID_FIL || (aacDecInfo->fillExtType != EXT_SBR_DATA && aacDecInfo->fillExtType != EXT_SBR_DATA_CRC)) { + return ERR_AAC_NONE; + } + + SetBitstreamPointer(&bsi, aacDecInfo->fillCount, aacDecInfo->fillBuf); + if (GetBits(&bsi, 4) != (unsigned int)aacDecInfo->fillExtType) { + return ERR_AAC_SBR_BITSTREAM; + } + + if (aacDecInfo->fillExtType == EXT_SBR_DATA_CRC) { + psi->crcCheckWord = GetBits(&bsi, 10); + } + + headerFlag = GetBits(&bsi, 1); + if (headerFlag) { + /* get sample rate index for output sample rate (2x base rate) */ + psi->sampRateIdx = GetSampRateIdx(2 * aacDecInfo->sampRate); + if (psi->sampRateIdx < 0 || psi->sampRateIdx >= NUM_SAMPLE_RATES) { + return ERR_AAC_SBR_BITSTREAM; + } else if (psi->sampRateIdx >= NUM_SAMPLE_RATES_SBR) { + return ERR_AAC_SBR_SINGLERATE_UNSUPPORTED; + } + + /* reset flag = 1 if header values changed */ + if (UnpackSBRHeader(&bsi, &(psi->sbrHdr[chBase]))) { + psi->sbrChan[chBase].reset = 1; + } + + /* first valid SBR header should always trigger CalcFreqTables(), since psi->reset was set in InitSBR() */ + if (psi->sbrChan[chBase].reset) { + CalcFreqTables(&(psi->sbrHdr[chBase + 0]), &(psi->sbrFreq[chBase]), psi->sampRateIdx); + } + + /* copy and reset state to right channel for CPE */ + if (aacDecInfo->prevBlockID == AAC_ID_CPE) { + psi->sbrChan[chBase + 1].reset = psi->sbrChan[chBase + 0].reset; + } + } + + + /* if no header has been received, upsample only */ + if (psi->sbrHdr[chBase].count == 0) { + return ERR_AAC_NONE; + } + + if (aacDecInfo->prevBlockID == AAC_ID_SCE) { + UnpackSBRSingleChannel(&bsi, psi, chBase); + } else if (aacDecInfo->prevBlockID == AAC_ID_CPE) { + UnpackSBRChannelPair(&bsi, psi, chBase); + } else { + return ERR_AAC_SBR_BITSTREAM; + } + + ByteAlignBitstream(&bsi); + + return ERR_AAC_NONE; } /************************************************************************************** - * Function: DecodeSBRData - * - * Description: apply SBR to one frame of PCM data - * - * Inputs: 1024 samples of decoded 32-bit PCM, before SBR - * size of input PCM samples (must be 4 bytes) - * number of fraction bits in input PCM samples - * base output channel (range = [0, nChans-1]) - * initialized state structs (SBRHdr, SBRGrid, SBRFreq, SBRChan) - * - * Outputs: 2048 samples of decoded 16-bit PCM, after SBR - * - * Return: 0 if successful, error code (< 0) if error + Function: DecodeSBRData + + Description: apply SBR to one frame of PCM data + + Inputs: 1024 samples of decoded 32-bit PCM, before SBR + size of input PCM samples (must be 4 bytes) + number of fraction bits in input PCM samples + base output channel (range = [0, nChans-1]) + initialized state structs (SBRHdr, SBRGrid, SBRFreq, SBRChan) + + Outputs: 2048 samples of decoded 16-bit PCM, after SBR + + Return: 0 if successful, error code (< 0) if error **************************************************************************************/ -int DecodeSBRData(AACDecInfo *aacDecInfo, int chBase, short *outbuf) -{ - int k, l, ch, chBlock, qmfaBands, qmfsBands; - int upsampleOnly, gbIdx, gbMask; - int *inbuf; - short *outptr; - PSInfoSBR *psi; - SBRHeader *sbrHdr; - SBRGrid *sbrGrid; - SBRFreq *sbrFreq; - SBRChan *sbrChan; - - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoSBR) - return ERR_AAC_NULL_POINTER; - psi = (PSInfoSBR *)(aacDecInfo->psInfoSBR); - - /* same header and freq tables for both channels in CPE */ - sbrHdr = &(psi->sbrHdr[chBase]); - sbrFreq = &(psi->sbrFreq[chBase]); - - /* upsample only if we haven't received an SBR header yet or if we have an LFE block */ - if (aacDecInfo->currBlockID == AAC_ID_LFE) { - chBlock = 1; - upsampleOnly = 1; - } else if (aacDecInfo->currBlockID == AAC_ID_FIL) { - if (aacDecInfo->prevBlockID == AAC_ID_SCE) - chBlock = 1; - else if (aacDecInfo->prevBlockID == AAC_ID_CPE) - chBlock = 2; - else - return ERR_AAC_NONE; - - upsampleOnly = (sbrHdr->count == 0 ? 1 : 0); - if (aacDecInfo->fillExtType != EXT_SBR_DATA && aacDecInfo->fillExtType != EXT_SBR_DATA_CRC) - return ERR_AAC_NONE; - } else { - /* ignore non-SBR blocks */ - return ERR_AAC_NONE; - } - - if (upsampleOnly) { - sbrFreq->kStart = 32; - sbrFreq->numQMFBands = 0; - } - - for (ch = 0; ch < chBlock; ch++) { - sbrGrid = &(psi->sbrGrid[chBase + ch]); - sbrChan = &(psi->sbrChan[chBase + ch]); - - if (aacDecInfo->rawSampleBuf[ch] == 0 || aacDecInfo->rawSampleBytes != 4) - return ERR_AAC_SBR_PCM_FORMAT; - inbuf = (int *)aacDecInfo->rawSampleBuf[ch]; - outptr = outbuf + chBase + ch; - - /* restore delay buffers (could use ring buffer or keep in temp buffer for nChans == 1) */ - for (l = 0; l < HF_GEN; l++) { - for (k = 0; k < 64; k++) { - psi->XBuf[l][k][0] = psi->XBufDelay[chBase + ch][l][k][0]; - psi->XBuf[l][k][1] = psi->XBufDelay[chBase + ch][l][k][1]; - } - } - - /* step 1 - analysis QMF */ - qmfaBands = sbrFreq->kStart; - for (l = 0; l < 32; l++) { - gbMask = QMFAnalysis(inbuf + l*32, psi->delayQMFA[chBase + ch], psi->XBuf[l + HF_GEN][0], - aacDecInfo->rawSampleFBits, &(psi->delayIdxQMFA[chBase + ch]), qmfaBands); - - gbIdx = ((l + HF_GEN) >> 5) & 0x01; - sbrChan->gbMask[gbIdx] |= gbMask; /* gbIdx = (0 if i < 32), (1 if i >= 32) */ - } - - if (upsampleOnly) { - /* no SBR - just run synthesis QMF to upsample by 2x */ - qmfsBands = 32; - for (l = 0; l < 32; l++) { - /* step 4 - synthesis QMF */ - QMFSynthesis(psi->XBuf[l + HF_ADJ][0], psi->delayQMFS[chBase + ch], &(psi->delayIdxQMFS[chBase + ch]), qmfsBands, outptr, aacDecInfo->nChans); - outptr += 64*aacDecInfo->nChans; - } - } else { - /* if previous frame had lower SBR starting freq than current, zero out the synthesized QMF - * bands so they aren't used as sources for patching - * after patch generation, restore from delay buffer - * can only happen after header reset - */ - for (k = sbrFreq->kStartPrev; k < sbrFreq->kStart; k++) { - for (l = 0; l < sbrGrid->envTimeBorder[0] + HF_ADJ; l++) { - psi->XBuf[l][k][0] = 0; - psi->XBuf[l][k][1] = 0; - } - } - - /* step 2 - HF generation */ - GenerateHighFreq(psi, sbrGrid, sbrFreq, sbrChan, ch); - - /* restore SBR bands that were cleared before patch generation (time slots 0, 1 no longer needed) */ - for (k = sbrFreq->kStartPrev; k < sbrFreq->kStart; k++) { - for (l = HF_ADJ; l < sbrGrid->envTimeBorder[0] + HF_ADJ; l++) { - psi->XBuf[l][k][0] = psi->XBufDelay[chBase + ch][l][k][0]; - psi->XBuf[l][k][1] = psi->XBufDelay[chBase + ch][l][k][1]; - } - } - - /* step 3 - HF adjustment */ - AdjustHighFreq(psi, sbrHdr, sbrGrid, sbrFreq, sbrChan, ch); - - /* step 4 - synthesis QMF */ - qmfsBands = sbrFreq->kStartPrev + sbrFreq->numQMFBandsPrev; - for (l = 0; l < sbrGrid->envTimeBorder[0]; l++) { - /* if new envelope starts mid-frame, use old settings until start of first envelope in this frame */ - QMFSynthesis(psi->XBuf[l + HF_ADJ][0], psi->delayQMFS[chBase + ch], &(psi->delayIdxQMFS[chBase + ch]), qmfsBands, outptr, aacDecInfo->nChans); - outptr += 64*aacDecInfo->nChans; - } - - qmfsBands = sbrFreq->kStart + sbrFreq->numQMFBands; - for ( ; l < 32; l++) { - /* use new settings for rest of frame (usually the entire frame, unless the first envelope starts mid-frame) */ - QMFSynthesis(psi->XBuf[l + HF_ADJ][0], psi->delayQMFS[chBase + ch], &(psi->delayIdxQMFS[chBase + ch]), qmfsBands, outptr, aacDecInfo->nChans); - outptr += 64*aacDecInfo->nChans; - } - } - - /* save delay */ - for (l = 0; l < HF_GEN; l++) { - for (k = 0; k < 64; k++) { - psi->XBufDelay[chBase + ch][l][k][0] = psi->XBuf[l+32][k][0]; - psi->XBufDelay[chBase + ch][l][k][1] = psi->XBuf[l+32][k][1]; - } - } - sbrChan->gbMask[0] = sbrChan->gbMask[1]; - sbrChan->gbMask[1] = 0; - - if (sbrHdr->count > 0) - sbrChan->reset = 0; - } - sbrFreq->kStartPrev = sbrFreq->kStart; - sbrFreq->numQMFBandsPrev = sbrFreq->numQMFBands; - - if (aacDecInfo->nChans > 0 && (chBase + ch) == aacDecInfo->nChans) - psi->frameCount++; - - return ERR_AAC_NONE; +int DecodeSBRData(AACDecInfo *aacDecInfo, int chBase, short *outbuf) { + int k, l, ch, chBlock, qmfaBands, qmfsBands; + int upsampleOnly, gbIdx, gbMask; + int *inbuf; + short *outptr; + PSInfoSBR *psi; + SBRHeader *sbrHdr; + SBRGrid *sbrGrid; + SBRFreq *sbrFreq; + SBRChan *sbrChan; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoSBR) { + return ERR_AAC_NULL_POINTER; + } + psi = (PSInfoSBR *)(aacDecInfo->psInfoSBR); + + /* same header and freq tables for both channels in CPE */ + sbrHdr = &(psi->sbrHdr[chBase]); + sbrFreq = &(psi->sbrFreq[chBase]); + + /* upsample only if we haven't received an SBR header yet or if we have an LFE block */ + if (aacDecInfo->currBlockID == AAC_ID_LFE) { + chBlock = 1; + upsampleOnly = 1; + } else if (aacDecInfo->currBlockID == AAC_ID_FIL) { + if (aacDecInfo->prevBlockID == AAC_ID_SCE) { + chBlock = 1; + } else if (aacDecInfo->prevBlockID == AAC_ID_CPE) { + chBlock = 2; + } else { + return ERR_AAC_NONE; + } + + upsampleOnly = (sbrHdr->count == 0 ? 1 : 0); + if (aacDecInfo->fillExtType != EXT_SBR_DATA && aacDecInfo->fillExtType != EXT_SBR_DATA_CRC) { + return ERR_AAC_NONE; + } + } else { + /* ignore non-SBR blocks */ + return ERR_AAC_NONE; + } + + if (upsampleOnly) { + sbrFreq->kStart = 32; + sbrFreq->numQMFBands = 0; + } + + for (ch = 0; ch < chBlock; ch++) { + sbrGrid = &(psi->sbrGrid[chBase + ch]); + sbrChan = &(psi->sbrChan[chBase + ch]); + + if (aacDecInfo->rawSampleBuf[ch] == 0 || aacDecInfo->rawSampleBytes != 4) { + return ERR_AAC_SBR_PCM_FORMAT; + } + inbuf = (int *)aacDecInfo->rawSampleBuf[ch]; + outptr = outbuf + chBase + ch; + + /* restore delay buffers (could use ring buffer or keep in temp buffer for nChans == 1) */ + for (l = 0; l < HF_GEN; l++) { + for (k = 0; k < 64; k++) { + psi->XBuf[l][k][0] = psi->XBufDelay[chBase + ch][l][k][0]; + psi->XBuf[l][k][1] = psi->XBufDelay[chBase + ch][l][k][1]; + } + } + + /* step 1 - analysis QMF */ + qmfaBands = sbrFreq->kStart; + for (l = 0; l < 32; l++) { + gbMask = QMFAnalysis(inbuf + l * 32, psi->delayQMFA[chBase + ch], psi->XBuf[l + HF_GEN][0], + aacDecInfo->rawSampleFBits, &(psi->delayIdxQMFA[chBase + ch]), qmfaBands); + + gbIdx = ((l + HF_GEN) >> 5) & 0x01; + sbrChan->gbMask[gbIdx] |= gbMask; /* gbIdx = (0 if i < 32), (1 if i >= 32) */ + } + + if (upsampleOnly) { + /* no SBR - just run synthesis QMF to upsample by 2x */ + qmfsBands = 32; + for (l = 0; l < 32; l++) { + /* step 4 - synthesis QMF */ + QMFSynthesis(psi->XBuf[l + HF_ADJ][0], psi->delayQMFS[chBase + ch], &(psi->delayIdxQMFS[chBase + ch]), qmfsBands, outptr, aacDecInfo->nChans); + outptr += 64 * aacDecInfo->nChans; + } + } else { + /* if previous frame had lower SBR starting freq than current, zero out the synthesized QMF + bands so they aren't used as sources for patching + after patch generation, restore from delay buffer + can only happen after header reset + */ + for (k = sbrFreq->kStartPrev; k < sbrFreq->kStart; k++) { + for (l = 0; l < sbrGrid->envTimeBorder[0] + HF_ADJ; l++) { + psi->XBuf[l][k][0] = 0; + psi->XBuf[l][k][1] = 0; + } + } + + /* step 2 - HF generation */ + GenerateHighFreq(psi, sbrGrid, sbrFreq, sbrChan, ch); + + /* restore SBR bands that were cleared before patch generation (time slots 0, 1 no longer needed) */ + for (k = sbrFreq->kStartPrev; k < sbrFreq->kStart; k++) { + for (l = HF_ADJ; l < sbrGrid->envTimeBorder[0] + HF_ADJ; l++) { + psi->XBuf[l][k][0] = psi->XBufDelay[chBase + ch][l][k][0]; + psi->XBuf[l][k][1] = psi->XBufDelay[chBase + ch][l][k][1]; + } + } + + /* step 3 - HF adjustment */ + AdjustHighFreq(psi, sbrHdr, sbrGrid, sbrFreq, sbrChan, ch); + + /* step 4 - synthesis QMF */ + qmfsBands = sbrFreq->kStartPrev + sbrFreq->numQMFBandsPrev; + for (l = 0; l < sbrGrid->envTimeBorder[0]; l++) { + /* if new envelope starts mid-frame, use old settings until start of first envelope in this frame */ + QMFSynthesis(psi->XBuf[l + HF_ADJ][0], psi->delayQMFS[chBase + ch], &(psi->delayIdxQMFS[chBase + ch]), qmfsBands, outptr, aacDecInfo->nChans); + outptr += 64 * aacDecInfo->nChans; + } + + qmfsBands = sbrFreq->kStart + sbrFreq->numQMFBands; + for (; l < 32; l++) { + /* use new settings for rest of frame (usually the entire frame, unless the first envelope starts mid-frame) */ + QMFSynthesis(psi->XBuf[l + HF_ADJ][0], psi->delayQMFS[chBase + ch], &(psi->delayIdxQMFS[chBase + ch]), qmfsBands, outptr, aacDecInfo->nChans); + outptr += 64 * aacDecInfo->nChans; + } + } + + /* save delay */ + for (l = 0; l < HF_GEN; l++) { + for (k = 0; k < 64; k++) { + psi->XBufDelay[chBase + ch][l][k][0] = psi->XBuf[l + 32][k][0]; + psi->XBufDelay[chBase + ch][l][k][1] = psi->XBuf[l + 32][k][1]; + } + } + sbrChan->gbMask[0] = sbrChan->gbMask[1]; + sbrChan->gbMask[1] = 0; + + if (sbrHdr->count > 0) { + sbrChan->reset = 0; + } + } + sbrFreq->kStartPrev = sbrFreq->kStart; + sbrFreq->numQMFBandsPrev = sbrFreq->numQMFBands; + + if (aacDecInfo->nChans > 0 && (chBase + ch) == aacDecInfo->nChans) { + psi->frameCount++; + } + + return ERR_AAC_NONE; } /************************************************************************************** - * Function: FlushCodecSBR - * - * Description: flush internal SBR codec state (after seeking, for example) - * - * Inputs: valid AACDecInfo struct - * - * Outputs: updated state variables for SBR - * - * Return: 0 if successful, error code (< 0) if error - * - * Notes: SBR is heavily dependent on state from previous frames - * (e.g. delta coded scalefactors, previous envelope boundaries, etc.) - * On flush, we reset everything as if SBR had just been initialized - * for the first time. This triggers "upsample-only" mode until - * the first valid SBR header is received. Then SBR starts as usual. + Function: FlushCodecSBR + + Description: flush internal SBR codec state (after seeking, for example) + + Inputs: valid AACDecInfo struct + + Outputs: updated state variables for SBR + + Return: 0 if successful, error code (< 0) if error + + Notes: SBR is heavily dependent on state from previous frames + (e.g. delta coded scalefactors, previous envelope boundaries, etc.) + On flush, we reset everything as if SBR had just been initialized + for the first time. This triggers "upsample-only" mode until + the first valid SBR header is received. Then SBR starts as usual. **************************************************************************************/ -int FlushCodecSBR(AACDecInfo *aacDecInfo) -{ - PSInfoSBR *psi; +int FlushCodecSBR(AACDecInfo *aacDecInfo) { + PSInfoSBR *psi; - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoSBR) - return ERR_AAC_NULL_POINTER; - psi = (PSInfoSBR *)(aacDecInfo->psInfoSBR); + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoSBR) { + return ERR_AAC_NULL_POINTER; + } + psi = (PSInfoSBR *)(aacDecInfo->psInfoSBR); - InitSBRState(psi); + InitSBRState(psi); - return 0; + return 0; } diff --git a/src/libhelix-aac/sbr.h b/src/libhelix-aac/sbr.h index 6c898a13..4c70606b 100644 --- a/src/libhelix-aac/sbr.h +++ b/src/libhelix-aac/sbr.h @@ -1,46 +1,46 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: sbr.h,v 1.2 2005/05/20 18:05:41 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: sbr.h,v 1.2 2005/05/20 18:05:41 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * sbr.h - definitions of platform-specific SBR data structures, functions, and tables + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + sbr.h - definitions of platform-specific SBR data structures, functions, and tables **************************************************************************************/ #ifndef _SBR_H @@ -147,192 +147,196 @@ } /* -#define CLIP_2N(y, n) { \ + #define CLIP_2N(y, n) { \ int sign = (y) >> 31; \ if (sign != ((y) >> (n))) { \ (y) = sign ^ ((1 << (n)) - 1); \ } \ -} + } */ enum { - SBR_GRID_FIXFIX = 0, - SBR_GRID_FIXVAR = 1, - SBR_GRID_VARFIX = 2, - SBR_GRID_VARVAR = 3 + SBR_GRID_FIXFIX = 0, + SBR_GRID_FIXVAR = 1, + SBR_GRID_VARFIX = 2, + SBR_GRID_VARVAR = 3 }; enum { - HuffTabSBR_tEnv15 = 0, - HuffTabSBR_fEnv15 = 1, - HuffTabSBR_tEnv15b = 2, - HuffTabSBR_fEnv15b = 3, - HuffTabSBR_tEnv30 = 4, - HuffTabSBR_fEnv30 = 5, - HuffTabSBR_tEnv30b = 6, - HuffTabSBR_fEnv30b = 7, - HuffTabSBR_tNoise30 = 8, - HuffTabSBR_fNoise30 = 5, - HuffTabSBR_tNoise30b = 9, - HuffTabSBR_fNoise30b = 7 + HuffTabSBR_tEnv15 = 0, + HuffTabSBR_fEnv15 = 1, + HuffTabSBR_tEnv15b = 2, + HuffTabSBR_fEnv15b = 3, + HuffTabSBR_tEnv30 = 4, + HuffTabSBR_fEnv30 = 5, + HuffTabSBR_tEnv30b = 6, + HuffTabSBR_fEnv30b = 7, + HuffTabSBR_tNoise30 = 8, + HuffTabSBR_fNoise30 = 5, + HuffTabSBR_tNoise30b = 9, + HuffTabSBR_fNoise30b = 7 }; typedef struct _HuffInfo { - int maxBits; /* number of bits in longest codeword */ + int maxBits; /* number of bits in longest codeword */ +#ifdef ESP8266 unsigned /*char*/ int count[MAX_HUFF_BITS]; /* count[i] = number of codes with length i+1 bits */ - int offset; /* offset into symbol table */ +#else + unsigned char count[MAX_HUFF_BITS]; /* count[i] = number of codes with length i+1 bits */ +#endif + int offset; /* offset into symbol table */ } HuffInfo; /* need one SBRHeader per element (SCE/CPE), updated only on new header */ typedef struct _SBRHeader { - int count; - - unsigned char ampRes; - unsigned char startFreq; - unsigned char stopFreq; - unsigned char crossOverBand; - unsigned char resBitsHdr; - unsigned char hdrExtra1; - unsigned char hdrExtra2; - - unsigned char freqScale; - unsigned char alterScale; - unsigned char noiseBands; - - unsigned char limiterBands; - unsigned char limiterGains; - unsigned char interpFreq; - unsigned char smoothMode; + int count; + + unsigned char ampRes; + unsigned char startFreq; + unsigned char stopFreq; + unsigned char crossOverBand; + unsigned char resBitsHdr; + unsigned char hdrExtra1; + unsigned char hdrExtra2; + + unsigned char freqScale; + unsigned char alterScale; + unsigned char noiseBands; + + unsigned char limiterBands; + unsigned char limiterGains; + unsigned char interpFreq; + unsigned char smoothMode; } SBRHeader; /* need one SBRGrid per channel, updated every frame */ typedef struct _SBRGrid { - unsigned char frameClass; - unsigned char ampResFrame; - unsigned char pointer; + unsigned char frameClass; + unsigned char ampResFrame; + unsigned char pointer; - unsigned char numEnv; /* L_E */ - unsigned char envTimeBorder[MAX_NUM_ENV+1]; /* t_E */ - unsigned char freqRes[MAX_NUM_ENV]; /* r */ + unsigned char numEnv; /* L_E */ + unsigned char envTimeBorder[MAX_NUM_ENV + 1]; /* t_E */ + unsigned char freqRes[MAX_NUM_ENV]; /* r */ - unsigned char numNoiseFloors; /* L_Q */ - unsigned char noiseTimeBorder[MAX_NUM_NOISE_FLOORS+1]; /* t_Q */ + unsigned char numNoiseFloors; /* L_Q */ + unsigned char noiseTimeBorder[MAX_NUM_NOISE_FLOORS + 1]; /* t_Q */ - unsigned char numEnvPrev; - unsigned char numNoiseFloorsPrev; - unsigned char freqResPrev; + unsigned char numEnvPrev; + unsigned char numNoiseFloorsPrev; + unsigned char freqResPrev; } SBRGrid; /* need one SBRFreq per element (SCE/CPE/LFE), updated only on header reset */ typedef struct _SBRFreq { - int kStart; /* k_x */ - int nMaster; - int nHigh; - int nLow; - int nLimiter; /* N_l */ - int numQMFBands; /* M */ - int numNoiseFloorBands; /* Nq */ - - int kStartPrev; - int numQMFBandsPrev; - - unsigned char freqMaster[MAX_QMF_BANDS + 1]; /* not necessary to save this after derived tables are generated */ - unsigned char freqHigh[MAX_QMF_BANDS + 1]; - unsigned char freqLow[MAX_QMF_BANDS / 2 + 1]; /* nLow = nHigh - (nHigh >> 1) */ - unsigned char freqNoise[MAX_NUM_NOISE_FLOOR_BANDS+1]; - unsigned char freqLimiter[MAX_QMF_BANDS / 2 + MAX_NUM_PATCHES]; /* max (intermediate) size = nLow + numPatches - 1 */ - - unsigned char numPatches; - unsigned char patchNumSubbands[MAX_NUM_PATCHES + 1]; - unsigned char patchStartSubband[MAX_NUM_PATCHES + 1]; + int kStart; /* k_x */ + int nMaster; + int nHigh; + int nLow; + int nLimiter; /* N_l */ + int numQMFBands; /* M */ + int numNoiseFloorBands; /* Nq */ + + int kStartPrev; + int numQMFBandsPrev; + + unsigned char freqMaster[MAX_QMF_BANDS + 1]; /* not necessary to save this after derived tables are generated */ + unsigned char freqHigh[MAX_QMF_BANDS + 1]; + unsigned char freqLow[MAX_QMF_BANDS / 2 + 1]; /* nLow = nHigh - (nHigh >> 1) */ + unsigned char freqNoise[MAX_NUM_NOISE_FLOOR_BANDS + 1]; + unsigned char freqLimiter[MAX_QMF_BANDS / 2 + MAX_NUM_PATCHES]; /* max (intermediate) size = nLow + numPatches - 1 */ + + unsigned char numPatches; + unsigned char patchNumSubbands[MAX_NUM_PATCHES + 1]; + unsigned char patchStartSubband[MAX_NUM_PATCHES + 1]; } SBRFreq; typedef struct _SBRChan { - int reset; - unsigned char deltaFlagEnv[MAX_NUM_ENV]; - unsigned char deltaFlagNoise[MAX_NUM_NOISE_FLOORS]; - - signed char envDataQuant[MAX_NUM_ENV][MAX_QMF_BANDS]; /* range = [0, 127] */ - signed char noiseDataQuant[MAX_NUM_NOISE_FLOORS][MAX_NUM_NOISE_FLOOR_BANDS]; - - unsigned char invfMode[2][MAX_NUM_NOISE_FLOOR_BANDS]; /* invfMode[0/1][band] = prev/curr */ - int chirpFact[MAX_NUM_NOISE_FLOOR_BANDS]; /* bwArray */ - unsigned char addHarmonicFlag[2]; /* addHarmonicFlag[0/1] = prev/curr */ - unsigned char addHarmonic[2][64]; /* addHarmonic[0/1][band] = prev/curr */ - - int gbMask[2]; /* gbMask[0/1] = XBuf[0-31]/XBuf[32-39] */ - signed char laPrev; - - int noiseTabIndex; - int sinIndex; - int gainNoiseIndex; - int gTemp[MAX_NUM_SMOOTH_COEFS][MAX_QMF_BANDS]; - int qTemp[MAX_NUM_SMOOTH_COEFS][MAX_QMF_BANDS]; + int reset; + unsigned char deltaFlagEnv[MAX_NUM_ENV]; + unsigned char deltaFlagNoise[MAX_NUM_NOISE_FLOORS]; + + signed char envDataQuant[MAX_NUM_ENV][MAX_QMF_BANDS]; /* range = [0, 127] */ + signed char noiseDataQuant[MAX_NUM_NOISE_FLOORS][MAX_NUM_NOISE_FLOOR_BANDS]; + + unsigned char invfMode[2][MAX_NUM_NOISE_FLOOR_BANDS]; /* invfMode[0/1][band] = prev/curr */ + int chirpFact[MAX_NUM_NOISE_FLOOR_BANDS]; /* bwArray */ + unsigned char addHarmonicFlag[2]; /* addHarmonicFlag[0/1] = prev/curr */ + unsigned char addHarmonic[2][64]; /* addHarmonic[0/1][band] = prev/curr */ + + int gbMask[2]; /* gbMask[0/1] = XBuf[0-31]/XBuf[32-39] */ + signed char laPrev; + + int noiseTabIndex; + int sinIndex; + int gainNoiseIndex; + int gTemp[MAX_NUM_SMOOTH_COEFS][MAX_QMF_BANDS]; + int qTemp[MAX_NUM_SMOOTH_COEFS][MAX_QMF_BANDS]; } SBRChan; typedef struct _PSInfoSBR { - /* save for entire file */ - int frameCount; - int sampRateIdx; - - /* state info that must be saved for each channel */ - SBRHeader sbrHdr[AAC_MAX_NCHANS]; - SBRGrid sbrGrid[AAC_MAX_NCHANS]; - SBRFreq sbrFreq[AAC_MAX_NCHANS]; - SBRChan sbrChan[AAC_MAX_NCHANS]; - - /* temp variables, no need to save between blocks */ - unsigned char dataExtra; - unsigned char resBitsData; - unsigned char extendedDataPresent; - int extendedDataSize; - - signed char envDataDequantScale[MAX_NCHANS_ELEM][MAX_NUM_ENV]; - int envDataDequant[MAX_NCHANS_ELEM][MAX_NUM_ENV][MAX_QMF_BANDS]; - int noiseDataDequant[MAX_NCHANS_ELEM][MAX_NUM_NOISE_FLOORS][MAX_NUM_NOISE_FLOOR_BANDS]; - - int eCurr[MAX_QMF_BANDS]; - unsigned char eCurrExp[MAX_QMF_BANDS]; - unsigned char eCurrExpMax; - signed char la; - - int crcCheckWord; - int couplingFlag; - int envBand; - int eOMGainMax; - int gainMax; - int gainMaxFBits; - int noiseFloorBand; - int qp1Inv; - int qqp1Inv; - int sMapped; - int sBand; - int highBand; - - int sumEOrigMapped; - int sumECurrGLim; - int sumSM; - int sumQM; - int gLimBoost[MAX_QMF_BANDS]; - int qmLimBoost[MAX_QMF_BANDS]; - int smBoost[MAX_QMF_BANDS]; - - int smBuf[MAX_QMF_BANDS]; - int qmLimBuf[MAX_QMF_BANDS]; - int gLimBuf[MAX_QMF_BANDS]; - int gLimFbits[MAX_QMF_BANDS]; - - int gFiltLast[MAX_QMF_BANDS]; - int qFiltLast[MAX_QMF_BANDS]; - - /* large buffers */ - int delayIdxQMFA[AAC_MAX_NCHANS]; - int delayQMFA[AAC_MAX_NCHANS][DELAY_SAMPS_QMFA]; - int delayIdxQMFS[AAC_MAX_NCHANS]; - int delayQMFS[AAC_MAX_NCHANS][DELAY_SAMPS_QMFS]; - int XBufDelay[AAC_MAX_NCHANS][HF_GEN][64][2]; - int XBuf[32+8][64][2]; + /* save for entire file */ + int frameCount; + int sampRateIdx; + + /* state info that must be saved for each channel */ + SBRHeader sbrHdr[AAC_MAX_NCHANS]; + SBRGrid sbrGrid[AAC_MAX_NCHANS]; + SBRFreq sbrFreq[AAC_MAX_NCHANS]; + SBRChan sbrChan[AAC_MAX_NCHANS]; + + /* temp variables, no need to save between blocks */ + unsigned char dataExtra; + unsigned char resBitsData; + unsigned char extendedDataPresent; + int extendedDataSize; + + signed char envDataDequantScale[MAX_NCHANS_ELEM][MAX_NUM_ENV]; + int envDataDequant[MAX_NCHANS_ELEM][MAX_NUM_ENV][MAX_QMF_BANDS]; + int noiseDataDequant[MAX_NCHANS_ELEM][MAX_NUM_NOISE_FLOORS][MAX_NUM_NOISE_FLOOR_BANDS]; + + int eCurr[MAX_QMF_BANDS]; + unsigned char eCurrExp[MAX_QMF_BANDS]; + unsigned char eCurrExpMax; + signed char la; + + int crcCheckWord; + int couplingFlag; + int envBand; + int eOMGainMax; + int gainMax; + int gainMaxFBits; + int noiseFloorBand; + int qp1Inv; + int qqp1Inv; + int sMapped; + int sBand; + int highBand; + + int sumEOrigMapped; + int sumECurrGLim; + int sumSM; + int sumQM; + int gLimBoost[MAX_QMF_BANDS]; + int qmLimBoost[MAX_QMF_BANDS]; + int smBoost[MAX_QMF_BANDS]; + + int smBuf[MAX_QMF_BANDS]; + int qmLimBuf[MAX_QMF_BANDS]; + int gLimBuf[MAX_QMF_BANDS]; + int gLimFbits[MAX_QMF_BANDS]; + + int gFiltLast[MAX_QMF_BANDS]; + int qFiltLast[MAX_QMF_BANDS]; + + /* large buffers */ + int delayIdxQMFA[AAC_MAX_NCHANS]; + int delayQMFA[AAC_MAX_NCHANS][DELAY_SAMPS_QMFA]; + int delayIdxQMFS[AAC_MAX_NCHANS]; + int delayQMFS[AAC_MAX_NCHANS][DELAY_SAMPS_QMFS]; + int XBufDelay[AAC_MAX_NCHANS][HF_GEN][64][2]; + int XBuf[32 + 8][64][2]; } PSInfoSBR; @@ -374,9 +378,13 @@ extern const unsigned char k0Tab[NUM_SAMPLE_RATES_SBR][16]; extern const unsigned char k2Tab[NUM_SAMPLE_RATES_SBR][14]; extern const unsigned char goalSBTab[NUM_SAMPLE_RATES_SBR]; extern const HuffInfo huffTabSBRInfo[10]; +#ifdef ESP8266 extern const signed int /*short*/ huffTabSBR[604]; +#else +extern const signed short huffTabSBR[604]; +#endif extern const int log2Tab[65]; -extern const int noiseTab[512*2]; +extern const int noiseTab[512 * 2]; extern const int cTabA[165]; extern const int cTabS[640]; diff --git a/src/libhelix-aac/sbrfft.c b/src/libhelix-aac/sbrfft.c index 23b36ac3..fdd895e9 100644 --- a/src/libhelix-aac/sbrfft.c +++ b/src/libhelix-aac/sbrfft.c @@ -1,46 +1,46 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: sbrfft.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: sbrfft.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * February 2005 - * - * sbrfft.c - optimized FFT for SBR QMF filters + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + February 2005 + + sbrfft.c - optimized FFT for SBR QMF filters **************************************************************************************/ #include "sbr.h" @@ -52,317 +52,313 @@ #define swapcplx(p0,p1) \ t = p0; t1 = *(&(p0)+1); p0 = p1; *(&(p0)+1) = *(&(p1)+1); p1 = t; *(&(p1)+1) = t1 -/* nfft = 32, hard coded since small, fixed size FFT -static const unsigned char bitrevtab32[9] = { +/* nfft = 32, hard coded since small, fixed size FFT + static const unsigned char bitrevtab32[9] = { 0x01, 0x04, 0x03, 0x06, 0x00, 0x02, 0x05, 0x07, 0x00, -}; + }; */ /* twiddle table for radix 4 pass, format = Q31 */ -static const int twidTabOdd32[8*6] = { - 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x539eba45, 0xe7821d59, - 0x4b418bbe, 0xf383a3e2, 0x58c542c5, 0xdc71898d, 0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59, - 0x539eba45, 0xc4df2862, 0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d, 0x3248d382, 0xc13ad060, - 0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x22a2f4f8, 0xc4df2862, - 0x58c542c5, 0xcac933ae, 0xcdb72c7e, 0xf383a3e2, 0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, - 0xac6145bb, 0x187de2a7, 0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060, 0xa73abd3b, 0x3536cc52, +static const int twidTabOdd32[8 * 6] = { + 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x539eba45, 0xe7821d59, + 0x4b418bbe, 0xf383a3e2, 0x58c542c5, 0xdc71898d, 0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59, + 0x539eba45, 0xc4df2862, 0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d, 0x3248d382, 0xc13ad060, + 0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x22a2f4f8, 0xc4df2862, + 0x58c542c5, 0xcac933ae, 0xcdb72c7e, 0xf383a3e2, 0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, + 0xac6145bb, 0x187de2a7, 0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060, 0xa73abd3b, 0x3536cc52, }; /************************************************************************************** - * Function: BitReverse32 - * - * Description: Ken's fast in-place bit reverse - * - * Inputs: buffer of 32 complex samples - * - * Outputs: bit-reversed samples in same buffer - * - * Return: none + Function: BitReverse32 + + Description: Ken's fast in-place bit reverse + + Inputs: buffer of 32 complex samples + + Outputs: bit-reversed samples in same buffer + + Return: none **************************************************************************************/ -static void BitReverse32(int *inout) -{ - int t, t1; - - swapcplx(inout[2], inout[32]); - swapcplx(inout[4], inout[16]); - swapcplx(inout[6], inout[48]); - swapcplx(inout[10], inout[40]); - swapcplx(inout[12], inout[24]); - swapcplx(inout[14], inout[56]); - swapcplx(inout[18], inout[36]); - swapcplx(inout[22], inout[52]); - swapcplx(inout[26], inout[44]); - swapcplx(inout[30], inout[60]); - swapcplx(inout[38], inout[50]); - swapcplx(inout[46], inout[58]); +static void BitReverse32(int *inout) { + int t, t1; + + swapcplx(inout[2], inout[32]); + swapcplx(inout[4], inout[16]); + swapcplx(inout[6], inout[48]); + swapcplx(inout[10], inout[40]); + swapcplx(inout[12], inout[24]); + swapcplx(inout[14], inout[56]); + swapcplx(inout[18], inout[36]); + swapcplx(inout[22], inout[52]); + swapcplx(inout[26], inout[44]); + swapcplx(inout[30], inout[60]); + swapcplx(inout[38], inout[50]); + swapcplx(inout[46], inout[58]); } /************************************************************************************** - * Function: R8FirstPass32 - * - * Description: radix-8 trivial pass for decimation-in-time FFT (log2(N) = 5) - * - * Inputs: buffer of (bit-reversed) samples - * - * Outputs: processed samples in same buffer - * - * Return: none - * - * Notes: assumes 3 guard bits, gains 1 integer bit - * guard bits out = guard bits in - 3 (if inputs are full scale) - * or guard bits in - 2 (if inputs bounded to +/- sqrt(2)/2) - * see scaling comments in fft.c for base AAC - * should compile with no stack spills on ARM (verify compiled output) - * current instruction count (per pass): 16 LDR, 16 STR, 4 SMULL, 61 ALU + Function: R8FirstPass32 + + Description: radix-8 trivial pass for decimation-in-time FFT (log2(N) = 5) + + Inputs: buffer of (bit-reversed) samples + + Outputs: processed samples in same buffer + + Return: none + + Notes: assumes 3 guard bits, gains 1 integer bit + guard bits out = guard bits in - 3 (if inputs are full scale) + or guard bits in - 2 (if inputs bounded to +/- sqrt(2)/2) + see scaling comments in fft.c for base AAC + should compile with no stack spills on ARM (verify compiled output) + current instruction count (per pass): 16 LDR, 16 STR, 4 SMULL, 61 ALU **************************************************************************************/ -static void R8FirstPass32(int *r0) -{ - int r1, r2, r3, r4, r5, r6, r7; - int r8, r9, r10, r11, r12, r14; - - /* number of passes = fft size / 8 = 32 / 8 = 4 */ - r1 = (32 >> 3); - do { - - r2 = r0[8]; - r3 = r0[9]; - r4 = r0[10]; - r5 = r0[11]; - r6 = r0[12]; - r7 = r0[13]; - r8 = r0[14]; - r9 = r0[15]; - - r10 = r2 + r4; - r11 = r3 + r5; - r12 = r6 + r8; - r14 = r7 + r9; - - r2 -= r4; - r3 -= r5; - r6 -= r8; - r7 -= r9; - - r4 = r2 - r7; - r5 = r2 + r7; - r8 = r3 - r6; - r9 = r3 + r6; - - r2 = r4 - r9; - r3 = r4 + r9; - r6 = r5 - r8; - r7 = r5 + r8; - - r2 = MULSHIFT32(SQRT1_2, r2); /* can use r4, r5, r8, or r9 for constant and lo32 scratch reg */ - r3 = MULSHIFT32(SQRT1_2, r3); - r6 = MULSHIFT32(SQRT1_2, r6); - r7 = MULSHIFT32(SQRT1_2, r7); - - r4 = r10 + r12; - r5 = r10 - r12; - r8 = r11 + r14; - r9 = r11 - r14; - - r10 = r0[0]; - r11 = r0[2]; - r12 = r0[4]; - r14 = r0[6]; - - r10 += r11; - r12 += r14; - - r4 >>= 1; - r10 += r12; - r4 += (r10 >> 1); - r0[ 0] = r4; - r4 -= (r10 >> 1); - r4 = (r10 >> 1) - r4; - r0[ 8] = r4; - - r9 >>= 1; - r10 -= 2*r12; - r4 = (r10 >> 1) + r9; - r0[ 4] = r4; - r4 = (r10 >> 1) - r9; - r0[12] = r4; - r10 += r12; - - r10 -= 2*r11; - r12 -= 2*r14; - - r4 = r0[1]; - r9 = r0[3]; - r11 = r0[5]; - r14 = r0[7]; - - r4 += r9; - r11 += r14; - - r8 >>= 1; - r4 += r11; - r8 += (r4 >> 1); - r0[ 1] = r8; - r8 -= (r4 >> 1); - r8 = (r4 >> 1) - r8; - r0[ 9] = r8; - - r5 >>= 1; - r4 -= 2*r11; - r8 = (r4 >> 1) - r5; - r0[ 5] = r8; - r8 = (r4 >> 1) + r5; - r0[13] = r8; - r4 += r11; - - r4 -= 2*r9; - r11 -= 2*r14; - - r9 = r10 - r11; - r10 += r11; - r14 = r4 + r12; - r4 -= r12; - - r5 = (r10 >> 1) + r7; - r8 = (r4 >> 1) - r6; - r0[ 2] = r5; - r0[ 3] = r8; - - r5 = (r9 >> 1) - r2; - r8 = (r14 >> 1) - r3; - r0[ 6] = r5; - r0[ 7] = r8; - - r5 = (r10 >> 1) - r7; - r8 = (r4 >> 1) + r6; - r0[10] = r5; - r0[11] = r8; - - r5 = (r9 >> 1) + r2; - r8 = (r14 >> 1) + r3; - r0[14] = r5; - r0[15] = r8; - - r0 += 16; - r1--; - } while (r1 != 0); +static void R8FirstPass32(int *r0) { + int r1, r2, r3, r4, r5, r6, r7; + int r8, r9, r10, r11, r12, r14; + + /* number of passes = fft size / 8 = 32 / 8 = 4 */ + r1 = (32 >> 3); + do { + + r2 = r0[8]; + r3 = r0[9]; + r4 = r0[10]; + r5 = r0[11]; + r6 = r0[12]; + r7 = r0[13]; + r8 = r0[14]; + r9 = r0[15]; + + r10 = r2 + r4; + r11 = r3 + r5; + r12 = r6 + r8; + r14 = r7 + r9; + + r2 -= r4; + r3 -= r5; + r6 -= r8; + r7 -= r9; + + r4 = r2 - r7; + r5 = r2 + r7; + r8 = r3 - r6; + r9 = r3 + r6; + + r2 = r4 - r9; + r3 = r4 + r9; + r6 = r5 - r8; + r7 = r5 + r8; + + r2 = MULSHIFT32(SQRT1_2, r2); /* can use r4, r5, r8, or r9 for constant and lo32 scratch reg */ + r3 = MULSHIFT32(SQRT1_2, r3); + r6 = MULSHIFT32(SQRT1_2, r6); + r7 = MULSHIFT32(SQRT1_2, r7); + + r4 = r10 + r12; + r5 = r10 - r12; + r8 = r11 + r14; + r9 = r11 - r14; + + r10 = r0[0]; + r11 = r0[2]; + r12 = r0[4]; + r14 = r0[6]; + + r10 += r11; + r12 += r14; + + r4 >>= 1; + r10 += r12; + r4 += (r10 >> 1); + r0[ 0] = r4; + r4 -= (r10 >> 1); + r4 = (r10 >> 1) - r4; + r0[ 8] = r4; + + r9 >>= 1; + r10 -= 2 * r12; + r4 = (r10 >> 1) + r9; + r0[ 4] = r4; + r4 = (r10 >> 1) - r9; + r0[12] = r4; + r10 += r12; + + r10 -= 2 * r11; + r12 -= 2 * r14; + + r4 = r0[1]; + r9 = r0[3]; + r11 = r0[5]; + r14 = r0[7]; + + r4 += r9; + r11 += r14; + + r8 >>= 1; + r4 += r11; + r8 += (r4 >> 1); + r0[ 1] = r8; + r8 -= (r4 >> 1); + r8 = (r4 >> 1) - r8; + r0[ 9] = r8; + + r5 >>= 1; + r4 -= 2 * r11; + r8 = (r4 >> 1) - r5; + r0[ 5] = r8; + r8 = (r4 >> 1) + r5; + r0[13] = r8; + r4 += r11; + + r4 -= 2 * r9; + r11 -= 2 * r14; + + r9 = r10 - r11; + r10 += r11; + r14 = r4 + r12; + r4 -= r12; + + r5 = (r10 >> 1) + r7; + r8 = (r4 >> 1) - r6; + r0[ 2] = r5; + r0[ 3] = r8; + + r5 = (r9 >> 1) - r2; + r8 = (r14 >> 1) - r3; + r0[ 6] = r5; + r0[ 7] = r8; + + r5 = (r10 >> 1) - r7; + r8 = (r4 >> 1) + r6; + r0[10] = r5; + r0[11] = r8; + + r5 = (r9 >> 1) + r2; + r8 = (r14 >> 1) + r3; + r0[14] = r5; + r0[15] = r8; + + r0 += 16; + r1--; + } while (r1 != 0); } /************************************************************************************** - * Function: R4Core32 - * - * Description: radix-4 pass for 32-point decimation-in-time FFT - * - * Inputs: buffer of samples - * - * Outputs: processed samples in same buffer - * - * Return: none - * - * Notes: gain 2 integer bits - * guard bits out = guard bits in - 1 (if inputs are full scale) - * see scaling comments in fft.c for base AAC - * uses 3-mul, 3-add butterflies instead of 4-mul, 2-add - * should compile with no stack spills on ARM (verify compiled output) - * current instruction count (per pass): 16 LDR, 16 STR, 4 SMULL, 61 ALU + Function: R4Core32 + + Description: radix-4 pass for 32-point decimation-in-time FFT + + Inputs: buffer of samples + + Outputs: processed samples in same buffer + + Return: none + + Notes: gain 2 integer bits + guard bits out = guard bits in - 1 (if inputs are full scale) + see scaling comments in fft.c for base AAC + uses 3-mul, 3-add butterflies instead of 4-mul, 2-add + should compile with no stack spills on ARM (verify compiled output) + current instruction count (per pass): 16 LDR, 16 STR, 4 SMULL, 61 ALU **************************************************************************************/ -static void R4Core32(int *r0) -{ - int r2, r3, r4, r5, r6, r7; - int r8, r9, r10, r12, r14; - int *r1; - - r1 = (int *)twidTabOdd32; - r10 = 8; - do { - /* can use r14 for lo32 scratch register in all MULSHIFT32 */ - r2 = r1[0]; - r3 = r1[1]; - r4 = r0[16]; - r5 = r0[17]; - r12 = r4 + r5; - r12 = MULSHIFT32(r3, r12); - r5 = MULSHIFT32(r2, r5) + r12; - r2 += 2*r3; - r4 = MULSHIFT32(r2, r4) - r12; - - r2 = r1[2]; - r3 = r1[3]; - r6 = r0[32]; - r7 = r0[33]; - r12 = r6 + r7; - r12 = MULSHIFT32(r3, r12); - r7 = MULSHIFT32(r2, r7) + r12; - r2 += 2*r3; - r6 = MULSHIFT32(r2, r6) - r12; - - r2 = r1[4]; - r3 = r1[5]; - r8 = r0[48]; - r9 = r0[49]; - r12 = r8 + r9; - r12 = MULSHIFT32(r3, r12); - r9 = MULSHIFT32(r2, r9) + r12; - r2 += 2*r3; - r8 = MULSHIFT32(r2, r8) - r12; - - r2 = r0[0]; - r3 = r0[1]; - - r12 = r6 + r8; - r8 = r6 - r8; - r14 = r9 - r7; - r9 = r9 + r7; - - r6 = (r2 >> 2) - r4; - r7 = (r3 >> 2) - r5; - r4 += (r2 >> 2); - r5 += (r3 >> 2); - - r2 = r4 + r12; - r3 = r5 + r9; - r0[0] = r2; - r0[1] = r3; - r2 = r6 - r14; - r3 = r7 - r8; - r0[16] = r2; - r0[17] = r3; - r2 = r4 - r12; - r3 = r5 - r9; - r0[32] = r2; - r0[33] = r3; - r2 = r6 + r14; - r3 = r7 + r8; - r0[48] = r2; - r0[49] = r3; - - r0 += 2; - r1 += 6; - r10--; - } while (r10 != 0); +static void R4Core32(int *r0) { + int r2, r3, r4, r5, r6, r7; + int r8, r9, r10, r12, r14; + int *r1; + + r1 = (int *)twidTabOdd32; + r10 = 8; + do { + /* can use r14 for lo32 scratch register in all MULSHIFT32 */ + r2 = r1[0]; + r3 = r1[1]; + r4 = r0[16]; + r5 = r0[17]; + r12 = r4 + r5; + r12 = MULSHIFT32(r3, r12); + r5 = MULSHIFT32(r2, r5) + r12; + r2 += 2 * r3; + r4 = MULSHIFT32(r2, r4) - r12; + + r2 = r1[2]; + r3 = r1[3]; + r6 = r0[32]; + r7 = r0[33]; + r12 = r6 + r7; + r12 = MULSHIFT32(r3, r12); + r7 = MULSHIFT32(r2, r7) + r12; + r2 += 2 * r3; + r6 = MULSHIFT32(r2, r6) - r12; + + r2 = r1[4]; + r3 = r1[5]; + r8 = r0[48]; + r9 = r0[49]; + r12 = r8 + r9; + r12 = MULSHIFT32(r3, r12); + r9 = MULSHIFT32(r2, r9) + r12; + r2 += 2 * r3; + r8 = MULSHIFT32(r2, r8) - r12; + + r2 = r0[0]; + r3 = r0[1]; + + r12 = r6 + r8; + r8 = r6 - r8; + r14 = r9 - r7; + r9 = r9 + r7; + + r6 = (r2 >> 2) - r4; + r7 = (r3 >> 2) - r5; + r4 += (r2 >> 2); + r5 += (r3 >> 2); + + r2 = r4 + r12; + r3 = r5 + r9; + r0[0] = r2; + r0[1] = r3; + r2 = r6 - r14; + r3 = r7 - r8; + r0[16] = r2; + r0[17] = r3; + r2 = r4 - r12; + r3 = r5 - r9; + r0[32] = r2; + r0[33] = r3; + r2 = r6 + r14; + r3 = r7 + r8; + r0[48] = r2; + r0[49] = r3; + + r0 += 2; + r1 += 6; + r10--; + } while (r10 != 0); } /************************************************************************************** - * Function: FFT32C - * - * Description: Ken's very fast in-place radix-4 decimation-in-time FFT - * - * Inputs: buffer of 32 complex samples (before bit-reversal) - * - * Outputs: processed samples in same buffer - * - * Return: none - * - * Notes: assumes 3 guard bits in, gains 3 integer bits - * guard bits out = guard bits in - 2 - * (guard bit analysis includes assumptions about steps immediately - * before and after, i.e. PreMul and PostMul for DCT) + Function: FFT32C + + Description: Ken's very fast in-place radix-4 decimation-in-time FFT + + Inputs: buffer of 32 complex samples (before bit-reversal) + + Outputs: processed samples in same buffer + + Return: none + + Notes: assumes 3 guard bits in, gains 3 integer bits + guard bits out = guard bits in - 2 + (guard bit analysis includes assumptions about steps immediately + before and after, i.e. PreMul and PostMul for DCT) **************************************************************************************/ -void FFT32C(int *x) -{ - /* decimation in time */ - BitReverse32(x); - - /* 32-point complex FFT */ - R8FirstPass32(x); /* gain 1 int bit, lose 2 GB (making assumptions about input) */ - R4Core32(x); /* gain 2 int bits, lose 0 GB (making assumptions about input) */ +void FFT32C(int *x) { + /* decimation in time */ + BitReverse32(x); + + /* 32-point complex FFT */ + R8FirstPass32(x); /* gain 1 int bit, lose 2 GB (making assumptions about input) */ + R4Core32(x); /* gain 2 int bits, lose 0 GB (making assumptions about input) */ } diff --git a/src/libhelix-aac/sbrfreq.c b/src/libhelix-aac/sbrfreq.c index 26a76063..7aa187ce 100644 --- a/src/libhelix-aac/sbrfreq.c +++ b/src/libhelix-aac/sbrfreq.c @@ -1,188 +1,189 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: sbrfreq.c,v 1.2 2005/05/20 18:05:41 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: sbrfreq.c,v 1.2 2005/05/20 18:05:41 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * sbrfreq.c - frequency band table calculation for SBR + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + sbrfreq.c - frequency band table calculation for SBR **************************************************************************************/ #include "sbr.h" #include "assembly.h" /************************************************************************************** - * Function: BubbleSort - * - * Description: in-place sort of unsigned chars - * - * Inputs: buffer of elements to sort - * number of elements to sort - * - * Outputs: sorted buffer - * - * Return: none + Function: BubbleSort + + Description: in-place sort of unsigned chars + + Inputs: buffer of elements to sort + number of elements to sort + + Outputs: sorted buffer + + Return: none **************************************************************************************/ -static void BubbleSort(unsigned char *v, int nItems) -{ - int i; - unsigned char t; - - while (nItems >= 2) { - for (i = 0; i < nItems-1; i++) { - if (v[i+1] < v[i]) { - t = v[i+1]; - v[i+1] = v[i]; - v[i] = t; - } - } - nItems--; - } +static void BubbleSort(unsigned char *v, int nItems) { + int i; + unsigned char t; + + while (nItems >= 2) { + for (i = 0; i < nItems - 1; i++) { + if (v[i + 1] < v[i]) { + t = v[i + 1]; + v[i + 1] = v[i]; + v[i] = t; + } + } + nItems--; + } } /************************************************************************************** - * Function: VMin - * - * Description: find smallest element in a buffer of unsigned chars - * - * Inputs: buffer of elements to search - * number of elements to search - * - * Outputs: none - * - * Return: smallest element in buffer + Function: VMin + + Description: find smallest element in a buffer of unsigned chars + + Inputs: buffer of elements to search + number of elements to search + + Outputs: none + + Return: smallest element in buffer **************************************************************************************/ -static unsigned char VMin(unsigned char *v, int nItems) -{ - int i; - unsigned char vMin; - - vMin = v[0]; - for (i = 1; i < nItems; i++) { - if (v[i] < vMin) - vMin = v[i]; - } - return vMin; +static unsigned char VMin(unsigned char *v, int nItems) { + int i; + unsigned char vMin; + + vMin = v[0]; + for (i = 1; i < nItems; i++) { + if (v[i] < vMin) { + vMin = v[i]; + } + } + return vMin; } /************************************************************************************** - * Function: VMax - * - * Description: find largest element in a buffer of unsigned chars - * - * Inputs: buffer of elements to search - * number of elements to search - * - * Outputs: none - * - * Return: largest element in buffer + Function: VMax + + Description: find largest element in a buffer of unsigned chars + + Inputs: buffer of elements to search + number of elements to search + + Outputs: none + + Return: largest element in buffer **************************************************************************************/ -static unsigned char VMax(unsigned char *v, int nItems) -{ - int i; - unsigned char vMax; - - vMax = v[0]; - for (i = 1; i < nItems; i++) { - if (v[i] > vMax) - vMax = v[i]; - } - return vMax; +static unsigned char VMax(unsigned char *v, int nItems) { + int i; + unsigned char vMax; + + vMax = v[0]; + for (i = 1; i < nItems; i++) { + if (v[i] > vMax) { + vMax = v[i]; + } + } + return vMax; } /************************************************************************************** - * Function: CalcFreqMasterScaleZero - * - * Description: calculate master frequency table when freqScale == 0 - * (4.6.18.3.2.1, figure 4.39) - * - * Inputs: alterScale flag - * index of first QMF subband in master freq table (k0) - * index of last QMF subband (k2) - * - * Outputs: master frequency table - * - * Return: number of bands in master frequency table - * - * Notes: assumes k2 - k0 <= 48 and k2 >= k0 (4.6.18.3.6) + Function: CalcFreqMasterScaleZero + + Description: calculate master frequency table when freqScale == 0 + (4.6.18.3.2.1, figure 4.39) + + Inputs: alterScale flag + index of first QMF subband in master freq table (k0) + index of last QMF subband (k2) + + Outputs: master frequency table + + Return: number of bands in master frequency table + + Notes: assumes k2 - k0 <= 48 and k2 >= k0 (4.6.18.3.6) **************************************************************************************/ -static int CalcFreqMasterScaleZero(unsigned char *freqMaster, int alterScale, int k0, int k2) -{ - int nMaster, k, nBands, k2Achieved, dk, vDk[64], k2Diff; - - if (alterScale) { - dk = 2; - nBands = 2 * ((k2 - k0 + 2) >> 2); - } else { - dk = 1; - nBands = 2 * ((k2 - k0) >> 1); - } - - if (nBands <= 0) - return 0; - - k2Achieved = k0 + nBands * dk; - k2Diff = k2 - k2Achieved; - for (k = 0; k < nBands; k++) - vDk[k] = dk; - - if (k2Diff > 0) { - k = nBands - 1; - while (k2Diff) { - vDk[k]++; - k--; - k2Diff--; - } - } else if (k2Diff < 0) { - k = 0; - while (k2Diff) { - vDk[k]--; - k++; - k2Diff++; - } - } - - nMaster = nBands; - freqMaster[0] = k0; - for (k = 1; k <= nBands; k++) - freqMaster[k] = freqMaster[k-1] + vDk[k-1]; - - return nMaster; +static int CalcFreqMasterScaleZero(unsigned char *freqMaster, int alterScale, int k0, int k2) { + int nMaster, k, nBands, k2Achieved, dk, vDk[64], k2Diff; + + if (alterScale) { + dk = 2; + nBands = 2 * ((k2 - k0 + 2) >> 2); + } else { + dk = 1; + nBands = 2 * ((k2 - k0) >> 1); + } + + if (nBands <= 0) { + return 0; + } + + k2Achieved = k0 + nBands * dk; + k2Diff = k2 - k2Achieved; + for (k = 0; k < nBands; k++) { + vDk[k] = dk; + } + + if (k2Diff > 0) { + k = nBands - 1; + while (k2Diff) { + vDk[k]++; + k--; + k2Diff--; + } + } else if (k2Diff < 0) { + k = 0; + while (k2Diff) { + vDk[k]--; + k++; + k2Diff++; + } + } + + nMaster = nBands; + freqMaster[0] = k0; + for (k = 1; k <= nBands; k++) { + freqMaster[k] = freqMaster[k - 1] + vDk[k - 1]; + } + + return nMaster; } /* mBandTab[i] = temp1[i] / 2 */ @@ -192,450 +193,462 @@ static const int mBandTab[3] PROGMEM = {6, 5, 4}; static const int invWarpTab[2] PROGMEM = {0x40000000, 0x313b13b1}; /************************************************************************************** - * Function: CalcFreqMasterScale - * - * Description: calculate master frequency table when freqScale > 0 - * (4.6.18.3.2.1, figure 4.39) - * - * Inputs: alterScale flag - * freqScale flag - * index of first QMF subband in master freq table (k0) - * index of last QMF subband (k2) - * - * Outputs: master frequency table - * - * Return: number of bands in master frequency table - * - * Notes: assumes k2 - k0 <= 48 and k2 >= k0 (4.6.18.3.6) + Function: CalcFreqMasterScale + + Description: calculate master frequency table when freqScale > 0 + (4.6.18.3.2.1, figure 4.39) + + Inputs: alterScale flag + freqScale flag + index of first QMF subband in master freq table (k0) + index of last QMF subband (k2) + + Outputs: master frequency table + + Return: number of bands in master frequency table + + Notes: assumes k2 - k0 <= 48 and k2 >= k0 (4.6.18.3.6) **************************************************************************************/ -static int CalcFreqMaster(unsigned char *freqMaster, int freqScale, int alterScale, int k0, int k2) -{ - int bands, twoRegions, k, k1, t, vLast, vCurr, pCurr; - int invWarp, nBands0, nBands1, change; - unsigned char vDk1Min, vDk0Max; - unsigned char *vDelta; - - if (freqScale < 1 || freqScale > 3) - return -1; - - bands = mBandTab[freqScale - 1]; - invWarp = invWarpTab[alterScale]; - - /* tested for all k0 = [5, 64], k2 = [k0, 64] */ - if (k2*10000 > 22449*k0) { - twoRegions = 1; - k1 = 2*k0; - } else { - twoRegions = 0; - k1 = k2; - } - - /* tested for all k0 = [5, 64], k1 = [k0, 64], freqScale = [1,3] */ - t = (log2Tab[k1] - log2Tab[k0]) >> 3; /* log2(k1/k0), Q28 to Q25 */ - nBands0 = 2 * (((bands * t) + (1 << 24)) >> 25); /* multiply by bands/2, round to nearest int (mBandTab has factor of 1/2 rolled in) */ - - /* tested for all valid combinations of k0, k1, nBands (from sampRate, freqScale, alterScale) - * roundoff error can be a problem with fixpt (e.g. pCurr = 12.499999 instead of 12.50003) - * because successive multiplication always undershoots a little bit, but this - * doesn't occur in any of the ratios we encounter from the valid k0/k1 bands in the spec - */ - t = RatioPowInv(k1, k0, nBands0); - pCurr = k0 << 24; - vLast = k0; - vDelta = freqMaster + 1; /* operate in-place */ - for (k = 0; k < nBands0; k++) { - pCurr = MULSHIFT32(pCurr, t) << 8; /* keep in Q24 */ - vCurr = (pCurr + (1 << 23)) >> 24; - vDelta[k] = (vCurr - vLast); - vLast = vCurr; - } - - /* sort the deltas and find max delta for first region */ - BubbleSort(vDelta, nBands0); - vDk0Max = VMax(vDelta, nBands0); - - /* fill master frequency table with bands from first region */ - freqMaster[0] = k0; - for (k = 1; k <= nBands0; k++) - freqMaster[k] += freqMaster[k-1]; - - /* if only one region, then the table is complete */ - if (!twoRegions) - return nBands0; - - /* tested for all k1 = [10, 64], k2 = [k0, 64], freqScale = [1,3] */ - t = (log2Tab[k2] - log2Tab[k1]) >> 3; /* log2(k1/k0), Q28 to Q25 */ - t = MULSHIFT32(bands * t, invWarp) << 2; /* multiply by bands/2, divide by warp factor, keep Q25 */ - nBands1 = 2 * ((t + (1 << 24)) >> 25); /* round to nearest int */ - - /* see comments above for calculations in first region */ - t = RatioPowInv(k2, k1, nBands1); - pCurr = k1 << 24; - vLast = k1; - vDelta = freqMaster + nBands0 + 1; /* operate in-place */ - for (k = 0; k < nBands1; k++) { - pCurr = MULSHIFT32(pCurr, t) << 8; /* keep in Q24 */ - vCurr = (pCurr + (1 << 23)) >> 24; - vDelta[k] = (vCurr - vLast); - vLast = vCurr; - } - - /* sort the deltas, adjusting first and last if the second region has smaller deltas than the first */ - vDk1Min = VMin(vDelta, nBands1); - if (vDk1Min < vDk0Max) { - BubbleSort(vDelta, nBands1); - change = vDk0Max - vDelta[0]; - if (change > ((vDelta[nBands1 - 1] - vDelta[0]) >> 1)) - change = ((vDelta[nBands1 - 1] - vDelta[0]) >> 1); - vDelta[0] += change; - vDelta[nBands1-1] -= change; - } - BubbleSort(vDelta, nBands1); - - /* fill master frequency table with bands from second region - * Note: freqMaster[nBands0] = k1 - */ - for (k = 1; k <= nBands1; k++) - freqMaster[k + nBands0] += freqMaster[k + nBands0 - 1]; - - return (nBands0 + nBands1); +static int CalcFreqMaster(unsigned char *freqMaster, int freqScale, int alterScale, int k0, int k2) { + int bands, twoRegions, k, k1, t, vLast, vCurr, pCurr; + int invWarp, nBands0, nBands1, change; + unsigned char vDk1Min, vDk0Max; + unsigned char *vDelta; + + if (freqScale < 1 || freqScale > 3) { + return -1; + } + + bands = mBandTab[freqScale - 1]; + invWarp = invWarpTab[alterScale]; + + /* tested for all k0 = [5, 64], k2 = [k0, 64] */ + if (k2 * 10000 > 22449 * k0) { + twoRegions = 1; + k1 = 2 * k0; + } else { + twoRegions = 0; + k1 = k2; + } + + /* tested for all k0 = [5, 64], k1 = [k0, 64], freqScale = [1,3] */ + t = (log2Tab[k1] - log2Tab[k0]) >> 3; /* log2(k1/k0), Q28 to Q25 */ + nBands0 = 2 * (((bands * t) + (1 << 24)) >> 25); /* multiply by bands/2, round to nearest int (mBandTab has factor of 1/2 rolled in) */ + + /* tested for all valid combinations of k0, k1, nBands (from sampRate, freqScale, alterScale) + roundoff error can be a problem with fixpt (e.g. pCurr = 12.499999 instead of 12.50003) + because successive multiplication always undershoots a little bit, but this + doesn't occur in any of the ratios we encounter from the valid k0/k1 bands in the spec + */ + t = RatioPowInv(k1, k0, nBands0); + pCurr = k0 << 24; + vLast = k0; + vDelta = freqMaster + 1; /* operate in-place */ + for (k = 0; k < nBands0; k++) { + pCurr = MULSHIFT32(pCurr, t) << 8; /* keep in Q24 */ + vCurr = (pCurr + (1 << 23)) >> 24; + vDelta[k] = (vCurr - vLast); + vLast = vCurr; + } + + /* sort the deltas and find max delta for first region */ + BubbleSort(vDelta, nBands0); + vDk0Max = VMax(vDelta, nBands0); + + /* fill master frequency table with bands from first region */ + freqMaster[0] = k0; + for (k = 1; k <= nBands0; k++) { + freqMaster[k] += freqMaster[k - 1]; + } + + /* if only one region, then the table is complete */ + if (!twoRegions) { + return nBands0; + } + + /* tested for all k1 = [10, 64], k2 = [k0, 64], freqScale = [1,3] */ + t = (log2Tab[k2] - log2Tab[k1]) >> 3; /* log2(k1/k0), Q28 to Q25 */ + t = MULSHIFT32(bands * t, invWarp) << 2; /* multiply by bands/2, divide by warp factor, keep Q25 */ + nBands1 = 2 * ((t + (1 << 24)) >> 25); /* round to nearest int */ + + /* see comments above for calculations in first region */ + t = RatioPowInv(k2, k1, nBands1); + pCurr = k1 << 24; + vLast = k1; + vDelta = freqMaster + nBands0 + 1; /* operate in-place */ + for (k = 0; k < nBands1; k++) { + pCurr = MULSHIFT32(pCurr, t) << 8; /* keep in Q24 */ + vCurr = (pCurr + (1 << 23)) >> 24; + vDelta[k] = (vCurr - vLast); + vLast = vCurr; + } + + /* sort the deltas, adjusting first and last if the second region has smaller deltas than the first */ + vDk1Min = VMin(vDelta, nBands1); + if (vDk1Min < vDk0Max) { + BubbleSort(vDelta, nBands1); + change = vDk0Max - vDelta[0]; + if (change > ((vDelta[nBands1 - 1] - vDelta[0]) >> 1)) { + change = ((vDelta[nBands1 - 1] - vDelta[0]) >> 1); + } + vDelta[0] += change; + vDelta[nBands1 - 1] -= change; + } + BubbleSort(vDelta, nBands1); + + /* fill master frequency table with bands from second region + Note: freqMaster[nBands0] = k1 + */ + for (k = 1; k <= nBands1; k++) { + freqMaster[k + nBands0] += freqMaster[k + nBands0 - 1]; + } + + return (nBands0 + nBands1); } /************************************************************************************** - * Function: CalcFreqHigh - * - * Description: calculate high resolution frequency table (4.6.18.3.2.2) - * - * Inputs: master frequency table - * number of bands in master frequency table - * crossover band from header - * - * Outputs: high resolution frequency table - * - * Return: number of bands in high resolution frequency table + Function: CalcFreqHigh + + Description: calculate high resolution frequency table (4.6.18.3.2.2) + + Inputs: master frequency table + number of bands in master frequency table + crossover band from header + + Outputs: high resolution frequency table + + Return: number of bands in high resolution frequency table **************************************************************************************/ -static int CalcFreqHigh(unsigned char *freqHigh, unsigned char *freqMaster, int nMaster, int crossOverBand) -{ - int k, nHigh; +static int CalcFreqHigh(unsigned char *freqHigh, unsigned char *freqMaster, int nMaster, int crossOverBand) { + int k, nHigh; + + nHigh = nMaster - crossOverBand; - nHigh = nMaster - crossOverBand; + for (k = 0; k <= nHigh; k++) { + freqHigh[k] = freqMaster[k + crossOverBand]; + } - for (k = 0; k <= nHigh; k++) - freqHigh[k] = freqMaster[k + crossOverBand]; - - return nHigh; + return nHigh; } /************************************************************************************** - * Function: CalcFreqLow - * - * Description: calculate low resolution frequency table (4.6.18.3.2.2) - * - * Inputs: high resolution frequency table - * number of bands in high resolution frequency table - * - * Outputs: low resolution frequency table - * - * Return: number of bands in low resolution frequency table + Function: CalcFreqLow + + Description: calculate low resolution frequency table (4.6.18.3.2.2) + + Inputs: high resolution frequency table + number of bands in high resolution frequency table + + Outputs: low resolution frequency table + + Return: number of bands in low resolution frequency table **************************************************************************************/ -static int CalcFreqLow(unsigned char *freqLow, unsigned char *freqHigh, int nHigh) -{ - int k, nLow, oddFlag; +static int CalcFreqLow(unsigned char *freqLow, unsigned char *freqHigh, int nHigh) { + int k, nLow, oddFlag; - nLow = nHigh - (nHigh >> 1); - freqLow[0] = freqHigh[0]; - oddFlag = nHigh & 0x01; + nLow = nHigh - (nHigh >> 1); + freqLow[0] = freqHigh[0]; + oddFlag = nHigh & 0x01; - for (k = 1; k <= nLow; k++) - freqLow[k] = freqHigh[2*k - oddFlag]; + for (k = 1; k <= nLow; k++) { + freqLow[k] = freqHigh[2 * k - oddFlag]; + } - return nLow; + return nLow; } /************************************************************************************** - * Function: CalcFreqNoise - * - * Description: calculate noise floor frequency table (4.6.18.3.2.2) - * - * Inputs: low resolution frequency table - * number of bands in low resolution frequency table - * index of starting QMF subband for SBR (kStart) - * index of last QMF subband (k2) - * number of noise bands - * - * Outputs: noise floor frequency table - * - * Return: number of bands in noise floor frequency table + Function: CalcFreqNoise + + Description: calculate noise floor frequency table (4.6.18.3.2.2) + + Inputs: low resolution frequency table + number of bands in low resolution frequency table + index of starting QMF subband for SBR (kStart) + index of last QMF subband (k2) + number of noise bands + + Outputs: noise floor frequency table + + Return: number of bands in noise floor frequency table **************************************************************************************/ -static int CalcFreqNoise(unsigned char *freqNoise, unsigned char *freqLow, int nLow, int kStart, int k2, int noiseBands) -{ - int i, iLast, k, nQ, lTop, lBottom; - - lTop = log2Tab[k2]; - lBottom = log2Tab[kStart]; - nQ = noiseBands*((lTop - lBottom) >> 2); /* Q28 to Q26, noiseBands = [0,3] */ - nQ = (nQ + (1 << 25)) >> 26; - if (nQ < 1) - nQ = 1; - - ASSERT(nQ <= MAX_NUM_NOISE_FLOOR_BANDS); /* required from 4.6.18.3.6 */ - - iLast = 0; - freqNoise[0] = freqLow[0]; - for (k = 1; k <= nQ; k++) { - i = iLast + (nLow - iLast) / (nQ + 1 - k); /* truncating division */ - freqNoise[k] = freqLow[i]; - iLast = i; - } - - return nQ; +static int CalcFreqNoise(unsigned char *freqNoise, unsigned char *freqLow, int nLow, int kStart, int k2, int noiseBands) { + int i, iLast, k, nQ, lTop, lBottom; + + lTop = log2Tab[k2]; + lBottom = log2Tab[kStart]; + nQ = noiseBands * ((lTop - lBottom) >> 2); /* Q28 to Q26, noiseBands = [0,3] */ + nQ = (nQ + (1 << 25)) >> 26; + if (nQ < 1) { + nQ = 1; + } + + ASSERT(nQ <= MAX_NUM_NOISE_FLOOR_BANDS); /* required from 4.6.18.3.6 */ + + iLast = 0; + freqNoise[0] = freqLow[0]; + for (k = 1; k <= nQ; k++) { + i = iLast + (nLow - iLast) / (nQ + 1 - k); /* truncating division */ + freqNoise[k] = freqLow[i]; + iLast = i; + } + + return nQ; } /************************************************************************************** - * Function: BuildPatches - * - * Description: build high frequency patches (4.6.18.6.3) - * - * Inputs: master frequency table - * number of bands in low resolution frequency table - * index of first QMF subband in master freq table (k0) - * index of starting QMF subband for SBR (kStart) - * number of QMF bands in high resolution frequency table - * sample rate index - * - * Outputs: starting subband for each patch - * number of subbands in each patch - * - * Return: number of patches + Function: BuildPatches + + Description: build high frequency patches (4.6.18.6.3) + + Inputs: master frequency table + number of bands in low resolution frequency table + index of first QMF subband in master freq table (k0) + index of starting QMF subband for SBR (kStart) + number of QMF bands in high resolution frequency table + sample rate index + + Outputs: starting subband for each patch + number of subbands in each patch + + Return: number of patches **************************************************************************************/ -static int BuildPatches(unsigned char *patchNumSubbands, unsigned char *patchStartSubband, unsigned char *freqMaster, - int nMaster, int k0, int kStart, int numQMFBands, int sampRateIdx) -{ - int i, j, k; - int msb, sb, usb, numPatches, goalSB, oddFlag; - - msb = k0; - usb = kStart; - numPatches = 0; - goalSB = goalSBTab[sampRateIdx]; - - if (nMaster == 0) { - patchNumSubbands[0] = 0; - patchStartSubband[0] = 0; - return 0; - } - - if (goalSB < kStart + numQMFBands) { - k = 0; - for (i = 0; freqMaster[i] < goalSB; i++) - k = i+1; - } else { - k = nMaster; - } - - do { - j = k+1; - do { - j--; - sb = freqMaster[j]; - oddFlag = (sb - 2 + k0) & 0x01; - } while (sb > k0 - 1 + msb - oddFlag); - - patchNumSubbands[numPatches] = MAX(sb - usb, 0); - patchStartSubband[numPatches] = k0 - oddFlag - patchNumSubbands[numPatches]; - - /* from MPEG reference code - slightly different from spec */ - if ((patchNumSubbands[numPatches] < 3) && (numPatches > 0)) - break; - - if (patchNumSubbands[numPatches] > 0) { - usb = sb; - msb = sb; - numPatches++; - } else { - msb = kStart; - } - - if (freqMaster[k] - sb < 3) - k = nMaster; - - } while (sb != (kStart + numQMFBands) && numPatches <= MAX_NUM_PATCHES); - - return numPatches; +static int BuildPatches(unsigned char *patchNumSubbands, unsigned char *patchStartSubband, unsigned char *freqMaster, + int nMaster, int k0, int kStart, int numQMFBands, int sampRateIdx) { + int i, j, k; + int msb, sb, usb, numPatches, goalSB, oddFlag; + + msb = k0; + usb = kStart; + numPatches = 0; + goalSB = goalSBTab[sampRateIdx]; + + if (nMaster == 0) { + patchNumSubbands[0] = 0; + patchStartSubband[0] = 0; + return 0; + } + + if (goalSB < kStart + numQMFBands) { + k = 0; + for (i = 0; freqMaster[i] < goalSB; i++) { + k = i + 1; + } + } else { + k = nMaster; + } + + do { + j = k + 1; + do { + j--; + sb = freqMaster[j]; + oddFlag = (sb - 2 + k0) & 0x01; + } while (sb > k0 - 1 + msb - oddFlag); + + patchNumSubbands[numPatches] = MAX(sb - usb, 0); + patchStartSubband[numPatches] = k0 - oddFlag - patchNumSubbands[numPatches]; + + /* from MPEG reference code - slightly different from spec */ + if ((patchNumSubbands[numPatches] < 3) && (numPatches > 0)) { + break; + } + + if (patchNumSubbands[numPatches] > 0) { + usb = sb; + msb = sb; + numPatches++; + } else { + msb = kStart; + } + + if (freqMaster[k] - sb < 3) { + k = nMaster; + } + + } while (sb != (kStart + numQMFBands) && numPatches <= MAX_NUM_PATCHES); + + return numPatches; } /************************************************************************************** - * Function: FindFreq - * - * Description: search buffer of unsigned chars for a specific value - * - * Inputs: buffer of elements to search - * number of elements to search - * value to search for - * - * Outputs: none - * - * Return: non-zero if the value is found anywhere in the buffer, zero otherwise + Function: FindFreq + + Description: search buffer of unsigned chars for a specific value + + Inputs: buffer of elements to search + number of elements to search + value to search for + + Outputs: none + + Return: non-zero if the value is found anywhere in the buffer, zero otherwise **************************************************************************************/ -static int FindFreq(unsigned char *freq, int nFreq, unsigned char val) -{ - int k; +static int FindFreq(unsigned char *freq, int nFreq, unsigned char val) { + int k; - for (k = 0; k < nFreq; k++) { - if (freq[k] == val) - return 1; - } + for (k = 0; k < nFreq; k++) { + if (freq[k] == val) { + return 1; + } + } - return 0; + return 0; } /************************************************************************************** - * Function: RemoveFreq - * - * Description: remove one element from a buffer of unsigned chars - * - * Inputs: buffer of elements - * number of elements - * index of element to remove - * - * Outputs: new buffer of length nFreq-1 - * - * Return: none + Function: RemoveFreq + + Description: remove one element from a buffer of unsigned chars + + Inputs: buffer of elements + number of elements + index of element to remove + + Outputs: new buffer of length nFreq-1 + + Return: none **************************************************************************************/ -static void RemoveFreq(unsigned char *freq, int nFreq, int removeIdx) -{ - int k; +static void RemoveFreq(unsigned char *freq, int nFreq, int removeIdx) { + int k; - if (removeIdx >= nFreq) - return; + if (removeIdx >= nFreq) { + return; + } - for (k = removeIdx; k < nFreq - 1; k++) - freq[k] = freq[k+1]; + for (k = removeIdx; k < nFreq - 1; k++) { + freq[k] = freq[k + 1]; + } } /************************************************************************************** - * Function: CalcFreqLimiter - * - * Description: calculate limiter frequency table (4.6.18.3.2.3) - * - * Inputs: number of subbands in each patch - * low resolution frequency table - * number of bands in low resolution frequency table - * index of starting QMF subband for SBR (kStart) - * number of limiter bands - * number of patches - * - * Outputs: limiter frequency table - * - * Return: number of bands in limiter frequency table + Function: CalcFreqLimiter + + Description: calculate limiter frequency table (4.6.18.3.2.3) + + Inputs: number of subbands in each patch + low resolution frequency table + number of bands in low resolution frequency table + index of starting QMF subband for SBR (kStart) + number of limiter bands + number of patches + + Outputs: limiter frequency table + + Return: number of bands in limiter frequency table **************************************************************************************/ -static int CalcFreqLimiter(unsigned char *freqLimiter, unsigned char *patchNumSubbands, unsigned char *freqLow, - int nLow, int kStart, int limiterBands, int numPatches) -{ - int k, bands, nLimiter, nOctaves; - int limBandsPerOctave[3] = {120, 200, 300}; /* [1.2, 2.0, 3.0] * 100 */ - unsigned char patchBorders[MAX_NUM_PATCHES + 1]; - - /* simple case */ - if (limiterBands == 0) { - freqLimiter[0] = freqLow[0] - kStart; - freqLimiter[1] = freqLow[nLow] - kStart; - return 1; - } - - bands = limBandsPerOctave[limiterBands - 1]; - patchBorders[0] = kStart; - - /* from MPEG reference code - slightly different from spec (top border) */ - for (k = 1; k < numPatches; k++) - patchBorders[k] = patchBorders[k-1] + patchNumSubbands[k-1]; - patchBorders[k] = freqLow[nLow]; - - for (k = 0; k <= nLow; k++) - freqLimiter[k] = freqLow[k]; - - for (k = 1; k < numPatches; k++) - freqLimiter[k+nLow] = patchBorders[k]; - - k = 1; - nLimiter = nLow + numPatches - 1; - BubbleSort(freqLimiter, nLimiter + 1); - - while (k <= nLimiter) { - nOctaves = log2Tab[freqLimiter[k]] - log2Tab[freqLimiter[k-1]]; /* Q28 */ - nOctaves = (nOctaves >> 9) * bands; /* Q19, max bands = 300 < 2^9 */ - if (nOctaves < (49 << 19)) { /* compare with 0.49*100, in Q19 */ - if (freqLimiter[k] == freqLimiter[k-1] || FindFreq(patchBorders, numPatches + 1, freqLimiter[k]) == 0) { - RemoveFreq(freqLimiter, nLimiter + 1, k); - nLimiter--; - } else if (FindFreq(patchBorders, numPatches + 1, freqLimiter[k-1]) == 0) { - RemoveFreq(freqLimiter, nLimiter + 1, k-1); - nLimiter--; - } else { - k++; - } - } else { - k++; - } - } - - /* store limiter boundaries as offsets from kStart */ - for (k = 0; k <= nLimiter; k++) - freqLimiter[k] -= kStart; - - return nLimiter; +static int CalcFreqLimiter(unsigned char *freqLimiter, unsigned char *patchNumSubbands, unsigned char *freqLow, + int nLow, int kStart, int limiterBands, int numPatches) { + int k, bands, nLimiter, nOctaves; + int limBandsPerOctave[3] = {120, 200, 300}; /* [1.2, 2.0, 3.0] * 100 */ + unsigned char patchBorders[MAX_NUM_PATCHES + 1]; + + /* simple case */ + if (limiterBands == 0) { + freqLimiter[0] = freqLow[0] - kStart; + freqLimiter[1] = freqLow[nLow] - kStart; + return 1; + } + + bands = limBandsPerOctave[limiterBands - 1]; + patchBorders[0] = kStart; + + /* from MPEG reference code - slightly different from spec (top border) */ + for (k = 1; k < numPatches; k++) { + patchBorders[k] = patchBorders[k - 1] + patchNumSubbands[k - 1]; + } + patchBorders[k] = freqLow[nLow]; + + for (k = 0; k <= nLow; k++) { + freqLimiter[k] = freqLow[k]; + } + + for (k = 1; k < numPatches; k++) { + freqLimiter[k + nLow] = patchBorders[k]; + } + + k = 1; + nLimiter = nLow + numPatches - 1; + BubbleSort(freqLimiter, nLimiter + 1); + + while (k <= nLimiter) { + nOctaves = log2Tab[freqLimiter[k]] - log2Tab[freqLimiter[k - 1]]; /* Q28 */ + nOctaves = (nOctaves >> 9) * bands; /* Q19, max bands = 300 < 2^9 */ + if (nOctaves < (49 << 19)) { /* compare with 0.49*100, in Q19 */ + if (freqLimiter[k] == freqLimiter[k - 1] || FindFreq(patchBorders, numPatches + 1, freqLimiter[k]) == 0) { + RemoveFreq(freqLimiter, nLimiter + 1, k); + nLimiter--; + } else if (FindFreq(patchBorders, numPatches + 1, freqLimiter[k - 1]) == 0) { + RemoveFreq(freqLimiter, nLimiter + 1, k - 1); + nLimiter--; + } else { + k++; + } + } else { + k++; + } + } + + /* store limiter boundaries as offsets from kStart */ + for (k = 0; k <= nLimiter; k++) { + freqLimiter[k] -= kStart; + } + + return nLimiter; } /************************************************************************************** - * Function: CalcFreqTables - * - * Description: calulate master and derived frequency tables, and patches - * - * Inputs: initialized SBRHeader struct for this SCE/CPE block - * initialized SBRFreq struct for this SCE/CPE block - * sample rate index of output sample rate (after SBR) - * - * Outputs: master and derived frequency tables, and patches - * - * Return: non-zero if error, zero otherwise + Function: CalcFreqTables + + Description: calulate master and derived frequency tables, and patches + + Inputs: initialized SBRHeader struct for this SCE/CPE block + initialized SBRFreq struct for this SCE/CPE block + sample rate index of output sample rate (after SBR) + + Outputs: master and derived frequency tables, and patches + + Return: non-zero if error, zero otherwise **************************************************************************************/ -int CalcFreqTables(SBRHeader *sbrHdr, SBRFreq *sbrFreq, int sampRateIdx) -{ - int k0, k2; - - k0 = k0Tab[sampRateIdx][sbrHdr->startFreq]; - - if (sbrHdr->stopFreq == 14) - k2 = 2*k0; - else if (sbrHdr->stopFreq == 15) - k2 = 3*k0; - else - k2 = k2Tab[sampRateIdx][sbrHdr->stopFreq]; - if (k2 > 64) - k2 = 64; - - /* calculate master frequency table */ - if (sbrHdr->freqScale == 0) - sbrFreq->nMaster = CalcFreqMasterScaleZero(sbrFreq->freqMaster, sbrHdr->alterScale, k0, k2); - else - sbrFreq->nMaster = CalcFreqMaster(sbrFreq->freqMaster, sbrHdr->freqScale, sbrHdr->alterScale, k0, k2); - - /* calculate high frequency table and related parameters */ - sbrFreq->nHigh = CalcFreqHigh(sbrFreq->freqHigh, sbrFreq->freqMaster, sbrFreq->nMaster, sbrHdr->crossOverBand); - sbrFreq->numQMFBands = sbrFreq->freqHigh[sbrFreq->nHigh] - sbrFreq->freqHigh[0]; - sbrFreq->kStart = sbrFreq->freqHigh[0]; - - /* calculate low frequency table */ - sbrFreq->nLow = CalcFreqLow(sbrFreq->freqLow, sbrFreq->freqHigh, sbrFreq->nHigh); - - /* calculate noise floor frequency table */ - sbrFreq->numNoiseFloorBands = CalcFreqNoise(sbrFreq->freqNoise, sbrFreq->freqLow, sbrFreq->nLow, sbrFreq->kStart, k2, sbrHdr->noiseBands); - - /* calculate limiter table */ - sbrFreq->numPatches = BuildPatches(sbrFreq->patchNumSubbands, sbrFreq->patchStartSubband, sbrFreq->freqMaster, - sbrFreq->nMaster, k0, sbrFreq->kStart, sbrFreq->numQMFBands, sampRateIdx); - sbrFreq->nLimiter = CalcFreqLimiter(sbrFreq->freqLimiter, sbrFreq->patchNumSubbands, sbrFreq->freqLow, sbrFreq->nLow, sbrFreq->kStart, - sbrHdr->limiterBands, sbrFreq->numPatches); - - return 0; +int CalcFreqTables(SBRHeader *sbrHdr, SBRFreq *sbrFreq, int sampRateIdx) { + int k0, k2; + + k0 = k0Tab[sampRateIdx][sbrHdr->startFreq]; + + if (sbrHdr->stopFreq == 14) { + k2 = 2 * k0; + } else if (sbrHdr->stopFreq == 15) { + k2 = 3 * k0; + } else { + k2 = k2Tab[sampRateIdx][sbrHdr->stopFreq]; + } + if (k2 > 64) { + k2 = 64; + } + + /* calculate master frequency table */ + if (sbrHdr->freqScale == 0) { + sbrFreq->nMaster = CalcFreqMasterScaleZero(sbrFreq->freqMaster, sbrHdr->alterScale, k0, k2); + } else { + sbrFreq->nMaster = CalcFreqMaster(sbrFreq->freqMaster, sbrHdr->freqScale, sbrHdr->alterScale, k0, k2); + } + + /* calculate high frequency table and related parameters */ + sbrFreq->nHigh = CalcFreqHigh(sbrFreq->freqHigh, sbrFreq->freqMaster, sbrFreq->nMaster, sbrHdr->crossOverBand); + sbrFreq->numQMFBands = sbrFreq->freqHigh[sbrFreq->nHigh] - sbrFreq->freqHigh[0]; + sbrFreq->kStart = sbrFreq->freqHigh[0]; + + /* calculate low frequency table */ + sbrFreq->nLow = CalcFreqLow(sbrFreq->freqLow, sbrFreq->freqHigh, sbrFreq->nHigh); + + /* calculate noise floor frequency table */ + sbrFreq->numNoiseFloorBands = CalcFreqNoise(sbrFreq->freqNoise, sbrFreq->freqLow, sbrFreq->nLow, sbrFreq->kStart, k2, sbrHdr->noiseBands); + + /* calculate limiter table */ + sbrFreq->numPatches = BuildPatches(sbrFreq->patchNumSubbands, sbrFreq->patchStartSubband, sbrFreq->freqMaster, + sbrFreq->nMaster, k0, sbrFreq->kStart, sbrFreq->numQMFBands, sampRateIdx); + sbrFreq->nLimiter = CalcFreqLimiter(sbrFreq->freqLimiter, sbrFreq->patchNumSubbands, sbrFreq->freqLow, sbrFreq->nLow, sbrFreq->kStart, + sbrHdr->limiterBands, sbrFreq->numPatches); + + return 0; } diff --git a/src/libhelix-aac/sbrhfadj.c b/src/libhelix-aac/sbrhfadj.c index f16cb07b..25dc0482 100644 --- a/src/libhelix-aac/sbrhfadj.c +++ b/src/libhelix-aac/sbrhfadj.c @@ -1,46 +1,46 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: sbrhfadj.c,v 1.3 2005/05/24 16:01:55 albertofloyd Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: sbrhfadj.c,v 1.3 2005/05/24 16:01:55 albertofloyd Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * sbrhfadj.c - high frequency adjustment for SBR + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + sbrhfadj.c - high frequency adjustment for SBR **************************************************************************************/ #include "sbr.h" @@ -48,169 +48,170 @@ /* invBandTab[i] = 1.0 / (i + 1), Q31 */ static const int invBandTab[64] PROGMEM = { - 0x7fffffff, 0x40000000, 0x2aaaaaab, 0x20000000, 0x1999999a, 0x15555555, 0x12492492, 0x10000000, - 0x0e38e38e, 0x0ccccccd, 0x0ba2e8ba, 0x0aaaaaab, 0x09d89d8a, 0x09249249, 0x08888889, 0x08000000, - 0x07878788, 0x071c71c7, 0x06bca1af, 0x06666666, 0x06186186, 0x05d1745d, 0x0590b216, 0x05555555, - 0x051eb852, 0x04ec4ec5, 0x04bda12f, 0x04924925, 0x0469ee58, 0x04444444, 0x04210842, 0x04000000, - 0x03e0f83e, 0x03c3c3c4, 0x03a83a84, 0x038e38e4, 0x03759f23, 0x035e50d8, 0x03483483, 0x03333333, - 0x031f3832, 0x030c30c3, 0x02fa0be8, 0x02e8ba2f, 0x02d82d83, 0x02c8590b, 0x02b93105, 0x02aaaaab, - 0x029cbc15, 0x028f5c29, 0x02828283, 0x02762762, 0x026a439f, 0x025ed098, 0x0253c825, 0x02492492, - 0x023ee090, 0x0234f72c, 0x022b63cc, 0x02222222, 0x02192e2a, 0x02108421, 0x02082082, 0x02000000, + 0x7fffffff, 0x40000000, 0x2aaaaaab, 0x20000000, 0x1999999a, 0x15555555, 0x12492492, 0x10000000, + 0x0e38e38e, 0x0ccccccd, 0x0ba2e8ba, 0x0aaaaaab, 0x09d89d8a, 0x09249249, 0x08888889, 0x08000000, + 0x07878788, 0x071c71c7, 0x06bca1af, 0x06666666, 0x06186186, 0x05d1745d, 0x0590b216, 0x05555555, + 0x051eb852, 0x04ec4ec5, 0x04bda12f, 0x04924925, 0x0469ee58, 0x04444444, 0x04210842, 0x04000000, + 0x03e0f83e, 0x03c3c3c4, 0x03a83a84, 0x038e38e4, 0x03759f23, 0x035e50d8, 0x03483483, 0x03333333, + 0x031f3832, 0x030c30c3, 0x02fa0be8, 0x02e8ba2f, 0x02d82d83, 0x02c8590b, 0x02b93105, 0x02aaaaab, + 0x029cbc15, 0x028f5c29, 0x02828283, 0x02762762, 0x026a439f, 0x025ed098, 0x0253c825, 0x02492492, + 0x023ee090, 0x0234f72c, 0x022b63cc, 0x02222222, 0x02192e2a, 0x02108421, 0x02082082, 0x02000000, }; /************************************************************************************** - * Function: EstimateEnvelope - * - * Description: estimate power of generated HF QMF bands in one time-domain envelope - * (4.6.18.7.3) - * - * Inputs: initialized PSInfoSBR struct - * initialized SBRHeader struct for this SCE/CPE block - * initialized SBRGrid struct for this channel - * initialized SBRFreq struct for this SCE/CPE block - * index of current envelope - * - * Outputs: power of each QMF subband, stored as integer (Q0) * 2^N, N >= 0 - * - * Return: none + Function: EstimateEnvelope + + Description: estimate power of generated HF QMF bands in one time-domain envelope + (4.6.18.7.3) + + Inputs: initialized PSInfoSBR struct + initialized SBRHeader struct for this SCE/CPE block + initialized SBRGrid struct for this channel + initialized SBRFreq struct for this SCE/CPE block + index of current envelope + + Outputs: power of each QMF subband, stored as integer (Q0) * 2^N, N >= 0 + + Return: none **************************************************************************************/ -static void EstimateEnvelope(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, int env) -{ - int i, m, iStart, iEnd, xre, xim, nScale, expMax; - int p, n, mStart, mEnd, invFact, t; - int *XBuf; - U64 eCurr; - unsigned char *freqBandTab; - - /* estimate current envelope */ - iStart = sbrGrid->envTimeBorder[env] + HF_ADJ; - iEnd = sbrGrid->envTimeBorder[env+1] + HF_ADJ; - if (sbrGrid->freqRes[env]) { - n = sbrFreq->nHigh; - freqBandTab = sbrFreq->freqHigh; - } else { - n = sbrFreq->nLow; - freqBandTab = sbrFreq->freqLow; - } - - /* ADS should inline MADD64 (smlal) properly, but check to make sure */ - expMax = 0; - if (sbrHdr->interpFreq) { - for (m = 0; m < sbrFreq->numQMFBands; m++) { - eCurr.w64 = 0; - XBuf = psi->XBuf[iStart][sbrFreq->kStart + m]; - for (i = iStart; i < iEnd; i++) { - /* scale to int before calculating power (precision not critical, and avoids overflow) */ - xre = (*XBuf) >> FBITS_OUT_QMFA; XBuf += 1; - xim = (*XBuf) >> FBITS_OUT_QMFA; XBuf += (2*64 - 1); - eCurr.w64 = MADD64(eCurr.w64, xre, xre); - eCurr.w64 = MADD64(eCurr.w64, xim, xim); - } - - /* eCurr.w64 is now Q(64 - 2*FBITS_OUT_QMFA) (64-bit word) - * if energy is too big to fit in 32-bit word (> 2^31) scale down by power of 2 - */ - nScale = 0; - if (eCurr.r.hi32) { - nScale = (32 - CLZ(eCurr.r.hi32)) + 1; - t = (int)(eCurr.r.lo32 >> nScale); /* logical (unsigned) >> */ - t |= eCurr.r.hi32 << (32 - nScale); - } else if (eCurr.r.lo32 >> 31) { - nScale = 1; - t = (int)(eCurr.r.lo32 >> nScale); /* logical (unsigned) >> */ - } else { - t = (int)eCurr.r.lo32; - } - - invFact = invBandTab[(iEnd - iStart)-1]; - psi->eCurr[m] = MULSHIFT32(t, invFact); - psi->eCurrExp[m] = nScale + 1; /* +1 for invFact = Q31 */ - if (psi->eCurrExp[m] > expMax) - expMax = psi->eCurrExp[m]; - } - } else { - for (p = 0; p < n; p++) { - mStart = freqBandTab[p]; - mEnd = freqBandTab[p+1]; - eCurr.w64 = 0; - for (i = iStart; i < iEnd; i++) { - XBuf = psi->XBuf[i][mStart]; - for (m = mStart; m < mEnd; m++) { - xre = (*XBuf++) >> FBITS_OUT_QMFA; - xim = (*XBuf++) >> FBITS_OUT_QMFA; - eCurr.w64 = MADD64(eCurr.w64, xre, xre); - eCurr.w64 = MADD64(eCurr.w64, xim, xim); - } - } - - nScale = 0; - if (eCurr.r.hi32) { - nScale = (32 - CLZ(eCurr.r.hi32)) + 1; - t = (int)(eCurr.r.lo32 >> nScale); /* logical (unsigned) >> */ - t |= eCurr.r.hi32 << (32 - nScale); - } else if (eCurr.r.lo32 >> 31) { - nScale = 1; - t = (int)(eCurr.r.lo32 >> nScale); /* logical (unsigned) >> */ - } else { - t = (int)eCurr.r.lo32; - } - - invFact = invBandTab[(iEnd - iStart)-1]; - invFact = MULSHIFT32(invBandTab[(mEnd - mStart)-1], invFact) << 1; - t = MULSHIFT32(t, invFact); - - for (m = mStart; m < mEnd; m++) { - psi->eCurr[m - sbrFreq->kStart] = t; - psi->eCurrExp[m - sbrFreq->kStart] = nScale + 1; /* +1 for invFact = Q31 */ - } - if (psi->eCurrExp[mStart - sbrFreq->kStart] > expMax) - expMax = psi->eCurrExp[mStart - sbrFreq->kStart]; - } - } - psi->eCurrExpMax = expMax; +static void EstimateEnvelope(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, int env) { + int i, m, iStart, iEnd, xre, xim, nScale, expMax; + int p, n, mStart, mEnd, invFact, t; + int *XBuf; + U64 eCurr; + unsigned char *freqBandTab; + + /* estimate current envelope */ + iStart = sbrGrid->envTimeBorder[env] + HF_ADJ; + iEnd = sbrGrid->envTimeBorder[env + 1] + HF_ADJ; + if (sbrGrid->freqRes[env]) { + n = sbrFreq->nHigh; + freqBandTab = sbrFreq->freqHigh; + } else { + n = sbrFreq->nLow; + freqBandTab = sbrFreq->freqLow; + } + + /* ADS should inline MADD64 (smlal) properly, but check to make sure */ + expMax = 0; + if (sbrHdr->interpFreq) { + for (m = 0; m < sbrFreq->numQMFBands; m++) { + eCurr.w64 = 0; + XBuf = psi->XBuf[iStart][sbrFreq->kStart + m]; + for (i = iStart; i < iEnd; i++) { + /* scale to int before calculating power (precision not critical, and avoids overflow) */ + xre = (*XBuf) >> FBITS_OUT_QMFA; XBuf += 1; + xim = (*XBuf) >> FBITS_OUT_QMFA; XBuf += (2 * 64 - 1); + eCurr.w64 = MADD64(eCurr.w64, xre, xre); + eCurr.w64 = MADD64(eCurr.w64, xim, xim); + } + + /* eCurr.w64 is now Q(64 - 2*FBITS_OUT_QMFA) (64-bit word) + if energy is too big to fit in 32-bit word (> 2^31) scale down by power of 2 + */ + nScale = 0; + if (eCurr.r.hi32) { + nScale = (32 - CLZ(eCurr.r.hi32)) + 1; + t = (int)(eCurr.r.lo32 >> nScale); /* logical (unsigned) >> */ + t |= eCurr.r.hi32 << (32 - nScale); + } else if (eCurr.r.lo32 >> 31) { + nScale = 1; + t = (int)(eCurr.r.lo32 >> nScale); /* logical (unsigned) >> */ + } else { + t = (int)eCurr.r.lo32; + } + + invFact = invBandTab[(iEnd - iStart) - 1]; + psi->eCurr[m] = MULSHIFT32(t, invFact); + psi->eCurrExp[m] = nScale + 1; /* +1 for invFact = Q31 */ + if (psi->eCurrExp[m] > expMax) { + expMax = psi->eCurrExp[m]; + } + } + } else { + for (p = 0; p < n; p++) { + mStart = freqBandTab[p]; + mEnd = freqBandTab[p + 1]; + eCurr.w64 = 0; + for (i = iStart; i < iEnd; i++) { + XBuf = psi->XBuf[i][mStart]; + for (m = mStart; m < mEnd; m++) { + xre = (*XBuf++) >> FBITS_OUT_QMFA; + xim = (*XBuf++) >> FBITS_OUT_QMFA; + eCurr.w64 = MADD64(eCurr.w64, xre, xre); + eCurr.w64 = MADD64(eCurr.w64, xim, xim); + } + } + + nScale = 0; + if (eCurr.r.hi32) { + nScale = (32 - CLZ(eCurr.r.hi32)) + 1; + t = (int)(eCurr.r.lo32 >> nScale); /* logical (unsigned) >> */ + t |= eCurr.r.hi32 << (32 - nScale); + } else if (eCurr.r.lo32 >> 31) { + nScale = 1; + t = (int)(eCurr.r.lo32 >> nScale); /* logical (unsigned) >> */ + } else { + t = (int)eCurr.r.lo32; + } + + invFact = invBandTab[(iEnd - iStart) - 1]; + invFact = MULSHIFT32(invBandTab[(mEnd - mStart) - 1], invFact) << 1; + t = MULSHIFT32(t, invFact); + + for (m = mStart; m < mEnd; m++) { + psi->eCurr[m - sbrFreq->kStart] = t; + psi->eCurrExp[m - sbrFreq->kStart] = nScale + 1; /* +1 for invFact = Q31 */ + } + if (psi->eCurrExp[mStart - sbrFreq->kStart] > expMax) { + expMax = psi->eCurrExp[mStart - sbrFreq->kStart]; + } + } + } + psi->eCurrExpMax = expMax; } /************************************************************************************** - * Function: GetSMapped - * - * Description: calculate SMapped (4.6.18.7.2) - * - * Inputs: initialized PSInfoSBR struct - * initialized SBRGrid struct for this channel - * initialized SBRFreq struct for this SCE/CPE block - * initialized SBRChan struct for this channel - * index of current envelope - * index of current QMF band - * la flag for this envelope - * - * Outputs: none - * - * Return: 1 if a sinusoid is present in this band, 0 if not + Function: GetSMapped + + Description: calculate SMapped (4.6.18.7.2) + + Inputs: initialized PSInfoSBR struct + initialized SBRGrid struct for this channel + initialized SBRFreq struct for this SCE/CPE block + initialized SBRChan struct for this channel + index of current envelope + index of current QMF band + la flag for this envelope + + Outputs: none + + Return: 1 if a sinusoid is present in this band, 0 if not **************************************************************************************/ -static int GetSMapped(SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int env, int band, int la) -{ - int bandStart, bandEnd, oddFlag, r; - - if (sbrGrid->freqRes[env]) { - /* high resolution */ - bandStart = band; - bandEnd = band+1; - } else { - /* low resolution (see CalcFreqLow() for mapping) */ - oddFlag = sbrFreq->nHigh & 0x01; - bandStart = (band > 0 ? 2*band - oddFlag : 0); /* starting index for freqLow[band] */ - bandEnd = 2*(band+1) - oddFlag; /* ending index for freqLow[band+1] */ - } - - /* sMapped = 1 if sIndexMapped == 1 for any frequency in this band */ - for (band = bandStart; band < bandEnd; band++) { - if (sbrChan->addHarmonic[1][band]) { - r = ((sbrFreq->freqHigh[band+1] + sbrFreq->freqHigh[band]) >> 1); - if (env >= la || sbrChan->addHarmonic[0][r] == 1) - return 1; - } - } - return 0; +static int GetSMapped(SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int env, int band, int la) { + int bandStart, bandEnd, oddFlag, r; + + if (sbrGrid->freqRes[env]) { + /* high resolution */ + bandStart = band; + bandEnd = band + 1; + } else { + /* low resolution (see CalcFreqLow() for mapping) */ + oddFlag = sbrFreq->nHigh & 0x01; + bandStart = (band > 0 ? 2 * band - oddFlag : 0); /* starting index for freqLow[band] */ + bandEnd = 2 * (band + 1) - oddFlag; /* ending index for freqLow[band+1] */ + } + + /* sMapped = 1 if sIndexMapped == 1 for any frequency in this band */ + for (band = bandStart; band < bandEnd; band++) { + if (sbrChan->addHarmonic[1][band]) { + r = ((sbrFreq->freqHigh[band + 1] + sbrFreq->freqHigh[band]) >> 1); + if (env >= la || sbrChan->addHarmonic[0][r] == 1) { + return 1; + } + } + } + return 0; } #define GBOOST_MAX 0x2830afd3 /* Q28, 1.584893192 squared */ @@ -220,634 +221,642 @@ static int GetSMapped(SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int static const int limGainTab[4] PROGMEM = {0x20138ca7, 0x40000000, 0x7fb27dce, 0x80000000}; /* Q30 (0x80000000 = sentinel for GMAX) */ /************************************************************************************** - * Function: CalcMaxGain - * - * Description: calculate max gain in one limiter band (4.6.18.7.5) - * - * Inputs: initialized PSInfoSBR struct - * initialized SBRHeader struct for this SCE/CPE block - * initialized SBRGrid struct for this channel - * initialized SBRFreq struct for this SCE/CPE block - * index of current channel (0 for SCE, 0 or 1 for CPE) - * index of current envelope - * index of current limiter band - * number of fraction bits in dequantized envelope - * (max = Q(FBITS_OUT_DQ_ENV - 6) = Q23, can go negative) - * - * Outputs: updated gainMax, gainMaxFBits, and sumEOrigMapped in PSInfoSBR struct - * - * Return: none + Function: CalcMaxGain + + Description: calculate max gain in one limiter band (4.6.18.7.5) + + Inputs: initialized PSInfoSBR struct + initialized SBRHeader struct for this SCE/CPE block + initialized SBRGrid struct for this channel + initialized SBRFreq struct for this SCE/CPE block + index of current channel (0 for SCE, 0 or 1 for CPE) + index of current envelope + index of current limiter band + number of fraction bits in dequantized envelope + (max = Q(FBITS_OUT_DQ_ENV - 6) = Q23, can go negative) + + Outputs: updated gainMax, gainMaxFBits, and sumEOrigMapped in PSInfoSBR struct + + Return: none **************************************************************************************/ -static void CalcMaxGain(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, int ch, int env, int lim, int fbitsDQ) -{ - int m, mStart, mEnd, q, z, r; - int sumEOrigMapped, sumECurr, gainMax, eOMGainMax, envBand; - unsigned char eCurrExpMax; - unsigned char *freqBandTab; - - mStart = sbrFreq->freqLimiter[lim]; /* these are offsets from kStart */ - mEnd = sbrFreq->freqLimiter[lim + 1]; - freqBandTab = (sbrGrid->freqRes[env] ? sbrFreq->freqHigh : sbrFreq->freqLow); - - /* calculate max gain to apply to signal in this limiter band */ - sumECurr = 0; - sumEOrigMapped = 0; - eCurrExpMax = psi->eCurrExpMax; - eOMGainMax = psi->eOMGainMax; - envBand = psi->envBand; - for (m = mStart; m < mEnd; m++) { - /* map current QMF band to appropriate envelope band */ - if (m == freqBandTab[envBand + 1] - sbrFreq->kStart) { - envBand++; - eOMGainMax = psi->envDataDequant[ch][env][envBand] >> ACC_SCALE; /* summing max 48 bands */ - } - sumEOrigMapped += eOMGainMax; - - /* easy test for overflow on ARM */ - sumECurr += (psi->eCurr[m] >> (eCurrExpMax - psi->eCurrExp[m])); - if (sumECurr >> 30) { - sumECurr >>= 1; - eCurrExpMax++; - } - } - psi->eOMGainMax = eOMGainMax; - psi->envBand = envBand; - - psi->gainMaxFBits = 30; /* Q30 tables */ - if (sumECurr == 0) { - /* any non-zero numerator * 1/EPS_0 is > G_MAX */ - gainMax = (sumEOrigMapped == 0 ? (int)limGainTab[sbrHdr->limiterGains] : (int)0x80000000); - } else if (sumEOrigMapped == 0) { - /* 1/(any non-zero denominator) * EPS_0 * limGainTab[x] is appx. 0 */ - gainMax = 0; - } else { - /* sumEOrigMapped = Q(fbitsDQ - ACC_SCALE), sumECurr = Q(-eCurrExpMax) */ - gainMax = limGainTab[sbrHdr->limiterGains]; - if (sbrHdr->limiterGains != 3) { - q = MULSHIFT32(sumEOrigMapped, gainMax); /* Q(fbitsDQ - ACC_SCALE - 2), gainMax = Q30 */ - z = CLZ(sumECurr) - 1; - r = InvRNormalized(sumECurr << z); /* in = Q(z - eCurrExpMax), out = Q(29 + 31 - z + eCurrExpMax) */ - gainMax = MULSHIFT32(q, r); /* Q(29 + 31 - z + eCurrExpMax + fbitsDQ - ACC_SCALE - 2 - 32) */ - psi->gainMaxFBits = 26 - z + eCurrExpMax + fbitsDQ - ACC_SCALE; - } - } - psi->sumEOrigMapped = sumEOrigMapped; - psi->gainMax = gainMax; +static void CalcMaxGain(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, int ch, int env, int lim, int fbitsDQ) { + int m, mStart, mEnd, q, z, r; + int sumEOrigMapped, sumECurr, gainMax, eOMGainMax, envBand; + unsigned char eCurrExpMax; + unsigned char *freqBandTab; + + mStart = sbrFreq->freqLimiter[lim]; /* these are offsets from kStart */ + mEnd = sbrFreq->freqLimiter[lim + 1]; + freqBandTab = (sbrGrid->freqRes[env] ? sbrFreq->freqHigh : sbrFreq->freqLow); + + /* calculate max gain to apply to signal in this limiter band */ + sumECurr = 0; + sumEOrigMapped = 0; + eCurrExpMax = psi->eCurrExpMax; + eOMGainMax = psi->eOMGainMax; + envBand = psi->envBand; + for (m = mStart; m < mEnd; m++) { + /* map current QMF band to appropriate envelope band */ + if (m == freqBandTab[envBand + 1] - sbrFreq->kStart) { + envBand++; + eOMGainMax = psi->envDataDequant[ch][env][envBand] >> ACC_SCALE; /* summing max 48 bands */ + } + sumEOrigMapped += eOMGainMax; + + /* easy test for overflow on ARM */ + sumECurr += (psi->eCurr[m] >> (eCurrExpMax - psi->eCurrExp[m])); + if (sumECurr >> 30) { + sumECurr >>= 1; + eCurrExpMax++; + } + } + psi->eOMGainMax = eOMGainMax; + psi->envBand = envBand; + + psi->gainMaxFBits = 30; /* Q30 tables */ + if (sumECurr == 0) { + /* any non-zero numerator * 1/EPS_0 is > G_MAX */ + gainMax = (sumEOrigMapped == 0 ? (int)limGainTab[sbrHdr->limiterGains] : (int)0x80000000); + } else if (sumEOrigMapped == 0) { + /* 1/(any non-zero denominator) * EPS_0 * limGainTab[x] is appx. 0 */ + gainMax = 0; + } else { + /* sumEOrigMapped = Q(fbitsDQ - ACC_SCALE), sumECurr = Q(-eCurrExpMax) */ + gainMax = limGainTab[sbrHdr->limiterGains]; + if (sbrHdr->limiterGains != 3) { + q = MULSHIFT32(sumEOrigMapped, gainMax); /* Q(fbitsDQ - ACC_SCALE - 2), gainMax = Q30 */ + z = CLZ(sumECurr) - 1; + r = InvRNormalized(sumECurr << z); /* in = Q(z - eCurrExpMax), out = Q(29 + 31 - z + eCurrExpMax) */ + gainMax = MULSHIFT32(q, r); /* Q(29 + 31 - z + eCurrExpMax + fbitsDQ - ACC_SCALE - 2 - 32) */ + psi->gainMaxFBits = 26 - z + eCurrExpMax + fbitsDQ - ACC_SCALE; + } + } + psi->sumEOrigMapped = sumEOrigMapped; + psi->gainMax = gainMax; } /************************************************************************************** - * Function: CalcNoiseDivFactors - * - * Description: calculate 1/(1+Q) and Q/(1+Q) (4.6.18.7.4; 4.6.18.7.5) - * - * Inputs: dequantized noise floor scalefactor - * - * Outputs: 1/(1+Q) and Q/(1+Q), format = Q31 - * - * Return: none + Function: CalcNoiseDivFactors + + Description: calculate 1/(1+Q) and Q/(1+Q) (4.6.18.7.4; 4.6.18.7.5) + + Inputs: dequantized noise floor scalefactor + + Outputs: 1/(1+Q) and Q/(1+Q), format = Q31 + + Return: none **************************************************************************************/ -static void CalcNoiseDivFactors(int q, int *qp1Inv, int *qqp1Inv) -{ - int z, qp1, t, s; - - /* 1 + Q_orig */ - qp1 = (q >> 1); - qp1 += (1 << (FBITS_OUT_DQ_NOISE - 1)); /* >> 1 to avoid overflow when adding 1.0 */ - z = CLZ(qp1) - 1; /* z <= 31 - FBITS_OUT_DQ_NOISE */ - qp1 <<= z; /* Q(FBITS_OUT_DQ_NOISE + z) = Q31 * 2^-(31 - (FBITS_OUT_DQ_NOISE + z)) */ - t = InvRNormalized(qp1) << 1; /* Q30 * 2^(31 - (FBITS_OUT_DQ_NOISE + z)), guaranteed not to overflow */ - - /* normalize to Q31 */ - s = (31 - (FBITS_OUT_DQ_NOISE - 1) - z - 1); /* clearly z >= 0, z <= (30 - (FBITS_OUT_DQ_NOISE - 1)) */ - *qp1Inv = (t >> s); /* s = [0, 31 - FBITS_OUT_DQ_NOISE] */ - *qqp1Inv = MULSHIFT32(t, q) << (32 - FBITS_OUT_DQ_NOISE - s); +static void CalcNoiseDivFactors(int q, int *qp1Inv, int *qqp1Inv) { + int z, qp1, t, s; + + /* 1 + Q_orig */ + qp1 = (q >> 1); + qp1 += (1 << (FBITS_OUT_DQ_NOISE - 1)); /* >> 1 to avoid overflow when adding 1.0 */ + z = CLZ(qp1) - 1; /* z <= 31 - FBITS_OUT_DQ_NOISE */ + qp1 <<= z; /* Q(FBITS_OUT_DQ_NOISE + z) = Q31 * 2^-(31 - (FBITS_OUT_DQ_NOISE + z)) */ + t = InvRNormalized(qp1) << 1; /* Q30 * 2^(31 - (FBITS_OUT_DQ_NOISE + z)), guaranteed not to overflow */ + + /* normalize to Q31 */ + s = (31 - (FBITS_OUT_DQ_NOISE - 1) - z - 1); /* clearly z >= 0, z <= (30 - (FBITS_OUT_DQ_NOISE - 1)) */ + *qp1Inv = (t >> s); /* s = [0, 31 - FBITS_OUT_DQ_NOISE] */ + *qqp1Inv = MULSHIFT32(t, q) << (32 - FBITS_OUT_DQ_NOISE - s); } /************************************************************************************** - * Function: CalcComponentGains - * - * Description: calculate gain of envelope, sinusoids, and noise in one limiter band - * (4.6.18.7.5) - * - * Inputs: initialized PSInfoSBR struct - * initialized SBRHeader struct for this SCE/CPE block - * initialized SBRGrid struct for this channel - * initialized SBRFreq struct for this SCE/CPE block - * initialized SBRChan struct for this channel - * index of current channel (0 for SCE, 0 or 1 for CPE) - * index of current envelope - * index of current limiter band - * number of fraction bits in dequantized envelope - * - * Outputs: gains for envelope, sinusoids and noise - * number of fraction bits for envelope gain - * sum of the total gain for each component in this band - * other updated state variables - * - * Return: none + Function: CalcComponentGains + + Description: calculate gain of envelope, sinusoids, and noise in one limiter band + (4.6.18.7.5) + + Inputs: initialized PSInfoSBR struct + initialized SBRHeader struct for this SCE/CPE block + initialized SBRGrid struct for this channel + initialized SBRFreq struct for this SCE/CPE block + initialized SBRChan struct for this channel + index of current channel (0 for SCE, 0 or 1 for CPE) + index of current envelope + index of current limiter band + number of fraction bits in dequantized envelope + + Outputs: gains for envelope, sinusoids and noise + number of fraction bits for envelope gain + sum of the total gain for each component in this band + other updated state variables + + Return: none **************************************************************************************/ -static void CalcComponentGains(PSInfoSBR *psi, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch, int env, int lim, int fbitsDQ) -{ - int d, m, mStart, mEnd, q, qm, noiseFloor, sIndexMapped; - int shift, eCurr, maxFlag, gainMax, gainMaxFBits; - int gain, sm, z, r, fbitsGain, gainScale; - unsigned char *freqBandTab; - - mStart = sbrFreq->freqLimiter[lim]; /* these are offsets from kStart */ - mEnd = sbrFreq->freqLimiter[lim + 1]; - - gainMax = psi->gainMax; - gainMaxFBits = psi->gainMaxFBits; - - d = (env == psi->la || env == sbrChan->laPrev ? 0 : 1); - freqBandTab = (sbrGrid->freqRes[env] ? sbrFreq->freqHigh : sbrFreq->freqLow); - - /* figure out which noise floor this envelope is in (only 1 or 2 noise floors allowed) */ - noiseFloor = 0; - if (sbrGrid->numNoiseFloors == 2 && sbrGrid->noiseTimeBorder[1] <= sbrGrid->envTimeBorder[env]) - noiseFloor++; - - psi->sumECurrGLim = 0; - psi->sumSM = 0; - psi->sumQM = 0; - /* calculate energy of noise to add in this limiter band */ - for (m = mStart; m < mEnd; m++) { - if (m == sbrFreq->freqNoise[psi->noiseFloorBand + 1] - sbrFreq->kStart) { - /* map current QMF band to appropriate noise floor band (NOTE: freqLimiter[0] == freqLow[0] = freqHigh[0]) */ - psi->noiseFloorBand++; - CalcNoiseDivFactors(psi->noiseDataDequant[ch][noiseFloor][psi->noiseFloorBand], &(psi->qp1Inv), &(psi->qqp1Inv)); - } - if (m == sbrFreq->freqHigh[psi->highBand + 1] - sbrFreq->kStart) - psi->highBand++; - if (m == freqBandTab[psi->sBand + 1] - sbrFreq->kStart) { - psi->sBand++; - psi->sMapped = GetSMapped(sbrGrid, sbrFreq, sbrChan, env, psi->sBand, psi->la); - } - - /* get sIndexMapped for this QMF subband */ - sIndexMapped = 0; - r = ((sbrFreq->freqHigh[psi->highBand+1] + sbrFreq->freqHigh[psi->highBand]) >> 1); - if (m + sbrFreq->kStart == r) { - /* r = center frequency, deltaStep = (env >= la || sIndexMapped'(r, numEnv'-1) == 1) */ - if (env >= psi->la || sbrChan->addHarmonic[0][r] == 1) - sIndexMapped = sbrChan->addHarmonic[1][psi->highBand]; - } - - /* save sine flags from last envelope in this frame: - * addHarmonic[0][0...63] = saved sine present flag from previous frame, for each QMF subband - * addHarmonic[1][0...nHigh-1] = addHarmonic bit from current frame, for each high-res frequency band - * from MPEG reference code - slightly different from spec - * (sIndexMapped'(m,LE'-1) can still be 0 when numEnv == psi->la) - */ - if (env == sbrGrid->numEnv - 1) { - if (m + sbrFreq->kStart == r) - sbrChan->addHarmonic[0][m + sbrFreq->kStart] = sbrChan->addHarmonic[1][psi->highBand]; - else - sbrChan->addHarmonic[0][m + sbrFreq->kStart] = 0; - } - - gain = psi->envDataDequant[ch][env][psi->sBand]; - qm = MULSHIFT32(gain, psi->qqp1Inv) << 1; - sm = (sIndexMapped ? MULSHIFT32(gain, psi->qp1Inv) << 1 : 0); - - /* three cases: (sMapped == 0 && delta == 1), (sMapped == 0 && delta == 0), (sMapped == 1) */ - if (d == 1 && psi->sMapped == 0) - gain = MULSHIFT32(psi->qp1Inv, gain) << 1; - else if (psi->sMapped != 0) - gain = MULSHIFT32(psi->qqp1Inv, gain) << 1; - - /* gain, qm, sm = Q(fbitsDQ), gainMax = Q(fbitsGainMax) */ - eCurr = psi->eCurr[m]; - if (eCurr) { - z = CLZ(eCurr) - 1; - r = InvRNormalized(eCurr << z); /* in = Q(z - eCurrExp), out = Q(29 + 31 - z + eCurrExp) */ - gainScale = MULSHIFT32(gain, r); /* out = Q(29 + 31 - z + eCurrExp + fbitsDQ - 32) */ - fbitsGain = 29 + 31 - z + psi->eCurrExp[m] + fbitsDQ - 32; - } else { - /* if eCurr == 0, then gain is unchanged (divide by EPS = 1) */ - gainScale = gain; - fbitsGain = fbitsDQ; - } - - /* see if gain for this band exceeds max gain */ - maxFlag = 0; - if (gainMax != (int)0x80000000) { - if (fbitsGain >= gainMaxFBits) { - shift = MIN(fbitsGain - gainMaxFBits, 31); - maxFlag = ((gainScale >> shift) > gainMax ? 1 : 0); - } else { - shift = MIN(gainMaxFBits - fbitsGain, 31); - maxFlag = (gainScale > (gainMax >> shift) ? 1 : 0); - } - } - - if (maxFlag) { - /* gainScale > gainMax, calculate ratio with 32/16 division */ - q = 0; - r = gainScale; /* guaranteed > 0, else maxFlag could not have been set */ - z = CLZ(r); - if (z < 16) { - q = 16 - z; - r >>= q; /* out = Q(fbitsGain - q) */ - } - - z = CLZ(gainMax) - 1; - r = (gainMax << z) / r; /* out = Q((fbitsGainMax + z) - (fbitsGain - q)) */ - q = (gainMaxFBits + z) - (fbitsGain - q); /* r = Q(q) */ - if (q > 30) { - r >>= MIN(q - 30, 31); - } else { - z = MIN(30 - q, 30); - CLIP_2N_SHIFT30(r, z); /* let r = Q30 since range = [0.0, 1.0) (clip to 0x3fffffff = 0.99999) */ - } - - qm = MULSHIFT32(qm, r) << 2; - gain = MULSHIFT32(gain, r) << 2; - psi->gLimBuf[m] = gainMax; - psi->gLimFbits[m] = gainMaxFBits; - } else { - psi->gLimBuf[m] = gainScale; - psi->gLimFbits[m] = fbitsGain; - } - - /* sumSM, sumQM, sumECurrGLim = Q(fbitsDQ - ACC_SCALE) */ - psi->smBuf[m] = sm; - psi->sumSM += (sm >> ACC_SCALE); - - psi->qmLimBuf[m] = qm; - if (env != psi->la && env != sbrChan->laPrev && sm == 0) - psi->sumQM += (qm >> ACC_SCALE); - - /* eCurr * gain^2 same as gain^2, before division by eCurr - * (but note that gain != 0 even if eCurr == 0, since it's divided by eps) - */ - if (eCurr) - psi->sumECurrGLim += (gain >> ACC_SCALE); - } +static void CalcComponentGains(PSInfoSBR *psi, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch, int env, int lim, int fbitsDQ) { + int d, m, mStart, mEnd, q, qm, noiseFloor, sIndexMapped; + int shift, eCurr, maxFlag, gainMax, gainMaxFBits; + int gain, sm, z, r, fbitsGain, gainScale; + unsigned char *freqBandTab; + + mStart = sbrFreq->freqLimiter[lim]; /* these are offsets from kStart */ + mEnd = sbrFreq->freqLimiter[lim + 1]; + + gainMax = psi->gainMax; + gainMaxFBits = psi->gainMaxFBits; + + d = (env == psi->la || env == sbrChan->laPrev ? 0 : 1); + freqBandTab = (sbrGrid->freqRes[env] ? sbrFreq->freqHigh : sbrFreq->freqLow); + + /* figure out which noise floor this envelope is in (only 1 or 2 noise floors allowed) */ + noiseFloor = 0; + if (sbrGrid->numNoiseFloors == 2 && sbrGrid->noiseTimeBorder[1] <= sbrGrid->envTimeBorder[env]) { + noiseFloor++; + } + + psi->sumECurrGLim = 0; + psi->sumSM = 0; + psi->sumQM = 0; + /* calculate energy of noise to add in this limiter band */ + for (m = mStart; m < mEnd; m++) { + if (m == sbrFreq->freqNoise[psi->noiseFloorBand + 1] - sbrFreq->kStart) { + /* map current QMF band to appropriate noise floor band (NOTE: freqLimiter[0] == freqLow[0] = freqHigh[0]) */ + psi->noiseFloorBand++; + CalcNoiseDivFactors(psi->noiseDataDequant[ch][noiseFloor][psi->noiseFloorBand], &(psi->qp1Inv), &(psi->qqp1Inv)); + } + if (m == sbrFreq->freqHigh[psi->highBand + 1] - sbrFreq->kStart) { + psi->highBand++; + } + if (m == freqBandTab[psi->sBand + 1] - sbrFreq->kStart) { + psi->sBand++; + psi->sMapped = GetSMapped(sbrGrid, sbrFreq, sbrChan, env, psi->sBand, psi->la); + } + + /* get sIndexMapped for this QMF subband */ + sIndexMapped = 0; + r = ((sbrFreq->freqHigh[psi->highBand + 1] + sbrFreq->freqHigh[psi->highBand]) >> 1); + if (m + sbrFreq->kStart == r) { + /* r = center frequency, deltaStep = (env >= la || sIndexMapped'(r, numEnv'-1) == 1) */ + if (env >= psi->la || sbrChan->addHarmonic[0][r] == 1) { + sIndexMapped = sbrChan->addHarmonic[1][psi->highBand]; + } + } + + /* save sine flags from last envelope in this frame: + addHarmonic[0][0...63] = saved sine present flag from previous frame, for each QMF subband + addHarmonic[1][0...nHigh-1] = addHarmonic bit from current frame, for each high-res frequency band + from MPEG reference code - slightly different from spec + (sIndexMapped'(m,LE'-1) can still be 0 when numEnv == psi->la) + */ + if (env == sbrGrid->numEnv - 1) { + if (m + sbrFreq->kStart == r) { + sbrChan->addHarmonic[0][m + sbrFreq->kStart] = sbrChan->addHarmonic[1][psi->highBand]; + } else { + sbrChan->addHarmonic[0][m + sbrFreq->kStart] = 0; + } + } + + gain = psi->envDataDequant[ch][env][psi->sBand]; + qm = MULSHIFT32(gain, psi->qqp1Inv) << 1; + sm = (sIndexMapped ? MULSHIFT32(gain, psi->qp1Inv) << 1 : 0); + + /* three cases: (sMapped == 0 && delta == 1), (sMapped == 0 && delta == 0), (sMapped == 1) */ + if (d == 1 && psi->sMapped == 0) { + gain = MULSHIFT32(psi->qp1Inv, gain) << 1; + } else if (psi->sMapped != 0) { + gain = MULSHIFT32(psi->qqp1Inv, gain) << 1; + } + + /* gain, qm, sm = Q(fbitsDQ), gainMax = Q(fbitsGainMax) */ + eCurr = psi->eCurr[m]; + if (eCurr) { + z = CLZ(eCurr) - 1; + r = InvRNormalized(eCurr << z); /* in = Q(z - eCurrExp), out = Q(29 + 31 - z + eCurrExp) */ + gainScale = MULSHIFT32(gain, r); /* out = Q(29 + 31 - z + eCurrExp + fbitsDQ - 32) */ + fbitsGain = 29 + 31 - z + psi->eCurrExp[m] + fbitsDQ - 32; + } else { + /* if eCurr == 0, then gain is unchanged (divide by EPS = 1) */ + gainScale = gain; + fbitsGain = fbitsDQ; + } + + /* see if gain for this band exceeds max gain */ + maxFlag = 0; + if (gainMax != (int)0x80000000) { + if (fbitsGain >= gainMaxFBits) { + shift = MIN(fbitsGain - gainMaxFBits, 31); + maxFlag = ((gainScale >> shift) > gainMax ? 1 : 0); + } else { + shift = MIN(gainMaxFBits - fbitsGain, 31); + maxFlag = (gainScale > (gainMax >> shift) ? 1 : 0); + } + } + + if (maxFlag) { + /* gainScale > gainMax, calculate ratio with 32/16 division */ + q = 0; + r = gainScale; /* guaranteed > 0, else maxFlag could not have been set */ + z = CLZ(r); + if (z < 16) { + q = 16 - z; + r >>= q; /* out = Q(fbitsGain - q) */ + } + + z = CLZ(gainMax) - 1; + r = (gainMax << z) / r; /* out = Q((fbitsGainMax + z) - (fbitsGain - q)) */ + q = (gainMaxFBits + z) - (fbitsGain - q); /* r = Q(q) */ + if (q > 30) { + r >>= MIN(q - 30, 31); + } else { + z = MIN(30 - q, 30); + CLIP_2N_SHIFT30(r, z); /* let r = Q30 since range = [0.0, 1.0) (clip to 0x3fffffff = 0.99999) */ + } + + qm = MULSHIFT32(qm, r) << 2; + gain = MULSHIFT32(gain, r) << 2; + psi->gLimBuf[m] = gainMax; + psi->gLimFbits[m] = gainMaxFBits; + } else { + psi->gLimBuf[m] = gainScale; + psi->gLimFbits[m] = fbitsGain; + } + + /* sumSM, sumQM, sumECurrGLim = Q(fbitsDQ - ACC_SCALE) */ + psi->smBuf[m] = sm; + psi->sumSM += (sm >> ACC_SCALE); + + psi->qmLimBuf[m] = qm; + if (env != psi->la && env != sbrChan->laPrev && sm == 0) { + psi->sumQM += (qm >> ACC_SCALE); + } + + /* eCurr * gain^2 same as gain^2, before division by eCurr + (but note that gain != 0 even if eCurr == 0, since it's divided by eps) + */ + if (eCurr) { + psi->sumECurrGLim += (gain >> ACC_SCALE); + } + } } /************************************************************************************** - * Function: ApplyBoost - * - * Description: calculate and apply boost factor for envelope, sinusoids, and noise - * in this limiter band (4.6.18.7.5) - * - * Inputs: initialized PSInfoSBR struct - * initialized SBRFreq struct for this SCE/CPE block - * index of current limiter band - * number of fraction bits in dequantized envelope - * - * Outputs: envelope gain, sinusoids and noise after scaling by gBoost - * format = Q(FBITS_GLIM_BOOST) for envelope gain, - * = Q(FBITS_QLIM_BOOST) for noise - * = Q(FBITS_OUT_QMFA) for sinusoids - * - * Return: none - * - * Notes: after scaling, each component has at least 1 GB + Function: ApplyBoost + + Description: calculate and apply boost factor for envelope, sinusoids, and noise + in this limiter band (4.6.18.7.5) + + Inputs: initialized PSInfoSBR struct + initialized SBRFreq struct for this SCE/CPE block + index of current limiter band + number of fraction bits in dequantized envelope + + Outputs: envelope gain, sinusoids and noise after scaling by gBoost + format = Q(FBITS_GLIM_BOOST) for envelope gain, + = Q(FBITS_QLIM_BOOST) for noise + = Q(FBITS_OUT_QMFA) for sinusoids + + Return: none + + Notes: after scaling, each component has at least 1 GB **************************************************************************************/ -static void ApplyBoost(PSInfoSBR *psi, SBRFreq *sbrFreq, int lim, int fbitsDQ) -{ - int m, mStart, mEnd, q, z, r; - int sumEOrigMapped, gBoost; - - mStart = sbrFreq->freqLimiter[lim]; /* these are offsets from kStart */ - mEnd = sbrFreq->freqLimiter[lim + 1]; - - sumEOrigMapped = psi->sumEOrigMapped >> 1; - r = (psi->sumECurrGLim >> 1) + (psi->sumSM >> 1) + (psi->sumQM >> 1); /* 1 GB fine (sm and qm are mutually exclusive in acc) */ - if (r < (1 << (31-28))) { - /* any non-zero numerator * 1/EPS_0 is > GBOOST_MAX - * round very small r to zero to avoid scaling problems - */ - gBoost = (sumEOrigMapped == 0 ? (1 << 28) : GBOOST_MAX); - z = 0; - } else if (sumEOrigMapped == 0) { - /* 1/(any non-zero denominator) * EPS_0 is appx. 0 */ - gBoost = 0; - z = 0; - } else { - /* numerator (sumEOrigMapped) and denominator (r) have same Q format (before << z) */ - z = CLZ(r) - 1; /* z = [0, 27] */ - r = InvRNormalized(r << z); - gBoost = MULSHIFT32(sumEOrigMapped, r); - } - - /* gBoost = Q(28 - z) */ - if (gBoost > (GBOOST_MAX >> z)) { - gBoost = GBOOST_MAX; - z = 0; - } - gBoost <<= z; /* gBoost = Q28, minimum 1 GB */ - - /* convert gain, noise, sinusoids to fixed Q format, clipping if necessary - * (rare, usually only happens at very low bitrates, introduces slight - * distortion into final HF mapping, but should be inaudible) - */ - for (m = mStart; m < mEnd; m++) { - /* let gLimBoost = Q24, since in practice the max values are usually 16 to 20 - * unless limiterGains == 3 (limiter off) and eCurr ~= 0 (i.e. huge gain, but only - * because the envelope has 0 power anyway) - */ - q = MULSHIFT32(psi->gLimBuf[m], gBoost) << 2; /* Q(gLimFbits) * Q(28) --> Q(gLimFbits[m]-2) */ - r = SqrtFix(q, psi->gLimFbits[m] - 2, &z); - z -= FBITS_GLIM_BOOST; - if (z >= 0) { - psi->gLimBoost[m] = r >> MIN(z, 31); - } else { - z = MIN(30, -z); - CLIP_2N_SHIFT30(r, z); - psi->gLimBoost[m] = r; - } - - q = MULSHIFT32(psi->qmLimBuf[m], gBoost) << 2; /* Q(fbitsDQ) * Q(28) --> Q(fbitsDQ-2) */ - r = SqrtFix(q, fbitsDQ - 2, &z); - z -= FBITS_QLIM_BOOST; /* << by 14, since integer sqrt of x < 2^16, and we want to leave 1 GB */ - if (z >= 0) { - psi->qmLimBoost[m] = r >> MIN(31, z); - } else { - z = MIN(30, -z); - CLIP_2N_SHIFT30(r, z); - psi->qmLimBoost[m] = r; - } - - q = MULSHIFT32(psi->smBuf[m], gBoost) << 2; /* Q(fbitsDQ) * Q(28) --> Q(fbitsDQ-2) */ - r = SqrtFix(q, fbitsDQ - 2, &z); - z -= FBITS_OUT_QMFA; /* justify for adding to signal (xBuf) later */ - if (z >= 0) { - psi->smBoost[m] = r >> MIN(31, z); - } else { - z = MIN(30, -z); - CLIP_2N_SHIFT30(r, z); - psi->smBoost[m] = r; - } - } +static void ApplyBoost(PSInfoSBR *psi, SBRFreq *sbrFreq, int lim, int fbitsDQ) { + int m, mStart, mEnd, q, z, r; + int sumEOrigMapped, gBoost; + + mStart = sbrFreq->freqLimiter[lim]; /* these are offsets from kStart */ + mEnd = sbrFreq->freqLimiter[lim + 1]; + + sumEOrigMapped = psi->sumEOrigMapped >> 1; + r = (psi->sumECurrGLim >> 1) + (psi->sumSM >> 1) + (psi->sumQM >> 1); /* 1 GB fine (sm and qm are mutually exclusive in acc) */ + if (r < (1 << (31 - 28))) { + /* any non-zero numerator * 1/EPS_0 is > GBOOST_MAX + round very small r to zero to avoid scaling problems + */ + gBoost = (sumEOrigMapped == 0 ? (1 << 28) : GBOOST_MAX); + z = 0; + } else if (sumEOrigMapped == 0) { + /* 1/(any non-zero denominator) * EPS_0 is appx. 0 */ + gBoost = 0; + z = 0; + } else { + /* numerator (sumEOrigMapped) and denominator (r) have same Q format (before << z) */ + z = CLZ(r) - 1; /* z = [0, 27] */ + r = InvRNormalized(r << z); + gBoost = MULSHIFT32(sumEOrigMapped, r); + } + + /* gBoost = Q(28 - z) */ + if (gBoost > (GBOOST_MAX >> z)) { + gBoost = GBOOST_MAX; + z = 0; + } + gBoost <<= z; /* gBoost = Q28, minimum 1 GB */ + + /* convert gain, noise, sinusoids to fixed Q format, clipping if necessary + (rare, usually only happens at very low bitrates, introduces slight + distortion into final HF mapping, but should be inaudible) + */ + for (m = mStart; m < mEnd; m++) { + /* let gLimBoost = Q24, since in practice the max values are usually 16 to 20 + unless limiterGains == 3 (limiter off) and eCurr ~= 0 (i.e. huge gain, but only + because the envelope has 0 power anyway) + */ + q = MULSHIFT32(psi->gLimBuf[m], gBoost) << 2; /* Q(gLimFbits) * Q(28) --> Q(gLimFbits[m]-2) */ + r = SqrtFix(q, psi->gLimFbits[m] - 2, &z); + z -= FBITS_GLIM_BOOST; + if (z >= 0) { + psi->gLimBoost[m] = r >> MIN(z, 31); + } else { + z = MIN(30, -z); + CLIP_2N_SHIFT30(r, z); + psi->gLimBoost[m] = r; + } + + q = MULSHIFT32(psi->qmLimBuf[m], gBoost) << 2; /* Q(fbitsDQ) * Q(28) --> Q(fbitsDQ-2) */ + r = SqrtFix(q, fbitsDQ - 2, &z); + z -= FBITS_QLIM_BOOST; /* << by 14, since integer sqrt of x < 2^16, and we want to leave 1 GB */ + if (z >= 0) { + psi->qmLimBoost[m] = r >> MIN(31, z); + } else { + z = MIN(30, -z); + CLIP_2N_SHIFT30(r, z); + psi->qmLimBoost[m] = r; + } + + q = MULSHIFT32(psi->smBuf[m], gBoost) << 2; /* Q(fbitsDQ) * Q(28) --> Q(fbitsDQ-2) */ + r = SqrtFix(q, fbitsDQ - 2, &z); + z -= FBITS_OUT_QMFA; /* justify for adding to signal (xBuf) later */ + if (z >= 0) { + psi->smBoost[m] = r >> MIN(31, z); + } else { + z = MIN(30, -z); + CLIP_2N_SHIFT30(r, z); + psi->smBoost[m] = r; + } + } } /************************************************************************************** - * Function: CalcGain - * - * Description: calculate and apply proper gain to HF components in one envelope - * (4.6.18.7.5) - * - * Inputs: initialized PSInfoSBR struct - * initialized SBRHeader struct for this SCE/CPE block - * initialized SBRGrid struct for this channel - * initialized SBRFreq struct for this SCE/CPE block - * initialized SBRChan struct for this channel - * index of current channel (0 for SCE, 0 or 1 for CPE) - * index of current envelope - * - * Outputs: envelope gain, sinusoids and noise after scaling - * - * Return: none + Function: CalcGain + + Description: calculate and apply proper gain to HF components in one envelope + (4.6.18.7.5) + + Inputs: initialized PSInfoSBR struct + initialized SBRHeader struct for this SCE/CPE block + initialized SBRGrid struct for this channel + initialized SBRFreq struct for this SCE/CPE block + initialized SBRChan struct for this channel + index of current channel (0 for SCE, 0 or 1 for CPE) + index of current envelope + + Outputs: envelope gain, sinusoids and noise after scaling + + Return: none **************************************************************************************/ -static void CalcGain(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch, int env) -{ - int lim, fbitsDQ; - - /* initialize to -1 so that mapping limiter bands to env/noise bands works right on first pass */ - psi->envBand = -1; - psi->noiseFloorBand = -1; - psi->sBand = -1; - psi->highBand = -1; - - fbitsDQ = (FBITS_OUT_DQ_ENV - psi->envDataDequantScale[ch][env]); /* Q(29 - optional scalefactor) */ - for (lim = 0; lim < sbrFreq->nLimiter; lim++) { - /* the QMF bands are divided into lim regions (consecutive, non-overlapping) */ - CalcMaxGain(psi, sbrHdr, sbrGrid, sbrFreq, ch, env, lim, fbitsDQ); - CalcComponentGains(psi, sbrGrid, sbrFreq, sbrChan, ch, env, lim, fbitsDQ); - ApplyBoost(psi, sbrFreq, lim, fbitsDQ); - } +static void CalcGain(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch, int env) { + int lim, fbitsDQ; + + /* initialize to -1 so that mapping limiter bands to env/noise bands works right on first pass */ + psi->envBand = -1; + psi->noiseFloorBand = -1; + psi->sBand = -1; + psi->highBand = -1; + + fbitsDQ = (FBITS_OUT_DQ_ENV - psi->envDataDequantScale[ch][env]); /* Q(29 - optional scalefactor) */ + for (lim = 0; lim < sbrFreq->nLimiter; lim++) { + /* the QMF bands are divided into lim regions (consecutive, non-overlapping) */ + CalcMaxGain(psi, sbrHdr, sbrGrid, sbrFreq, ch, env, lim, fbitsDQ); + CalcComponentGains(psi, sbrGrid, sbrFreq, sbrChan, ch, env, lim, fbitsDQ); + ApplyBoost(psi, sbrFreq, lim, fbitsDQ); + } } /* hSmooth table from 4.7.18.7.6, format = Q31 */ static const int hSmoothCoef[MAX_NUM_SMOOTH_COEFS] PROGMEM = { - 0x2aaaaaab, 0x2697a512, 0x1becfa68, 0x0ebdb043, 0x04130598, + 0x2aaaaaab, 0x2697a512, 0x1becfa68, 0x0ebdb043, 0x04130598, }; /************************************************************************************** - * Function: MapHF - * - * Description: map HF components to proper QMF bands, with optional gain smoothing - * filter (4.6.18.7.6) - * - * Inputs: initialized PSInfoSBR struct - * initialized SBRHeader struct for this SCE/CPE block - * initialized SBRGrid struct for this channel - * initialized SBRFreq struct for this SCE/CPE block - * initialized SBRChan struct for this channel - * index of current envelope - * reset flag (can be non-zero for first envelope only) - * - * Outputs: complete reconstructed subband QMF samples for this envelope - * - * Return: none - * - * Notes: ensures that output has >= MIN_GBITS_IN_QMFS guard bits, - * so it's not necessary to check anything in the synth QMF + Function: MapHF + + Description: map HF components to proper QMF bands, with optional gain smoothing + filter (4.6.18.7.6) + + Inputs: initialized PSInfoSBR struct + initialized SBRHeader struct for this SCE/CPE block + initialized SBRGrid struct for this channel + initialized SBRFreq struct for this SCE/CPE block + initialized SBRChan struct for this channel + index of current envelope + reset flag (can be non-zero for first envelope only) + + Outputs: complete reconstructed subband QMF samples for this envelope + + Return: none + + Notes: ensures that output has >= MIN_GBITS_IN_QMFS guard bits, + so it's not necessary to check anything in the synth QMF **************************************************************************************/ -static void MapHF(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int env, int hfReset) -{ - int noiseTabIndex, sinIndex, gainNoiseIndex, hSL; - int i, iStart, iEnd, m, idx, j, s, n, smre, smim; - int gFilt, qFilt, xre, xim, gbMask, gbIdx; - int *XBuf; - - noiseTabIndex = sbrChan->noiseTabIndex; - sinIndex = sbrChan->sinIndex; - gainNoiseIndex = sbrChan->gainNoiseIndex; /* oldest entries in filter delay buffer */ - - if (hfReset) - noiseTabIndex = 2; /* starts at 1, double since complex */ - hSL = (sbrHdr->smoothMode ? 0 : 4); - - if (hfReset) { - for (i = 0; i < hSL; i++) { - for (m = 0; m < sbrFreq->numQMFBands; m++) { - sbrChan->gTemp[gainNoiseIndex][m] = psi->gLimBoost[m]; - sbrChan->qTemp[gainNoiseIndex][m] = psi->qmLimBoost[m]; - } - gainNoiseIndex++; - if (gainNoiseIndex == MAX_NUM_SMOOTH_COEFS) - gainNoiseIndex = 0; - } - ASSERT(env == 0); /* should only be reset when env == 0 */ - } - - iStart = sbrGrid->envTimeBorder[env]; - iEnd = sbrGrid->envTimeBorder[env+1]; - for (i = iStart; i < iEnd; i++) { - /* save new values in temp buffers (delay) - * we only store MAX_NUM_SMOOTH_COEFS most recent values, - * so don't keep storing the same value over and over - */ - if (i - iStart < MAX_NUM_SMOOTH_COEFS) { - for (m = 0; m < sbrFreq->numQMFBands; m++) { - sbrChan->gTemp[gainNoiseIndex][m] = psi->gLimBoost[m]; - sbrChan->qTemp[gainNoiseIndex][m] = psi->qmLimBoost[m]; - } - } - - /* see 4.6.18.7.6 */ - XBuf = psi->XBuf[i + HF_ADJ][sbrFreq->kStart]; - gbMask = 0; - for (m = 0; m < sbrFreq->numQMFBands; m++) { - if (env == psi->la || env == sbrChan->laPrev) { - /* no smoothing filter for gain, and qFilt = 0 (only need to do once) */ - if (i == iStart) { - psi->gFiltLast[m] = sbrChan->gTemp[gainNoiseIndex][m]; - psi->qFiltLast[m] = 0; - } - } else if (hSL == 0) { - /* no smoothing filter for gain, (only need to do once) */ - if (i == iStart) { - psi->gFiltLast[m] = sbrChan->gTemp[gainNoiseIndex][m]; - psi->qFiltLast[m] = sbrChan->qTemp[gainNoiseIndex][m]; - } - } else { - /* apply smoothing filter to gain and noise (after MAX_NUM_SMOOTH_COEFS, it's always the same) */ - if (i - iStart < MAX_NUM_SMOOTH_COEFS) { - gFilt = 0; - qFilt = 0; - idx = gainNoiseIndex; - for (j = 0; j < MAX_NUM_SMOOTH_COEFS; j++) { - /* sum(abs(hSmoothCoef[j])) for all j < 1.0 */ - gFilt += MULSHIFT32(sbrChan->gTemp[idx][m], hSmoothCoef[j]); - qFilt += MULSHIFT32(sbrChan->qTemp[idx][m], hSmoothCoef[j]); - idx--; - if (idx < 0) - idx += MAX_NUM_SMOOTH_COEFS; - } - psi->gFiltLast[m] = gFilt << 1; /* restore to Q(FBITS_GLIM_BOOST) (gain of filter < 1.0, so no overflow) */ - psi->qFiltLast[m] = qFilt << 1; /* restore to Q(FBITS_QLIM_BOOST) */ - } - } - - if (psi->smBoost[m] != 0) { - /* add scaled signal and sinusoid, don't add noise (qFilt = 0) */ - smre = psi->smBoost[m]; - smim = smre; - - /* sinIndex: [0] xre += sm [1] xim += sm*s [2] xre -= sm [3] xim -= sm*s */ - s = (sinIndex >> 1); /* if 2 or 3, flip sign to subtract sm */ - s <<= 31; - smre ^= (s >> 31); - smre -= (s >> 31); - s ^= ((m + sbrFreq->kStart) << 31); - smim ^= (s >> 31); - smim -= (s >> 31); - - /* if sinIndex == 0 or 2, smim = 0; if sinIndex == 1 or 3, smre = 0 */ - s = sinIndex << 31; - smim &= (s >> 31); - s ^= 0x80000000; - smre &= (s >> 31); - - noiseTabIndex += 2; /* noise filtered by 0, but still need to bump index */ - } else { - /* add scaled signal and scaled noise */ - qFilt = psi->qFiltLast[m]; - n = noiseTab[noiseTabIndex++]; - smre = MULSHIFT32(n, qFilt) >> (FBITS_QLIM_BOOST - 1 - FBITS_OUT_QMFA); - - n = noiseTab[noiseTabIndex++]; - smim = MULSHIFT32(n, qFilt) >> (FBITS_QLIM_BOOST - 1 - FBITS_OUT_QMFA); - } - noiseTabIndex &= 1023; /* 512 complex numbers */ - - gFilt = psi->gFiltLast[m]; - xre = MULSHIFT32(gFilt, XBuf[0]); - xim = MULSHIFT32(gFilt, XBuf[1]); - CLIP_2N_SHIFT30(xre, 32 - FBITS_GLIM_BOOST); - CLIP_2N_SHIFT30(xim, 32 - FBITS_GLIM_BOOST); - - xre += smre; *XBuf++ = xre; - xim += smim; *XBuf++ = xim; - - gbMask |= FASTABS(xre); - gbMask |= FASTABS(xim); - } - /* update circular buffer index */ - gainNoiseIndex++; - if (gainNoiseIndex == MAX_NUM_SMOOTH_COEFS) - gainNoiseIndex = 0; - - sinIndex++; - sinIndex &= 3; - - /* ensure MIN_GBITS_IN_QMFS guard bits in output - * almost never occurs in practice, but checking here makes synth QMF logic very simple - */ - if (gbMask >> (31 - MIN_GBITS_IN_QMFS)) { - XBuf = psi->XBuf[i + HF_ADJ][sbrFreq->kStart]; - for (m = 0; m < sbrFreq->numQMFBands; m++) { - xre = XBuf[0]; xim = XBuf[1]; - CLIP_2N(xre, (31 - MIN_GBITS_IN_QMFS)); - CLIP_2N(xim, (31 - MIN_GBITS_IN_QMFS)); - *XBuf++ = xre; *XBuf++ = xim; - } - CLIP_2N(gbMask, (31 - MIN_GBITS_IN_QMFS)); - } - gbIdx = ((i + HF_ADJ) >> 5) & 0x01; - sbrChan->gbMask[gbIdx] |= gbMask; - } - sbrChan->noiseTabIndex = noiseTabIndex; - sbrChan->sinIndex = sinIndex; - sbrChan->gainNoiseIndex = gainNoiseIndex; +static void MapHF(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int env, int hfReset) { + int noiseTabIndex, sinIndex, gainNoiseIndex, hSL; + int i, iStart, iEnd, m, idx, j, s, n, smre, smim; + int gFilt, qFilt, xre, xim, gbMask, gbIdx; + int *XBuf; + + noiseTabIndex = sbrChan->noiseTabIndex; + sinIndex = sbrChan->sinIndex; + gainNoiseIndex = sbrChan->gainNoiseIndex; /* oldest entries in filter delay buffer */ + + if (hfReset) { + noiseTabIndex = 2; /* starts at 1, double since complex */ + } + hSL = (sbrHdr->smoothMode ? 0 : 4); + + if (hfReset) { + for (i = 0; i < hSL; i++) { + for (m = 0; m < sbrFreq->numQMFBands; m++) { + sbrChan->gTemp[gainNoiseIndex][m] = psi->gLimBoost[m]; + sbrChan->qTemp[gainNoiseIndex][m] = psi->qmLimBoost[m]; + } + gainNoiseIndex++; + if (gainNoiseIndex == MAX_NUM_SMOOTH_COEFS) { + gainNoiseIndex = 0; + } + } + ASSERT(env == 0); /* should only be reset when env == 0 */ + } + + iStart = sbrGrid->envTimeBorder[env]; + iEnd = sbrGrid->envTimeBorder[env + 1]; + for (i = iStart; i < iEnd; i++) { + /* save new values in temp buffers (delay) + we only store MAX_NUM_SMOOTH_COEFS most recent values, + so don't keep storing the same value over and over + */ + if (i - iStart < MAX_NUM_SMOOTH_COEFS) { + for (m = 0; m < sbrFreq->numQMFBands; m++) { + sbrChan->gTemp[gainNoiseIndex][m] = psi->gLimBoost[m]; + sbrChan->qTemp[gainNoiseIndex][m] = psi->qmLimBoost[m]; + } + } + + /* see 4.6.18.7.6 */ + XBuf = psi->XBuf[i + HF_ADJ][sbrFreq->kStart]; + gbMask = 0; + for (m = 0; m < sbrFreq->numQMFBands; m++) { + if (env == psi->la || env == sbrChan->laPrev) { + /* no smoothing filter for gain, and qFilt = 0 (only need to do once) */ + if (i == iStart) { + psi->gFiltLast[m] = sbrChan->gTemp[gainNoiseIndex][m]; + psi->qFiltLast[m] = 0; + } + } else if (hSL == 0) { + /* no smoothing filter for gain, (only need to do once) */ + if (i == iStart) { + psi->gFiltLast[m] = sbrChan->gTemp[gainNoiseIndex][m]; + psi->qFiltLast[m] = sbrChan->qTemp[gainNoiseIndex][m]; + } + } else { + /* apply smoothing filter to gain and noise (after MAX_NUM_SMOOTH_COEFS, it's always the same) */ + if (i - iStart < MAX_NUM_SMOOTH_COEFS) { + gFilt = 0; + qFilt = 0; + idx = gainNoiseIndex; + for (j = 0; j < MAX_NUM_SMOOTH_COEFS; j++) { + /* sum(abs(hSmoothCoef[j])) for all j < 1.0 */ + gFilt += MULSHIFT32(sbrChan->gTemp[idx][m], hSmoothCoef[j]); + qFilt += MULSHIFT32(sbrChan->qTemp[idx][m], hSmoothCoef[j]); + idx--; + if (idx < 0) { + idx += MAX_NUM_SMOOTH_COEFS; + } + } + psi->gFiltLast[m] = gFilt << 1; /* restore to Q(FBITS_GLIM_BOOST) (gain of filter < 1.0, so no overflow) */ + psi->qFiltLast[m] = qFilt << 1; /* restore to Q(FBITS_QLIM_BOOST) */ + } + } + + if (psi->smBoost[m] != 0) { + /* add scaled signal and sinusoid, don't add noise (qFilt = 0) */ + smre = psi->smBoost[m]; + smim = smre; + + /* sinIndex: [0] xre += sm [1] xim += sm*s [2] xre -= sm [3] xim -= sm*s */ + s = (sinIndex >> 1); /* if 2 or 3, flip sign to subtract sm */ + s <<= 31; + smre ^= (s >> 31); + smre -= (s >> 31); + s ^= ((m + sbrFreq->kStart) << 31); + smim ^= (s >> 31); + smim -= (s >> 31); + + /* if sinIndex == 0 or 2, smim = 0; if sinIndex == 1 or 3, smre = 0 */ + s = sinIndex << 31; + smim &= (s >> 31); + s ^= 0x80000000; + smre &= (s >> 31); + + noiseTabIndex += 2; /* noise filtered by 0, but still need to bump index */ + } else { + /* add scaled signal and scaled noise */ + qFilt = psi->qFiltLast[m]; + n = noiseTab[noiseTabIndex++]; + smre = MULSHIFT32(n, qFilt) >> (FBITS_QLIM_BOOST - 1 - FBITS_OUT_QMFA); + + n = noiseTab[noiseTabIndex++]; + smim = MULSHIFT32(n, qFilt) >> (FBITS_QLIM_BOOST - 1 - FBITS_OUT_QMFA); + } + noiseTabIndex &= 1023; /* 512 complex numbers */ + + gFilt = psi->gFiltLast[m]; + xre = MULSHIFT32(gFilt, XBuf[0]); + xim = MULSHIFT32(gFilt, XBuf[1]); + CLIP_2N_SHIFT30(xre, 32 - FBITS_GLIM_BOOST); + CLIP_2N_SHIFT30(xim, 32 - FBITS_GLIM_BOOST); + + xre += smre; *XBuf++ = xre; + xim += smim; *XBuf++ = xim; + + gbMask |= FASTABS(xre); + gbMask |= FASTABS(xim); + } + /* update circular buffer index */ + gainNoiseIndex++; + if (gainNoiseIndex == MAX_NUM_SMOOTH_COEFS) { + gainNoiseIndex = 0; + } + + sinIndex++; + sinIndex &= 3; + + /* ensure MIN_GBITS_IN_QMFS guard bits in output + almost never occurs in practice, but checking here makes synth QMF logic very simple + */ + if (gbMask >> (31 - MIN_GBITS_IN_QMFS)) { + XBuf = psi->XBuf[i + HF_ADJ][sbrFreq->kStart]; + for (m = 0; m < sbrFreq->numQMFBands; m++) { + xre = XBuf[0]; xim = XBuf[1]; + CLIP_2N(xre, (31 - MIN_GBITS_IN_QMFS)); + CLIP_2N(xim, (31 - MIN_GBITS_IN_QMFS)); + *XBuf++ = xre; *XBuf++ = xim; + } + CLIP_2N(gbMask, (31 - MIN_GBITS_IN_QMFS)); + } + gbIdx = ((i + HF_ADJ) >> 5) & 0x01; + sbrChan->gbMask[gbIdx] |= gbMask; + } + sbrChan->noiseTabIndex = noiseTabIndex; + sbrChan->sinIndex = sinIndex; + sbrChan->gainNoiseIndex = gainNoiseIndex; } /************************************************************************************** - * Function: AdjustHighFreq - * - * Description: adjust high frequencies and add noise and sinusoids (4.6.18.7) - * - * Inputs: initialized PSInfoSBR struct - * initialized SBRHeader struct for this SCE/CPE block - * initialized SBRGrid struct for this channel - * initialized SBRFreq struct for this SCE/CPE block - * initialized SBRChan struct for this channel - * index of current channel (0 for SCE, 0 or 1 for CPE) - * - * Outputs: complete reconstructed subband QMF samples for this channel - * - * Return: none + Function: AdjustHighFreq + + Description: adjust high frequencies and add noise and sinusoids (4.6.18.7) + + Inputs: initialized PSInfoSBR struct + initialized SBRHeader struct for this SCE/CPE block + initialized SBRGrid struct for this channel + initialized SBRFreq struct for this SCE/CPE block + initialized SBRChan struct for this channel + index of current channel (0 for SCE, 0 or 1 for CPE) + + Outputs: complete reconstructed subband QMF samples for this channel + + Return: none **************************************************************************************/ -void AdjustHighFreq(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch) -{ - int i, env, hfReset; - unsigned char frameClass, pointer; - - frameClass = sbrGrid->frameClass; - pointer = sbrGrid->pointer; - - /* derive la from table 4.159 */ - if ((frameClass == SBR_GRID_FIXVAR || frameClass == SBR_GRID_VARVAR) && pointer > 0) - psi->la = sbrGrid->numEnv + 1 - pointer; - else if (frameClass == SBR_GRID_VARFIX && pointer > 1) - psi->la = pointer - 1; - else - psi->la = -1; - - /* for each envelope, estimate gain and adjust SBR QMF bands */ - hfReset = sbrChan->reset; - for (env = 0; env < sbrGrid->numEnv; env++) { - EstimateEnvelope(psi, sbrHdr, sbrGrid, sbrFreq, env); - CalcGain(psi, sbrHdr, sbrGrid, sbrFreq, sbrChan, ch, env); - MapHF(psi, sbrHdr, sbrGrid, sbrFreq, sbrChan, env, hfReset); - hfReset = 0; /* only set for first envelope after header reset */ - } - - /* set saved sine flags to 0 for QMF bands outside of current frequency range */ - for (i = 0; i < sbrFreq->freqLimiter[0] + sbrFreq->kStart; i++) - sbrChan->addHarmonic[0][i] = 0; - for (i = sbrFreq->freqLimiter[sbrFreq->nLimiter] + sbrFreq->kStart; i < 64; i++) - sbrChan->addHarmonic[0][i] = 0; - sbrChan->addHarmonicFlag[0] = sbrChan->addHarmonicFlag[1]; - - /* save la for next frame */ - if (psi->la == sbrGrid->numEnv) - sbrChan->laPrev = 0; - else - sbrChan->laPrev = -1; +void AdjustHighFreq(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch) { + int i, env, hfReset; + unsigned char frameClass, pointer; + + frameClass = sbrGrid->frameClass; + pointer = sbrGrid->pointer; + + /* derive la from table 4.159 */ + if ((frameClass == SBR_GRID_FIXVAR || frameClass == SBR_GRID_VARVAR) && pointer > 0) { + psi->la = sbrGrid->numEnv + 1 - pointer; + } else if (frameClass == SBR_GRID_VARFIX && pointer > 1) { + psi->la = pointer - 1; + } else { + psi->la = -1; + } + + /* for each envelope, estimate gain and adjust SBR QMF bands */ + hfReset = sbrChan->reset; + for (env = 0; env < sbrGrid->numEnv; env++) { + EstimateEnvelope(psi, sbrHdr, sbrGrid, sbrFreq, env); + CalcGain(psi, sbrHdr, sbrGrid, sbrFreq, sbrChan, ch, env); + MapHF(psi, sbrHdr, sbrGrid, sbrFreq, sbrChan, env, hfReset); + hfReset = 0; /* only set for first envelope after header reset */ + } + + /* set saved sine flags to 0 for QMF bands outside of current frequency range */ + for (i = 0; i < sbrFreq->freqLimiter[0] + sbrFreq->kStart; i++) { + sbrChan->addHarmonic[0][i] = 0; + } + for (i = sbrFreq->freqLimiter[sbrFreq->nLimiter] + sbrFreq->kStart; i < 64; i++) { + sbrChan->addHarmonic[0][i] = 0; + } + sbrChan->addHarmonicFlag[0] = sbrChan->addHarmonicFlag[1]; + + /* save la for next frame */ + if (psi->la == sbrGrid->numEnv) { + sbrChan->laPrev = 0; + } else { + sbrChan->laPrev = -1; + } } diff --git a/src/libhelix-aac/sbrhfgen.c b/src/libhelix-aac/sbrhfgen.c index 7ebc047a..360ac317 100644 --- a/src/libhelix-aac/sbrhfgen.c +++ b/src/libhelix-aac/sbrhfgen.c @@ -1,46 +1,46 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: sbrhfgen.c,v 1.2 2005/05/19 20:45:20 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: sbrhfgen.c,v 1.2 2005/05/19 20:45:20 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * sbrhfgen.c - high frequency generation for SBR + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + sbrhfgen.c - high frequency generation for SBR **************************************************************************************/ #include "sbr.h" @@ -50,567 +50,564 @@ #define MAG_16 (16 * (1 << (32 - (2*(32-FBITS_LPCOEFS))))) /* i.e. 16 in Q26 format */ #define RELAX_COEF 0x7ffff79c /* 1.0 / (1.0 + 1e-6), Q31 */ -/* newBWTab[prev invfMode][curr invfMode], format = Q31 (table 4.158) - * sample file which uses all of these: al_sbr_sr_64_2_fsaac32.aac - */ +/* newBWTab[prev invfMode][curr invfMode], format = Q31 (table 4.158) + sample file which uses all of these: al_sbr_sr_64_2_fsaac32.aac +*/ static const int newBWTab[4][4] PROGMEM = { - {0x00000000, 0x4ccccccd, 0x73333333, 0x7d70a3d7}, - {0x4ccccccd, 0x60000000, 0x73333333, 0x7d70a3d7}, - {0x00000000, 0x60000000, 0x73333333, 0x7d70a3d7}, - {0x00000000, 0x60000000, 0x73333333, 0x7d70a3d7}, + {0x00000000, 0x4ccccccd, 0x73333333, 0x7d70a3d7}, + {0x4ccccccd, 0x60000000, 0x73333333, 0x7d70a3d7}, + {0x00000000, 0x60000000, 0x73333333, 0x7d70a3d7}, + {0x00000000, 0x60000000, 0x73333333, 0x7d70a3d7}, }; /************************************************************************************** - * Function: CVKernel1 - * - * Description: kernel of covariance matrix calculation for p01, p11, p12, p22 - * - * Inputs: buffer of low-freq samples, starting at time index = 0, - * freq index = patch subband - * - * Outputs: 64-bit accumulators for p01re, p01im, p12re, p12im, p11re, p22re - * stored in accBuf - * - * Return: none - * - * Notes: this is carefully written to be efficient on ARM - * use the assembly code version in sbrcov.s when building for ARM! + Function: CVKernel1 + + Description: kernel of covariance matrix calculation for p01, p11, p12, p22 + + Inputs: buffer of low-freq samples, starting at time index = 0, + freq index = patch subband + + Outputs: 64-bit accumulators for p01re, p01im, p12re, p12im, p11re, p22re + stored in accBuf + + Return: none + + Notes: this is carefully written to be efficient on ARM + use the assembly code version in sbrcov.s when building for ARM! **************************************************************************************/ -#if (defined (__arm) && defined (__ARMCC_VERSION)) || (defined (_WIN32) && defined (_WIN32_WCE) && defined (ARM)) || (defined(__GNUC__) && defined(__arm__)) +#if (defined (XXXX__arm) && defined (__ARMCC_VERSION)) || (defined (_WIN32) && defined (_WIN32_WCE) && defined (ARM)) || (defined(__GNUC__) && defined(XXXX__arm__)) #ifdef __cplusplus extern "C" #endif void CVKernel1(int *XBuf, int *accBuf); #else -void CVKernel1(int *XBuf, int *accBuf) -{ - U64 p01re, p01im, p12re, p12im, p11re, p22re; - int n, x0re, x0im, x1re, x1im; - - x0re = XBuf[0]; - x0im = XBuf[1]; - XBuf += (2*64); - x1re = XBuf[0]; - x1im = XBuf[1]; - XBuf += (2*64); - - p01re.w64 = p01im.w64 = 0; - p12re.w64 = p12im.w64 = 0; - p11re.w64 = 0; - p22re.w64 = 0; - - p12re.w64 = MADD64(p12re.w64, x1re, x0re); - p12re.w64 = MADD64(p12re.w64, x1im, x0im); - p12im.w64 = MADD64(p12im.w64, x0re, x1im); - p12im.w64 = MADD64(p12im.w64, -x0im, x1re); - p22re.w64 = MADD64(p22re.w64, x0re, x0re); - p22re.w64 = MADD64(p22re.w64, x0im, x0im); - for (n = (NUM_TIME_SLOTS*SAMPLES_PER_SLOT + 6); n != 0; n--) { - /* 4 input, 3*2 acc, 1 ptr, 1 loop counter = 12 registers (use same for x0im, -x0im) */ - x0re = x1re; - x0im = x1im; - x1re = XBuf[0]; - x1im = XBuf[1]; - - p01re.w64 = MADD64(p01re.w64, x1re, x0re); - p01re.w64 = MADD64(p01re.w64, x1im, x0im); - p01im.w64 = MADD64(p01im.w64, x0re, x1im); - p01im.w64 = MADD64(p01im.w64, -x0im, x1re); - p11re.w64 = MADD64(p11re.w64, x0re, x0re); - p11re.w64 = MADD64(p11re.w64, x0im, x0im); - - XBuf += (2*64); - } - /* these can be derived by slight changes to account for boundary conditions */ - p12re.w64 += p01re.w64; - p12re.w64 = MADD64(p12re.w64, x1re, -x0re); - p12re.w64 = MADD64(p12re.w64, x1im, -x0im); - p12im.w64 += p01im.w64; - p12im.w64 = MADD64(p12im.w64, x0re, -x1im); - p12im.w64 = MADD64(p12im.w64, x0im, x1re); - p22re.w64 += p11re.w64; - p22re.w64 = MADD64(p22re.w64, x0re, -x0re); - p22re.w64 = MADD64(p22re.w64, x0im, -x0im); - - accBuf[0] = p01re.r.lo32; accBuf[1] = p01re.r.hi32; - accBuf[2] = p01im.r.lo32; accBuf[3] = p01im.r.hi32; - accBuf[4] = p11re.r.lo32; accBuf[5] = p11re.r.hi32; - accBuf[6] = p12re.r.lo32; accBuf[7] = p12re.r.hi32; - accBuf[8] = p12im.r.lo32; accBuf[9] = p12im.r.hi32; - accBuf[10] = p22re.r.lo32; accBuf[11] = p22re.r.hi32; +void CVKernel1(int *XBuf, int *accBuf) { + U64 p01re, p01im, p12re, p12im, p11re, p22re; + int n, x0re, x0im, x1re, x1im; + + x0re = XBuf[0]; + x0im = XBuf[1]; + XBuf += (2 * 64); + x1re = XBuf[0]; + x1im = XBuf[1]; + XBuf += (2 * 64); + + p01re.w64 = p01im.w64 = 0; + p12re.w64 = p12im.w64 = 0; + p11re.w64 = 0; + p22re.w64 = 0; + + p12re.w64 = MADD64(p12re.w64, x1re, x0re); + p12re.w64 = MADD64(p12re.w64, x1im, x0im); + p12im.w64 = MADD64(p12im.w64, x0re, x1im); + p12im.w64 = MADD64(p12im.w64, -x0im, x1re); + p22re.w64 = MADD64(p22re.w64, x0re, x0re); + p22re.w64 = MADD64(p22re.w64, x0im, x0im); + for (n = (NUM_TIME_SLOTS * SAMPLES_PER_SLOT + 6); n != 0; n--) { + /* 4 input, 3*2 acc, 1 ptr, 1 loop counter = 12 registers (use same for x0im, -x0im) */ + x0re = x1re; + x0im = x1im; + x1re = XBuf[0]; + x1im = XBuf[1]; + + p01re.w64 = MADD64(p01re.w64, x1re, x0re); + p01re.w64 = MADD64(p01re.w64, x1im, x0im); + p01im.w64 = MADD64(p01im.w64, x0re, x1im); + p01im.w64 = MADD64(p01im.w64, -x0im, x1re); + p11re.w64 = MADD64(p11re.w64, x0re, x0re); + p11re.w64 = MADD64(p11re.w64, x0im, x0im); + + XBuf += (2 * 64); + } + /* these can be derived by slight changes to account for boundary conditions */ + p12re.w64 += p01re.w64; + p12re.w64 = MADD64(p12re.w64, x1re, -x0re); + p12re.w64 = MADD64(p12re.w64, x1im, -x0im); + p12im.w64 += p01im.w64; + p12im.w64 = MADD64(p12im.w64, x0re, -x1im); + p12im.w64 = MADD64(p12im.w64, x0im, x1re); + p22re.w64 += p11re.w64; + p22re.w64 = MADD64(p22re.w64, x0re, -x0re); + p22re.w64 = MADD64(p22re.w64, x0im, -x0im); + + accBuf[0] = p01re.r.lo32; accBuf[1] = p01re.r.hi32; + accBuf[2] = p01im.r.lo32; accBuf[3] = p01im.r.hi32; + accBuf[4] = p11re.r.lo32; accBuf[5] = p11re.r.hi32; + accBuf[6] = p12re.r.lo32; accBuf[7] = p12re.r.hi32; + accBuf[8] = p12im.r.lo32; accBuf[9] = p12im.r.hi32; + accBuf[10] = p22re.r.lo32; accBuf[11] = p22re.r.hi32; } #endif /************************************************************************************** - * Function: CalcCovariance1 - * - * Description: calculate covariance matrix for p01, p12, p11, p22 (4.6.18.6.2) - * - * Inputs: buffer of low-freq samples, starting at time index 0, - * freq index = patch subband - * - * Outputs: complex covariance elements p01re, p01im, p12re, p12im, p11re, p22re - * (p11im = p22im = 0) - * format = integer (Q0) * 2^N, with scalefactor N >= 0 - * - * Return: scalefactor N - * - * Notes: outputs are normalized to have 1 GB (sign in at least top 2 bits) + Function: CalcCovariance1 + + Description: calculate covariance matrix for p01, p12, p11, p22 (4.6.18.6.2) + + Inputs: buffer of low-freq samples, starting at time index 0, + freq index = patch subband + + Outputs: complex covariance elements p01re, p01im, p12re, p12im, p11re, p22re + (p11im = p22im = 0) + format = integer (Q0) * 2^N, with scalefactor N >= 0 + + Return: scalefactor N + + Notes: outputs are normalized to have 1 GB (sign in at least top 2 bits) **************************************************************************************/ -static int CalcCovariance1(int *XBuf, int *p01reN, int *p01imN, int *p12reN, int *p12imN, int *p11reN, int *p22reN) -{ - int accBuf[2*6]; - int n, z, s, loShift, hiShift, gbMask; - U64 p01re, p01im, p12re, p12im, p11re, p22re; - - CVKernel1(XBuf, accBuf); - p01re.r.lo32 = accBuf[0]; p01re.r.hi32 = accBuf[1]; - p01im.r.lo32 = accBuf[2]; p01im.r.hi32 = accBuf[3]; - p11re.r.lo32 = accBuf[4]; p11re.r.hi32 = accBuf[5]; - p12re.r.lo32 = accBuf[6]; p12re.r.hi32 = accBuf[7]; - p12im.r.lo32 = accBuf[8]; p12im.r.hi32 = accBuf[9]; - p22re.r.lo32 = accBuf[10]; p22re.r.hi32 = accBuf[11]; - - /* 64-bit accumulators now have 2*FBITS_OUT_QMFA fraction bits - * want to scale them down to integers (32-bit signed, Q0) - * with scale factor of 2^n, n >= 0 - * leave 2 GB's for calculating determinant, so take top 30 non-zero bits - */ - gbMask = ((p01re.r.hi32) ^ (p01re.r.hi32 >> 31)) | ((p01im.r.hi32) ^ (p01im.r.hi32 >> 31)); - gbMask |= ((p12re.r.hi32) ^ (p12re.r.hi32 >> 31)) | ((p12im.r.hi32) ^ (p12im.r.hi32 >> 31)); - gbMask |= ((p11re.r.hi32) ^ (p11re.r.hi32 >> 31)) | ((p22re.r.hi32) ^ (p22re.r.hi32 >> 31)); - if (gbMask == 0) { - s = p01re.r.hi32 >> 31; gbMask = (p01re.r.lo32 ^ s) - s; - s = p01im.r.hi32 >> 31; gbMask |= (p01im.r.lo32 ^ s) - s; - s = p12re.r.hi32 >> 31; gbMask |= (p12re.r.lo32 ^ s) - s; - s = p12im.r.hi32 >> 31; gbMask |= (p12im.r.lo32 ^ s) - s; - s = p11re.r.hi32 >> 31; gbMask |= (p11re.r.lo32 ^ s) - s; - s = p22re.r.hi32 >> 31; gbMask |= (p22re.r.lo32 ^ s) - s; - z = 32 + CLZ(gbMask); - } else { - gbMask = FASTABS(p01re.r.hi32) | FASTABS(p01im.r.hi32); - gbMask |= FASTABS(p12re.r.hi32) | FASTABS(p12im.r.hi32); - gbMask |= FASTABS(p11re.r.hi32) | FASTABS(p22re.r.hi32); - z = CLZ(gbMask); - } - - n = 64 - z; /* number of non-zero bits in bottom of 64-bit word */ - if (n <= 30) { - loShift = (30 - n); - *p01reN = p01re.r.lo32 << loShift; *p01imN = p01im.r.lo32 << loShift; - *p12reN = p12re.r.lo32 << loShift; *p12imN = p12im.r.lo32 << loShift; - *p11reN = p11re.r.lo32 << loShift; *p22reN = p22re.r.lo32 << loShift; - return -(loShift + 2*FBITS_OUT_QMFA); - } else if (n < 32 + 30) { - loShift = (n - 30); - hiShift = 32 - loShift; - *p01reN = (p01re.r.hi32 << hiShift) | (p01re.r.lo32 >> loShift); - *p01imN = (p01im.r.hi32 << hiShift) | (p01im.r.lo32 >> loShift); - *p12reN = (p12re.r.hi32 << hiShift) | (p12re.r.lo32 >> loShift); - *p12imN = (p12im.r.hi32 << hiShift) | (p12im.r.lo32 >> loShift); - *p11reN = (p11re.r.hi32 << hiShift) | (p11re.r.lo32 >> loShift); - *p22reN = (p22re.r.hi32 << hiShift) | (p22re.r.lo32 >> loShift); - return (loShift - 2*FBITS_OUT_QMFA); - } else { - hiShift = n - (32 + 30); - *p01reN = p01re.r.hi32 >> hiShift; *p01imN = p01im.r.hi32 >> hiShift; - *p12reN = p12re.r.hi32 >> hiShift; *p12imN = p12im.r.hi32 >> hiShift; - *p11reN = p11re.r.hi32 >> hiShift; *p22reN = p22re.r.hi32 >> hiShift; - return (32 - 2*FBITS_OUT_QMFA - hiShift); - } - - return 0; +static int CalcCovariance1(int *XBuf, int *p01reN, int *p01imN, int *p12reN, int *p12imN, int *p11reN, int *p22reN) { + int accBuf[2 * 6]; + int n, z, s, loShift, hiShift, gbMask; + U64 p01re, p01im, p12re, p12im, p11re, p22re; + + CVKernel1(XBuf, accBuf); + p01re.r.lo32 = accBuf[0]; p01re.r.hi32 = accBuf[1]; + p01im.r.lo32 = accBuf[2]; p01im.r.hi32 = accBuf[3]; + p11re.r.lo32 = accBuf[4]; p11re.r.hi32 = accBuf[5]; + p12re.r.lo32 = accBuf[6]; p12re.r.hi32 = accBuf[7]; + p12im.r.lo32 = accBuf[8]; p12im.r.hi32 = accBuf[9]; + p22re.r.lo32 = accBuf[10]; p22re.r.hi32 = accBuf[11]; + + /* 64-bit accumulators now have 2*FBITS_OUT_QMFA fraction bits + want to scale them down to integers (32-bit signed, Q0) + with scale factor of 2^n, n >= 0 + leave 2 GB's for calculating determinant, so take top 30 non-zero bits + */ + gbMask = ((p01re.r.hi32) ^ (p01re.r.hi32 >> 31)) | ((p01im.r.hi32) ^ (p01im.r.hi32 >> 31)); + gbMask |= ((p12re.r.hi32) ^ (p12re.r.hi32 >> 31)) | ((p12im.r.hi32) ^ (p12im.r.hi32 >> 31)); + gbMask |= ((p11re.r.hi32) ^ (p11re.r.hi32 >> 31)) | ((p22re.r.hi32) ^ (p22re.r.hi32 >> 31)); + if (gbMask == 0) { + s = p01re.r.hi32 >> 31; gbMask = (p01re.r.lo32 ^ s) - s; + s = p01im.r.hi32 >> 31; gbMask |= (p01im.r.lo32 ^ s) - s; + s = p12re.r.hi32 >> 31; gbMask |= (p12re.r.lo32 ^ s) - s; + s = p12im.r.hi32 >> 31; gbMask |= (p12im.r.lo32 ^ s) - s; + s = p11re.r.hi32 >> 31; gbMask |= (p11re.r.lo32 ^ s) - s; + s = p22re.r.hi32 >> 31; gbMask |= (p22re.r.lo32 ^ s) - s; + z = 32 + CLZ(gbMask); + } else { + gbMask = FASTABS(p01re.r.hi32) | FASTABS(p01im.r.hi32); + gbMask |= FASTABS(p12re.r.hi32) | FASTABS(p12im.r.hi32); + gbMask |= FASTABS(p11re.r.hi32) | FASTABS(p22re.r.hi32); + z = CLZ(gbMask); + } + + n = 64 - z; /* number of non-zero bits in bottom of 64-bit word */ + if (n <= 30) { + loShift = (30 - n); + *p01reN = p01re.r.lo32 << loShift; *p01imN = p01im.r.lo32 << loShift; + *p12reN = p12re.r.lo32 << loShift; *p12imN = p12im.r.lo32 << loShift; + *p11reN = p11re.r.lo32 << loShift; *p22reN = p22re.r.lo32 << loShift; + return -(loShift + 2 * FBITS_OUT_QMFA); + } else if (n < 32 + 30) { + loShift = (n - 30); + hiShift = 32 - loShift; + *p01reN = (p01re.r.hi32 << hiShift) | (p01re.r.lo32 >> loShift); + *p01imN = (p01im.r.hi32 << hiShift) | (p01im.r.lo32 >> loShift); + *p12reN = (p12re.r.hi32 << hiShift) | (p12re.r.lo32 >> loShift); + *p12imN = (p12im.r.hi32 << hiShift) | (p12im.r.lo32 >> loShift); + *p11reN = (p11re.r.hi32 << hiShift) | (p11re.r.lo32 >> loShift); + *p22reN = (p22re.r.hi32 << hiShift) | (p22re.r.lo32 >> loShift); + return (loShift - 2 * FBITS_OUT_QMFA); + } else { + hiShift = n - (32 + 30); + *p01reN = p01re.r.hi32 >> hiShift; *p01imN = p01im.r.hi32 >> hiShift; + *p12reN = p12re.r.hi32 >> hiShift; *p12imN = p12im.r.hi32 >> hiShift; + *p11reN = p11re.r.hi32 >> hiShift; *p22reN = p22re.r.hi32 >> hiShift; + return (32 - 2 * FBITS_OUT_QMFA - hiShift); + } + + return 0; } /************************************************************************************** - * Function: CVKernel2 - * - * Description: kernel of covariance matrix calculation for p02 - * - * Inputs: buffer of low-freq samples, starting at time index = 0, - * freq index = patch subband - * - * Outputs: 64-bit accumulators for p02re, p02im stored in accBuf - * - * Return: none - * - * Notes: this is carefully written to be efficient on ARM - * use the assembly code version in sbrcov.s when building for ARM! + Function: CVKernel2 + + Description: kernel of covariance matrix calculation for p02 + + Inputs: buffer of low-freq samples, starting at time index = 0, + freq index = patch subband + + Outputs: 64-bit accumulators for p02re, p02im stored in accBuf + + Return: none + + Notes: this is carefully written to be efficient on ARM + use the assembly code version in sbrcov.s when building for ARM! **************************************************************************************/ -#if (defined (__arm) && defined (__ARMCC_VERSION)) || (defined (_WIN32) && defined (_WIN32_WCE) && defined (ARM)) || (defined(__GNUC__) && defined(__arm__)) +#if (defined (XXXX__arm) && defined (__ARMCC_VERSION)) || (defined (_WIN32) && defined (_WIN32_WCE) && defined (ARM)) || (defined(__GNUC__) && defined(XXXX__arm__)) #ifdef __cplusplus extern "C" #endif void CVKernel2(int *XBuf, int *accBuf); #else -void CVKernel2(int *XBuf, int *accBuf) -{ - U64 p02re, p02im; - int n, x0re, x0im, x1re, x1im, x2re, x2im; - - p02re.w64 = p02im.w64 = 0; - - x0re = XBuf[0]; - x0im = XBuf[1]; - XBuf += (2*64); - x1re = XBuf[0]; - x1im = XBuf[1]; - XBuf += (2*64); - - for (n = (NUM_TIME_SLOTS*SAMPLES_PER_SLOT + 6); n != 0; n--) { - /* 6 input, 2*2 acc, 1 ptr, 1 loop counter = 12 registers (use same for x0im, -x0im) */ - x2re = XBuf[0]; - x2im = XBuf[1]; - - p02re.w64 = MADD64(p02re.w64, x2re, x0re); - p02re.w64 = MADD64(p02re.w64, x2im, x0im); - p02im.w64 = MADD64(p02im.w64, x0re, x2im); - p02im.w64 = MADD64(p02im.w64, -x0im, x2re); - - x0re = x1re; - x0im = x1im; - x1re = x2re; - x1im = x2im; - XBuf += (2*64); - } - - accBuf[0] = p02re.r.lo32; - accBuf[1] = p02re.r.hi32; - accBuf[2] = p02im.r.lo32; - accBuf[3] = p02im.r.hi32; +void CVKernel2(int *XBuf, int *accBuf) { + U64 p02re, p02im; + int n, x0re, x0im, x1re, x1im, x2re, x2im; + + p02re.w64 = p02im.w64 = 0; + + x0re = XBuf[0]; + x0im = XBuf[1]; + XBuf += (2 * 64); + x1re = XBuf[0]; + x1im = XBuf[1]; + XBuf += (2 * 64); + + for (n = (NUM_TIME_SLOTS * SAMPLES_PER_SLOT + 6); n != 0; n--) { + /* 6 input, 2*2 acc, 1 ptr, 1 loop counter = 12 registers (use same for x0im, -x0im) */ + x2re = XBuf[0]; + x2im = XBuf[1]; + + p02re.w64 = MADD64(p02re.w64, x2re, x0re); + p02re.w64 = MADD64(p02re.w64, x2im, x0im); + p02im.w64 = MADD64(p02im.w64, x0re, x2im); + p02im.w64 = MADD64(p02im.w64, -x0im, x2re); + + x0re = x1re; + x0im = x1im; + x1re = x2re; + x1im = x2im; + XBuf += (2 * 64); + } + + accBuf[0] = p02re.r.lo32; + accBuf[1] = p02re.r.hi32; + accBuf[2] = p02im.r.lo32; + accBuf[3] = p02im.r.hi32; } #endif /************************************************************************************** - * Function: CalcCovariance2 - * - * Description: calculate covariance matrix for p02 (4.6.18.6.2) - * - * Inputs: buffer of low-freq samples, starting at time index = 0, - * freq index = patch subband - * - * Outputs: complex covariance element p02re, p02im - * format = integer (Q0) * 2^N, with scalefactor N >= 0 - * - * Return: scalefactor N - * - * Notes: outputs are normalized to have 1 GB (sign in at least top 2 bits) + Function: CalcCovariance2 + + Description: calculate covariance matrix for p02 (4.6.18.6.2) + + Inputs: buffer of low-freq samples, starting at time index = 0, + freq index = patch subband + + Outputs: complex covariance element p02re, p02im + format = integer (Q0) * 2^N, with scalefactor N >= 0 + + Return: scalefactor N + + Notes: outputs are normalized to have 1 GB (sign in at least top 2 bits) **************************************************************************************/ -static int CalcCovariance2(int *XBuf, int *p02reN, int *p02imN) -{ - U64 p02re, p02im; - int n, z, s, loShift, hiShift, gbMask; - int accBuf[2*2]; - - CVKernel2(XBuf, accBuf); - p02re.r.lo32 = accBuf[0]; - p02re.r.hi32 = accBuf[1]; - p02im.r.lo32 = accBuf[2]; - p02im.r.hi32 = accBuf[3]; - - /* 64-bit accumulators now have 2*FBITS_OUT_QMFA fraction bits - * want to scale them down to integers (32-bit signed, Q0) - * with scale factor of 2^n, n >= 0 - * leave 1 GB for calculating determinant, so take top 30 non-zero bits - */ - gbMask = ((p02re.r.hi32) ^ (p02re.r.hi32 >> 31)) | ((p02im.r.hi32) ^ (p02im.r.hi32 >> 31)); - if (gbMask == 0) { - s = p02re.r.hi32 >> 31; gbMask = (p02re.r.lo32 ^ s) - s; - s = p02im.r.hi32 >> 31; gbMask |= (p02im.r.lo32 ^ s) - s; - z = 32 + CLZ(gbMask); - } else { - gbMask = FASTABS(p02re.r.hi32) | FASTABS(p02im.r.hi32); - z = CLZ(gbMask); - } - n = 64 - z; /* number of non-zero bits in bottom of 64-bit word */ - - if (n <= 30) { - loShift = (30 - n); - *p02reN = p02re.r.lo32 << loShift; - *p02imN = p02im.r.lo32 << loShift; - return -(loShift + 2*FBITS_OUT_QMFA); - } else if (n < 32 + 30) { - loShift = (n - 30); - hiShift = 32 - loShift; - *p02reN = (p02re.r.hi32 << hiShift) | (p02re.r.lo32 >> loShift); - *p02imN = (p02im.r.hi32 << hiShift) | (p02im.r.lo32 >> loShift); - return (loShift - 2*FBITS_OUT_QMFA); - } else { - hiShift = n - (32 + 30); - *p02reN = p02re.r.hi32 >> hiShift; - *p02imN = p02im.r.hi32 >> hiShift; - return (32 - 2*FBITS_OUT_QMFA - hiShift); - } - - return 0; +static int CalcCovariance2(int *XBuf, int *p02reN, int *p02imN) { + U64 p02re, p02im; + int n, z, s, loShift, hiShift, gbMask; + int accBuf[2 * 2]; + + CVKernel2(XBuf, accBuf); + p02re.r.lo32 = accBuf[0]; + p02re.r.hi32 = accBuf[1]; + p02im.r.lo32 = accBuf[2]; + p02im.r.hi32 = accBuf[3]; + + /* 64-bit accumulators now have 2*FBITS_OUT_QMFA fraction bits + want to scale them down to integers (32-bit signed, Q0) + with scale factor of 2^n, n >= 0 + leave 1 GB for calculating determinant, so take top 30 non-zero bits + */ + gbMask = ((p02re.r.hi32) ^ (p02re.r.hi32 >> 31)) | ((p02im.r.hi32) ^ (p02im.r.hi32 >> 31)); + if (gbMask == 0) { + s = p02re.r.hi32 >> 31; gbMask = (p02re.r.lo32 ^ s) - s; + s = p02im.r.hi32 >> 31; gbMask |= (p02im.r.lo32 ^ s) - s; + z = 32 + CLZ(gbMask); + } else { + gbMask = FASTABS(p02re.r.hi32) | FASTABS(p02im.r.hi32); + z = CLZ(gbMask); + } + n = 64 - z; /* number of non-zero bits in bottom of 64-bit word */ + + if (n <= 30) { + loShift = (30 - n); + *p02reN = p02re.r.lo32 << loShift; + *p02imN = p02im.r.lo32 << loShift; + return -(loShift + 2 * FBITS_OUT_QMFA); + } else if (n < 32 + 30) { + loShift = (n - 30); + hiShift = 32 - loShift; + *p02reN = (p02re.r.hi32 << hiShift) | (p02re.r.lo32 >> loShift); + *p02imN = (p02im.r.hi32 << hiShift) | (p02im.r.lo32 >> loShift); + return (loShift - 2 * FBITS_OUT_QMFA); + } else { + hiShift = n - (32 + 30); + *p02reN = p02re.r.hi32 >> hiShift; + *p02imN = p02im.r.hi32 >> hiShift; + return (32 - 2 * FBITS_OUT_QMFA - hiShift); + } + + return 0; } /************************************************************************************** - * Function: CalcLPCoefs - * - * Description: calculate linear prediction coefficients for one subband (4.6.18.6.2) - * - * Inputs: buffer of low-freq samples, starting at time index = 0, - * freq index = patch subband - * number of guard bits in input sample buffer - * - * Outputs: complex LP coefficients a0re, a0im, a1re, a1im, format = Q29 - * - * Return: none - * - * Notes: output coefficients (a0re, a0im, a1re, a1im) clipped to range (-4, 4) - * if the comples coefficients have magnitude >= 4.0, they are all - * set to 0 (see spec) + Function: CalcLPCoefs + + Description: calculate linear prediction coefficients for one subband (4.6.18.6.2) + + Inputs: buffer of low-freq samples, starting at time index = 0, + freq index = patch subband + number of guard bits in input sample buffer + + Outputs: complex LP coefficients a0re, a0im, a1re, a1im, format = Q29 + + Return: none + + Notes: output coefficients (a0re, a0im, a1re, a1im) clipped to range (-4, 4) + if the comples coefficients have magnitude >= 4.0, they are all + set to 0 (see spec) **************************************************************************************/ -static void CalcLPCoefs(int *XBuf, int *a0re, int *a0im, int *a1re, int *a1im, int gb) -{ - int zFlag, n1, n2, nd, d, dInv, tre, tim; - int p01re, p01im, p02re, p02im, p12re, p12im, p11re, p22re; - - /* pre-scale to avoid overflow - probably never happens in practice (see QMFA) - * max bit growth per accumulator = 38*2 = 76 mul-adds (X * X) - * using 64-bit MADD, so if X has n guard bits, X*X has 2n+1 guard bits - * gain 1 extra sign bit per multiply, so ensure ceil(log2(76/2) / 2) = 3 guard bits on inputs - */ - if (gb < 3) { - nd = 3 - gb; - for (n1 = (NUM_TIME_SLOTS*SAMPLES_PER_SLOT + 6 + 2); n1 != 0; n1--) { - XBuf[0] >>= nd; XBuf[1] >>= nd; - XBuf += (2*64); - } - XBuf -= (2*64*(NUM_TIME_SLOTS*SAMPLES_PER_SLOT + 6 + 2)); - } - - /* calculate covariance elements */ - n1 = CalcCovariance1(XBuf, &p01re, &p01im, &p12re, &p12im, &p11re, &p22re); - n2 = CalcCovariance2(XBuf, &p02re, &p02im); - - /* normalize everything to larger power of 2 scalefactor, call it n1 */ - if (n1 < n2) { - nd = MIN(n2 - n1, 31); - p01re >>= nd; p01im >>= nd; - p12re >>= nd; p12im >>= nd; - p11re >>= nd; p22re >>= nd; - n1 = n2; - } else if (n1 > n2) { - nd = MIN(n1 - n2, 31); - p02re >>= nd; p02im >>= nd; - } - - /* calculate determinant of covariance matrix (at least 1 GB in pXX) */ - d = MULSHIFT32(p12re, p12re) + MULSHIFT32(p12im, p12im); - d = MULSHIFT32(d, RELAX_COEF) << 1; - d = MULSHIFT32(p11re, p22re) - d; - ASSERT(d >= 0); /* should never be < 0 */ - - zFlag = 0; - *a0re = *a0im = 0; - *a1re = *a1im = 0; - if (d > 0) { - /* input = Q31 d = Q(-2*n1 - 32 + nd) = Q31 * 2^(31 + 2*n1 + 32 - nd) - * inverse = Q29 dInv = Q29 * 2^(-31 - 2*n1 - 32 + nd) = Q(29 + 31 + 2*n1 + 32 - nd) - * - * numerator has same Q format as d, since it's sum of normalized squares - * so num * inverse = Q(-2*n1 - 32) * Q(29 + 31 + 2*n1 + 32 - nd) - * = Q(29 + 31 - nd), drop low 32 in MULSHIFT32 - * = Q(29 + 31 - 32 - nd) = Q(28 - nd) - */ - nd = CLZ(d) - 1; - d <<= nd; - dInv = InvRNormalized(d); - - /* 1 GB in pXX */ - tre = MULSHIFT32(p01re, p12re) - MULSHIFT32(p01im, p12im) - MULSHIFT32(p02re, p11re); - tre = MULSHIFT32(tre, dInv); - tim = MULSHIFT32(p01re, p12im) + MULSHIFT32(p01im, p12re) - MULSHIFT32(p02im, p11re); - tim = MULSHIFT32(tim, dInv); - - /* if d is extremely small, just set coefs to 0 (would have poor precision anyway) */ - if (nd > 28 || (FASTABS(tre) >> (28 - nd)) >= 4 || (FASTABS(tim) >> (28 - nd)) >= 4) { - zFlag = 1; - } else { - *a1re = tre << (FBITS_LPCOEFS - 28 + nd); /* i.e. convert Q(28 - nd) to Q(29) */ - *a1im = tim << (FBITS_LPCOEFS - 28 + nd); - } - } - - if (p11re) { - /* input = Q31 p11re = Q(-n1 + nd) = Q31 * 2^(31 + n1 - nd) - * inverse = Q29 dInv = Q29 * 2^(-31 - n1 + nd) = Q(29 + 31 + n1 - nd) - * - * numerator is Q(-n1 - 3) - * so num * inverse = Q(-n1 - 3) * Q(29 + 31 + n1 - nd) - * = Q(29 + 31 - 3 - nd), drop low 32 in MULSHIFT32 - * = Q(29 + 31 - 3 - 32 - nd) = Q(25 - nd) - */ - nd = CLZ(p11re) - 1; /* assume positive */ - p11re <<= nd; - dInv = InvRNormalized(p11re); - - /* a1re, a1im = Q29, so scaled by (n1 + 3) */ - tre = (p01re >> 3) + MULSHIFT32(p12re, *a1re) + MULSHIFT32(p12im, *a1im); - tre = -MULSHIFT32(tre, dInv); - tim = (p01im >> 3) - MULSHIFT32(p12im, *a1re) + MULSHIFT32(p12re, *a1im); - tim = -MULSHIFT32(tim, dInv); - - if (nd > 25 || (FASTABS(tre) >> (25 - nd)) >= 4 || (FASTABS(tim) >> (25 - nd)) >= 4) { - zFlag = 1; - } else { - *a0re = tre << (FBITS_LPCOEFS - 25 + nd); /* i.e. convert Q(25 - nd) to Q(29) */ - *a0im = tim << (FBITS_LPCOEFS - 25 + nd); - } - } - - /* see 4.6.18.6.2 - if magnitude of a0 or a1 >= 4 then a0 = a1 = 0 - * i.e. a0re < 4, a0im < 4, a1re < 4, a1im < 4 - * Q29*Q29 = Q26 - */ - if (zFlag || MULSHIFT32(*a0re, *a0re) + MULSHIFT32(*a0im, *a0im) >= MAG_16 || MULSHIFT32(*a1re, *a1re) + MULSHIFT32(*a1im, *a1im) >= MAG_16) { - *a0re = *a0im = 0; - *a1re = *a1im = 0; - } - - /* no need to clip - we never changed the XBuf data, just used it to calculate a0 and a1 */ - if (gb < 3) { - nd = 3 - gb; - for (n1 = (NUM_TIME_SLOTS*SAMPLES_PER_SLOT + 6 + 2); n1 != 0; n1--) { - XBuf[0] <<= nd; XBuf[1] <<= nd; - XBuf += (2*64); - } - } +static void CalcLPCoefs(int *XBuf, int *a0re, int *a0im, int *a1re, int *a1im, int gb) { + int zFlag, n1, n2, nd, d, dInv, tre, tim; + int p01re, p01im, p02re, p02im, p12re, p12im, p11re, p22re; + + /* pre-scale to avoid overflow - probably never happens in practice (see QMFA) + max bit growth per accumulator = 38*2 = 76 mul-adds (X * X) + using 64-bit MADD, so if X has n guard bits, X*X has 2n+1 guard bits + gain 1 extra sign bit per multiply, so ensure ceil(log2(76/2) / 2) = 3 guard bits on inputs + */ + if (gb < 3) { + nd = 3 - gb; + for (n1 = (NUM_TIME_SLOTS * SAMPLES_PER_SLOT + 6 + 2); n1 != 0; n1--) { + XBuf[0] >>= nd; XBuf[1] >>= nd; + XBuf += (2 * 64); + } + XBuf -= (2 * 64 * (NUM_TIME_SLOTS * SAMPLES_PER_SLOT + 6 + 2)); + } + + /* calculate covariance elements */ + n1 = CalcCovariance1(XBuf, &p01re, &p01im, &p12re, &p12im, &p11re, &p22re); + n2 = CalcCovariance2(XBuf, &p02re, &p02im); + + /* normalize everything to larger power of 2 scalefactor, call it n1 */ + if (n1 < n2) { + nd = MIN(n2 - n1, 31); + p01re >>= nd; p01im >>= nd; + p12re >>= nd; p12im >>= nd; + p11re >>= nd; p22re >>= nd; + n1 = n2; + } else if (n1 > n2) { + nd = MIN(n1 - n2, 31); + p02re >>= nd; p02im >>= nd; + } + + /* calculate determinant of covariance matrix (at least 1 GB in pXX) */ + d = MULSHIFT32(p12re, p12re) + MULSHIFT32(p12im, p12im); + d = MULSHIFT32(d, RELAX_COEF) << 1; + d = MULSHIFT32(p11re, p22re) - d; + ASSERT(d >= 0); /* should never be < 0 */ + + zFlag = 0; + *a0re = *a0im = 0; + *a1re = *a1im = 0; + if (d > 0) { + /* input = Q31 d = Q(-2*n1 - 32 + nd) = Q31 * 2^(31 + 2*n1 + 32 - nd) + inverse = Q29 dInv = Q29 * 2^(-31 - 2*n1 - 32 + nd) = Q(29 + 31 + 2*n1 + 32 - nd) + + numerator has same Q format as d, since it's sum of normalized squares + so num * inverse = Q(-2*n1 - 32) * Q(29 + 31 + 2*n1 + 32 - nd) + = Q(29 + 31 - nd), drop low 32 in MULSHIFT32 + = Q(29 + 31 - 32 - nd) = Q(28 - nd) + */ + nd = CLZ(d) - 1; + d <<= nd; + dInv = InvRNormalized(d); + + /* 1 GB in pXX */ + tre = MULSHIFT32(p01re, p12re) - MULSHIFT32(p01im, p12im) - MULSHIFT32(p02re, p11re); + tre = MULSHIFT32(tre, dInv); + tim = MULSHIFT32(p01re, p12im) + MULSHIFT32(p01im, p12re) - MULSHIFT32(p02im, p11re); + tim = MULSHIFT32(tim, dInv); + + /* if d is extremely small, just set coefs to 0 (would have poor precision anyway) */ + if (nd > 28 || (FASTABS(tre) >> (28 - nd)) >= 4 || (FASTABS(tim) >> (28 - nd)) >= 4) { + zFlag = 1; + } else { + *a1re = tre << (FBITS_LPCOEFS - 28 + nd); /* i.e. convert Q(28 - nd) to Q(29) */ + *a1im = tim << (FBITS_LPCOEFS - 28 + nd); + } + } + + if (p11re) { + /* input = Q31 p11re = Q(-n1 + nd) = Q31 * 2^(31 + n1 - nd) + inverse = Q29 dInv = Q29 * 2^(-31 - n1 + nd) = Q(29 + 31 + n1 - nd) + + numerator is Q(-n1 - 3) + so num * inverse = Q(-n1 - 3) * Q(29 + 31 + n1 - nd) + = Q(29 + 31 - 3 - nd), drop low 32 in MULSHIFT32 + = Q(29 + 31 - 3 - 32 - nd) = Q(25 - nd) + */ + nd = CLZ(p11re) - 1; /* assume positive */ + p11re <<= nd; + dInv = InvRNormalized(p11re); + + /* a1re, a1im = Q29, so scaled by (n1 + 3) */ + tre = (p01re >> 3) + MULSHIFT32(p12re, *a1re) + MULSHIFT32(p12im, *a1im); + tre = -MULSHIFT32(tre, dInv); + tim = (p01im >> 3) - MULSHIFT32(p12im, *a1re) + MULSHIFT32(p12re, *a1im); + tim = -MULSHIFT32(tim, dInv); + + if (nd > 25 || (FASTABS(tre) >> (25 - nd)) >= 4 || (FASTABS(tim) >> (25 - nd)) >= 4) { + zFlag = 1; + } else { + *a0re = tre << (FBITS_LPCOEFS - 25 + nd); /* i.e. convert Q(25 - nd) to Q(29) */ + *a0im = tim << (FBITS_LPCOEFS - 25 + nd); + } + } + + /* see 4.6.18.6.2 - if magnitude of a0 or a1 >= 4 then a0 = a1 = 0 + i.e. a0re < 4, a0im < 4, a1re < 4, a1im < 4 + Q29*Q29 = Q26 + */ + if (zFlag || MULSHIFT32(*a0re, *a0re) + MULSHIFT32(*a0im, *a0im) >= MAG_16 || MULSHIFT32(*a1re, *a1re) + MULSHIFT32(*a1im, *a1im) >= MAG_16) { + *a0re = *a0im = 0; + *a1re = *a1im = 0; + } + + /* no need to clip - we never changed the XBuf data, just used it to calculate a0 and a1 */ + if (gb < 3) { + nd = 3 - gb; + for (n1 = (NUM_TIME_SLOTS * SAMPLES_PER_SLOT + 6 + 2); n1 != 0; n1--) { + XBuf[0] <<= nd; XBuf[1] <<= nd; + XBuf += (2 * 64); + } + } } /************************************************************************************** - * Function: GenerateHighFreq - * - * Description: generate high frequencies with SBR (4.6.18.6) - * - * Inputs: initialized PSInfoSBR struct - * initialized SBRGrid struct for this channel - * initialized SBRFreq struct for this SCE/CPE block - * initialized SBRChan struct for this channel - * index of current channel (0 for SCE, 0 or 1 for CPE) - * - * Outputs: new high frequency samples starting at frequency kStart - * - * Return: none + Function: GenerateHighFreq + + Description: generate high frequencies with SBR (4.6.18.6) + + Inputs: initialized PSInfoSBR struct + initialized SBRGrid struct for this channel + initialized SBRFreq struct for this SCE/CPE block + initialized SBRChan struct for this channel + index of current channel (0 for SCE, 0 or 1 for CPE) + + Outputs: new high frequency samples starting at frequency kStart + + Return: none **************************************************************************************/ -void GenerateHighFreq(PSInfoSBR *psi, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch) -{ - int band, newBW, c, t, gb, gbMask, gbIdx; - int currPatch, p, x, k, g, i, iStart, iEnd, bw, bwsq; - int a0re, a0im, a1re, a1im; - int x1re, x1im, x2re, x2im; - int ACCre, ACCim; - int *XBufLo, *XBufHi; - (void) ch; - - /* calculate array of chirp factors */ - for (band = 0; band < sbrFreq->numNoiseFloorBands; band++) { - c = sbrChan->chirpFact[band]; /* previous (bwArray') */ - newBW = newBWTab[sbrChan->invfMode[0][band]][sbrChan->invfMode[1][band]]; - - /* weighted average of new and old (can't overflow - total gain = 1.0) */ - if (newBW < c) - t = MULSHIFT32(newBW, 0x60000000) + MULSHIFT32(0x20000000, c); /* new is smaller: 0.75*new + 0.25*old */ - else - t = MULSHIFT32(newBW, 0x74000000) + MULSHIFT32(0x0c000000, c); /* new is larger: 0.90625*new + 0.09375*old */ - t <<= 1; - - if (t < 0x02000000) /* below 0.015625, clip to 0 */ - t = 0; - if (t > 0x7f800000) /* clip to 0.99609375 */ - t = 0x7f800000; - - /* save curr as prev for next time */ - sbrChan->chirpFact[band] = t; - sbrChan->invfMode[0][band] = sbrChan->invfMode[1][band]; - } - - iStart = sbrGrid->envTimeBorder[0] + HF_ADJ; - iEnd = sbrGrid->envTimeBorder[sbrGrid->numEnv] + HF_ADJ; - - /* generate new high freqs from low freqs, patches, and chirp factors */ - k = sbrFreq->kStart; - g = 0; - bw = sbrChan->chirpFact[g]; - bwsq = MULSHIFT32(bw, bw) << 1; - - gbMask = (sbrChan->gbMask[0] | sbrChan->gbMask[1]); /* older 32 | newer 8 */ - gb = CLZ(gbMask) - 1; - - for (currPatch = 0; currPatch < sbrFreq->numPatches; currPatch++) { - for (x = 0; x < sbrFreq->patchNumSubbands[currPatch]; x++) { - /* map k to corresponding noise floor band */ - if (k >= sbrFreq->freqNoise[g+1]) { - g++; - bw = sbrChan->chirpFact[g]; /* Q31 */ - bwsq = MULSHIFT32(bw, bw) << 1; /* Q31 */ - } - - p = sbrFreq->patchStartSubband[currPatch] + x; /* low QMF band */ - XBufHi = psi->XBuf[iStart][k]; - if (bw) { - CalcLPCoefs(psi->XBuf[0][p], &a0re, &a0im, &a1re, &a1im, gb); - - a0re = MULSHIFT32(bw, a0re); /* Q31 * Q29 = Q28 */ - a0im = MULSHIFT32(bw, a0im); - a1re = MULSHIFT32(bwsq, a1re); - a1im = MULSHIFT32(bwsq, a1im); - - XBufLo = psi->XBuf[iStart-2][p]; - - x2re = XBufLo[0]; /* RE{XBuf[n-2]} */ - x2im = XBufLo[1]; /* IM{XBuf[n-2]} */ - XBufLo += (64*2); - - x1re = XBufLo[0]; /* RE{XBuf[n-1]} */ - x1im = XBufLo[1]; /* IM{XBuf[n-1]} */ - XBufLo += (64*2); - - for (i = iStart; i < iEnd; i++) { - /* a0re/im, a1re/im are Q28 with at least 1 GB, - * so the summing for AACre/im is fine (1 GB in, plus 1 from MULSHIFT32) - */ - ACCre = MULSHIFT32(x2re, a1re) - MULSHIFT32(x2im, a1im); - ACCim = MULSHIFT32(x2re, a1im) + MULSHIFT32(x2im, a1re); - x2re = x1re; - x2im = x1im; - - ACCre += MULSHIFT32(x1re, a0re) - MULSHIFT32(x1im, a0im); - ACCim += MULSHIFT32(x1re, a0im) + MULSHIFT32(x1im, a0re); - x1re = XBufLo[0]; /* RE{XBuf[n]} */ - x1im = XBufLo[1]; /* IM{XBuf[n]} */ - XBufLo += (64*2); - - /* lost 4 fbits when scaling by a0re/im, a1re/im (Q28) */ - CLIP_2N_SHIFT30(ACCre, 4); - ACCre += x1re; - CLIP_2N_SHIFT30(ACCim, 4); - ACCim += x1im; - - XBufHi[0] = ACCre; - XBufHi[1] = ACCim; - XBufHi += (64*2); - - /* update guard bit masks */ - gbMask = FASTABS(ACCre); - gbMask |= FASTABS(ACCim); - gbIdx = (i >> 5) & 0x01; /* 0 if i < 32, 1 if i >= 32 */ - sbrChan->gbMask[gbIdx] |= gbMask; - } - } else { - XBufLo = (int *)psi->XBuf[iStart][p]; - for (i = iStart; i < iEnd; i++) { - XBufHi[0] = XBufLo[0]; - XBufHi[1] = XBufLo[1]; - XBufLo += (64*2); - XBufHi += (64*2); - } - } - k++; /* high QMF band */ - } - } +void GenerateHighFreq(PSInfoSBR *psi, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch) { + int band, newBW, c, t, gb, gbMask, gbIdx; + int currPatch, p, x, k, g, i, iStart, iEnd, bw, bwsq; + int a0re, a0im, a1re, a1im; + int x1re, x1im, x2re, x2im; + int ACCre, ACCim; + int *XBufLo, *XBufHi; + (void) ch; + + /* calculate array of chirp factors */ + for (band = 0; band < sbrFreq->numNoiseFloorBands; band++) { + c = sbrChan->chirpFact[band]; /* previous (bwArray') */ + newBW = newBWTab[sbrChan->invfMode[0][band]][sbrChan->invfMode[1][band]]; + + /* weighted average of new and old (can't overflow - total gain = 1.0) */ + if (newBW < c) { + t = MULSHIFT32(newBW, 0x60000000) + MULSHIFT32(0x20000000, c); /* new is smaller: 0.75*new + 0.25*old */ + } else { + t = MULSHIFT32(newBW, 0x74000000) + MULSHIFT32(0x0c000000, c); /* new is larger: 0.90625*new + 0.09375*old */ + } + t <<= 1; + + if (t < 0x02000000) { /* below 0.015625, clip to 0 */ + t = 0; + } + if (t > 0x7f800000) { /* clip to 0.99609375 */ + t = 0x7f800000; + } + + /* save curr as prev for next time */ + sbrChan->chirpFact[band] = t; + sbrChan->invfMode[0][band] = sbrChan->invfMode[1][band]; + } + + iStart = sbrGrid->envTimeBorder[0] + HF_ADJ; + iEnd = sbrGrid->envTimeBorder[sbrGrid->numEnv] + HF_ADJ; + + /* generate new high freqs from low freqs, patches, and chirp factors */ + k = sbrFreq->kStart; + g = 0; + bw = sbrChan->chirpFact[g]; + bwsq = MULSHIFT32(bw, bw) << 1; + + gbMask = (sbrChan->gbMask[0] | sbrChan->gbMask[1]); /* older 32 | newer 8 */ + gb = CLZ(gbMask) - 1; + + for (currPatch = 0; currPatch < sbrFreq->numPatches; currPatch++) { + for (x = 0; x < sbrFreq->patchNumSubbands[currPatch]; x++) { + /* map k to corresponding noise floor band */ + if (k >= sbrFreq->freqNoise[g + 1]) { + g++; + bw = sbrChan->chirpFact[g]; /* Q31 */ + bwsq = MULSHIFT32(bw, bw) << 1; /* Q31 */ + } + + p = sbrFreq->patchStartSubband[currPatch] + x; /* low QMF band */ + XBufHi = psi->XBuf[iStart][k]; + if (bw) { + CalcLPCoefs(psi->XBuf[0][p], &a0re, &a0im, &a1re, &a1im, gb); + + a0re = MULSHIFT32(bw, a0re); /* Q31 * Q29 = Q28 */ + a0im = MULSHIFT32(bw, a0im); + a1re = MULSHIFT32(bwsq, a1re); + a1im = MULSHIFT32(bwsq, a1im); + + XBufLo = psi->XBuf[iStart - 2][p]; + + x2re = XBufLo[0]; /* RE{XBuf[n-2]} */ + x2im = XBufLo[1]; /* IM{XBuf[n-2]} */ + XBufLo += (64 * 2); + + x1re = XBufLo[0]; /* RE{XBuf[n-1]} */ + x1im = XBufLo[1]; /* IM{XBuf[n-1]} */ + XBufLo += (64 * 2); + + for (i = iStart; i < iEnd; i++) { + /* a0re/im, a1re/im are Q28 with at least 1 GB, + so the summing for AACre/im is fine (1 GB in, plus 1 from MULSHIFT32) + */ + ACCre = MULSHIFT32(x2re, a1re) - MULSHIFT32(x2im, a1im); + ACCim = MULSHIFT32(x2re, a1im) + MULSHIFT32(x2im, a1re); + x2re = x1re; + x2im = x1im; + + ACCre += MULSHIFT32(x1re, a0re) - MULSHIFT32(x1im, a0im); + ACCim += MULSHIFT32(x1re, a0im) + MULSHIFT32(x1im, a0re); + x1re = XBufLo[0]; /* RE{XBuf[n]} */ + x1im = XBufLo[1]; /* IM{XBuf[n]} */ + XBufLo += (64 * 2); + + /* lost 4 fbits when scaling by a0re/im, a1re/im (Q28) */ + CLIP_2N_SHIFT30(ACCre, 4); + ACCre += x1re; + CLIP_2N_SHIFT30(ACCim, 4); + ACCim += x1im; + + XBufHi[0] = ACCre; + XBufHi[1] = ACCim; + XBufHi += (64 * 2); + + /* update guard bit masks */ + gbMask = FASTABS(ACCre); + gbMask |= FASTABS(ACCim); + gbIdx = (i >> 5) & 0x01; /* 0 if i < 32, 1 if i >= 32 */ + sbrChan->gbMask[gbIdx] |= gbMask; + } + } else { + XBufLo = (int *)psi->XBuf[iStart][p]; + for (i = iStart; i < iEnd; i++) { + XBufHi[0] = XBufLo[0]; + XBufHi[1] = XBufLo[1]; + XBufLo += (64 * 2); + XBufHi += (64 * 2); + } + } + k++; /* high QMF band */ + } + } } diff --git a/src/libhelix-aac/sbrhuff.c b/src/libhelix-aac/sbrhuff.c index a174e1e8..8e4a5eb4 100644 --- a/src/libhelix-aac/sbrhuff.c +++ b/src/libhelix-aac/sbrhuff.c @@ -1,476 +1,494 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: sbrhuff.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +#pragma GCC optimize ("O3") +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: sbrhuff.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * sbrhuff.c - functions for unpacking Huffman-coded envelope and noise data + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + sbrhuff.c - functions for unpacking Huffman-coded envelope and noise data **************************************************************************************/ #include "sbr.h" #include "assembly.h" /************************************************************************************** - * Function: DecodeHuffmanScalar - * - * Description: decode one Huffman symbol from bitstream - * - * Inputs: pointers to Huffman table and info struct - * left-aligned bit buffer with >= huffTabInfo->maxBits bits - * - * Outputs: decoded symbol in *val - * - * Return: number of bits in symbol - * - * Notes: assumes canonical Huffman codes: - * first CW always 0, we have "count" CW's of length "nBits" bits - * starting CW for codes of length nBits+1 = - * (startCW[nBits] + count[nBits]) << 1 - * if there are no codes at nBits, then we just keep << 1 each time - * (since count[nBits] = 0) + Function: DecodeHuffmanScalar + + Description: decode one Huffman symbol from bitstream + + Inputs: pointers to Huffman table and info struct + left-aligned bit buffer with >= huffTabInfo->maxBits bits + + Outputs: decoded symbol in *val + + Return: number of bits in symbol + + Notes: assumes canonical Huffman codes: + first CW always 0, we have "count" CW's of length "nBits" bits + starting CW for codes of length nBits+1 = + (startCW[nBits] + count[nBits]) << 1 + if there are no codes at nBits, then we just keep << 1 each time + (since count[nBits] = 0) **************************************************************************************/ -static int DecodeHuffmanScalar(const signed /*short*/ int *huffTab, const HuffInfo *huffTabInfo, unsigned int bitBuf, signed int *val) -{ +#ifdef ESP8266 +static int DecodeHuffmanScalar(const signed /*short*/ int *huffTab, const HuffInfo *huffTabInfo, unsigned int bitBuf, signed int *val) { +#else +static int DecodeHuffmanScalar(const signed short int *huffTab, const HuffInfo *huffTabInfo, unsigned int bitBuf, signed int *val) { +#endif unsigned int count, start, shift, t; - const unsigned int /*char*/ *countPtr; - const signed int /*short*/ *map; - - map = huffTab + huffTabInfo->offset; - countPtr = huffTabInfo->count; - - start = 0; - count = 0; - shift = 32; - do { - start += count; - start <<= 1; - map += count; - count = *countPtr++; - shift--; - t = (bitBuf >> shift) - start; - } while (t >= count); - - *val = (signed int)map[t]; - return (countPtr - huffTabInfo->count); +#ifdef ESP8266 + const unsigned int /*char*/ *countPtr; + const signed int /*short*/ *map; +#else + const unsigned char *countPtr; + const signed short *map; +#endif + + map = huffTab + huffTabInfo->offset; + countPtr = huffTabInfo->count; + + start = 0; + count = 0; + shift = 32; + do { + start += count; + start <<= 1; + map += count; + count = *countPtr++; + shift--; + t = (bitBuf >> shift) - start; + } while (t >= count); + + *val = (signed int)map[t]; + return (countPtr - huffTabInfo->count); } /************************************************************************************** - * Function: DecodeOneSymbol - * - * Description: dequantize one Huffman symbol from bitstream, - * using table huffTabSBR[huffTabIndex] - * - * Inputs: BitStreamInfo struct pointing to start of next Huffman codeword - * index of Huffman table - * - * Outputs: bitstream advanced by number of bits in codeword - * - * Return: one decoded symbol + Function: DecodeOneSymbol + + Description: dequantize one Huffman symbol from bitstream, + using table huffTabSBR[huffTabIndex] + + Inputs: BitStreamInfo struct pointing to start of next Huffman codeword + index of Huffman table + + Outputs: bitstream advanced by number of bits in codeword + + Return: one decoded symbol **************************************************************************************/ -static int DecodeOneSymbol(BitStreamInfo *bsi, int huffTabIndex) -{ - int nBits, val; - unsigned int bitBuf; - const HuffInfo *hi; - - hi = &(huffTabSBRInfo[huffTabIndex]); - - bitBuf = GetBitsNoAdvance(bsi, hi->maxBits) << (32 - hi->maxBits); - nBits = DecodeHuffmanScalar(huffTabSBR, hi, bitBuf, &val); - AdvanceBitstream(bsi, nBits); - - return val; +static int DecodeOneSymbol(BitStreamInfo *bsi, int huffTabIndex) { + int nBits, val; + unsigned int bitBuf; + const HuffInfo *hi; + + hi = &(huffTabSBRInfo[huffTabIndex]); + + bitBuf = GetBitsNoAdvance(bsi, hi->maxBits) << (32 - hi->maxBits); + nBits = DecodeHuffmanScalar(huffTabSBR, hi, bitBuf, &val); + AdvanceBitstream(bsi, nBits); + + return val; } /* [1.0, sqrt(2)], format = Q29 (one guard bit for decoupling) */ static const int envDQTab[2] PROGMEM = {0x20000000, 0x2d413ccc}; /************************************************************************************** - * Function: DequantizeEnvelope - * - * Description: dequantize envelope scalefactors - * - * Inputs: number of scalefactors to process - * amplitude resolution flag for this frame (0 or 1) - * quantized envelope scalefactors - * - * Outputs: dequantized envelope scalefactors - * - * Return: extra int bits in output (6 + expMax) - * in other words, output format = Q(FBITS_OUT_DQ_ENV - (6 + expMax)) - * - * Notes: dequantized scalefactors have at least 2 GB + Function: DequantizeEnvelope + + Description: dequantize envelope scalefactors + + Inputs: number of scalefactors to process + amplitude resolution flag for this frame (0 or 1) + quantized envelope scalefactors + + Outputs: dequantized envelope scalefactors + + Return: extra int bits in output (6 + expMax) + in other words, output format = Q(FBITS_OUT_DQ_ENV - (6 + expMax)) + + Notes: dequantized scalefactors have at least 2 GB **************************************************************************************/ -static int DequantizeEnvelope(int nBands, int ampRes, signed char *envQuant, int *envDequant) -{ - int exp, expMax, i, scalei; - - if (nBands <= 0) - return 0; - - /* scan for largest dequant value (do separately from envelope decoding to keep code cleaner) */ - expMax = 0; - for (i = 0; i < nBands; i++) { - if (envQuant[i] > expMax) - expMax = envQuant[i]; - } - - /* dequantized envelope gains - * envDequant = 64*2^(envQuant / alpha) = 2^(6 + envQuant / alpha) - * if ampRes == 0, alpha = 2 and range of envQuant = [0, 127] - * if ampRes == 1, alpha = 1 and range of envQuant = [0, 63] - * also if coupling is on, envDequant is scaled by something in range [0, 2] - * so range of envDequant = [2^6, 2^69] (no coupling), [2^6, 2^70] (with coupling) - * - * typical range (from observation) of envQuant/alpha = [0, 27] --> largest envQuant ~= 2^33 - * output: Q(29 - (6 + expMax)) - * - * reference: 14496-3:2001(E)/4.6.18.3.5 and 14496-4:200X/FPDAM8/5.6.5.1.2.1.5 - */ - if (ampRes) { - do { - exp = *envQuant++; - scalei = MIN(expMax - exp, 31); - *envDequant++ = envDQTab[0] >> scalei; - } while (--nBands); - - return (6 + expMax); - } else { - expMax >>= 1; - do { - exp = *envQuant++; - scalei = MIN(expMax - (exp >> 1), 31); - *envDequant++ = envDQTab[exp & 0x01] >> scalei; - } while (--nBands); - - return (6 + expMax); - } +static int DequantizeEnvelope(int nBands, int ampRes, signed char *envQuant, int *envDequant) { + int exp, expMax, i, scalei; + + if (nBands <= 0) { + return 0; + } + + /* scan for largest dequant value (do separately from envelope decoding to keep code cleaner) */ + expMax = 0; + for (i = 0; i < nBands; i++) { + if (envQuant[i] > expMax) { + expMax = envQuant[i]; + } + } + + /* dequantized envelope gains + envDequant = 64*2^(envQuant / alpha) = 2^(6 + envQuant / alpha) + if ampRes == 0, alpha = 2 and range of envQuant = [0, 127] + if ampRes == 1, alpha = 1 and range of envQuant = [0, 63] + also if coupling is on, envDequant is scaled by something in range [0, 2] + so range of envDequant = [2^6, 2^69] (no coupling), [2^6, 2^70] (with coupling) + + typical range (from observation) of envQuant/alpha = [0, 27] --> largest envQuant ~= 2^33 + output: Q(29 - (6 + expMax)) + + reference: 14496-3:2001(E)/4.6.18.3.5 and 14496-4:200X/FPDAM8/5.6.5.1.2.1.5 + */ + if (ampRes) { + do { + exp = *envQuant++; + scalei = MIN(expMax - exp, 31); + *envDequant++ = envDQTab[0] >> scalei; + } while (--nBands); + + return (6 + expMax); + } else { + expMax >>= 1; + do { + exp = *envQuant++; + scalei = MIN(expMax - (exp >> 1), 31); + *envDequant++ = envDQTab[exp & 0x01] >> scalei; + } while (--nBands); + + return (6 + expMax); + } } /************************************************************************************** - * Function: DequantizeNoise - * - * Description: dequantize noise scalefactors - * - * Inputs: number of scalefactors to process - * quantized noise scalefactors - * - * Outputs: dequantized noise scalefactors, format = Q(FBITS_OUT_DQ_NOISE) - * - * Return: none - * - * Notes: dequantized scalefactors have at least 2 GB + Function: DequantizeNoise + + Description: dequantize noise scalefactors + + Inputs: number of scalefactors to process + quantized noise scalefactors + + Outputs: dequantized noise scalefactors, format = Q(FBITS_OUT_DQ_NOISE) + + Return: none + + Notes: dequantized scalefactors have at least 2 GB **************************************************************************************/ -static void DequantizeNoise(int nBands, signed char *noiseQuant, int *noiseDequant) -{ - int exp, scalei; - - if (nBands <= 0) - return; - - /* dequantize noise floor gains (4.6.18.3.5): - * noiseDequant = 2^(NOISE_FLOOR_OFFSET - noiseQuant) - * - * range of noiseQuant = [0, 30] (see 4.6.18.3.6), NOISE_FLOOR_OFFSET = 6 - * so range of noiseDequant = [2^-24, 2^6] - */ - do { - exp = *noiseQuant++; - scalei = NOISE_FLOOR_OFFSET - exp + FBITS_OUT_DQ_NOISE; /* 6 + 24 - exp, exp = [0,30] */ - - if (scalei < 0) - *noiseDequant++ = 0; - else if (scalei < 30) - *noiseDequant++ = 1 << scalei; - else - *noiseDequant++ = 0x3fffffff; /* leave 2 GB */ - - } while (--nBands); +static void DequantizeNoise(int nBands, signed char *noiseQuant, int *noiseDequant) { + int exp, scalei; + + if (nBands <= 0) { + return; + } + + /* dequantize noise floor gains (4.6.18.3.5): + noiseDequant = 2^(NOISE_FLOOR_OFFSET - noiseQuant) + + range of noiseQuant = [0, 30] (see 4.6.18.3.6), NOISE_FLOOR_OFFSET = 6 + so range of noiseDequant = [2^-24, 2^6] + */ + do { + exp = *noiseQuant++; + scalei = NOISE_FLOOR_OFFSET - exp + FBITS_OUT_DQ_NOISE; /* 6 + 24 - exp, exp = [0,30] */ + + if (scalei < 0) { + *noiseDequant++ = 0; + } else if (scalei < 30) { + *noiseDequant++ = 1 << scalei; + } else { + *noiseDequant++ = 0x3fffffff; /* leave 2 GB */ + } + + } while (--nBands); } /************************************************************************************** - * Function: DecodeSBREnvelope - * - * Description: decode delta Huffman coded envelope scalefactors from bitstream - * - * Inputs: BitStreamInfo struct pointing to start of env data - * initialized PSInfoSBR struct - * initialized SBRGrid struct for this channel - * initialized SBRFreq struct for this SCE/CPE block - * initialized SBRChan struct for this channel - * index of current channel (0 for SCE, 0 or 1 for CPE) - * - * Outputs: dequantized env scalefactors for left channel (before decoupling) - * dequantized env scalefactors for right channel (if coupling off) - * or raw decoded env scalefactors for right channel (if coupling on) - * - * Return: none + Function: DecodeSBREnvelope + + Description: decode delta Huffman coded envelope scalefactors from bitstream + + Inputs: BitStreamInfo struct pointing to start of env data + initialized PSInfoSBR struct + initialized SBRGrid struct for this channel + initialized SBRFreq struct for this SCE/CPE block + initialized SBRChan struct for this channel + index of current channel (0 for SCE, 0 or 1 for CPE) + + Outputs: dequantized env scalefactors for left channel (before decoupling) + dequantized env scalefactors for right channel (if coupling off) + or raw decoded env scalefactors for right channel (if coupling on) + + Return: none **************************************************************************************/ -void DecodeSBREnvelope(BitStreamInfo *bsi, PSInfoSBR *psi, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch) -{ - int huffIndexTime, huffIndexFreq, env, envStartBits, band, nBands, sf, lastEnv; - int freqRes, freqResPrev, dShift, i; - - if (psi->couplingFlag && ch) { - dShift = 1; - if (sbrGrid->ampResFrame) { - huffIndexTime = HuffTabSBR_tEnv30b; - huffIndexFreq = HuffTabSBR_fEnv30b; - envStartBits = 5; - } else { - huffIndexTime = HuffTabSBR_tEnv15b; - huffIndexFreq = HuffTabSBR_fEnv15b; - envStartBits = 6; - } - } else { - dShift = 0; - if (sbrGrid->ampResFrame) { - huffIndexTime = HuffTabSBR_tEnv30; - huffIndexFreq = HuffTabSBR_fEnv30; - envStartBits = 6; - } else { - huffIndexTime = HuffTabSBR_tEnv15; - huffIndexFreq = HuffTabSBR_fEnv15; - envStartBits = 7; - } - } - - /* range of envDataQuant[] = [0, 127] (see comments in DequantizeEnvelope() for reference) */ - for (env = 0; env < sbrGrid->numEnv; env++) { - nBands = (sbrGrid->freqRes[env] ? sbrFreq->nHigh : sbrFreq->nLow); - freqRes = (sbrGrid->freqRes[env]); - freqResPrev = (env == 0 ? sbrGrid->freqResPrev : sbrGrid->freqRes[env-1]); - lastEnv = (env == 0 ? sbrGrid->numEnvPrev-1 : env-1); - if (lastEnv < 0) - lastEnv = 0; /* first frame */ - - ASSERT(nBands <= MAX_QMF_BANDS); - - if (sbrChan->deltaFlagEnv[env] == 0) { - /* delta coding in freq */ - sf = GetBits(bsi, envStartBits) << dShift; - sbrChan->envDataQuant[env][0] = sf; - for (band = 1; band < nBands; band++) { - sf = DecodeOneSymbol(bsi, huffIndexFreq) << dShift; - sbrChan->envDataQuant[env][band] = sf + sbrChan->envDataQuant[env][band-1]; - } - } else if (freqRes == freqResPrev) { - /* delta coding in time - same freq resolution for both frames */ - for (band = 0; band < nBands; band++) { - sf = DecodeOneSymbol(bsi, huffIndexTime) << dShift; - sbrChan->envDataQuant[env][band] = sf + sbrChan->envDataQuant[lastEnv][band]; - } - } else if (freqRes == 0 && freqResPrev == 1) { - /* delta coding in time - low freq resolution for new frame, high freq resolution for old frame */ - for (band = 0; band < nBands; band++) { - sf = DecodeOneSymbol(bsi, huffIndexTime) << dShift; - sbrChan->envDataQuant[env][band] = sf; - for (i = 0; i < sbrFreq->nHigh; i++) { - if (sbrFreq->freqHigh[i] == sbrFreq->freqLow[band]) { - sbrChan->envDataQuant[env][band] += sbrChan->envDataQuant[lastEnv][i]; - break; - } - } - } - } else if (freqRes == 1 && freqResPrev == 0) { - /* delta coding in time - high freq resolution for new frame, low freq resolution for old frame */ - for (band = 0; band < nBands; band++) { - sf = DecodeOneSymbol(bsi, huffIndexTime) << dShift; - sbrChan->envDataQuant[env][band] = sf; - for (i = 0; i < sbrFreq->nLow; i++) { - if (sbrFreq->freqLow[i] <= sbrFreq->freqHigh[band] && sbrFreq->freqHigh[band] < sbrFreq->freqLow[i+1] ) { - sbrChan->envDataQuant[env][band] += sbrChan->envDataQuant[lastEnv][i]; - break; - } - } - } - } - - /* skip coupling channel */ - if (ch != 1 || psi->couplingFlag != 1) - psi->envDataDequantScale[ch][env] = DequantizeEnvelope(nBands, sbrGrid->ampResFrame, sbrChan->envDataQuant[env], psi->envDataDequant[ch][env]); - } - sbrGrid->numEnvPrev = sbrGrid->numEnv; - sbrGrid->freqResPrev = sbrGrid->freqRes[sbrGrid->numEnv-1]; +void DecodeSBREnvelope(BitStreamInfo *bsi, PSInfoSBR *psi, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch) { + int huffIndexTime, huffIndexFreq, env, envStartBits, band, nBands, sf, lastEnv; + int freqRes, freqResPrev, dShift, i; + + if (psi->couplingFlag && ch) { + dShift = 1; + if (sbrGrid->ampResFrame) { + huffIndexTime = HuffTabSBR_tEnv30b; + huffIndexFreq = HuffTabSBR_fEnv30b; + envStartBits = 5; + } else { + huffIndexTime = HuffTabSBR_tEnv15b; + huffIndexFreq = HuffTabSBR_fEnv15b; + envStartBits = 6; + } + } else { + dShift = 0; + if (sbrGrid->ampResFrame) { + huffIndexTime = HuffTabSBR_tEnv30; + huffIndexFreq = HuffTabSBR_fEnv30; + envStartBits = 6; + } else { + huffIndexTime = HuffTabSBR_tEnv15; + huffIndexFreq = HuffTabSBR_fEnv15; + envStartBits = 7; + } + } + + /* range of envDataQuant[] = [0, 127] (see comments in DequantizeEnvelope() for reference) */ + for (env = 0; env < sbrGrid->numEnv; env++) { + nBands = (sbrGrid->freqRes[env] ? sbrFreq->nHigh : sbrFreq->nLow); + freqRes = (sbrGrid->freqRes[env]); + freqResPrev = (env == 0 ? sbrGrid->freqResPrev : sbrGrid->freqRes[env - 1]); + lastEnv = (env == 0 ? sbrGrid->numEnvPrev - 1 : env - 1); + if (lastEnv < 0) { + lastEnv = 0; /* first frame */ + } + + ASSERT(nBands <= MAX_QMF_BANDS); + + if (sbrChan->deltaFlagEnv[env] == 0) { + /* delta coding in freq */ + sf = GetBits(bsi, envStartBits) << dShift; + sbrChan->envDataQuant[env][0] = sf; + for (band = 1; band < nBands; band++) { + sf = DecodeOneSymbol(bsi, huffIndexFreq) << dShift; + sbrChan->envDataQuant[env][band] = sf + sbrChan->envDataQuant[env][band - 1]; + } + } else if (freqRes == freqResPrev) { + /* delta coding in time - same freq resolution for both frames */ + for (band = 0; band < nBands; band++) { + sf = DecodeOneSymbol(bsi, huffIndexTime) << dShift; + sbrChan->envDataQuant[env][band] = sf + sbrChan->envDataQuant[lastEnv][band]; + } + } else if (freqRes == 0 && freqResPrev == 1) { + /* delta coding in time - low freq resolution for new frame, high freq resolution for old frame */ + for (band = 0; band < nBands; band++) { + sf = DecodeOneSymbol(bsi, huffIndexTime) << dShift; + sbrChan->envDataQuant[env][band] = sf; + for (i = 0; i < sbrFreq->nHigh; i++) { + if (sbrFreq->freqHigh[i] == sbrFreq->freqLow[band]) { + sbrChan->envDataQuant[env][band] += sbrChan->envDataQuant[lastEnv][i]; + break; + } + } + } + } else if (freqRes == 1 && freqResPrev == 0) { + /* delta coding in time - high freq resolution for new frame, low freq resolution for old frame */ + for (band = 0; band < nBands; band++) { + sf = DecodeOneSymbol(bsi, huffIndexTime) << dShift; + sbrChan->envDataQuant[env][band] = sf; + for (i = 0; i < sbrFreq->nLow; i++) { + if (sbrFreq->freqLow[i] <= sbrFreq->freqHigh[band] && sbrFreq->freqHigh[band] < sbrFreq->freqLow[i + 1]) { + sbrChan->envDataQuant[env][band] += sbrChan->envDataQuant[lastEnv][i]; + break; + } + } + } + } + + /* skip coupling channel */ + if (ch != 1 || psi->couplingFlag != 1) { + psi->envDataDequantScale[ch][env] = DequantizeEnvelope(nBands, sbrGrid->ampResFrame, sbrChan->envDataQuant[env], psi->envDataDequant[ch][env]); + } + } + sbrGrid->numEnvPrev = sbrGrid->numEnv; + sbrGrid->freqResPrev = sbrGrid->freqRes[sbrGrid->numEnv - 1]; } /************************************************************************************** - * Function: DecodeSBRNoise - * - * Description: decode delta Huffman coded noise scalefactors from bitstream - * - * Inputs: BitStreamInfo struct pointing to start of noise data - * initialized PSInfoSBR struct - * initialized SBRGrid struct for this channel - * initialized SBRFreq struct for this SCE/CPE block - * initialized SBRChan struct for this channel - * index of current channel (0 for SCE, 0 or 1 for CPE) - * - * Outputs: dequantized noise scalefactors for left channel (before decoupling) - * dequantized noise scalefactors for right channel (if coupling off) - * or raw decoded noise scalefactors for right channel (if coupling on) - * - * Return: none + Function: DecodeSBRNoise + + Description: decode delta Huffman coded noise scalefactors from bitstream + + Inputs: BitStreamInfo struct pointing to start of noise data + initialized PSInfoSBR struct + initialized SBRGrid struct for this channel + initialized SBRFreq struct for this SCE/CPE block + initialized SBRChan struct for this channel + index of current channel (0 for SCE, 0 or 1 for CPE) + + Outputs: dequantized noise scalefactors for left channel (before decoupling) + dequantized noise scalefactors for right channel (if coupling off) + or raw decoded noise scalefactors for right channel (if coupling on) + + Return: none **************************************************************************************/ -void DecodeSBRNoise(BitStreamInfo *bsi, PSInfoSBR *psi, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch) -{ - int huffIndexTime, huffIndexFreq, noiseFloor, band, dShift, sf, lastNoiseFloor; - - if (psi->couplingFlag && ch) { - dShift = 1; - huffIndexTime = HuffTabSBR_tNoise30b; - huffIndexFreq = HuffTabSBR_fNoise30b; - } else { - dShift = 0; - huffIndexTime = HuffTabSBR_tNoise30; - huffIndexFreq = HuffTabSBR_fNoise30; - } - - for (noiseFloor = 0; noiseFloor < sbrGrid->numNoiseFloors; noiseFloor++) { - lastNoiseFloor = (noiseFloor == 0 ? sbrGrid->numNoiseFloorsPrev-1 : noiseFloor-1); - if (lastNoiseFloor < 0) - lastNoiseFloor = 0; /* first frame */ - - ASSERT(sbrFreq->numNoiseFloorBands <= MAX_QMF_BANDS); - - if (sbrChan->deltaFlagNoise[noiseFloor] == 0) { - /* delta coding in freq */ - sbrChan->noiseDataQuant[noiseFloor][0] = GetBits(bsi, 5) << dShift; - for (band = 1; band < sbrFreq->numNoiseFloorBands; band++) { - sf = DecodeOneSymbol(bsi, huffIndexFreq) << dShift; - sbrChan->noiseDataQuant[noiseFloor][band] = sf + sbrChan->noiseDataQuant[noiseFloor][band-1]; - } - } else { - /* delta coding in time */ - for (band = 0; band < sbrFreq->numNoiseFloorBands; band++) { - sf = DecodeOneSymbol(bsi, huffIndexTime) << dShift; - sbrChan->noiseDataQuant[noiseFloor][band] = sf + sbrChan->noiseDataQuant[lastNoiseFloor][band]; - } - } - - /* skip coupling channel */ - if (ch != 1 || psi->couplingFlag != 1) - DequantizeNoise(sbrFreq->numNoiseFloorBands, sbrChan->noiseDataQuant[noiseFloor], psi->noiseDataDequant[ch][noiseFloor]); - } - sbrGrid->numNoiseFloorsPrev = sbrGrid->numNoiseFloors; +void DecodeSBRNoise(BitStreamInfo *bsi, PSInfoSBR *psi, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch) { + int huffIndexTime, huffIndexFreq, noiseFloor, band, dShift, sf, lastNoiseFloor; + + if (psi->couplingFlag && ch) { + dShift = 1; + huffIndexTime = HuffTabSBR_tNoise30b; + huffIndexFreq = HuffTabSBR_fNoise30b; + } else { + dShift = 0; + huffIndexTime = HuffTabSBR_tNoise30; + huffIndexFreq = HuffTabSBR_fNoise30; + } + + for (noiseFloor = 0; noiseFloor < sbrGrid->numNoiseFloors; noiseFloor++) { + lastNoiseFloor = (noiseFloor == 0 ? sbrGrid->numNoiseFloorsPrev - 1 : noiseFloor - 1); + if (lastNoiseFloor < 0) { + lastNoiseFloor = 0; /* first frame */ + } + + ASSERT(sbrFreq->numNoiseFloorBands <= MAX_QMF_BANDS); + + if (sbrChan->deltaFlagNoise[noiseFloor] == 0) { + /* delta coding in freq */ + sbrChan->noiseDataQuant[noiseFloor][0] = GetBits(bsi, 5) << dShift; + for (band = 1; band < sbrFreq->numNoiseFloorBands; band++) { + sf = DecodeOneSymbol(bsi, huffIndexFreq) << dShift; + sbrChan->noiseDataQuant[noiseFloor][band] = sf + sbrChan->noiseDataQuant[noiseFloor][band - 1]; + } + } else { + /* delta coding in time */ + for (band = 0; band < sbrFreq->numNoiseFloorBands; band++) { + sf = DecodeOneSymbol(bsi, huffIndexTime) << dShift; + sbrChan->noiseDataQuant[noiseFloor][band] = sf + sbrChan->noiseDataQuant[lastNoiseFloor][band]; + } + } + + /* skip coupling channel */ + if (ch != 1 || psi->couplingFlag != 1) { + DequantizeNoise(sbrFreq->numNoiseFloorBands, sbrChan->noiseDataQuant[noiseFloor], psi->noiseDataDequant[ch][noiseFloor]); + } + } + sbrGrid->numNoiseFloorsPrev = sbrGrid->numNoiseFloors; } /* dqTabCouple[i] = 2 / (1 + 2^(12 - i)), format = Q30 */ static const int dqTabCouple[25] PROGMEM = { - 0x0007ff80, 0x000ffe00, 0x001ff802, 0x003fe010, 0x007f8080, 0x00fe03f8, 0x01f81f82, 0x03e0f83e, - 0x07878788, 0x0e38e38e, 0x1999999a, 0x2aaaaaab, 0x40000000, 0x55555555, 0x66666666, 0x71c71c72, - 0x78787878, 0x7c1f07c2, 0x7e07e07e, 0x7f01fc08, 0x7f807f80, 0x7fc01ff0, 0x7fe007fe, 0x7ff00200, - 0x7ff80080, + 0x0007ff80, 0x000ffe00, 0x001ff802, 0x003fe010, 0x007f8080, 0x00fe03f8, 0x01f81f82, 0x03e0f83e, + 0x07878788, 0x0e38e38e, 0x1999999a, 0x2aaaaaab, 0x40000000, 0x55555555, 0x66666666, 0x71c71c72, + 0x78787878, 0x7c1f07c2, 0x7e07e07e, 0x7f01fc08, 0x7f807f80, 0x7fc01ff0, 0x7fe007fe, 0x7ff00200, + 0x7ff80080, }; /************************************************************************************** - * Function: UncoupleSBREnvelope - * - * Description: scale dequantized envelope scalefactors according to channel - * coupling rules - * - * Inputs: initialized PSInfoSBR struct including - * dequantized envelope data for left channel - * initialized SBRGrid struct for this channel - * initialized SBRFreq struct for this SCE/CPE block - * initialized SBRChan struct for right channel including - * quantized envelope scalefactors - * - * Outputs: dequantized envelope data for left channel (after decoupling) - * dequantized envelope data for right channel (after decoupling) - * - * Return: none + Function: UncoupleSBREnvelope + + Description: scale dequantized envelope scalefactors according to channel + coupling rules + + Inputs: initialized PSInfoSBR struct including + dequantized envelope data for left channel + initialized SBRGrid struct for this channel + initialized SBRFreq struct for this SCE/CPE block + initialized SBRChan struct for right channel including + quantized envelope scalefactors + + Outputs: dequantized envelope data for left channel (after decoupling) + dequantized envelope data for right channel (after decoupling) + + Return: none **************************************************************************************/ -void UncoupleSBREnvelope(PSInfoSBR *psi, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChanR) -{ - int env, band, nBands, scalei, E_1; - - scalei = (sbrGrid->ampResFrame ? 0 : 1); - for (env = 0; env < sbrGrid->numEnv; env++) { - nBands = (sbrGrid->freqRes[env] ? sbrFreq->nHigh : sbrFreq->nLow); - psi->envDataDequantScale[1][env] = psi->envDataDequantScale[0][env]; /* same scalefactor for L and R */ - for (band = 0; band < nBands; band++) { - /* clip E_1 to [0, 24] (scalefactors approach 0 or 2) */ - E_1 = sbrChanR->envDataQuant[env][band] >> scalei; - if (E_1 < 0) E_1 = 0; - if (E_1 > 24) E_1 = 24; - - /* envDataDequant[0] has 1 GB, so << by 2 is okay */ - psi->envDataDequant[1][env][band] = MULSHIFT32(psi->envDataDequant[0][env][band], dqTabCouple[24 - E_1]) << 2; - psi->envDataDequant[0][env][band] = MULSHIFT32(psi->envDataDequant[0][env][band], dqTabCouple[E_1]) << 2; - } - } +void UncoupleSBREnvelope(PSInfoSBR *psi, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChanR) { + int env, band, nBands, scalei, E_1; + + scalei = (sbrGrid->ampResFrame ? 0 : 1); + for (env = 0; env < sbrGrid->numEnv; env++) { + nBands = (sbrGrid->freqRes[env] ? sbrFreq->nHigh : sbrFreq->nLow); + psi->envDataDequantScale[1][env] = psi->envDataDequantScale[0][env]; /* same scalefactor for L and R */ + for (band = 0; band < nBands; band++) { + /* clip E_1 to [0, 24] (scalefactors approach 0 or 2) */ + E_1 = sbrChanR->envDataQuant[env][band] >> scalei; + if (E_1 < 0) { + E_1 = 0; + } + if (E_1 > 24) { + E_1 = 24; + } + + /* envDataDequant[0] has 1 GB, so << by 2 is okay */ + psi->envDataDequant[1][env][band] = MULSHIFT32(psi->envDataDequant[0][env][band], dqTabCouple[24 - E_1]) << 2; + psi->envDataDequant[0][env][band] = MULSHIFT32(psi->envDataDequant[0][env][band], dqTabCouple[E_1]) << 2; + } + } } /************************************************************************************** - * Function: UncoupleSBRNoise - * - * Description: scale dequantized noise floor scalefactors according to channel - * coupling rules - * - * Inputs: initialized PSInfoSBR struct including - * dequantized noise data for left channel - * initialized SBRGrid struct for this channel - * initialized SBRFreq struct for this SCE/CPE block - * initialized SBRChan struct for this channel including - * quantized noise scalefactors - * - * Outputs: dequantized noise data for left channel (after decoupling) - * dequantized noise data for right channel (after decoupling) - * - * Return: none + Function: UncoupleSBRNoise + + Description: scale dequantized noise floor scalefactors according to channel + coupling rules + + Inputs: initialized PSInfoSBR struct including + dequantized noise data for left channel + initialized SBRGrid struct for this channel + initialized SBRFreq struct for this SCE/CPE block + initialized SBRChan struct for this channel including + quantized noise scalefactors + + Outputs: dequantized noise data for left channel (after decoupling) + dequantized noise data for right channel (after decoupling) + + Return: none **************************************************************************************/ -void UncoupleSBRNoise(PSInfoSBR *psi, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChanR) -{ - int noiseFloor, band, Q_1; - - for (noiseFloor = 0; noiseFloor < sbrGrid->numNoiseFloors; noiseFloor++) { - for (band = 0; band < sbrFreq->numNoiseFloorBands; band++) { - /* Q_1 should be in range [0, 24] according to 4.6.18.3.6, but check to make sure */ - Q_1 = sbrChanR->noiseDataQuant[noiseFloor][band]; - if (Q_1 < 0) Q_1 = 0; - if (Q_1 > 24) Q_1 = 24; - - /* noiseDataDequant[0] has 1 GB, so << by 2 is okay */ - psi->noiseDataDequant[1][noiseFloor][band] = MULSHIFT32(psi->noiseDataDequant[0][noiseFloor][band], dqTabCouple[24 - Q_1]) << 2; - psi->noiseDataDequant[0][noiseFloor][band] = MULSHIFT32(psi->noiseDataDequant[0][noiseFloor][band], dqTabCouple[Q_1]) << 2; - } - } +void UncoupleSBRNoise(PSInfoSBR *psi, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChanR) { + int noiseFloor, band, Q_1; + + for (noiseFloor = 0; noiseFloor < sbrGrid->numNoiseFloors; noiseFloor++) { + for (band = 0; band < sbrFreq->numNoiseFloorBands; band++) { + /* Q_1 should be in range [0, 24] according to 4.6.18.3.6, but check to make sure */ + Q_1 = sbrChanR->noiseDataQuant[noiseFloor][band]; + if (Q_1 < 0) { + Q_1 = 0; + } + if (Q_1 > 24) { + Q_1 = 24; + } + + /* noiseDataDequant[0] has 1 GB, so << by 2 is okay */ + psi->noiseDataDequant[1][noiseFloor][band] = MULSHIFT32(psi->noiseDataDequant[0][noiseFloor][band], dqTabCouple[24 - Q_1]) << 2; + psi->noiseDataDequant[0][noiseFloor][band] = MULSHIFT32(psi->noiseDataDequant[0][noiseFloor][band], dqTabCouple[Q_1]) << 2; + } + } } diff --git a/src/libhelix-aac/sbrimdct.c b/src/libhelix-aac/sbrimdct.c index 365ff02a..fa225185 100644 --- a/src/libhelix-aac/sbrimdct.c +++ b/src/libhelix-aac/sbrimdct.c @@ -1,447 +1,443 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: sbrimdct.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: sbrimdct.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * sbrimdct.c - inverse MDCT without clipping or interleaving, for input to SBR + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + sbrimdct.c - inverse MDCT without clipping or interleaving, for input to SBR **************************************************************************************/ #include "coder.h" #include "assembly.h" /************************************************************************************** - * Function: DecWindowOverlapNoClip - * - * Description: apply synthesis window, do overlap-add without clipping, - * for winSequence LONG-LONG - * - * Inputs: input buffer (output of type-IV DCT) - * overlap buffer (saved from last time) - * window type (sin or KBD) for input buffer - * window type (sin or KBD) for overlap buffer - * - * Outputs: one channel, one frame of 32-bit PCM, non-interleaved - * - * Return: none - * - * Notes: use this function when the decoded PCM is going to the SBR decoder + Function: DecWindowOverlapNoClip + + Description: apply synthesis window, do overlap-add without clipping, + for winSequence LONG-LONG + + Inputs: input buffer (output of type-IV DCT) + overlap buffer (saved from last time) + window type (sin or KBD) for input buffer + window type (sin or KBD) for overlap buffer + + Outputs: one channel, one frame of 32-bit PCM, non-interleaved + + Return: none + + Notes: use this function when the decoded PCM is going to the SBR decoder **************************************************************************************/ -void DecWindowOverlapNoClip(int *buf0, int *over0, int *out0, int winTypeCurr, int winTypePrev) -{ - int in, w0, w1, f0, f1; - int *buf1, *over1, *out1; - const int *wndPrev, *wndCurr; - - buf0 += (1024 >> 1); - buf1 = buf0 - 1; - out1 = out0 + 1024 - 1; - over1 = over0 + 1024 - 1; - - wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]); - if (winTypeCurr == winTypePrev) { - /* cut window loads in half since current and overlap sections use same symmetric window */ - do { - w0 = *wndPrev++; - w1 = *wndPrev++; - in = *buf0++; - - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); - - in = *over0; - *out0++ = in - f0; - - in = *over1; - *out1-- = in + f1; - - in = *buf1--; - *over1-- = MULSHIFT32(w0, in); - *over0++ = MULSHIFT32(w1, in); - } while (over0 < over1); - } else { - /* different windows for current and overlap parts - should still fit in registers on ARM w/o stack spill */ - wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]); - do { - w0 = *wndPrev++; - w1 = *wndPrev++; - in = *buf0++; - - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); - - in = *over0; - *out0++ = in - f0; - - in = *over1; - *out1-- = in + f1; - - w0 = *wndCurr++; - w1 = *wndCurr++; - in = *buf1--; - - *over1-- = MULSHIFT32(w0, in); - *over0++ = MULSHIFT32(w1, in); - } while (over0 < over1); - } +void DecWindowOverlapNoClip(int *buf0, int *over0, int *out0, int winTypeCurr, int winTypePrev) { + int in, w0, w1, f0, f1; + int *buf1, *over1, *out1; + const int *wndPrev, *wndCurr; + + buf0 += (1024 >> 1); + buf1 = buf0 - 1; + out1 = out0 + 1024 - 1; + over1 = over0 + 1024 - 1; + + wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]); + if (winTypeCurr == winTypePrev) { + /* cut window loads in half since current and overlap sections use same symmetric window */ + do { + w0 = *wndPrev++; + w1 = *wndPrev++; + in = *buf0++; + + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); + + in = *over0; + *out0++ = in - f0; + + in = *over1; + *out1-- = in + f1; + + in = *buf1--; + *over1-- = MULSHIFT32(w0, in); + *over0++ = MULSHIFT32(w1, in); + } while (over0 < over1); + } else { + /* different windows for current and overlap parts - should still fit in registers on ARM w/o stack spill */ + wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]); + do { + w0 = *wndPrev++; + w1 = *wndPrev++; + in = *buf0++; + + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); + + in = *over0; + *out0++ = in - f0; + + in = *over1; + *out1-- = in + f1; + + w0 = *wndCurr++; + w1 = *wndCurr++; + in = *buf1--; + + *over1-- = MULSHIFT32(w0, in); + *over0++ = MULSHIFT32(w1, in); + } while (over0 < over1); + } } /************************************************************************************** - * Function: DecWindowOverlapLongStart - * - * Description: apply synthesis window, do overlap-add, without clipping - * for winSequence LONG-START - * - * Inputs: input buffer (output of type-IV DCT) - * overlap buffer (saved from last time) - * window type (sin or KBD) for input buffer - * window type (sin or KBD) for overlap buffer - * - * Outputs: one channel, one frame of 32-bit PCM, non-interleaved - * - * Return: none - * - * Notes: use this function when the decoded PCM is going to the SBR decoder + Function: DecWindowOverlapLongStart + + Description: apply synthesis window, do overlap-add, without clipping + for winSequence LONG-START + + Inputs: input buffer (output of type-IV DCT) + overlap buffer (saved from last time) + window type (sin or KBD) for input buffer + window type (sin or KBD) for overlap buffer + + Outputs: one channel, one frame of 32-bit PCM, non-interleaved + + Return: none + + Notes: use this function when the decoded PCM is going to the SBR decoder **************************************************************************************/ -void DecWindowOverlapLongStartNoClip(int *buf0, int *over0, int *out0, int winTypeCurr, int winTypePrev) -{ - int i, in, w0, w1, f0, f1; - int *buf1, *over1, *out1; - const int *wndPrev, *wndCurr; +void DecWindowOverlapLongStartNoClip(int *buf0, int *over0, int *out0, int winTypeCurr, int winTypePrev) { + int i, in, w0, w1, f0, f1; + int *buf1, *over1, *out1; + const int *wndPrev, *wndCurr; - buf0 += (1024 >> 1); - buf1 = buf0 - 1; - out1 = out0 + 1024 - 1; - over1 = over0 + 1024 - 1; + buf0 += (1024 >> 1); + buf1 = buf0 - 1; + out1 = out0 + 1024 - 1; + over1 = over0 + 1024 - 1; - wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]); - i = 448; /* 2 outputs, 2 overlaps per loop */ - do { - w0 = *wndPrev++; - w1 = *wndPrev++; - in = *buf0++; + wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]); + i = 448; /* 2 outputs, 2 overlaps per loop */ + do { + w0 = *wndPrev++; + w1 = *wndPrev++; + in = *buf0++; - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); - in = *over0; - *out0++ = in - f0; + in = *over0; + *out0++ = in - f0; - in = *over1; - *out1-- = in + f1; + in = *over1; + *out1-- = in + f1; - in = *buf1--; + in = *buf1--; - *over1-- = 0; /* Wn = 0 for n = (2047, 2046, ... 1600) */ - *over0++ = in >> 1; /* Wn = 1 for n = (1024, 1025, ... 1471) */ - } while (--i); + *over1-- = 0; /* Wn = 0 for n = (2047, 2046, ... 1600) */ + *over0++ = in >> 1; /* Wn = 1 for n = (1024, 1025, ... 1471) */ + } while (--i); - wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]); + wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]); - /* do 64 more loops - 2 outputs, 2 overlaps per loop */ - do { - w0 = *wndPrev++; - w1 = *wndPrev++; - in = *buf0++; + /* do 64 more loops - 2 outputs, 2 overlaps per loop */ + do { + w0 = *wndPrev++; + w1 = *wndPrev++; + in = *buf0++; - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); - in = *over0; - *out0++ = in - f0; + in = *over0; + *out0++ = in - f0; - in = *over1; - *out1-- = in + f1; + in = *over1; + *out1-- = in + f1; - w0 = *wndCurr++; /* W[0], W[1], ... --> W[255], W[254], ... */ - w1 = *wndCurr++; /* W[127], W[126], ... --> W[128], W[129], ... */ - in = *buf1--; + w0 = *wndCurr++; /* W[0], W[1], ... --> W[255], W[254], ... */ + w1 = *wndCurr++; /* W[127], W[126], ... --> W[128], W[129], ... */ + in = *buf1--; - *over1-- = MULSHIFT32(w0, in); /* Wn = short window for n = (1599, 1598, ... , 1536) */ - *over0++ = MULSHIFT32(w1, in); /* Wn = short window for n = (1472, 1473, ... , 1535) */ - } while (over0 < over1); + *over1-- = MULSHIFT32(w0, in); /* Wn = short window for n = (1599, 1598, ... , 1536) */ + *over0++ = MULSHIFT32(w1, in); /* Wn = short window for n = (1472, 1473, ... , 1535) */ + } while (over0 < over1); } /************************************************************************************** - * Function: DecWindowOverlapLongStop - * - * Description: apply synthesis window, do overlap-add, without clipping - * for winSequence LONG-STOP - * - * Inputs: input buffer (output of type-IV DCT) - * overlap buffer (saved from last time) - * window type (sin or KBD) for input buffer - * window type (sin or KBD) for overlap buffer - * - * Outputs: one channel, one frame of 32-bit PCM, non-interleaved - * - * Return: none - * - * Notes: use this function when the decoded PCM is going to the SBR decoder + Function: DecWindowOverlapLongStop + + Description: apply synthesis window, do overlap-add, without clipping + for winSequence LONG-STOP + + Inputs: input buffer (output of type-IV DCT) + overlap buffer (saved from last time) + window type (sin or KBD) for input buffer + window type (sin or KBD) for overlap buffer + + Outputs: one channel, one frame of 32-bit PCM, non-interleaved + + Return: none + + Notes: use this function when the decoded PCM is going to the SBR decoder **************************************************************************************/ -void DecWindowOverlapLongStopNoClip(int *buf0, int *over0, int *out0, int winTypeCurr, int winTypePrev) -{ - int i, in, w0, w1, f0, f1; - int *buf1, *over1, *out1; - const int *wndPrev, *wndCurr; - - buf0 += (1024 >> 1); - buf1 = buf0 - 1; - out1 = out0 + 1024 - 1; - over1 = over0 + 1024 - 1; - - wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]); - wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]); - - i = 448; /* 2 outputs, 2 overlaps per loop */ - do { - /* Wn = 0 for n = (0, 1, ... 447) */ - /* Wn = 1 for n = (576, 577, ... 1023) */ - in = *buf0++; - f1 = in >> 1; /* scale since skipping multiply by Q31 */ - - in = *over0; - *out0++ = in; - - in = *over1; - *out1-- = in + f1; - - w0 = *wndCurr++; - w1 = *wndCurr++; - in = *buf1--; - - *over1-- = MULSHIFT32(w0, in); - *over0++ = MULSHIFT32(w1, in); - } while (--i); - - /* do 64 more loops - 2 outputs, 2 overlaps per loop */ - do { - w0 = *wndPrev++; /* W[0], W[1], ...W[63] */ - w1 = *wndPrev++; /* W[127], W[126], ... W[64] */ - in = *buf0++; - - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); - - in = *over0; - *out0++ = in - f0; - - in = *over1; - *out1-- = in + f1; - - w0 = *wndCurr++; - w1 = *wndCurr++; - in = *buf1--; - - *over1-- = MULSHIFT32(w0, in); - *over0++ = MULSHIFT32(w1, in); - } while (over0 < over1); +void DecWindowOverlapLongStopNoClip(int *buf0, int *over0, int *out0, int winTypeCurr, int winTypePrev) { + int i, in, w0, w1, f0, f1; + int *buf1, *over1, *out1; + const int *wndPrev, *wndCurr; + + buf0 += (1024 >> 1); + buf1 = buf0 - 1; + out1 = out0 + 1024 - 1; + over1 = over0 + 1024 - 1; + + wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]); + wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]); + + i = 448; /* 2 outputs, 2 overlaps per loop */ + do { + /* Wn = 0 for n = (0, 1, ... 447) */ + /* Wn = 1 for n = (576, 577, ... 1023) */ + in = *buf0++; + f1 = in >> 1; /* scale since skipping multiply by Q31 */ + + in = *over0; + *out0++ = in; + + in = *over1; + *out1-- = in + f1; + + w0 = *wndCurr++; + w1 = *wndCurr++; + in = *buf1--; + + *over1-- = MULSHIFT32(w0, in); + *over0++ = MULSHIFT32(w1, in); + } while (--i); + + /* do 64 more loops - 2 outputs, 2 overlaps per loop */ + do { + w0 = *wndPrev++; /* W[0], W[1], ...W[63] */ + w1 = *wndPrev++; /* W[127], W[126], ... W[64] */ + in = *buf0++; + + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); + + in = *over0; + *out0++ = in - f0; + + in = *over1; + *out1-- = in + f1; + + w0 = *wndCurr++; + w1 = *wndCurr++; + in = *buf1--; + + *over1-- = MULSHIFT32(w0, in); + *over0++ = MULSHIFT32(w1, in); + } while (over0 < over1); } /************************************************************************************** - * Function: DecWindowOverlapShort - * - * Description: apply synthesis window, do overlap-add, without clipping - * for winSequence EIGHT-SHORT (does all 8 short blocks) - * - * Inputs: input buffer (output of type-IV DCT) - * overlap buffer (saved from last time) - * window type (sin or KBD) for input buffer - * window type (sin or KBD) for overlap buffer - * - * Outputs: one channel, one frame of 32-bit PCM, non-interleaved - * - * Return: none - * - * Notes: use this function when the decoded PCM is going to the SBR decoder + Function: DecWindowOverlapShort + + Description: apply synthesis window, do overlap-add, without clipping + for winSequence EIGHT-SHORT (does all 8 short blocks) + + Inputs: input buffer (output of type-IV DCT) + overlap buffer (saved from last time) + window type (sin or KBD) for input buffer + window type (sin or KBD) for overlap buffer + + Outputs: one channel, one frame of 32-bit PCM, non-interleaved + + Return: none + + Notes: use this function when the decoded PCM is going to the SBR decoder **************************************************************************************/ -void DecWindowOverlapShortNoClip(int *buf0, int *over0, int *out0, int winTypeCurr, int winTypePrev) -{ - int i, in, w0, w1, f0, f1; - int *buf1, *over1, *out1; - const int *wndPrev, *wndCurr; - - wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]); - wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]); - - /* pcm[0-447] = 0 + overlap[0-447] */ - i = 448; - do { - f0 = *over0++; - f1 = *over0++; - *out0++ = f0; - *out0++ = f1; - i -= 2; - } while (i); - - /* pcm[448-575] = Wp[0-127] * block0[0-127] + overlap[448-575] */ - out1 = out0 + (128 - 1); - over1 = over0 + 128 - 1; - buf0 += 64; - buf1 = buf0 - 1; - do { - w0 = *wndPrev++; /* W[0], W[1], ...W[63] */ - w1 = *wndPrev++; /* W[127], W[126], ... W[64] */ - in = *buf0++; - - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); - - in = *over0; - *out0++ = in - f0; - - in = *over1; - *out1-- = in + f1; - - w0 = *wndCurr++; - w1 = *wndCurr++; - in = *buf1--; - - /* save over0/over1 for next short block, in the slots just vacated */ - *over1-- = MULSHIFT32(w0, in); - *over0++ = MULSHIFT32(w1, in); - } while (over0 < over1); - - /* pcm[576-703] = Wc[128-255] * block0[128-255] + Wc[0-127] * block1[0-127] + overlap[576-703] - * pcm[704-831] = Wc[128-255] * block1[128-255] + Wc[0-127] * block2[0-127] + overlap[704-831] - * pcm[832-959] = Wc[128-255] * block2[128-255] + Wc[0-127] * block3[0-127] + overlap[832-959] - */ - for (i = 0; i < 3; i++) { - out0 += 64; - out1 = out0 + 128 - 1; - over0 += 64; - over1 = over0 + 128 - 1; - buf0 += 64; - buf1 = buf0 - 1; - wndCurr -= 128; - - do { - w0 = *wndCurr++; /* W[0], W[1], ...W[63] */ - w1 = *wndCurr++; /* W[127], W[126], ... W[64] */ - in = *buf0++; - - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); - - in = *(over0 - 128); /* from last short block */ - in += *(over0 + 0); /* from last full frame */ - *out0++ = in - f0; - - in = *(over1 - 128); /* from last short block */ - in += *(over1 + 0); /* from last full frame */ - *out1-- = in + f1; - - /* save over0/over1 for next short block, in the slots just vacated */ - in = *buf1--; - *over1-- = MULSHIFT32(w0, in); - *over0++ = MULSHIFT32(w1, in); - } while (over0 < over1); - } - - /* pcm[960-1023] = Wc[128-191] * block3[128-191] + Wc[0-63] * block4[0-63] + overlap[960-1023] - * over[0-63] = Wc[192-255] * block3[192-255] + Wc[64-127] * block4[64-127] - */ - out0 += 64; - over0 -= 832; /* points at overlap[64] */ - over1 = over0 + 128 - 1; /* points at overlap[191] */ - buf0 += 64; - buf1 = buf0 - 1; - wndCurr -= 128; - do { - w0 = *wndCurr++; /* W[0], W[1], ...W[63] */ - w1 = *wndCurr++; /* W[127], W[126], ... W[64] */ - in = *buf0++; - - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); - - in = *(over0 + 768); /* from last short block */ - in += *(over0 + 896); /* from last full frame */ - *out0++ = in - f0; - - in = *(over1 + 768); /* from last short block */ - *(over1 - 128) = in + f1; - - in = *buf1--; - *over1-- = MULSHIFT32(w0, in); /* save in overlap[128-191] */ - *over0++ = MULSHIFT32(w1, in); /* save in overlap[64-127] */ - } while (over0 < over1); - - /* over0 now points at overlap[128] */ - - /* over[64-191] = Wc[128-255] * block4[128-255] + Wc[0-127] * block5[0-127] - * over[192-319] = Wc[128-255] * block5[128-255] + Wc[0-127] * block6[0-127] - * over[320-447] = Wc[128-255] * block6[128-255] + Wc[0-127] * block7[0-127] - * over[448-576] = Wc[128-255] * block7[128-255] - */ - for (i = 0; i < 3; i++) { - over0 += 64; - over1 = over0 + 128 - 1; - buf0 += 64; - buf1 = buf0 - 1; - wndCurr -= 128; - do { - w0 = *wndCurr++; /* W[0], W[1], ...W[63] */ - w1 = *wndCurr++; /* W[127], W[126], ... W[64] */ - in = *buf0++; - - f0 = MULSHIFT32(w0, in); - f1 = MULSHIFT32(w1, in); - - /* from last short block */ - *(over0 - 128) -= f0; - *(over1 - 128)+= f1; - - in = *buf1--; - *over1-- = MULSHIFT32(w0, in); - *over0++ = MULSHIFT32(w1, in); - } while (over0 < over1); - } - - /* over[576-1024] = 0 */ - i = 448; - over0 += 64; - do { - *over0++ = 0; - *over0++ = 0; - *over0++ = 0; - *over0++ = 0; - i -= 4; - } while (i); +void DecWindowOverlapShortNoClip(int *buf0, int *over0, int *out0, int winTypeCurr, int winTypePrev) { + int i, in, w0, w1, f0, f1; + int *buf1, *over1, *out1; + const int *wndPrev, *wndCurr; + + wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]); + wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]); + + /* pcm[0-447] = 0 + overlap[0-447] */ + i = 448; + do { + f0 = *over0++; + f1 = *over0++; + *out0++ = f0; + *out0++ = f1; + i -= 2; + } while (i); + + /* pcm[448-575] = Wp[0-127] * block0[0-127] + overlap[448-575] */ + out1 = out0 + (128 - 1); + over1 = over0 + 128 - 1; + buf0 += 64; + buf1 = buf0 - 1; + do { + w0 = *wndPrev++; /* W[0], W[1], ...W[63] */ + w1 = *wndPrev++; /* W[127], W[126], ... W[64] */ + in = *buf0++; + + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); + + in = *over0; + *out0++ = in - f0; + + in = *over1; + *out1-- = in + f1; + + w0 = *wndCurr++; + w1 = *wndCurr++; + in = *buf1--; + + /* save over0/over1 for next short block, in the slots just vacated */ + *over1-- = MULSHIFT32(w0, in); + *over0++ = MULSHIFT32(w1, in); + } while (over0 < over1); + + /* pcm[576-703] = Wc[128-255] * block0[128-255] + Wc[0-127] * block1[0-127] + overlap[576-703] + pcm[704-831] = Wc[128-255] * block1[128-255] + Wc[0-127] * block2[0-127] + overlap[704-831] + pcm[832-959] = Wc[128-255] * block2[128-255] + Wc[0-127] * block3[0-127] + overlap[832-959] + */ + for (i = 0; i < 3; i++) { + out0 += 64; + out1 = out0 + 128 - 1; + over0 += 64; + over1 = over0 + 128 - 1; + buf0 += 64; + buf1 = buf0 - 1; + wndCurr -= 128; + + do { + w0 = *wndCurr++; /* W[0], W[1], ...W[63] */ + w1 = *wndCurr++; /* W[127], W[126], ... W[64] */ + in = *buf0++; + + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); + + in = *(over0 - 128); /* from last short block */ + in += *(over0 + 0); /* from last full frame */ + *out0++ = in - f0; + + in = *(over1 - 128); /* from last short block */ + in += *(over1 + 0); /* from last full frame */ + *out1-- = in + f1; + + /* save over0/over1 for next short block, in the slots just vacated */ + in = *buf1--; + *over1-- = MULSHIFT32(w0, in); + *over0++ = MULSHIFT32(w1, in); + } while (over0 < over1); + } + + /* pcm[960-1023] = Wc[128-191] * block3[128-191] + Wc[0-63] * block4[0-63] + overlap[960-1023] + over[0-63] = Wc[192-255] * block3[192-255] + Wc[64-127] * block4[64-127] + */ + out0 += 64; + over0 -= 832; /* points at overlap[64] */ + over1 = over0 + 128 - 1; /* points at overlap[191] */ + buf0 += 64; + buf1 = buf0 - 1; + wndCurr -= 128; + do { + w0 = *wndCurr++; /* W[0], W[1], ...W[63] */ + w1 = *wndCurr++; /* W[127], W[126], ... W[64] */ + in = *buf0++; + + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); + + in = *(over0 + 768); /* from last short block */ + in += *(over0 + 896); /* from last full frame */ + *out0++ = in - f0; + + in = *(over1 + 768); /* from last short block */ + *(over1 - 128) = in + f1; + + in = *buf1--; + *over1-- = MULSHIFT32(w0, in); /* save in overlap[128-191] */ + *over0++ = MULSHIFT32(w1, in); /* save in overlap[64-127] */ + } while (over0 < over1); + + /* over0 now points at overlap[128] */ + + /* over[64-191] = Wc[128-255] * block4[128-255] + Wc[0-127] * block5[0-127] + over[192-319] = Wc[128-255] * block5[128-255] + Wc[0-127] * block6[0-127] + over[320-447] = Wc[128-255] * block6[128-255] + Wc[0-127] * block7[0-127] + over[448-576] = Wc[128-255] * block7[128-255] + */ + for (i = 0; i < 3; i++) { + over0 += 64; + over1 = over0 + 128 - 1; + buf0 += 64; + buf1 = buf0 - 1; + wndCurr -= 128; + do { + w0 = *wndCurr++; /* W[0], W[1], ...W[63] */ + w1 = *wndCurr++; /* W[127], W[126], ... W[64] */ + in = *buf0++; + + f0 = MULSHIFT32(w0, in); + f1 = MULSHIFT32(w1, in); + + /* from last short block */ + *(over0 - 128) -= f0; + *(over1 - 128) += f1; + + in = *buf1--; + *over1-- = MULSHIFT32(w0, in); + *over0++ = MULSHIFT32(w1, in); + } while (over0 < over1); + } + + /* over[576-1024] = 0 */ + i = 448; + over0 += 64; + do { + *over0++ = 0; + *over0++ = 0; + *over0++ = 0; + *over0++ = 0; + i -= 4; + } while (i); } diff --git a/src/libhelix-aac/sbrmath.c b/src/libhelix-aac/sbrmath.c index 930889d8..e738d6f1 100644 --- a/src/libhelix-aac/sbrmath.c +++ b/src/libhelix-aac/sbrmath.c @@ -1,46 +1,46 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: sbrmath.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: sbrmath.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * sbrmath.c - fixed-point math functions for SBR + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + sbrmath.c - fixed-point math functions for SBR **************************************************************************************/ #include "sbr.h" @@ -52,49 +52,48 @@ #define NUM_ITER_IRN 5 /************************************************************************************** - * Function: InvRNormalized - * - * Description: use Newton's method to solve for x = 1/r - * - * Inputs: r = Q31, range = [0.5, 1) (normalize your inputs to this range) - * - * Outputs: none - * - * Return: x = Q29, range ~= [1.0, 2.0] - * - * Notes: guaranteed to converge and not overflow for any r in [0.5, 1) - * - * xn+1 = xn - f(xn)/f'(xn) - * f(x) = 1/r - x = 0 (find root) - * = 1/x - r - * f'(x) = -1/x^2 - * - * so xn+1 = xn - (1/xn - r) / (-1/xn^2) - * = xn * (2 - r*xn) - * - * NUM_ITER_IRN = 2, maxDiff = 6.2500e-02 (precision of about 4 bits) - * NUM_ITER_IRN = 3, maxDiff = 3.9063e-03 (precision of about 8 bits) - * NUM_ITER_IRN = 4, maxDiff = 1.5288e-05 (precision of about 16 bits) - * NUM_ITER_IRN = 5, maxDiff = 3.0034e-08 (precision of about 24 bits) + Function: InvRNormalized + + Description: use Newton's method to solve for x = 1/r + + Inputs: r = Q31, range = [0.5, 1) (normalize your inputs to this range) + + Outputs: none + + Return: x = Q29, range ~= [1.0, 2.0] + + Notes: guaranteed to converge and not overflow for any r in [0.5, 1) + + xn+1 = xn - f(xn)/f'(xn) + f(x) = 1/r - x = 0 (find root) + = 1/x - r + f'(x) = -1/x^2 + + so xn+1 = xn - (1/xn - r) / (-1/xn^2) + = xn * (2 - r*xn) + + NUM_ITER_IRN = 2, maxDiff = 6.2500e-02 (precision of about 4 bits) + NUM_ITER_IRN = 3, maxDiff = 3.9063e-03 (precision of about 8 bits) + NUM_ITER_IRN = 4, maxDiff = 1.5288e-05 (precision of about 16 bits) + NUM_ITER_IRN = 5, maxDiff = 3.0034e-08 (precision of about 24 bits) **************************************************************************************/ -int InvRNormalized(int r) -{ - int i, xn, t; - - /* r = [0.5, 1.0) - * 1/r = (1.0, 2.0] - * so use 1.5 as initial guess - */ - xn = Q28_15; - - /* xn = xn*(2.0 - r*xn) */ - for (i = NUM_ITER_IRN; i != 0; i--) { - t = MULSHIFT32(r, xn); /* Q31*Q29 = Q28 */ - t = Q28_2 - t; /* Q28 */ - xn = MULSHIFT32(xn, t) << 4; /* Q29*Q28 << 4 = Q29 */ - } - - return xn; +int InvRNormalized(int r) { + int i, xn, t; + + /* r = [0.5, 1.0) + 1/r = (1.0, 2.0] + so use 1.5 as initial guess + */ + xn = Q28_15; + + /* xn = xn*(2.0 - r*xn) */ + for (i = NUM_ITER_IRN; i != 0; i--) { + t = MULSHIFT32(r, xn); /* Q31*Q29 = Q28 */ + t = Q28_2 - t; /* Q28 */ + xn = MULSHIFT32(xn, t) << 4; /* Q29*Q28 << 4 = Q29 */ + } + + return xn; } #define NUM_TERMS_RPI 5 @@ -104,92 +103,93 @@ int InvRNormalized(int r) static const int invTab[NUM_TERMS_RPI] PROGMEM = {0x40000000, 0x20000000, 0x15555555, 0x10000000, 0x0ccccccd}; /************************************************************************************** - * Function: RatioPowInv - * - * Description: use Taylor (MacLaurin) series expansion to calculate (a/b) ^ (1/c) - * - * Inputs: a = [1, 64], b = [1, 64], c = [1, 64], a >= b - * - * Outputs: none - * - * Return: y = Q24, range ~= [0.015625, 64] + Function: RatioPowInv + + Description: use Taylor (MacLaurin) series expansion to calculate (a/b) ^ (1/c) + + Inputs: a = [1, 64], b = [1, 64], c = [1, 64], a >= b + + Outputs: none + + Return: y = Q24, range ~= [0.015625, 64] **************************************************************************************/ -int RatioPowInv(int a, int b, int c) -{ - int lna, lnb, i, p, t, y; +int RatioPowInv(int a, int b, int c) { + int lna, lnb, i, p, t, y; - if (a < 1 || b < 1 || c < 1 || a > 64 || b > 64 || c > 64 || a < b) - return 0; + if (a < 1 || b < 1 || c < 1 || a > 64 || b > 64 || c > 64 || a < b) { + return 0; + } - lna = MULSHIFT32(log2Tab[a], LOG2_EXP_INV) << 1; /* ln(a), Q28 */ - lnb = MULSHIFT32(log2Tab[b], LOG2_EXP_INV) << 1; /* ln(b), Q28 */ - p = (lna - lnb) / c; /* Q28 */ + lna = MULSHIFT32(log2Tab[a], LOG2_EXP_INV) << 1; /* ln(a), Q28 */ + lnb = MULSHIFT32(log2Tab[b], LOG2_EXP_INV) << 1; /* ln(b), Q28 */ + p = (lna - lnb) / c; /* Q28 */ - /* sum in Q24 */ - y = (1 << 24); - t = p >> 4; /* t = p^1 * 1/1! (Q24)*/ - y += t; + /* sum in Q24 */ + y = (1 << 24); + t = p >> 4; /* t = p^1 * 1/1! (Q24)*/ + y += t; - for (i = 2; i <= NUM_TERMS_RPI; i++) { - t = MULSHIFT32(invTab[i-1], t) << 2; - t = MULSHIFT32(p, t) << 4; /* t = p^i * 1/i! (Q24) */ - y += t; - } + for (i = 2; i <= NUM_TERMS_RPI; i++) { + t = MULSHIFT32(invTab[i - 1], t) << 2; + t = MULSHIFT32(p, t) << 4; /* t = p^i * 1/i! (Q24) */ + y += t; + } - return y; + return y; } /************************************************************************************** - * Function: SqrtFix - * - * Description: use binary search to calculate sqrt(q) - * - * Inputs: q = Q30 - * number of fraction bits in input - * - * Outputs: number of fraction bits in output - * - * Return: lo = Q(fBitsOut) - * - * Notes: absolute precision varies depending on fBitsIn - * normalizes input to range [0x200000000, 0x7fffffff] and takes - * floor(sqrt(input)), and sets fBitsOut appropriately + Function: SqrtFix + + Description: use binary search to calculate sqrt(q) + + Inputs: q = Q30 + number of fraction bits in input + + Outputs: number of fraction bits in output + + Return: lo = Q(fBitsOut) + + Notes: absolute precision varies depending on fBitsIn + normalizes input to range [0x200000000, 0x7fffffff] and takes + floor(sqrt(input)), and sets fBitsOut appropriately **************************************************************************************/ -int SqrtFix(int q, int fBitsIn, int *fBitsOut) -{ - int z, lo, hi, mid; - - if (q <= 0) { - *fBitsOut = fBitsIn; - return 0; - } - - /* force even fBitsIn */ - z = fBitsIn & 0x01; - q >>= z; - fBitsIn -= z; - - /* for max precision, normalize to [0x20000000, 0x7fffffff] */ - z = (CLZ(q) - 1); - z >>= 1; - q <<= (2*z); - - /* choose initial bounds */ - lo = 1; - if (q >= 0x10000000) - lo = 16384; /* (int)sqrt(0x10000000) */ - hi = 46340; /* (int)sqrt(0x7fffffff) */ - - /* do binary search with 32x32->32 multiply test */ - do { - mid = (lo + hi) >> 1; - if (mid*mid > q) - hi = mid - 1; - else - lo = mid + 1; - } while (hi >= lo); - lo--; - - *fBitsOut = ((fBitsIn + 2*z) >> 1); - return lo; +int SqrtFix(int q, int fBitsIn, int *fBitsOut) { + int z, lo, hi, mid; + + if (q <= 0) { + *fBitsOut = fBitsIn; + return 0; + } + + /* force even fBitsIn */ + z = fBitsIn & 0x01; + q >>= z; + fBitsIn -= z; + + /* for max precision, normalize to [0x20000000, 0x7fffffff] */ + z = (CLZ(q) - 1); + z >>= 1; + q <<= (2 * z); + + /* choose initial bounds */ + lo = 1; + if (q >= 0x10000000) { + lo = 16384; /* (int)sqrt(0x10000000) */ + } + hi = 46340; /* (int)sqrt(0x7fffffff) */ + + /* do binary search with 32x32->32 multiply test */ + do { + mid = (lo + hi) >> 1; + if (mid * mid > q) { + hi = mid - 1; + } else { + lo = mid + 1; + } + } while (hi >= lo); + lo--; + + *fBitsOut = ((fBitsIn + 2 * z) >> 1); + return lo; } diff --git a/src/libhelix-aac/sbrqmf.c b/src/libhelix-aac/sbrqmf.c index 83cf14a4..7ac1fb32 100644 --- a/src/libhelix-aac/sbrqmf.c +++ b/src/libhelix-aac/sbrqmf.c @@ -1,376 +1,413 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: sbrqmf.c,v 1.2 2005/05/19 20:45:20 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: sbrqmf.c,v 1.2 2005/05/19 20:45:20 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * sbrqmf.c - analysis and synthesis QMF filters for SBR + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + sbrqmf.c - analysis and synthesis QMF filters for SBR **************************************************************************************/ #include "sbr.h" #include "assembly.h" -/* PreMultiply64() table - * format = Q30 - * reordered for sequential access - * - * for (i = 0; i < 64/4; i++) { - * angle = (i + 0.25) * M_PI / nmdct; - * x = (cos(angle) + sin(angle)); - * x = sin(angle); - * - * angle = (nmdct/2 - 1 - i + 0.25) * M_PI / nmdct; - * x = (cos(angle) + sin(angle)); - * x = sin(angle); - * } - */ +/* PreMultiply64() table + format = Q30 + reordered for sequential access + + for (i = 0; i < 64/4; i++) { + angle = (i + 0.25) * M_PI / nmdct; + x = (cos(angle) + sin(angle)); + x = sin(angle); + + angle = (nmdct/2 - 1 - i + 0.25) * M_PI / nmdct; + x = (cos(angle) + sin(angle)); + x = sin(angle); + } +*/ static const int cos4sin4tab64[64] PROGMEM = { - 0x40c7d2bd, 0x00c90e90, 0x424ff28f, 0x3ff4e5e0, 0x43cdd89a, 0x03ecadcf, 0x454149fc, 0x3fc395f9, - 0x46aa0d6d, 0x070de172, 0x4807eb4b, 0x3f6af2e3, 0x495aada2, 0x0a2abb59, 0x4aa22036, 0x3eeb3347, - 0x4bde1089, 0x0d415013, 0x4d0e4de2, 0x3e44a5ef, 0x4e32a956, 0x104fb80e, 0x4f4af5d1, 0x3d77b192, - 0x50570819, 0x135410c3, 0x5156b6d9, 0x3c84d496, 0x5249daa2, 0x164c7ddd, 0x53304df6, 0x3b6ca4c4, - 0x5409ed4b, 0x19372a64, 0x54d69714, 0x3a2fcee8, 0x55962bc0, 0x1c1249d8, 0x56488dc5, 0x38cf1669, - 0x56eda1a0, 0x1edc1953, 0x57854ddd, 0x374b54ce, 0x580f7b19, 0x2192e09b, 0x588c1404, 0x35a5793c, - 0x58fb0568, 0x2434f332, 0x595c3e2a, 0x33de87de, 0x59afaf4c, 0x26c0b162, 0x59f54bee, 0x31f79948, - 0x5a2d0957, 0x29348937, 0x5a56deec, 0x2ff1d9c7, 0x5a72c63b, 0x2b8ef77d, 0x5a80baf6, 0x2dce88aa, + 0x40c7d2bd, 0x00c90e90, 0x424ff28f, 0x3ff4e5e0, 0x43cdd89a, 0x03ecadcf, 0x454149fc, 0x3fc395f9, + 0x46aa0d6d, 0x070de172, 0x4807eb4b, 0x3f6af2e3, 0x495aada2, 0x0a2abb59, 0x4aa22036, 0x3eeb3347, + 0x4bde1089, 0x0d415013, 0x4d0e4de2, 0x3e44a5ef, 0x4e32a956, 0x104fb80e, 0x4f4af5d1, 0x3d77b192, + 0x50570819, 0x135410c3, 0x5156b6d9, 0x3c84d496, 0x5249daa2, 0x164c7ddd, 0x53304df6, 0x3b6ca4c4, + 0x5409ed4b, 0x19372a64, 0x54d69714, 0x3a2fcee8, 0x55962bc0, 0x1c1249d8, 0x56488dc5, 0x38cf1669, + 0x56eda1a0, 0x1edc1953, 0x57854ddd, 0x374b54ce, 0x580f7b19, 0x2192e09b, 0x588c1404, 0x35a5793c, + 0x58fb0568, 0x2434f332, 0x595c3e2a, 0x33de87de, 0x59afaf4c, 0x26c0b162, 0x59f54bee, 0x31f79948, + 0x5a2d0957, 0x29348937, 0x5a56deec, 0x2ff1d9c7, 0x5a72c63b, 0x2b8ef77d, 0x5a80baf6, 0x2dce88aa, }; -/* PostMultiply64() table - * format = Q30 - * reordered for sequential access - * - * for (i = 0; i <= (32/2); i++) { - * angle = i * M_PI / 64; - * x = (cos(angle) + sin(angle)); - * x = sin(angle); - * } - */ +/* PostMultiply64() table + format = Q30 + reordered for sequential access + + for (i = 0; i <= (32/2); i++) { + angle = i * M_PI / 64; + x = (cos(angle) + sin(angle)); + x = sin(angle); + } +*/ static const int cos1sin1tab64[34] PROGMEM = { - 0x40000000, 0x00000000, 0x43103085, 0x0323ecbe, 0x45f704f7, 0x0645e9af, 0x48b2b335, 0x09640837, - 0x4b418bbe, 0x0c7c5c1e, 0x4da1fab5, 0x0f8cfcbe, 0x4fd288dc, 0x1294062f, 0x51d1dc80, 0x158f9a76, - 0x539eba45, 0x187de2a7, 0x553805f2, 0x1b5d100a, 0x569cc31b, 0x1e2b5d38, 0x57cc15bc, 0x20e70f32, - 0x58c542c5, 0x238e7673, 0x5987b08a, 0x261feffa, 0x5a12e720, 0x2899e64a, 0x5a6690ae, 0x2afad269, - 0x5a82799a, 0x2d413ccd, + 0x40000000, 0x00000000, 0x43103085, 0x0323ecbe, 0x45f704f7, 0x0645e9af, 0x48b2b335, 0x09640837, + 0x4b418bbe, 0x0c7c5c1e, 0x4da1fab5, 0x0f8cfcbe, 0x4fd288dc, 0x1294062f, 0x51d1dc80, 0x158f9a76, + 0x539eba45, 0x187de2a7, 0x553805f2, 0x1b5d100a, 0x569cc31b, 0x1e2b5d38, 0x57cc15bc, 0x20e70f32, + 0x58c542c5, 0x238e7673, 0x5987b08a, 0x261feffa, 0x5a12e720, 0x2899e64a, 0x5a6690ae, 0x2afad269, + 0x5a82799a, 0x2d413ccd, }; /************************************************************************************** - * Function: PreMultiply64 - * - * Description: pre-twiddle stage of 64-point DCT-IV - * - * Inputs: buffer of 64 samples - * - * Outputs: processed samples in same buffer - * - * Return: none - * - * Notes: minimum 1 GB in, 2 GB out, gains 2 int bits - * gbOut = gbIn + 1 - * output is limited to sqrt(2)/2 plus GB in full GB - * uses 3-mul, 3-add butterflies instead of 4-mul, 2-add + Function: PreMultiply64 + + Description: pre-twiddle stage of 64-point DCT-IV + + Inputs: buffer of 64 samples + + Outputs: processed samples in same buffer + + Return: none + + Notes: minimum 1 GB in, 2 GB out, gains 2 int bits + gbOut = gbIn + 1 + output is limited to sqrt(2)/2 plus GB in full GB + uses 3-mul, 3-add butterflies instead of 4-mul, 2-add **************************************************************************************/ -static void PreMultiply64(int *zbuf1) -{ - int i, ar1, ai1, ar2, ai2, z1, z2; - int t, cms2, cps2a, sin2a, cps2b, sin2b; - int *zbuf2; - const int *csptr; - - zbuf2 = zbuf1 + 64 - 1; - csptr = cos4sin4tab64; - - /* whole thing should fit in registers - verify that compiler does this */ - for (i = 64 >> 2; i != 0; i--) { - /* cps2 = (cos+sin), sin2 = sin, cms2 = (cos-sin) */ - cps2a = *csptr++; - sin2a = *csptr++; - cps2b = *csptr++; - sin2b = *csptr++; - - ar1 = *(zbuf1 + 0); - ai2 = *(zbuf1 + 1); - ai1 = *(zbuf2 + 0); - ar2 = *(zbuf2 - 1); - - /* gain 2 ints bit from MULSHIFT32 by Q30 - * max per-sample gain (ignoring implicit scaling) = MAX(sin(angle)+cos(angle)) = 1.414 - * i.e. gain 1 GB since worst case is sin(angle) = cos(angle) = 0.707 (Q30), gain 2 from - * extra sign bits, and eat one in adding - */ - t = MULSHIFT32(sin2a, ar1 + ai1); - z2 = MULSHIFT32(cps2a, ai1) - t; - cms2 = cps2a - 2*sin2a; - z1 = MULSHIFT32(cms2, ar1) + t; - *zbuf1++ = z1; /* cos*ar1 + sin*ai1 */ - *zbuf1++ = z2; /* cos*ai1 - sin*ar1 */ - - t = MULSHIFT32(sin2b, ar2 + ai2); - z2 = MULSHIFT32(cps2b, ai2) - t; - cms2 = cps2b - 2*sin2b; - z1 = MULSHIFT32(cms2, ar2) + t; - *zbuf2-- = z2; /* cos*ai2 - sin*ar2 */ - *zbuf2-- = z1; /* cos*ar2 + sin*ai2 */ - } +static void PreMultiply64(int *zbuf1) { + int i, ar1, ai1, ar2, ai2, z1, z2; + int t, cms2, cps2a, sin2a, cps2b, sin2b; + int *zbuf2; + const int *csptr; + + zbuf2 = zbuf1 + 64 - 1; + csptr = cos4sin4tab64; + + /* whole thing should fit in registers - verify that compiler does this */ + for (i = 64 >> 2; i != 0; i--) { + /* cps2 = (cos+sin), sin2 = sin, cms2 = (cos-sin) */ + cps2a = *csptr++; + sin2a = *csptr++; + cps2b = *csptr++; + sin2b = *csptr++; + + ar1 = *(zbuf1 + 0); + ai2 = *(zbuf1 + 1); + ai1 = *(zbuf2 + 0); + ar2 = *(zbuf2 - 1); + + /* gain 2 ints bit from MULSHIFT32 by Q30 + max per-sample gain (ignoring implicit scaling) = MAX(sin(angle)+cos(angle)) = 1.414 + i.e. gain 1 GB since worst case is sin(angle) = cos(angle) = 0.707 (Q30), gain 2 from + extra sign bits, and eat one in adding + */ + t = MULSHIFT32(sin2a, ar1 + ai1); + z2 = MULSHIFT32(cps2a, ai1) - t; + cms2 = cps2a - 2 * sin2a; + z1 = MULSHIFT32(cms2, ar1) + t; + *zbuf1++ = z1; /* cos*ar1 + sin*ai1 */ + *zbuf1++ = z2; /* cos*ai1 - sin*ar1 */ + + t = MULSHIFT32(sin2b, ar2 + ai2); + z2 = MULSHIFT32(cps2b, ai2) - t; + cms2 = cps2b - 2 * sin2b; + z1 = MULSHIFT32(cms2, ar2) + t; + *zbuf2-- = z2; /* cos*ai2 - sin*ar2 */ + *zbuf2-- = z1; /* cos*ar2 + sin*ai2 */ + } } /************************************************************************************** - * Function: PostMultiply64 - * - * Description: post-twiddle stage of 64-point type-IV DCT - * - * Inputs: buffer of 64 samples - * number of output samples to calculate - * - * Outputs: processed samples in same buffer - * - * Return: none - * - * Notes: minimum 1 GB in, 2 GB out, gains 2 int bits - * gbOut = gbIn + 1 - * output is limited to sqrt(2)/2 plus GB in full GB - * nSampsOut is rounded up to next multiple of 4, since we calculate - * 4 samples per loop + Function: PostMultiply64 + + Description: post-twiddle stage of 64-point type-IV DCT + + Inputs: buffer of 64 samples + number of output samples to calculate + + Outputs: processed samples in same buffer + + Return: none + + Notes: minimum 1 GB in, 2 GB out, gains 2 int bits + gbOut = gbIn + 1 + output is limited to sqrt(2)/2 plus GB in full GB + nSampsOut is rounded up to next multiple of 4, since we calculate + 4 samples per loop **************************************************************************************/ -static void PostMultiply64(int *fft1, int nSampsOut) -{ - int i, ar1, ai1, ar2, ai2; - int t, cms2, cps2, sin2; - int *fft2; - const int *csptr; - - csptr = cos1sin1tab64; - fft2 = fft1 + 64 - 1; - - /* load coeffs for first pass - * cps2 = (cos+sin)/2, sin2 = sin/2, cms2 = (cos-sin)/2 - */ - cps2 = *csptr++; - sin2 = *csptr++; - cms2 = cps2 - 2*sin2; - - for (i = (nSampsOut + 3) >> 2; i != 0; i--) { - ar1 = *(fft1 + 0); - ai1 = *(fft1 + 1); - ar2 = *(fft2 - 1); - ai2 = *(fft2 + 0); - - /* gain 2 int bits (multiplying by Q30), max gain = sqrt(2) */ - t = MULSHIFT32(sin2, ar1 + ai1); - *fft2-- = t - MULSHIFT32(cps2, ai1); - *fft1++ = t + MULSHIFT32(cms2, ar1); - - cps2 = *csptr++; - sin2 = *csptr++; - - ai2 = -ai2; - t = MULSHIFT32(sin2, ar2 + ai2); - *fft2-- = t - MULSHIFT32(cps2, ai2); - cms2 = cps2 - 2*sin2; - *fft1++ = t + MULSHIFT32(cms2, ar2); - } +static void PostMultiply64(int *fft1, int nSampsOut) { + int i, ar1, ai1, ar2, ai2; + int t, cms2, cps2, sin2; + int *fft2; + const int *csptr; + + csptr = cos1sin1tab64; + fft2 = fft1 + 64 - 1; + + /* load coeffs for first pass + cps2 = (cos+sin)/2, sin2 = sin/2, cms2 = (cos-sin)/2 + */ + cps2 = *csptr++; + sin2 = *csptr++; + cms2 = cps2 - 2 * sin2; + + for (i = (nSampsOut + 3) >> 2; i != 0; i--) { + ar1 = *(fft1 + 0); + ai1 = *(fft1 + 1); + ar2 = *(fft2 - 1); + ai2 = *(fft2 + 0); + + /* gain 2 int bits (multiplying by Q30), max gain = sqrt(2) */ + t = MULSHIFT32(sin2, ar1 + ai1); + *fft2-- = t - MULSHIFT32(cps2, ai1); + *fft1++ = t + MULSHIFT32(cms2, ar1); + + cps2 = *csptr++; + sin2 = *csptr++; + + ai2 = -ai2; + t = MULSHIFT32(sin2, ar2 + ai2); + *fft2-- = t - MULSHIFT32(cps2, ai2); + cms2 = cps2 - 2 * sin2; + *fft1++ = t + MULSHIFT32(cms2, ar2); + } } /************************************************************************************** - * Function: QMFAnalysisConv - * - * Description: convolution kernel for analysis QMF - * - * Inputs: pointer to coefficient table, reordered for sequential access - * delay buffer of size 32*10 = 320 real-valued PCM samples - * index for delay ring buffer (range = [0, 9]) - * - * Outputs: 64 consecutive 32-bit samples - * - * Return: none - * - * Notes: this is carefully written to be efficient on ARM - * use the assembly code version in sbrqmfak.s when building for ARM! + Function: QMFAnalysisConv + + Description: convolution kernel for analysis QMF + + Inputs: pointer to coefficient table, reordered for sequential access + delay buffer of size 32*10 = 320 real-valued PCM samples + index for delay ring buffer (range = [0, 9]) + + Outputs: 64 consecutive 32-bit samples + + Return: none + + Notes: this is carefully written to be efficient on ARM + use the assembly code version in sbrqmfak.s when building for ARM! **************************************************************************************/ -#if (defined (__arm) && defined (__ARMCC_VERSION)) || (defined (_WIN32) && defined (_WIN32_WCE) && defined (ARM)) || (defined(__GNUC__) && defined(__arm__)) +//TODO - ADD IN .S SOURCES SOMEHOW +#if 0 //(defined (__arm) && defined (__ARMCC_VERSION)) || (defined (_WIN32) && defined (_WIN32_WCE) && defined (ARM)) || (defined(__GNUC__) && defined(__arm__)) #ifdef __cplusplus extern "C" #endif void QMFAnalysisConv(int *cTab, int *delay, int dIdx, int *uBuf); #else -void QMFAnalysisConv(int *cTab, int *delay, int dIdx, int *uBuf) -{ - int k, dOff; - int *cPtr0, *cPtr1; - U64 u64lo, u64hi; - - dOff = dIdx*32 + 31; - cPtr0 = cTab; - cPtr1 = cTab + 33*5 - 1; - - /* special first pass since we need to flip sign to create cTab[384], cTab[512] */ - u64lo.w64 = 0; - u64hi.w64 = 0; - u64lo.w64 = MADD64(u64lo.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64hi.w64 = MADD64(u64hi.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64lo.w64 = MADD64(u64lo.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64hi.w64 = MADD64(u64hi.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64lo.w64 = MADD64(u64lo.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64hi.w64 = MADD64(u64hi.w64, *cPtr1--, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64lo.w64 = MADD64(u64lo.w64, -(*cPtr1--), delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64hi.w64 = MADD64(u64hi.w64, *cPtr1--, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64lo.w64 = MADD64(u64lo.w64, -(*cPtr1--), delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64hi.w64 = MADD64(u64hi.w64, *cPtr1--, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - - uBuf[0] = u64lo.r.hi32; - uBuf[32] = u64hi.r.hi32; - uBuf++; - dOff--; - - /* max gain for any sample in uBuf, after scaling by cTab, ~= 0.99 - * so we can just sum the uBuf values with no overflow problems - */ - for (k = 1; k <= 31; k++) { - u64lo.w64 = 0; - u64hi.w64 = 0; - u64lo.w64 = MADD64(u64lo.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64hi.w64 = MADD64(u64hi.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64lo.w64 = MADD64(u64lo.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64hi.w64 = MADD64(u64hi.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64lo.w64 = MADD64(u64lo.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64hi.w64 = MADD64(u64hi.w64, *cPtr1--, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64lo.w64 = MADD64(u64lo.w64, *cPtr1--, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64hi.w64 = MADD64(u64hi.w64, *cPtr1--, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64lo.w64 = MADD64(u64lo.w64, *cPtr1--, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - u64hi.w64 = MADD64(u64hi.w64, *cPtr1--, delay[dOff]); dOff -= 32; if (dOff < 0) {dOff += 320;} - - uBuf[0] = u64lo.r.hi32; - uBuf[32] = u64hi.r.hi32; - uBuf++; - dOff--; - } +void QMFAnalysisConv(int *cTab, int *delay, int dIdx, int *uBuf) { + int k, dOff; + int *cPtr0, *cPtr1; + U64 u64lo, u64hi; + + dOff = dIdx * 32 + 31; + cPtr0 = cTab; + cPtr1 = cTab + 33 * 5 - 1; + + /* special first pass since we need to flip sign to create cTab[384], cTab[512] */ + u64lo.w64 = 0; + u64hi.w64 = 0; + u64lo.w64 = MADD64(u64lo.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64hi.w64 = MADD64(u64hi.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64lo.w64 = MADD64(u64lo.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64hi.w64 = MADD64(u64hi.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64lo.w64 = MADD64(u64lo.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64hi.w64 = MADD64(u64hi.w64, *cPtr1--, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64lo.w64 = MADD64(u64lo.w64, -(*cPtr1--), delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64hi.w64 = MADD64(u64hi.w64, *cPtr1--, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64lo.w64 = MADD64(u64lo.w64, -(*cPtr1--), delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64hi.w64 = MADD64(u64hi.w64, *cPtr1--, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + + uBuf[0] = u64lo.r.hi32; + uBuf[32] = u64hi.r.hi32; + uBuf++; + dOff--; + + /* max gain for any sample in uBuf, after scaling by cTab, ~= 0.99 + so we can just sum the uBuf values with no overflow problems + */ + for (k = 1; k <= 31; k++) { + u64lo.w64 = 0; + u64hi.w64 = 0; + u64lo.w64 = MADD64(u64lo.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64hi.w64 = MADD64(u64hi.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64lo.w64 = MADD64(u64lo.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64hi.w64 = MADD64(u64hi.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64lo.w64 = MADD64(u64lo.w64, *cPtr0++, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64hi.w64 = MADD64(u64hi.w64, *cPtr1--, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64lo.w64 = MADD64(u64lo.w64, *cPtr1--, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64hi.w64 = MADD64(u64hi.w64, *cPtr1--, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64lo.w64 = MADD64(u64lo.w64, *cPtr1--, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + u64hi.w64 = MADD64(u64hi.w64, *cPtr1--, delay[dOff]); dOff -= 32; if (dOff < 0) { + dOff += 320; + } + + uBuf[0] = u64lo.r.hi32; + uBuf[32] = u64hi.r.hi32; + uBuf++; + dOff--; + } } #endif /************************************************************************************** - * Function: QMFAnalysis - * - * Description: 32-subband analysis QMF (4.6.18.4.1) - * - * Inputs: 32 consecutive samples of decoded 32-bit PCM, format = Q(fBitsIn) - * delay buffer of size 32*10 = 320 PCM samples - * number of fraction bits in input PCM - * index for delay ring buffer (range = [0, 9]) - * number of subbands to calculate (range = [0, 32]) - * - * Outputs: qmfaBands complex subband samples, format = Q(FBITS_OUT_QMFA) - * updated delay buffer - * updated delay index - * - * Return: guard bit mask - * - * Notes: output stored as RE{X0}, IM{X0}, RE{X1}, IM{X1}, ... RE{X31}, IM{X31} - * output stored in int buffer of size 64*2 = 128 - * (zero-filled from XBuf[2*qmfaBands] to XBuf[127]) + Function: QMFAnalysis + + Description: 32-subband analysis QMF (4.6.18.4.1) + + Inputs: 32 consecutive samples of decoded 32-bit PCM, format = Q(fBitsIn) + delay buffer of size 32*10 = 320 PCM samples + number of fraction bits in input PCM + index for delay ring buffer (range = [0, 9]) + number of subbands to calculate (range = [0, 32]) + + Outputs: qmfaBands complex subband samples, format = Q(FBITS_OUT_QMFA) + updated delay buffer + updated delay index + + Return: guard bit mask + + Notes: output stored as RE{X0}, IM{X0}, RE{X1}, IM{X1}, ... RE{X31}, IM{X31} + output stored in int buffer of size 64*2 = 128 + (zero-filled from XBuf[2*qmfaBands] to XBuf[127]) **************************************************************************************/ -int QMFAnalysis(int *inbuf, int *delay, int *XBuf, int fBitsIn, int *delayIdx, int qmfaBands) -{ - int n, y, shift, gbMask; - int *delayPtr, *uBuf, *tBuf; - - /* use XBuf[128] as temp buffer for reordering */ - uBuf = XBuf; /* first 64 samples */ - tBuf = XBuf + 64; /* second 64 samples */ - - /* overwrite oldest PCM with new PCM - * delay[n] has 1 GB after shifting (either << or >>) - */ - delayPtr = delay + (*delayIdx * 32); - if (fBitsIn > FBITS_IN_QMFA) { - shift = MIN(fBitsIn - FBITS_IN_QMFA, 31); - for (n = 32; n != 0; n--) { - y = (*inbuf) >> shift; - inbuf++; - *delayPtr++ = y; - } - } else { - shift = MIN(FBITS_IN_QMFA - fBitsIn, 30); - for (n = 32; n != 0; n--) { - y = *inbuf++; - CLIP_2N_SHIFT30(y, shift); - *delayPtr++ = y; - } - } - - QMFAnalysisConv((int *)cTabA, delay, *delayIdx, uBuf); - - /* uBuf has at least 2 GB right now (1 from clipping to Q(FBITS_IN_QMFA), one from - * the scaling by cTab (MULSHIFT32(*delayPtr--, *cPtr++), with net gain of < 1.0) - * TODO - fuse with QMFAnalysisConv to avoid separate reordering - */ - tBuf[2*0 + 0] = uBuf[0]; - tBuf[2*0 + 1] = uBuf[1]; +int QMFAnalysis(int *inbuf, int *delay, int *XBuf, int fBitsIn, int *delayIdx, int qmfaBands) { + int n, y, shift, gbMask; + int *delayPtr, *uBuf, *tBuf; + + /* use XBuf[128] as temp buffer for reordering */ + uBuf = XBuf; /* first 64 samples */ + tBuf = XBuf + 64; /* second 64 samples */ + + /* overwrite oldest PCM with new PCM + delay[n] has 1 GB after shifting (either << or >>) + */ + delayPtr = delay + (*delayIdx * 32); + if (fBitsIn > FBITS_IN_QMFA) { + shift = MIN(fBitsIn - FBITS_IN_QMFA, 31); + for (n = 32; n != 0; n--) { + y = (*inbuf) >> shift; + inbuf++; + *delayPtr++ = y; + } + } else { + shift = MIN(FBITS_IN_QMFA - fBitsIn, 30); + for (n = 32; n != 0; n--) { + y = *inbuf++; + CLIP_2N_SHIFT30(y, shift); + *delayPtr++ = y; + } + } + + QMFAnalysisConv((int *)cTabA, delay, *delayIdx, uBuf); + + /* uBuf has at least 2 GB right now (1 from clipping to Q(FBITS_IN_QMFA), one from + the scaling by cTab (MULSHIFT32(*delayPtr--, *cPtr++), with net gain of < 1.0) + TODO - fuse with QMFAnalysisConv to avoid separate reordering + */ + tBuf[2 * 0 + 0] = uBuf[0]; + tBuf[2 * 0 + 1] = uBuf[1]; for (n = 1; n < 31; n++) { - tBuf[2*n + 0] = -uBuf[64-n]; - tBuf[2*n + 1] = uBuf[n+1]; + tBuf[2 * n + 0] = -uBuf[64 - n]; + tBuf[2 * n + 1] = uBuf[n + 1]; + } + tBuf[2 * 31 + 1] = uBuf[32]; + tBuf[2 * 31 + 0] = -uBuf[33]; + + /* fast in-place DCT-IV - only need 2*qmfaBands output samples */ + PreMultiply64(tBuf); /* 2 GB in, 3 GB out */ + FFT32C(tBuf); /* 3 GB in, 1 GB out */ + PostMultiply64(tBuf, qmfaBands * 2); /* 1 GB in, 2 GB out */ + + /* TODO - roll into PostMultiply (if enough registers) */ + gbMask = 0; + for (n = 0; n < qmfaBands; n++) { + XBuf[2 * n + 0] = tBuf[ n + 0]; /* implicit scaling of 2 in our output Q format */ + gbMask |= FASTABS(XBuf[2 * n + 0]); + XBuf[2 * n + 1] = -tBuf[63 - n]; + gbMask |= FASTABS(XBuf[2 * n + 1]); + } + + /* fill top section with zeros for HF generation */ + for (; n < 64; n++) { + XBuf[2 * n + 0] = 0; + XBuf[2 * n + 1] = 0; } - tBuf[2*31 + 1] = uBuf[32]; - tBuf[2*31 + 0] = -uBuf[33]; - - /* fast in-place DCT-IV - only need 2*qmfaBands output samples */ - PreMultiply64(tBuf); /* 2 GB in, 3 GB out */ - FFT32C(tBuf); /* 3 GB in, 1 GB out */ - PostMultiply64(tBuf, qmfaBands*2); /* 1 GB in, 2 GB out */ - - /* TODO - roll into PostMultiply (if enough registers) */ - gbMask = 0; - for (n = 0; n < qmfaBands; n++) { - XBuf[2*n+0] = tBuf[ n + 0]; /* implicit scaling of 2 in our output Q format */ - gbMask |= FASTABS(XBuf[2*n+0]); - XBuf[2*n+1] = -tBuf[63 - n]; - gbMask |= FASTABS(XBuf[2*n+1]); - } - - /* fill top section with zeros for HF generation */ - for ( ; n < 64; n++) { - XBuf[2*n+0] = 0; - XBuf[2*n+1] = 0; - } - - *delayIdx = (*delayIdx == NUM_QMF_DELAY_BUFS - 1 ? 0 : *delayIdx + 1); - - /* minimum of 2 GB in output */ - return gbMask; + + *delayIdx = (*delayIdx == NUM_QMF_DELAY_BUFS - 1 ? 0 : *delayIdx + 1); + + /* minimum of 2 GB in output */ + return gbMask; } /* lose FBITS_LOST_DCT4_64 in DCT4, gain 6 for implicit scaling by 1/64, lose 1 for cTab multiply (Q31) */ @@ -378,150 +415,169 @@ int QMFAnalysis(int *inbuf, int *delay, int *XBuf, int fBitsIn, int *delayIdx, i #define RND_VAL (1 << (FBITS_OUT_QMFS-1)) /************************************************************************************** - * Function: QMFSynthesisConv - * - * Description: final convolution kernel for synthesis QMF - * - * Inputs: pointer to coefficient table, reordered for sequential access - * delay buffer of size 64*10 = 640 complex samples (1280 ints) - * index for delay ring buffer (range = [0, 9]) - * number of QMF subbands to process (range = [0, 64]) - * number of channels - * - * Outputs: 64 consecutive 16-bit PCM samples, interleaved by factor of nChans - * - * Return: none - * - * Notes: this is carefully written to be efficient on ARM - * use the assembly code version in sbrqmfsk.s when building for ARM! + Function: QMFSynthesisConv + + Description: final convolution kernel for synthesis QMF + + Inputs: pointer to coefficient table, reordered for sequential access + delay buffer of size 64*10 = 640 complex samples (1280 ints) + index for delay ring buffer (range = [0, 9]) + number of QMF subbands to process (range = [0, 64]) + number of channels + + Outputs: 64 consecutive 16-bit PCM samples, interleaved by factor of nChans + + Return: none + + Notes: this is carefully written to be efficient on ARM + use the assembly code version in sbrqmfsk.s when building for ARM! **************************************************************************************/ -#if (defined (__arm) && defined (__ARMCC_VERSION)) || (defined (_WIN32) && defined (_WIN32_WCE) && defined (ARM)) || (defined(__GNUC__) && defined(__arm__)) +#if 0 //(defined (__arm) && defined (__ARMCC_VERSION)) || (defined (_WIN32) && defined (_WIN32_WCE) && defined (ARM)) || (defined(__GNUC__) && defined(__arm__)) #ifdef __cplusplus extern "C" #endif void QMFSynthesisConv(int *cPtr, int *delay, int dIdx, short *outbuf, int nChans); #else -void QMFSynthesisConv(int *cPtr, int *delay, int dIdx, short *outbuf, int nChans) -{ - int k, dOff0, dOff1; - U64 sum64; - - dOff0 = (dIdx)*128; - dOff1 = dOff0 - 1; - if (dOff1 < 0) - dOff1 += 1280; - - /* scaling note: total gain of coefs (cPtr[0]-cPtr[9] for any k) is < 2.0, so 1 GB in delay values is adequate */ - for (k = 0; k <= 63; k++) { - sum64.w64 = 0; - sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff0]); dOff0 -= 256; if (dOff0 < 0) {dOff0 += 1280;} - sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff1]); dOff1 -= 256; if (dOff1 < 0) {dOff1 += 1280;} - sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff0]); dOff0 -= 256; if (dOff0 < 0) {dOff0 += 1280;} - sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff1]); dOff1 -= 256; if (dOff1 < 0) {dOff1 += 1280;} - sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff0]); dOff0 -= 256; if (dOff0 < 0) {dOff0 += 1280;} - sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff1]); dOff1 -= 256; if (dOff1 < 0) {dOff1 += 1280;} - sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff0]); dOff0 -= 256; if (dOff0 < 0) {dOff0 += 1280;} - sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff1]); dOff1 -= 256; if (dOff1 < 0) {dOff1 += 1280;} - sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff0]); dOff0 -= 256; if (dOff0 < 0) {dOff0 += 1280;} - sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff1]); dOff1 -= 256; if (dOff1 < 0) {dOff1 += 1280;} - - dOff0++; - dOff1--; - *outbuf = CLIPTOSHORT((sum64.r.hi32 + RND_VAL) >> FBITS_OUT_QMFS); - outbuf += nChans; - } +void QMFSynthesisConv(int *cPtr, int *delay, int dIdx, short *outbuf, int nChans) { + int k, dOff0, dOff1; + U64 sum64; + + dOff0 = (dIdx) * 128; + dOff1 = dOff0 - 1; + if (dOff1 < 0) { + dOff1 += 1280; + } + + /* scaling note: total gain of coefs (cPtr[0]-cPtr[9] for any k) is < 2.0, so 1 GB in delay values is adequate */ + for (k = 0; k <= 63; k++) { + sum64.w64 = 0; + sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff0]); dOff0 -= 256; if (dOff0 < 0) { + dOff0 += 1280; + } + sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff1]); dOff1 -= 256; if (dOff1 < 0) { + dOff1 += 1280; + } + sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff0]); dOff0 -= 256; if (dOff0 < 0) { + dOff0 += 1280; + } + sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff1]); dOff1 -= 256; if (dOff1 < 0) { + dOff1 += 1280; + } + sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff0]); dOff0 -= 256; if (dOff0 < 0) { + dOff0 += 1280; + } + sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff1]); dOff1 -= 256; if (dOff1 < 0) { + dOff1 += 1280; + } + sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff0]); dOff0 -= 256; if (dOff0 < 0) { + dOff0 += 1280; + } + sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff1]); dOff1 -= 256; if (dOff1 < 0) { + dOff1 += 1280; + } + sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff0]); dOff0 -= 256; if (dOff0 < 0) { + dOff0 += 1280; + } + sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff1]); dOff1 -= 256; if (dOff1 < 0) { + dOff1 += 1280; + } + + dOff0++; + dOff1--; + *outbuf = CLIPTOSHORT((sum64.r.hi32 + RND_VAL) >> FBITS_OUT_QMFS); + outbuf += nChans; + } } #endif /************************************************************************************** - * Function: QMFSynthesis - * - * Description: 64-subband synthesis QMF (4.6.18.4.2) - * - * Inputs: 64 consecutive complex subband QMF samples, format = Q(FBITS_IN_QMFS) - * delay buffer of size 64*10 = 640 complex samples (1280 ints) - * index for delay ring buffer (range = [0, 9]) - * number of QMF subbands to process (range = [0, 64]) - * number of channels - * - * Outputs: 64 consecutive 16-bit PCM samples, interleaved by factor of nChans - * updated delay buffer - * updated delay index - * - * Return: none - * - * Notes: assumes MIN_GBITS_IN_QMFS guard bits in input, either from - * QMFAnalysis (if upsampling only) or from MapHF (if SBR on) + Function: QMFSynthesis + + Description: 64-subband synthesis QMF (4.6.18.4.2) + + Inputs: 64 consecutive complex subband QMF samples, format = Q(FBITS_IN_QMFS) + delay buffer of size 64*10 = 640 complex samples (1280 ints) + index for delay ring buffer (range = [0, 9]) + number of QMF subbands to process (range = [0, 64]) + number of channels + + Outputs: 64 consecutive 16-bit PCM samples, interleaved by factor of nChans + updated delay buffer + updated delay index + + Return: none + + Notes: assumes MIN_GBITS_IN_QMFS guard bits in input, either from + QMFAnalysis (if upsampling only) or from MapHF (if SBR on) **************************************************************************************/ -void QMFSynthesis(int *inbuf, int *delay, int *delayIdx, int qmfsBands, short *outbuf, int nChans) -{ - int n, a0, a1, b0, b1, dOff0, dOff1, dIdx; - int *tBufLo, *tBufHi; - - dIdx = *delayIdx; - tBufLo = delay + dIdx*128 + 0; - tBufHi = delay + dIdx*128 + 127; - - /* reorder inputs to DCT-IV, only use first qmfsBands (complex) samples - * TODO - fuse with PreMultiply64 to avoid separate reordering steps - */ +void QMFSynthesis(int *inbuf, int *delay, int *delayIdx, int qmfsBands, short *outbuf, int nChans) { + int n, a0, a1, b0, b1, dOff0, dOff1, dIdx; + int *tBufLo, *tBufHi; + + dIdx = *delayIdx; + tBufLo = delay + dIdx * 128 + 0; + tBufHi = delay + dIdx * 128 + 127; + + /* reorder inputs to DCT-IV, only use first qmfsBands (complex) samples + TODO - fuse with PreMultiply64 to avoid separate reordering steps + */ for (n = 0; n < qmfsBands >> 1; n++) { - a0 = *inbuf++; - b0 = *inbuf++; - a1 = *inbuf++; - b1 = *inbuf++; - *tBufLo++ = a0; + a0 = *inbuf++; + b0 = *inbuf++; + a1 = *inbuf++; + b1 = *inbuf++; + *tBufLo++ = a0; *tBufLo++ = a1; *tBufHi-- = b0; *tBufHi-- = b1; } - if (qmfsBands & 0x01) { - a0 = *inbuf++; - b0 = *inbuf++; - *tBufLo++ = a0; + if (qmfsBands & 0x01) { + a0 = *inbuf++; + b0 = *inbuf++; + *tBufLo++ = a0; *tBufHi-- = b0; *tBufLo++ = 0; - *tBufHi-- = 0; - n++; - } - for ( ; n < 32; n++) { - *tBufLo++ = 0; + *tBufHi-- = 0; + n++; + } + for (; n < 32; n++) { + *tBufLo++ = 0; *tBufHi-- = 0; *tBufLo++ = 0; *tBufHi-- = 0; - } - - tBufLo = delay + dIdx*128 + 0; - tBufHi = delay + dIdx*128 + 64; - - /* 2 GB in, 3 GB out */ - PreMultiply64(tBufLo); - PreMultiply64(tBufHi); - - /* 3 GB in, 1 GB out */ - FFT32C(tBufLo); - FFT32C(tBufHi); - - /* 1 GB in, 2 GB out */ - PostMultiply64(tBufLo, 64); - PostMultiply64(tBufHi, 64); - - /* could fuse with PostMultiply64 to avoid separate pass */ - dOff0 = dIdx*128; - dOff1 = dIdx*128 + 64; - for (n = 32; n != 0; n--) { - a0 = (*tBufLo++); - a1 = (*tBufLo++); - b0 = (*tBufHi++); - b1 = -(*tBufHi++); + } - delay[dOff0++] = (b0 - a0); - delay[dOff0++] = (b1 - a1); - delay[dOff1++] = (b0 + a0); - delay[dOff1++] = (b1 + a1); - } + tBufLo = delay + dIdx * 128 + 0; + tBufHi = delay + dIdx * 128 + 64; + + /* 2 GB in, 3 GB out */ + PreMultiply64(tBufLo); + PreMultiply64(tBufHi); + + /* 3 GB in, 1 GB out */ + FFT32C(tBufLo); + FFT32C(tBufHi); + + /* 1 GB in, 2 GB out */ + PostMultiply64(tBufLo, 64); + PostMultiply64(tBufHi, 64); + + /* could fuse with PostMultiply64 to avoid separate pass */ + dOff0 = dIdx * 128; + dOff1 = dIdx * 128 + 64; + for (n = 32; n != 0; n--) { + a0 = (*tBufLo++); + a1 = (*tBufLo++); + b0 = (*tBufHi++); + b1 = -(*tBufHi++); + + delay[dOff0++] = (b0 - a0); + delay[dOff0++] = (b1 - a1); + delay[dOff1++] = (b0 + a0); + delay[dOff1++] = (b1 + a1); + } - QMFSynthesisConv((int *)cTabS, delay, dIdx, outbuf, nChans); + QMFSynthesisConv((int *)cTabS, delay, dIdx, outbuf, nChans); - *delayIdx = (*delayIdx == NUM_QMF_DELAY_BUFS - 1 ? 0 : *delayIdx + 1); + *delayIdx = (*delayIdx == NUM_QMF_DELAY_BUFS - 1 ? 0 : *delayIdx + 1); } diff --git a/src/libhelix-aac/sbrside.c b/src/libhelix-aac/sbrside.c index 6bb49f31..5a5e00fe 100644 --- a/src/libhelix-aac/sbrside.c +++ b/src/libhelix-aac/sbrside.c @@ -1,575 +1,605 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: sbrside.c,v 1.2 2005/05/24 16:01:55 albertofloyd Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: sbrside.c,v 1.2 2005/05/24 16:01:55 albertofloyd Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * sbrside.c - functions for unpacking side info from SBR bitstream + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + sbrside.c - functions for unpacking side info from SBR bitstream **************************************************************************************/ #include "sbr.h" /************************************************************************************** - * Function: GetSampRateIdx - * - * Description: get index of given sample rate - * - * Inputs: sample rate (in Hz) - * - * Outputs: none - * - * Return: index of sample rate (table 1.15 in 14496-3:2001(E)) - * -1 if sample rate not found in table + Function: GetSampRateIdx + + Description: get index of given sample rate + + Inputs: sample rate (in Hz) + + Outputs: none + + Return: index of sample rate (table 1.15 in 14496-3:2001(E)) + -1 if sample rate not found in table **************************************************************************************/ -int GetSampRateIdx(int sampRate) -{ - int idx; +int GetSampRateIdx(int sampRate) { + int idx; - for (idx = 0; idx < NUM_SAMPLE_RATES; idx++) { - if (sampRate == sampRateTab[idx]) - return idx; - } + for (idx = 0; idx < NUM_SAMPLE_RATES; idx++) { + if (sampRate == sampRateTab[idx]) { + return idx; + } + } - return -1; + return -1; } /************************************************************************************** - * Function: UnpackSBRHeader - * - * Description: unpack SBR header (table 4.56) - * - * Inputs: BitStreamInfo struct pointing to start of SBR header - * - * Outputs: initialized SBRHeader struct for this SCE/CPE block - * - * Return: non-zero if frame reset is triggered, zero otherwise + Function: UnpackSBRHeader + + Description: unpack SBR header (table 4.56) + + Inputs: BitStreamInfo struct pointing to start of SBR header + + Outputs: initialized SBRHeader struct for this SCE/CPE block + + Return: non-zero if frame reset is triggered, zero otherwise **************************************************************************************/ -int UnpackSBRHeader(BitStreamInfo *bsi, SBRHeader *sbrHdr) -{ - SBRHeader sbrHdrPrev; - - /* save previous values so we know whether to reset decoder */ - sbrHdrPrev.startFreq = sbrHdr->startFreq; - sbrHdrPrev.stopFreq = sbrHdr->stopFreq; - sbrHdrPrev.freqScale = sbrHdr->freqScale; - sbrHdrPrev.alterScale = sbrHdr->alterScale; - sbrHdrPrev.crossOverBand = sbrHdr->crossOverBand; - sbrHdrPrev.noiseBands = sbrHdr->noiseBands; - - sbrHdr->ampRes = GetBits(bsi, 1); - sbrHdr->startFreq = GetBits(bsi, 4); - sbrHdr->stopFreq = GetBits(bsi, 4); - sbrHdr->crossOverBand = GetBits(bsi, 3); - sbrHdr->resBitsHdr = GetBits(bsi, 2); - sbrHdr->hdrExtra1 = GetBits(bsi, 1); - sbrHdr->hdrExtra2 = GetBits(bsi, 1); - - if (sbrHdr->hdrExtra1) { - sbrHdr->freqScale = GetBits(bsi, 2); - sbrHdr->alterScale = GetBits(bsi, 1); - sbrHdr->noiseBands = GetBits(bsi, 2); - } else { - /* defaults */ - sbrHdr->freqScale = 2; - sbrHdr->alterScale = 1; - sbrHdr->noiseBands = 2; - } - - if (sbrHdr->hdrExtra2) { - sbrHdr->limiterBands = GetBits(bsi, 2); - sbrHdr->limiterGains = GetBits(bsi, 2); - sbrHdr->interpFreq = GetBits(bsi, 1); - sbrHdr->smoothMode = GetBits(bsi, 1); - } else { - /* defaults */ - sbrHdr->limiterBands = 2; - sbrHdr->limiterGains = 2; - sbrHdr->interpFreq = 1; - sbrHdr->smoothMode = 1; - } - sbrHdr->count++; - - /* if any of these have changed from previous frame, reset the SBR module */ - if (sbrHdr->startFreq != sbrHdrPrev.startFreq || sbrHdr->stopFreq != sbrHdrPrev.stopFreq || - sbrHdr->freqScale != sbrHdrPrev.freqScale || sbrHdr->alterScale != sbrHdrPrev.alterScale || - sbrHdr->crossOverBand != sbrHdrPrev.crossOverBand || sbrHdr->noiseBands != sbrHdrPrev.noiseBands - ) - return -1; - else - return 0; +int UnpackSBRHeader(BitStreamInfo *bsi, SBRHeader *sbrHdr) { + SBRHeader sbrHdrPrev; + + /* save previous values so we know whether to reset decoder */ + sbrHdrPrev.startFreq = sbrHdr->startFreq; + sbrHdrPrev.stopFreq = sbrHdr->stopFreq; + sbrHdrPrev.freqScale = sbrHdr->freqScale; + sbrHdrPrev.alterScale = sbrHdr->alterScale; + sbrHdrPrev.crossOverBand = sbrHdr->crossOverBand; + sbrHdrPrev.noiseBands = sbrHdr->noiseBands; + + sbrHdr->ampRes = GetBits(bsi, 1); + sbrHdr->startFreq = GetBits(bsi, 4); + sbrHdr->stopFreq = GetBits(bsi, 4); + sbrHdr->crossOverBand = GetBits(bsi, 3); + sbrHdr->resBitsHdr = GetBits(bsi, 2); + sbrHdr->hdrExtra1 = GetBits(bsi, 1); + sbrHdr->hdrExtra2 = GetBits(bsi, 1); + + if (sbrHdr->hdrExtra1) { + sbrHdr->freqScale = GetBits(bsi, 2); + sbrHdr->alterScale = GetBits(bsi, 1); + sbrHdr->noiseBands = GetBits(bsi, 2); + } else { + /* defaults */ + sbrHdr->freqScale = 2; + sbrHdr->alterScale = 1; + sbrHdr->noiseBands = 2; + } + + if (sbrHdr->hdrExtra2) { + sbrHdr->limiterBands = GetBits(bsi, 2); + sbrHdr->limiterGains = GetBits(bsi, 2); + sbrHdr->interpFreq = GetBits(bsi, 1); + sbrHdr->smoothMode = GetBits(bsi, 1); + } else { + /* defaults */ + sbrHdr->limiterBands = 2; + sbrHdr->limiterGains = 2; + sbrHdr->interpFreq = 1; + sbrHdr->smoothMode = 1; + } + sbrHdr->count++; + + /* if any of these have changed from previous frame, reset the SBR module */ + if (sbrHdr->startFreq != sbrHdrPrev.startFreq || sbrHdr->stopFreq != sbrHdrPrev.stopFreq || + sbrHdr->freqScale != sbrHdrPrev.freqScale || sbrHdr->alterScale != sbrHdrPrev.alterScale || + sbrHdr->crossOverBand != sbrHdrPrev.crossOverBand || sbrHdr->noiseBands != sbrHdrPrev.noiseBands + ) { + return -1; + } else { + return 0; + } } /* cLog2[i] = ceil(log2(i)) (disregard i == 0) */ static const unsigned char cLog2[9] = {0, 0, 1, 2, 2, 3, 3, 3, 3}; /************************************************************************************** - * Function: UnpackSBRGrid - * - * Description: unpack SBR grid (table 4.62) - * - * Inputs: BitStreamInfo struct pointing to start of SBR grid - * initialized SBRHeader struct for this SCE/CPE block - * - * Outputs: initialized SBRGrid struct for this channel - * - * Return: none - **************************************************************************************/ -static void UnpackSBRGrid(BitStreamInfo *bsi, SBRHeader *sbrHdr, SBRGrid *sbrGrid) -{ - int numEnvRaw, env, rel, pBits, border, middleBorder=0; - unsigned char relBordLead[MAX_NUM_ENV], relBordTrail[MAX_NUM_ENV]; - unsigned char relBorder0[3], relBorder1[3], relBorder[3]; - unsigned char numRelBorder0, numRelBorder1, numRelBorder, numRelLead=0, numRelTrail; - unsigned char absBordLead=0, absBordTrail=0, absBorder; - - sbrGrid->ampResFrame = sbrHdr->ampRes; - sbrGrid->frameClass = GetBits(bsi, 2); - switch (sbrGrid->frameClass) { + Function: UnpackSBRGrid - case SBR_GRID_FIXFIX: - numEnvRaw = GetBits(bsi, 2); - sbrGrid->numEnv = (1 << numEnvRaw); - if (sbrGrid->numEnv == 1) - sbrGrid->ampResFrame = 0; + Description: unpack SBR grid (table 4.62) - ASSERT(sbrGrid->numEnv == 1 || sbrGrid->numEnv == 2 || sbrGrid->numEnv == 4); + Inputs: BitStreamInfo struct pointing to start of SBR grid + initialized SBRHeader struct for this SCE/CPE block - sbrGrid->freqRes[0] = GetBits(bsi, 1); - for (env = 1; env < sbrGrid->numEnv; env++) - sbrGrid->freqRes[env] = sbrGrid->freqRes[0]; + Outputs: initialized SBRGrid struct for this channel - absBordLead = 0; - absBordTrail = NUM_TIME_SLOTS; - numRelLead = sbrGrid->numEnv - 1; - numRelTrail = 0; + Return: none + **************************************************************************************/ +static void UnpackSBRGrid(BitStreamInfo *bsi, SBRHeader *sbrHdr, SBRGrid *sbrGrid) { + int numEnvRaw, env, rel, pBits, border, middleBorder = 0; + unsigned char relBordLead[MAX_NUM_ENV], relBordTrail[MAX_NUM_ENV]; + unsigned char relBorder0[3], relBorder1[3], relBorder[3]; + unsigned char numRelBorder0, numRelBorder1, numRelBorder, numRelLead = 0, numRelTrail; + unsigned char absBordLead = 0, absBordTrail = 0, absBorder; + + sbrGrid->ampResFrame = sbrHdr->ampRes; + sbrGrid->frameClass = GetBits(bsi, 2); + switch (sbrGrid->frameClass) { + + case SBR_GRID_FIXFIX: + numEnvRaw = GetBits(bsi, 2); + sbrGrid->numEnv = (1 << numEnvRaw); + if (sbrGrid->numEnv == 1) { + sbrGrid->ampResFrame = 0; + } + + ASSERT(sbrGrid->numEnv == 1 || sbrGrid->numEnv == 2 || sbrGrid->numEnv == 4); + + sbrGrid->freqRes[0] = GetBits(bsi, 1); + for (env = 1; env < sbrGrid->numEnv; env++) { + sbrGrid->freqRes[env] = sbrGrid->freqRes[0]; + } + + absBordLead = 0; + absBordTrail = NUM_TIME_SLOTS; + numRelLead = sbrGrid->numEnv - 1; + numRelTrail = 0; + + /* numEnv = 1, 2, or 4 */ + if (sbrGrid->numEnv == 1) { + border = NUM_TIME_SLOTS / 1; + } else if (sbrGrid->numEnv == 2) { + border = NUM_TIME_SLOTS / 2; + } else { + border = NUM_TIME_SLOTS / 4; + } + + for (rel = 0; rel < numRelLead; rel++) { + relBordLead[rel] = border; + } + + middleBorder = (sbrGrid->numEnv >> 1); + + break; + + case SBR_GRID_FIXVAR: + absBorder = GetBits(bsi, 2) + NUM_TIME_SLOTS; + numRelBorder = GetBits(bsi, 2); + sbrGrid->numEnv = numRelBorder + 1; + for (rel = 0; rel < numRelBorder && rel < 3; rel++) { + relBorder[rel] = 2 * GetBits(bsi, 2) + 2; + } + + pBits = cLog2[sbrGrid->numEnv + 1]; + sbrGrid->pointer = GetBits(bsi, pBits); + + for (env = sbrGrid->numEnv - 1; env >= 0; env--) { + sbrGrid->freqRes[env] = GetBits(bsi, 1); + } + + absBordLead = 0; + absBordTrail = absBorder; + numRelLead = 0; + numRelTrail = numRelBorder; + + for (rel = 0; rel < numRelTrail; rel++) { + relBordTrail[rel] = relBorder[rel]; + } + + if (sbrGrid->pointer > 1) { + middleBorder = sbrGrid->numEnv + 1 - sbrGrid->pointer; + } else { + middleBorder = sbrGrid->numEnv - 1; + } + + break; + + case SBR_GRID_VARFIX: + absBorder = GetBits(bsi, 2); + numRelBorder = GetBits(bsi, 2); + sbrGrid->numEnv = numRelBorder + 1; + for (rel = 0; rel < numRelBorder && rel < 3; rel++) { + relBorder[rel] = 2 * GetBits(bsi, 2) + 2; + } + + pBits = cLog2[sbrGrid->numEnv + 1]; + sbrGrid->pointer = GetBits(bsi, pBits); + + for (env = 0; env < sbrGrid->numEnv && env < MAX_NUM_ENV; env++) { + sbrGrid->freqRes[env] = GetBits(bsi, 1); + } + + absBordLead = absBorder; + absBordTrail = NUM_TIME_SLOTS; + numRelLead = numRelBorder; + numRelTrail = 0; + + for (rel = 0; rel < numRelLead; rel++) { + relBordLead[rel] = relBorder[rel]; + } + + if (sbrGrid->pointer == 0) { + middleBorder = 1; + } else if (sbrGrid->pointer == 1) { + middleBorder = sbrGrid->numEnv - 1; + } else { + middleBorder = sbrGrid->pointer - 1; + } + + break; + + case SBR_GRID_VARVAR: + absBordLead = GetBits(bsi, 2); /* absBorder0 */ + absBordTrail = GetBits(bsi, 2) + NUM_TIME_SLOTS; /* absBorder1 */ + numRelBorder0 = GetBits(bsi, 2); + numRelBorder1 = GetBits(bsi, 2); + + sbrGrid->numEnv = numRelBorder0 + numRelBorder1 + 1; + ASSERT(sbrGrid->numEnv <= 5); + + for (rel = 0; rel < numRelBorder0 && rel < 3; rel++) { + relBorder0[rel] = 2 * GetBits(bsi, 2) + 2; + } + + for (rel = 0; rel < numRelBorder1 && rel < 3; rel++) { + relBorder1[rel] = 2 * GetBits(bsi, 2) + 2; + } + + pBits = cLog2[numRelBorder0 + numRelBorder1 + 2]; + sbrGrid->pointer = GetBits(bsi, pBits); + + for (env = 0; env < sbrGrid->numEnv && env < MAX_NUM_ENV; env++) { + sbrGrid->freqRes[env] = GetBits(bsi, 1); + } + + numRelLead = numRelBorder0; + numRelTrail = numRelBorder1; + + for (rel = 0; rel < numRelLead; rel++) { + relBordLead[rel] = relBorder0[rel]; + } + + for (rel = 0; rel < numRelTrail; rel++) { + relBordTrail[rel] = relBorder1[rel]; + } + + if (sbrGrid->pointer > 1) { + middleBorder = sbrGrid->numEnv + 1 - sbrGrid->pointer; + } else { + middleBorder = sbrGrid->numEnv - 1; + } + + break; + } + + /* build time border vector */ + sbrGrid->envTimeBorder[0] = absBordLead * SAMPLES_PER_SLOT; + + rel = 0; + border = absBordLead; + for (env = 1; env <= numRelLead; env++) { + border += relBordLead[rel++]; + sbrGrid->envTimeBorder[env] = border * SAMPLES_PER_SLOT; + } + + rel = 0; + border = absBordTrail; + for (env = sbrGrid->numEnv - 1; env > numRelLead; env--) { + border -= relBordTrail[rel++]; + sbrGrid->envTimeBorder[env] = border * SAMPLES_PER_SLOT; + } + + sbrGrid->envTimeBorder[sbrGrid->numEnv] = absBordTrail * SAMPLES_PER_SLOT; + + if (sbrGrid->numEnv > 1) { + sbrGrid->numNoiseFloors = 2; + sbrGrid->noiseTimeBorder[0] = sbrGrid->envTimeBorder[0]; + sbrGrid->noiseTimeBorder[1] = sbrGrid->envTimeBorder[middleBorder]; + sbrGrid->noiseTimeBorder[2] = sbrGrid->envTimeBorder[sbrGrid->numEnv]; + } else { + sbrGrid->numNoiseFloors = 1; + sbrGrid->noiseTimeBorder[0] = sbrGrid->envTimeBorder[0]; + sbrGrid->noiseTimeBorder[1] = sbrGrid->envTimeBorder[1]; + } +} + +/************************************************************************************** + Function: UnpackDeltaTimeFreq - /* numEnv = 1, 2, or 4 */ - if (sbrGrid->numEnv == 1) border = NUM_TIME_SLOTS / 1; - else if (sbrGrid->numEnv == 2) border = NUM_TIME_SLOTS / 2; - else border = NUM_TIME_SLOTS / 4; + Description: unpack time/freq flags for delta coding of SBR envelopes (table 4.63) - for (rel = 0; rel < numRelLead; rel++) - relBordLead[rel] = border; + Inputs: BitStreamInfo struct pointing to start of dt/df flags + number of envelopes + number of noise floors - middleBorder = (sbrGrid->numEnv >> 1); + Outputs: delta flags for envelope and noise floors + + Return: none + **************************************************************************************/ +static void UnpackDeltaTimeFreq(BitStreamInfo *bsi, int numEnv, unsigned char *deltaFlagEnv, + int numNoiseFloors, unsigned char *deltaFlagNoise) { + int env, noiseFloor; - break; + for (env = 0; env < numEnv; env++) { + deltaFlagEnv[env] = GetBits(bsi, 1); + } - case SBR_GRID_FIXVAR: - absBorder = GetBits(bsi, 2) + NUM_TIME_SLOTS; - numRelBorder = GetBits(bsi, 2); - sbrGrid->numEnv = numRelBorder + 1; - for (rel = 0; rel < numRelBorder; rel++) - relBorder[rel] = 2*GetBits(bsi, 2) + 2; + for (noiseFloor = 0; noiseFloor < numNoiseFloors; noiseFloor++) { + deltaFlagNoise[noiseFloor] = GetBits(bsi, 1); + } +} - pBits = cLog2[sbrGrid->numEnv + 1]; - sbrGrid->pointer = GetBits(bsi, pBits); +/************************************************************************************** + Function: UnpackInverseFilterMode - for (env = sbrGrid->numEnv - 1; env >= 0; env--) - sbrGrid->freqRes[env] = GetBits(bsi, 1); + Description: unpack invf flags for chirp factor calculation (table 4.64) - absBordLead = 0; - absBordTrail = absBorder; - numRelLead = 0; - numRelTrail = numRelBorder; - - for (rel = 0; rel < numRelTrail; rel++) - relBordTrail[rel] = relBorder[rel]; - - if (sbrGrid->pointer > 1) middleBorder = sbrGrid->numEnv + 1 - sbrGrid->pointer; - else middleBorder = sbrGrid->numEnv - 1; - - break; - - case SBR_GRID_VARFIX: - absBorder = GetBits(bsi, 2); - numRelBorder = GetBits(bsi, 2); - sbrGrid->numEnv = numRelBorder + 1; - for (rel = 0; rel < numRelBorder; rel++) - relBorder[rel] = 2*GetBits(bsi, 2) + 2; - - pBits = cLog2[sbrGrid->numEnv + 1]; - sbrGrid->pointer = GetBits(bsi, pBits); - - for (env = 0; env < sbrGrid->numEnv; env++) - sbrGrid->freqRes[env] = GetBits(bsi, 1); - - absBordLead = absBorder; - absBordTrail = NUM_TIME_SLOTS; - numRelLead = numRelBorder; - numRelTrail = 0; - - for (rel = 0; rel < numRelLead; rel++) - relBordLead[rel] = relBorder[rel]; - - if (sbrGrid->pointer == 0) middleBorder = 1; - else if (sbrGrid->pointer == 1) middleBorder = sbrGrid->numEnv - 1; - else middleBorder = sbrGrid->pointer - 1; - - break; - - case SBR_GRID_VARVAR: - absBordLead = GetBits(bsi, 2); /* absBorder0 */ - absBordTrail = GetBits(bsi, 2) + NUM_TIME_SLOTS; /* absBorder1 */ - numRelBorder0 = GetBits(bsi, 2); - numRelBorder1 = GetBits(bsi, 2); - - sbrGrid->numEnv = numRelBorder0 + numRelBorder1 + 1; - ASSERT(sbrGrid->numEnv <= 5); - - for (rel = 0; rel < numRelBorder0; rel++) - relBorder0[rel] = 2*GetBits(bsi, 2) + 2; + Inputs: BitStreamInfo struct pointing to start of invf flags + number of noise floor bands - for (rel = 0; rel < numRelBorder1; rel++) - relBorder1[rel] = 2*GetBits(bsi, 2) + 2; + Outputs: invf flags for noise floor bands - pBits = cLog2[numRelBorder0 + numRelBorder1 + 2]; - sbrGrid->pointer = GetBits(bsi, pBits); + Return: none + **************************************************************************************/ +static void UnpackInverseFilterMode(BitStreamInfo *bsi, int numNoiseFloorBands, unsigned char *mode) { + int n; - for (env = 0; env < sbrGrid->numEnv; env++) - sbrGrid->freqRes[env] = GetBits(bsi, 1); + for (n = 0; n < numNoiseFloorBands; n++) { + mode[n] = GetBits(bsi, 2); + } +} - numRelLead = numRelBorder0; - numRelTrail = numRelBorder1; +/************************************************************************************** + Function: UnpackSinusoids - for (rel = 0; rel < numRelLead; rel++) - relBordLead[rel] = relBorder0[rel]; + Description: unpack sinusoid (harmonic) flags for each SBR subband (table 4.67) - for (rel = 0; rel < numRelTrail; rel++) - relBordTrail[rel] = relBorder1[rel]; + Inputs: BitStreamInfo struct pointing to start of sinusoid flags + number of high resolution SBR subbands (nHigh) - if (sbrGrid->pointer > 1) middleBorder = sbrGrid->numEnv + 1 - sbrGrid->pointer; - else middleBorder = sbrGrid->numEnv - 1; + Outputs: sinusoid flags for each SBR subband, zero-filled above nHigh - break; - } + Return: none + **************************************************************************************/ +static void UnpackSinusoids(BitStreamInfo *bsi, int nHigh, int addHarmonicFlag, unsigned char *addHarmonic) { + int n; + + n = 0; + if (addHarmonicFlag) { + for (; n < nHigh; n++) { + addHarmonic[n] = GetBits(bsi, 1); + } + } + + /* zero out unused bands */ + for (; n < MAX_QMF_BANDS; n++) { + addHarmonic[n] = 0; + } +} - /* build time border vector */ - sbrGrid->envTimeBorder[0] = absBordLead * SAMPLES_PER_SLOT; +/************************************************************************************** + Function: CopyCouplingGrid - rel = 0; - border = absBordLead; - for (env = 1; env <= numRelLead; env++) { - border += relBordLead[rel++]; - sbrGrid->envTimeBorder[env] = border * SAMPLES_PER_SLOT; - } + Description: copy grid parameters from left to right for channel coupling - rel = 0; - border = absBordTrail; - for (env = sbrGrid->numEnv - 1; env > numRelLead; env--) { - border -= relBordTrail[rel++]; - sbrGrid->envTimeBorder[env] = border * SAMPLES_PER_SLOT; - } + Inputs: initialized SBRGrid struct for left channel - sbrGrid->envTimeBorder[sbrGrid->numEnv] = absBordTrail * SAMPLES_PER_SLOT; + Outputs: initialized SBRGrid struct for right channel - if (sbrGrid->numEnv > 1) { - sbrGrid->numNoiseFloors = 2; - sbrGrid->noiseTimeBorder[0] = sbrGrid->envTimeBorder[0]; - sbrGrid->noiseTimeBorder[1] = sbrGrid->envTimeBorder[middleBorder]; - sbrGrid->noiseTimeBorder[2] = sbrGrid->envTimeBorder[sbrGrid->numEnv]; - } else { - sbrGrid->numNoiseFloors = 1; - sbrGrid->noiseTimeBorder[0] = sbrGrid->envTimeBorder[0]; - sbrGrid->noiseTimeBorder[1] = sbrGrid->envTimeBorder[1]; - } + Return: none + **************************************************************************************/ +static void CopyCouplingGrid(SBRGrid *sbrGridLeft, SBRGrid *sbrGridRight) { + int env, noiseFloor; + + sbrGridRight->frameClass = sbrGridLeft->frameClass; + sbrGridRight->ampResFrame = sbrGridLeft->ampResFrame; + sbrGridRight->pointer = sbrGridLeft->pointer; + + sbrGridRight->numEnv = sbrGridLeft->numEnv; + for (env = 0; env < sbrGridLeft->numEnv; env++) { + sbrGridRight->envTimeBorder[env] = sbrGridLeft->envTimeBorder[env]; + sbrGridRight->freqRes[env] = sbrGridLeft->freqRes[env]; + } + sbrGridRight->envTimeBorder[env] = sbrGridLeft->envTimeBorder[env]; /* borders are [0, numEnv] inclusive */ + + sbrGridRight->numNoiseFloors = sbrGridLeft->numNoiseFloors; + for (noiseFloor = 0; noiseFloor <= sbrGridLeft->numNoiseFloors; noiseFloor++) { + sbrGridRight->noiseTimeBorder[noiseFloor] = sbrGridLeft->noiseTimeBorder[noiseFloor]; + } + + /* numEnvPrev, numNoiseFloorsPrev, freqResPrev are updated in DecodeSBREnvelope() and DecodeSBRNoise() */ } /************************************************************************************** - * Function: UnpackDeltaTimeFreq - * - * Description: unpack time/freq flags for delta coding of SBR envelopes (table 4.63) - * - * Inputs: BitStreamInfo struct pointing to start of dt/df flags - * number of envelopes - * number of noise floors - * - * Outputs: delta flags for envelope and noise floors - * - * Return: none - **************************************************************************************/ -static void UnpackDeltaTimeFreq(BitStreamInfo *bsi, int numEnv, unsigned char *deltaFlagEnv, - int numNoiseFloors, unsigned char *deltaFlagNoise) -{ - int env, noiseFloor; + Function: CopyCouplingInverseFilterMode - for (env = 0; env < numEnv; env++) - deltaFlagEnv[env] = GetBits(bsi, 1); + Description: copy invf flags from left to right for channel coupling - for (noiseFloor = 0; noiseFloor < numNoiseFloors; noiseFloor++) - deltaFlagNoise[noiseFloor] = GetBits(bsi, 1); -} + Inputs: invf flags for left channel + number of noise floor bands -/************************************************************************************** - * Function: UnpackInverseFilterMode - * - * Description: unpack invf flags for chirp factor calculation (table 4.64) - * - * Inputs: BitStreamInfo struct pointing to start of invf flags - * number of noise floor bands - * - * Outputs: invf flags for noise floor bands - * - * Return: none + Outputs: invf flags for right channel + + Return: none **************************************************************************************/ -static void UnpackInverseFilterMode(BitStreamInfo *bsi, int numNoiseFloorBands, unsigned char *mode) -{ - int n; +static void CopyCouplingInverseFilterMode(int numNoiseFloorBands, unsigned char *modeLeft, unsigned char *modeRight) { + int band; - for (n = 0; n < numNoiseFloorBands; n++) - mode[n] = GetBits(bsi, 2); + for (band = 0; band < numNoiseFloorBands; band++) { + modeRight[band] = modeLeft[band]; + } } /************************************************************************************** - * Function: UnpackSinusoids - * - * Description: unpack sinusoid (harmonic) flags for each SBR subband (table 4.67) - * - * Inputs: BitStreamInfo struct pointing to start of sinusoid flags - * number of high resolution SBR subbands (nHigh) - * - * Outputs: sinusoid flags for each SBR subband, zero-filled above nHigh - * - * Return: none - **************************************************************************************/ -static void UnpackSinusoids(BitStreamInfo *bsi, int nHigh, int addHarmonicFlag, unsigned char *addHarmonic) -{ - int n; - - n = 0; - if (addHarmonicFlag) { - for ( ; n < nHigh; n++) - addHarmonic[n] = GetBits(bsi, 1); - } - - /* zero out unused bands */ - for ( ; n < MAX_QMF_BANDS; n++) - addHarmonic[n] = 0; -} + Function: UnpackSBRSingleChannel -/************************************************************************************** - * Function: CopyCouplingGrid - * - * Description: copy grid parameters from left to right for channel coupling - * - * Inputs: initialized SBRGrid struct for left channel - * - * Outputs: initialized SBRGrid struct for right channel - * - * Return: none - **************************************************************************************/ -static void CopyCouplingGrid(SBRGrid *sbrGridLeft, SBRGrid *sbrGridRight) -{ - int env, noiseFloor; - - sbrGridRight->frameClass = sbrGridLeft->frameClass; - sbrGridRight->ampResFrame = sbrGridLeft->ampResFrame; - sbrGridRight->pointer = sbrGridLeft->pointer; - - sbrGridRight->numEnv = sbrGridLeft->numEnv; - for (env = 0; env < sbrGridLeft->numEnv; env++) { - sbrGridRight->envTimeBorder[env] = sbrGridLeft->envTimeBorder[env]; - sbrGridRight->freqRes[env] = sbrGridLeft->freqRes[env]; - } - sbrGridRight->envTimeBorder[env] = sbrGridLeft->envTimeBorder[env]; /* borders are [0, numEnv] inclusive */ - - sbrGridRight->numNoiseFloors = sbrGridLeft->numNoiseFloors; - for (noiseFloor = 0; noiseFloor <= sbrGridLeft->numNoiseFloors; noiseFloor++) - sbrGridRight->noiseTimeBorder[noiseFloor] = sbrGridLeft->noiseTimeBorder[noiseFloor]; - - /* numEnvPrev, numNoiseFloorsPrev, freqResPrev are updated in DecodeSBREnvelope() and DecodeSBRNoise() */ -} + Description: unpack sideband info (grid, delta flags, invf flags, envelope and + noise floor configuration, sinusoids) for a single channel -/************************************************************************************** - * Function: CopyCouplingInverseFilterMode - * - * Description: copy invf flags from left to right for channel coupling - * - * Inputs: invf flags for left channel - * number of noise floor bands - * - * Outputs: invf flags for right channel - * - * Return: none - **************************************************************************************/ -static void CopyCouplingInverseFilterMode(int numNoiseFloorBands, unsigned char *modeLeft, unsigned char *modeRight) -{ - int band; + Inputs: BitStreamInfo struct pointing to start of sideband info + initialized PSInfoSBR struct (after parsing SBR header and building + frequency tables) + base output channel (range = [0, nChans-1]) - for (band = 0; band < numNoiseFloorBands; band++) - modeRight[band] = modeLeft[band]; -} + Outputs: updated PSInfoSBR struct (SBRGrid and SBRChan) -/************************************************************************************** - * Function: UnpackSBRSingleChannel - * - * Description: unpack sideband info (grid, delta flags, invf flags, envelope and - * noise floor configuration, sinusoids) for a single channel - * - * Inputs: BitStreamInfo struct pointing to start of sideband info - * initialized PSInfoSBR struct (after parsing SBR header and building - * frequency tables) - * base output channel (range = [0, nChans-1]) - * - * Outputs: updated PSInfoSBR struct (SBRGrid and SBRChan) - * - * Return: none + Return: none **************************************************************************************/ -void UnpackSBRSingleChannel(BitStreamInfo *bsi, PSInfoSBR *psi, int chBase) -{ - int bitsLeft; - SBRHeader *sbrHdr = &(psi->sbrHdr[chBase]); - SBRGrid *sbrGridL = &(psi->sbrGrid[chBase+0]); - SBRFreq *sbrFreq = &(psi->sbrFreq[chBase]); - SBRChan *sbrChanL = &(psi->sbrChan[chBase+0]); - - psi->dataExtra = GetBits(bsi, 1); - if (psi->dataExtra) - psi->resBitsData = GetBits(bsi, 4); - - UnpackSBRGrid(bsi, sbrHdr, sbrGridL); - UnpackDeltaTimeFreq(bsi, sbrGridL->numEnv, sbrChanL->deltaFlagEnv, sbrGridL->numNoiseFloors, sbrChanL->deltaFlagNoise); - UnpackInverseFilterMode(bsi, sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1]); - - DecodeSBREnvelope(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); - DecodeSBRNoise(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); - - sbrChanL->addHarmonicFlag[1] = GetBits(bsi, 1); - UnpackSinusoids(bsi, sbrFreq->nHigh, sbrChanL->addHarmonicFlag[1], sbrChanL->addHarmonic[1]); - - psi->extendedDataPresent = GetBits(bsi, 1); - if (psi->extendedDataPresent) { - psi->extendedDataSize = GetBits(bsi, 4); - if (psi->extendedDataSize == 15) - psi->extendedDataSize += GetBits(bsi, 8); - - bitsLeft = 8 * psi->extendedDataSize; - - /* get ID, unpack extension info, do whatever is necessary with it... */ - while (bitsLeft > 0) { - GetBits(bsi, 8); - bitsLeft -= 8; - } - } +void UnpackSBRSingleChannel(BitStreamInfo *bsi, PSInfoSBR *psi, int chBase) { + int bitsLeft; + SBRHeader *sbrHdr = &(psi->sbrHdr[chBase]); + SBRGrid *sbrGridL = &(psi->sbrGrid[chBase + 0]); + SBRFreq *sbrFreq = &(psi->sbrFreq[chBase]); + SBRChan *sbrChanL = &(psi->sbrChan[chBase + 0]); + + psi->dataExtra = GetBits(bsi, 1); + if (psi->dataExtra) { + psi->resBitsData = GetBits(bsi, 4); + } + + UnpackSBRGrid(bsi, sbrHdr, sbrGridL); + UnpackDeltaTimeFreq(bsi, sbrGridL->numEnv, sbrChanL->deltaFlagEnv, sbrGridL->numNoiseFloors, sbrChanL->deltaFlagNoise); + UnpackInverseFilterMode(bsi, sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1]); + + DecodeSBREnvelope(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); + DecodeSBRNoise(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); + + sbrChanL->addHarmonicFlag[1] = GetBits(bsi, 1); + UnpackSinusoids(bsi, sbrFreq->nHigh, sbrChanL->addHarmonicFlag[1], sbrChanL->addHarmonic[1]); + + psi->extendedDataPresent = GetBits(bsi, 1); + if (psi->extendedDataPresent) { + psi->extendedDataSize = GetBits(bsi, 4); + if (psi->extendedDataSize == 15) { + psi->extendedDataSize += GetBits(bsi, 8); + } + + bitsLeft = 8 * psi->extendedDataSize; + + /* get ID, unpack extension info, do whatever is necessary with it... */ + while (bitsLeft > 0) { + GetBits(bsi, 8); + bitsLeft -= 8; + } + } } /************************************************************************************** - * Function: UnpackSBRChannelPair - * - * Description: unpack sideband info (grid, delta flags, invf flags, envelope and - * noise floor configuration, sinusoids) for a channel pair - * - * Inputs: BitStreamInfo struct pointing to start of sideband info - * initialized PSInfoSBR struct (after parsing SBR header and building - * frequency tables) - * base output channel (range = [0, nChans-1]) - * - * Outputs: updated PSInfoSBR struct (SBRGrid and SBRChan for both channels) - * - * Return: none + Function: UnpackSBRChannelPair + + Description: unpack sideband info (grid, delta flags, invf flags, envelope and + noise floor configuration, sinusoids) for a channel pair + + Inputs: BitStreamInfo struct pointing to start of sideband info + initialized PSInfoSBR struct (after parsing SBR header and building + frequency tables) + base output channel (range = [0, nChans-1]) + + Outputs: updated PSInfoSBR struct (SBRGrid and SBRChan for both channels) + + Return: none **************************************************************************************/ -void UnpackSBRChannelPair(BitStreamInfo *bsi, PSInfoSBR *psi, int chBase) -{ - int bitsLeft; - SBRHeader *sbrHdr = &(psi->sbrHdr[chBase]); - SBRGrid *sbrGridL = &(psi->sbrGrid[chBase+0]), *sbrGridR = &(psi->sbrGrid[chBase+1]); - SBRFreq *sbrFreq = &(psi->sbrFreq[chBase]); - SBRChan *sbrChanL = &(psi->sbrChan[chBase+0]), *sbrChanR = &(psi->sbrChan[chBase+1]); - - psi->dataExtra = GetBits(bsi, 1); - if (psi->dataExtra) { - psi->resBitsData = GetBits(bsi, 4); - psi->resBitsData = GetBits(bsi, 4); - } - - psi->couplingFlag = GetBits(bsi, 1); - if (psi->couplingFlag) { - UnpackSBRGrid(bsi, sbrHdr, sbrGridL); - CopyCouplingGrid(sbrGridL, sbrGridR); - - UnpackDeltaTimeFreq(bsi, sbrGridL->numEnv, sbrChanL->deltaFlagEnv, sbrGridL->numNoiseFloors, sbrChanL->deltaFlagNoise); - UnpackDeltaTimeFreq(bsi, sbrGridR->numEnv, sbrChanR->deltaFlagEnv, sbrGridR->numNoiseFloors, sbrChanR->deltaFlagNoise); - - UnpackInverseFilterMode(bsi, sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1]); - CopyCouplingInverseFilterMode(sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1], sbrChanR->invfMode[1]); - - DecodeSBREnvelope(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); - DecodeSBRNoise(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); - DecodeSBREnvelope(bsi, psi, sbrGridR, sbrFreq, sbrChanR, 1); - DecodeSBRNoise(bsi, psi, sbrGridR, sbrFreq, sbrChanR, 1); - - /* pass RIGHT sbrChan struct */ - UncoupleSBREnvelope(psi, sbrGridL, sbrFreq, sbrChanR); - UncoupleSBRNoise(psi, sbrGridL, sbrFreq, sbrChanR); - - } else { - UnpackSBRGrid(bsi, sbrHdr, sbrGridL); - UnpackSBRGrid(bsi, sbrHdr, sbrGridR); - UnpackDeltaTimeFreq(bsi, sbrGridL->numEnv, sbrChanL->deltaFlagEnv, sbrGridL->numNoiseFloors, sbrChanL->deltaFlagNoise); - UnpackDeltaTimeFreq(bsi, sbrGridR->numEnv, sbrChanR->deltaFlagEnv, sbrGridR->numNoiseFloors, sbrChanR->deltaFlagNoise); - UnpackInverseFilterMode(bsi, sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1]); - UnpackInverseFilterMode(bsi, sbrFreq->numNoiseFloorBands, sbrChanR->invfMode[1]); - - DecodeSBREnvelope(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); - DecodeSBREnvelope(bsi, psi, sbrGridR, sbrFreq, sbrChanR, 1); - DecodeSBRNoise(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); - DecodeSBRNoise(bsi, psi, sbrGridR, sbrFreq, sbrChanR, 1); - } - - sbrChanL->addHarmonicFlag[1] = GetBits(bsi, 1); - UnpackSinusoids(bsi, sbrFreq->nHigh, sbrChanL->addHarmonicFlag[1], sbrChanL->addHarmonic[1]); - - sbrChanR->addHarmonicFlag[1] = GetBits(bsi, 1); - UnpackSinusoids(bsi, sbrFreq->nHigh, sbrChanR->addHarmonicFlag[1], sbrChanR->addHarmonic[1]); - - psi->extendedDataPresent = GetBits(bsi, 1); - if (psi->extendedDataPresent) { - psi->extendedDataSize = GetBits(bsi, 4); - if (psi->extendedDataSize == 15) - psi->extendedDataSize += GetBits(bsi, 8); - - bitsLeft = 8 * psi->extendedDataSize; - - /* get ID, unpack extension info, do whatever is necessary with it... */ - while (bitsLeft > 0) { - GetBits(bsi, 8); - bitsLeft -= 8; - } - } +void UnpackSBRChannelPair(BitStreamInfo *bsi, PSInfoSBR *psi, int chBase) { + int bitsLeft; + SBRHeader *sbrHdr = &(psi->sbrHdr[chBase]); + SBRGrid *sbrGridL = &(psi->sbrGrid[chBase + 0]), *sbrGridR = &(psi->sbrGrid[chBase + 1]); + SBRFreq *sbrFreq = &(psi->sbrFreq[chBase]); + SBRChan *sbrChanL = &(psi->sbrChan[chBase + 0]), *sbrChanR = &(psi->sbrChan[chBase + 1]); + + psi->dataExtra = GetBits(bsi, 1); + if (psi->dataExtra) { + psi->resBitsData = GetBits(bsi, 4); + psi->resBitsData = GetBits(bsi, 4); + } + + psi->couplingFlag = GetBits(bsi, 1); + if (psi->couplingFlag) { + UnpackSBRGrid(bsi, sbrHdr, sbrGridL); + CopyCouplingGrid(sbrGridL, sbrGridR); + + UnpackDeltaTimeFreq(bsi, sbrGridL->numEnv, sbrChanL->deltaFlagEnv, sbrGridL->numNoiseFloors, sbrChanL->deltaFlagNoise); + UnpackDeltaTimeFreq(bsi, sbrGridR->numEnv, sbrChanR->deltaFlagEnv, sbrGridR->numNoiseFloors, sbrChanR->deltaFlagNoise); + + UnpackInverseFilterMode(bsi, sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1]); + CopyCouplingInverseFilterMode(sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1], sbrChanR->invfMode[1]); + + DecodeSBREnvelope(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); + DecodeSBRNoise(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); + DecodeSBREnvelope(bsi, psi, sbrGridR, sbrFreq, sbrChanR, 1); + DecodeSBRNoise(bsi, psi, sbrGridR, sbrFreq, sbrChanR, 1); + + /* pass RIGHT sbrChan struct */ + UncoupleSBREnvelope(psi, sbrGridL, sbrFreq, sbrChanR); + UncoupleSBRNoise(psi, sbrGridL, sbrFreq, sbrChanR); + + } else { + UnpackSBRGrid(bsi, sbrHdr, sbrGridL); + UnpackSBRGrid(bsi, sbrHdr, sbrGridR); + UnpackDeltaTimeFreq(bsi, sbrGridL->numEnv, sbrChanL->deltaFlagEnv, sbrGridL->numNoiseFloors, sbrChanL->deltaFlagNoise); + UnpackDeltaTimeFreq(bsi, sbrGridR->numEnv, sbrChanR->deltaFlagEnv, sbrGridR->numNoiseFloors, sbrChanR->deltaFlagNoise); + UnpackInverseFilterMode(bsi, sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1]); + UnpackInverseFilterMode(bsi, sbrFreq->numNoiseFloorBands, sbrChanR->invfMode[1]); + + DecodeSBREnvelope(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); + DecodeSBREnvelope(bsi, psi, sbrGridR, sbrFreq, sbrChanR, 1); + DecodeSBRNoise(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); + DecodeSBRNoise(bsi, psi, sbrGridR, sbrFreq, sbrChanR, 1); + } + + sbrChanL->addHarmonicFlag[1] = GetBits(bsi, 1); + UnpackSinusoids(bsi, sbrFreq->nHigh, sbrChanL->addHarmonicFlag[1], sbrChanL->addHarmonic[1]); + + sbrChanR->addHarmonicFlag[1] = GetBits(bsi, 1); + UnpackSinusoids(bsi, sbrFreq->nHigh, sbrChanR->addHarmonicFlag[1], sbrChanR->addHarmonic[1]); + + psi->extendedDataPresent = GetBits(bsi, 1); + if (psi->extendedDataPresent) { + psi->extendedDataSize = GetBits(bsi, 4); + if (psi->extendedDataSize == 15) { + psi->extendedDataSize += GetBits(bsi, 8); + } + + bitsLeft = 8 * psi->extendedDataSize; + + /* get ID, unpack extension info, do whatever is necessary with it... */ + while (bitsLeft > 0) { + GetBits(bsi, 8); + bitsLeft -= 8; + } + } } diff --git a/src/libhelix-aac/sbrtabs.c b/src/libhelix-aac/sbrtabs.c index 01da8617..45763590 100644 --- a/src/libhelix-aac/sbrtabs.c +++ b/src/libhelix-aac/sbrtabs.c @@ -1,53 +1,60 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: sbrtabs.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +#pragma GCC optimize ("O3") +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: sbrtabs.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * sbrtabs.c - platform-independent tables for SBR (global, read-only) + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + sbrtabs.c - platform-independent tables for SBR (global, read-only) **************************************************************************************/ #include "sbr.h" -/* k0Tab[sampRateIdx][k] = k0 = startMin + offset(bs_start_freq) for given sample rate (4.6.18.3.2.1) - * downsampled (single-rate) SBR not currently supported - */ +#if defined(PICO_RP2040) || defined(PICO_RP2350) +#define DPROGMEM __attribute__(( section(".time_critical.data") )) +#else +#define DPROGMEM PROGMEM +#endif + +/* k0Tab[sampRateIdx][k] = k0 = startMin + offset(bs_start_freq) for given sample rate (4.6.18.3.2.1) + downsampled (single-rate) SBR not currently supported +*/ const unsigned char k0Tab[NUM_SAMPLE_RATES_SBR][16] = { { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 23, 27, 31 }, /* 96 kHz */ { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 23, 27, 31 }, /* 88 kHz */ @@ -60,341 +67,345 @@ const unsigned char k0Tab[NUM_SAMPLE_RATES_SBR][16] = { { 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }, /* 16 kHz */ }; -/* k2Tab[sampRateIdx][k] = stopVector(bs_stop_freq) for given sample rate, bs_stop_freq = [0, 13] (4.6.18.3.2.1) - * generated with Matlab script calc_stopvec.m - * downsampled (single-rate) SBR not currently supported - */ +/* k2Tab[sampRateIdx][k] = stopVector(bs_stop_freq) for given sample rate, bs_stop_freq = [0, 13] (4.6.18.3.2.1) + generated with Matlab script calc_stopvec.m + downsampled (single-rate) SBR not currently supported +*/ const unsigned char k2Tab[NUM_SAMPLE_RATES_SBR][14] = { - { 13, 15, 17, 19, 21, 24, 27, 31, 35, 39, 44, 50, 57, 64 }, /* 96 kHz */ - { 15, 17, 19, 21, 23, 26, 29, 33, 37, 41, 46, 51, 57, 64 }, /* 88 kHz */ - { 20, 22, 24, 26, 28, 31, 34, 37, 41, 45, 49, 54, 59, 64 }, /* 64 kHz */ - { 21, 23, 25, 27, 29, 32, 35, 38, 41, 45, 49, 54, 59, 64 }, /* 48 kHz */ - { 23, 25, 27, 29, 31, 34, 37, 40, 43, 47, 51, 55, 59, 64 }, /* 44 kHz */ - { 32, 34, 36, 38, 40, 42, 44, 46, 49, 52, 55, 58, 61, 64 }, /* 32 kHz */ - { 32, 34, 36, 38, 40, 42, 44, 46, 49, 52, 55, 58, 61, 64 }, /* 24 kHz */ - { 35, 36, 38, 40, 42, 44, 46, 48, 50, 52, 55, 58, 61, 64 }, /* 22 kHz */ - { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 62, 64 }, /* 16 kHz */ + { 13, 15, 17, 19, 21, 24, 27, 31, 35, 39, 44, 50, 57, 64 }, /* 96 kHz */ + { 15, 17, 19, 21, 23, 26, 29, 33, 37, 41, 46, 51, 57, 64 }, /* 88 kHz */ + { 20, 22, 24, 26, 28, 31, 34, 37, 41, 45, 49, 54, 59, 64 }, /* 64 kHz */ + { 21, 23, 25, 27, 29, 32, 35, 38, 41, 45, 49, 54, 59, 64 }, /* 48 kHz */ + { 23, 25, 27, 29, 31, 34, 37, 40, 43, 47, 51, 55, 59, 64 }, /* 44 kHz */ + { 32, 34, 36, 38, 40, 42, 44, 46, 49, 52, 55, 58, 61, 64 }, /* 32 kHz */ + { 32, 34, 36, 38, 40, 42, 44, 46, 49, 52, 55, 58, 61, 64 }, /* 24 kHz */ + { 35, 36, 38, 40, 42, 44, 46, 48, 50, 52, 55, 58, 61, 64 }, /* 22 kHz */ + { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 62, 64 }, /* 16 kHz */ }; -/* NINT(2.048E6 / Fs) (figure 4.47) - * downsampled (single-rate) SBR not currently supported - */ -const unsigned char goalSBTab[NUM_SAMPLE_RATES_SBR] = { - 21, 23, 32, 43, 46, 64, 85, 93, 128 +/* NINT(2.048E6 / Fs) (figure 4.47) + downsampled (single-rate) SBR not currently supported +*/ +const unsigned char goalSBTab[NUM_SAMPLE_RATES_SBR] = { + 21, 23, 32, 43, 46, 64, 85, 93, 128 }; const HuffInfo huffTabSBRInfo[10] PROGMEM = { - {19, { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 2, 7, 4, 8, 72, 0}, 0}, - {20, { 0, 2, 2, 2, 2, 2, 1, 3, 3, 2, 4, 4, 4, 3, 2, 5, 6, 13, 15, 46}, 121}, - {17, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 0, 0, 1, 25, 10, 0, 0, 0}, 242}, - {19, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 3, 1, 0, 1, 1, 2, 1, 29, 2, 0}, 291}, - {19, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 1, 2, 5, 1, 4, 2, 3, 34, 0}, 340}, - {20, { 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 1, 2, 3, 4, 4, 7, 10, 16}, 403}, - {14, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 13, 2, 0, 0, 0, 0, 0, 0}, 466}, - {14, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 8, 0, 0, 0, 0, 0, 0}, 491}, - {14, { 1, 1, 1, 1, 1, 1, 0, 2, 0, 1, 1, 0, 51, 2, 0, 0, 0, 0, 0, 0}, 516}, - { 8, { 1, 1, 1, 0, 1, 1, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 579}, + {19, { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 2, 7, 4, 8, 72, 0}, 0}, + {20, { 0, 2, 2, 2, 2, 2, 1, 3, 3, 2, 4, 4, 4, 3, 2, 5, 6, 13, 15, 46}, 121}, + {17, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 0, 0, 1, 25, 10, 0, 0, 0}, 242}, + {19, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 3, 1, 0, 1, 1, 2, 1, 29, 2, 0}, 291}, + {19, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 1, 2, 5, 1, 4, 2, 3, 34, 0}, 340}, + {20, { 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 1, 2, 3, 4, 4, 7, 10, 16}, 403}, + {14, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 13, 2, 0, 0, 0, 0, 0, 0}, 466}, + {14, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 8, 0, 0, 0, 0, 0, 0}, 491}, + {14, { 1, 1, 1, 1, 1, 1, 0, 2, 0, 1, 1, 0, 51, 2, 0, 0, 0, 0, 0, 0}, 516}, + { 8, { 1, 1, 1, 0, 1, 1, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 579}, }; /* Huffman tables from appendix 4.A.6.1, includes offset of -LAV[i] for table i */ +#ifdef ESP8266 const signed int /*short*/ huffTabSBR[604] PROGMEM = { - /* SBR table sbr_tenv15 [121] (signed) */ - 0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7, -8, - -9, 8, -10, 9, -11, 10, -12, -13, 11, -14, 12, -15, -16, 13, -19, -18, - -17, 14, -24, -20, 16, -26, -21, 15, -23, -25, -22, -60, -59, -58, -57, -56, - -55, -54, -53, -52, -51, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, -40, - -39, -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, - /* SBR table sbr_fenv15 [121] (signed) */ - 0, -1, 1, -2, -3, 2, -4, 3, -5, 4, -6, 5, -7, 6, -8, 7, - -9, 8, -10, 9, -11, 10, 11, -12, 12, -13, 13, 14, -14, -15, 15, 16, - 17, -16, -17, -18, -19, 18, 19, -20, -21, 20, 21, -24, -23, -22, -26, -28, - 22, 23, 25, -41, -25, 26, 27, -30, -27, 24, 28, 44, -51, -46, -44, -43, - -37, -33, -31, -29, 30, 37, 42, 47, 48, -60, -59, -58, -57, -56, -55, -54, - -53, -52, -50, -49, -48, -47, -45, -42, -40, -39, -38, -36, -35, -34, -32, 29, - 31, 32, 33, 34, 35, 36, 38, 39, 40, 41, 43, 45, 46, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, - /* SBR table sbr_tenv15b [49] (signed) */ - 0, 1, -1, 2, -2, 3, -3, 4, -4, -5, 5, -6, 6, 7, -7, 8, - -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, - -8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, - /* SBR table sbr_fenv15b [49] (signed) */ - 0, -1, 1, -2, 2, 3, -3, -4, 4, -5, 5, -6, 6, -7, 7, 8, - -9, -8, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, - -10, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, - /* SBR table sbr_tenv30 [63] (signed) */ - 0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, -7, 6, -8, 7, - -9, -10, 8, 9, 10, -13, -11, -12, -14, 11, 12, -31, -30, -29, -28, -27, - -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - /* SBR table sbr_fenv30 [63] (signed) */ - 0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7, -8, - 8, 9, -9, -10, 10, 11, -11, -12, 12, 13, -13, -15, 14, 15, -14, 18, - -18, -24, -19, 16, 17, -22, -21, -16, 20, 21, 22, 25, -23, -20, 24, -31, - -30, -29, -28, -27, -26, -25, -17, 19, 23, 26, 27, 28, 29, 30, 31, - /* SBR table sbr_tenv30b [25] (signed) */ - 0, 1, -1, -2, 2, 3, -3, -4, 4, -5, -12, -11, -10, -9, -8, -7, - -6, 5, 6, 7, 8, 9, 10, 11, 12, - /* SBR table sbr_fenv30b [25] (signed) */ - 0, -1, 1, -2, 2, 3, -3, -4, 4, -5, 5, 6, -12, -11, -10, -9, - -8, -7, -6, 7, 8, 9, 10, 11, 12, - /* SBR table sbr_tnoise30 [63] (signed) */ - 0, 1, -1, -2, 2, -3, 3, -4, 4, -5, 5, 11, -31, -30, -29, -28, - -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, - -11, -10, -9, -8, -7, -6, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - /* SBR table sbr_tnoise30b [25] (signed) */ - 0, -1, 1, -2, 2, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, +#else +const signed short huffTabSBR[604] PROGMEM = { +#endif + /* SBR table sbr_tenv15 [121] (signed) */ + 0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7, -8, + -9, 8, -10, 9, -11, 10, -12, -13, 11, -14, 12, -15, -16, 13, -19, -18, + -17, 14, -24, -20, 16, -26, -21, 15, -23, -25, -22, -60, -59, -58, -57, -56, + -55, -54, -53, -52, -51, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, -40, + -39, -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, + /* SBR table sbr_fenv15 [121] (signed) */ + 0, -1, 1, -2, -3, 2, -4, 3, -5, 4, -6, 5, -7, 6, -8, 7, + -9, 8, -10, 9, -11, 10, 11, -12, 12, -13, 13, 14, -14, -15, 15, 16, + 17, -16, -17, -18, -19, 18, 19, -20, -21, 20, 21, -24, -23, -22, -26, -28, + 22, 23, 25, -41, -25, 26, 27, -30, -27, 24, 28, 44, -51, -46, -44, -43, + -37, -33, -31, -29, 30, 37, 42, 47, 48, -60, -59, -58, -57, -56, -55, -54, + -53, -52, -50, -49, -48, -47, -45, -42, -40, -39, -38, -36, -35, -34, -32, 29, + 31, 32, 33, 34, 35, 36, 38, 39, 40, 41, 43, 45, 46, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, + /* SBR table sbr_tenv15b [49] (signed) */ + 0, 1, -1, 2, -2, 3, -3, 4, -4, -5, 5, -6, 6, 7, -7, 8, + -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, + -8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, + /* SBR table sbr_fenv15b [49] (signed) */ + 0, -1, 1, -2, 2, 3, -3, -4, 4, -5, 5, -6, 6, -7, 7, 8, + -9, -8, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, + -10, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, + /* SBR table sbr_tenv30 [63] (signed) */ + 0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, -7, 6, -8, 7, + -9, -10, 8, 9, 10, -13, -11, -12, -14, 11, 12, -31, -30, -29, -28, -27, + -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + /* SBR table sbr_fenv30 [63] (signed) */ + 0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7, -8, + 8, 9, -9, -10, 10, 11, -11, -12, 12, 13, -13, -15, 14, 15, -14, 18, + -18, -24, -19, 16, 17, -22, -21, -16, 20, 21, 22, 25, -23, -20, 24, -31, + -30, -29, -28, -27, -26, -25, -17, 19, 23, 26, 27, 28, 29, 30, 31, + /* SBR table sbr_tenv30b [25] (signed) */ + 0, 1, -1, -2, 2, 3, -3, -4, 4, -5, -12, -11, -10, -9, -8, -7, + -6, 5, 6, 7, 8, 9, 10, 11, 12, + /* SBR table sbr_fenv30b [25] (signed) */ + 0, -1, 1, -2, 2, 3, -3, -4, 4, -5, 5, 6, -12, -11, -10, -9, + -8, -7, -6, 7, 8, 9, 10, 11, 12, + /* SBR table sbr_tnoise30 [63] (signed) */ + 0, 1, -1, -2, 2, -3, 3, -4, 4, -5, 5, 11, -31, -30, -29, -28, + -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, + -11, -10, -9, -8, -7, -6, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + /* SBR table sbr_tnoise30b [25] (signed) */ + 0, -1, 1, -2, 2, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, }; /* log2Tab[x] = floor(log2(x)), format = Q28 */ const int log2Tab[65] PROGMEM = { - 0x00000000, 0x00000000, 0x10000000, 0x195c01a3, 0x20000000, 0x25269e12, 0x295c01a3, 0x2ceaecfe, - 0x30000000, 0x32b80347, 0x35269e12, 0x3759d4f8, 0x395c01a3, 0x3b350047, 0x3ceaecfe, 0x3e829fb6, - 0x40000000, 0x41663f6f, 0x42b80347, 0x43f782d7, 0x45269e12, 0x4646eea2, 0x4759d4f8, 0x48608280, - 0x495c01a3, 0x4a4d3c25, 0x4b350047, 0x4c1404ea, 0x4ceaecfe, 0x4dba4a47, 0x4e829fb6, 0x4f446359, - 0x50000000, 0x50b5d69b, 0x51663f6f, 0x52118b11, 0x52b80347, 0x5359ebc5, 0x53f782d7, 0x549101ea, - 0x55269e12, 0x55b88873, 0x5646eea2, 0x56d1fafd, 0x5759d4f8, 0x57dea15a, 0x58608280, 0x58df988f, - 0x595c01a3, 0x59d5d9fd, 0x5a4d3c25, 0x5ac24113, 0x5b350047, 0x5ba58feb, 0x5c1404ea, 0x5c80730b, - 0x5ceaecfe, 0x5d53847a, 0x5dba4a47, 0x5e1f4e51, 0x5e829fb6, 0x5ee44cd5, 0x5f446359, 0x5fa2f045, - 0x60000000 + 0x00000000, 0x00000000, 0x10000000, 0x195c01a3, 0x20000000, 0x25269e12, 0x295c01a3, 0x2ceaecfe, + 0x30000000, 0x32b80347, 0x35269e12, 0x3759d4f8, 0x395c01a3, 0x3b350047, 0x3ceaecfe, 0x3e829fb6, + 0x40000000, 0x41663f6f, 0x42b80347, 0x43f782d7, 0x45269e12, 0x4646eea2, 0x4759d4f8, 0x48608280, + 0x495c01a3, 0x4a4d3c25, 0x4b350047, 0x4c1404ea, 0x4ceaecfe, 0x4dba4a47, 0x4e829fb6, 0x4f446359, + 0x50000000, 0x50b5d69b, 0x51663f6f, 0x52118b11, 0x52b80347, 0x5359ebc5, 0x53f782d7, 0x549101ea, + 0x55269e12, 0x55b88873, 0x5646eea2, 0x56d1fafd, 0x5759d4f8, 0x57dea15a, 0x58608280, 0x58df988f, + 0x595c01a3, 0x59d5d9fd, 0x5a4d3c25, 0x5ac24113, 0x5b350047, 0x5ba58feb, 0x5c1404ea, 0x5c80730b, + 0x5ceaecfe, 0x5d53847a, 0x5dba4a47, 0x5e1f4e51, 0x5e829fb6, 0x5ee44cd5, 0x5f446359, 0x5fa2f045, + 0x60000000 }; -/* coefficient table 4.A.87, format = Q31 - * reordered as: - * cTab[0], cTab[64], cTab[128], cTab[192], cTab[256], - * cTab[2], cTab[66], cTab[130], cTab[194], cTab[258], - * ... - * cTab[64], cTab[128], cTab[192], cTab[256], cTab[320] - * - * NOTE: cTab[1, 2, ... , 318, 319] = cTab[639, 638, ... 322, 321] - * except cTab[384] = -cTab[256], cTab[512] = -cTab[128] - */ +/* coefficient table 4.A.87, format = Q31 + reordered as: + cTab[0], cTab[64], cTab[128], cTab[192], cTab[256], + cTab[2], cTab[66], cTab[130], cTab[194], cTab[258], + ... + cTab[64], cTab[128], cTab[192], cTab[256], cTab[320] + + NOTE: cTab[1, 2, ... , 318, 319] = cTab[639, 638, ... 322, 321] + except cTab[384] = -cTab[256], cTab[512] = -cTab[128] +*/ const int cTabA[165] PROGMEM = { - 0x00000000, 0x0055dba1, 0x01b2e41d, 0x09015651, 0x2e3a7532, 0xffed978a, 0x006090c4, 0x01fd3ba0, 0x08a24899, 0x311af3a4, - 0xfff0065d, 0x006b47fa, 0x024bf7a1, 0x082f552e, 0x33ff670e, 0xffef7b8b, 0x0075fded, 0x029e35b4, 0x07a8127d, 0x36e69691, - 0xffee1650, 0x00807994, 0x02f3e48d, 0x070bbf58, 0x39ce0477, 0xffecc31b, 0x008a7dd7, 0x034d01f0, 0x06593912, 0x3cb41219, - 0xffeb50b2, 0x009424c6, 0x03a966bb, 0x0590a67d, 0x3f962fb8, 0xffe9ca76, 0x009d10bf, 0x04083fec, 0x04b0adcb, 0x4272a385, - 0xffe88ba8, 0x00a520bb, 0x04694101, 0x03b8f8dc, 0x4547daea, 0xffe79e16, 0x00abe79e, 0x04cc2fcf, 0x02a99097, 0x4812f848, - 0xffe6d466, 0x00b1978d, 0x05303f87, 0x01816e06, 0x4ad237a2, 0xffe65416, 0x00b5c867, 0x05950122, 0x0040c496, 0x4d83976c, - 0xffe66dd0, 0x00b8394b, 0x05f9c051, 0xfee723c6, 0x5024d70e, 0xffe69423, 0x00b8c6b0, 0x065dd56a, 0xfd7475d8, 0x52b449de, - 0xffe75361, 0x00b73ab0, 0x06c0f0c0, 0xfbe8f5bd, 0x552f8ff7, 0xffe85b4b, 0x00b36acd, 0x0721bf22, 0xfa44a069, 0x579505f5, - 0xffea353a, 0x00acbd2f, 0x077fedb3, 0xf887507c, 0x59e2f69e, 0xffec8409, 0x00a3508f, 0x07da2b7f, 0xf6b1f3c3, 0x5c16d0ae, - 0xffef2395, 0x0096dcc2, 0x08303897, 0xf4c473c6, 0x5e2f6367, 0xfff294c3, 0x00872c63, 0x0880ffdd, 0xf2bf6ea4, 0x602b0c7f, - 0xfff681d6, 0x007400b8, 0x08cb4e23, 0xf0a3959f, 0x6207f220, 0xfffb42b0, 0x005d36df, 0x090ec1fc, 0xee71b2fe, 0x63c45243, - 0x00007134, 0x00426f36, 0x0949eaac, 0xec2a3f5f, 0x655f63f2, 0x0006b1cf, 0x0023b989, 0x097c1ee8, 0xe9cea84a, 0x66d76725, - 0x000d31b5, 0x0000e790, 0x09a3e163, 0xe75f8bb8, 0x682b39a4, 0x001471f8, 0xffda17f2, 0x09c0e59f, 0xe4de0cb0, 0x6959709d, - 0x001c3549, 0xffaea5d6, 0x09d19ca9, 0xe24b8f66, 0x6a619c5e, 0x0024dd50, 0xff7ee3f1, 0x09d5560b, 0xdfa93ab5, 0x6b42a864, - 0x002d8e42, 0xff4aabc8, 0x09caeb0f, 0xdcf898fb, 0x6bfbdd98, 0x003745f9, 0xff120d70, 0x09b18a1d, 0xda3b176a, 0x6c8c4c7a, - 0x004103f4, 0xfed4bec3, 0x09881dc5, 0xd7722f04, 0x6cf4073e, 0x004b6c46, 0xfe933dc0, 0x094d7ec2, 0xd49fd55f, 0x6d32730f, - 0x0055dba1, 0x01b2e41d, 0x09015651, 0x2e3a7532, 0x6d474e1d, + 0x00000000, 0x0055dba1, 0x01b2e41d, 0x09015651, 0x2e3a7532, 0xffed978a, 0x006090c4, 0x01fd3ba0, 0x08a24899, 0x311af3a4, + 0xfff0065d, 0x006b47fa, 0x024bf7a1, 0x082f552e, 0x33ff670e, 0xffef7b8b, 0x0075fded, 0x029e35b4, 0x07a8127d, 0x36e69691, + 0xffee1650, 0x00807994, 0x02f3e48d, 0x070bbf58, 0x39ce0477, 0xffecc31b, 0x008a7dd7, 0x034d01f0, 0x06593912, 0x3cb41219, + 0xffeb50b2, 0x009424c6, 0x03a966bb, 0x0590a67d, 0x3f962fb8, 0xffe9ca76, 0x009d10bf, 0x04083fec, 0x04b0adcb, 0x4272a385, + 0xffe88ba8, 0x00a520bb, 0x04694101, 0x03b8f8dc, 0x4547daea, 0xffe79e16, 0x00abe79e, 0x04cc2fcf, 0x02a99097, 0x4812f848, + 0xffe6d466, 0x00b1978d, 0x05303f87, 0x01816e06, 0x4ad237a2, 0xffe65416, 0x00b5c867, 0x05950122, 0x0040c496, 0x4d83976c, + 0xffe66dd0, 0x00b8394b, 0x05f9c051, 0xfee723c6, 0x5024d70e, 0xffe69423, 0x00b8c6b0, 0x065dd56a, 0xfd7475d8, 0x52b449de, + 0xffe75361, 0x00b73ab0, 0x06c0f0c0, 0xfbe8f5bd, 0x552f8ff7, 0xffe85b4b, 0x00b36acd, 0x0721bf22, 0xfa44a069, 0x579505f5, + 0xffea353a, 0x00acbd2f, 0x077fedb3, 0xf887507c, 0x59e2f69e, 0xffec8409, 0x00a3508f, 0x07da2b7f, 0xf6b1f3c3, 0x5c16d0ae, + 0xffef2395, 0x0096dcc2, 0x08303897, 0xf4c473c6, 0x5e2f6367, 0xfff294c3, 0x00872c63, 0x0880ffdd, 0xf2bf6ea4, 0x602b0c7f, + 0xfff681d6, 0x007400b8, 0x08cb4e23, 0xf0a3959f, 0x6207f220, 0xfffb42b0, 0x005d36df, 0x090ec1fc, 0xee71b2fe, 0x63c45243, + 0x00007134, 0x00426f36, 0x0949eaac, 0xec2a3f5f, 0x655f63f2, 0x0006b1cf, 0x0023b989, 0x097c1ee8, 0xe9cea84a, 0x66d76725, + 0x000d31b5, 0x0000e790, 0x09a3e163, 0xe75f8bb8, 0x682b39a4, 0x001471f8, 0xffda17f2, 0x09c0e59f, 0xe4de0cb0, 0x6959709d, + 0x001c3549, 0xffaea5d6, 0x09d19ca9, 0xe24b8f66, 0x6a619c5e, 0x0024dd50, 0xff7ee3f1, 0x09d5560b, 0xdfa93ab5, 0x6b42a864, + 0x002d8e42, 0xff4aabc8, 0x09caeb0f, 0xdcf898fb, 0x6bfbdd98, 0x003745f9, 0xff120d70, 0x09b18a1d, 0xda3b176a, 0x6c8c4c7a, + 0x004103f4, 0xfed4bec3, 0x09881dc5, 0xd7722f04, 0x6cf4073e, 0x004b6c46, 0xfe933dc0, 0x094d7ec2, 0xd49fd55f, 0x6d32730f, + 0x0055dba1, 0x01b2e41d, 0x09015651, 0x2e3a7532, 0x6d474e1d, }; -/* coefficient table 4.A.87, format = Q31 - * reordered as cTab[0], cTab[64], cTab[128], ... cTab[576], cTab[1], cTab[65], cTab[129], ... cTab[639] - * keeping full table (not using symmetry) to allow sequential access in synth filter inner loop - * format = Q31 - */ +/* coefficient table 4.A.87, format = Q31 + reordered as cTab[0], cTab[64], cTab[128], ... cTab[576], cTab[1], cTab[65], cTab[129], ... cTab[639] + keeping full table (not using symmetry) to allow sequential access in synth filter inner loop + format = Q31 +*/ const int cTabS[640] PROGMEM = { - 0x00000000, 0x0055dba1, 0x01b2e41d, 0x09015651, 0x2e3a7532, 0x6d474e1d, 0xd1c58ace, 0x09015651, 0xfe4d1be3, 0x0055dba1, - 0xffede50e, 0x005b5371, 0x01d78bfc, 0x08d3e41b, 0x2faa221c, 0x6d41d963, 0xd3337b3d, 0x09299ead, 0xfe70b8d1, 0x0050b177, - 0xffed978a, 0x006090c4, 0x01fd3ba0, 0x08a24899, 0x311af3a4, 0x6d32730f, 0xd49fd55f, 0x094d7ec2, 0xfe933dc0, 0x004b6c46, - 0xffefc9b9, 0x0065fde5, 0x02244a24, 0x086b1eeb, 0x328cc6f0, 0x6d18520e, 0xd60a46e5, 0x096d0e21, 0xfeb48d0d, 0x00465348, - 0xfff0065d, 0x006b47fa, 0x024bf7a1, 0x082f552e, 0x33ff670e, 0x6cf4073e, 0xd7722f04, 0x09881dc5, 0xfed4bec3, 0x004103f4, - 0xffeff6ca, 0x0070c8a5, 0x0274ba43, 0x07ee507c, 0x3572ec70, 0x6cc59bab, 0xd8d7f21f, 0x099ec3dc, 0xfef3f6ab, 0x003c1fa4, - 0xffef7b8b, 0x0075fded, 0x029e35b4, 0x07a8127d, 0x36e69691, 0x6c8c4c7a, 0xda3b176a, 0x09b18a1d, 0xff120d70, 0x003745f9, - 0xffeedfa4, 0x007b3875, 0x02c89901, 0x075ca90c, 0x385a49c4, 0x6c492217, 0xdb9b5b12, 0x09c018ce, 0xff2ef725, 0x00329ab6, - 0xffee1650, 0x00807994, 0x02f3e48d, 0x070bbf58, 0x39ce0477, 0x6bfbdd98, 0xdcf898fb, 0x09caeb0f, 0xff4aabc8, 0x002d8e42, - 0xffed651d, 0x0085c217, 0x03201116, 0x06b559c3, 0x3b415115, 0x6ba4629f, 0xde529086, 0x09d1fa23, 0xff6542d1, 0x00293718, - 0xffecc31b, 0x008a7dd7, 0x034d01f0, 0x06593912, 0x3cb41219, 0x6b42a864, 0xdfa93ab5, 0x09d5560b, 0xff7ee3f1, 0x0024dd50, - 0xffebe77b, 0x008f4bfc, 0x037ad438, 0x05f7fb90, 0x3e25b17e, 0x6ad73e8d, 0xe0fc421e, 0x09d52709, 0xff975c01, 0x002064f8, - 0xffeb50b2, 0x009424c6, 0x03a966bb, 0x0590a67d, 0x3f962fb8, 0x6a619c5e, 0xe24b8f66, 0x09d19ca9, 0xffaea5d6, 0x001c3549, - 0xffea9192, 0x0098b855, 0x03d8afe6, 0x05237f9d, 0x41058bc6, 0x69e29784, 0xe396a45d, 0x09cab9f2, 0xffc4e365, 0x0018703f, - 0xffe9ca76, 0x009d10bf, 0x04083fec, 0x04b0adcb, 0x4272a385, 0x6959709d, 0xe4de0cb0, 0x09c0e59f, 0xffda17f2, 0x001471f8, - 0xffe940f4, 0x00a1039c, 0x043889c6, 0x0437fb0a, 0x43de620a, 0x68c7269b, 0xe620c476, 0x09b3d77f, 0xffee183b, 0x0010bc63, - 0xffe88ba8, 0x00a520bb, 0x04694101, 0x03b8f8dc, 0x4547daea, 0x682b39a4, 0xe75f8bb8, 0x09a3e163, 0x0000e790, 0x000d31b5, - 0xffe83a07, 0x00a8739d, 0x049aa82f, 0x03343533, 0x46aea856, 0x6785c24d, 0xe89971b7, 0x099140a7, 0x00131c75, 0x0009aa3f, - 0xffe79e16, 0x00abe79e, 0x04cc2fcf, 0x02a99097, 0x4812f848, 0x66d76725, 0xe9cea84a, 0x097c1ee8, 0x0023b989, 0x0006b1cf, - 0xffe7746e, 0x00af374c, 0x04fe20be, 0x02186a91, 0x4973fef1, 0x661fd6b8, 0xeafee7f1, 0x0963ed46, 0x0033b927, 0x00039609, - 0xffe6d466, 0x00b1978d, 0x05303f87, 0x01816e06, 0x4ad237a2, 0x655f63f2, 0xec2a3f5f, 0x0949eaac, 0x00426f36, 0x00007134, - 0xffe6afee, 0x00b3d15c, 0x05626209, 0x00e42fa2, 0x4c2ca3df, 0x64964063, 0xed50a31d, 0x092d7970, 0x00504f41, 0xfffdfa25, - 0xffe65416, 0x00b5c867, 0x05950122, 0x0040c496, 0x4d83976c, 0x63c45243, 0xee71b2fe, 0x090ec1fc, 0x005d36df, 0xfffb42b0, - 0xffe681c6, 0x00b74c37, 0x05c76fed, 0xff96db90, 0x4ed62be3, 0x62ea6474, 0xef8d4d7b, 0x08edfeaa, 0x006928a0, 0xfff91fca, - 0xffe66dd0, 0x00b8394b, 0x05f9c051, 0xfee723c6, 0x5024d70e, 0x6207f220, 0xf0a3959f, 0x08cb4e23, 0x007400b8, 0xfff681d6, - 0xffe66fac, 0x00b8fe0d, 0x062bf5ec, 0xfe310657, 0x516eefb9, 0x611d58a3, 0xf1b461ab, 0x08a75da4, 0x007e0393, 0xfff48700, - 0xffe69423, 0x00b8c6b0, 0x065dd56a, 0xfd7475d8, 0x52b449de, 0x602b0c7f, 0xf2bf6ea4, 0x0880ffdd, 0x00872c63, 0xfff294c3, - 0xffe6fed4, 0x00b85f70, 0x068f8b44, 0xfcb1d740, 0x53f495aa, 0x5f30ff5f, 0xf3c4e887, 0x08594887, 0x008f87aa, 0xfff0e7ef, - 0xffe75361, 0x00b73ab0, 0x06c0f0c0, 0xfbe8f5bd, 0x552f8ff7, 0x5e2f6367, 0xf4c473c6, 0x08303897, 0x0096dcc2, 0xffef2395, - 0xffe80414, 0x00b58c8c, 0x06f1825d, 0xfb19b7bd, 0x56654bdd, 0x5d26be9b, 0xf5be0fa9, 0x08061671, 0x009da526, 0xffedc418, - 0xffe85b4b, 0x00b36acd, 0x0721bf22, 0xfa44a069, 0x579505f5, 0x5c16d0ae, 0xf6b1f3c3, 0x07da2b7f, 0x00a3508f, 0xffec8409, - 0xffe954d0, 0x00b06b68, 0x075112a2, 0xf96916f5, 0x58befacd, 0x5b001db8, 0xf79fa13a, 0x07ad8c26, 0x00a85e94, 0xffeb3849, - 0xffea353a, 0x00acbd2f, 0x077fedb3, 0xf887507c, 0x59e2f69e, 0x59e2f69e, 0xf887507c, 0x077fedb3, 0x00acbd2f, 0xffea353a, - 0xffeb3849, 0x00a85e94, 0x07ad8c26, 0xf79fa13a, 0x5b001db8, 0x58befacd, 0xf96916f5, 0x075112a2, 0x00b06b68, 0xffe954d0, - 0xffec8409, 0x00a3508f, 0x07da2b7f, 0xf6b1f3c3, 0x5c16d0ae, 0x579505f5, 0xfa44a069, 0x0721bf22, 0x00b36acd, 0xffe85b4b, - 0xffedc418, 0x009da526, 0x08061671, 0xf5be0fa9, 0x5d26be9b, 0x56654bdd, 0xfb19b7bd, 0x06f1825d, 0x00b58c8c, 0xffe80414, - 0xffef2395, 0x0096dcc2, 0x08303897, 0xf4c473c6, 0x5e2f6367, 0x552f8ff7, 0xfbe8f5bd, 0x06c0f0c0, 0x00b73ab0, 0xffe75361, - 0xfff0e7ef, 0x008f87aa, 0x08594887, 0xf3c4e887, 0x5f30ff5f, 0x53f495aa, 0xfcb1d740, 0x068f8b44, 0x00b85f70, 0xffe6fed4, - 0xfff294c3, 0x00872c63, 0x0880ffdd, 0xf2bf6ea4, 0x602b0c7f, 0x52b449de, 0xfd7475d8, 0x065dd56a, 0x00b8c6b0, 0xffe69423, - 0xfff48700, 0x007e0393, 0x08a75da4, 0xf1b461ab, 0x611d58a3, 0x516eefb9, 0xfe310657, 0x062bf5ec, 0x00b8fe0d, 0xffe66fac, - 0xfff681d6, 0x007400b8, 0x08cb4e23, 0xf0a3959f, 0x6207f220, 0x5024d70e, 0xfee723c6, 0x05f9c051, 0x00b8394b, 0xffe66dd0, - 0xfff91fca, 0x006928a0, 0x08edfeaa, 0xef8d4d7b, 0x62ea6474, 0x4ed62be3, 0xff96db90, 0x05c76fed, 0x00b74c37, 0xffe681c6, - 0xfffb42b0, 0x005d36df, 0x090ec1fc, 0xee71b2fe, 0x63c45243, 0x4d83976c, 0x0040c496, 0x05950122, 0x00b5c867, 0xffe65416, - 0xfffdfa25, 0x00504f41, 0x092d7970, 0xed50a31d, 0x64964063, 0x4c2ca3df, 0x00e42fa2, 0x05626209, 0x00b3d15c, 0xffe6afee, - 0x00007134, 0x00426f36, 0x0949eaac, 0xec2a3f5f, 0x655f63f2, 0x4ad237a2, 0x01816e06, 0x05303f87, 0x00b1978d, 0xffe6d466, - 0x00039609, 0x0033b927, 0x0963ed46, 0xeafee7f1, 0x661fd6b8, 0x4973fef1, 0x02186a91, 0x04fe20be, 0x00af374c, 0xffe7746e, - 0x0006b1cf, 0x0023b989, 0x097c1ee8, 0xe9cea84a, 0x66d76725, 0x4812f848, 0x02a99097, 0x04cc2fcf, 0x00abe79e, 0xffe79e16, - 0x0009aa3f, 0x00131c75, 0x099140a7, 0xe89971b7, 0x6785c24d, 0x46aea856, 0x03343533, 0x049aa82f, 0x00a8739d, 0xffe83a07, - 0x000d31b5, 0x0000e790, 0x09a3e163, 0xe75f8bb8, 0x682b39a4, 0x4547daea, 0x03b8f8dc, 0x04694101, 0x00a520bb, 0xffe88ba8, - 0x0010bc63, 0xffee183b, 0x09b3d77f, 0xe620c476, 0x68c7269b, 0x43de620a, 0x0437fb0a, 0x043889c6, 0x00a1039c, 0xffe940f4, - 0x001471f8, 0xffda17f2, 0x09c0e59f, 0xe4de0cb0, 0x6959709d, 0x4272a385, 0x04b0adcb, 0x04083fec, 0x009d10bf, 0xffe9ca76, - 0x0018703f, 0xffc4e365, 0x09cab9f2, 0xe396a45d, 0x69e29784, 0x41058bc6, 0x05237f9d, 0x03d8afe6, 0x0098b855, 0xffea9192, - 0x001c3549, 0xffaea5d6, 0x09d19ca9, 0xe24b8f66, 0x6a619c5e, 0x3f962fb8, 0x0590a67d, 0x03a966bb, 0x009424c6, 0xffeb50b2, - 0x002064f8, 0xff975c01, 0x09d52709, 0xe0fc421e, 0x6ad73e8d, 0x3e25b17e, 0x05f7fb90, 0x037ad438, 0x008f4bfc, 0xffebe77b, - 0x0024dd50, 0xff7ee3f1, 0x09d5560b, 0xdfa93ab5, 0x6b42a864, 0x3cb41219, 0x06593912, 0x034d01f0, 0x008a7dd7, 0xffecc31b, - 0x00293718, 0xff6542d1, 0x09d1fa23, 0xde529086, 0x6ba4629f, 0x3b415115, 0x06b559c3, 0x03201116, 0x0085c217, 0xffed651d, - 0x002d8e42, 0xff4aabc8, 0x09caeb0f, 0xdcf898fb, 0x6bfbdd98, 0x39ce0477, 0x070bbf58, 0x02f3e48d, 0x00807994, 0xffee1650, - 0x00329ab6, 0xff2ef725, 0x09c018ce, 0xdb9b5b12, 0x6c492217, 0x385a49c4, 0x075ca90c, 0x02c89901, 0x007b3875, 0xffeedfa4, - 0x003745f9, 0xff120d70, 0x09b18a1d, 0xda3b176a, 0x6c8c4c7a, 0x36e69691, 0x07a8127d, 0x029e35b4, 0x0075fded, 0xffef7b8b, - 0x003c1fa4, 0xfef3f6ab, 0x099ec3dc, 0xd8d7f21f, 0x6cc59bab, 0x3572ec70, 0x07ee507c, 0x0274ba43, 0x0070c8a5, 0xffeff6ca, - 0x004103f4, 0xfed4bec3, 0x09881dc5, 0xd7722f04, 0x6cf4073e, 0x33ff670e, 0x082f552e, 0x024bf7a1, 0x006b47fa, 0xfff0065d, - 0x00465348, 0xfeb48d0d, 0x096d0e21, 0xd60a46e5, 0x6d18520e, 0x328cc6f0, 0x086b1eeb, 0x02244a24, 0x0065fde5, 0xffefc9b9, - 0x004b6c46, 0xfe933dc0, 0x094d7ec2, 0xd49fd55f, 0x6d32730f, 0x311af3a4, 0x08a24899, 0x01fd3ba0, 0x006090c4, 0xffed978a, - 0x0050b177, 0xfe70b8d1, 0x09299ead, 0xd3337b3d, 0x6d41d963, 0x2faa221c, 0x08d3e41b, 0x01d78bfc, 0x005b5371, 0xffede50f, + 0x00000000, 0x0055dba1, 0x01b2e41d, 0x09015651, 0x2e3a7532, 0x6d474e1d, 0xd1c58ace, 0x09015651, 0xfe4d1be3, 0x0055dba1, + 0xffede50e, 0x005b5371, 0x01d78bfc, 0x08d3e41b, 0x2faa221c, 0x6d41d963, 0xd3337b3d, 0x09299ead, 0xfe70b8d1, 0x0050b177, + 0xffed978a, 0x006090c4, 0x01fd3ba0, 0x08a24899, 0x311af3a4, 0x6d32730f, 0xd49fd55f, 0x094d7ec2, 0xfe933dc0, 0x004b6c46, + 0xffefc9b9, 0x0065fde5, 0x02244a24, 0x086b1eeb, 0x328cc6f0, 0x6d18520e, 0xd60a46e5, 0x096d0e21, 0xfeb48d0d, 0x00465348, + 0xfff0065d, 0x006b47fa, 0x024bf7a1, 0x082f552e, 0x33ff670e, 0x6cf4073e, 0xd7722f04, 0x09881dc5, 0xfed4bec3, 0x004103f4, + 0xffeff6ca, 0x0070c8a5, 0x0274ba43, 0x07ee507c, 0x3572ec70, 0x6cc59bab, 0xd8d7f21f, 0x099ec3dc, 0xfef3f6ab, 0x003c1fa4, + 0xffef7b8b, 0x0075fded, 0x029e35b4, 0x07a8127d, 0x36e69691, 0x6c8c4c7a, 0xda3b176a, 0x09b18a1d, 0xff120d70, 0x003745f9, + 0xffeedfa4, 0x007b3875, 0x02c89901, 0x075ca90c, 0x385a49c4, 0x6c492217, 0xdb9b5b12, 0x09c018ce, 0xff2ef725, 0x00329ab6, + 0xffee1650, 0x00807994, 0x02f3e48d, 0x070bbf58, 0x39ce0477, 0x6bfbdd98, 0xdcf898fb, 0x09caeb0f, 0xff4aabc8, 0x002d8e42, + 0xffed651d, 0x0085c217, 0x03201116, 0x06b559c3, 0x3b415115, 0x6ba4629f, 0xde529086, 0x09d1fa23, 0xff6542d1, 0x00293718, + 0xffecc31b, 0x008a7dd7, 0x034d01f0, 0x06593912, 0x3cb41219, 0x6b42a864, 0xdfa93ab5, 0x09d5560b, 0xff7ee3f1, 0x0024dd50, + 0xffebe77b, 0x008f4bfc, 0x037ad438, 0x05f7fb90, 0x3e25b17e, 0x6ad73e8d, 0xe0fc421e, 0x09d52709, 0xff975c01, 0x002064f8, + 0xffeb50b2, 0x009424c6, 0x03a966bb, 0x0590a67d, 0x3f962fb8, 0x6a619c5e, 0xe24b8f66, 0x09d19ca9, 0xffaea5d6, 0x001c3549, + 0xffea9192, 0x0098b855, 0x03d8afe6, 0x05237f9d, 0x41058bc6, 0x69e29784, 0xe396a45d, 0x09cab9f2, 0xffc4e365, 0x0018703f, + 0xffe9ca76, 0x009d10bf, 0x04083fec, 0x04b0adcb, 0x4272a385, 0x6959709d, 0xe4de0cb0, 0x09c0e59f, 0xffda17f2, 0x001471f8, + 0xffe940f4, 0x00a1039c, 0x043889c6, 0x0437fb0a, 0x43de620a, 0x68c7269b, 0xe620c476, 0x09b3d77f, 0xffee183b, 0x0010bc63, + 0xffe88ba8, 0x00a520bb, 0x04694101, 0x03b8f8dc, 0x4547daea, 0x682b39a4, 0xe75f8bb8, 0x09a3e163, 0x0000e790, 0x000d31b5, + 0xffe83a07, 0x00a8739d, 0x049aa82f, 0x03343533, 0x46aea856, 0x6785c24d, 0xe89971b7, 0x099140a7, 0x00131c75, 0x0009aa3f, + 0xffe79e16, 0x00abe79e, 0x04cc2fcf, 0x02a99097, 0x4812f848, 0x66d76725, 0xe9cea84a, 0x097c1ee8, 0x0023b989, 0x0006b1cf, + 0xffe7746e, 0x00af374c, 0x04fe20be, 0x02186a91, 0x4973fef1, 0x661fd6b8, 0xeafee7f1, 0x0963ed46, 0x0033b927, 0x00039609, + 0xffe6d466, 0x00b1978d, 0x05303f87, 0x01816e06, 0x4ad237a2, 0x655f63f2, 0xec2a3f5f, 0x0949eaac, 0x00426f36, 0x00007134, + 0xffe6afee, 0x00b3d15c, 0x05626209, 0x00e42fa2, 0x4c2ca3df, 0x64964063, 0xed50a31d, 0x092d7970, 0x00504f41, 0xfffdfa25, + 0xffe65416, 0x00b5c867, 0x05950122, 0x0040c496, 0x4d83976c, 0x63c45243, 0xee71b2fe, 0x090ec1fc, 0x005d36df, 0xfffb42b0, + 0xffe681c6, 0x00b74c37, 0x05c76fed, 0xff96db90, 0x4ed62be3, 0x62ea6474, 0xef8d4d7b, 0x08edfeaa, 0x006928a0, 0xfff91fca, + 0xffe66dd0, 0x00b8394b, 0x05f9c051, 0xfee723c6, 0x5024d70e, 0x6207f220, 0xf0a3959f, 0x08cb4e23, 0x007400b8, 0xfff681d6, + 0xffe66fac, 0x00b8fe0d, 0x062bf5ec, 0xfe310657, 0x516eefb9, 0x611d58a3, 0xf1b461ab, 0x08a75da4, 0x007e0393, 0xfff48700, + 0xffe69423, 0x00b8c6b0, 0x065dd56a, 0xfd7475d8, 0x52b449de, 0x602b0c7f, 0xf2bf6ea4, 0x0880ffdd, 0x00872c63, 0xfff294c3, + 0xffe6fed4, 0x00b85f70, 0x068f8b44, 0xfcb1d740, 0x53f495aa, 0x5f30ff5f, 0xf3c4e887, 0x08594887, 0x008f87aa, 0xfff0e7ef, + 0xffe75361, 0x00b73ab0, 0x06c0f0c0, 0xfbe8f5bd, 0x552f8ff7, 0x5e2f6367, 0xf4c473c6, 0x08303897, 0x0096dcc2, 0xffef2395, + 0xffe80414, 0x00b58c8c, 0x06f1825d, 0xfb19b7bd, 0x56654bdd, 0x5d26be9b, 0xf5be0fa9, 0x08061671, 0x009da526, 0xffedc418, + 0xffe85b4b, 0x00b36acd, 0x0721bf22, 0xfa44a069, 0x579505f5, 0x5c16d0ae, 0xf6b1f3c3, 0x07da2b7f, 0x00a3508f, 0xffec8409, + 0xffe954d0, 0x00b06b68, 0x075112a2, 0xf96916f5, 0x58befacd, 0x5b001db8, 0xf79fa13a, 0x07ad8c26, 0x00a85e94, 0xffeb3849, + 0xffea353a, 0x00acbd2f, 0x077fedb3, 0xf887507c, 0x59e2f69e, 0x59e2f69e, 0xf887507c, 0x077fedb3, 0x00acbd2f, 0xffea353a, + 0xffeb3849, 0x00a85e94, 0x07ad8c26, 0xf79fa13a, 0x5b001db8, 0x58befacd, 0xf96916f5, 0x075112a2, 0x00b06b68, 0xffe954d0, + 0xffec8409, 0x00a3508f, 0x07da2b7f, 0xf6b1f3c3, 0x5c16d0ae, 0x579505f5, 0xfa44a069, 0x0721bf22, 0x00b36acd, 0xffe85b4b, + 0xffedc418, 0x009da526, 0x08061671, 0xf5be0fa9, 0x5d26be9b, 0x56654bdd, 0xfb19b7bd, 0x06f1825d, 0x00b58c8c, 0xffe80414, + 0xffef2395, 0x0096dcc2, 0x08303897, 0xf4c473c6, 0x5e2f6367, 0x552f8ff7, 0xfbe8f5bd, 0x06c0f0c0, 0x00b73ab0, 0xffe75361, + 0xfff0e7ef, 0x008f87aa, 0x08594887, 0xf3c4e887, 0x5f30ff5f, 0x53f495aa, 0xfcb1d740, 0x068f8b44, 0x00b85f70, 0xffe6fed4, + 0xfff294c3, 0x00872c63, 0x0880ffdd, 0xf2bf6ea4, 0x602b0c7f, 0x52b449de, 0xfd7475d8, 0x065dd56a, 0x00b8c6b0, 0xffe69423, + 0xfff48700, 0x007e0393, 0x08a75da4, 0xf1b461ab, 0x611d58a3, 0x516eefb9, 0xfe310657, 0x062bf5ec, 0x00b8fe0d, 0xffe66fac, + 0xfff681d6, 0x007400b8, 0x08cb4e23, 0xf0a3959f, 0x6207f220, 0x5024d70e, 0xfee723c6, 0x05f9c051, 0x00b8394b, 0xffe66dd0, + 0xfff91fca, 0x006928a0, 0x08edfeaa, 0xef8d4d7b, 0x62ea6474, 0x4ed62be3, 0xff96db90, 0x05c76fed, 0x00b74c37, 0xffe681c6, + 0xfffb42b0, 0x005d36df, 0x090ec1fc, 0xee71b2fe, 0x63c45243, 0x4d83976c, 0x0040c496, 0x05950122, 0x00b5c867, 0xffe65416, + 0xfffdfa25, 0x00504f41, 0x092d7970, 0xed50a31d, 0x64964063, 0x4c2ca3df, 0x00e42fa2, 0x05626209, 0x00b3d15c, 0xffe6afee, + 0x00007134, 0x00426f36, 0x0949eaac, 0xec2a3f5f, 0x655f63f2, 0x4ad237a2, 0x01816e06, 0x05303f87, 0x00b1978d, 0xffe6d466, + 0x00039609, 0x0033b927, 0x0963ed46, 0xeafee7f1, 0x661fd6b8, 0x4973fef1, 0x02186a91, 0x04fe20be, 0x00af374c, 0xffe7746e, + 0x0006b1cf, 0x0023b989, 0x097c1ee8, 0xe9cea84a, 0x66d76725, 0x4812f848, 0x02a99097, 0x04cc2fcf, 0x00abe79e, 0xffe79e16, + 0x0009aa3f, 0x00131c75, 0x099140a7, 0xe89971b7, 0x6785c24d, 0x46aea856, 0x03343533, 0x049aa82f, 0x00a8739d, 0xffe83a07, + 0x000d31b5, 0x0000e790, 0x09a3e163, 0xe75f8bb8, 0x682b39a4, 0x4547daea, 0x03b8f8dc, 0x04694101, 0x00a520bb, 0xffe88ba8, + 0x0010bc63, 0xffee183b, 0x09b3d77f, 0xe620c476, 0x68c7269b, 0x43de620a, 0x0437fb0a, 0x043889c6, 0x00a1039c, 0xffe940f4, + 0x001471f8, 0xffda17f2, 0x09c0e59f, 0xe4de0cb0, 0x6959709d, 0x4272a385, 0x04b0adcb, 0x04083fec, 0x009d10bf, 0xffe9ca76, + 0x0018703f, 0xffc4e365, 0x09cab9f2, 0xe396a45d, 0x69e29784, 0x41058bc6, 0x05237f9d, 0x03d8afe6, 0x0098b855, 0xffea9192, + 0x001c3549, 0xffaea5d6, 0x09d19ca9, 0xe24b8f66, 0x6a619c5e, 0x3f962fb8, 0x0590a67d, 0x03a966bb, 0x009424c6, 0xffeb50b2, + 0x002064f8, 0xff975c01, 0x09d52709, 0xe0fc421e, 0x6ad73e8d, 0x3e25b17e, 0x05f7fb90, 0x037ad438, 0x008f4bfc, 0xffebe77b, + 0x0024dd50, 0xff7ee3f1, 0x09d5560b, 0xdfa93ab5, 0x6b42a864, 0x3cb41219, 0x06593912, 0x034d01f0, 0x008a7dd7, 0xffecc31b, + 0x00293718, 0xff6542d1, 0x09d1fa23, 0xde529086, 0x6ba4629f, 0x3b415115, 0x06b559c3, 0x03201116, 0x0085c217, 0xffed651d, + 0x002d8e42, 0xff4aabc8, 0x09caeb0f, 0xdcf898fb, 0x6bfbdd98, 0x39ce0477, 0x070bbf58, 0x02f3e48d, 0x00807994, 0xffee1650, + 0x00329ab6, 0xff2ef725, 0x09c018ce, 0xdb9b5b12, 0x6c492217, 0x385a49c4, 0x075ca90c, 0x02c89901, 0x007b3875, 0xffeedfa4, + 0x003745f9, 0xff120d70, 0x09b18a1d, 0xda3b176a, 0x6c8c4c7a, 0x36e69691, 0x07a8127d, 0x029e35b4, 0x0075fded, 0xffef7b8b, + 0x003c1fa4, 0xfef3f6ab, 0x099ec3dc, 0xd8d7f21f, 0x6cc59bab, 0x3572ec70, 0x07ee507c, 0x0274ba43, 0x0070c8a5, 0xffeff6ca, + 0x004103f4, 0xfed4bec3, 0x09881dc5, 0xd7722f04, 0x6cf4073e, 0x33ff670e, 0x082f552e, 0x024bf7a1, 0x006b47fa, 0xfff0065d, + 0x00465348, 0xfeb48d0d, 0x096d0e21, 0xd60a46e5, 0x6d18520e, 0x328cc6f0, 0x086b1eeb, 0x02244a24, 0x0065fde5, 0xffefc9b9, + 0x004b6c46, 0xfe933dc0, 0x094d7ec2, 0xd49fd55f, 0x6d32730f, 0x311af3a4, 0x08a24899, 0x01fd3ba0, 0x006090c4, 0xffed978a, + 0x0050b177, 0xfe70b8d1, 0x09299ead, 0xd3337b3d, 0x6d41d963, 0x2faa221c, 0x08d3e41b, 0x01d78bfc, 0x005b5371, 0xffede50f, }; /* noise table 4.A.88, format = Q31 */ -const int noiseTab[512*2] PROGMEM = { - 0x8010fd38, 0xb3dc7948, 0x7c4e2301, 0xa9904192, 0x121622a7, 0x86489625, 0xc3d53d25, 0xd0343fa9, - 0x674d6f70, 0x25f4e9fd, 0xce1a8c8b, 0x72a726c5, 0xfea6efc6, 0xaa4adb1a, 0x8b2dd628, 0xf14029e4, - 0x46321c1a, 0x604889a0, 0x33363b63, 0x815ed069, 0x802b4315, 0x8f2bf7f3, 0x85b86073, 0x745cfb46, - 0xc57886b3, 0xb76731f0, 0xa2a66772, 0x828ca631, 0x60cc145e, 0x1ad1010f, 0x090c83d4, 0x9bd7ba87, - 0x5f5aeea2, 0x8b4dbd99, 0x848e7b1e, 0x86bb9fa2, 0x26f18ae5, 0xc0b81194, 0x553407bf, 0x52c17953, - 0x755f468d, 0x166b04f8, 0xa5687981, 0x4343248b, 0xa6558d5e, 0xc5f6fab7, 0x80a4fb8c, 0x8cb53cb7, - 0x7da68a54, 0x9cd8df8a, 0xba05376c, 0xfcb58ee2, 0xfdd657a4, 0x005e35ca, 0x91c75c55, 0x367651e6, - 0x816abf85, 0x8f831c4f, 0x423f9c9c, 0x55aa919e, 0x80779834, 0xb59f4244, 0x800a095c, 0x7de9e0cc, - 0x46bda5cb, 0x4c184464, 0x2c438f71, 0x797216b5, 0x5035cee6, 0xa0c3a26e, 0x9d3f95fa, 0xd4a100c0, - 0x8ac30dac, 0x04b87397, 0x9e5ac516, 0x8b0b442e, 0x66210ad6, 0x88ba7598, 0x45b9bd33, 0xf0be5087, - 0x9261b85e, 0x364f6a31, 0x891c4b50, 0x23ad08ce, 0xf10366a6, 0x80414276, 0x1b562e06, 0x8be21591, - 0x9e798195, 0x7fb4045c, 0x7d9506cf, 0x854e691f, 0x9207f092, 0x7a94c9d5, 0x88911536, 0x3f45cc61, - 0x27059279, 0xa5b57109, 0x6d2bb67b, 0x3bdc5379, 0x74e662d8, 0x80348f8c, 0xf875e638, 0x5a8caea1, - 0x2459ae75, 0x2c54b939, 0x79ee3203, 0xb9bc8683, 0x9b6f630c, 0x9f45b351, 0x8563b2b9, 0xe5dbba41, - 0x697c7d0d, 0x7bb7c90e, 0xac900866, 0x8e6b5177, 0x8822dd37, 0x7fd5a91e, 0x7506da05, 0x82302aca, - 0xa5e4be04, 0x4b4288eb, 0x00b8bc9f, 0x4f1033e4, 0x7200d612, 0x43900c8c, 0xa815b900, 0x676ed1d4, - 0x5c5f23b2, 0xa758ee11, 0xaf73abfa, 0x11714ec0, 0x265239e0, 0xc50de679, 0x8a84e341, 0xa1438354, - 0x7f1a341f, 0x343ec96b, 0x696e71b0, 0xa13bde39, 0x81e75094, 0x80091111, 0x853a73bf, 0x80f9c1ee, - 0xe4980086, 0x886a8e28, 0xa7e89426, 0xdd93edd7, 0x7592100d, 0x0bfa8123, 0x850a26d4, 0x2e34f395, - 0x421b6c00, 0xa4a462e4, 0x4e3f5090, 0x3c189f4c, 0x3c971a56, 0xdd0376d2, 0x747a5367, 0x7bcbc9d7, - 0x3966be6a, 0x7efda616, 0x55445e15, 0x7ba2ab3f, 0x5fe684f2, 0x8cf42af9, 0x808c61c3, 0x4390c27b, - 0x7cac62ff, 0xea6cab22, 0x5d0902ad, 0xc27b7208, 0x7a27389d, 0x5820a357, 0xa29bbe59, 0x9df0f1fd, - 0x92bd67e5, 0x7195b587, 0x97cac65b, 0x8339807e, 0x8f72d832, 0x5fad8685, 0xa462d9d3, 0x81d46214, - 0x6ae93e1d, 0x6b23a5b9, 0xc2732874, 0x81795268, 0x7c568cb6, 0x668513ea, 0x428d024e, 0x66b78b3a, - 0xfee9ef03, 0x9ddcbb82, 0xa605f07e, 0x46dc55e0, 0x85415054, 0xc89ec271, 0x7c42edfb, 0x0befe59b, - 0x89b8f607, 0x6d732a1a, 0xa7081ebd, 0x7e403258, 0x21feeb7b, 0x5dd7a1e7, 0x23e3a31a, 0x129bc896, - 0xa11a6b54, 0x7f1e031c, 0xfdc1a4d1, 0x96402e53, 0xb9700f1a, 0x8168ecd6, 0x7d63d3cc, 0x87a70d65, - 0x81075a7a, 0x55c8caa7, 0xa95d00b5, 0x102b1652, 0x0bb30215, 0xe5b63237, 0xa446ca44, 0x82d4c333, - 0x67b2e094, 0x44c3d661, 0x33fd6036, 0xde1ea2a1, 0xa95e8e47, 0x78f66eb9, 0x6f2aef1e, 0xe8887247, - 0x80a3b70e, 0xfca0d9d3, 0x6bf0fd20, 0x0d5226de, 0xf4341c87, 0x5902df05, 0x7ff1a38d, 0xf02e5a5b, - 0x99f129af, 0x8ac63d01, 0x7b53f599, 0x7bb32532, 0x99ac59b0, 0x5255a80f, 0xf1320a41, 0x2497aa5c, - 0xcce60bd8, 0x787c634b, 0x7ed58c5b, 0x8a28eb3a, 0x24a5e647, 0x8b79a2c1, 0x955f5ce5, 0xa9d12bc4, - 0x7a1e20c6, 0x3eeda7ac, 0xf7be823a, 0x042924ce, 0x808b3f03, 0x364248da, 0xac2895e5, 0x69a8b5fa, - 0x97fe8b63, 0xbdeac9aa, 0x8073e0ad, 0x6c25dba7, 0x005e51d2, 0x52e74389, 0x59d3988c, 0xe5d1f39c, - 0x7b57dc91, 0x341adbe7, 0xa7d42b8d, 0x74e9f335, 0xd35bf7d8, 0x5b7c0a4b, 0x75bc0874, 0x552129bf, - 0x8144b70d, 0x6de93bbb, 0x5825f14b, 0x473ec5ca, 0x80a8f37c, 0xe6552d69, 0x7898360b, 0x806379b0, - 0xa9b59339, 0x3f6bf60c, 0xc367d731, 0x920ade99, 0x125592f7, 0x877e5ed1, 0xda895d95, 0x075f2ece, - 0x380e5f5e, 0x9b006b62, 0xd17a6dd2, 0x530a0e13, 0xf4cc9a14, 0x7d0a0ed4, 0x847c6e3f, 0xbaee4975, - 0x47131163, 0x64fb2cac, 0x5e2100a6, 0x7b756a42, 0xd87609f4, 0x98bfe48c, 0x0493745e, 0x836c5784, - 0x7e5ccb40, 0x3df6b476, 0x97700d28, 0x8bbd93fd, 0x56de9cdb, 0x680b4e65, 0xebc3d90e, 0x6d286793, - 0x6753712e, 0xe05c98a7, 0x3d2b6b85, 0xc4b18ddb, 0x7b59b869, 0x31435688, 0x811888e9, 0xe011ee7a, - 0x6a5844f9, 0x86ae35ea, 0xb4cbc10b, 0x01a6f5d6, 0x7a49ed64, 0x927caa49, 0x847ddaed, 0xae0d9bb6, - 0x836bdb04, 0x0fd810a6, 0x74fe126b, 0x4a346b5f, 0x80184d36, 0x5afd153c, 0x90cc8102, 0xe606d0e6, - 0xde69aa58, 0xa89f1222, 0xe06df715, 0x8fd16144, 0x0317c3e8, 0x22ce92fc, 0x690c3eca, 0x93166f02, - 0x71573414, 0x8d43cffb, 0xe8bd0bb6, 0xde86770f, 0x0bf99a41, 0x4633a661, 0xba064108, 0x7adafae3, - 0x2f6cde5d, 0xb350a52c, 0xa5ebfb0b, 0x74c57b46, 0xd3b603b5, 0x80b70892, 0xa7f7fa53, 0xd94b566c, - 0xdda3fd86, 0x6a635793, 0x3ed005ca, 0xc5f087d8, 0x31e3a746, 0x7a4278f9, 0x82def1f9, 0x06caa2b2, - 0xe9d2c349, 0x8940e7f7, 0x7feef8dd, 0x4a9b01f0, 0xacde69f8, 0x57ddc280, 0xf09e4ba4, 0xb6d9f729, - 0xb48c18f2, 0xd3654aa9, 0xca7a03c8, 0x14d57545, 0x7fda87a5, 0x0e411366, 0xb77d0df0, 0x8c2aa467, - 0x787f2590, 0x2d292db1, 0x9f12682c, 0x44ac364d, 0x1a4b31a6, 0x871f7ded, 0x7ff99167, 0x6630a1d5, - 0x25385eb9, 0x2d4dd549, 0xaf8a7004, 0x319ebe0f, 0x379ab730, 0x81dc56a4, 0x822d8523, 0x1ae8554c, - 0x18fa0786, 0x875f7de4, 0x85ca350f, 0x7de818dc, 0x7786a38f, 0xa5456355, 0x92e60f88, 0xf5526122, - 0x916039bc, 0xc561e2de, 0x31c42042, 0x7c82e290, 0x75d158b2, 0xb015bda1, 0x7220c750, 0x46565441, - 0xd0da1fdd, 0x7b777481, 0x782e73c6, 0x8cd72b7b, 0x7f1006aa, 0xfb30e51e, 0x87994818, 0x34e7c7db, - 0x7faae06b, 0xea74fbc0, 0xd20c7af4, 0xc44f396b, 0x06b4234e, 0xdf2e2a93, 0x2efb07c8, 0xce861911, - 0x7550ea05, 0xd8d90bbb, 0x58522eec, 0x746b3520, 0xce844ce9, 0x7f5cacc3, 0xda8f17e0, 0x2fedf9cb, - 0xb2f77ec4, 0x6f13f4c0, 0x834de085, 0x7b7ace4b, 0x713b16ac, 0x499c5ab0, 0x06a7961d, 0x1b39a48a, - 0xbb853e6e, 0x7c781cc1, 0xc0baebf5, 0x7dace394, 0x815ceebc, 0xcc7b27d4, 0x8274b181, 0xa2be40a2, - 0xdd01d5dc, 0x7fefeb14, 0x0813ec78, 0xba3077cc, 0xe5cf1e1c, 0xedcfacae, 0x54c43a9b, 0x5cd62a42, - 0x93806b55, 0x03095c5b, 0x8e076ae3, 0x71bfcd2a, 0x7ac1989b, 0x623bc71a, 0x5e15d4d2, 0xfb341dd1, - 0xd75dfbca, 0xd0da32be, 0xd4569063, 0x337869da, 0x3d30606a, 0xcd89cca2, 0x7dd2ae36, 0x028c03cd, - 0xd85e052c, 0xe8dc9ec5, 0x7ffd9241, 0xde5bf4c6, 0x88c4b235, 0x8228be2e, 0x7fe6ec64, 0x996abe6a, - 0xdeb0666d, 0x9eb86611, 0xd249b922, 0x18b3e26b, 0x80211168, 0x5f8bb99c, 0x6ecb0dd2, 0x4728ff8d, - 0x2ac325b8, 0x6e5169d2, 0x7ebbd68d, 0x05e41d17, 0xaaa19f28, 0x8ab238a6, 0x51f105be, 0x140809cc, - 0x7f7345d9, 0x3aae5a9d, 0xaecec6e4, 0x1afb3473, 0xf6229ed1, 0x8d55f467, 0x7e32003a, 0x70f30c14, - 0x6686f33f, 0xd0d45ed8, 0x644fab57, 0x3a3fbbd3, 0x0b255fc4, 0x679a1701, 0x90e17b6e, 0x325d537b, - 0xcd7b9b87, 0xaa7be2a2, 0x7d47c966, 0xa33dbce5, 0x8659c3bb, 0x72a41367, 0x15c446e0, 0x45fe8b0a, - 0x9d8ddf26, 0x84d47643, 0x7fabe0da, 0x36a70122, 0x7a28ebfe, 0x7c29b8b8, 0x7f760406, 0xbabe4672, - 0x23ea216e, 0x92bcc50a, 0x6d20dba2, 0xad5a7c7e, 0xbf3897f5, 0xabb793e1, 0x8391fc7e, 0xe270291c, - 0x7a248d58, 0x80f8fd15, 0x83ef19f3, 0x5e6ece7d, 0x278430c1, 0x35239f4d, 0xe09c073b, 0x50e78cb5, - 0xd4b811bd, 0xce834ee0, 0xf88aaa34, 0xf71da5a9, 0xe2b0a1d5, 0x7c3aef31, 0xe84eabca, 0x3ce25964, - 0xf29336d3, 0x8fa78b2c, 0xa3fc3415, 0x63e1313d, 0x7fbc74e0, 0x7340bc93, 0x49ae583b, 0x8b79de4b, - 0x25011ce9, 0x7b462279, 0x36007db0, 0x3da1599c, 0x77780772, 0xc845c9bb, 0x83ba68be, 0x6ee507d1, - 0x2f0159b8, 0x5392c4ed, 0x98336ff6, 0x0b3c7f11, 0xde697aac, 0x893fc8d0, 0x6b83f8f3, 0x47799a0d, - 0x801d9dfc, 0x8516a83e, 0x5f8d22ec, 0x0f8ba384, 0xa049dc4b, 0xdd920b05, 0x7a99bc9f, 0x9ad19344, - 0x7a345dba, 0xf501a13f, 0x3e58bf19, 0x7fffaf9a, 0x3b4e1511, 0x0e08b991, 0x9e157620, 0x7230a326, - 0x4977f9ff, 0x2d2bbae1, 0x607aa7fc, 0x7bc85d5f, 0xb441bbbe, 0x8d8fa5f2, 0x601cce26, 0xda1884f2, - 0x81c82d64, 0x200b709c, 0xcbd36abe, 0x8cbdddd3, 0x55ab61d3, 0x7e3ee993, 0x833f18aa, 0xffc1aaea, - 0x7362e16a, 0x7fb85db2, 0x904ee04c, 0x7f04dca6, 0x8ad7a046, 0xebe7d8f7, 0xfbc4c687, 0xd0609458, - 0x093ed977, 0x8e546085, 0x7f5b8236, 0x7c47e118, 0xa01f2641, 0x7ffb3e48, 0x05de7cda, 0x7fc281b9, - 0x8e0278fc, 0xd74e6d07, 0x94c24450, 0x7cf9e641, 0x2ad27871, 0x919fa815, 0x805fd205, 0x7758397f, - 0xe2c7e02c, 0x1828e194, 0x5613d6fe, 0xfb55359f, 0xf9699516, 0x8978ee26, 0x7feebad9, 0x77d71d82, - 0x55b28b60, 0x7e997600, 0x80821a6b, 0xc6d78af1, 0x691822ab, 0x7f6982a0, 0x7ef56f99, 0x5c307f40, - 0xac6f8b76, 0x42cc8ba4, 0x782c61d9, 0xa0224dd0, 0x7bd234d1, 0x74576e3b, 0xe38cfe9a, 0x491e66ef, - 0xc78291c5, 0x895bb87f, 0x924f7889, 0x71b89394, 0x757b779d, 0xc4a9c604, 0x5cdf7829, 0x8020e9df, - 0x805e8245, 0x4a82c398, 0x6360bd62, 0x78bb60fc, 0x09e0d014, 0x4b0ea180, 0xb841978b, 0x69a0e864, - 0x7df35977, 0x3284b0dd, 0x3cdc2efd, 0x57d31f5e, 0x541069cc, 0x1776e92e, 0x04309ea3, 0xa015eb2d, - 0xce7bfabc, 0x41b638f8, 0x8365932e, 0x846ab44c, 0xbbcc80cb, 0x8afa6cac, 0x7fc422ea, 0x4e403fc0, - 0xbfac9aee, 0x8e4c6709, 0x028e01fb, 0x6d160a9b, 0x7fe93004, 0x790f9cdc, 0x6a1f37a0, 0xf7e7ef30, - 0xb4ea0f04, 0x7bf4c8e6, 0xe981701f, 0xc258a9d3, 0x6acbbfba, 0xef5479c7, 0x079c8bd8, 0x1a410f56, - 0x6853b799, 0x86cd4f01, 0xc66e23b6, 0x34585565, 0x8d1fe00d, 0x7fcdba1a, 0x32c9717b, 0xa02f9f48, - 0xf64940db, 0x5ed7d8f1, 0x61b823b2, 0x356f8918, 0xa0a7151e, 0x793fc969, 0x530beaeb, 0x34e93270, - 0x4fc4ddb5, 0x88d58b6c, 0x36094774, 0xf620ac80, 0x03763a72, 0xf910c9a6, 0x6666fb2d, 0x752c8be8, - 0x9a6dfdd8, 0xd1a7117d, 0x51c1b1d4, 0x0a67773d, 0x43b32a79, 0x4cdcd085, 0x5f067d30, 0x05bfe92a, - 0x7ed7d203, 0xe71a3c85, 0x99127ce2, 0x8eb3cac4, 0xad4bbcea, 0x5c6a0fd0, 0x0eec04af, 0x94e95cd4, - 0x8654f921, 0x83eabb5d, 0xb058d7ca, 0x69f12d3c, 0x03d881b2, 0x80558ef7, 0x82938cb3, 0x2ec0e1d6, - 0x80044422, 0xd1e47051, 0x720fc6ff, 0x82b20316, 0x0d527b02, 0x63049a15, 0x7ad5b9ad, 0xd2a4641d, - 0x41144f86, 0x7b04917a, 0x15c4a2c0, 0x9da07916, 0x211df54a, 0x7fdd09af, 0xfe924f3f, 0x7e132cfe, - 0x9a1d18d6, 0x7c56508b, 0x80f0f0af, 0x8095ced6, 0x8037d0d7, 0x026719d1, 0xa55fec43, 0x2b1c7cb7, - 0xa5cd5ac1, 0x77639fad, 0x7fcd8b62, 0x81a18c27, 0xaee4912e, 0xeae9eebe, 0xeb3081de, 0x8532aada, - 0xc822362e, 0x86a649a9, 0x8031a71d, 0x7b319dc6, 0xea8022e6, 0x814bc5a9, 0x8f62f7a1, 0xa430ea17, - 0x388deafb, 0x883b5185, 0x776fe13c, 0x801c683f, 0x87c11b98, 0xb7cbc644, 0x8e9ad3e8, 0x3cf5a10c, - 0x7ff6a634, 0x949ef096, 0x9f84aa7c, 0x010af13f, 0x782d1de8, 0xf18e492a, 0x6cf63b01, 0x4301cd81, - 0x32d15c9e, 0x68ad8cef, 0xd09bd2d6, 0x908c5c15, 0xd1e36260, 0x2c5bfdd0, 0x88765a99, 0x93deba1e, - 0xac6ae342, 0xe865b84c, 0x0f4f2847, 0x7fdf0499, 0x78b1c9b3, 0x6a73261e, 0x601a96f6, 0xd2847933, - 0x489aa888, 0xe12e8093, 0x3bfa5a5f, 0xd96ba5f7, 0x7c8f4c8d, 0x80940c6f, 0xcef9dd1a, 0x7e1a055f, - 0x3483558b, 0x02b59cc4, 0x0c56333e, 0x05a5b813, 0x92d66287, 0x7516b679, 0x71bfe03f, 0x8056bf68, - 0xc24d0724, 0x8416bcf3, 0x234afbdb, 0x4b0d6f9c, 0xaba97333, 0x4b4f42b6, 0x7e8343ab, 0x7ffe2603, - 0xe590f73c, 0x45e10c76, 0xb07a6a78, 0xb35609d3, 0x1a027dfd, 0x90cb6e20, 0x82d3fe38, 0x7b409257, - 0x0e395afa, 0x1b802093, 0xcb0c6c59, 0x241e17e7, 0x1ee3ea0a, 0x41a82302, 0xab04350a, 0xf570beb7, - 0xbb444b9b, 0x83021459, 0x838d65dc, 0x1c439c84, 0x6fdcc454, 0xef9ef325, 0x18626c1c, 0x020d251f, - 0xc4aae786, 0x8614cb48, 0xf6f53ca6, 0x8710dbab, 0x89abec0d, 0xf29d41c1, 0x94b50336, 0xfdd49178, - 0x604658d1, 0x800e85be, 0xca1bb079, 0x7fa48eeb, 0xa3b7fafe, 0xd330436b, 0x64eb604c, 0x43a658ae, - 0x7caa1337, 0xddd445e6, 0x7efbf955, 0xb706ec71, 0x624a6b53, 0x9e0e231f, 0x97097248, 0xa1e1a17a, - 0x68dd2e44, 0x7f9d2e14, 0xddcc7074, 0x58324197, 0xc88fc426, 0x6d3640ae, 0x7ef83600, 0x759a0270, - 0x98b6d854, 0xd63c9b84, 0x372474a2, 0xe3f18cfd, 0x56ab0bdb, 0x85c9be7e, 0x47dfcfeb, 0xa5830d41, - 0x0ddd6283, 0xf4f480ad, 0x74c60e38, 0xab8943c3, 0xc1508fe7, 0x480cdc39, 0x8e097362, 0xa44793be, - 0x538b7e18, 0x545f5b41, 0x56529175, 0x9771a97e, 0xc2da7421, 0xea8265f2, 0x805d1163, 0x883c5d28, - 0x8ba94c48, 0x4f676e65, 0xf78735b3, 0xe1853671, 0x7f454f53, 0x18147f85, 0x7d09e15d, 0xdb4f3494, - 0x795c8973, 0x83310632, 0x85d8061c, 0x9a1a0ebf, 0xc125583c, 0x2a1b1a95, 0x7fd9103f, 0x71e98c72, - 0x40932ed7, 0x91ed227a, 0x3c5e560e, 0xe816dee9, 0xb0891b80, 0x600038ba, 0xc7d9a80d, 0x7fff5e09, - 0x7e3f4351, 0xbb6b4424, 0xb14448d4, 0x8d6bb7e1, 0xfb153626, 0xa68ad537, 0xd9782006, 0xf62f6991, - 0x359ba8c1, 0x02ccff0b, 0x91bf2256, 0x7ea71c4d, 0x560ce5df, 0xeeba289b, 0xa574c4e7, 0x9e04f6ee, - 0x7860a5ec, 0x0b8db4a2, 0x968ba3d7, 0x0b6c77df, 0xd6f3157d, 0x402eff1a, 0x49b820b3, 0x8152aebb, - 0xd180b0b6, 0x098604d4, 0x7ff92224, 0xede9c996, 0x89c58061, 0x829624c4, 0xc6e71ea7, 0xba94d915, - 0x389c3cf6, 0x5b4c5a06, 0x04b335e6, 0x516a8aab, 0x42c8d7d9, 0x92b12af6, 0x86c8549f, 0xfda98acf, - 0x819673b6, 0x69545dac, 0x6feaa230, 0x726e6d3f, 0x886ebdfe, 0x34f5730a, 0x7af63ba2, 0x77307bbf, - 0x7cd80630, 0x6e45efe0, 0x7f8ad7eb, 0x59d7df99, 0x86c70946, 0xda233629, 0x753f6cbf, 0x825eeb40, +const int noiseTab[512 * 2] PROGMEM = { + 0x8010fd38, 0xb3dc7948, 0x7c4e2301, 0xa9904192, 0x121622a7, 0x86489625, 0xc3d53d25, 0xd0343fa9, + 0x674d6f70, 0x25f4e9fd, 0xce1a8c8b, 0x72a726c5, 0xfea6efc6, 0xaa4adb1a, 0x8b2dd628, 0xf14029e4, + 0x46321c1a, 0x604889a0, 0x33363b63, 0x815ed069, 0x802b4315, 0x8f2bf7f3, 0x85b86073, 0x745cfb46, + 0xc57886b3, 0xb76731f0, 0xa2a66772, 0x828ca631, 0x60cc145e, 0x1ad1010f, 0x090c83d4, 0x9bd7ba87, + 0x5f5aeea2, 0x8b4dbd99, 0x848e7b1e, 0x86bb9fa2, 0x26f18ae5, 0xc0b81194, 0x553407bf, 0x52c17953, + 0x755f468d, 0x166b04f8, 0xa5687981, 0x4343248b, 0xa6558d5e, 0xc5f6fab7, 0x80a4fb8c, 0x8cb53cb7, + 0x7da68a54, 0x9cd8df8a, 0xba05376c, 0xfcb58ee2, 0xfdd657a4, 0x005e35ca, 0x91c75c55, 0x367651e6, + 0x816abf85, 0x8f831c4f, 0x423f9c9c, 0x55aa919e, 0x80779834, 0xb59f4244, 0x800a095c, 0x7de9e0cc, + 0x46bda5cb, 0x4c184464, 0x2c438f71, 0x797216b5, 0x5035cee6, 0xa0c3a26e, 0x9d3f95fa, 0xd4a100c0, + 0x8ac30dac, 0x04b87397, 0x9e5ac516, 0x8b0b442e, 0x66210ad6, 0x88ba7598, 0x45b9bd33, 0xf0be5087, + 0x9261b85e, 0x364f6a31, 0x891c4b50, 0x23ad08ce, 0xf10366a6, 0x80414276, 0x1b562e06, 0x8be21591, + 0x9e798195, 0x7fb4045c, 0x7d9506cf, 0x854e691f, 0x9207f092, 0x7a94c9d5, 0x88911536, 0x3f45cc61, + 0x27059279, 0xa5b57109, 0x6d2bb67b, 0x3bdc5379, 0x74e662d8, 0x80348f8c, 0xf875e638, 0x5a8caea1, + 0x2459ae75, 0x2c54b939, 0x79ee3203, 0xb9bc8683, 0x9b6f630c, 0x9f45b351, 0x8563b2b9, 0xe5dbba41, + 0x697c7d0d, 0x7bb7c90e, 0xac900866, 0x8e6b5177, 0x8822dd37, 0x7fd5a91e, 0x7506da05, 0x82302aca, + 0xa5e4be04, 0x4b4288eb, 0x00b8bc9f, 0x4f1033e4, 0x7200d612, 0x43900c8c, 0xa815b900, 0x676ed1d4, + 0x5c5f23b2, 0xa758ee11, 0xaf73abfa, 0x11714ec0, 0x265239e0, 0xc50de679, 0x8a84e341, 0xa1438354, + 0x7f1a341f, 0x343ec96b, 0x696e71b0, 0xa13bde39, 0x81e75094, 0x80091111, 0x853a73bf, 0x80f9c1ee, + 0xe4980086, 0x886a8e28, 0xa7e89426, 0xdd93edd7, 0x7592100d, 0x0bfa8123, 0x850a26d4, 0x2e34f395, + 0x421b6c00, 0xa4a462e4, 0x4e3f5090, 0x3c189f4c, 0x3c971a56, 0xdd0376d2, 0x747a5367, 0x7bcbc9d7, + 0x3966be6a, 0x7efda616, 0x55445e15, 0x7ba2ab3f, 0x5fe684f2, 0x8cf42af9, 0x808c61c3, 0x4390c27b, + 0x7cac62ff, 0xea6cab22, 0x5d0902ad, 0xc27b7208, 0x7a27389d, 0x5820a357, 0xa29bbe59, 0x9df0f1fd, + 0x92bd67e5, 0x7195b587, 0x97cac65b, 0x8339807e, 0x8f72d832, 0x5fad8685, 0xa462d9d3, 0x81d46214, + 0x6ae93e1d, 0x6b23a5b9, 0xc2732874, 0x81795268, 0x7c568cb6, 0x668513ea, 0x428d024e, 0x66b78b3a, + 0xfee9ef03, 0x9ddcbb82, 0xa605f07e, 0x46dc55e0, 0x85415054, 0xc89ec271, 0x7c42edfb, 0x0befe59b, + 0x89b8f607, 0x6d732a1a, 0xa7081ebd, 0x7e403258, 0x21feeb7b, 0x5dd7a1e7, 0x23e3a31a, 0x129bc896, + 0xa11a6b54, 0x7f1e031c, 0xfdc1a4d1, 0x96402e53, 0xb9700f1a, 0x8168ecd6, 0x7d63d3cc, 0x87a70d65, + 0x81075a7a, 0x55c8caa7, 0xa95d00b5, 0x102b1652, 0x0bb30215, 0xe5b63237, 0xa446ca44, 0x82d4c333, + 0x67b2e094, 0x44c3d661, 0x33fd6036, 0xde1ea2a1, 0xa95e8e47, 0x78f66eb9, 0x6f2aef1e, 0xe8887247, + 0x80a3b70e, 0xfca0d9d3, 0x6bf0fd20, 0x0d5226de, 0xf4341c87, 0x5902df05, 0x7ff1a38d, 0xf02e5a5b, + 0x99f129af, 0x8ac63d01, 0x7b53f599, 0x7bb32532, 0x99ac59b0, 0x5255a80f, 0xf1320a41, 0x2497aa5c, + 0xcce60bd8, 0x787c634b, 0x7ed58c5b, 0x8a28eb3a, 0x24a5e647, 0x8b79a2c1, 0x955f5ce5, 0xa9d12bc4, + 0x7a1e20c6, 0x3eeda7ac, 0xf7be823a, 0x042924ce, 0x808b3f03, 0x364248da, 0xac2895e5, 0x69a8b5fa, + 0x97fe8b63, 0xbdeac9aa, 0x8073e0ad, 0x6c25dba7, 0x005e51d2, 0x52e74389, 0x59d3988c, 0xe5d1f39c, + 0x7b57dc91, 0x341adbe7, 0xa7d42b8d, 0x74e9f335, 0xd35bf7d8, 0x5b7c0a4b, 0x75bc0874, 0x552129bf, + 0x8144b70d, 0x6de93bbb, 0x5825f14b, 0x473ec5ca, 0x80a8f37c, 0xe6552d69, 0x7898360b, 0x806379b0, + 0xa9b59339, 0x3f6bf60c, 0xc367d731, 0x920ade99, 0x125592f7, 0x877e5ed1, 0xda895d95, 0x075f2ece, + 0x380e5f5e, 0x9b006b62, 0xd17a6dd2, 0x530a0e13, 0xf4cc9a14, 0x7d0a0ed4, 0x847c6e3f, 0xbaee4975, + 0x47131163, 0x64fb2cac, 0x5e2100a6, 0x7b756a42, 0xd87609f4, 0x98bfe48c, 0x0493745e, 0x836c5784, + 0x7e5ccb40, 0x3df6b476, 0x97700d28, 0x8bbd93fd, 0x56de9cdb, 0x680b4e65, 0xebc3d90e, 0x6d286793, + 0x6753712e, 0xe05c98a7, 0x3d2b6b85, 0xc4b18ddb, 0x7b59b869, 0x31435688, 0x811888e9, 0xe011ee7a, + 0x6a5844f9, 0x86ae35ea, 0xb4cbc10b, 0x01a6f5d6, 0x7a49ed64, 0x927caa49, 0x847ddaed, 0xae0d9bb6, + 0x836bdb04, 0x0fd810a6, 0x74fe126b, 0x4a346b5f, 0x80184d36, 0x5afd153c, 0x90cc8102, 0xe606d0e6, + 0xde69aa58, 0xa89f1222, 0xe06df715, 0x8fd16144, 0x0317c3e8, 0x22ce92fc, 0x690c3eca, 0x93166f02, + 0x71573414, 0x8d43cffb, 0xe8bd0bb6, 0xde86770f, 0x0bf99a41, 0x4633a661, 0xba064108, 0x7adafae3, + 0x2f6cde5d, 0xb350a52c, 0xa5ebfb0b, 0x74c57b46, 0xd3b603b5, 0x80b70892, 0xa7f7fa53, 0xd94b566c, + 0xdda3fd86, 0x6a635793, 0x3ed005ca, 0xc5f087d8, 0x31e3a746, 0x7a4278f9, 0x82def1f9, 0x06caa2b2, + 0xe9d2c349, 0x8940e7f7, 0x7feef8dd, 0x4a9b01f0, 0xacde69f8, 0x57ddc280, 0xf09e4ba4, 0xb6d9f729, + 0xb48c18f2, 0xd3654aa9, 0xca7a03c8, 0x14d57545, 0x7fda87a5, 0x0e411366, 0xb77d0df0, 0x8c2aa467, + 0x787f2590, 0x2d292db1, 0x9f12682c, 0x44ac364d, 0x1a4b31a6, 0x871f7ded, 0x7ff99167, 0x6630a1d5, + 0x25385eb9, 0x2d4dd549, 0xaf8a7004, 0x319ebe0f, 0x379ab730, 0x81dc56a4, 0x822d8523, 0x1ae8554c, + 0x18fa0786, 0x875f7de4, 0x85ca350f, 0x7de818dc, 0x7786a38f, 0xa5456355, 0x92e60f88, 0xf5526122, + 0x916039bc, 0xc561e2de, 0x31c42042, 0x7c82e290, 0x75d158b2, 0xb015bda1, 0x7220c750, 0x46565441, + 0xd0da1fdd, 0x7b777481, 0x782e73c6, 0x8cd72b7b, 0x7f1006aa, 0xfb30e51e, 0x87994818, 0x34e7c7db, + 0x7faae06b, 0xea74fbc0, 0xd20c7af4, 0xc44f396b, 0x06b4234e, 0xdf2e2a93, 0x2efb07c8, 0xce861911, + 0x7550ea05, 0xd8d90bbb, 0x58522eec, 0x746b3520, 0xce844ce9, 0x7f5cacc3, 0xda8f17e0, 0x2fedf9cb, + 0xb2f77ec4, 0x6f13f4c0, 0x834de085, 0x7b7ace4b, 0x713b16ac, 0x499c5ab0, 0x06a7961d, 0x1b39a48a, + 0xbb853e6e, 0x7c781cc1, 0xc0baebf5, 0x7dace394, 0x815ceebc, 0xcc7b27d4, 0x8274b181, 0xa2be40a2, + 0xdd01d5dc, 0x7fefeb14, 0x0813ec78, 0xba3077cc, 0xe5cf1e1c, 0xedcfacae, 0x54c43a9b, 0x5cd62a42, + 0x93806b55, 0x03095c5b, 0x8e076ae3, 0x71bfcd2a, 0x7ac1989b, 0x623bc71a, 0x5e15d4d2, 0xfb341dd1, + 0xd75dfbca, 0xd0da32be, 0xd4569063, 0x337869da, 0x3d30606a, 0xcd89cca2, 0x7dd2ae36, 0x028c03cd, + 0xd85e052c, 0xe8dc9ec5, 0x7ffd9241, 0xde5bf4c6, 0x88c4b235, 0x8228be2e, 0x7fe6ec64, 0x996abe6a, + 0xdeb0666d, 0x9eb86611, 0xd249b922, 0x18b3e26b, 0x80211168, 0x5f8bb99c, 0x6ecb0dd2, 0x4728ff8d, + 0x2ac325b8, 0x6e5169d2, 0x7ebbd68d, 0x05e41d17, 0xaaa19f28, 0x8ab238a6, 0x51f105be, 0x140809cc, + 0x7f7345d9, 0x3aae5a9d, 0xaecec6e4, 0x1afb3473, 0xf6229ed1, 0x8d55f467, 0x7e32003a, 0x70f30c14, + 0x6686f33f, 0xd0d45ed8, 0x644fab57, 0x3a3fbbd3, 0x0b255fc4, 0x679a1701, 0x90e17b6e, 0x325d537b, + 0xcd7b9b87, 0xaa7be2a2, 0x7d47c966, 0xa33dbce5, 0x8659c3bb, 0x72a41367, 0x15c446e0, 0x45fe8b0a, + 0x9d8ddf26, 0x84d47643, 0x7fabe0da, 0x36a70122, 0x7a28ebfe, 0x7c29b8b8, 0x7f760406, 0xbabe4672, + 0x23ea216e, 0x92bcc50a, 0x6d20dba2, 0xad5a7c7e, 0xbf3897f5, 0xabb793e1, 0x8391fc7e, 0xe270291c, + 0x7a248d58, 0x80f8fd15, 0x83ef19f3, 0x5e6ece7d, 0x278430c1, 0x35239f4d, 0xe09c073b, 0x50e78cb5, + 0xd4b811bd, 0xce834ee0, 0xf88aaa34, 0xf71da5a9, 0xe2b0a1d5, 0x7c3aef31, 0xe84eabca, 0x3ce25964, + 0xf29336d3, 0x8fa78b2c, 0xa3fc3415, 0x63e1313d, 0x7fbc74e0, 0x7340bc93, 0x49ae583b, 0x8b79de4b, + 0x25011ce9, 0x7b462279, 0x36007db0, 0x3da1599c, 0x77780772, 0xc845c9bb, 0x83ba68be, 0x6ee507d1, + 0x2f0159b8, 0x5392c4ed, 0x98336ff6, 0x0b3c7f11, 0xde697aac, 0x893fc8d0, 0x6b83f8f3, 0x47799a0d, + 0x801d9dfc, 0x8516a83e, 0x5f8d22ec, 0x0f8ba384, 0xa049dc4b, 0xdd920b05, 0x7a99bc9f, 0x9ad19344, + 0x7a345dba, 0xf501a13f, 0x3e58bf19, 0x7fffaf9a, 0x3b4e1511, 0x0e08b991, 0x9e157620, 0x7230a326, + 0x4977f9ff, 0x2d2bbae1, 0x607aa7fc, 0x7bc85d5f, 0xb441bbbe, 0x8d8fa5f2, 0x601cce26, 0xda1884f2, + 0x81c82d64, 0x200b709c, 0xcbd36abe, 0x8cbdddd3, 0x55ab61d3, 0x7e3ee993, 0x833f18aa, 0xffc1aaea, + 0x7362e16a, 0x7fb85db2, 0x904ee04c, 0x7f04dca6, 0x8ad7a046, 0xebe7d8f7, 0xfbc4c687, 0xd0609458, + 0x093ed977, 0x8e546085, 0x7f5b8236, 0x7c47e118, 0xa01f2641, 0x7ffb3e48, 0x05de7cda, 0x7fc281b9, + 0x8e0278fc, 0xd74e6d07, 0x94c24450, 0x7cf9e641, 0x2ad27871, 0x919fa815, 0x805fd205, 0x7758397f, + 0xe2c7e02c, 0x1828e194, 0x5613d6fe, 0xfb55359f, 0xf9699516, 0x8978ee26, 0x7feebad9, 0x77d71d82, + 0x55b28b60, 0x7e997600, 0x80821a6b, 0xc6d78af1, 0x691822ab, 0x7f6982a0, 0x7ef56f99, 0x5c307f40, + 0xac6f8b76, 0x42cc8ba4, 0x782c61d9, 0xa0224dd0, 0x7bd234d1, 0x74576e3b, 0xe38cfe9a, 0x491e66ef, + 0xc78291c5, 0x895bb87f, 0x924f7889, 0x71b89394, 0x757b779d, 0xc4a9c604, 0x5cdf7829, 0x8020e9df, + 0x805e8245, 0x4a82c398, 0x6360bd62, 0x78bb60fc, 0x09e0d014, 0x4b0ea180, 0xb841978b, 0x69a0e864, + 0x7df35977, 0x3284b0dd, 0x3cdc2efd, 0x57d31f5e, 0x541069cc, 0x1776e92e, 0x04309ea3, 0xa015eb2d, + 0xce7bfabc, 0x41b638f8, 0x8365932e, 0x846ab44c, 0xbbcc80cb, 0x8afa6cac, 0x7fc422ea, 0x4e403fc0, + 0xbfac9aee, 0x8e4c6709, 0x028e01fb, 0x6d160a9b, 0x7fe93004, 0x790f9cdc, 0x6a1f37a0, 0xf7e7ef30, + 0xb4ea0f04, 0x7bf4c8e6, 0xe981701f, 0xc258a9d3, 0x6acbbfba, 0xef5479c7, 0x079c8bd8, 0x1a410f56, + 0x6853b799, 0x86cd4f01, 0xc66e23b6, 0x34585565, 0x8d1fe00d, 0x7fcdba1a, 0x32c9717b, 0xa02f9f48, + 0xf64940db, 0x5ed7d8f1, 0x61b823b2, 0x356f8918, 0xa0a7151e, 0x793fc969, 0x530beaeb, 0x34e93270, + 0x4fc4ddb5, 0x88d58b6c, 0x36094774, 0xf620ac80, 0x03763a72, 0xf910c9a6, 0x6666fb2d, 0x752c8be8, + 0x9a6dfdd8, 0xd1a7117d, 0x51c1b1d4, 0x0a67773d, 0x43b32a79, 0x4cdcd085, 0x5f067d30, 0x05bfe92a, + 0x7ed7d203, 0xe71a3c85, 0x99127ce2, 0x8eb3cac4, 0xad4bbcea, 0x5c6a0fd0, 0x0eec04af, 0x94e95cd4, + 0x8654f921, 0x83eabb5d, 0xb058d7ca, 0x69f12d3c, 0x03d881b2, 0x80558ef7, 0x82938cb3, 0x2ec0e1d6, + 0x80044422, 0xd1e47051, 0x720fc6ff, 0x82b20316, 0x0d527b02, 0x63049a15, 0x7ad5b9ad, 0xd2a4641d, + 0x41144f86, 0x7b04917a, 0x15c4a2c0, 0x9da07916, 0x211df54a, 0x7fdd09af, 0xfe924f3f, 0x7e132cfe, + 0x9a1d18d6, 0x7c56508b, 0x80f0f0af, 0x8095ced6, 0x8037d0d7, 0x026719d1, 0xa55fec43, 0x2b1c7cb7, + 0xa5cd5ac1, 0x77639fad, 0x7fcd8b62, 0x81a18c27, 0xaee4912e, 0xeae9eebe, 0xeb3081de, 0x8532aada, + 0xc822362e, 0x86a649a9, 0x8031a71d, 0x7b319dc6, 0xea8022e6, 0x814bc5a9, 0x8f62f7a1, 0xa430ea17, + 0x388deafb, 0x883b5185, 0x776fe13c, 0x801c683f, 0x87c11b98, 0xb7cbc644, 0x8e9ad3e8, 0x3cf5a10c, + 0x7ff6a634, 0x949ef096, 0x9f84aa7c, 0x010af13f, 0x782d1de8, 0xf18e492a, 0x6cf63b01, 0x4301cd81, + 0x32d15c9e, 0x68ad8cef, 0xd09bd2d6, 0x908c5c15, 0xd1e36260, 0x2c5bfdd0, 0x88765a99, 0x93deba1e, + 0xac6ae342, 0xe865b84c, 0x0f4f2847, 0x7fdf0499, 0x78b1c9b3, 0x6a73261e, 0x601a96f6, 0xd2847933, + 0x489aa888, 0xe12e8093, 0x3bfa5a5f, 0xd96ba5f7, 0x7c8f4c8d, 0x80940c6f, 0xcef9dd1a, 0x7e1a055f, + 0x3483558b, 0x02b59cc4, 0x0c56333e, 0x05a5b813, 0x92d66287, 0x7516b679, 0x71bfe03f, 0x8056bf68, + 0xc24d0724, 0x8416bcf3, 0x234afbdb, 0x4b0d6f9c, 0xaba97333, 0x4b4f42b6, 0x7e8343ab, 0x7ffe2603, + 0xe590f73c, 0x45e10c76, 0xb07a6a78, 0xb35609d3, 0x1a027dfd, 0x90cb6e20, 0x82d3fe38, 0x7b409257, + 0x0e395afa, 0x1b802093, 0xcb0c6c59, 0x241e17e7, 0x1ee3ea0a, 0x41a82302, 0xab04350a, 0xf570beb7, + 0xbb444b9b, 0x83021459, 0x838d65dc, 0x1c439c84, 0x6fdcc454, 0xef9ef325, 0x18626c1c, 0x020d251f, + 0xc4aae786, 0x8614cb48, 0xf6f53ca6, 0x8710dbab, 0x89abec0d, 0xf29d41c1, 0x94b50336, 0xfdd49178, + 0x604658d1, 0x800e85be, 0xca1bb079, 0x7fa48eeb, 0xa3b7fafe, 0xd330436b, 0x64eb604c, 0x43a658ae, + 0x7caa1337, 0xddd445e6, 0x7efbf955, 0xb706ec71, 0x624a6b53, 0x9e0e231f, 0x97097248, 0xa1e1a17a, + 0x68dd2e44, 0x7f9d2e14, 0xddcc7074, 0x58324197, 0xc88fc426, 0x6d3640ae, 0x7ef83600, 0x759a0270, + 0x98b6d854, 0xd63c9b84, 0x372474a2, 0xe3f18cfd, 0x56ab0bdb, 0x85c9be7e, 0x47dfcfeb, 0xa5830d41, + 0x0ddd6283, 0xf4f480ad, 0x74c60e38, 0xab8943c3, 0xc1508fe7, 0x480cdc39, 0x8e097362, 0xa44793be, + 0x538b7e18, 0x545f5b41, 0x56529175, 0x9771a97e, 0xc2da7421, 0xea8265f2, 0x805d1163, 0x883c5d28, + 0x8ba94c48, 0x4f676e65, 0xf78735b3, 0xe1853671, 0x7f454f53, 0x18147f85, 0x7d09e15d, 0xdb4f3494, + 0x795c8973, 0x83310632, 0x85d8061c, 0x9a1a0ebf, 0xc125583c, 0x2a1b1a95, 0x7fd9103f, 0x71e98c72, + 0x40932ed7, 0x91ed227a, 0x3c5e560e, 0xe816dee9, 0xb0891b80, 0x600038ba, 0xc7d9a80d, 0x7fff5e09, + 0x7e3f4351, 0xbb6b4424, 0xb14448d4, 0x8d6bb7e1, 0xfb153626, 0xa68ad537, 0xd9782006, 0xf62f6991, + 0x359ba8c1, 0x02ccff0b, 0x91bf2256, 0x7ea71c4d, 0x560ce5df, 0xeeba289b, 0xa574c4e7, 0x9e04f6ee, + 0x7860a5ec, 0x0b8db4a2, 0x968ba3d7, 0x0b6c77df, 0xd6f3157d, 0x402eff1a, 0x49b820b3, 0x8152aebb, + 0xd180b0b6, 0x098604d4, 0x7ff92224, 0xede9c996, 0x89c58061, 0x829624c4, 0xc6e71ea7, 0xba94d915, + 0x389c3cf6, 0x5b4c5a06, 0x04b335e6, 0x516a8aab, 0x42c8d7d9, 0x92b12af6, 0x86c8549f, 0xfda98acf, + 0x819673b6, 0x69545dac, 0x6feaa230, 0x726e6d3f, 0x886ebdfe, 0x34f5730a, 0x7af63ba2, 0x77307bbf, + 0x7cd80630, 0x6e45efe0, 0x7f8ad7eb, 0x59d7df99, 0x86c70946, 0xda233629, 0x753f6cbf, 0x825eeb40, }; diff --git a/src/libhelix-aac/statname.h b/src/libhelix-aac/statname.h index a27f04d5..2899ca93 100644 --- a/src/libhelix-aac/statname.h +++ b/src/libhelix-aac/statname.h @@ -1,59 +1,59 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: statname.h,v 1.1 2005/02/26 01:47:34 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: statname.h,v 1.1 2005/02/26 01:47:34 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * statname.h - name mangling macros for static linking + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + statname.h - name mangling macros for static linking **************************************************************************************/ #ifndef _STATNAME_H #define _STATNAME_H -/* define STAT_PREFIX to a unique name for static linking - * all the C functions and global variables will be mangled by the preprocessor - * e.g. void DCT4(...) becomes void raac_DCT4(...) - */ +/* define STAT_PREFIX to a unique name for static linking + all the C functions and global variables will be mangled by the preprocessor + e.g. void DCT4(...) becomes void raac_DCT4(...) +*/ #define STAT_PREFIX raac #define STATCC1(x,y,z) STATCC2(x,y,z) -#define STATCC2(x,y,z) x##y##z +#define STATCC2(x,y,z) x##y##z #ifdef STAT_PREFIX #define STATNAME(func) STATCC1(STAT_PREFIX, _, func) @@ -106,10 +106,10 @@ #define tnsMaxBandsLong STATNAME(tnsMaxBandsLong) #define tnsMaxOrderLong STATNAME(tnsMaxOrderLong) -/* in your implementation's top-level include file (e.g. real\coder.h) you should - * add new #define sym STATNAME(sym) lines for all the - * additional global functions or variables which your - * implementation uses - */ +/* in your implementation's top-level include file (e.g. real\coder.h) you should + add new #define sym STATNAME(sym) lines for all the + additional global functions or variables which your + implementation uses +*/ #endif /* _STATNAME_H */ diff --git a/src/libhelix-aac/stproc.c b/src/libhelix-aac/stproc.c index 93854e45..e329e137 100644 --- a/src/libhelix-aac/stproc.c +++ b/src/libhelix-aac/stproc.c @@ -1,246 +1,252 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: stproc.c,v 1.3 2005/05/24 16:01:55 albertofloyd Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: stproc.c,v 1.3 2005/05/24 16:01:55 albertofloyd Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * stproc.c - mid-side and intensity stereo processing + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + stproc.c - mid-side and intensity stereo processing **************************************************************************************/ #include "coder.h" #include "assembly.h" -/* pow14[0][i] = -pow(2, i/4.0) - * pow14[1][i] = +pow(2, i/4.0) - * - * i = [0,1,2,3] - * format = Q30 - */ +/* pow14[0][i] = -pow(2, i/4.0) + pow14[1][i] = +pow(2, i/4.0) + + i = [0,1,2,3] + format = Q30 +*/ /************************************************************************************** - * Function: StereoProcessGroup - * - * Description: apply mid-side and intensity stereo to group of transform coefficients - * - * Inputs: dequantized transform coefficients for both channels - * pointer to appropriate scalefactor band table - * mid-side mask enabled flag - * buffer with mid-side mask (one bit for each scalefactor band) - * bit offset into mid-side mask buffer - * max coded scalefactor band - * buffer of codebook indices for right channel - * buffer of scalefactors for right channel, range = [0, 256] - * - * Outputs: updated transform coefficients in Q(FBITS_OUT_DQ_OFF) - * updated minimum guard bit count for both channels - * - * Return: none - * - * Notes: assume no guard bits in input - * gains 0 int bits + Function: StereoProcessGroup + + Description: apply mid-side and intensity stereo to group of transform coefficients + + Inputs: dequantized transform coefficients for both channels + pointer to appropriate scalefactor band table + mid-side mask enabled flag + buffer with mid-side mask (one bit for each scalefactor band) + bit offset into mid-side mask buffer + max coded scalefactor band + buffer of codebook indices for right channel + buffer of scalefactors for right channel, range = [0, 256] + + Outputs: updated transform coefficients in Q(FBITS_OUT_DQ_OFF) + updated minimum guard bit count for both channels + + Return: none + + Notes: assume no guard bits in input + gains 0 int bits **************************************************************************************/ -static void StereoProcessGroup(int *coefL, int *coefR, const /*short*/ int *sfbTab, - int msMaskPres, unsigned char *msMaskPtr, int msMaskOffset, int maxSFB, - unsigned char *cbRight, short *sfRight, int *gbCurrent) -{ -//fb +static void StereoProcessGroup(int *coefL, int *coefR, const /*short*/ int *sfbTab, + int msMaskPres, unsigned char *msMaskPtr, int msMaskOffset, int maxSFB, + unsigned char *cbRight, short *sfRight, int *gbCurrent) { + //fb #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnarrowing" -static const int pow14[2][4] PROGMEM = { - { 0xc0000000, 0xb3e407d7, 0xa57d8666, 0x945d819b }, - { 0x40000000, 0x4c1bf829, 0x5a82799a, 0x6ba27e65 } -}; + static const int pow14[2][4] PROGMEM = { + { 0xc0000000, 0xb3e407d7, 0xa57d8666, 0x945d819b }, + { 0x40000000, 0x4c1bf829, 0x5a82799a, 0x6ba27e65 } + }; #pragma GCC diagnostic pop - int sfb, width, cbIdx, sf, cl, cr, scalef, scalei; - int gbMaskL, gbMaskR; - unsigned char msMask; - - msMask = (*msMaskPtr++) >> msMaskOffset; - gbMaskL = 0; - gbMaskR = 0; - - for (sfb = 0; sfb < maxSFB; sfb++) { - width = sfbTab[sfb+1] - sfbTab[sfb]; /* assume >= 0 (see sfBandTabLong/sfBandTabShort) */ - cbIdx = cbRight[sfb]; - - if (cbIdx == 14 || cbIdx == 15) { - /* intensity stereo */ - if (msMaskPres == 1 && (msMask & 0x01)) - cbIdx ^= 0x01; /* invert_intensity(): 14 becomes 15, or 15 becomes 14 */ - sf = -sfRight[sfb]; /* negative since we use identity 0.5^(x) = 2^(-x) (see spec) */ - cbIdx &= 0x01; /* choose - or + scale factor */ - scalef = pow14[cbIdx][sf & 0x03]; - scalei = (sf >> 2) + 2; /* +2 to compensate for scalef = Q30 */ - - if (scalei > 0) { - if (scalei > 30) - scalei = 30; - do { - cr = MULSHIFT32(*coefL++, scalef); - CLIP_2N(cr, 31-scalei); - cr <<= scalei; - gbMaskR |= FASTABS(cr); - *coefR++ = cr; - } while (--width); - } else { - scalei = -scalei; - if (scalei > 31) - scalei = 31; - do { - cr = MULSHIFT32(*coefL++, scalef) >> scalei; - gbMaskR |= FASTABS(cr); - *coefR++ = cr; - } while (--width); - } - } else if ( cbIdx != 13 && ((msMaskPres == 1 && (msMask & 0x01)) || msMaskPres == 2) ) { - /* mid-side stereo (assumes no GB in inputs) */ - do { - cl = *coefL; - cr = *coefR; - - if ( (FASTABS(cl) | FASTABS(cr)) >> 30 ) { - /* avoid overflow (rare) */ - cl >>= 1; - sf = cl + (cr >> 1); CLIP_2N(sf, 30); sf <<= 1; - cl = cl - (cr >> 1); CLIP_2N(cl, 30); cl <<= 1; - } else { - /* usual case */ - sf = cl + cr; - cl -= cr; - } - - *coefL++ = sf; - gbMaskL |= FASTABS(sf); - *coefR++ = cl; - gbMaskR |= FASTABS(cl); - } while (--width); - - } else { - /* nothing to do */ - coefL += width; - coefR += width; - } - - /* get next mask bit (should be branchless on ARM) */ - msMask >>= 1; - if (++msMaskOffset == 8) { - msMask = *msMaskPtr++; - msMaskOffset = 0; - } - } - - cl = CLZ(gbMaskL) - 1; - if (gbCurrent[0] > cl) - gbCurrent[0] = cl; - - cr = CLZ(gbMaskR) - 1; - if (gbCurrent[1] > cr) - gbCurrent[1] = cr; - - return; + int sfb, width, cbIdx, sf, cl, cr, scalef, scalei; + int gbMaskL, gbMaskR; + unsigned char msMask; + + msMask = (*msMaskPtr++) >> msMaskOffset; + gbMaskL = 0; + gbMaskR = 0; + + for (sfb = 0; sfb < maxSFB; sfb++) { + width = sfbTab[sfb + 1] - sfbTab[sfb]; /* assume >= 0 (see sfBandTabLong/sfBandTabShort) */ + cbIdx = cbRight[sfb]; + + if (cbIdx == 14 || cbIdx == 15) { + /* intensity stereo */ + if (msMaskPres == 1 && (msMask & 0x01)) { + cbIdx ^= 0x01; /* invert_intensity(): 14 becomes 15, or 15 becomes 14 */ + } + sf = -sfRight[sfb]; /* negative since we use identity 0.5^(x) = 2^(-x) (see spec) */ + cbIdx &= 0x01; /* choose - or + scale factor */ + scalef = pow14[cbIdx][sf & 0x03]; + scalei = (sf >> 2) + 2; /* +2 to compensate for scalef = Q30 */ + + if (scalei > 0) { + if (scalei > 30) { + scalei = 30; + } + do { + cr = MULSHIFT32(*coefL++, scalef); + CLIP_2N(cr, 31 - scalei); + cr <<= scalei; + gbMaskR |= FASTABS(cr); + *coefR++ = cr; + } while (--width); + } else { + scalei = -scalei; + if (scalei > 31) { + scalei = 31; + } + do { + cr = MULSHIFT32(*coefL++, scalef) >> scalei; + gbMaskR |= FASTABS(cr); + *coefR++ = cr; + } while (--width); + } + } else if (cbIdx != 13 && ((msMaskPres == 1 && (msMask & 0x01)) || msMaskPres == 2)) { + /* mid-side stereo (assumes no GB in inputs) */ + do { + cl = *coefL; + cr = *coefR; + + if ((FASTABS(cl) | FASTABS(cr)) >> 30) { + /* avoid overflow (rare) */ + cl >>= 1; + sf = cl + (cr >> 1); CLIP_2N(sf, 30); sf <<= 1; + cl = cl - (cr >> 1); CLIP_2N(cl, 30); cl <<= 1; + } else { + /* usual case */ + sf = cl + cr; + cl -= cr; + } + + *coefL++ = sf; + gbMaskL |= FASTABS(sf); + *coefR++ = cl; + gbMaskR |= FASTABS(cl); + } while (--width); + + } else { + /* nothing to do */ + coefL += width; + coefR += width; + } + + /* get next mask bit (should be branchless on ARM) */ + msMask >>= 1; + if (++msMaskOffset == 8) { + msMask = *msMaskPtr++; + msMaskOffset = 0; + } + } + + cl = CLZ(gbMaskL) - 1; + if (gbCurrent[0] > cl) { + gbCurrent[0] = cl; + } + + cr = CLZ(gbMaskR) - 1; + if (gbCurrent[1] > cr) { + gbCurrent[1] = cr; + } + + return; } /************************************************************************************** - * Function: StereoProcess - * - * Description: apply mid-side and intensity stereo, if enabled - * - * Inputs: valid AACDecInfo struct (including dequantized transform coefficients) - * - * Outputs: updated transform coefficients in Q(FBITS_OUT_DQ_OFF) - * updated minimum guard bit count for both channels - * - * Return: 0 if successful, -1 if error + Function: StereoProcess + + Description: apply mid-side and intensity stereo, if enabled + + Inputs: valid AACDecInfo struct (including dequantized transform coefficients) + + Outputs: updated transform coefficients in Q(FBITS_OUT_DQ_OFF) + updated minimum guard bit count for both channels + + Return: 0 if successful, -1 if error **************************************************************************************/ -int StereoProcess(AACDecInfo *aacDecInfo) -{ - PSInfoBase *psi; - ICSInfo *icsInfo; - int gp, win, nSamps, msMaskOffset; - int *coefL, *coefR; - unsigned char *msMaskPtr; - const /*short*/ int *sfbTab; - - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return -1; - psi = (PSInfoBase *)(aacDecInfo->psInfoBase); - - /* mid-side and intensity stereo require common_window == 1 (see MPEG4 spec, Correction 2, 2004) */ - if (psi->commonWin != 1 || aacDecInfo->currBlockID != AAC_ID_CPE) - return 0; - - /* nothing to do */ - if (!psi->msMaskPresent && !psi->intensityUsed[1]) - return 0; - - icsInfo = &(psi->icsInfo[0]); - if (icsInfo->winSequence == 2) { - sfbTab = sfBandTabShort + sfBandTabShortOffset[psi->sampRateIdx]; - nSamps = NSAMPS_SHORT; - } else { - sfbTab = sfBandTabLong + sfBandTabLongOffset[psi->sampRateIdx]; - nSamps = NSAMPS_LONG; - } - coefL = psi->coef[0]; - coefR = psi->coef[1]; - - /* do fused mid-side/intensity processing for each block (one long or eight short) */ - msMaskOffset = 0; - msMaskPtr = psi->msMaskBits; - for (gp = 0; gp < icsInfo->numWinGroup; gp++) { - for (win = 0; win < icsInfo->winGroupLen[gp]; win++) { - StereoProcessGroup(coefL, coefR, sfbTab, psi->msMaskPresent, - msMaskPtr, msMaskOffset, icsInfo->maxSFB, psi->sfbCodeBook[1] + gp*icsInfo->maxSFB, - psi->scaleFactors[1] + gp*icsInfo->maxSFB, psi->gbCurrent); - coefL += nSamps; - coefR += nSamps; - } - /* we use one bit per sfb, so there are maxSFB bits for each window group */ - msMaskPtr += (msMaskOffset + icsInfo->maxSFB) >> 3; - msMaskOffset = (msMaskOffset + icsInfo->maxSFB) & 0x07; - } - - ASSERT(coefL == psi->coef[0] + 1024); - ASSERT(coefR == psi->coef[1] + 1024); - - return 0; +int StereoProcess(AACDecInfo *aacDecInfo) { + PSInfoBase *psi; + ICSInfo *icsInfo; + int gp, win, nSamps, msMaskOffset; + int *coefL, *coefR; + unsigned char *msMaskPtr; + const /*short*/ int *sfbTab; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return -1; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + + /* mid-side and intensity stereo require common_window == 1 (see MPEG4 spec, Correction 2, 2004) */ + if (psi->commonWin != 1 || aacDecInfo->currBlockID != AAC_ID_CPE) { + return 0; + } + + /* nothing to do */ + if (!psi->msMaskPresent && !psi->intensityUsed[1]) { + return 0; + } + + icsInfo = &(psi->icsInfo[0]); + if (icsInfo->winSequence == 2) { + sfbTab = sfBandTabShort + sfBandTabShortOffset[psi->sampRateIdx]; + nSamps = NSAMPS_SHORT; + } else { + sfbTab = sfBandTabLong + sfBandTabLongOffset[psi->sampRateIdx]; + nSamps = NSAMPS_LONG; + } + coefL = psi->coef[0]; + coefR = psi->coef[1]; + + /* do fused mid-side/intensity processing for each block (one long or eight short) */ + msMaskOffset = 0; + msMaskPtr = psi->msMaskBits; + for (gp = 0; gp < icsInfo->numWinGroup; gp++) { + for (win = 0; win < icsInfo->winGroupLen[gp]; win++) { + StereoProcessGroup(coefL, coefR, sfbTab, psi->msMaskPresent, + msMaskPtr, msMaskOffset, icsInfo->maxSFB, psi->sfbCodeBook[1] + gp * icsInfo->maxSFB, + psi->scaleFactors[1] + gp * icsInfo->maxSFB, psi->gbCurrent); + coefL += nSamps; + coefR += nSamps; + } + /* we use one bit per sfb, so there are maxSFB bits for each window group */ + msMaskPtr += (msMaskOffset + icsInfo->maxSFB) >> 3; + msMaskOffset = (msMaskOffset + icsInfo->maxSFB) & 0x07; + } + + ASSERT(coefL == psi->coef[0] + 1024); + ASSERT(coefR == psi->coef[1] + 1024); + + return 0; } diff --git a/src/libhelix-aac/tns.c b/src/libhelix-aac/tns.c index 87726067..e8f65669 100644 --- a/src/libhelix-aac/tns.c +++ b/src/libhelix-aac/tns.c @@ -1,46 +1,46 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: tns.c,v 1.2 2005/05/24 16:01:55 albertofloyd Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: tns.c,v 1.2 2005/05/24 16:01:55 albertofloyd Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com) - * February 2005 - * - * tns.c - apply TNS to spectrum + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com) + February 2005 + + tns.c - apply TNS to spectrum **************************************************************************************/ #include "coder.h" @@ -52,249 +52,259 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnarrowing" -/* inverse quantization tables for TNS filter coefficients, format = Q31 - * see bottom of file for table generation - * negative (vs. spec) since we use MADD for filter kernel - */ +/* inverse quantization tables for TNS filter coefficients, format = Q31 + see bottom of file for table generation + negative (vs. spec) since we use MADD for filter kernel +*/ static const int invQuant3[16] PROGMEM = { - 0x00000000, 0xc8767f65, 0x9becf22c, 0x83358feb, 0x83358feb, 0x9becf22c, 0xc8767f65, 0x00000000, - 0x2bc750e9, 0x5246dd49, 0x6ed9eba1, 0x7e0e2e32, 0x7e0e2e32, 0x6ed9eba1, 0x5246dd49, 0x2bc750e9, + 0x00000000, 0xc8767f65, 0x9becf22c, 0x83358feb, 0x83358feb, 0x9becf22c, 0xc8767f65, 0x00000000, + 0x2bc750e9, 0x5246dd49, 0x6ed9eba1, 0x7e0e2e32, 0x7e0e2e32, 0x6ed9eba1, 0x5246dd49, 0x2bc750e9, }; static const int invQuant4[16] PROGMEM = { - 0x00000000, 0xe5632654, 0xcbf00dbe, 0xb4c373ee, 0xa0e0a15f, 0x9126145f, 0x8643c7b3, 0x80b381ac, - 0x7f7437ad, 0x7b1d1a49, 0x7294b5f2, 0x66256db2, 0x563ba8aa, 0x4362210e, 0x2e3d2abb, 0x17851aad, + 0x00000000, 0xe5632654, 0xcbf00dbe, 0xb4c373ee, 0xa0e0a15f, 0x9126145f, 0x8643c7b3, 0x80b381ac, + 0x7f7437ad, 0x7b1d1a49, 0x7294b5f2, 0x66256db2, 0x563ba8aa, 0x4362210e, 0x2e3d2abb, 0x17851aad, }; #pragma GCC diagnostic pop /************************************************************************************** - * Function: DecodeLPCCoefs - * - * Description: decode LPC coefficients for TNS - * - * Inputs: order of TNS filter - * resolution of coefficients (3 or 4 bits) - * coefficients unpacked from bitstream - * scratch buffer (b) of size >= order - * - * Outputs: LPC coefficients in Q(FBITS_LPC_COEFS), in 'a' - * - * Return: none - * - * Notes: assumes no guard bits in input transform coefficients - * a[i] = Q(FBITS_LPC_COEFS), don't store a0 = 1.0 - * (so a[0] = first delay tap, etc.) - * max abs(a[i]) < log2(order), so for max order = 20 a[i] < 4.4 - * (up to 3 bits of gain) so a[i] has at least 31 - FBITS_LPC_COEFS - 3 - * guard bits - * to ensure no intermediate overflow in all-pole filter, set - * FBITS_LPC_COEFS such that number of guard bits >= log2(max order) + Function: DecodeLPCCoefs + + Description: decode LPC coefficients for TNS + + Inputs: order of TNS filter + resolution of coefficients (3 or 4 bits) + coefficients unpacked from bitstream + scratch buffer (b) of size >= order + + Outputs: LPC coefficients in Q(FBITS_LPC_COEFS), in 'a' + + Return: none + + Notes: assumes no guard bits in input transform coefficients + a[i] = Q(FBITS_LPC_COEFS), don't store a0 = 1.0 + (so a[0] = first delay tap, etc.) + max abs(a[i]) < log2(order), so for max order = 20 a[i] < 4.4 + (up to 3 bits of gain) so a[i] has at least 31 - FBITS_LPC_COEFS - 3 + guard bits + to ensure no intermediate overflow in all-pole filter, set + FBITS_LPC_COEFS such that number of guard bits >= log2(max order) **************************************************************************************/ -static void DecodeLPCCoefs(int order, int res, signed char *filtCoef, int *a, int *b) -{ - int i, m, t; - const int *invQuantTab; - - if (res == 3) invQuantTab = invQuant3; - else if (res == 4) invQuantTab = invQuant4; - else return; - - for (m = 0; m < order; m++) { - t = invQuantTab[filtCoef[m] & 0x0f]; /* t = Q31 */ - for (i = 0; i < m; i++) - b[i] = a[i] - (MULSHIFT32(t, a[m-i-1]) << 1); - for (i = 0; i < m; i++) - a[i] = b[i]; - a[m] = t >> (31 - FBITS_LPC_COEFS); - } +static void DecodeLPCCoefs(int order, int res, signed char *filtCoef, int *a, int *b) { + int i, m, t; + const int *invQuantTab; + + if (res == 3) { + invQuantTab = invQuant3; + } else if (res == 4) { + invQuantTab = invQuant4; + } else { + return; + } + + for (m = 0; m < order; m++) { + t = invQuantTab[filtCoef[m] & 0x0f]; /* t = Q31 */ + for (i = 0; i < m; i++) { + b[i] = a[i] - (MULSHIFT32(t, a[m - i - 1]) << 1); + } + for (i = 0; i < m; i++) { + a[i] = b[i]; + } + a[m] = t >> (31 - FBITS_LPC_COEFS); + } } /************************************************************************************** - * Function: FilterRegion - * - * Description: apply LPC filter to one region of coefficients - * - * Inputs: number of transform coefficients in this region - * direction flag (forward = 1, backward = -1) - * order of filter - * 'size' transform coefficients - * 'order' LPC coefficients in Q(FBITS_LPC_COEFS) - * scratch buffer for history (must be >= order samples long) - * - * Outputs: filtered transform coefficients - * - * Return: guard bit mask (OR of abs value of all filtered transform coefs) - * - * Notes: assumes no guard bits in input transform coefficients - * gains 0 int bits - * history buffer does not need to be preserved between regions + Function: FilterRegion + + Description: apply LPC filter to one region of coefficients + + Inputs: number of transform coefficients in this region + direction flag (forward = 1, backward = -1) + order of filter + 'size' transform coefficients + 'order' LPC coefficients in Q(FBITS_LPC_COEFS) + scratch buffer for history (must be >= order samples long) + + Outputs: filtered transform coefficients + + Return: guard bit mask (OR of abs value of all filtered transform coefs) + + Notes: assumes no guard bits in input transform coefficients + gains 0 int bits + history buffer does not need to be preserved between regions **************************************************************************************/ -static int FilterRegion(int size, int dir, int order, int *audioCoef, int *a, int *hist) -{ - int i, j, y, hi32, inc, gbMask; - U64 sum64; - - /* init history to 0 every time */ - for (i = 0; i < order; i++) - hist[i] = 0; - - sum64.w64 = 0; /* avoid warning */ - gbMask = 0; - inc = (dir ? -1 : 1); - do { - /* sum64 = a0*y[n] = 1.0*y[n] */ - y = *audioCoef; - sum64.r.hi32 = y >> (32 - FBITS_LPC_COEFS); - sum64.r.lo32 = y << FBITS_LPC_COEFS; - - /* sum64 += (a1*y[n-1] + a2*y[n-2] + ... + a[order-1]*y[n-(order-1)]) */ +static int FilterRegion(int size, int dir, int order, int *audioCoef, int *a, int *hist) { + int i, j, y, hi32, inc, gbMask; + U64 sum64; + + /* init history to 0 every time */ + for (i = 0; i < order; i++) { + hist[i] = 0; + } + + sum64.w64 = 0; /* avoid warning */ + gbMask = 0; + inc = (dir ? -1 : 1); + do { + /* sum64 = a0*y[n] = 1.0*y[n] */ + y = *audioCoef; + sum64.r.hi32 = y >> (32 - FBITS_LPC_COEFS); + sum64.r.lo32 = y << FBITS_LPC_COEFS; + + /* sum64 += (a1*y[n-1] + a2*y[n-2] + ... + a[order-1]*y[n-(order-1)]) */ for (j = order - 1; j > 0; j--) { - sum64.w64 = MADD64(sum64.w64, hist[j], a[j]); - hist[j] = hist[j-1]; - } - sum64.w64 = MADD64(sum64.w64, hist[0], a[0]); - y = (sum64.r.hi32 << (32 - FBITS_LPC_COEFS)) | (sum64.r.lo32 >> FBITS_LPC_COEFS); - - /* clip output (rare) */ - hi32 = sum64.r.hi32; - if ((hi32 >> 31) != (hi32 >> (FBITS_LPC_COEFS-1))) - y = (hi32 >> 31) ^ 0x7fffffff; - - hist[0] = y; - *audioCoef = y; - audioCoef += inc; - gbMask |= FASTABS(y); - } while (--size); - - return gbMask; + sum64.w64 = MADD64(sum64.w64, hist[j], a[j]); + hist[j] = hist[j - 1]; + } + sum64.w64 = MADD64(sum64.w64, hist[0], a[0]); + y = (sum64.r.hi32 << (32 - FBITS_LPC_COEFS)) | (sum64.r.lo32 >> FBITS_LPC_COEFS); + + /* clip output (rare) */ + hi32 = sum64.r.hi32; + if ((hi32 >> 31) != (hi32 >> (FBITS_LPC_COEFS - 1))) { + y = (hi32 >> 31) ^ 0x7fffffff; + } + + hist[0] = y; + *audioCoef = y; + audioCoef += inc; + gbMask |= FASTABS(y); + } while (--size); + + return gbMask; } /************************************************************************************** - * Function: TNSFilter - * - * Description: apply temporal noise shaping, if enabled - * - * Inputs: valid AACDecInfo struct - * index of current channel - * - * Outputs: updated transform coefficients - * updated minimum guard bit count for this channel - * - * Return: 0 if successful, -1 if error + Function: TNSFilter + + Description: apply temporal noise shaping, if enabled + + Inputs: valid AACDecInfo struct + index of current channel + + Outputs: updated transform coefficients + updated minimum guard bit count for this channel + + Return: 0 if successful, -1 if error **************************************************************************************/ -int TNSFilter(AACDecInfo *aacDecInfo, int ch) -{ - int win, winLen, nWindows, nSFB, filt, bottom, top, order, maxOrder, dir; - int start, end, size, tnsMaxBand, numFilt, gbMask; - int *audioCoef; - unsigned char *filtLength, *filtOrder, *filtRes, *filtDir; - signed char *filtCoef; - const unsigned /*char*/ int *tnsMaxBandTab; - const /*short*/ int *sfbTab; - ICSInfo *icsInfo; - TNSInfo *ti; - PSInfoBase *psi; - - /* validate pointers */ - if (!aacDecInfo || !aacDecInfo->psInfoBase) - return -1; - psi = (PSInfoBase *)(aacDecInfo->psInfoBase); - icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]); - ti = &psi->tnsInfo[ch]; - - if (!ti->tnsDataPresent) - return 0; - - if (icsInfo->winSequence == 2) { - nWindows = NWINDOWS_SHORT; - winLen = NSAMPS_SHORT; - nSFB = sfBandTotalShort[psi->sampRateIdx]; - maxOrder = tnsMaxOrderShort[aacDecInfo->profile]; - sfbTab = sfBandTabShort + sfBandTabShortOffset[psi->sampRateIdx]; - tnsMaxBandTab = tnsMaxBandsShort + tnsMaxBandsShortOffset[aacDecInfo->profile]; - tnsMaxBand = tnsMaxBandTab[psi->sampRateIdx]; - } else { - nWindows = NWINDOWS_LONG; - winLen = NSAMPS_LONG; - nSFB = sfBandTotalLong[psi->sampRateIdx]; - maxOrder = tnsMaxOrderLong[aacDecInfo->profile]; - sfbTab = sfBandTabLong + sfBandTabLongOffset[psi->sampRateIdx]; - tnsMaxBandTab = tnsMaxBandsLong + tnsMaxBandsLongOffset[aacDecInfo->profile]; - tnsMaxBand = tnsMaxBandTab[psi->sampRateIdx]; - } - - if (tnsMaxBand > icsInfo->maxSFB) - tnsMaxBand = icsInfo->maxSFB; - - filtRes = ti->coefRes; - filtLength = ti->length; - filtOrder = ti->order; - filtDir = ti->dir; - filtCoef = ti->coef; - - gbMask = 0; - audioCoef = psi->coef[ch]; - for (win = 0; win < nWindows; win++) { - bottom = nSFB; - numFilt = ti->numFilt[win]; - for (filt = 0; filt < numFilt; filt++) { - top = bottom; - bottom = top - *filtLength++; - bottom = MAX(bottom, 0); - order = *filtOrder++; - order = MIN(order, maxOrder); - - if (order) { - start = sfbTab[MIN(bottom, tnsMaxBand)]; - end = sfbTab[MIN(top, tnsMaxBand)]; - size = end - start; - if (size > 0) { - dir = *filtDir++; - if (dir) - start = end - 1; - - DecodeLPCCoefs(order, filtRes[win], filtCoef, psi->tnsLPCBuf, psi->tnsWorkBuf); - gbMask |= FilterRegion(size, dir, order, audioCoef + start, psi->tnsLPCBuf, psi->tnsWorkBuf); - } - filtCoef += order; - } - } - audioCoef += winLen; - } - - /* update guard bit count if necessary */ - size = CLZ(gbMask) - 1; - if (psi->gbCurrent[ch] > size) - psi->gbCurrent[ch] = size; - - return 0; +int TNSFilter(AACDecInfo *aacDecInfo, int ch) { + int win, winLen, nWindows, nSFB, filt, bottom, top, order, maxOrder, dir; + int start, end, size, tnsMaxBand, numFilt, gbMask; + int *audioCoef; + unsigned char *filtLength, *filtOrder, *filtRes, *filtDir; + signed char *filtCoef; + const unsigned /*char*/ int *tnsMaxBandTab; + const /*short*/ int *sfbTab; + ICSInfo *icsInfo; + TNSInfo *ti; + PSInfoBase *psi; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return -1; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]); + ti = &psi->tnsInfo[ch]; + + if (!ti->tnsDataPresent) { + return 0; + } + + if (icsInfo->winSequence == 2) { + nWindows = NWINDOWS_SHORT; + winLen = NSAMPS_SHORT; + nSFB = sfBandTotalShort[psi->sampRateIdx]; + maxOrder = tnsMaxOrderShort[aacDecInfo->profile]; + sfbTab = sfBandTabShort + sfBandTabShortOffset[psi->sampRateIdx]; + tnsMaxBandTab = tnsMaxBandsShort + tnsMaxBandsShortOffset[aacDecInfo->profile]; + tnsMaxBand = tnsMaxBandTab[psi->sampRateIdx]; + } else { + nWindows = NWINDOWS_LONG; + winLen = NSAMPS_LONG; + nSFB = sfBandTotalLong[psi->sampRateIdx]; + maxOrder = tnsMaxOrderLong[aacDecInfo->profile]; + sfbTab = sfBandTabLong + sfBandTabLongOffset[psi->sampRateIdx]; + tnsMaxBandTab = tnsMaxBandsLong + tnsMaxBandsLongOffset[aacDecInfo->profile]; + tnsMaxBand = tnsMaxBandTab[psi->sampRateIdx]; + } + + if (tnsMaxBand > icsInfo->maxSFB) { + tnsMaxBand = icsInfo->maxSFB; + } + + filtRes = ti->coefRes; + filtLength = ti->length; + filtOrder = ti->order; + filtDir = ti->dir; + filtCoef = ti->coef; + + gbMask = 0; + audioCoef = psi->coef[ch]; + for (win = 0; win < nWindows; win++) { + bottom = nSFB; + numFilt = ti->numFilt[win]; + for (filt = 0; filt < numFilt; filt++) { + top = bottom; + bottom = top - *filtLength++; + bottom = MAX(bottom, 0); + order = *filtOrder++; + order = MIN(order, maxOrder); + + if (order) { + start = sfbTab[MIN(bottom, tnsMaxBand)]; + end = sfbTab[MIN(top, tnsMaxBand)]; + size = end - start; + if (size > 0) { + dir = *filtDir++; + if (dir) { + start = end - 1; + } + + DecodeLPCCoefs(order, filtRes[win], filtCoef, psi->tnsLPCBuf, psi->tnsWorkBuf); + gbMask |= FilterRegion(size, dir, order, audioCoef + start, psi->tnsLPCBuf, psi->tnsWorkBuf); + } + filtCoef += order; + } + } + audioCoef += winLen; + } + + /* update guard bit count if necessary */ + size = CLZ(gbMask) - 1; + if (psi->gbCurrent[ch] > size) { + psi->gbCurrent[ch] = size; + } + + return 0; } -/* Code to generate invQuantXXX[] tables - * { - * int res, i, t; - * double powScale, iqfac, iqfac_m, d; - * - * powScale = pow(2.0, 31) * -1.0; / ** make coefficients negative for using MADD in kernel ** / - * for (res = 3; res <= 4; res++) { - * iqfac = ( ((1 << (res-1)) - 0.5) * (2.0 / M_PI) ); - * iqfac_m = ( ((1 << (res-1)) + 0.5) * (2.0 / M_PI) ); - * printf("static const int invQuant%d[16] = {\n", res); - * for (i = 0; i < 16; i++) { - * / ** extend bottom 4 bits into signed, 2's complement number ** / - * t = (i << 28) >> 28; - * - * if (t >= 0) d = sin(t / iqfac); - * else d = sin(t / iqfac_m); - * - * d *= powScale; - * printf("0x%08x, ", (int)(d > 0 ? d + 0.5 : d - 0.5)); - * if ((i & 0x07) == 0x07) - * printf("\n"); - * } - * printf("};\n\n"); - * } - * } - */ +/* Code to generate invQuantXXX[] tables + { + int res, i, t; + double powScale, iqfac, iqfac_m, d; + + powScale = pow(2.0, 31) * -1.0; / ** make coefficients negative for using MADD in kernel ** / + for (res = 3; res <= 4; res++) { + iqfac = ( ((1 << (res-1)) - 0.5) * (2.0 / M_PI) ); + iqfac_m = ( ((1 << (res-1)) + 0.5) * (2.0 / M_PI) ); + printf("static const int invQuant%d[16] = {\n", res); + for (i = 0; i < 16; i++) { + / ** extend bottom 4 bits into signed, 2's complement number ** / + t = (i << 28) >> 28; + + if (t >= 0) d = sin(t / iqfac); + else d = sin(t / iqfac_m); + + d *= powScale; + printf("0x%08x, ", (int)(d > 0 ? d + 0.5 : d - 0.5)); + if ((i & 0x07) == 0x07) + printf("\n"); + } + printf("};\n\n"); + } + } +*/ diff --git a/src/libhelix-aac/trigtabs.c b/src/libhelix-aac/trigtabs.c index 43012904..c8e6209e 100644 --- a/src/libhelix-aac/trigtabs.c +++ b/src/libhelix-aac/trigtabs.c @@ -1,46 +1,46 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Source last modified: $Id: trigtabs.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $ - * - * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, - * are subject to the current version of the RealNetworks Public - * Source License (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the current version of the RealNetworks Community - * Source License (the "RCSL") available at - * http://www.helixcommunity.org/content/rcsl, in which case the RCSL - * will apply. You may also obtain the license terms directly from - * RealNetworks. You may not use this file except in compliance with - * the RPSL or, if you have a valid RCSL with RealNetworks applicable - * to this file, the RCSL. Please see the applicable RPSL or RCSL for - * the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the - * portions it created. - * - * This file, and the files included with this file, is distributed - * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS - * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET - * ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Source last modified: $Id: trigtabs.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $ + + Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, + are subject to the current version of the RealNetworks Public + Source License (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the current version of the RealNetworks Community + Source License (the "RCSL") available at + http://www.helixcommunity.org/content/rcsl, in which case the RCSL + will apply. You may also obtain the license terms directly from + RealNetworks. You may not use this file except in compliance with + the RPSL or, if you have a valid RCSL with RealNetworks applicable + to this file, the RCSL. Please see the applicable RPSL or RCSL for + the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the + portions it created. + + This file, and the files included with this file, is distributed + and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS + ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET + ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point HE-AAC decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * February 2005 - * - * trigtabs.c - tables of sin, cos, etc. for IMDCT + Fixed-point HE-AAC decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + February 2005 + + trigtabs.c - tables of sin, cos, etc. for IMDCT **************************************************************************************/ #include "coder.h" @@ -48,848 +48,854 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnarrowing" -const int cos4sin4tabOffset[NUM_IMDCT_SIZES] PROGMEM = {0, 128}; - -/* PreMultiply() tables - * format = Q30 * 2^[-7, -10] for nmdct = [128, 1024] - * reordered for sequential access - * - * invM = -1.0 / nmdct; - * for (i = 0; i < nmdct/4; i++) { - * angle = (i + 0.25) * M_PI / nmdct; - * x = invM * (cos(angle) + sin(angle)); - * x = invM * sin(angle); - * - * angle = (nmdct/2 - 1 - i + 0.25) * M_PI / nmdct; - * x = invM * (cos(angle) + sin(angle)); - * x = invM * sin(angle); - * } - */ -const int cos4sin4tab[128 + 1024] PROGMEM = { -/* 128 - format = Q30 * 2^-7 */ -0xbf9bc731, 0xff9b783c, 0xbed5332c, 0xc002c697, 0xbe112251, 0xfe096c8d, 0xbd4f9c30, 0xc00f1c4a, -0xbc90a83f, 0xfc77ae5e, 0xbbd44dd9, 0xc0254e27, 0xbb1a9443, 0xfae67ba2, 0xba6382a6, 0xc04558c0, -0xb9af200f, 0xf9561237, 0xb8fd7373, 0xc06f3726, 0xb84e83ac, 0xf7c6afdc, 0xb7a25779, 0xc0a2e2e3, -0xb6f8f57c, 0xf6389228, 0xb652643e, 0xc0e05401, 0xb5aeaa2a, 0xf4abf67e, 0xb50dcd90, 0xc1278104, -0xb46fd4a4, 0xf3211a07, 0xb3d4c57c, 0xc1785ef4, 0xb33ca614, 0xf19839a6, 0xb2a77c49, 0xc1d2e158, -0xb2154dda, 0xf01191f3, 0xb186206b, 0xc236fa3b, 0xb0f9f981, 0xee8d5f29, 0xb070de82, 0xc2a49a2e, -0xafead4b9, 0xed0bdd25, 0xaf67e14f, 0xc31bb049, 0xaee80952, 0xeb8d475b, 0xae6b51ae, 0xc39c2a2f, -0xadf1bf34, 0xea11d8c8, 0xad7b5692, 0xc425f410, 0xad081c5a, 0xe899cbf1, 0xac9814fd, 0xc4b8f8ad, -0xac2b44cc, 0xe7255ad1, 0xabc1aff9, 0xc555215a, 0xab5b5a96, 0xe5b4bed8, 0xaaf84896, 0xc5fa5603, -0xaa987dca, 0xe44830dd, 0xaa3bfde3, 0xc6a87d2d, 0xa9e2cc73, 0xe2dfe917, 0xa98cece9, 0xc75f7bfe, -0xa93a6296, 0xe17c1f15, 0xa8eb30a7, 0xc81f363d, 0xa89f5a2b, 0xe01d09b4, 0xa856e20e, 0xc8e78e5b, -0xa811cb1b, 0xdec2df18, 0xa7d017fc, 0xc9b86572, 0xa791cb39, 0xdd6dd4a2, 0xa756e73a, 0xca919b4e, -0xa71f6e43, 0xdc1e1ee9, 0xa6eb6279, 0xcb730e70, 0xa6bac5dc, 0xdad3f1b1, 0xa68d9a4c, 0xcc5c9c14, -0xa663e188, 0xd98f7fe6, 0xa63d9d2b, 0xcd4e2037, 0xa61aceaf, 0xd850fb8e, 0xa5fb776b, 0xce47759a, -0xa5df9894, 0xd71895c9, 0xa5c7333e, 0xcf4875ca, 0xa5b2485a, 0xd5e67ec1, 0xa5a0d8b5, 0xd050f926, -0xa592e4fd, 0xd4bae5ab, 0xa5886dba, 0xd160d6e5, 0xa5817354, 0xd395f8ba, 0xa57df60f, 0xd277e518, -/* 1024 - format = Q30 * 2^-10 */ -0xbff3703e, 0xfff36f02, 0xbfda5824, 0xc0000b1a, 0xbfc149ed, 0xffc12b16, 0xbfa845a0, 0xc0003c74, -0xbf8f4b3e, 0xff8ee750, 0xbf765acc, 0xc0009547, 0xbf5d744e, 0xff5ca3d0, 0xbf4497c8, 0xc0011594, -0xbf2bc53d, 0xff2a60b4, 0xbf12fcb2, 0xc001bd5c, 0xbefa3e2a, 0xfef81e1d, 0xbee189a8, 0xc0028c9c, -0xbec8df32, 0xfec5dc28, 0xbeb03eca, 0xc0038356, 0xbe97a875, 0xfe939af5, 0xbe7f1c36, 0xc004a188, -0xbe669a10, 0xfe615aa3, 0xbe4e2209, 0xc005e731, 0xbe35b423, 0xfe2f1b50, 0xbe1d5062, 0xc0075452, -0xbe04f6cb, 0xfdfcdd1d, 0xbdeca760, 0xc008e8e8, 0xbdd46225, 0xfdcaa027, 0xbdbc2720, 0xc00aa4f3, -0xbda3f652, 0xfd98648d, 0xbd8bcfbf, 0xc00c8872, 0xbd73b36d, 0xfd662a70, 0xbd5ba15d, 0xc00e9364, -0xbd439995, 0xfd33f1ed, 0xbd2b9c17, 0xc010c5c7, 0xbd13a8e7, 0xfd01bb24, 0xbcfbc00a, 0xc0131f9b, -0xbce3e182, 0xfccf8634, 0xbccc0d53, 0xc015a0dd, 0xbcb44382, 0xfc9d533b, 0xbc9c8411, 0xc018498c, -0xbc84cf05, 0xfc6b2259, 0xbc6d2461, 0xc01b19a7, 0xbc558428, 0xfc38f3ac, 0xbc3dee5f, 0xc01e112b, -0xbc266309, 0xfc06c754, 0xbc0ee22a, 0xc0213018, 0xbbf76bc4, 0xfbd49d70, 0xbbdfffdd, 0xc024766a, -0xbbc89e77, 0xfba2761e, 0xbbb14796, 0xc027e421, 0xbb99fb3e, 0xfb70517d, 0xbb82b972, 0xc02b7939, -0xbb6b8235, 0xfb3e2fac, 0xbb54558d, 0xc02f35b1, 0xbb3d337b, 0xfb0c10cb, 0xbb261c04, 0xc0331986, -0xbb0f0f2b, 0xfad9f4f8, 0xbaf80cf4, 0xc03724b6, 0xbae11561, 0xfaa7dc52, 0xbaca2878, 0xc03b573f, -0xbab3463b, 0xfa75c6f8, 0xba9c6eae, 0xc03fb11d, 0xba85a1d4, 0xfa43b508, 0xba6edfb1, 0xc044324f, -0xba582849, 0xfa11a6a3, 0xba417b9e, 0xc048dad1, 0xba2ad9b5, 0xf9df9be6, 0xba144291, 0xc04daaa1, -0xb9fdb635, 0xf9ad94f0, 0xb9e734a4, 0xc052a1bb, 0xb9d0bde4, 0xf97b91e1, 0xb9ba51f6, 0xc057c01d, -0xb9a3f0de, 0xf94992d7, 0xb98d9aa0, 0xc05d05c3, 0xb9774f3f, 0xf91797f0, 0xb9610ebe, 0xc06272aa, -0xb94ad922, 0xf8e5a14d, 0xb934ae6d, 0xc06806ce, 0xb91e8ea3, 0xf8b3af0c, 0xb90879c7, 0xc06dc22e, -0xb8f26fdc, 0xf881c14b, 0xb8dc70e7, 0xc073a4c3, 0xb8c67cea, 0xf84fd829, 0xb8b093ea, 0xc079ae8c, -0xb89ab5e8, 0xf81df3c5, 0xb884e2e9, 0xc07fdf85, 0xb86f1af0, 0xf7ec143e, 0xb8595e00, 0xc08637a9, -0xb843ac1d, 0xf7ba39b3, 0xb82e0549, 0xc08cb6f5, 0xb818698a, 0xf7886442, 0xb802d8e0, 0xc0935d64, -0xb7ed5351, 0xf756940a, 0xb7d7d8df, 0xc09a2af3, 0xb7c2698e, 0xf724c92a, 0xb7ad0561, 0xc0a11f9d, -0xb797ac5b, 0xf6f303c0, 0xb7825e80, 0xc0a83b5e, 0xb76d1bd2, 0xf6c143ec, 0xb757e455, 0xc0af7e33, -0xb742b80d, 0xf68f89cb, 0xb72d96fd, 0xc0b6e815, 0xb7188127, 0xf65dd57d, 0xb7037690, 0xc0be7901, -0xb6ee773a, 0xf62c2721, 0xb6d98328, 0xc0c630f2, 0xb6c49a5e, 0xf5fa7ed4, 0xb6afbce0, 0xc0ce0fe3, -0xb69aeab0, 0xf5c8dcb6, 0xb68623d1, 0xc0d615cf, 0xb6716847, 0xf59740e5, 0xb65cb815, 0xc0de42b2, -0xb648133e, 0xf565ab80, 0xb63379c5, 0xc0e69686, 0xb61eebae, 0xf5341ca5, 0xb60a68fb, 0xc0ef1147, -0xb5f5f1b1, 0xf5029473, 0xb5e185d1, 0xc0f7b2ee, 0xb5cd255f, 0xf4d11308, 0xb5b8d05f, 0xc1007b77, -0xb5a486d2, 0xf49f9884, 0xb59048be, 0xc1096add, 0xb57c1624, 0xf46e2504, 0xb567ef08, 0xc1128119, -0xb553d36c, 0xf43cb8a7, 0xb53fc355, 0xc11bbe26, 0xb52bbec4, 0xf40b538b, 0xb517c5be, 0xc12521ff, -0xb503d845, 0xf3d9f5cf, 0xb4eff65c, 0xc12eac9d, 0xb4dc2007, 0xf3a89f92, 0xb4c85548, 0xc1385dfb, -0xb4b49622, 0xf37750f2, 0xb4a0e299, 0xc1423613, 0xb48d3ab0, 0xf3460a0d, 0xb4799e69, 0xc14c34df, -0xb4660dc8, 0xf314cb02, 0xb45288cf, 0xc1565a58, 0xb43f0f82, 0xf2e393ef, 0xb42ba1e4, 0xc160a678, -0xb4183ff7, 0xf2b264f2, 0xb404e9bf, 0xc16b193a, 0xb3f19f3e, 0xf2813e2a, 0xb3de6078, 0xc175b296, -0xb3cb2d70, 0xf2501fb5, 0xb3b80628, 0xc1807285, 0xb3a4eaa4, 0xf21f09b1, 0xb391dae6, 0xc18b5903, -0xb37ed6f1, 0xf1edfc3d, 0xb36bdec9, 0xc1966606, 0xb358f26f, 0xf1bcf777, 0xb34611e8, 0xc1a1998a, -0xb3333d36, 0xf18bfb7d, 0xb320745c, 0xc1acf386, 0xb30db75d, 0xf15b086d, 0xb2fb063b, 0xc1b873f5, -0xb2e860fa, 0xf12a1e66, 0xb2d5c79d, 0xc1c41ace, 0xb2c33a26, 0xf0f93d86, 0xb2b0b898, 0xc1cfe80a, -0xb29e42f6, 0xf0c865ea, 0xb28bd943, 0xc1dbdba3, 0xb2797b82, 0xf09797b2, 0xb26729b5, 0xc1e7f591, -0xb254e3e0, 0xf066d2fa, 0xb242aa05, 0xc1f435cc, 0xb2307c27, 0xf03617e2, 0xb21e5a49, 0xc2009c4e, -0xb20c446d, 0xf0056687, 0xb1fa3a97, 0xc20d290d, 0xb1e83cc9, 0xefd4bf08, 0xb1d64b06, 0xc219dc03, -0xb1c46551, 0xefa42181, 0xb1b28bad, 0xc226b528, 0xb1a0be1b, 0xef738e12, 0xb18efca0, 0xc233b473, -0xb17d473d, 0xef4304d8, 0xb16b9df6, 0xc240d9de, 0xb15a00cd, 0xef1285f2, 0xb1486fc5, 0xc24e255e, -0xb136eae1, 0xeee2117c, 0xb1257223, 0xc25b96ee, 0xb114058e, 0xeeb1a796, 0xb102a524, 0xc2692e83, -0xb0f150e9, 0xee81485c, 0xb0e008e0, 0xc276ec16, 0xb0cecd09, 0xee50f3ed, 0xb0bd9d6a, 0xc284cf9f, -0xb0ac7a03, 0xee20aa67, 0xb09b62d8, 0xc292d914, 0xb08a57eb, 0xedf06be6, 0xb079593f, 0xc2a1086d, -0xb06866d7, 0xedc0388a, 0xb05780b5, 0xc2af5da2, 0xb046a6db, 0xed901070, 0xb035d94e, 0xc2bdd8a9, -0xb025180e, 0xed5ff3b5, 0xb014631e, 0xc2cc7979, 0xb003ba82, 0xed2fe277, 0xaff31e3b, 0xc2db400a, -0xafe28e4d, 0xecffdcd4, 0xafd20ab9, 0xc2ea2c53, 0xafc19383, 0xeccfe2ea, 0xafb128ad, 0xc2f93e4a, -0xafa0ca39, 0xec9ff4d6, 0xaf90782a, 0xc30875e5, 0xaf803283, 0xec7012b5, 0xaf6ff945, 0xc317d31c, -0xaf5fcc74, 0xec403ca5, 0xaf4fac12, 0xc32755e5, 0xaf3f9822, 0xec1072c4, 0xaf2f90a5, 0xc336fe37, -0xaf1f959f, 0xebe0b52f, 0xaf0fa712, 0xc346cc07, 0xaeffc500, 0xebb10404, 0xaeefef6c, 0xc356bf4d, -0xaee02658, 0xeb815f60, 0xaed069c7, 0xc366d7fd, 0xaec0b9bb, 0xeb51c760, 0xaeb11636, 0xc377160f, -0xaea17f3b, 0xeb223c22, 0xae91f4cd, 0xc3877978, 0xae8276ed, 0xeaf2bdc3, 0xae73059f, 0xc398022f, -0xae63a0e3, 0xeac34c60, 0xae5448be, 0xc3a8b028, 0xae44fd31, 0xea93e817, 0xae35be3f, 0xc3b9835a, -0xae268be9, 0xea649105, 0xae176633, 0xc3ca7bba, 0xae084d1f, 0xea354746, 0xadf940ae, 0xc3db993e, -0xadea40e4, 0xea060af9, 0xaddb4dc2, 0xc3ecdbdc, 0xadcc674b, 0xe9d6dc3b, 0xadbd8d82, 0xc3fe4388, -0xadaec067, 0xe9a7bb28, 0xad9fffff, 0xc40fd037, 0xad914c4b, 0xe978a7dd, 0xad82a54c, 0xc42181e0, -0xad740b07, 0xe949a278, 0xad657d7c, 0xc4335877, 0xad56fcaf, 0xe91aab16, 0xad4888a0, 0xc44553f2, -0xad3a2153, 0xe8ebc1d3, 0xad2bc6ca, 0xc4577444, 0xad1d7907, 0xe8bce6cd, 0xad0f380c, 0xc469b963, -0xad0103db, 0xe88e1a20, 0xacf2dc77, 0xc47c2344, 0xace4c1e2, 0xe85f5be9, 0xacd6b41e, 0xc48eb1db, -0xacc8b32c, 0xe830ac45, 0xacbabf10, 0xc4a1651c, 0xacacd7cb, 0xe8020b52, 0xac9efd60, 0xc4b43cfd, -0xac912fd1, 0xe7d3792b, 0xac836f1f, 0xc4c73972, 0xac75bb4d, 0xe7a4f5ed, 0xac68145d, 0xc4da5a6f, -0xac5a7a52, 0xe77681b6, 0xac4ced2c, 0xc4ed9fe7, 0xac3f6cef, 0xe7481ca1, 0xac31f99d, 0xc50109d0, -0xac249336, 0xe719c6cb, 0xac1739bf, 0xc514981d, 0xac09ed38, 0xe6eb8052, 0xabfcada3, 0xc5284ac3, -0xabef7b04, 0xe6bd4951, 0xabe2555b, 0xc53c21b4, 0xabd53caa, 0xe68f21e5, 0xabc830f5, 0xc5501ce5, -0xabbb323c, 0xe6610a2a, 0xabae4082, 0xc5643c4a, 0xaba15bc9, 0xe633023e, 0xab948413, 0xc5787fd6, -0xab87b962, 0xe6050a3b, 0xab7afbb7, 0xc58ce77c, 0xab6e4b15, 0xe5d72240, 0xab61a77d, 0xc5a17330, -0xab5510f3, 0xe5a94a67, 0xab488776, 0xc5b622e6, 0xab3c0b0b, 0xe57b82cd, 0xab2f9bb1, 0xc5caf690, -0xab23396c, 0xe54dcb8f, 0xab16e43d, 0xc5dfee22, 0xab0a9c27, 0xe52024c9, 0xaafe612a, 0xc5f5098f, -0xaaf23349, 0xe4f28e96, 0xaae61286, 0xc60a48c9, 0xaad9fee3, 0xe4c50914, 0xaacdf861, 0xc61fabc4, -0xaac1ff03, 0xe497945d, 0xaab612ca, 0xc6353273, 0xaaaa33b8, 0xe46a308f, 0xaa9e61cf, 0xc64adcc7, -0xaa929d10, 0xe43cddc4, 0xaa86e57e, 0xc660aab5, 0xaa7b3b1b, 0xe40f9c1a, 0xaa6f9de7, 0xc6769c2e, -0xaa640de6, 0xe3e26bac, 0xaa588b18, 0xc68cb124, 0xaa4d157f, 0xe3b54c95, 0xaa41ad1e, 0xc6a2e98b, -0xaa3651f6, 0xe3883ef2, 0xaa2b0409, 0xc6b94554, 0xaa1fc358, 0xe35b42df, 0xaa148fe6, 0xc6cfc472, -0xaa0969b3, 0xe32e5876, 0xa9fe50c2, 0xc6e666d7, 0xa9f34515, 0xe3017fd5, 0xa9e846ad, 0xc6fd2c75, -0xa9dd558b, 0xe2d4b916, 0xa9d271b2, 0xc714153e, 0xa9c79b23, 0xe2a80456, 0xa9bcd1e0, 0xc72b2123, -0xa9b215ea, 0xe27b61af, 0xa9a76744, 0xc7425016, 0xa99cc5ee, 0xe24ed13d, 0xa99231eb, 0xc759a20a, -0xa987ab3c, 0xe222531c, 0xa97d31e3, 0xc77116f0, 0xa972c5e1, 0xe1f5e768, 0xa9686738, 0xc788aeb9, -0xa95e15e9, 0xe1c98e3b, 0xa953d1f7, 0xc7a06957, 0xa9499b62, 0xe19d47b1, 0xa93f722c, 0xc7b846ba, -0xa9355658, 0xe17113e5, 0xa92b47e5, 0xc7d046d6, 0xa92146d7, 0xe144f2f3, 0xa917532e, 0xc7e8699a, -0xa90d6cec, 0xe118e4f6, 0xa9039413, 0xc800aef7, 0xa8f9c8a4, 0xe0ecea09, 0xa8f00aa0, 0xc81916df, -0xa8e65a0a, 0xe0c10247, 0xa8dcb6e2, 0xc831a143, 0xa8d3212a, 0xe0952dcb, 0xa8c998e3, 0xc84a4e14, -0xa8c01e10, 0xe0696cb0, 0xa8b6b0b1, 0xc8631d42, 0xa8ad50c8, 0xe03dbf11, 0xa8a3fe57, 0xc87c0ebd, -0xa89ab95e, 0xe012250a, 0xa89181df, 0xc8952278, 0xa88857dc, 0xdfe69eb4, 0xa87f3b57, 0xc8ae5862, -0xa8762c4f, 0xdfbb2c2c, 0xa86d2ac8, 0xc8c7b06b, 0xa86436c2, 0xdf8fcd8b, 0xa85b503e, 0xc8e12a84, -0xa852773f, 0xdf6482ed, 0xa849abc4, 0xc8fac69e, 0xa840edd1, 0xdf394c6b, 0xa8383d66, 0xc91484a8, -0xa82f9a84, 0xdf0e2a22, 0xa827052d, 0xc92e6492, 0xa81e7d62, 0xdee31c2b, 0xa8160324, 0xc948664d, -0xa80d9675, 0xdeb822a1, 0xa8053756, 0xc96289c9, 0xa7fce5c9, 0xde8d3d9e, 0xa7f4a1ce, 0xc97ccef5, -0xa7ec6b66, 0xde626d3e, 0xa7e44294, 0xc99735c2, 0xa7dc2759, 0xde37b199, 0xa7d419b4, 0xc9b1be1e, -0xa7cc19a9, 0xde0d0acc, 0xa7c42738, 0xc9cc67fa, 0xa7bc4262, 0xdde278ef, 0xa7b46b29, 0xc9e73346, -0xa7aca18e, 0xddb7fc1e, 0xa7a4e591, 0xca021fef, 0xa79d3735, 0xdd8d9472, 0xa795967a, 0xca1d2de7, -0xa78e0361, 0xdd634206, 0xa7867dec, 0xca385d1d, 0xa77f061c, 0xdd3904f4, 0xa7779bf2, 0xca53ad7e, -0xa7703f70, 0xdd0edd55, 0xa768f095, 0xca6f1efc, 0xa761af64, 0xdce4cb44, 0xa75a7bdd, 0xca8ab184, -0xa7535602, 0xdcbacedb, 0xa74c3dd4, 0xcaa66506, 0xa7453353, 0xdc90e834, 0xa73e3681, 0xcac23971, -0xa7374760, 0xdc671768, 0xa73065ef, 0xcade2eb3, 0xa7299231, 0xdc3d5c91, 0xa722cc25, 0xcafa44bc, -0xa71c13ce, 0xdc13b7c9, 0xa715692c, 0xcb167b79, 0xa70ecc41, 0xdbea292b, 0xa7083d0d, 0xcb32d2da, -0xa701bb91, 0xdbc0b0ce, 0xa6fb47ce, 0xcb4f4acd, 0xa6f4e1c6, 0xdb974ece, 0xa6ee8979, 0xcb6be341, -0xa6e83ee8, 0xdb6e0342, 0xa6e20214, 0xcb889c23, 0xa6dbd2ff, 0xdb44ce46, 0xa6d5b1a9, 0xcba57563, -0xa6cf9e13, 0xdb1baff2, 0xa6c9983e, 0xcbc26eee, 0xa6c3a02b, 0xdaf2a860, 0xa6bdb5da, 0xcbdf88b3, -0xa6b7d94e, 0xdac9b7a9, 0xa6b20a86, 0xcbfcc29f, 0xa6ac4984, 0xdaa0dde7, 0xa6a69649, 0xcc1a1ca0, -0xa6a0f0d5, 0xda781b31, 0xa69b5929, 0xcc3796a5, 0xa695cf46, 0xda4f6fa3, 0xa690532d, 0xcc55309b, -0xa68ae4df, 0xda26db54, 0xa685845c, 0xcc72ea70, 0xa68031a6, 0xd9fe5e5e, 0xa67aecbd, 0xcc90c412, -0xa675b5a3, 0xd9d5f8d9, 0xa6708c57, 0xccaebd6e, 0xa66b70db, 0xd9adaadf, 0xa6666330, 0xccccd671, -0xa6616355, 0xd9857489, 0xa65c714d, 0xcceb0f0a, 0xa6578d18, 0xd95d55ef, 0xa652b6b6, 0xcd096725, -0xa64dee28, 0xd9354f2a, 0xa6493370, 0xcd27deb0, 0xa644868d, 0xd90d6053, 0xa63fe781, 0xcd467599, -0xa63b564c, 0xd8e58982, 0xa636d2ee, 0xcd652bcb, 0xa6325d6a, 0xd8bdcad0, 0xa62df5bf, 0xcd840134, -0xa6299bed, 0xd8962456, 0xa6254ff7, 0xcda2f5c2, 0xa62111db, 0xd86e962b, 0xa61ce19c, 0xcdc20960, -0xa618bf39, 0xd8472069, 0xa614aab3, 0xcde13bfd, 0xa610a40c, 0xd81fc328, 0xa60cab43, 0xce008d84, -0xa608c058, 0xd7f87e7f, 0xa604e34e, 0xce1ffde2, 0xa6011424, 0xd7d15288, 0xa5fd52db, 0xce3f8d05, -0xa5f99f73, 0xd7aa3f5a, 0xa5f5f9ed, 0xce5f3ad8, 0xa5f2624a, 0xd783450d, 0xa5eed88a, 0xce7f0748, -0xa5eb5cae, 0xd75c63ba, 0xa5e7eeb6, 0xce9ef241, 0xa5e48ea3, 0xd7359b78, 0xa5e13c75, 0xcebefbb0, -0xa5ddf82d, 0xd70eec60, 0xa5dac1cb, 0xcedf2380, 0xa5d79950, 0xd6e85689, 0xa5d47ebc, 0xceff699f, -0xa5d17210, 0xd6c1da0b, 0xa5ce734d, 0xcf1fcdf8, 0xa5cb8272, 0xd69b76fe, 0xa5c89f80, 0xcf405077, -0xa5c5ca77, 0xd6752d79, 0xa5c30359, 0xcf60f108, 0xa5c04a25, 0xd64efd94, 0xa5bd9edc, 0xcf81af97, -0xa5bb017f, 0xd628e767, 0xa5b8720d, 0xcfa28c10, 0xa5b5f087, 0xd602eb0a, 0xa5b37cee, 0xcfc3865e, -0xa5b11741, 0xd5dd0892, 0xa5aebf82, 0xcfe49e6d, 0xa5ac75b0, 0xd5b74019, 0xa5aa39cd, 0xd005d42a, -0xa5a80bd7, 0xd59191b5, 0xa5a5ebd0, 0xd027277e, 0xa5a3d9b8, 0xd56bfd7d, 0xa5a1d590, 0xd0489856, -0xa59fdf57, 0xd5468389, 0xa59df70e, 0xd06a269d, 0xa59c1cb5, 0xd52123f0, 0xa59a504c, 0xd08bd23f, -0xa59891d4, 0xd4fbdec9, 0xa596e14e, 0xd0ad9b26, 0xa5953eb8, 0xd4d6b42b, 0xa593aa14, 0xd0cf813e, -0xa5922362, 0xd4b1a42c, 0xa590aaa2, 0xd0f18472, 0xa58f3fd4, 0xd48caee4, 0xa58de2f8, 0xd113a4ad, -0xa58c940f, 0xd467d469, 0xa58b5319, 0xd135e1d9, 0xa58a2016, 0xd44314d3, 0xa588fb06, 0xd1583be2, -0xa587e3ea, 0xd41e7037, 0xa586dac1, 0xd17ab2b3, 0xa585df8c, 0xd3f9e6ad, 0xa584f24b, 0xd19d4636, -0xa58412fe, 0xd3d5784a, 0xa58341a5, 0xd1bff656, 0xa5827e40, 0xd3b12526, 0xa581c8d0, 0xd1e2c2fd, -0xa5812154, 0xd38ced57, 0xa58087cd, 0xd205ac17, 0xa57ffc3b, 0xd368d0f3, 0xa57f7e9d, 0xd228b18d, -0xa57f0ef5, 0xd344d011, 0xa57ead41, 0xd24bd34a, 0xa57e5982, 0xd320eac6, 0xa57e13b8, 0xd26f1138, -0xa57ddbe4, 0xd2fd2129, 0xa57db204, 0xd2926b41, 0xa57d961a, 0xd2d97350, 0xa57d8825, 0xd2b5e151, +#if defined(PICO_RP2040) || defined(PICO_RP2350) +#define DPROGMEM __attribute__(( section(".time_critical.data") )) +#else +#define DPROGMEM PROGMEM +#endif + +const int cos4sin4tabOffset[NUM_IMDCT_SIZES] DPROGMEM = {0, 128}; + +/* PreMultiply() tables + format = Q30 * 2^[-7, -10] for nmdct = [128, 1024] + reordered for sequential access + + invM = -1.0 / nmdct; + for (i = 0; i < nmdct/4; i++) { + angle = (i + 0.25) * M_PI / nmdct; + x = invM * (cos(angle) + sin(angle)); + x = invM * sin(angle); + + angle = (nmdct/2 - 1 - i + 0.25) * M_PI / nmdct; + x = invM * (cos(angle) + sin(angle)); + x = invM * sin(angle); + } +*/ +const int cos4sin4tab[128 + 1024] DPROGMEM = { + /* 128 - format = Q30 * 2^-7 */ + 0xbf9bc731, 0xff9b783c, 0xbed5332c, 0xc002c697, 0xbe112251, 0xfe096c8d, 0xbd4f9c30, 0xc00f1c4a, + 0xbc90a83f, 0xfc77ae5e, 0xbbd44dd9, 0xc0254e27, 0xbb1a9443, 0xfae67ba2, 0xba6382a6, 0xc04558c0, + 0xb9af200f, 0xf9561237, 0xb8fd7373, 0xc06f3726, 0xb84e83ac, 0xf7c6afdc, 0xb7a25779, 0xc0a2e2e3, + 0xb6f8f57c, 0xf6389228, 0xb652643e, 0xc0e05401, 0xb5aeaa2a, 0xf4abf67e, 0xb50dcd90, 0xc1278104, + 0xb46fd4a4, 0xf3211a07, 0xb3d4c57c, 0xc1785ef4, 0xb33ca614, 0xf19839a6, 0xb2a77c49, 0xc1d2e158, + 0xb2154dda, 0xf01191f3, 0xb186206b, 0xc236fa3b, 0xb0f9f981, 0xee8d5f29, 0xb070de82, 0xc2a49a2e, + 0xafead4b9, 0xed0bdd25, 0xaf67e14f, 0xc31bb049, 0xaee80952, 0xeb8d475b, 0xae6b51ae, 0xc39c2a2f, + 0xadf1bf34, 0xea11d8c8, 0xad7b5692, 0xc425f410, 0xad081c5a, 0xe899cbf1, 0xac9814fd, 0xc4b8f8ad, + 0xac2b44cc, 0xe7255ad1, 0xabc1aff9, 0xc555215a, 0xab5b5a96, 0xe5b4bed8, 0xaaf84896, 0xc5fa5603, + 0xaa987dca, 0xe44830dd, 0xaa3bfde3, 0xc6a87d2d, 0xa9e2cc73, 0xe2dfe917, 0xa98cece9, 0xc75f7bfe, + 0xa93a6296, 0xe17c1f15, 0xa8eb30a7, 0xc81f363d, 0xa89f5a2b, 0xe01d09b4, 0xa856e20e, 0xc8e78e5b, + 0xa811cb1b, 0xdec2df18, 0xa7d017fc, 0xc9b86572, 0xa791cb39, 0xdd6dd4a2, 0xa756e73a, 0xca919b4e, + 0xa71f6e43, 0xdc1e1ee9, 0xa6eb6279, 0xcb730e70, 0xa6bac5dc, 0xdad3f1b1, 0xa68d9a4c, 0xcc5c9c14, + 0xa663e188, 0xd98f7fe6, 0xa63d9d2b, 0xcd4e2037, 0xa61aceaf, 0xd850fb8e, 0xa5fb776b, 0xce47759a, + 0xa5df9894, 0xd71895c9, 0xa5c7333e, 0xcf4875ca, 0xa5b2485a, 0xd5e67ec1, 0xa5a0d8b5, 0xd050f926, + 0xa592e4fd, 0xd4bae5ab, 0xa5886dba, 0xd160d6e5, 0xa5817354, 0xd395f8ba, 0xa57df60f, 0xd277e518, + /* 1024 - format = Q30 * 2^-10 */ + 0xbff3703e, 0xfff36f02, 0xbfda5824, 0xc0000b1a, 0xbfc149ed, 0xffc12b16, 0xbfa845a0, 0xc0003c74, + 0xbf8f4b3e, 0xff8ee750, 0xbf765acc, 0xc0009547, 0xbf5d744e, 0xff5ca3d0, 0xbf4497c8, 0xc0011594, + 0xbf2bc53d, 0xff2a60b4, 0xbf12fcb2, 0xc001bd5c, 0xbefa3e2a, 0xfef81e1d, 0xbee189a8, 0xc0028c9c, + 0xbec8df32, 0xfec5dc28, 0xbeb03eca, 0xc0038356, 0xbe97a875, 0xfe939af5, 0xbe7f1c36, 0xc004a188, + 0xbe669a10, 0xfe615aa3, 0xbe4e2209, 0xc005e731, 0xbe35b423, 0xfe2f1b50, 0xbe1d5062, 0xc0075452, + 0xbe04f6cb, 0xfdfcdd1d, 0xbdeca760, 0xc008e8e8, 0xbdd46225, 0xfdcaa027, 0xbdbc2720, 0xc00aa4f3, + 0xbda3f652, 0xfd98648d, 0xbd8bcfbf, 0xc00c8872, 0xbd73b36d, 0xfd662a70, 0xbd5ba15d, 0xc00e9364, + 0xbd439995, 0xfd33f1ed, 0xbd2b9c17, 0xc010c5c7, 0xbd13a8e7, 0xfd01bb24, 0xbcfbc00a, 0xc0131f9b, + 0xbce3e182, 0xfccf8634, 0xbccc0d53, 0xc015a0dd, 0xbcb44382, 0xfc9d533b, 0xbc9c8411, 0xc018498c, + 0xbc84cf05, 0xfc6b2259, 0xbc6d2461, 0xc01b19a7, 0xbc558428, 0xfc38f3ac, 0xbc3dee5f, 0xc01e112b, + 0xbc266309, 0xfc06c754, 0xbc0ee22a, 0xc0213018, 0xbbf76bc4, 0xfbd49d70, 0xbbdfffdd, 0xc024766a, + 0xbbc89e77, 0xfba2761e, 0xbbb14796, 0xc027e421, 0xbb99fb3e, 0xfb70517d, 0xbb82b972, 0xc02b7939, + 0xbb6b8235, 0xfb3e2fac, 0xbb54558d, 0xc02f35b1, 0xbb3d337b, 0xfb0c10cb, 0xbb261c04, 0xc0331986, + 0xbb0f0f2b, 0xfad9f4f8, 0xbaf80cf4, 0xc03724b6, 0xbae11561, 0xfaa7dc52, 0xbaca2878, 0xc03b573f, + 0xbab3463b, 0xfa75c6f8, 0xba9c6eae, 0xc03fb11d, 0xba85a1d4, 0xfa43b508, 0xba6edfb1, 0xc044324f, + 0xba582849, 0xfa11a6a3, 0xba417b9e, 0xc048dad1, 0xba2ad9b5, 0xf9df9be6, 0xba144291, 0xc04daaa1, + 0xb9fdb635, 0xf9ad94f0, 0xb9e734a4, 0xc052a1bb, 0xb9d0bde4, 0xf97b91e1, 0xb9ba51f6, 0xc057c01d, + 0xb9a3f0de, 0xf94992d7, 0xb98d9aa0, 0xc05d05c3, 0xb9774f3f, 0xf91797f0, 0xb9610ebe, 0xc06272aa, + 0xb94ad922, 0xf8e5a14d, 0xb934ae6d, 0xc06806ce, 0xb91e8ea3, 0xf8b3af0c, 0xb90879c7, 0xc06dc22e, + 0xb8f26fdc, 0xf881c14b, 0xb8dc70e7, 0xc073a4c3, 0xb8c67cea, 0xf84fd829, 0xb8b093ea, 0xc079ae8c, + 0xb89ab5e8, 0xf81df3c5, 0xb884e2e9, 0xc07fdf85, 0xb86f1af0, 0xf7ec143e, 0xb8595e00, 0xc08637a9, + 0xb843ac1d, 0xf7ba39b3, 0xb82e0549, 0xc08cb6f5, 0xb818698a, 0xf7886442, 0xb802d8e0, 0xc0935d64, + 0xb7ed5351, 0xf756940a, 0xb7d7d8df, 0xc09a2af3, 0xb7c2698e, 0xf724c92a, 0xb7ad0561, 0xc0a11f9d, + 0xb797ac5b, 0xf6f303c0, 0xb7825e80, 0xc0a83b5e, 0xb76d1bd2, 0xf6c143ec, 0xb757e455, 0xc0af7e33, + 0xb742b80d, 0xf68f89cb, 0xb72d96fd, 0xc0b6e815, 0xb7188127, 0xf65dd57d, 0xb7037690, 0xc0be7901, + 0xb6ee773a, 0xf62c2721, 0xb6d98328, 0xc0c630f2, 0xb6c49a5e, 0xf5fa7ed4, 0xb6afbce0, 0xc0ce0fe3, + 0xb69aeab0, 0xf5c8dcb6, 0xb68623d1, 0xc0d615cf, 0xb6716847, 0xf59740e5, 0xb65cb815, 0xc0de42b2, + 0xb648133e, 0xf565ab80, 0xb63379c5, 0xc0e69686, 0xb61eebae, 0xf5341ca5, 0xb60a68fb, 0xc0ef1147, + 0xb5f5f1b1, 0xf5029473, 0xb5e185d1, 0xc0f7b2ee, 0xb5cd255f, 0xf4d11308, 0xb5b8d05f, 0xc1007b77, + 0xb5a486d2, 0xf49f9884, 0xb59048be, 0xc1096add, 0xb57c1624, 0xf46e2504, 0xb567ef08, 0xc1128119, + 0xb553d36c, 0xf43cb8a7, 0xb53fc355, 0xc11bbe26, 0xb52bbec4, 0xf40b538b, 0xb517c5be, 0xc12521ff, + 0xb503d845, 0xf3d9f5cf, 0xb4eff65c, 0xc12eac9d, 0xb4dc2007, 0xf3a89f92, 0xb4c85548, 0xc1385dfb, + 0xb4b49622, 0xf37750f2, 0xb4a0e299, 0xc1423613, 0xb48d3ab0, 0xf3460a0d, 0xb4799e69, 0xc14c34df, + 0xb4660dc8, 0xf314cb02, 0xb45288cf, 0xc1565a58, 0xb43f0f82, 0xf2e393ef, 0xb42ba1e4, 0xc160a678, + 0xb4183ff7, 0xf2b264f2, 0xb404e9bf, 0xc16b193a, 0xb3f19f3e, 0xf2813e2a, 0xb3de6078, 0xc175b296, + 0xb3cb2d70, 0xf2501fb5, 0xb3b80628, 0xc1807285, 0xb3a4eaa4, 0xf21f09b1, 0xb391dae6, 0xc18b5903, + 0xb37ed6f1, 0xf1edfc3d, 0xb36bdec9, 0xc1966606, 0xb358f26f, 0xf1bcf777, 0xb34611e8, 0xc1a1998a, + 0xb3333d36, 0xf18bfb7d, 0xb320745c, 0xc1acf386, 0xb30db75d, 0xf15b086d, 0xb2fb063b, 0xc1b873f5, + 0xb2e860fa, 0xf12a1e66, 0xb2d5c79d, 0xc1c41ace, 0xb2c33a26, 0xf0f93d86, 0xb2b0b898, 0xc1cfe80a, + 0xb29e42f6, 0xf0c865ea, 0xb28bd943, 0xc1dbdba3, 0xb2797b82, 0xf09797b2, 0xb26729b5, 0xc1e7f591, + 0xb254e3e0, 0xf066d2fa, 0xb242aa05, 0xc1f435cc, 0xb2307c27, 0xf03617e2, 0xb21e5a49, 0xc2009c4e, + 0xb20c446d, 0xf0056687, 0xb1fa3a97, 0xc20d290d, 0xb1e83cc9, 0xefd4bf08, 0xb1d64b06, 0xc219dc03, + 0xb1c46551, 0xefa42181, 0xb1b28bad, 0xc226b528, 0xb1a0be1b, 0xef738e12, 0xb18efca0, 0xc233b473, + 0xb17d473d, 0xef4304d8, 0xb16b9df6, 0xc240d9de, 0xb15a00cd, 0xef1285f2, 0xb1486fc5, 0xc24e255e, + 0xb136eae1, 0xeee2117c, 0xb1257223, 0xc25b96ee, 0xb114058e, 0xeeb1a796, 0xb102a524, 0xc2692e83, + 0xb0f150e9, 0xee81485c, 0xb0e008e0, 0xc276ec16, 0xb0cecd09, 0xee50f3ed, 0xb0bd9d6a, 0xc284cf9f, + 0xb0ac7a03, 0xee20aa67, 0xb09b62d8, 0xc292d914, 0xb08a57eb, 0xedf06be6, 0xb079593f, 0xc2a1086d, + 0xb06866d7, 0xedc0388a, 0xb05780b5, 0xc2af5da2, 0xb046a6db, 0xed901070, 0xb035d94e, 0xc2bdd8a9, + 0xb025180e, 0xed5ff3b5, 0xb014631e, 0xc2cc7979, 0xb003ba82, 0xed2fe277, 0xaff31e3b, 0xc2db400a, + 0xafe28e4d, 0xecffdcd4, 0xafd20ab9, 0xc2ea2c53, 0xafc19383, 0xeccfe2ea, 0xafb128ad, 0xc2f93e4a, + 0xafa0ca39, 0xec9ff4d6, 0xaf90782a, 0xc30875e5, 0xaf803283, 0xec7012b5, 0xaf6ff945, 0xc317d31c, + 0xaf5fcc74, 0xec403ca5, 0xaf4fac12, 0xc32755e5, 0xaf3f9822, 0xec1072c4, 0xaf2f90a5, 0xc336fe37, + 0xaf1f959f, 0xebe0b52f, 0xaf0fa712, 0xc346cc07, 0xaeffc500, 0xebb10404, 0xaeefef6c, 0xc356bf4d, + 0xaee02658, 0xeb815f60, 0xaed069c7, 0xc366d7fd, 0xaec0b9bb, 0xeb51c760, 0xaeb11636, 0xc377160f, + 0xaea17f3b, 0xeb223c22, 0xae91f4cd, 0xc3877978, 0xae8276ed, 0xeaf2bdc3, 0xae73059f, 0xc398022f, + 0xae63a0e3, 0xeac34c60, 0xae5448be, 0xc3a8b028, 0xae44fd31, 0xea93e817, 0xae35be3f, 0xc3b9835a, + 0xae268be9, 0xea649105, 0xae176633, 0xc3ca7bba, 0xae084d1f, 0xea354746, 0xadf940ae, 0xc3db993e, + 0xadea40e4, 0xea060af9, 0xaddb4dc2, 0xc3ecdbdc, 0xadcc674b, 0xe9d6dc3b, 0xadbd8d82, 0xc3fe4388, + 0xadaec067, 0xe9a7bb28, 0xad9fffff, 0xc40fd037, 0xad914c4b, 0xe978a7dd, 0xad82a54c, 0xc42181e0, + 0xad740b07, 0xe949a278, 0xad657d7c, 0xc4335877, 0xad56fcaf, 0xe91aab16, 0xad4888a0, 0xc44553f2, + 0xad3a2153, 0xe8ebc1d3, 0xad2bc6ca, 0xc4577444, 0xad1d7907, 0xe8bce6cd, 0xad0f380c, 0xc469b963, + 0xad0103db, 0xe88e1a20, 0xacf2dc77, 0xc47c2344, 0xace4c1e2, 0xe85f5be9, 0xacd6b41e, 0xc48eb1db, + 0xacc8b32c, 0xe830ac45, 0xacbabf10, 0xc4a1651c, 0xacacd7cb, 0xe8020b52, 0xac9efd60, 0xc4b43cfd, + 0xac912fd1, 0xe7d3792b, 0xac836f1f, 0xc4c73972, 0xac75bb4d, 0xe7a4f5ed, 0xac68145d, 0xc4da5a6f, + 0xac5a7a52, 0xe77681b6, 0xac4ced2c, 0xc4ed9fe7, 0xac3f6cef, 0xe7481ca1, 0xac31f99d, 0xc50109d0, + 0xac249336, 0xe719c6cb, 0xac1739bf, 0xc514981d, 0xac09ed38, 0xe6eb8052, 0xabfcada3, 0xc5284ac3, + 0xabef7b04, 0xe6bd4951, 0xabe2555b, 0xc53c21b4, 0xabd53caa, 0xe68f21e5, 0xabc830f5, 0xc5501ce5, + 0xabbb323c, 0xe6610a2a, 0xabae4082, 0xc5643c4a, 0xaba15bc9, 0xe633023e, 0xab948413, 0xc5787fd6, + 0xab87b962, 0xe6050a3b, 0xab7afbb7, 0xc58ce77c, 0xab6e4b15, 0xe5d72240, 0xab61a77d, 0xc5a17330, + 0xab5510f3, 0xe5a94a67, 0xab488776, 0xc5b622e6, 0xab3c0b0b, 0xe57b82cd, 0xab2f9bb1, 0xc5caf690, + 0xab23396c, 0xe54dcb8f, 0xab16e43d, 0xc5dfee22, 0xab0a9c27, 0xe52024c9, 0xaafe612a, 0xc5f5098f, + 0xaaf23349, 0xe4f28e96, 0xaae61286, 0xc60a48c9, 0xaad9fee3, 0xe4c50914, 0xaacdf861, 0xc61fabc4, + 0xaac1ff03, 0xe497945d, 0xaab612ca, 0xc6353273, 0xaaaa33b8, 0xe46a308f, 0xaa9e61cf, 0xc64adcc7, + 0xaa929d10, 0xe43cddc4, 0xaa86e57e, 0xc660aab5, 0xaa7b3b1b, 0xe40f9c1a, 0xaa6f9de7, 0xc6769c2e, + 0xaa640de6, 0xe3e26bac, 0xaa588b18, 0xc68cb124, 0xaa4d157f, 0xe3b54c95, 0xaa41ad1e, 0xc6a2e98b, + 0xaa3651f6, 0xe3883ef2, 0xaa2b0409, 0xc6b94554, 0xaa1fc358, 0xe35b42df, 0xaa148fe6, 0xc6cfc472, + 0xaa0969b3, 0xe32e5876, 0xa9fe50c2, 0xc6e666d7, 0xa9f34515, 0xe3017fd5, 0xa9e846ad, 0xc6fd2c75, + 0xa9dd558b, 0xe2d4b916, 0xa9d271b2, 0xc714153e, 0xa9c79b23, 0xe2a80456, 0xa9bcd1e0, 0xc72b2123, + 0xa9b215ea, 0xe27b61af, 0xa9a76744, 0xc7425016, 0xa99cc5ee, 0xe24ed13d, 0xa99231eb, 0xc759a20a, + 0xa987ab3c, 0xe222531c, 0xa97d31e3, 0xc77116f0, 0xa972c5e1, 0xe1f5e768, 0xa9686738, 0xc788aeb9, + 0xa95e15e9, 0xe1c98e3b, 0xa953d1f7, 0xc7a06957, 0xa9499b62, 0xe19d47b1, 0xa93f722c, 0xc7b846ba, + 0xa9355658, 0xe17113e5, 0xa92b47e5, 0xc7d046d6, 0xa92146d7, 0xe144f2f3, 0xa917532e, 0xc7e8699a, + 0xa90d6cec, 0xe118e4f6, 0xa9039413, 0xc800aef7, 0xa8f9c8a4, 0xe0ecea09, 0xa8f00aa0, 0xc81916df, + 0xa8e65a0a, 0xe0c10247, 0xa8dcb6e2, 0xc831a143, 0xa8d3212a, 0xe0952dcb, 0xa8c998e3, 0xc84a4e14, + 0xa8c01e10, 0xe0696cb0, 0xa8b6b0b1, 0xc8631d42, 0xa8ad50c8, 0xe03dbf11, 0xa8a3fe57, 0xc87c0ebd, + 0xa89ab95e, 0xe012250a, 0xa89181df, 0xc8952278, 0xa88857dc, 0xdfe69eb4, 0xa87f3b57, 0xc8ae5862, + 0xa8762c4f, 0xdfbb2c2c, 0xa86d2ac8, 0xc8c7b06b, 0xa86436c2, 0xdf8fcd8b, 0xa85b503e, 0xc8e12a84, + 0xa852773f, 0xdf6482ed, 0xa849abc4, 0xc8fac69e, 0xa840edd1, 0xdf394c6b, 0xa8383d66, 0xc91484a8, + 0xa82f9a84, 0xdf0e2a22, 0xa827052d, 0xc92e6492, 0xa81e7d62, 0xdee31c2b, 0xa8160324, 0xc948664d, + 0xa80d9675, 0xdeb822a1, 0xa8053756, 0xc96289c9, 0xa7fce5c9, 0xde8d3d9e, 0xa7f4a1ce, 0xc97ccef5, + 0xa7ec6b66, 0xde626d3e, 0xa7e44294, 0xc99735c2, 0xa7dc2759, 0xde37b199, 0xa7d419b4, 0xc9b1be1e, + 0xa7cc19a9, 0xde0d0acc, 0xa7c42738, 0xc9cc67fa, 0xa7bc4262, 0xdde278ef, 0xa7b46b29, 0xc9e73346, + 0xa7aca18e, 0xddb7fc1e, 0xa7a4e591, 0xca021fef, 0xa79d3735, 0xdd8d9472, 0xa795967a, 0xca1d2de7, + 0xa78e0361, 0xdd634206, 0xa7867dec, 0xca385d1d, 0xa77f061c, 0xdd3904f4, 0xa7779bf2, 0xca53ad7e, + 0xa7703f70, 0xdd0edd55, 0xa768f095, 0xca6f1efc, 0xa761af64, 0xdce4cb44, 0xa75a7bdd, 0xca8ab184, + 0xa7535602, 0xdcbacedb, 0xa74c3dd4, 0xcaa66506, 0xa7453353, 0xdc90e834, 0xa73e3681, 0xcac23971, + 0xa7374760, 0xdc671768, 0xa73065ef, 0xcade2eb3, 0xa7299231, 0xdc3d5c91, 0xa722cc25, 0xcafa44bc, + 0xa71c13ce, 0xdc13b7c9, 0xa715692c, 0xcb167b79, 0xa70ecc41, 0xdbea292b, 0xa7083d0d, 0xcb32d2da, + 0xa701bb91, 0xdbc0b0ce, 0xa6fb47ce, 0xcb4f4acd, 0xa6f4e1c6, 0xdb974ece, 0xa6ee8979, 0xcb6be341, + 0xa6e83ee8, 0xdb6e0342, 0xa6e20214, 0xcb889c23, 0xa6dbd2ff, 0xdb44ce46, 0xa6d5b1a9, 0xcba57563, + 0xa6cf9e13, 0xdb1baff2, 0xa6c9983e, 0xcbc26eee, 0xa6c3a02b, 0xdaf2a860, 0xa6bdb5da, 0xcbdf88b3, + 0xa6b7d94e, 0xdac9b7a9, 0xa6b20a86, 0xcbfcc29f, 0xa6ac4984, 0xdaa0dde7, 0xa6a69649, 0xcc1a1ca0, + 0xa6a0f0d5, 0xda781b31, 0xa69b5929, 0xcc3796a5, 0xa695cf46, 0xda4f6fa3, 0xa690532d, 0xcc55309b, + 0xa68ae4df, 0xda26db54, 0xa685845c, 0xcc72ea70, 0xa68031a6, 0xd9fe5e5e, 0xa67aecbd, 0xcc90c412, + 0xa675b5a3, 0xd9d5f8d9, 0xa6708c57, 0xccaebd6e, 0xa66b70db, 0xd9adaadf, 0xa6666330, 0xccccd671, + 0xa6616355, 0xd9857489, 0xa65c714d, 0xcceb0f0a, 0xa6578d18, 0xd95d55ef, 0xa652b6b6, 0xcd096725, + 0xa64dee28, 0xd9354f2a, 0xa6493370, 0xcd27deb0, 0xa644868d, 0xd90d6053, 0xa63fe781, 0xcd467599, + 0xa63b564c, 0xd8e58982, 0xa636d2ee, 0xcd652bcb, 0xa6325d6a, 0xd8bdcad0, 0xa62df5bf, 0xcd840134, + 0xa6299bed, 0xd8962456, 0xa6254ff7, 0xcda2f5c2, 0xa62111db, 0xd86e962b, 0xa61ce19c, 0xcdc20960, + 0xa618bf39, 0xd8472069, 0xa614aab3, 0xcde13bfd, 0xa610a40c, 0xd81fc328, 0xa60cab43, 0xce008d84, + 0xa608c058, 0xd7f87e7f, 0xa604e34e, 0xce1ffde2, 0xa6011424, 0xd7d15288, 0xa5fd52db, 0xce3f8d05, + 0xa5f99f73, 0xd7aa3f5a, 0xa5f5f9ed, 0xce5f3ad8, 0xa5f2624a, 0xd783450d, 0xa5eed88a, 0xce7f0748, + 0xa5eb5cae, 0xd75c63ba, 0xa5e7eeb6, 0xce9ef241, 0xa5e48ea3, 0xd7359b78, 0xa5e13c75, 0xcebefbb0, + 0xa5ddf82d, 0xd70eec60, 0xa5dac1cb, 0xcedf2380, 0xa5d79950, 0xd6e85689, 0xa5d47ebc, 0xceff699f, + 0xa5d17210, 0xd6c1da0b, 0xa5ce734d, 0xcf1fcdf8, 0xa5cb8272, 0xd69b76fe, 0xa5c89f80, 0xcf405077, + 0xa5c5ca77, 0xd6752d79, 0xa5c30359, 0xcf60f108, 0xa5c04a25, 0xd64efd94, 0xa5bd9edc, 0xcf81af97, + 0xa5bb017f, 0xd628e767, 0xa5b8720d, 0xcfa28c10, 0xa5b5f087, 0xd602eb0a, 0xa5b37cee, 0xcfc3865e, + 0xa5b11741, 0xd5dd0892, 0xa5aebf82, 0xcfe49e6d, 0xa5ac75b0, 0xd5b74019, 0xa5aa39cd, 0xd005d42a, + 0xa5a80bd7, 0xd59191b5, 0xa5a5ebd0, 0xd027277e, 0xa5a3d9b8, 0xd56bfd7d, 0xa5a1d590, 0xd0489856, + 0xa59fdf57, 0xd5468389, 0xa59df70e, 0xd06a269d, 0xa59c1cb5, 0xd52123f0, 0xa59a504c, 0xd08bd23f, + 0xa59891d4, 0xd4fbdec9, 0xa596e14e, 0xd0ad9b26, 0xa5953eb8, 0xd4d6b42b, 0xa593aa14, 0xd0cf813e, + 0xa5922362, 0xd4b1a42c, 0xa590aaa2, 0xd0f18472, 0xa58f3fd4, 0xd48caee4, 0xa58de2f8, 0xd113a4ad, + 0xa58c940f, 0xd467d469, 0xa58b5319, 0xd135e1d9, 0xa58a2016, 0xd44314d3, 0xa588fb06, 0xd1583be2, + 0xa587e3ea, 0xd41e7037, 0xa586dac1, 0xd17ab2b3, 0xa585df8c, 0xd3f9e6ad, 0xa584f24b, 0xd19d4636, + 0xa58412fe, 0xd3d5784a, 0xa58341a5, 0xd1bff656, 0xa5827e40, 0xd3b12526, 0xa581c8d0, 0xd1e2c2fd, + 0xa5812154, 0xd38ced57, 0xa58087cd, 0xd205ac17, 0xa57ffc3b, 0xd368d0f3, 0xa57f7e9d, 0xd228b18d, + 0xa57f0ef5, 0xd344d011, 0xa57ead41, 0xd24bd34a, 0xa57e5982, 0xd320eac6, 0xa57e13b8, 0xd26f1138, + 0xa57ddbe4, 0xd2fd2129, 0xa57db204, 0xd2926b41, 0xa57d961a, 0xd2d97350, 0xa57d8825, 0xd2b5e151, }; -/* PostMultiply() tables - * format = Q30 - * reordered for sequential access - * decimate (skip by 16 instead of 2) for small transform (128) - * - * for (i = 0; i <= (512/2); i++) { - * angle = i * M_PI / 1024; - * x = (cos(angle) + sin(angle)); - * x = sin(angle); - * } - */ -const int cos1sin1tab[514] PROGMEM = { -/* format = Q30 */ -0x40000000, 0x00000000, 0x40323034, 0x003243f1, 0x406438cf, 0x006487c4, 0x409619b2, 0x0096cb58, -0x40c7d2bd, 0x00c90e90, 0x40f963d3, 0x00fb514b, 0x412accd4, 0x012d936c, 0x415c0da3, 0x015fd4d2, -0x418d2621, 0x0192155f, 0x41be162f, 0x01c454f5, 0x41eeddaf, 0x01f69373, 0x421f7c84, 0x0228d0bb, -0x424ff28f, 0x025b0caf, 0x42803fb2, 0x028d472e, 0x42b063d0, 0x02bf801a, 0x42e05ecb, 0x02f1b755, -0x43103085, 0x0323ecbe, 0x433fd8e1, 0x03562038, 0x436f57c1, 0x038851a2, 0x439ead09, 0x03ba80df, -0x43cdd89a, 0x03ecadcf, 0x43fcda59, 0x041ed854, 0x442bb227, 0x0451004d, 0x445a5fe8, 0x0483259d, -0x4488e37f, 0x04b54825, 0x44b73ccf, 0x04e767c5, 0x44e56bbd, 0x0519845e, 0x4513702a, 0x054b9dd3, -0x454149fc, 0x057db403, 0x456ef916, 0x05afc6d0, 0x459c7d5a, 0x05e1d61b, 0x45c9d6af, 0x0613e1c5, -0x45f704f7, 0x0645e9af, 0x46240816, 0x0677edbb, 0x4650dff1, 0x06a9edc9, 0x467d8c6d, 0x06dbe9bb, -0x46aa0d6d, 0x070de172, 0x46d662d6, 0x073fd4cf, 0x47028c8d, 0x0771c3b3, 0x472e8a76, 0x07a3adff, -0x475a5c77, 0x07d59396, 0x47860275, 0x08077457, 0x47b17c54, 0x08395024, 0x47dcc9f9, 0x086b26de, -0x4807eb4b, 0x089cf867, 0x4832e02d, 0x08cec4a0, 0x485da887, 0x09008b6a, 0x4888443d, 0x09324ca7, -0x48b2b335, 0x09640837, 0x48dcf556, 0x0995bdfd, 0x49070a84, 0x09c76dd8, 0x4930f2a6, 0x09f917ac, -0x495aada2, 0x0a2abb59, 0x49843b5f, 0x0a5c58c0, 0x49ad9bc2, 0x0a8defc3, 0x49d6ceb3, 0x0abf8043, -0x49ffd417, 0x0af10a22, 0x4a28abd6, 0x0b228d42, 0x4a5155d6, 0x0b540982, 0x4a79d1ff, 0x0b857ec7, -0x4aa22036, 0x0bb6ecef, 0x4aca4065, 0x0be853de, 0x4af23270, 0x0c19b374, 0x4b19f641, 0x0c4b0b94, -0x4b418bbe, 0x0c7c5c1e, 0x4b68f2cf, 0x0cada4f5, 0x4b902b5c, 0x0cdee5f9, 0x4bb7354d, 0x0d101f0e, -0x4bde1089, 0x0d415013, 0x4c04bcf8, 0x0d7278eb, 0x4c2b3a84, 0x0da39978, 0x4c518913, 0x0dd4b19a, -0x4c77a88e, 0x0e05c135, 0x4c9d98de, 0x0e36c82a, 0x4cc359ec, 0x0e67c65a, 0x4ce8eb9f, 0x0e98bba7, -0x4d0e4de2, 0x0ec9a7f3, 0x4d33809c, 0x0efa8b20, 0x4d5883b7, 0x0f2b650f, 0x4d7d571c, 0x0f5c35a3, -0x4da1fab5, 0x0f8cfcbe, 0x4dc66e6a, 0x0fbdba40, 0x4deab226, 0x0fee6e0d, 0x4e0ec5d1, 0x101f1807, -0x4e32a956, 0x104fb80e, 0x4e565c9f, 0x10804e06, 0x4e79df95, 0x10b0d9d0, 0x4e9d3222, 0x10e15b4e, -0x4ec05432, 0x1111d263, 0x4ee345ad, 0x11423ef0, 0x4f06067f, 0x1172a0d7, 0x4f289692, 0x11a2f7fc, -0x4f4af5d1, 0x11d3443f, 0x4f6d2427, 0x12038584, 0x4f8f217e, 0x1233bbac, 0x4fb0edc1, 0x1263e699, -0x4fd288dc, 0x1294062f, 0x4ff3f2bb, 0x12c41a4f, 0x50152b47, 0x12f422db, 0x5036326e, 0x13241fb6, -0x50570819, 0x135410c3, 0x5077ac37, 0x1383f5e3, 0x50981eb1, 0x13b3cefa, 0x50b85f74, 0x13e39be9, -0x50d86e6d, 0x14135c94, 0x50f84b87, 0x144310dd, 0x5117f6ae, 0x1472b8a5, 0x51376fd0, 0x14a253d1, -0x5156b6d9, 0x14d1e242, 0x5175cbb5, 0x150163dc, 0x5194ae52, 0x1530d881, 0x51b35e9b, 0x15604013, -0x51d1dc80, 0x158f9a76, 0x51f027eb, 0x15bee78c, 0x520e40cc, 0x15ee2738, 0x522c270f, 0x161d595d, -0x5249daa2, 0x164c7ddd, 0x52675b72, 0x167b949d, 0x5284a96e, 0x16aa9d7e, 0x52a1c482, 0x16d99864, -0x52beac9f, 0x17088531, 0x52db61b0, 0x173763c9, 0x52f7e3a6, 0x1766340f, 0x5314326d, 0x1794f5e6, -0x53304df6, 0x17c3a931, 0x534c362d, 0x17f24dd3, 0x5367eb03, 0x1820e3b0, 0x53836c66, 0x184f6aab, -0x539eba45, 0x187de2a7, 0x53b9d48f, 0x18ac4b87, 0x53d4bb34, 0x18daa52f, 0x53ef6e23, 0x1908ef82, -0x5409ed4b, 0x19372a64, 0x5424389d, 0x196555b8, 0x543e5007, 0x19937161, 0x5458337a, 0x19c17d44, -0x5471e2e6, 0x19ef7944, 0x548b5e3b, 0x1a1d6544, 0x54a4a56a, 0x1a4b4128, 0x54bdb862, 0x1a790cd4, -0x54d69714, 0x1aa6c82b, 0x54ef4171, 0x1ad47312, 0x5507b76a, 0x1b020d6c, 0x551ff8ef, 0x1b2f971e, -0x553805f2, 0x1b5d100a, 0x554fde64, 0x1b8a7815, 0x55678236, 0x1bb7cf23, 0x557ef15a, 0x1be51518, -0x55962bc0, 0x1c1249d8, 0x55ad315b, 0x1c3f6d47, 0x55c4021d, 0x1c6c7f4a, 0x55da9df7, 0x1c997fc4, -0x55f104dc, 0x1cc66e99, 0x560736bd, 0x1cf34baf, 0x561d338d, 0x1d2016e9, 0x5632fb3f, 0x1d4cd02c, -0x56488dc5, 0x1d79775c, 0x565deb11, 0x1da60c5d, 0x56731317, 0x1dd28f15, 0x568805c9, 0x1dfeff67, -0x569cc31b, 0x1e2b5d38, 0x56b14b00, 0x1e57a86d, 0x56c59d6a, 0x1e83e0eb, 0x56d9ba4e, 0x1eb00696, -0x56eda1a0, 0x1edc1953, 0x57015352, 0x1f081907, 0x5714cf59, 0x1f340596, 0x572815a8, 0x1f5fdee6, -0x573b2635, 0x1f8ba4dc, 0x574e00f2, 0x1fb7575c, 0x5760a5d5, 0x1fe2f64c, 0x577314d2, 0x200e8190, -0x57854ddd, 0x2039f90f, 0x579750ec, 0x20655cac, 0x57a91df2, 0x2090ac4d, 0x57bab4e6, 0x20bbe7d8, -0x57cc15bc, 0x20e70f32, 0x57dd406a, 0x21122240, 0x57ee34e5, 0x213d20e8, 0x57fef323, 0x21680b0f, -0x580f7b19, 0x2192e09b, 0x581fccbc, 0x21bda171, 0x582fe804, 0x21e84d76, 0x583fcce6, 0x2212e492, -0x584f7b58, 0x223d66a8, 0x585ef351, 0x2267d3a0, 0x586e34c7, 0x22922b5e, 0x587d3fb0, 0x22bc6dca, -0x588c1404, 0x22e69ac8, 0x589ab1b9, 0x2310b23e, 0x58a918c6, 0x233ab414, 0x58b74923, 0x2364a02e, -0x58c542c5, 0x238e7673, 0x58d305a6, 0x23b836ca, 0x58e091bd, 0x23e1e117, 0x58ede700, 0x240b7543, -0x58fb0568, 0x2434f332, 0x5907eced, 0x245e5acc, 0x59149d87, 0x2487abf7, 0x5921172e, 0x24b0e699, -0x592d59da, 0x24da0a9a, 0x59396584, 0x250317df, 0x59453a24, 0x252c0e4f, 0x5950d7b3, 0x2554edd1, -0x595c3e2a, 0x257db64c, 0x59676d82, 0x25a667a7, 0x597265b4, 0x25cf01c8, 0x597d26b8, 0x25f78497, -0x5987b08a, 0x261feffa, 0x59920321, 0x264843d9, 0x599c1e78, 0x2670801a, 0x59a60288, 0x2698a4a6, -0x59afaf4c, 0x26c0b162, 0x59b924bc, 0x26e8a637, 0x59c262d5, 0x2710830c, 0x59cb698f, 0x273847c8, -0x59d438e5, 0x275ff452, 0x59dcd0d3, 0x27878893, 0x59e53151, 0x27af0472, 0x59ed5a5c, 0x27d667d5, -0x59f54bee, 0x27fdb2a7, 0x59fd0603, 0x2824e4cc, 0x5a048895, 0x284bfe2f, 0x5a0bd3a1, 0x2872feb6, -0x5a12e720, 0x2899e64a, 0x5a19c310, 0x28c0b4d2, 0x5a20676c, 0x28e76a37, 0x5a26d42f, 0x290e0661, -0x5a2d0957, 0x29348937, 0x5a3306de, 0x295af2a3, 0x5a38ccc2, 0x2981428c, 0x5a3e5afe, 0x29a778db, -0x5a43b190, 0x29cd9578, 0x5a48d074, 0x29f3984c, 0x5a4db7a6, 0x2a19813f, 0x5a526725, 0x2a3f503a, -0x5a56deec, 0x2a650525, 0x5a5b1efa, 0x2a8a9fea, 0x5a5f274b, 0x2ab02071, 0x5a62f7dd, 0x2ad586a3, -0x5a6690ae, 0x2afad269, 0x5a69f1bb, 0x2b2003ac, 0x5a6d1b03, 0x2b451a55, 0x5a700c84, 0x2b6a164d, -0x5a72c63b, 0x2b8ef77d, 0x5a754827, 0x2bb3bdce, 0x5a779246, 0x2bd8692b, 0x5a79a498, 0x2bfcf97c, -0x5a7b7f1a, 0x2c216eaa, 0x5a7d21cc, 0x2c45c8a0, 0x5a7e8cac, 0x2c6a0746, 0x5a7fbfbb, 0x2c8e2a87, -0x5a80baf6, 0x2cb2324c, 0x5a817e5d, 0x2cd61e7f, 0x5a8209f1, 0x2cf9ef09, 0x5a825db0, 0x2d1da3d5, -0x5a82799a, 0x2d413ccd, +/* PostMultiply() tables + format = Q30 + reordered for sequential access + decimate (skip by 16 instead of 2) for small transform (128) + + for (i = 0; i <= (512/2); i++) { + angle = i * M_PI / 1024; + x = (cos(angle) + sin(angle)); + x = sin(angle); + } +*/ +const int cos1sin1tab[514] DPROGMEM = { + /* format = Q30 */ + 0x40000000, 0x00000000, 0x40323034, 0x003243f1, 0x406438cf, 0x006487c4, 0x409619b2, 0x0096cb58, + 0x40c7d2bd, 0x00c90e90, 0x40f963d3, 0x00fb514b, 0x412accd4, 0x012d936c, 0x415c0da3, 0x015fd4d2, + 0x418d2621, 0x0192155f, 0x41be162f, 0x01c454f5, 0x41eeddaf, 0x01f69373, 0x421f7c84, 0x0228d0bb, + 0x424ff28f, 0x025b0caf, 0x42803fb2, 0x028d472e, 0x42b063d0, 0x02bf801a, 0x42e05ecb, 0x02f1b755, + 0x43103085, 0x0323ecbe, 0x433fd8e1, 0x03562038, 0x436f57c1, 0x038851a2, 0x439ead09, 0x03ba80df, + 0x43cdd89a, 0x03ecadcf, 0x43fcda59, 0x041ed854, 0x442bb227, 0x0451004d, 0x445a5fe8, 0x0483259d, + 0x4488e37f, 0x04b54825, 0x44b73ccf, 0x04e767c5, 0x44e56bbd, 0x0519845e, 0x4513702a, 0x054b9dd3, + 0x454149fc, 0x057db403, 0x456ef916, 0x05afc6d0, 0x459c7d5a, 0x05e1d61b, 0x45c9d6af, 0x0613e1c5, + 0x45f704f7, 0x0645e9af, 0x46240816, 0x0677edbb, 0x4650dff1, 0x06a9edc9, 0x467d8c6d, 0x06dbe9bb, + 0x46aa0d6d, 0x070de172, 0x46d662d6, 0x073fd4cf, 0x47028c8d, 0x0771c3b3, 0x472e8a76, 0x07a3adff, + 0x475a5c77, 0x07d59396, 0x47860275, 0x08077457, 0x47b17c54, 0x08395024, 0x47dcc9f9, 0x086b26de, + 0x4807eb4b, 0x089cf867, 0x4832e02d, 0x08cec4a0, 0x485da887, 0x09008b6a, 0x4888443d, 0x09324ca7, + 0x48b2b335, 0x09640837, 0x48dcf556, 0x0995bdfd, 0x49070a84, 0x09c76dd8, 0x4930f2a6, 0x09f917ac, + 0x495aada2, 0x0a2abb59, 0x49843b5f, 0x0a5c58c0, 0x49ad9bc2, 0x0a8defc3, 0x49d6ceb3, 0x0abf8043, + 0x49ffd417, 0x0af10a22, 0x4a28abd6, 0x0b228d42, 0x4a5155d6, 0x0b540982, 0x4a79d1ff, 0x0b857ec7, + 0x4aa22036, 0x0bb6ecef, 0x4aca4065, 0x0be853de, 0x4af23270, 0x0c19b374, 0x4b19f641, 0x0c4b0b94, + 0x4b418bbe, 0x0c7c5c1e, 0x4b68f2cf, 0x0cada4f5, 0x4b902b5c, 0x0cdee5f9, 0x4bb7354d, 0x0d101f0e, + 0x4bde1089, 0x0d415013, 0x4c04bcf8, 0x0d7278eb, 0x4c2b3a84, 0x0da39978, 0x4c518913, 0x0dd4b19a, + 0x4c77a88e, 0x0e05c135, 0x4c9d98de, 0x0e36c82a, 0x4cc359ec, 0x0e67c65a, 0x4ce8eb9f, 0x0e98bba7, + 0x4d0e4de2, 0x0ec9a7f3, 0x4d33809c, 0x0efa8b20, 0x4d5883b7, 0x0f2b650f, 0x4d7d571c, 0x0f5c35a3, + 0x4da1fab5, 0x0f8cfcbe, 0x4dc66e6a, 0x0fbdba40, 0x4deab226, 0x0fee6e0d, 0x4e0ec5d1, 0x101f1807, + 0x4e32a956, 0x104fb80e, 0x4e565c9f, 0x10804e06, 0x4e79df95, 0x10b0d9d0, 0x4e9d3222, 0x10e15b4e, + 0x4ec05432, 0x1111d263, 0x4ee345ad, 0x11423ef0, 0x4f06067f, 0x1172a0d7, 0x4f289692, 0x11a2f7fc, + 0x4f4af5d1, 0x11d3443f, 0x4f6d2427, 0x12038584, 0x4f8f217e, 0x1233bbac, 0x4fb0edc1, 0x1263e699, + 0x4fd288dc, 0x1294062f, 0x4ff3f2bb, 0x12c41a4f, 0x50152b47, 0x12f422db, 0x5036326e, 0x13241fb6, + 0x50570819, 0x135410c3, 0x5077ac37, 0x1383f5e3, 0x50981eb1, 0x13b3cefa, 0x50b85f74, 0x13e39be9, + 0x50d86e6d, 0x14135c94, 0x50f84b87, 0x144310dd, 0x5117f6ae, 0x1472b8a5, 0x51376fd0, 0x14a253d1, + 0x5156b6d9, 0x14d1e242, 0x5175cbb5, 0x150163dc, 0x5194ae52, 0x1530d881, 0x51b35e9b, 0x15604013, + 0x51d1dc80, 0x158f9a76, 0x51f027eb, 0x15bee78c, 0x520e40cc, 0x15ee2738, 0x522c270f, 0x161d595d, + 0x5249daa2, 0x164c7ddd, 0x52675b72, 0x167b949d, 0x5284a96e, 0x16aa9d7e, 0x52a1c482, 0x16d99864, + 0x52beac9f, 0x17088531, 0x52db61b0, 0x173763c9, 0x52f7e3a6, 0x1766340f, 0x5314326d, 0x1794f5e6, + 0x53304df6, 0x17c3a931, 0x534c362d, 0x17f24dd3, 0x5367eb03, 0x1820e3b0, 0x53836c66, 0x184f6aab, + 0x539eba45, 0x187de2a7, 0x53b9d48f, 0x18ac4b87, 0x53d4bb34, 0x18daa52f, 0x53ef6e23, 0x1908ef82, + 0x5409ed4b, 0x19372a64, 0x5424389d, 0x196555b8, 0x543e5007, 0x19937161, 0x5458337a, 0x19c17d44, + 0x5471e2e6, 0x19ef7944, 0x548b5e3b, 0x1a1d6544, 0x54a4a56a, 0x1a4b4128, 0x54bdb862, 0x1a790cd4, + 0x54d69714, 0x1aa6c82b, 0x54ef4171, 0x1ad47312, 0x5507b76a, 0x1b020d6c, 0x551ff8ef, 0x1b2f971e, + 0x553805f2, 0x1b5d100a, 0x554fde64, 0x1b8a7815, 0x55678236, 0x1bb7cf23, 0x557ef15a, 0x1be51518, + 0x55962bc0, 0x1c1249d8, 0x55ad315b, 0x1c3f6d47, 0x55c4021d, 0x1c6c7f4a, 0x55da9df7, 0x1c997fc4, + 0x55f104dc, 0x1cc66e99, 0x560736bd, 0x1cf34baf, 0x561d338d, 0x1d2016e9, 0x5632fb3f, 0x1d4cd02c, + 0x56488dc5, 0x1d79775c, 0x565deb11, 0x1da60c5d, 0x56731317, 0x1dd28f15, 0x568805c9, 0x1dfeff67, + 0x569cc31b, 0x1e2b5d38, 0x56b14b00, 0x1e57a86d, 0x56c59d6a, 0x1e83e0eb, 0x56d9ba4e, 0x1eb00696, + 0x56eda1a0, 0x1edc1953, 0x57015352, 0x1f081907, 0x5714cf59, 0x1f340596, 0x572815a8, 0x1f5fdee6, + 0x573b2635, 0x1f8ba4dc, 0x574e00f2, 0x1fb7575c, 0x5760a5d5, 0x1fe2f64c, 0x577314d2, 0x200e8190, + 0x57854ddd, 0x2039f90f, 0x579750ec, 0x20655cac, 0x57a91df2, 0x2090ac4d, 0x57bab4e6, 0x20bbe7d8, + 0x57cc15bc, 0x20e70f32, 0x57dd406a, 0x21122240, 0x57ee34e5, 0x213d20e8, 0x57fef323, 0x21680b0f, + 0x580f7b19, 0x2192e09b, 0x581fccbc, 0x21bda171, 0x582fe804, 0x21e84d76, 0x583fcce6, 0x2212e492, + 0x584f7b58, 0x223d66a8, 0x585ef351, 0x2267d3a0, 0x586e34c7, 0x22922b5e, 0x587d3fb0, 0x22bc6dca, + 0x588c1404, 0x22e69ac8, 0x589ab1b9, 0x2310b23e, 0x58a918c6, 0x233ab414, 0x58b74923, 0x2364a02e, + 0x58c542c5, 0x238e7673, 0x58d305a6, 0x23b836ca, 0x58e091bd, 0x23e1e117, 0x58ede700, 0x240b7543, + 0x58fb0568, 0x2434f332, 0x5907eced, 0x245e5acc, 0x59149d87, 0x2487abf7, 0x5921172e, 0x24b0e699, + 0x592d59da, 0x24da0a9a, 0x59396584, 0x250317df, 0x59453a24, 0x252c0e4f, 0x5950d7b3, 0x2554edd1, + 0x595c3e2a, 0x257db64c, 0x59676d82, 0x25a667a7, 0x597265b4, 0x25cf01c8, 0x597d26b8, 0x25f78497, + 0x5987b08a, 0x261feffa, 0x59920321, 0x264843d9, 0x599c1e78, 0x2670801a, 0x59a60288, 0x2698a4a6, + 0x59afaf4c, 0x26c0b162, 0x59b924bc, 0x26e8a637, 0x59c262d5, 0x2710830c, 0x59cb698f, 0x273847c8, + 0x59d438e5, 0x275ff452, 0x59dcd0d3, 0x27878893, 0x59e53151, 0x27af0472, 0x59ed5a5c, 0x27d667d5, + 0x59f54bee, 0x27fdb2a7, 0x59fd0603, 0x2824e4cc, 0x5a048895, 0x284bfe2f, 0x5a0bd3a1, 0x2872feb6, + 0x5a12e720, 0x2899e64a, 0x5a19c310, 0x28c0b4d2, 0x5a20676c, 0x28e76a37, 0x5a26d42f, 0x290e0661, + 0x5a2d0957, 0x29348937, 0x5a3306de, 0x295af2a3, 0x5a38ccc2, 0x2981428c, 0x5a3e5afe, 0x29a778db, + 0x5a43b190, 0x29cd9578, 0x5a48d074, 0x29f3984c, 0x5a4db7a6, 0x2a19813f, 0x5a526725, 0x2a3f503a, + 0x5a56deec, 0x2a650525, 0x5a5b1efa, 0x2a8a9fea, 0x5a5f274b, 0x2ab02071, 0x5a62f7dd, 0x2ad586a3, + 0x5a6690ae, 0x2afad269, 0x5a69f1bb, 0x2b2003ac, 0x5a6d1b03, 0x2b451a55, 0x5a700c84, 0x2b6a164d, + 0x5a72c63b, 0x2b8ef77d, 0x5a754827, 0x2bb3bdce, 0x5a779246, 0x2bd8692b, 0x5a79a498, 0x2bfcf97c, + 0x5a7b7f1a, 0x2c216eaa, 0x5a7d21cc, 0x2c45c8a0, 0x5a7e8cac, 0x2c6a0746, 0x5a7fbfbb, 0x2c8e2a87, + 0x5a80baf6, 0x2cb2324c, 0x5a817e5d, 0x2cd61e7f, 0x5a8209f1, 0x2cf9ef09, 0x5a825db0, 0x2d1da3d5, + 0x5a82799a, 0x2d413ccd, }; -const int sinWindowOffset[NUM_IMDCT_SIZES] PROGMEM = {0, 128}; - -/* Synthesis window - SIN - * format = Q31 for nmdct = [128, 1024] - * reordered for sequential access - * - * for (i = 0; i < nmdct/2; i++) { - * angle = (i + 0.5) * M_PI / (2.0 * nmdct); - * x = sin(angle); - * - * angle = (nmdct - 1 - i + 0.5) * M_PI / (2.0 * nmdct); - * x = sin(angle); - * } - */ +const int sinWindowOffset[NUM_IMDCT_SIZES] DPROGMEM = {0, 128}; + +/* Synthesis window - SIN + format = Q31 for nmdct = [128, 1024] + reordered for sequential access + + for (i = 0; i < nmdct/2; i++) { + angle = (i + 0.5) * M_PI / (2.0 * nmdct); + x = sin(angle); + + angle = (nmdct - 1 - i + 0.5) * M_PI / (2.0 * nmdct); + x = sin(angle); + } +*/ const int sinWindow[128 + 1024] PROGMEM = { -/* 128 - format = Q31 * 2^0 */ -0x00c90f88, 0x7fff6216, 0x025b26d7, 0x7ffa72d1, 0x03ed26e6, 0x7ff09478, 0x057f0035, 0x7fe1c76b, -0x0710a345, 0x7fce0c3e, 0x08a2009a, 0x7fb563b3, 0x0a3308bd, 0x7f97cebd, 0x0bc3ac35, 0x7f754e80, -0x0d53db92, 0x7f4de451, 0x0ee38766, 0x7f2191b4, 0x1072a048, 0x7ef05860, 0x120116d5, 0x7eba3a39, -0x138edbb1, 0x7e7f3957, 0x151bdf86, 0x7e3f57ff, 0x16a81305, 0x7dfa98a8, 0x183366e9, 0x7db0fdf8, -0x19bdcbf3, 0x7d628ac6, 0x1b4732ef, 0x7d0f4218, 0x1ccf8cb3, 0x7cb72724, 0x1e56ca1e, 0x7c5a3d50, -0x1fdcdc1b, 0x7bf88830, 0x2161b3a0, 0x7b920b89, 0x22e541af, 0x7b26cb4f, 0x24677758, 0x7ab6cba4, -0x25e845b6, 0x7a4210d8, 0x27679df4, 0x79c89f6e, 0x28e5714b, 0x794a7c12, 0x2a61b101, 0x78c7aba2, -0x2bdc4e6f, 0x78403329, 0x2d553afc, 0x77b417df, 0x2ecc681e, 0x77235f2d, 0x3041c761, 0x768e0ea6, -0x31b54a5e, 0x75f42c0b, 0x3326e2c3, 0x7555bd4c, 0x34968250, 0x74b2c884, 0x36041ad9, 0x740b53fb, -0x376f9e46, 0x735f6626, 0x38d8fe93, 0x72af05a7, 0x3a402dd2, 0x71fa3949, 0x3ba51e29, 0x71410805, -0x3d07c1d6, 0x708378ff, 0x3e680b2c, 0x6fc19385, 0x3fc5ec98, 0x6efb5f12, 0x4121589b, 0x6e30e34a, -0x427a41d0, 0x6d6227fa, 0x43d09aed, 0x6c8f351c, 0x452456bd, 0x6bb812d1, 0x46756828, 0x6adcc964, -0x47c3c22f, 0x69fd614a, 0x490f57ee, 0x6919e320, 0x4a581c9e, 0x683257ab, 0x4b9e0390, 0x6746c7d8, -0x4ce10034, 0x66573cbb, 0x4e210617, 0x6563bf92, 0x4f5e08e3, 0x646c59bf, 0x5097fc5e, 0x637114cc, -0x51ced46e, 0x6271fa69, 0x53028518, 0x616f146c, 0x5433027d, 0x60686ccf, 0x556040e2, 0x5f5e0db3, -0x568a34a9, 0x5e50015d, 0x57b0d256, 0x5d3e5237, 0x58d40e8c, 0x5c290acc, 0x59f3de12, 0x5b1035cf, -/* 1024 - format = Q31 * 2^0 */ -0x001921fb, 0x7ffffd88, 0x004b65ee, 0x7fffe9cb, 0x007da9d4, 0x7fffc251, 0x00afeda8, 0x7fff8719, -0x00e23160, 0x7fff3824, 0x011474f6, 0x7ffed572, 0x0146b860, 0x7ffe5f03, 0x0178fb99, 0x7ffdd4d7, -0x01ab3e97, 0x7ffd36ee, 0x01dd8154, 0x7ffc8549, 0x020fc3c6, 0x7ffbbfe6, 0x024205e8, 0x7ffae6c7, -0x027447b0, 0x7ff9f9ec, 0x02a68917, 0x7ff8f954, 0x02d8ca16, 0x7ff7e500, 0x030b0aa4, 0x7ff6bcf0, -0x033d4abb, 0x7ff58125, 0x036f8a51, 0x7ff4319d, 0x03a1c960, 0x7ff2ce5b, 0x03d407df, 0x7ff1575d, -0x040645c7, 0x7fefcca4, 0x04388310, 0x7fee2e30, 0x046abfb3, 0x7fec7c02, 0x049cfba7, 0x7feab61a, -0x04cf36e5, 0x7fe8dc78, 0x05017165, 0x7fe6ef1c, 0x0533ab20, 0x7fe4ee06, 0x0565e40d, 0x7fe2d938, -0x05981c26, 0x7fe0b0b1, 0x05ca5361, 0x7fde7471, 0x05fc89b8, 0x7fdc247a, 0x062ebf22, 0x7fd9c0ca, -0x0660f398, 0x7fd74964, 0x06932713, 0x7fd4be46, 0x06c5598a, 0x7fd21f72, 0x06f78af6, 0x7fcf6ce8, -0x0729bb4e, 0x7fcca6a7, 0x075bea8c, 0x7fc9ccb2, 0x078e18a7, 0x7fc6df08, 0x07c04598, 0x7fc3dda9, -0x07f27157, 0x7fc0c896, 0x08249bdd, 0x7fbd9fd0, 0x0856c520, 0x7fba6357, 0x0888ed1b, 0x7fb7132b, -0x08bb13c5, 0x7fb3af4e, 0x08ed3916, 0x7fb037bf, 0x091f5d06, 0x7facac7f, 0x09517f8f, 0x7fa90d8e, -0x0983a0a7, 0x7fa55aee, 0x09b5c048, 0x7fa1949e, 0x09e7de6a, 0x7f9dbaa0, 0x0a19fb04, 0x7f99ccf4, -0x0a4c1610, 0x7f95cb9a, 0x0a7e2f85, 0x7f91b694, 0x0ab0475c, 0x7f8d8de1, 0x0ae25d8d, 0x7f895182, -0x0b147211, 0x7f850179, 0x0b4684df, 0x7f809dc5, 0x0b7895f0, 0x7f7c2668, 0x0baaa53b, 0x7f779b62, -0x0bdcb2bb, 0x7f72fcb4, 0x0c0ebe66, 0x7f6e4a5e, 0x0c40c835, 0x7f698461, 0x0c72d020, 0x7f64aabf, -0x0ca4d620, 0x7f5fbd77, 0x0cd6da2d, 0x7f5abc8a, 0x0d08dc3f, 0x7f55a7fa, 0x0d3adc4e, 0x7f507fc7, -0x0d6cda53, 0x7f4b43f2, 0x0d9ed646, 0x7f45f47b, 0x0dd0d01f, 0x7f409164, 0x0e02c7d7, 0x7f3b1aad, -0x0e34bd66, 0x7f359057, 0x0e66b0c3, 0x7f2ff263, 0x0e98a1e9, 0x7f2a40d2, 0x0eca90ce, 0x7f247ba5, -0x0efc7d6b, 0x7f1ea2dc, 0x0f2e67b8, 0x7f18b679, 0x0f604faf, 0x7f12b67c, 0x0f923546, 0x7f0ca2e7, -0x0fc41876, 0x7f067bba, 0x0ff5f938, 0x7f0040f6, 0x1027d784, 0x7ef9f29d, 0x1059b352, 0x7ef390ae, -0x108b8c9b, 0x7eed1b2c, 0x10bd6356, 0x7ee69217, 0x10ef377d, 0x7edff570, 0x11210907, 0x7ed94538, -0x1152d7ed, 0x7ed28171, 0x1184a427, 0x7ecbaa1a, 0x11b66dad, 0x7ec4bf36, 0x11e83478, 0x7ebdc0c6, -0x1219f880, 0x7eb6aeca, 0x124bb9be, 0x7eaf8943, 0x127d7829, 0x7ea85033, 0x12af33ba, 0x7ea1039b, -0x12e0ec6a, 0x7e99a37c, 0x1312a230, 0x7e922fd6, 0x13445505, 0x7e8aa8ac, 0x137604e2, 0x7e830dff, -0x13a7b1bf, 0x7e7b5fce, 0x13d95b93, 0x7e739e1d, 0x140b0258, 0x7e6bc8eb, 0x143ca605, 0x7e63e03b, -0x146e4694, 0x7e5be40c, 0x149fe3fc, 0x7e53d462, 0x14d17e36, 0x7e4bb13c, 0x1503153a, 0x7e437a9c, -0x1534a901, 0x7e3b3083, 0x15663982, 0x7e32d2f4, 0x1597c6b7, 0x7e2a61ed, 0x15c95097, 0x7e21dd73, -0x15fad71b, 0x7e194584, 0x162c5a3b, 0x7e109a24, 0x165dd9f0, 0x7e07db52, 0x168f5632, 0x7dff0911, -0x16c0cef9, 0x7df62362, 0x16f2443e, 0x7ded2a47, 0x1723b5f9, 0x7de41dc0, 0x17552422, 0x7ddafdce, -0x17868eb3, 0x7dd1ca75, 0x17b7f5a3, 0x7dc883b4, 0x17e958ea, 0x7dbf298d, 0x181ab881, 0x7db5bc02, -0x184c1461, 0x7dac3b15, 0x187d6c82, 0x7da2a6c6, 0x18aec0db, 0x7d98ff17, 0x18e01167, 0x7d8f4409, -0x19115e1c, 0x7d85759f, 0x1942a6f3, 0x7d7b93da, 0x1973ebe6, 0x7d719eba, 0x19a52ceb, 0x7d679642, -0x19d669fc, 0x7d5d7a74, 0x1a07a311, 0x7d534b50, 0x1a38d823, 0x7d4908d9, 0x1a6a0929, 0x7d3eb30f, -0x1a9b361d, 0x7d3449f5, 0x1acc5ef6, 0x7d29cd8c, 0x1afd83ad, 0x7d1f3dd6, 0x1b2ea43a, 0x7d149ad5, -0x1b5fc097, 0x7d09e489, 0x1b90d8bb, 0x7cff1af5, 0x1bc1ec9e, 0x7cf43e1a, 0x1bf2fc3a, 0x7ce94dfb, -0x1c240786, 0x7cde4a98, 0x1c550e7c, 0x7cd333f3, 0x1c861113, 0x7cc80a0f, 0x1cb70f43, 0x7cbcccec, -0x1ce80906, 0x7cb17c8d, 0x1d18fe54, 0x7ca618f3, 0x1d49ef26, 0x7c9aa221, 0x1d7adb73, 0x7c8f1817, -0x1dabc334, 0x7c837ad8, 0x1ddca662, 0x7c77ca65, 0x1e0d84f5, 0x7c6c06c0, 0x1e3e5ee5, 0x7c602fec, -0x1e6f342c, 0x7c5445e9, 0x1ea004c1, 0x7c4848ba, 0x1ed0d09d, 0x7c3c3860, 0x1f0197b8, 0x7c3014de, -0x1f325a0b, 0x7c23de35, 0x1f63178f, 0x7c179467, 0x1f93d03c, 0x7c0b3777, 0x1fc4840a, 0x7bfec765, -0x1ff532f2, 0x7bf24434, 0x2025dcec, 0x7be5ade6, 0x205681f1, 0x7bd9047c, 0x208721f9, 0x7bcc47fa, -0x20b7bcfe, 0x7bbf7860, 0x20e852f6, 0x7bb295b0, 0x2118e3dc, 0x7ba59fee, 0x21496fa7, 0x7b989719, -0x2179f64f, 0x7b8b7b36, 0x21aa77cf, 0x7b7e4c45, 0x21daf41d, 0x7b710a49, 0x220b6b32, 0x7b63b543, -0x223bdd08, 0x7b564d36, 0x226c4996, 0x7b48d225, 0x229cb0d5, 0x7b3b4410, 0x22cd12bd, 0x7b2da2fa, -0x22fd6f48, 0x7b1feee5, 0x232dc66d, 0x7b1227d3, 0x235e1826, 0x7b044dc7, 0x238e646a, 0x7af660c2, -0x23beab33, 0x7ae860c7, 0x23eeec78, 0x7ada4dd8, 0x241f2833, 0x7acc27f7, 0x244f5e5c, 0x7abdef25, -0x247f8eec, 0x7aafa367, 0x24afb9da, 0x7aa144bc, 0x24dfdf20, 0x7a92d329, 0x250ffeb7, 0x7a844eae, -0x25401896, 0x7a75b74f, 0x25702cb7, 0x7a670d0d, 0x25a03b11, 0x7a584feb, 0x25d0439f, 0x7a497feb, -0x26004657, 0x7a3a9d0f, 0x26304333, 0x7a2ba75a, 0x26603a2c, 0x7a1c9ece, 0x26902b39, 0x7a0d836d, -0x26c01655, 0x79fe5539, 0x26effb76, 0x79ef1436, 0x271fda96, 0x79dfc064, 0x274fb3ae, 0x79d059c8, -0x277f86b5, 0x79c0e062, 0x27af53a6, 0x79b15435, 0x27df1a77, 0x79a1b545, 0x280edb23, 0x79920392, -0x283e95a1, 0x79823f20, 0x286e49ea, 0x797267f2, 0x289df7f8, 0x79627e08, 0x28cd9fc1, 0x79528167, -0x28fd4140, 0x79427210, 0x292cdc6d, 0x79325006, 0x295c7140, 0x79221b4b, 0x298bffb2, 0x7911d3e2, -0x29bb87bc, 0x790179cd, 0x29eb0957, 0x78f10d0f, 0x2a1a847b, 0x78e08dab, 0x2a49f920, 0x78cffba3, -0x2a796740, 0x78bf56f9, 0x2aa8ced3, 0x78ae9fb0, 0x2ad82fd2, 0x789dd5cb, 0x2b078a36, 0x788cf94c, -0x2b36ddf7, 0x787c0a36, 0x2b662b0e, 0x786b088c, 0x2b957173, 0x7859f44f, 0x2bc4b120, 0x7848cd83, -0x2bf3ea0d, 0x7837942b, 0x2c231c33, 0x78264849, 0x2c52478a, 0x7814e9df, 0x2c816c0c, 0x780378f1, -0x2cb089b1, 0x77f1f581, 0x2cdfa071, 0x77e05f91, 0x2d0eb046, 0x77ceb725, 0x2d3db928, 0x77bcfc3f, -0x2d6cbb10, 0x77ab2ee2, 0x2d9bb5f6, 0x77994f11, 0x2dcaa9d5, 0x77875cce, 0x2df996a3, 0x7775581d, -0x2e287c5a, 0x776340ff, 0x2e575af3, 0x77511778, 0x2e863267, 0x773edb8b, 0x2eb502ae, 0x772c8d3a, -0x2ee3cbc1, 0x771a2c88, 0x2f128d99, 0x7707b979, 0x2f41482e, 0x76f5340e, 0x2f6ffb7a, 0x76e29c4b, -0x2f9ea775, 0x76cff232, 0x2fcd4c19, 0x76bd35c7, 0x2ffbe95d, 0x76aa670d, 0x302a7f3a, 0x76978605, -0x30590dab, 0x768492b4, 0x308794a6, 0x76718d1c, 0x30b61426, 0x765e7540, 0x30e48c22, 0x764b4b23, -0x3112fc95, 0x76380ec8, 0x31416576, 0x7624c031, 0x316fc6be, 0x76115f63, 0x319e2067, 0x75fdec60, -0x31cc7269, 0x75ea672a, 0x31fabcbd, 0x75d6cfc5, 0x3228ff5c, 0x75c32634, 0x32573a3f, 0x75af6a7b, -0x32856d5e, 0x759b9c9b, 0x32b398b3, 0x7587bc98, 0x32e1bc36, 0x7573ca75, 0x330fd7e1, 0x755fc635, -0x333debab, 0x754bafdc, 0x336bf78f, 0x7537876c, 0x3399fb85, 0x75234ce8, 0x33c7f785, 0x750f0054, -0x33f5eb89, 0x74faa1b3, 0x3423d78a, 0x74e63108, 0x3451bb81, 0x74d1ae55, 0x347f9766, 0x74bd199f, -0x34ad6b32, 0x74a872e8, 0x34db36df, 0x7493ba34, 0x3508fa66, 0x747eef85, 0x3536b5be, 0x746a12df, -0x356468e2, 0x74552446, 0x359213c9, 0x744023bc, 0x35bfb66e, 0x742b1144, 0x35ed50c9, 0x7415ece2, -0x361ae2d3, 0x7400b69a, 0x36486c86, 0x73eb6e6e, 0x3675edd9, 0x73d61461, 0x36a366c6, 0x73c0a878, -0x36d0d746, 0x73ab2ab4, 0x36fe3f52, 0x73959b1b, 0x372b9ee3, 0x737ff9ae, 0x3758f5f2, 0x736a4671, -0x37864477, 0x73548168, 0x37b38a6d, 0x733eaa96, 0x37e0c7cc, 0x7328c1ff, 0x380dfc8d, 0x7312c7a5, -0x383b28a9, 0x72fcbb8c, 0x38684c19, 0x72e69db7, 0x389566d6, 0x72d06e2b, 0x38c278d9, 0x72ba2cea, -0x38ef821c, 0x72a3d9f7, 0x391c8297, 0x728d7557, 0x39497a43, 0x7276ff0d, 0x39766919, 0x7260771b, -0x39a34f13, 0x7249dd86, 0x39d02c2a, 0x72333251, 0x39fd0056, 0x721c7580, 0x3a29cb91, 0x7205a716, -0x3a568dd4, 0x71eec716, 0x3a834717, 0x71d7d585, 0x3aaff755, 0x71c0d265, 0x3adc9e86, 0x71a9bdba, -0x3b093ca3, 0x71929789, 0x3b35d1a5, 0x717b5fd3, 0x3b625d86, 0x7164169d, 0x3b8ee03e, 0x714cbbeb, -0x3bbb59c7, 0x71354fc0, 0x3be7ca1a, 0x711dd220, 0x3c143130, 0x7106430e, 0x3c408f03, 0x70eea28e, -0x3c6ce38a, 0x70d6f0a4, 0x3c992ec0, 0x70bf2d53, 0x3cc5709e, 0x70a7589f, 0x3cf1a91c, 0x708f728b, -0x3d1dd835, 0x70777b1c, 0x3d49fde1, 0x705f7255, 0x3d761a19, 0x70475839, 0x3da22cd7, 0x702f2ccd, -0x3dce3614, 0x7016f014, 0x3dfa35c8, 0x6ffea212, 0x3e262bee, 0x6fe642ca, 0x3e52187f, 0x6fcdd241, -0x3e7dfb73, 0x6fb5507a, 0x3ea9d4c3, 0x6f9cbd79, 0x3ed5a46b, 0x6f841942, 0x3f016a61, 0x6f6b63d8, -0x3f2d26a0, 0x6f529d40, 0x3f58d921, 0x6f39c57d, 0x3f8481dd, 0x6f20dc92, 0x3fb020ce, 0x6f07e285, -0x3fdbb5ec, 0x6eeed758, 0x40074132, 0x6ed5bb10, 0x4032c297, 0x6ebc8db0, 0x405e3a16, 0x6ea34f3d, -0x4089a7a8, 0x6e89ffb9, 0x40b50b46, 0x6e709f2a, 0x40e064ea, 0x6e572d93, 0x410bb48c, 0x6e3daaf8, -0x4136fa27, 0x6e24175c, 0x416235b2, 0x6e0a72c5, 0x418d6729, 0x6df0bd35, 0x41b88e84, 0x6dd6f6b1, -0x41e3abbc, 0x6dbd1f3c, 0x420ebecb, 0x6da336dc, 0x4239c7aa, 0x6d893d93, 0x4264c653, 0x6d6f3365, -0x428fbabe, 0x6d551858, 0x42baa4e6, 0x6d3aec6e, 0x42e584c3, 0x6d20afac, 0x43105a50, 0x6d066215, -0x433b2585, 0x6cec03af, 0x4365e65b, 0x6cd1947c, 0x43909ccd, 0x6cb71482, 0x43bb48d4, 0x6c9c83c3, -0x43e5ea68, 0x6c81e245, 0x44108184, 0x6c67300b, 0x443b0e21, 0x6c4c6d1a, 0x44659039, 0x6c319975, -0x449007c4, 0x6c16b521, 0x44ba74bd, 0x6bfbc021, 0x44e4d71c, 0x6be0ba7b, 0x450f2edb, 0x6bc5a431, -0x45397bf4, 0x6baa7d49, 0x4563be60, 0x6b8f45c7, 0x458df619, 0x6b73fdae, 0x45b82318, 0x6b58a503, -0x45e24556, 0x6b3d3bcb, 0x460c5cce, 0x6b21c208, 0x46366978, 0x6b0637c1, 0x46606b4e, 0x6aea9cf8, -0x468a624a, 0x6acef1b2, 0x46b44e65, 0x6ab335f4, 0x46de2f99, 0x6a9769c1, 0x470805df, 0x6a7b8d1e, -0x4731d131, 0x6a5fa010, 0x475b9188, 0x6a43a29a, 0x478546de, 0x6a2794c1, 0x47aef12c, 0x6a0b7689, -0x47d8906d, 0x69ef47f6, 0x48022499, 0x69d3090e, 0x482badab, 0x69b6b9d3, 0x48552b9b, 0x699a5a4c, -0x487e9e64, 0x697dea7b, 0x48a805ff, 0x69616a65, 0x48d16265, 0x6944da10, 0x48fab391, 0x6928397e, -0x4923f97b, 0x690b88b5, 0x494d341e, 0x68eec7b9, 0x49766373, 0x68d1f68f, 0x499f8774, 0x68b5153a, -0x49c8a01b, 0x689823bf, 0x49f1ad61, 0x687b2224, 0x4a1aaf3f, 0x685e106c, 0x4a43a5b0, 0x6840ee9b, -0x4a6c90ad, 0x6823bcb7, 0x4a957030, 0x68067ac3, 0x4abe4433, 0x67e928c5, 0x4ae70caf, 0x67cbc6c0, -0x4b0fc99d, 0x67ae54ba, 0x4b387af9, 0x6790d2b6, 0x4b6120bb, 0x677340ba, 0x4b89badd, 0x67559eca, -0x4bb24958, 0x6737ecea, 0x4bdacc28, 0x671a2b20, 0x4c034345, 0x66fc596f, 0x4c2baea9, 0x66de77dc, -0x4c540e4e, 0x66c0866d, 0x4c7c622d, 0x66a28524, 0x4ca4aa41, 0x66847408, 0x4ccce684, 0x6666531d, -0x4cf516ee, 0x66482267, 0x4d1d3b7a, 0x6629e1ec, 0x4d455422, 0x660b91af, 0x4d6d60df, 0x65ed31b5, -0x4d9561ac, 0x65cec204, 0x4dbd5682, 0x65b0429f, 0x4de53f5a, 0x6591b38c, 0x4e0d1c30, 0x657314cf, -0x4e34ecfc, 0x6554666d, 0x4e5cb1b9, 0x6535a86b, 0x4e846a60, 0x6516dacd, 0x4eac16eb, 0x64f7fd98, -0x4ed3b755, 0x64d910d1, 0x4efb4b96, 0x64ba147d, 0x4f22d3aa, 0x649b08a0, 0x4f4a4f89, 0x647bed3f, -0x4f71bf2e, 0x645cc260, 0x4f992293, 0x643d8806, 0x4fc079b1, 0x641e3e38, 0x4fe7c483, 0x63fee4f8, -0x500f0302, 0x63df7c4d, 0x50363529, 0x63c0043b, 0x505d5af1, 0x63a07cc7, 0x50847454, 0x6380e5f6, -0x50ab814d, 0x63613fcd, 0x50d281d5, 0x63418a50, 0x50f975e6, 0x6321c585, 0x51205d7b, 0x6301f171, -0x5147388c, 0x62e20e17, 0x516e0715, 0x62c21b7e, 0x5194c910, 0x62a219aa, 0x51bb7e75, 0x628208a1, -0x51e22740, 0x6261e866, 0x5208c36a, 0x6241b8ff, 0x522f52ee, 0x62217a72, 0x5255d5c5, 0x62012cc2, -0x527c4bea, 0x61e0cff5, 0x52a2b556, 0x61c06410, 0x52c91204, 0x619fe918, 0x52ef61ee, 0x617f5f12, -0x5315a50e, 0x615ec603, 0x533bdb5d, 0x613e1df0, 0x536204d7, 0x611d66de, 0x53882175, 0x60fca0d2, -0x53ae3131, 0x60dbcbd1, 0x53d43406, 0x60bae7e1, 0x53fa29ed, 0x6099f505, 0x542012e1, 0x6078f344, -0x5445eedb, 0x6057e2a2, 0x546bbdd7, 0x6036c325, 0x54917fce, 0x601594d1, 0x54b734ba, 0x5ff457ad, -0x54dcdc96, 0x5fd30bbc, 0x5502775c, 0x5fb1b104, 0x55280505, 0x5f90478a, 0x554d858d, 0x5f6ecf53, -0x5572f8ed, 0x5f4d4865, 0x55985f20, 0x5f2bb2c5, 0x55bdb81f, 0x5f0a0e77, 0x55e303e6, 0x5ee85b82, -0x5608426e, 0x5ec699e9, 0x562d73b2, 0x5ea4c9b3, 0x565297ab, 0x5e82eae5, 0x5677ae54, 0x5e60fd84, -0x569cb7a8, 0x5e3f0194, 0x56c1b3a1, 0x5e1cf71c, 0x56e6a239, 0x5dfade20, 0x570b8369, 0x5dd8b6a7, -0x5730572e, 0x5db680b4, 0x57551d80, 0x5d943c4e, 0x5779d65b, 0x5d71e979, 0x579e81b8, 0x5d4f883b, -0x57c31f92, 0x5d2d189a, 0x57e7afe4, 0x5d0a9a9a, 0x580c32a7, 0x5ce80e41, 0x5830a7d6, 0x5cc57394, -0x58550f6c, 0x5ca2ca99, 0x58796962, 0x5c801354, 0x589db5b3, 0x5c5d4dcc, 0x58c1f45b, 0x5c3a7a05, -0x58e62552, 0x5c179806, 0x590a4893, 0x5bf4a7d2, 0x592e5e19, 0x5bd1a971, 0x595265df, 0x5bae9ce7, -0x59765fde, 0x5b8b8239, 0x599a4c12, 0x5b68596d, 0x59be2a74, 0x5b452288, 0x59e1faff, 0x5b21dd90, -0x5a05bdae, 0x5afe8a8b, 0x5a29727b, 0x5adb297d, 0x5a4d1960, 0x5ab7ba6c, 0x5a70b258, 0x5a943d5e, + /* 128 - format = Q31 * 2^0 */ + 0x00c90f88, 0x7fff6216, 0x025b26d7, 0x7ffa72d1, 0x03ed26e6, 0x7ff09478, 0x057f0035, 0x7fe1c76b, + 0x0710a345, 0x7fce0c3e, 0x08a2009a, 0x7fb563b3, 0x0a3308bd, 0x7f97cebd, 0x0bc3ac35, 0x7f754e80, + 0x0d53db92, 0x7f4de451, 0x0ee38766, 0x7f2191b4, 0x1072a048, 0x7ef05860, 0x120116d5, 0x7eba3a39, + 0x138edbb1, 0x7e7f3957, 0x151bdf86, 0x7e3f57ff, 0x16a81305, 0x7dfa98a8, 0x183366e9, 0x7db0fdf8, + 0x19bdcbf3, 0x7d628ac6, 0x1b4732ef, 0x7d0f4218, 0x1ccf8cb3, 0x7cb72724, 0x1e56ca1e, 0x7c5a3d50, + 0x1fdcdc1b, 0x7bf88830, 0x2161b3a0, 0x7b920b89, 0x22e541af, 0x7b26cb4f, 0x24677758, 0x7ab6cba4, + 0x25e845b6, 0x7a4210d8, 0x27679df4, 0x79c89f6e, 0x28e5714b, 0x794a7c12, 0x2a61b101, 0x78c7aba2, + 0x2bdc4e6f, 0x78403329, 0x2d553afc, 0x77b417df, 0x2ecc681e, 0x77235f2d, 0x3041c761, 0x768e0ea6, + 0x31b54a5e, 0x75f42c0b, 0x3326e2c3, 0x7555bd4c, 0x34968250, 0x74b2c884, 0x36041ad9, 0x740b53fb, + 0x376f9e46, 0x735f6626, 0x38d8fe93, 0x72af05a7, 0x3a402dd2, 0x71fa3949, 0x3ba51e29, 0x71410805, + 0x3d07c1d6, 0x708378ff, 0x3e680b2c, 0x6fc19385, 0x3fc5ec98, 0x6efb5f12, 0x4121589b, 0x6e30e34a, + 0x427a41d0, 0x6d6227fa, 0x43d09aed, 0x6c8f351c, 0x452456bd, 0x6bb812d1, 0x46756828, 0x6adcc964, + 0x47c3c22f, 0x69fd614a, 0x490f57ee, 0x6919e320, 0x4a581c9e, 0x683257ab, 0x4b9e0390, 0x6746c7d8, + 0x4ce10034, 0x66573cbb, 0x4e210617, 0x6563bf92, 0x4f5e08e3, 0x646c59bf, 0x5097fc5e, 0x637114cc, + 0x51ced46e, 0x6271fa69, 0x53028518, 0x616f146c, 0x5433027d, 0x60686ccf, 0x556040e2, 0x5f5e0db3, + 0x568a34a9, 0x5e50015d, 0x57b0d256, 0x5d3e5237, 0x58d40e8c, 0x5c290acc, 0x59f3de12, 0x5b1035cf, + /* 1024 - format = Q31 * 2^0 */ + 0x001921fb, 0x7ffffd88, 0x004b65ee, 0x7fffe9cb, 0x007da9d4, 0x7fffc251, 0x00afeda8, 0x7fff8719, + 0x00e23160, 0x7fff3824, 0x011474f6, 0x7ffed572, 0x0146b860, 0x7ffe5f03, 0x0178fb99, 0x7ffdd4d7, + 0x01ab3e97, 0x7ffd36ee, 0x01dd8154, 0x7ffc8549, 0x020fc3c6, 0x7ffbbfe6, 0x024205e8, 0x7ffae6c7, + 0x027447b0, 0x7ff9f9ec, 0x02a68917, 0x7ff8f954, 0x02d8ca16, 0x7ff7e500, 0x030b0aa4, 0x7ff6bcf0, + 0x033d4abb, 0x7ff58125, 0x036f8a51, 0x7ff4319d, 0x03a1c960, 0x7ff2ce5b, 0x03d407df, 0x7ff1575d, + 0x040645c7, 0x7fefcca4, 0x04388310, 0x7fee2e30, 0x046abfb3, 0x7fec7c02, 0x049cfba7, 0x7feab61a, + 0x04cf36e5, 0x7fe8dc78, 0x05017165, 0x7fe6ef1c, 0x0533ab20, 0x7fe4ee06, 0x0565e40d, 0x7fe2d938, + 0x05981c26, 0x7fe0b0b1, 0x05ca5361, 0x7fde7471, 0x05fc89b8, 0x7fdc247a, 0x062ebf22, 0x7fd9c0ca, + 0x0660f398, 0x7fd74964, 0x06932713, 0x7fd4be46, 0x06c5598a, 0x7fd21f72, 0x06f78af6, 0x7fcf6ce8, + 0x0729bb4e, 0x7fcca6a7, 0x075bea8c, 0x7fc9ccb2, 0x078e18a7, 0x7fc6df08, 0x07c04598, 0x7fc3dda9, + 0x07f27157, 0x7fc0c896, 0x08249bdd, 0x7fbd9fd0, 0x0856c520, 0x7fba6357, 0x0888ed1b, 0x7fb7132b, + 0x08bb13c5, 0x7fb3af4e, 0x08ed3916, 0x7fb037bf, 0x091f5d06, 0x7facac7f, 0x09517f8f, 0x7fa90d8e, + 0x0983a0a7, 0x7fa55aee, 0x09b5c048, 0x7fa1949e, 0x09e7de6a, 0x7f9dbaa0, 0x0a19fb04, 0x7f99ccf4, + 0x0a4c1610, 0x7f95cb9a, 0x0a7e2f85, 0x7f91b694, 0x0ab0475c, 0x7f8d8de1, 0x0ae25d8d, 0x7f895182, + 0x0b147211, 0x7f850179, 0x0b4684df, 0x7f809dc5, 0x0b7895f0, 0x7f7c2668, 0x0baaa53b, 0x7f779b62, + 0x0bdcb2bb, 0x7f72fcb4, 0x0c0ebe66, 0x7f6e4a5e, 0x0c40c835, 0x7f698461, 0x0c72d020, 0x7f64aabf, + 0x0ca4d620, 0x7f5fbd77, 0x0cd6da2d, 0x7f5abc8a, 0x0d08dc3f, 0x7f55a7fa, 0x0d3adc4e, 0x7f507fc7, + 0x0d6cda53, 0x7f4b43f2, 0x0d9ed646, 0x7f45f47b, 0x0dd0d01f, 0x7f409164, 0x0e02c7d7, 0x7f3b1aad, + 0x0e34bd66, 0x7f359057, 0x0e66b0c3, 0x7f2ff263, 0x0e98a1e9, 0x7f2a40d2, 0x0eca90ce, 0x7f247ba5, + 0x0efc7d6b, 0x7f1ea2dc, 0x0f2e67b8, 0x7f18b679, 0x0f604faf, 0x7f12b67c, 0x0f923546, 0x7f0ca2e7, + 0x0fc41876, 0x7f067bba, 0x0ff5f938, 0x7f0040f6, 0x1027d784, 0x7ef9f29d, 0x1059b352, 0x7ef390ae, + 0x108b8c9b, 0x7eed1b2c, 0x10bd6356, 0x7ee69217, 0x10ef377d, 0x7edff570, 0x11210907, 0x7ed94538, + 0x1152d7ed, 0x7ed28171, 0x1184a427, 0x7ecbaa1a, 0x11b66dad, 0x7ec4bf36, 0x11e83478, 0x7ebdc0c6, + 0x1219f880, 0x7eb6aeca, 0x124bb9be, 0x7eaf8943, 0x127d7829, 0x7ea85033, 0x12af33ba, 0x7ea1039b, + 0x12e0ec6a, 0x7e99a37c, 0x1312a230, 0x7e922fd6, 0x13445505, 0x7e8aa8ac, 0x137604e2, 0x7e830dff, + 0x13a7b1bf, 0x7e7b5fce, 0x13d95b93, 0x7e739e1d, 0x140b0258, 0x7e6bc8eb, 0x143ca605, 0x7e63e03b, + 0x146e4694, 0x7e5be40c, 0x149fe3fc, 0x7e53d462, 0x14d17e36, 0x7e4bb13c, 0x1503153a, 0x7e437a9c, + 0x1534a901, 0x7e3b3083, 0x15663982, 0x7e32d2f4, 0x1597c6b7, 0x7e2a61ed, 0x15c95097, 0x7e21dd73, + 0x15fad71b, 0x7e194584, 0x162c5a3b, 0x7e109a24, 0x165dd9f0, 0x7e07db52, 0x168f5632, 0x7dff0911, + 0x16c0cef9, 0x7df62362, 0x16f2443e, 0x7ded2a47, 0x1723b5f9, 0x7de41dc0, 0x17552422, 0x7ddafdce, + 0x17868eb3, 0x7dd1ca75, 0x17b7f5a3, 0x7dc883b4, 0x17e958ea, 0x7dbf298d, 0x181ab881, 0x7db5bc02, + 0x184c1461, 0x7dac3b15, 0x187d6c82, 0x7da2a6c6, 0x18aec0db, 0x7d98ff17, 0x18e01167, 0x7d8f4409, + 0x19115e1c, 0x7d85759f, 0x1942a6f3, 0x7d7b93da, 0x1973ebe6, 0x7d719eba, 0x19a52ceb, 0x7d679642, + 0x19d669fc, 0x7d5d7a74, 0x1a07a311, 0x7d534b50, 0x1a38d823, 0x7d4908d9, 0x1a6a0929, 0x7d3eb30f, + 0x1a9b361d, 0x7d3449f5, 0x1acc5ef6, 0x7d29cd8c, 0x1afd83ad, 0x7d1f3dd6, 0x1b2ea43a, 0x7d149ad5, + 0x1b5fc097, 0x7d09e489, 0x1b90d8bb, 0x7cff1af5, 0x1bc1ec9e, 0x7cf43e1a, 0x1bf2fc3a, 0x7ce94dfb, + 0x1c240786, 0x7cde4a98, 0x1c550e7c, 0x7cd333f3, 0x1c861113, 0x7cc80a0f, 0x1cb70f43, 0x7cbcccec, + 0x1ce80906, 0x7cb17c8d, 0x1d18fe54, 0x7ca618f3, 0x1d49ef26, 0x7c9aa221, 0x1d7adb73, 0x7c8f1817, + 0x1dabc334, 0x7c837ad8, 0x1ddca662, 0x7c77ca65, 0x1e0d84f5, 0x7c6c06c0, 0x1e3e5ee5, 0x7c602fec, + 0x1e6f342c, 0x7c5445e9, 0x1ea004c1, 0x7c4848ba, 0x1ed0d09d, 0x7c3c3860, 0x1f0197b8, 0x7c3014de, + 0x1f325a0b, 0x7c23de35, 0x1f63178f, 0x7c179467, 0x1f93d03c, 0x7c0b3777, 0x1fc4840a, 0x7bfec765, + 0x1ff532f2, 0x7bf24434, 0x2025dcec, 0x7be5ade6, 0x205681f1, 0x7bd9047c, 0x208721f9, 0x7bcc47fa, + 0x20b7bcfe, 0x7bbf7860, 0x20e852f6, 0x7bb295b0, 0x2118e3dc, 0x7ba59fee, 0x21496fa7, 0x7b989719, + 0x2179f64f, 0x7b8b7b36, 0x21aa77cf, 0x7b7e4c45, 0x21daf41d, 0x7b710a49, 0x220b6b32, 0x7b63b543, + 0x223bdd08, 0x7b564d36, 0x226c4996, 0x7b48d225, 0x229cb0d5, 0x7b3b4410, 0x22cd12bd, 0x7b2da2fa, + 0x22fd6f48, 0x7b1feee5, 0x232dc66d, 0x7b1227d3, 0x235e1826, 0x7b044dc7, 0x238e646a, 0x7af660c2, + 0x23beab33, 0x7ae860c7, 0x23eeec78, 0x7ada4dd8, 0x241f2833, 0x7acc27f7, 0x244f5e5c, 0x7abdef25, + 0x247f8eec, 0x7aafa367, 0x24afb9da, 0x7aa144bc, 0x24dfdf20, 0x7a92d329, 0x250ffeb7, 0x7a844eae, + 0x25401896, 0x7a75b74f, 0x25702cb7, 0x7a670d0d, 0x25a03b11, 0x7a584feb, 0x25d0439f, 0x7a497feb, + 0x26004657, 0x7a3a9d0f, 0x26304333, 0x7a2ba75a, 0x26603a2c, 0x7a1c9ece, 0x26902b39, 0x7a0d836d, + 0x26c01655, 0x79fe5539, 0x26effb76, 0x79ef1436, 0x271fda96, 0x79dfc064, 0x274fb3ae, 0x79d059c8, + 0x277f86b5, 0x79c0e062, 0x27af53a6, 0x79b15435, 0x27df1a77, 0x79a1b545, 0x280edb23, 0x79920392, + 0x283e95a1, 0x79823f20, 0x286e49ea, 0x797267f2, 0x289df7f8, 0x79627e08, 0x28cd9fc1, 0x79528167, + 0x28fd4140, 0x79427210, 0x292cdc6d, 0x79325006, 0x295c7140, 0x79221b4b, 0x298bffb2, 0x7911d3e2, + 0x29bb87bc, 0x790179cd, 0x29eb0957, 0x78f10d0f, 0x2a1a847b, 0x78e08dab, 0x2a49f920, 0x78cffba3, + 0x2a796740, 0x78bf56f9, 0x2aa8ced3, 0x78ae9fb0, 0x2ad82fd2, 0x789dd5cb, 0x2b078a36, 0x788cf94c, + 0x2b36ddf7, 0x787c0a36, 0x2b662b0e, 0x786b088c, 0x2b957173, 0x7859f44f, 0x2bc4b120, 0x7848cd83, + 0x2bf3ea0d, 0x7837942b, 0x2c231c33, 0x78264849, 0x2c52478a, 0x7814e9df, 0x2c816c0c, 0x780378f1, + 0x2cb089b1, 0x77f1f581, 0x2cdfa071, 0x77e05f91, 0x2d0eb046, 0x77ceb725, 0x2d3db928, 0x77bcfc3f, + 0x2d6cbb10, 0x77ab2ee2, 0x2d9bb5f6, 0x77994f11, 0x2dcaa9d5, 0x77875cce, 0x2df996a3, 0x7775581d, + 0x2e287c5a, 0x776340ff, 0x2e575af3, 0x77511778, 0x2e863267, 0x773edb8b, 0x2eb502ae, 0x772c8d3a, + 0x2ee3cbc1, 0x771a2c88, 0x2f128d99, 0x7707b979, 0x2f41482e, 0x76f5340e, 0x2f6ffb7a, 0x76e29c4b, + 0x2f9ea775, 0x76cff232, 0x2fcd4c19, 0x76bd35c7, 0x2ffbe95d, 0x76aa670d, 0x302a7f3a, 0x76978605, + 0x30590dab, 0x768492b4, 0x308794a6, 0x76718d1c, 0x30b61426, 0x765e7540, 0x30e48c22, 0x764b4b23, + 0x3112fc95, 0x76380ec8, 0x31416576, 0x7624c031, 0x316fc6be, 0x76115f63, 0x319e2067, 0x75fdec60, + 0x31cc7269, 0x75ea672a, 0x31fabcbd, 0x75d6cfc5, 0x3228ff5c, 0x75c32634, 0x32573a3f, 0x75af6a7b, + 0x32856d5e, 0x759b9c9b, 0x32b398b3, 0x7587bc98, 0x32e1bc36, 0x7573ca75, 0x330fd7e1, 0x755fc635, + 0x333debab, 0x754bafdc, 0x336bf78f, 0x7537876c, 0x3399fb85, 0x75234ce8, 0x33c7f785, 0x750f0054, + 0x33f5eb89, 0x74faa1b3, 0x3423d78a, 0x74e63108, 0x3451bb81, 0x74d1ae55, 0x347f9766, 0x74bd199f, + 0x34ad6b32, 0x74a872e8, 0x34db36df, 0x7493ba34, 0x3508fa66, 0x747eef85, 0x3536b5be, 0x746a12df, + 0x356468e2, 0x74552446, 0x359213c9, 0x744023bc, 0x35bfb66e, 0x742b1144, 0x35ed50c9, 0x7415ece2, + 0x361ae2d3, 0x7400b69a, 0x36486c86, 0x73eb6e6e, 0x3675edd9, 0x73d61461, 0x36a366c6, 0x73c0a878, + 0x36d0d746, 0x73ab2ab4, 0x36fe3f52, 0x73959b1b, 0x372b9ee3, 0x737ff9ae, 0x3758f5f2, 0x736a4671, + 0x37864477, 0x73548168, 0x37b38a6d, 0x733eaa96, 0x37e0c7cc, 0x7328c1ff, 0x380dfc8d, 0x7312c7a5, + 0x383b28a9, 0x72fcbb8c, 0x38684c19, 0x72e69db7, 0x389566d6, 0x72d06e2b, 0x38c278d9, 0x72ba2cea, + 0x38ef821c, 0x72a3d9f7, 0x391c8297, 0x728d7557, 0x39497a43, 0x7276ff0d, 0x39766919, 0x7260771b, + 0x39a34f13, 0x7249dd86, 0x39d02c2a, 0x72333251, 0x39fd0056, 0x721c7580, 0x3a29cb91, 0x7205a716, + 0x3a568dd4, 0x71eec716, 0x3a834717, 0x71d7d585, 0x3aaff755, 0x71c0d265, 0x3adc9e86, 0x71a9bdba, + 0x3b093ca3, 0x71929789, 0x3b35d1a5, 0x717b5fd3, 0x3b625d86, 0x7164169d, 0x3b8ee03e, 0x714cbbeb, + 0x3bbb59c7, 0x71354fc0, 0x3be7ca1a, 0x711dd220, 0x3c143130, 0x7106430e, 0x3c408f03, 0x70eea28e, + 0x3c6ce38a, 0x70d6f0a4, 0x3c992ec0, 0x70bf2d53, 0x3cc5709e, 0x70a7589f, 0x3cf1a91c, 0x708f728b, + 0x3d1dd835, 0x70777b1c, 0x3d49fde1, 0x705f7255, 0x3d761a19, 0x70475839, 0x3da22cd7, 0x702f2ccd, + 0x3dce3614, 0x7016f014, 0x3dfa35c8, 0x6ffea212, 0x3e262bee, 0x6fe642ca, 0x3e52187f, 0x6fcdd241, + 0x3e7dfb73, 0x6fb5507a, 0x3ea9d4c3, 0x6f9cbd79, 0x3ed5a46b, 0x6f841942, 0x3f016a61, 0x6f6b63d8, + 0x3f2d26a0, 0x6f529d40, 0x3f58d921, 0x6f39c57d, 0x3f8481dd, 0x6f20dc92, 0x3fb020ce, 0x6f07e285, + 0x3fdbb5ec, 0x6eeed758, 0x40074132, 0x6ed5bb10, 0x4032c297, 0x6ebc8db0, 0x405e3a16, 0x6ea34f3d, + 0x4089a7a8, 0x6e89ffb9, 0x40b50b46, 0x6e709f2a, 0x40e064ea, 0x6e572d93, 0x410bb48c, 0x6e3daaf8, + 0x4136fa27, 0x6e24175c, 0x416235b2, 0x6e0a72c5, 0x418d6729, 0x6df0bd35, 0x41b88e84, 0x6dd6f6b1, + 0x41e3abbc, 0x6dbd1f3c, 0x420ebecb, 0x6da336dc, 0x4239c7aa, 0x6d893d93, 0x4264c653, 0x6d6f3365, + 0x428fbabe, 0x6d551858, 0x42baa4e6, 0x6d3aec6e, 0x42e584c3, 0x6d20afac, 0x43105a50, 0x6d066215, + 0x433b2585, 0x6cec03af, 0x4365e65b, 0x6cd1947c, 0x43909ccd, 0x6cb71482, 0x43bb48d4, 0x6c9c83c3, + 0x43e5ea68, 0x6c81e245, 0x44108184, 0x6c67300b, 0x443b0e21, 0x6c4c6d1a, 0x44659039, 0x6c319975, + 0x449007c4, 0x6c16b521, 0x44ba74bd, 0x6bfbc021, 0x44e4d71c, 0x6be0ba7b, 0x450f2edb, 0x6bc5a431, + 0x45397bf4, 0x6baa7d49, 0x4563be60, 0x6b8f45c7, 0x458df619, 0x6b73fdae, 0x45b82318, 0x6b58a503, + 0x45e24556, 0x6b3d3bcb, 0x460c5cce, 0x6b21c208, 0x46366978, 0x6b0637c1, 0x46606b4e, 0x6aea9cf8, + 0x468a624a, 0x6acef1b2, 0x46b44e65, 0x6ab335f4, 0x46de2f99, 0x6a9769c1, 0x470805df, 0x6a7b8d1e, + 0x4731d131, 0x6a5fa010, 0x475b9188, 0x6a43a29a, 0x478546de, 0x6a2794c1, 0x47aef12c, 0x6a0b7689, + 0x47d8906d, 0x69ef47f6, 0x48022499, 0x69d3090e, 0x482badab, 0x69b6b9d3, 0x48552b9b, 0x699a5a4c, + 0x487e9e64, 0x697dea7b, 0x48a805ff, 0x69616a65, 0x48d16265, 0x6944da10, 0x48fab391, 0x6928397e, + 0x4923f97b, 0x690b88b5, 0x494d341e, 0x68eec7b9, 0x49766373, 0x68d1f68f, 0x499f8774, 0x68b5153a, + 0x49c8a01b, 0x689823bf, 0x49f1ad61, 0x687b2224, 0x4a1aaf3f, 0x685e106c, 0x4a43a5b0, 0x6840ee9b, + 0x4a6c90ad, 0x6823bcb7, 0x4a957030, 0x68067ac3, 0x4abe4433, 0x67e928c5, 0x4ae70caf, 0x67cbc6c0, + 0x4b0fc99d, 0x67ae54ba, 0x4b387af9, 0x6790d2b6, 0x4b6120bb, 0x677340ba, 0x4b89badd, 0x67559eca, + 0x4bb24958, 0x6737ecea, 0x4bdacc28, 0x671a2b20, 0x4c034345, 0x66fc596f, 0x4c2baea9, 0x66de77dc, + 0x4c540e4e, 0x66c0866d, 0x4c7c622d, 0x66a28524, 0x4ca4aa41, 0x66847408, 0x4ccce684, 0x6666531d, + 0x4cf516ee, 0x66482267, 0x4d1d3b7a, 0x6629e1ec, 0x4d455422, 0x660b91af, 0x4d6d60df, 0x65ed31b5, + 0x4d9561ac, 0x65cec204, 0x4dbd5682, 0x65b0429f, 0x4de53f5a, 0x6591b38c, 0x4e0d1c30, 0x657314cf, + 0x4e34ecfc, 0x6554666d, 0x4e5cb1b9, 0x6535a86b, 0x4e846a60, 0x6516dacd, 0x4eac16eb, 0x64f7fd98, + 0x4ed3b755, 0x64d910d1, 0x4efb4b96, 0x64ba147d, 0x4f22d3aa, 0x649b08a0, 0x4f4a4f89, 0x647bed3f, + 0x4f71bf2e, 0x645cc260, 0x4f992293, 0x643d8806, 0x4fc079b1, 0x641e3e38, 0x4fe7c483, 0x63fee4f8, + 0x500f0302, 0x63df7c4d, 0x50363529, 0x63c0043b, 0x505d5af1, 0x63a07cc7, 0x50847454, 0x6380e5f6, + 0x50ab814d, 0x63613fcd, 0x50d281d5, 0x63418a50, 0x50f975e6, 0x6321c585, 0x51205d7b, 0x6301f171, + 0x5147388c, 0x62e20e17, 0x516e0715, 0x62c21b7e, 0x5194c910, 0x62a219aa, 0x51bb7e75, 0x628208a1, + 0x51e22740, 0x6261e866, 0x5208c36a, 0x6241b8ff, 0x522f52ee, 0x62217a72, 0x5255d5c5, 0x62012cc2, + 0x527c4bea, 0x61e0cff5, 0x52a2b556, 0x61c06410, 0x52c91204, 0x619fe918, 0x52ef61ee, 0x617f5f12, + 0x5315a50e, 0x615ec603, 0x533bdb5d, 0x613e1df0, 0x536204d7, 0x611d66de, 0x53882175, 0x60fca0d2, + 0x53ae3131, 0x60dbcbd1, 0x53d43406, 0x60bae7e1, 0x53fa29ed, 0x6099f505, 0x542012e1, 0x6078f344, + 0x5445eedb, 0x6057e2a2, 0x546bbdd7, 0x6036c325, 0x54917fce, 0x601594d1, 0x54b734ba, 0x5ff457ad, + 0x54dcdc96, 0x5fd30bbc, 0x5502775c, 0x5fb1b104, 0x55280505, 0x5f90478a, 0x554d858d, 0x5f6ecf53, + 0x5572f8ed, 0x5f4d4865, 0x55985f20, 0x5f2bb2c5, 0x55bdb81f, 0x5f0a0e77, 0x55e303e6, 0x5ee85b82, + 0x5608426e, 0x5ec699e9, 0x562d73b2, 0x5ea4c9b3, 0x565297ab, 0x5e82eae5, 0x5677ae54, 0x5e60fd84, + 0x569cb7a8, 0x5e3f0194, 0x56c1b3a1, 0x5e1cf71c, 0x56e6a239, 0x5dfade20, 0x570b8369, 0x5dd8b6a7, + 0x5730572e, 0x5db680b4, 0x57551d80, 0x5d943c4e, 0x5779d65b, 0x5d71e979, 0x579e81b8, 0x5d4f883b, + 0x57c31f92, 0x5d2d189a, 0x57e7afe4, 0x5d0a9a9a, 0x580c32a7, 0x5ce80e41, 0x5830a7d6, 0x5cc57394, + 0x58550f6c, 0x5ca2ca99, 0x58796962, 0x5c801354, 0x589db5b3, 0x5c5d4dcc, 0x58c1f45b, 0x5c3a7a05, + 0x58e62552, 0x5c179806, 0x590a4893, 0x5bf4a7d2, 0x592e5e19, 0x5bd1a971, 0x595265df, 0x5bae9ce7, + 0x59765fde, 0x5b8b8239, 0x599a4c12, 0x5b68596d, 0x59be2a74, 0x5b452288, 0x59e1faff, 0x5b21dd90, + 0x5a05bdae, 0x5afe8a8b, 0x5a29727b, 0x5adb297d, 0x5a4d1960, 0x5ab7ba6c, 0x5a70b258, 0x5a943d5e, }; -const int kbdWindowOffset[NUM_IMDCT_SIZES] PROGMEM = {0, 128}; - -/* Synthesis window - KBD - * format = Q31 for nmdct = [128, 1024] - * reordered for sequential access - * - * aacScaleFact = -sqrt(1.0 / (2.0 * nmdct)); - * for (i = 0; i < nmdct/2; i++) { - * x = kbdWindowRef[i] * aacScaleFact; - * x = kbdWindowRef[nmdct - 1 - i] * aacScaleFact; - * } - * Note: see below for code to generate kbdWindowRef[] - */ +const int kbdWindowOffset[NUM_IMDCT_SIZES] DPROGMEM = {0, 128}; + +/* Synthesis window - KBD + format = Q31 for nmdct = [128, 1024] + reordered for sequential access + + aacScaleFact = -sqrt(1.0 / (2.0 * nmdct)); + for (i = 0; i < nmdct/2; i++) { + x = kbdWindowRef[i] * aacScaleFact; + x = kbdWindowRef[nmdct - 1 - i] * aacScaleFact; + } + Note: see below for code to generate kbdWindowRef[] +*/ const int kbdWindow[128 + 1024] PROGMEM = { -/* 128 - format = Q31 * 2^0 */ -0x00016f63, 0x7ffffffe, 0x0003e382, 0x7ffffff1, 0x00078f64, 0x7fffffc7, 0x000cc323, 0x7fffff5d, -0x0013d9ed, 0x7ffffe76, 0x001d3a9d, 0x7ffffcaa, 0x0029581f, 0x7ffff953, 0x0038b1bd, 0x7ffff372, -0x004bd34d, 0x7fffe98b, 0x00635538, 0x7fffd975, 0x007fdc64, 0x7fffc024, 0x00a219f1, 0x7fff995b, -0x00cacad0, 0x7fff5f5b, 0x00fab72d, 0x7fff0a75, 0x0132b1af, 0x7ffe9091, 0x01739689, 0x7ffde49e, -0x01be4a63, 0x7ffcf5ef, 0x0213b910, 0x7ffbaf84, 0x0274d41e, 0x7ff9f73a, 0x02e2913a, 0x7ff7acf1, -0x035de86c, 0x7ff4a99a, 0x03e7d233, 0x7ff0be3d, 0x0481457c, 0x7febb2f1, 0x052b357c, 0x7fe545d4, -0x05e68f77, 0x7fdd2a02, 0x06b4386f, 0x7fd30695, 0x07950acb, 0x7fc675b4, 0x0889d3ef, 0x7fb703be, -0x099351e0, 0x7fa42e89, 0x0ab230e0, 0x7f8d64d8, 0x0be70923, 0x7f7205f8, 0x0d325c93, 0x7f516195, -0x0e9494ae, 0x7f2ab7d0, 0x100e0085, 0x7efd3997, 0x119ed2ef, 0x7ec8094a, 0x134720d8, 0x7e8a3ba7, -0x1506dfdc, 0x7e42d906, 0x16dde50b, 0x7df0dee4, 0x18cbe3f7, 0x7d9341b4, 0x1ad06e07, 0x7d28ef02, -0x1ceaf215, 0x7cb0cfcc, 0x1f1abc4f, 0x7c29cb20, 0x215ef677, 0x7b92c8eb, 0x23b6a867, 0x7aeab4ec, -0x2620b8ec, 0x7a3081d0, 0x289beef5, 0x79632c5a, 0x2b26f30b, 0x7881be95, 0x2dc0511f, 0x778b5304, -0x30667aa2, 0x767f17c0, 0x3317c8dd, 0x755c5178, 0x35d27f98, 0x74225e50, 0x3894cff3, 0x72d0b887, -0x3b5cdb7b, 0x7166f8e7, 0x3e28b770, 0x6fe4d8e8, 0x40f6702a, 0x6e4a3491, 0x43c40caa, 0x6c970bfc, -0x468f9231, 0x6acb8483, 0x495707f5, 0x68e7e994, 0x4c187ac7, 0x66ecad1c, 0x4ed200c5, 0x64da6797, -0x5181bcea, 0x62b1d7b7, 0x5425e28e, 0x6073e1ae, 0x56bcb8c2, 0x5e218e16, 0x59449d76, 0x5bbc0875, -/* 1024 - format = Q31 * 2^0 */ -0x0009962f, 0x7fffffa4, 0x000e16fb, 0x7fffff39, 0x0011ea65, 0x7ffffebf, 0x0015750e, 0x7ffffe34, -0x0018dc74, 0x7ffffd96, 0x001c332e, 0x7ffffce5, 0x001f83f5, 0x7ffffc1f, 0x0022d59a, 0x7ffffb43, -0x00262cc2, 0x7ffffa4f, 0x00298cc4, 0x7ffff942, 0x002cf81f, 0x7ffff81a, 0x003070c4, 0x7ffff6d6, -0x0033f840, 0x7ffff573, 0x00378fd9, 0x7ffff3f1, 0x003b38a1, 0x7ffff24d, 0x003ef381, 0x7ffff085, -0x0042c147, 0x7fffee98, 0x0046a2a8, 0x7fffec83, 0x004a9847, 0x7fffea44, 0x004ea2b7, 0x7fffe7d8, -0x0052c283, 0x7fffe53f, 0x0056f829, 0x7fffe274, 0x005b4422, 0x7fffdf76, 0x005fa6dd, 0x7fffdc43, -0x006420c8, 0x7fffd8d6, 0x0068b249, 0x7fffd52f, 0x006d5bc4, 0x7fffd149, 0x00721d9a, 0x7fffcd22, -0x0076f828, 0x7fffc8b6, 0x007bebca, 0x7fffc404, 0x0080f8d9, 0x7fffbf06, 0x00861fae, 0x7fffb9bb, -0x008b609e, 0x7fffb41e, 0x0090bbff, 0x7fffae2c, 0x00963224, 0x7fffa7e1, 0x009bc362, 0x7fffa13a, -0x00a17009, 0x7fff9a32, 0x00a7386c, 0x7fff92c5, 0x00ad1cdc, 0x7fff8af0, 0x00b31da8, 0x7fff82ad, -0x00b93b21, 0x7fff79f9, 0x00bf7596, 0x7fff70cf, 0x00c5cd57, 0x7fff672a, 0x00cc42b1, 0x7fff5d05, -0x00d2d5f3, 0x7fff525c, 0x00d9876c, 0x7fff4729, 0x00e05769, 0x7fff3b66, 0x00e74638, 0x7fff2f10, -0x00ee5426, 0x7fff221f, 0x00f58182, 0x7fff148e, 0x00fcce97, 0x7fff0658, 0x01043bb3, 0x7ffef776, -0x010bc923, 0x7ffee7e2, 0x01137733, 0x7ffed795, 0x011b4631, 0x7ffec68a, 0x01233669, 0x7ffeb4ba, -0x012b4827, 0x7ffea21d, 0x01337bb8, 0x7ffe8eac, 0x013bd167, 0x7ffe7a61, 0x01444982, 0x7ffe6533, -0x014ce454, 0x7ffe4f1c, 0x0155a229, 0x7ffe3813, 0x015e834d, 0x7ffe2011, 0x0167880c, 0x7ffe070d, -0x0170b0b2, 0x7ffdecff, 0x0179fd8b, 0x7ffdd1df, 0x01836ee1, 0x7ffdb5a2, 0x018d0500, 0x7ffd9842, -0x0196c035, 0x7ffd79b3, 0x01a0a0ca, 0x7ffd59ee, 0x01aaa70a, 0x7ffd38e8, 0x01b4d341, 0x7ffd1697, -0x01bf25b9, 0x7ffcf2f2, 0x01c99ebd, 0x7ffccdee, 0x01d43e99, 0x7ffca780, 0x01df0597, 0x7ffc7f9e, -0x01e9f401, 0x7ffc563d, 0x01f50a22, 0x7ffc2b51, 0x02004844, 0x7ffbfecf, 0x020baeb1, 0x7ffbd0ab, -0x02173db4, 0x7ffba0da, 0x0222f596, 0x7ffb6f4f, 0x022ed6a1, 0x7ffb3bfd, 0x023ae11f, 0x7ffb06d8, -0x02471558, 0x7ffacfd3, 0x02537397, 0x7ffa96e0, 0x025ffc25, 0x7ffa5bf2, 0x026caf4a, 0x7ffa1efc, -0x02798d4f, 0x7ff9dfee, 0x0286967c, 0x7ff99ebb, 0x0293cb1b, 0x7ff95b55, 0x02a12b72, 0x7ff915ab, -0x02aeb7cb, 0x7ff8cdaf, 0x02bc706d, 0x7ff88351, 0x02ca559f, 0x7ff83682, 0x02d867a9, 0x7ff7e731, -0x02e6a6d2, 0x7ff7954e, 0x02f51361, 0x7ff740c8, 0x0303ad9c, 0x7ff6e98e, 0x031275ca, 0x7ff68f8f, -0x03216c30, 0x7ff632ba, 0x03309116, 0x7ff5d2fb, 0x033fe4bf, 0x7ff57042, 0x034f6773, 0x7ff50a7a, -0x035f1975, 0x7ff4a192, 0x036efb0a, 0x7ff43576, 0x037f0c78, 0x7ff3c612, 0x038f4e02, 0x7ff35353, -0x039fbfeb, 0x7ff2dd24, 0x03b06279, 0x7ff26370, 0x03c135ed, 0x7ff1e623, 0x03d23a8b, 0x7ff16527, -0x03e37095, 0x7ff0e067, 0x03f4d84e, 0x7ff057cc, 0x040671f7, 0x7fefcb40, 0x04183dd3, 0x7fef3aad, -0x042a3c22, 0x7feea5fa, 0x043c6d25, 0x7fee0d11, 0x044ed11d, 0x7fed6fda, 0x04616849, 0x7fecce3d, -0x047432eb, 0x7fec2821, 0x04873140, 0x7feb7d6c, 0x049a6388, 0x7feace07, 0x04adca01, 0x7fea19d6, -0x04c164ea, 0x7fe960c0, 0x04d53481, 0x7fe8a2aa, 0x04e93902, 0x7fe7df79, 0x04fd72aa, 0x7fe71712, -0x0511e1b6, 0x7fe6495a, 0x05268663, 0x7fe57634, 0x053b60eb, 0x7fe49d83, 0x05507189, 0x7fe3bf2b, -0x0565b879, 0x7fe2db0f, 0x057b35f4, 0x7fe1f110, 0x0590ea35, 0x7fe10111, 0x05a6d574, 0x7fe00af3, -0x05bcf7ea, 0x7fdf0e97, 0x05d351cf, 0x7fde0bdd, 0x05e9e35c, 0x7fdd02a6, 0x0600acc8, 0x7fdbf2d2, -0x0617ae48, 0x7fdadc40, 0x062ee814, 0x7fd9becf, 0x06465a62, 0x7fd89a5e, 0x065e0565, 0x7fd76eca, -0x0675e954, 0x7fd63bf1, 0x068e0662, 0x7fd501b0, 0x06a65cc3, 0x7fd3bfe4, 0x06beecaa, 0x7fd2766a, -0x06d7b648, 0x7fd1251e, 0x06f0b9d1, 0x7fcfcbda, 0x0709f775, 0x7fce6a7a, 0x07236f65, 0x7fcd00d8, -0x073d21d2, 0x7fcb8ecf, 0x07570eea, 0x7fca1439, 0x077136dd, 0x7fc890ed, 0x078b99da, 0x7fc704c7, -0x07a6380d, 0x7fc56f9d, 0x07c111a4, 0x7fc3d147, 0x07dc26cc, 0x7fc2299e, 0x07f777b1, 0x7fc07878, -0x0813047d, 0x7fbebdac, 0x082ecd5b, 0x7fbcf90f, 0x084ad276, 0x7fbb2a78, 0x086713f7, 0x7fb951bc, -0x08839206, 0x7fb76eaf, 0x08a04ccb, 0x7fb58126, 0x08bd446e, 0x7fb388f4, 0x08da7915, 0x7fb185ee, -0x08f7eae7, 0x7faf77e5, 0x09159a09, 0x7fad5ead, 0x0933869f, 0x7fab3a17, 0x0951b0cd, 0x7fa909f6, -0x097018b7, 0x7fa6ce1a, 0x098ebe7f, 0x7fa48653, 0x09ada248, 0x7fa23273, 0x09ccc431, 0x7f9fd249, -0x09ec245b, 0x7f9d65a4, 0x0a0bc2e7, 0x7f9aec53, 0x0a2b9ff3, 0x7f986625, 0x0a4bbb9e, 0x7f95d2e7, -0x0a6c1604, 0x7f933267, 0x0a8caf43, 0x7f908472, 0x0aad8776, 0x7f8dc8d5, 0x0ace9eb9, 0x7f8aff5c, -0x0aeff526, 0x7f8827d3, 0x0b118ad8, 0x7f854204, 0x0b335fe6, 0x7f824dbb, 0x0b557469, 0x7f7f4ac3, -0x0b77c879, 0x7f7c38e4, 0x0b9a5c2b, 0x7f7917e9, 0x0bbd2f97, 0x7f75e79b, 0x0be042d0, 0x7f72a7c3, -0x0c0395ec, 0x7f6f5828, 0x0c2728fd, 0x7f6bf892, 0x0c4afc16, 0x7f6888c9, 0x0c6f0f4a, 0x7f650894, -0x0c9362a8, 0x7f6177b9, 0x0cb7f642, 0x7f5dd5ff, 0x0cdcca26, 0x7f5a232a, 0x0d01de63, 0x7f565f00, -0x0d273307, 0x7f528947, 0x0d4cc81f, 0x7f4ea1c2, 0x0d729db7, 0x7f4aa835, 0x0d98b3da, 0x7f469c65, -0x0dbf0a92, 0x7f427e13, 0x0de5a1e9, 0x7f3e4d04, 0x0e0c79e7, 0x7f3a08f9, 0x0e339295, 0x7f35b1b4, -0x0e5aebfa, 0x7f3146f8, 0x0e82861a, 0x7f2cc884, 0x0eaa60fd, 0x7f28361b, 0x0ed27ca5, 0x7f238f7c, -0x0efad917, 0x7f1ed467, 0x0f237656, 0x7f1a049d, 0x0f4c5462, 0x7f151fdc, 0x0f75733d, 0x7f1025e3, -0x0f9ed2e6, 0x7f0b1672, 0x0fc8735e, 0x7f05f146, 0x0ff254a1, 0x7f00b61d, 0x101c76ae, 0x7efb64b4, -0x1046d981, 0x7ef5fcca, 0x10717d15, 0x7ef07e19, 0x109c6165, 0x7eeae860, 0x10c7866a, 0x7ee53b5b, -0x10f2ec1e, 0x7edf76c4, 0x111e9279, 0x7ed99a58, 0x114a7971, 0x7ed3a5d1, 0x1176a0fc, 0x7ecd98eb, -0x11a30910, 0x7ec77360, 0x11cfb1a1, 0x7ec134eb, 0x11fc9aa2, 0x7ebadd44, 0x1229c406, 0x7eb46c27, -0x12572dbf, 0x7eade14c, 0x1284d7bc, 0x7ea73c6c, 0x12b2c1ed, 0x7ea07d41, 0x12e0ec42, 0x7e99a382, -0x130f56a8, 0x7e92aee7, 0x133e010b, 0x7e8b9f2a, 0x136ceb59, 0x7e847402, 0x139c157b, 0x7e7d2d25, -0x13cb7f5d, 0x7e75ca4c, 0x13fb28e6, 0x7e6e4b2d, 0x142b1200, 0x7e66af7f, 0x145b3a92, 0x7e5ef6f8, -0x148ba281, 0x7e572150, 0x14bc49b4, 0x7e4f2e3b, 0x14ed300f, 0x7e471d70, 0x151e5575, 0x7e3eeea5, -0x154fb9c9, 0x7e36a18e, 0x15815ced, 0x7e2e35e2, 0x15b33ec1, 0x7e25ab56, 0x15e55f25, 0x7e1d019e, -0x1617bdf9, 0x7e14386e, 0x164a5b19, 0x7e0b4f7d, 0x167d3662, 0x7e02467e, 0x16b04fb2, 0x7df91d25, -0x16e3a6e2, 0x7defd327, 0x17173bce, 0x7de66837, 0x174b0e4d, 0x7ddcdc0a, 0x177f1e39, 0x7dd32e53, -0x17b36b69, 0x7dc95ec6, 0x17e7f5b3, 0x7dbf6d17, 0x181cbcec, 0x7db558f9, 0x1851c0e9, 0x7dab221f, -0x1887017d, 0x7da0c83c, 0x18bc7e7c, 0x7d964b05, 0x18f237b6, 0x7d8baa2b, 0x19282cfd, 0x7d80e563, -0x195e5e20, 0x7d75fc5e, 0x1994caee, 0x7d6aeed0, 0x19cb7335, 0x7d5fbc6d, 0x1a0256c2, 0x7d5464e6, -0x1a397561, 0x7d48e7ef, 0x1a70cede, 0x7d3d453b, 0x1aa86301, 0x7d317c7c, 0x1ae03195, 0x7d258d65, -0x1b183a63, 0x7d1977aa, 0x1b507d30, 0x7d0d3afc, 0x1b88f9c5, 0x7d00d710, 0x1bc1afe6, 0x7cf44b97, -0x1bfa9f58, 0x7ce79846, 0x1c33c7e0, 0x7cdabcce, 0x1c6d293f, 0x7ccdb8e4, 0x1ca6c337, 0x7cc08c39, -0x1ce0958a, 0x7cb33682, 0x1d1a9ff8, 0x7ca5b772, 0x1d54e240, 0x7c980ebd, 0x1d8f5c21, 0x7c8a3c14, -0x1dca0d56, 0x7c7c3f2e, 0x1e04f59f, 0x7c6e17bc, 0x1e4014b4, 0x7c5fc573, 0x1e7b6a53, 0x7c514807, -0x1eb6f633, 0x7c429f2c, 0x1ef2b80f, 0x7c33ca96, 0x1f2eaf9e, 0x7c24c9fa, 0x1f6adc98, 0x7c159d0d, -0x1fa73eb2, 0x7c064383, 0x1fe3d5a3, 0x7bf6bd11, 0x2020a11e, 0x7be7096c, 0x205da0d8, 0x7bd7284a, -0x209ad483, 0x7bc71960, 0x20d83bd1, 0x7bb6dc65, 0x2115d674, 0x7ba6710d, 0x2153a41b, 0x7b95d710, -0x2191a476, 0x7b850e24, 0x21cfd734, 0x7b7415ff, 0x220e3c02, 0x7b62ee59, 0x224cd28d, 0x7b5196e9, -0x228b9a82, 0x7b400f67, 0x22ca938a, 0x7b2e578a, 0x2309bd52, 0x7b1c6f0b, 0x23491783, 0x7b0a55a1, -0x2388a1c4, 0x7af80b07, 0x23c85bbf, 0x7ae58ef5, 0x2408451a, 0x7ad2e124, 0x24485d7c, 0x7ac0014e, -0x2488a48a, 0x7aacef2e, 0x24c919e9, 0x7a99aa7e, 0x2509bd3d, 0x7a8632f8, 0x254a8e29, 0x7a728858, -0x258b8c50, 0x7a5eaa5a, 0x25ccb753, 0x7a4a98b9, 0x260e0ed3, 0x7a365333, 0x264f9271, 0x7a21d983, -0x269141cb, 0x7a0d2b68, 0x26d31c80, 0x79f8489e, 0x2715222f, 0x79e330e4, 0x27575273, 0x79cde3f8, -0x2799acea, 0x79b8619a, 0x27dc3130, 0x79a2a989, 0x281ededf, 0x798cbb85, 0x2861b591, 0x7976974e, -0x28a4b4e0, 0x79603ca5, 0x28e7dc65, 0x7949ab4c, 0x292b2bb8, 0x7932e304, 0x296ea270, 0x791be390, -0x29b24024, 0x7904acb3, 0x29f6046b, 0x78ed3e30, 0x2a39eed8, 0x78d597cc, 0x2a7dff02, 0x78bdb94a, -0x2ac2347c, 0x78a5a270, 0x2b068eda, 0x788d5304, 0x2b4b0dae, 0x7874cacb, 0x2b8fb08a, 0x785c098d, -0x2bd47700, 0x78430f11, 0x2c1960a1, 0x7829db1f, 0x2c5e6cfd, 0x78106d7f, 0x2ca39ba3, 0x77f6c5fb, -0x2ce8ec23, 0x77dce45c, 0x2d2e5e0b, 0x77c2c86e, 0x2d73f0e8, 0x77a871fa, 0x2db9a449, 0x778de0cd, -0x2dff77b8, 0x777314b2, 0x2e456ac4, 0x77580d78, 0x2e8b7cf6, 0x773ccaeb, 0x2ed1addb, 0x77214cdb, -0x2f17fcfb, 0x77059315, 0x2f5e69e2, 0x76e99d69, 0x2fa4f419, 0x76cd6ba9, 0x2feb9b27, 0x76b0fda4, -0x30325e96, 0x7694532e, 0x30793dee, 0x76776c17, 0x30c038b5, 0x765a4834, 0x31074e72, 0x763ce759, -0x314e7eab, 0x761f4959, 0x3195c8e6, 0x76016e0b, 0x31dd2ca9, 0x75e35545, 0x3224a979, 0x75c4fedc, -0x326c3ed8, 0x75a66aab, 0x32b3ec4d, 0x75879887, 0x32fbb159, 0x7568884b, 0x33438d81, 0x754939d1, -0x338b8045, 0x7529acf4, 0x33d3892a, 0x7509e18e, 0x341ba7b1, 0x74e9d77d, 0x3463db5a, 0x74c98e9e, -0x34ac23a7, 0x74a906cd, 0x34f48019, 0x74883fec, 0x353cf02f, 0x746739d8, 0x3585736a, 0x7445f472, -0x35ce0949, 0x74246f9c, 0x3616b14c, 0x7402ab37, 0x365f6af0, 0x73e0a727, 0x36a835b5, 0x73be6350, -0x36f11118, 0x739bdf95, 0x3739fc98, 0x73791bdd, 0x3782f7b2, 0x7356180e, 0x37cc01e3, 0x7332d410, -0x38151aa8, 0x730f4fc9, 0x385e417e, 0x72eb8b24, 0x38a775e1, 0x72c7860a, 0x38f0b74d, 0x72a34066, -0x393a053e, 0x727eba24, 0x39835f30, 0x7259f331, 0x39ccc49e, 0x7234eb79, 0x3a163503, 0x720fa2eb, -0x3a5fafda, 0x71ea1977, 0x3aa9349e, 0x71c44f0c, 0x3af2c2ca, 0x719e439d, 0x3b3c59d7, 0x7177f71a, -0x3b85f940, 0x71516978, 0x3bcfa07e, 0x712a9aaa, 0x3c194f0d, 0x71038aa4, 0x3c630464, 0x70dc395e, -0x3cacbfff, 0x70b4a6cd, 0x3cf68155, 0x708cd2e9, 0x3d4047e1, 0x7064bdab, 0x3d8a131c, 0x703c670d, -0x3dd3e27e, 0x7013cf0a, 0x3e1db580, 0x6feaf59c, 0x3e678b9b, 0x6fc1dac1, 0x3eb16449, 0x6f987e76, -0x3efb3f01, 0x6f6ee0b9, 0x3f451b3d, 0x6f45018b, 0x3f8ef874, 0x6f1ae0eb, 0x3fd8d620, 0x6ef07edb, -0x4022b3b9, 0x6ec5db5d, 0x406c90b7, 0x6e9af675, 0x40b66c93, 0x6e6fd027, 0x410046c5, 0x6e446879, -0x414a1ec6, 0x6e18bf71, 0x4193f40d, 0x6decd517, 0x41ddc615, 0x6dc0a972, 0x42279455, 0x6d943c8d, -0x42715e45, 0x6d678e71, 0x42bb235f, 0x6d3a9f2a, 0x4304e31a, 0x6d0d6ec5, 0x434e9cf1, 0x6cdffd4f, -0x4398505b, 0x6cb24ad6, 0x43e1fcd1, 0x6c84576b, 0x442ba1cd, 0x6c56231c, 0x44753ec7, 0x6c27adfd, -0x44bed33a, 0x6bf8f81e, 0x45085e9d, 0x6bca0195, 0x4551e06b, 0x6b9aca75, 0x459b581e, 0x6b6b52d5, -0x45e4c52f, 0x6b3b9ac9, 0x462e2717, 0x6b0ba26b, 0x46777d52, 0x6adb69d3, 0x46c0c75a, 0x6aaaf11b, -0x470a04a9, 0x6a7a385c, 0x475334b9, 0x6a493fb3, 0x479c5707, 0x6a18073d, 0x47e56b0c, 0x69e68f17, -0x482e7045, 0x69b4d761, 0x4877662c, 0x6982e039, 0x48c04c3f, 0x6950a9c0, 0x490921f8, 0x691e341a, -0x4951e6d5, 0x68eb7f67, 0x499a9a51, 0x68b88bcd, 0x49e33beb, 0x68855970, 0x4a2bcb1f, 0x6851e875, -0x4a74476b, 0x681e3905, 0x4abcb04c, 0x67ea4b47, 0x4b050541, 0x67b61f63, 0x4b4d45c9, 0x6781b585, -0x4b957162, 0x674d0dd6, 0x4bdd878c, 0x67182883, 0x4c2587c6, 0x66e305b8, 0x4c6d7190, 0x66ada5a5, -0x4cb5446a, 0x66780878, 0x4cfcffd5, 0x66422e60, 0x4d44a353, 0x660c1790, 0x4d8c2e64, 0x65d5c439, -0x4dd3a08c, 0x659f348e, 0x4e1af94b, 0x656868c3, 0x4e623825, 0x6531610d, 0x4ea95c9d, 0x64fa1da3, -0x4ef06637, 0x64c29ebb, 0x4f375477, 0x648ae48d, 0x4f7e26e1, 0x6452ef53, 0x4fc4dcfb, 0x641abf46, -0x500b7649, 0x63e254a2, 0x5051f253, 0x63a9afa2, 0x5098509f, 0x6370d083, 0x50de90b3, 0x6337b784, -0x5124b218, 0x62fe64e3, 0x516ab455, 0x62c4d8e0, 0x51b096f3, 0x628b13bc, 0x51f6597b, 0x625115b8, -0x523bfb78, 0x6216df18, 0x52817c72, 0x61dc701f, 0x52c6dbf5, 0x61a1c912, 0x530c198d, 0x6166ea36, -0x535134c5, 0x612bd3d2, 0x53962d2a, 0x60f0862d, 0x53db024a, 0x60b50190, 0x541fb3b1, 0x60794644, -0x546440ef, 0x603d5494, 0x54a8a992, 0x60012cca, 0x54eced2b, 0x5fc4cf33, 0x55310b48, 0x5f883c1c, -0x5575037c, 0x5f4b73d2, 0x55b8d558, 0x5f0e76a5, 0x55fc806f, 0x5ed144e5, 0x56400452, 0x5e93dee1, -0x56836096, 0x5e5644ec, 0x56c694cf, 0x5e187757, 0x5709a092, 0x5dda7677, 0x574c8374, 0x5d9c429f, -0x578f3d0d, 0x5d5ddc24, 0x57d1ccf2, 0x5d1f435d, 0x581432bd, 0x5ce078a0, 0x58566e04, 0x5ca17c45, -0x58987e63, 0x5c624ea4, 0x58da6372, 0x5c22f016, 0x591c1ccc, 0x5be360f6, 0x595daa0d, 0x5ba3a19f, -0x599f0ad1, 0x5b63b26c, 0x59e03eb6, 0x5b2393ba, 0x5a214558, 0x5ae345e7, 0x5a621e56, 0x5aa2c951, + /* 128 - format = Q31 * 2^0 */ + 0x00016f63, 0x7ffffffe, 0x0003e382, 0x7ffffff1, 0x00078f64, 0x7fffffc7, 0x000cc323, 0x7fffff5d, + 0x0013d9ed, 0x7ffffe76, 0x001d3a9d, 0x7ffffcaa, 0x0029581f, 0x7ffff953, 0x0038b1bd, 0x7ffff372, + 0x004bd34d, 0x7fffe98b, 0x00635538, 0x7fffd975, 0x007fdc64, 0x7fffc024, 0x00a219f1, 0x7fff995b, + 0x00cacad0, 0x7fff5f5b, 0x00fab72d, 0x7fff0a75, 0x0132b1af, 0x7ffe9091, 0x01739689, 0x7ffde49e, + 0x01be4a63, 0x7ffcf5ef, 0x0213b910, 0x7ffbaf84, 0x0274d41e, 0x7ff9f73a, 0x02e2913a, 0x7ff7acf1, + 0x035de86c, 0x7ff4a99a, 0x03e7d233, 0x7ff0be3d, 0x0481457c, 0x7febb2f1, 0x052b357c, 0x7fe545d4, + 0x05e68f77, 0x7fdd2a02, 0x06b4386f, 0x7fd30695, 0x07950acb, 0x7fc675b4, 0x0889d3ef, 0x7fb703be, + 0x099351e0, 0x7fa42e89, 0x0ab230e0, 0x7f8d64d8, 0x0be70923, 0x7f7205f8, 0x0d325c93, 0x7f516195, + 0x0e9494ae, 0x7f2ab7d0, 0x100e0085, 0x7efd3997, 0x119ed2ef, 0x7ec8094a, 0x134720d8, 0x7e8a3ba7, + 0x1506dfdc, 0x7e42d906, 0x16dde50b, 0x7df0dee4, 0x18cbe3f7, 0x7d9341b4, 0x1ad06e07, 0x7d28ef02, + 0x1ceaf215, 0x7cb0cfcc, 0x1f1abc4f, 0x7c29cb20, 0x215ef677, 0x7b92c8eb, 0x23b6a867, 0x7aeab4ec, + 0x2620b8ec, 0x7a3081d0, 0x289beef5, 0x79632c5a, 0x2b26f30b, 0x7881be95, 0x2dc0511f, 0x778b5304, + 0x30667aa2, 0x767f17c0, 0x3317c8dd, 0x755c5178, 0x35d27f98, 0x74225e50, 0x3894cff3, 0x72d0b887, + 0x3b5cdb7b, 0x7166f8e7, 0x3e28b770, 0x6fe4d8e8, 0x40f6702a, 0x6e4a3491, 0x43c40caa, 0x6c970bfc, + 0x468f9231, 0x6acb8483, 0x495707f5, 0x68e7e994, 0x4c187ac7, 0x66ecad1c, 0x4ed200c5, 0x64da6797, + 0x5181bcea, 0x62b1d7b7, 0x5425e28e, 0x6073e1ae, 0x56bcb8c2, 0x5e218e16, 0x59449d76, 0x5bbc0875, + /* 1024 - format = Q31 * 2^0 */ + 0x0009962f, 0x7fffffa4, 0x000e16fb, 0x7fffff39, 0x0011ea65, 0x7ffffebf, 0x0015750e, 0x7ffffe34, + 0x0018dc74, 0x7ffffd96, 0x001c332e, 0x7ffffce5, 0x001f83f5, 0x7ffffc1f, 0x0022d59a, 0x7ffffb43, + 0x00262cc2, 0x7ffffa4f, 0x00298cc4, 0x7ffff942, 0x002cf81f, 0x7ffff81a, 0x003070c4, 0x7ffff6d6, + 0x0033f840, 0x7ffff573, 0x00378fd9, 0x7ffff3f1, 0x003b38a1, 0x7ffff24d, 0x003ef381, 0x7ffff085, + 0x0042c147, 0x7fffee98, 0x0046a2a8, 0x7fffec83, 0x004a9847, 0x7fffea44, 0x004ea2b7, 0x7fffe7d8, + 0x0052c283, 0x7fffe53f, 0x0056f829, 0x7fffe274, 0x005b4422, 0x7fffdf76, 0x005fa6dd, 0x7fffdc43, + 0x006420c8, 0x7fffd8d6, 0x0068b249, 0x7fffd52f, 0x006d5bc4, 0x7fffd149, 0x00721d9a, 0x7fffcd22, + 0x0076f828, 0x7fffc8b6, 0x007bebca, 0x7fffc404, 0x0080f8d9, 0x7fffbf06, 0x00861fae, 0x7fffb9bb, + 0x008b609e, 0x7fffb41e, 0x0090bbff, 0x7fffae2c, 0x00963224, 0x7fffa7e1, 0x009bc362, 0x7fffa13a, + 0x00a17009, 0x7fff9a32, 0x00a7386c, 0x7fff92c5, 0x00ad1cdc, 0x7fff8af0, 0x00b31da8, 0x7fff82ad, + 0x00b93b21, 0x7fff79f9, 0x00bf7596, 0x7fff70cf, 0x00c5cd57, 0x7fff672a, 0x00cc42b1, 0x7fff5d05, + 0x00d2d5f3, 0x7fff525c, 0x00d9876c, 0x7fff4729, 0x00e05769, 0x7fff3b66, 0x00e74638, 0x7fff2f10, + 0x00ee5426, 0x7fff221f, 0x00f58182, 0x7fff148e, 0x00fcce97, 0x7fff0658, 0x01043bb3, 0x7ffef776, + 0x010bc923, 0x7ffee7e2, 0x01137733, 0x7ffed795, 0x011b4631, 0x7ffec68a, 0x01233669, 0x7ffeb4ba, + 0x012b4827, 0x7ffea21d, 0x01337bb8, 0x7ffe8eac, 0x013bd167, 0x7ffe7a61, 0x01444982, 0x7ffe6533, + 0x014ce454, 0x7ffe4f1c, 0x0155a229, 0x7ffe3813, 0x015e834d, 0x7ffe2011, 0x0167880c, 0x7ffe070d, + 0x0170b0b2, 0x7ffdecff, 0x0179fd8b, 0x7ffdd1df, 0x01836ee1, 0x7ffdb5a2, 0x018d0500, 0x7ffd9842, + 0x0196c035, 0x7ffd79b3, 0x01a0a0ca, 0x7ffd59ee, 0x01aaa70a, 0x7ffd38e8, 0x01b4d341, 0x7ffd1697, + 0x01bf25b9, 0x7ffcf2f2, 0x01c99ebd, 0x7ffccdee, 0x01d43e99, 0x7ffca780, 0x01df0597, 0x7ffc7f9e, + 0x01e9f401, 0x7ffc563d, 0x01f50a22, 0x7ffc2b51, 0x02004844, 0x7ffbfecf, 0x020baeb1, 0x7ffbd0ab, + 0x02173db4, 0x7ffba0da, 0x0222f596, 0x7ffb6f4f, 0x022ed6a1, 0x7ffb3bfd, 0x023ae11f, 0x7ffb06d8, + 0x02471558, 0x7ffacfd3, 0x02537397, 0x7ffa96e0, 0x025ffc25, 0x7ffa5bf2, 0x026caf4a, 0x7ffa1efc, + 0x02798d4f, 0x7ff9dfee, 0x0286967c, 0x7ff99ebb, 0x0293cb1b, 0x7ff95b55, 0x02a12b72, 0x7ff915ab, + 0x02aeb7cb, 0x7ff8cdaf, 0x02bc706d, 0x7ff88351, 0x02ca559f, 0x7ff83682, 0x02d867a9, 0x7ff7e731, + 0x02e6a6d2, 0x7ff7954e, 0x02f51361, 0x7ff740c8, 0x0303ad9c, 0x7ff6e98e, 0x031275ca, 0x7ff68f8f, + 0x03216c30, 0x7ff632ba, 0x03309116, 0x7ff5d2fb, 0x033fe4bf, 0x7ff57042, 0x034f6773, 0x7ff50a7a, + 0x035f1975, 0x7ff4a192, 0x036efb0a, 0x7ff43576, 0x037f0c78, 0x7ff3c612, 0x038f4e02, 0x7ff35353, + 0x039fbfeb, 0x7ff2dd24, 0x03b06279, 0x7ff26370, 0x03c135ed, 0x7ff1e623, 0x03d23a8b, 0x7ff16527, + 0x03e37095, 0x7ff0e067, 0x03f4d84e, 0x7ff057cc, 0x040671f7, 0x7fefcb40, 0x04183dd3, 0x7fef3aad, + 0x042a3c22, 0x7feea5fa, 0x043c6d25, 0x7fee0d11, 0x044ed11d, 0x7fed6fda, 0x04616849, 0x7fecce3d, + 0x047432eb, 0x7fec2821, 0x04873140, 0x7feb7d6c, 0x049a6388, 0x7feace07, 0x04adca01, 0x7fea19d6, + 0x04c164ea, 0x7fe960c0, 0x04d53481, 0x7fe8a2aa, 0x04e93902, 0x7fe7df79, 0x04fd72aa, 0x7fe71712, + 0x0511e1b6, 0x7fe6495a, 0x05268663, 0x7fe57634, 0x053b60eb, 0x7fe49d83, 0x05507189, 0x7fe3bf2b, + 0x0565b879, 0x7fe2db0f, 0x057b35f4, 0x7fe1f110, 0x0590ea35, 0x7fe10111, 0x05a6d574, 0x7fe00af3, + 0x05bcf7ea, 0x7fdf0e97, 0x05d351cf, 0x7fde0bdd, 0x05e9e35c, 0x7fdd02a6, 0x0600acc8, 0x7fdbf2d2, + 0x0617ae48, 0x7fdadc40, 0x062ee814, 0x7fd9becf, 0x06465a62, 0x7fd89a5e, 0x065e0565, 0x7fd76eca, + 0x0675e954, 0x7fd63bf1, 0x068e0662, 0x7fd501b0, 0x06a65cc3, 0x7fd3bfe4, 0x06beecaa, 0x7fd2766a, + 0x06d7b648, 0x7fd1251e, 0x06f0b9d1, 0x7fcfcbda, 0x0709f775, 0x7fce6a7a, 0x07236f65, 0x7fcd00d8, + 0x073d21d2, 0x7fcb8ecf, 0x07570eea, 0x7fca1439, 0x077136dd, 0x7fc890ed, 0x078b99da, 0x7fc704c7, + 0x07a6380d, 0x7fc56f9d, 0x07c111a4, 0x7fc3d147, 0x07dc26cc, 0x7fc2299e, 0x07f777b1, 0x7fc07878, + 0x0813047d, 0x7fbebdac, 0x082ecd5b, 0x7fbcf90f, 0x084ad276, 0x7fbb2a78, 0x086713f7, 0x7fb951bc, + 0x08839206, 0x7fb76eaf, 0x08a04ccb, 0x7fb58126, 0x08bd446e, 0x7fb388f4, 0x08da7915, 0x7fb185ee, + 0x08f7eae7, 0x7faf77e5, 0x09159a09, 0x7fad5ead, 0x0933869f, 0x7fab3a17, 0x0951b0cd, 0x7fa909f6, + 0x097018b7, 0x7fa6ce1a, 0x098ebe7f, 0x7fa48653, 0x09ada248, 0x7fa23273, 0x09ccc431, 0x7f9fd249, + 0x09ec245b, 0x7f9d65a4, 0x0a0bc2e7, 0x7f9aec53, 0x0a2b9ff3, 0x7f986625, 0x0a4bbb9e, 0x7f95d2e7, + 0x0a6c1604, 0x7f933267, 0x0a8caf43, 0x7f908472, 0x0aad8776, 0x7f8dc8d5, 0x0ace9eb9, 0x7f8aff5c, + 0x0aeff526, 0x7f8827d3, 0x0b118ad8, 0x7f854204, 0x0b335fe6, 0x7f824dbb, 0x0b557469, 0x7f7f4ac3, + 0x0b77c879, 0x7f7c38e4, 0x0b9a5c2b, 0x7f7917e9, 0x0bbd2f97, 0x7f75e79b, 0x0be042d0, 0x7f72a7c3, + 0x0c0395ec, 0x7f6f5828, 0x0c2728fd, 0x7f6bf892, 0x0c4afc16, 0x7f6888c9, 0x0c6f0f4a, 0x7f650894, + 0x0c9362a8, 0x7f6177b9, 0x0cb7f642, 0x7f5dd5ff, 0x0cdcca26, 0x7f5a232a, 0x0d01de63, 0x7f565f00, + 0x0d273307, 0x7f528947, 0x0d4cc81f, 0x7f4ea1c2, 0x0d729db7, 0x7f4aa835, 0x0d98b3da, 0x7f469c65, + 0x0dbf0a92, 0x7f427e13, 0x0de5a1e9, 0x7f3e4d04, 0x0e0c79e7, 0x7f3a08f9, 0x0e339295, 0x7f35b1b4, + 0x0e5aebfa, 0x7f3146f8, 0x0e82861a, 0x7f2cc884, 0x0eaa60fd, 0x7f28361b, 0x0ed27ca5, 0x7f238f7c, + 0x0efad917, 0x7f1ed467, 0x0f237656, 0x7f1a049d, 0x0f4c5462, 0x7f151fdc, 0x0f75733d, 0x7f1025e3, + 0x0f9ed2e6, 0x7f0b1672, 0x0fc8735e, 0x7f05f146, 0x0ff254a1, 0x7f00b61d, 0x101c76ae, 0x7efb64b4, + 0x1046d981, 0x7ef5fcca, 0x10717d15, 0x7ef07e19, 0x109c6165, 0x7eeae860, 0x10c7866a, 0x7ee53b5b, + 0x10f2ec1e, 0x7edf76c4, 0x111e9279, 0x7ed99a58, 0x114a7971, 0x7ed3a5d1, 0x1176a0fc, 0x7ecd98eb, + 0x11a30910, 0x7ec77360, 0x11cfb1a1, 0x7ec134eb, 0x11fc9aa2, 0x7ebadd44, 0x1229c406, 0x7eb46c27, + 0x12572dbf, 0x7eade14c, 0x1284d7bc, 0x7ea73c6c, 0x12b2c1ed, 0x7ea07d41, 0x12e0ec42, 0x7e99a382, + 0x130f56a8, 0x7e92aee7, 0x133e010b, 0x7e8b9f2a, 0x136ceb59, 0x7e847402, 0x139c157b, 0x7e7d2d25, + 0x13cb7f5d, 0x7e75ca4c, 0x13fb28e6, 0x7e6e4b2d, 0x142b1200, 0x7e66af7f, 0x145b3a92, 0x7e5ef6f8, + 0x148ba281, 0x7e572150, 0x14bc49b4, 0x7e4f2e3b, 0x14ed300f, 0x7e471d70, 0x151e5575, 0x7e3eeea5, + 0x154fb9c9, 0x7e36a18e, 0x15815ced, 0x7e2e35e2, 0x15b33ec1, 0x7e25ab56, 0x15e55f25, 0x7e1d019e, + 0x1617bdf9, 0x7e14386e, 0x164a5b19, 0x7e0b4f7d, 0x167d3662, 0x7e02467e, 0x16b04fb2, 0x7df91d25, + 0x16e3a6e2, 0x7defd327, 0x17173bce, 0x7de66837, 0x174b0e4d, 0x7ddcdc0a, 0x177f1e39, 0x7dd32e53, + 0x17b36b69, 0x7dc95ec6, 0x17e7f5b3, 0x7dbf6d17, 0x181cbcec, 0x7db558f9, 0x1851c0e9, 0x7dab221f, + 0x1887017d, 0x7da0c83c, 0x18bc7e7c, 0x7d964b05, 0x18f237b6, 0x7d8baa2b, 0x19282cfd, 0x7d80e563, + 0x195e5e20, 0x7d75fc5e, 0x1994caee, 0x7d6aeed0, 0x19cb7335, 0x7d5fbc6d, 0x1a0256c2, 0x7d5464e6, + 0x1a397561, 0x7d48e7ef, 0x1a70cede, 0x7d3d453b, 0x1aa86301, 0x7d317c7c, 0x1ae03195, 0x7d258d65, + 0x1b183a63, 0x7d1977aa, 0x1b507d30, 0x7d0d3afc, 0x1b88f9c5, 0x7d00d710, 0x1bc1afe6, 0x7cf44b97, + 0x1bfa9f58, 0x7ce79846, 0x1c33c7e0, 0x7cdabcce, 0x1c6d293f, 0x7ccdb8e4, 0x1ca6c337, 0x7cc08c39, + 0x1ce0958a, 0x7cb33682, 0x1d1a9ff8, 0x7ca5b772, 0x1d54e240, 0x7c980ebd, 0x1d8f5c21, 0x7c8a3c14, + 0x1dca0d56, 0x7c7c3f2e, 0x1e04f59f, 0x7c6e17bc, 0x1e4014b4, 0x7c5fc573, 0x1e7b6a53, 0x7c514807, + 0x1eb6f633, 0x7c429f2c, 0x1ef2b80f, 0x7c33ca96, 0x1f2eaf9e, 0x7c24c9fa, 0x1f6adc98, 0x7c159d0d, + 0x1fa73eb2, 0x7c064383, 0x1fe3d5a3, 0x7bf6bd11, 0x2020a11e, 0x7be7096c, 0x205da0d8, 0x7bd7284a, + 0x209ad483, 0x7bc71960, 0x20d83bd1, 0x7bb6dc65, 0x2115d674, 0x7ba6710d, 0x2153a41b, 0x7b95d710, + 0x2191a476, 0x7b850e24, 0x21cfd734, 0x7b7415ff, 0x220e3c02, 0x7b62ee59, 0x224cd28d, 0x7b5196e9, + 0x228b9a82, 0x7b400f67, 0x22ca938a, 0x7b2e578a, 0x2309bd52, 0x7b1c6f0b, 0x23491783, 0x7b0a55a1, + 0x2388a1c4, 0x7af80b07, 0x23c85bbf, 0x7ae58ef5, 0x2408451a, 0x7ad2e124, 0x24485d7c, 0x7ac0014e, + 0x2488a48a, 0x7aacef2e, 0x24c919e9, 0x7a99aa7e, 0x2509bd3d, 0x7a8632f8, 0x254a8e29, 0x7a728858, + 0x258b8c50, 0x7a5eaa5a, 0x25ccb753, 0x7a4a98b9, 0x260e0ed3, 0x7a365333, 0x264f9271, 0x7a21d983, + 0x269141cb, 0x7a0d2b68, 0x26d31c80, 0x79f8489e, 0x2715222f, 0x79e330e4, 0x27575273, 0x79cde3f8, + 0x2799acea, 0x79b8619a, 0x27dc3130, 0x79a2a989, 0x281ededf, 0x798cbb85, 0x2861b591, 0x7976974e, + 0x28a4b4e0, 0x79603ca5, 0x28e7dc65, 0x7949ab4c, 0x292b2bb8, 0x7932e304, 0x296ea270, 0x791be390, + 0x29b24024, 0x7904acb3, 0x29f6046b, 0x78ed3e30, 0x2a39eed8, 0x78d597cc, 0x2a7dff02, 0x78bdb94a, + 0x2ac2347c, 0x78a5a270, 0x2b068eda, 0x788d5304, 0x2b4b0dae, 0x7874cacb, 0x2b8fb08a, 0x785c098d, + 0x2bd47700, 0x78430f11, 0x2c1960a1, 0x7829db1f, 0x2c5e6cfd, 0x78106d7f, 0x2ca39ba3, 0x77f6c5fb, + 0x2ce8ec23, 0x77dce45c, 0x2d2e5e0b, 0x77c2c86e, 0x2d73f0e8, 0x77a871fa, 0x2db9a449, 0x778de0cd, + 0x2dff77b8, 0x777314b2, 0x2e456ac4, 0x77580d78, 0x2e8b7cf6, 0x773ccaeb, 0x2ed1addb, 0x77214cdb, + 0x2f17fcfb, 0x77059315, 0x2f5e69e2, 0x76e99d69, 0x2fa4f419, 0x76cd6ba9, 0x2feb9b27, 0x76b0fda4, + 0x30325e96, 0x7694532e, 0x30793dee, 0x76776c17, 0x30c038b5, 0x765a4834, 0x31074e72, 0x763ce759, + 0x314e7eab, 0x761f4959, 0x3195c8e6, 0x76016e0b, 0x31dd2ca9, 0x75e35545, 0x3224a979, 0x75c4fedc, + 0x326c3ed8, 0x75a66aab, 0x32b3ec4d, 0x75879887, 0x32fbb159, 0x7568884b, 0x33438d81, 0x754939d1, + 0x338b8045, 0x7529acf4, 0x33d3892a, 0x7509e18e, 0x341ba7b1, 0x74e9d77d, 0x3463db5a, 0x74c98e9e, + 0x34ac23a7, 0x74a906cd, 0x34f48019, 0x74883fec, 0x353cf02f, 0x746739d8, 0x3585736a, 0x7445f472, + 0x35ce0949, 0x74246f9c, 0x3616b14c, 0x7402ab37, 0x365f6af0, 0x73e0a727, 0x36a835b5, 0x73be6350, + 0x36f11118, 0x739bdf95, 0x3739fc98, 0x73791bdd, 0x3782f7b2, 0x7356180e, 0x37cc01e3, 0x7332d410, + 0x38151aa8, 0x730f4fc9, 0x385e417e, 0x72eb8b24, 0x38a775e1, 0x72c7860a, 0x38f0b74d, 0x72a34066, + 0x393a053e, 0x727eba24, 0x39835f30, 0x7259f331, 0x39ccc49e, 0x7234eb79, 0x3a163503, 0x720fa2eb, + 0x3a5fafda, 0x71ea1977, 0x3aa9349e, 0x71c44f0c, 0x3af2c2ca, 0x719e439d, 0x3b3c59d7, 0x7177f71a, + 0x3b85f940, 0x71516978, 0x3bcfa07e, 0x712a9aaa, 0x3c194f0d, 0x71038aa4, 0x3c630464, 0x70dc395e, + 0x3cacbfff, 0x70b4a6cd, 0x3cf68155, 0x708cd2e9, 0x3d4047e1, 0x7064bdab, 0x3d8a131c, 0x703c670d, + 0x3dd3e27e, 0x7013cf0a, 0x3e1db580, 0x6feaf59c, 0x3e678b9b, 0x6fc1dac1, 0x3eb16449, 0x6f987e76, + 0x3efb3f01, 0x6f6ee0b9, 0x3f451b3d, 0x6f45018b, 0x3f8ef874, 0x6f1ae0eb, 0x3fd8d620, 0x6ef07edb, + 0x4022b3b9, 0x6ec5db5d, 0x406c90b7, 0x6e9af675, 0x40b66c93, 0x6e6fd027, 0x410046c5, 0x6e446879, + 0x414a1ec6, 0x6e18bf71, 0x4193f40d, 0x6decd517, 0x41ddc615, 0x6dc0a972, 0x42279455, 0x6d943c8d, + 0x42715e45, 0x6d678e71, 0x42bb235f, 0x6d3a9f2a, 0x4304e31a, 0x6d0d6ec5, 0x434e9cf1, 0x6cdffd4f, + 0x4398505b, 0x6cb24ad6, 0x43e1fcd1, 0x6c84576b, 0x442ba1cd, 0x6c56231c, 0x44753ec7, 0x6c27adfd, + 0x44bed33a, 0x6bf8f81e, 0x45085e9d, 0x6bca0195, 0x4551e06b, 0x6b9aca75, 0x459b581e, 0x6b6b52d5, + 0x45e4c52f, 0x6b3b9ac9, 0x462e2717, 0x6b0ba26b, 0x46777d52, 0x6adb69d3, 0x46c0c75a, 0x6aaaf11b, + 0x470a04a9, 0x6a7a385c, 0x475334b9, 0x6a493fb3, 0x479c5707, 0x6a18073d, 0x47e56b0c, 0x69e68f17, + 0x482e7045, 0x69b4d761, 0x4877662c, 0x6982e039, 0x48c04c3f, 0x6950a9c0, 0x490921f8, 0x691e341a, + 0x4951e6d5, 0x68eb7f67, 0x499a9a51, 0x68b88bcd, 0x49e33beb, 0x68855970, 0x4a2bcb1f, 0x6851e875, + 0x4a74476b, 0x681e3905, 0x4abcb04c, 0x67ea4b47, 0x4b050541, 0x67b61f63, 0x4b4d45c9, 0x6781b585, + 0x4b957162, 0x674d0dd6, 0x4bdd878c, 0x67182883, 0x4c2587c6, 0x66e305b8, 0x4c6d7190, 0x66ada5a5, + 0x4cb5446a, 0x66780878, 0x4cfcffd5, 0x66422e60, 0x4d44a353, 0x660c1790, 0x4d8c2e64, 0x65d5c439, + 0x4dd3a08c, 0x659f348e, 0x4e1af94b, 0x656868c3, 0x4e623825, 0x6531610d, 0x4ea95c9d, 0x64fa1da3, + 0x4ef06637, 0x64c29ebb, 0x4f375477, 0x648ae48d, 0x4f7e26e1, 0x6452ef53, 0x4fc4dcfb, 0x641abf46, + 0x500b7649, 0x63e254a2, 0x5051f253, 0x63a9afa2, 0x5098509f, 0x6370d083, 0x50de90b3, 0x6337b784, + 0x5124b218, 0x62fe64e3, 0x516ab455, 0x62c4d8e0, 0x51b096f3, 0x628b13bc, 0x51f6597b, 0x625115b8, + 0x523bfb78, 0x6216df18, 0x52817c72, 0x61dc701f, 0x52c6dbf5, 0x61a1c912, 0x530c198d, 0x6166ea36, + 0x535134c5, 0x612bd3d2, 0x53962d2a, 0x60f0862d, 0x53db024a, 0x60b50190, 0x541fb3b1, 0x60794644, + 0x546440ef, 0x603d5494, 0x54a8a992, 0x60012cca, 0x54eced2b, 0x5fc4cf33, 0x55310b48, 0x5f883c1c, + 0x5575037c, 0x5f4b73d2, 0x55b8d558, 0x5f0e76a5, 0x55fc806f, 0x5ed144e5, 0x56400452, 0x5e93dee1, + 0x56836096, 0x5e5644ec, 0x56c694cf, 0x5e187757, 0x5709a092, 0x5dda7677, 0x574c8374, 0x5d9c429f, + 0x578f3d0d, 0x5d5ddc24, 0x57d1ccf2, 0x5d1f435d, 0x581432bd, 0x5ce078a0, 0x58566e04, 0x5ca17c45, + 0x58987e63, 0x5c624ea4, 0x58da6372, 0x5c22f016, 0x591c1ccc, 0x5be360f6, 0x595daa0d, 0x5ba3a19f, + 0x599f0ad1, 0x5b63b26c, 0x59e03eb6, 0x5b2393ba, 0x5a214558, 0x5ae345e7, 0x5a621e56, 0x5aa2c951, }; /* bit reverse tables for FFT */ -const int bitrevtabOffset[NUM_IMDCT_SIZES] PROGMEM = {0, 17}; +const int bitrevtabOffset[NUM_IMDCT_SIZES] DPROGMEM = {0, 17}; -const unsigned char bitrevtab[17 + 129] PROGMEM = { -/* nfft = 64 */ -0x01, 0x08, 0x02, 0x04, 0x03, 0x0c, 0x05, 0x0a, 0x07, 0x0e, 0x0b, 0x0d, 0x00, 0x06, 0x09, 0x0f, -0x00, +const unsigned char bitrevtab[17 + 129] DPROGMEM = { + /* nfft = 64 */ + 0x01, 0x08, 0x02, 0x04, 0x03, 0x0c, 0x05, 0x0a, 0x07, 0x0e, 0x0b, 0x0d, 0x00, 0x06, 0x09, 0x0f, + 0x00, -/* nfft = 512 */ -0x01, 0x40, 0x02, 0x20, 0x03, 0x60, 0x04, 0x10, 0x05, 0x50, 0x06, 0x30, 0x07, 0x70, 0x09, 0x48, -0x0a, 0x28, 0x0b, 0x68, 0x0c, 0x18, 0x0d, 0x58, 0x0e, 0x38, 0x0f, 0x78, 0x11, 0x44, 0x12, 0x24, -0x13, 0x64, 0x15, 0x54, 0x16, 0x34, 0x17, 0x74, 0x19, 0x4c, 0x1a, 0x2c, 0x1b, 0x6c, 0x1d, 0x5c, -0x1e, 0x3c, 0x1f, 0x7c, 0x21, 0x42, 0x23, 0x62, 0x25, 0x52, 0x26, 0x32, 0x27, 0x72, 0x29, 0x4a, -0x2b, 0x6a, 0x2d, 0x5a, 0x2e, 0x3a, 0x2f, 0x7a, 0x31, 0x46, 0x33, 0x66, 0x35, 0x56, 0x37, 0x76, -0x39, 0x4e, 0x3b, 0x6e, 0x3d, 0x5e, 0x3f, 0x7e, 0x43, 0x61, 0x45, 0x51, 0x47, 0x71, 0x4b, 0x69, -0x4d, 0x59, 0x4f, 0x79, 0x53, 0x65, 0x57, 0x75, 0x5b, 0x6d, 0x5f, 0x7d, 0x67, 0x73, 0x6f, 0x7b, -0x00, 0x08, 0x14, 0x1c, 0x22, 0x2a, 0x36, 0x3e, 0x41, 0x49, 0x55, 0x5d, 0x63, 0x6b, 0x77, 0x7f, -0x00, + /* nfft = 512 */ + 0x01, 0x40, 0x02, 0x20, 0x03, 0x60, 0x04, 0x10, 0x05, 0x50, 0x06, 0x30, 0x07, 0x70, 0x09, 0x48, + 0x0a, 0x28, 0x0b, 0x68, 0x0c, 0x18, 0x0d, 0x58, 0x0e, 0x38, 0x0f, 0x78, 0x11, 0x44, 0x12, 0x24, + 0x13, 0x64, 0x15, 0x54, 0x16, 0x34, 0x17, 0x74, 0x19, 0x4c, 0x1a, 0x2c, 0x1b, 0x6c, 0x1d, 0x5c, + 0x1e, 0x3c, 0x1f, 0x7c, 0x21, 0x42, 0x23, 0x62, 0x25, 0x52, 0x26, 0x32, 0x27, 0x72, 0x29, 0x4a, + 0x2b, 0x6a, 0x2d, 0x5a, 0x2e, 0x3a, 0x2f, 0x7a, 0x31, 0x46, 0x33, 0x66, 0x35, 0x56, 0x37, 0x76, + 0x39, 0x4e, 0x3b, 0x6e, 0x3d, 0x5e, 0x3f, 0x7e, 0x43, 0x61, 0x45, 0x51, 0x47, 0x71, 0x4b, 0x69, + 0x4d, 0x59, 0x4f, 0x79, 0x53, 0x65, 0x57, 0x75, 0x5b, 0x6d, 0x5f, 0x7d, 0x67, 0x73, 0x6f, 0x7b, + 0x00, 0x08, 0x14, 0x1c, 0x22, 0x2a, 0x36, 0x3e, 0x41, 0x49, 0x55, 0x5d, 0x63, 0x6b, 0x77, 0x7f, + 0x00, }; -const unsigned char uniqueIDTab[8] = {0x5f, 0x4b, 0x43, 0x5f, 0x5f, 0x4a, 0x52, 0x5f}; - -/* Twiddle tables for FFT - * format = Q30 - * - * for (k = 4; k <= N/4; k <<= 1) { - * for (j = 0; j < k; j++) { - * double wr1, wi1, wr2, wi2, wr3, wi3; - * - * wr1 = cos(1.0 * M_PI * j / (2*k)); - * wi1 = sin(1.0 * M_PI * j / (2*k)); - * wr1 = (wr1 + wi1); - * wi1 = -wi1; - * - * wr2 = cos(2.0 * M_PI * j / (2*k)); - * wi2 = sin(2.0 * M_PI * j / (2*k)); - * wr2 = (wr2 + wi2); - * wi2 = -wi2; - * - * wr3 = cos(3.0 * M_PI * j / (2*k)); - * wi3 = sin(3.0 * M_PI * j / (2*k)); - * wr3 = (wr3 + wi3); - * wi3 = -wi3; - * - * if (k & 0xaaaaaaaa) { - * w_odd[iodd++] = (float)wr2; - * w_odd[iodd++] = (float)wi2; - * w_odd[iodd++] = (float)wr1; - * w_odd[iodd++] = (float)wi1; - * w_odd[iodd++] = (float)wr3; - * w_odd[iodd++] = (float)wi3; - * } else { - * w_even[ieven++] = (float)wr2; - * w_even[ieven++] = (float)wi2; - * w_even[ieven++] = (float)wr1; - * w_even[ieven++] = (float)wi1; - * w_even[ieven++] = (float)wr3; - * w_even[ieven++] = (float)wi3; - * } - * } - * } - */ -const int twidTabOdd[8*6 + 32*6 + 128*6] PROGMEM = { - 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x539eba45, 0xe7821d59, - 0x4b418bbe, 0xf383a3e2, 0x58c542c5, 0xdc71898d, 0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59, - 0x539eba45, 0xc4df2862, 0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d, 0x3248d382, 0xc13ad060, - 0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x22a2f4f8, 0xc4df2862, - 0x58c542c5, 0xcac933ae, 0xcdb72c7e, 0xf383a3e2, 0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, - 0xac6145bb, 0x187de2a7, 0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060, 0xa73abd3b, 0x3536cc52, - - 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x45f704f7, 0xf9ba1651, - 0x43103085, 0xfcdc1342, 0x48b2b335, 0xf69bf7c9, 0x4b418bbe, 0xf383a3e2, 0x45f704f7, 0xf9ba1651, - 0x4fd288dc, 0xed6bf9d1, 0x4fd288dc, 0xed6bf9d1, 0x48b2b335, 0xf69bf7c9, 0x553805f2, 0xe4a2eff6, - 0x539eba45, 0xe7821d59, 0x4b418bbe, 0xf383a3e2, 0x58c542c5, 0xdc71898d, 0x569cc31b, 0xe1d4a2c8, - 0x4da1fab5, 0xf0730342, 0x5a6690ae, 0xd5052d97, 0x58c542c5, 0xdc71898d, 0x4fd288dc, 0xed6bf9d1, - 0x5a12e720, 0xce86ff2a, 0x5a12e720, 0xd76619b6, 0x51d1dc80, 0xea70658a, 0x57cc15bc, 0xc91af976, - 0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59, 0x539eba45, 0xc4df2862, 0x5a12e720, 0xce86ff2a, - 0x553805f2, 0xe4a2eff6, 0x4da1fab5, 0xc1eb0209, 0x58c542c5, 0xcac933ae, 0x569cc31b, 0xe1d4a2c8, - 0x45f704f7, 0xc04ee4b8, 0x569cc31b, 0xc78e9a1d, 0x57cc15bc, 0xdf18f0ce, 0x3cc85709, 0xc013bc39, - 0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d, 0x3248d382, 0xc13ad060, 0x4fd288dc, 0xc2c17d52, - 0x5987b08a, 0xd9e01006, 0x26b2a794, 0xc3bdbdf6, 0x4b418bbe, 0xc13ad060, 0x5a12e720, 0xd76619b6, - 0x1a4608ab, 0xc78e9a1d, 0x45f704f7, 0xc04ee4b8, 0x5a6690ae, 0xd5052d97, 0x0d47d096, 0xcc983f70, - 0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x396b3199, 0xc04ee4b8, - 0x5a6690ae, 0xd09441bb, 0xf2b82f6a, 0xd9e01006, 0x3248d382, 0xc13ad060, 0x5a12e720, 0xce86ff2a, - 0xe5b9f755, 0xe1d4a2c8, 0x2aaa7c7f, 0xc2c17d52, 0x5987b08a, 0xcc983f70, 0xd94d586c, 0xea70658a, - 0x22a2f4f8, 0xc4df2862, 0x58c542c5, 0xcac933ae, 0xcdb72c7e, 0xf383a3e2, 0x1a4608ab, 0xc78e9a1d, - 0x57cc15bc, 0xc91af976, 0xc337a8f7, 0xfcdc1342, 0x11a855df, 0xcac933ae, 0x569cc31b, 0xc78e9a1d, - 0xba08fb09, 0x0645e9af, 0x08df1a8c, 0xce86ff2a, 0x553805f2, 0xc6250a18, 0xb25e054b, 0x0f8cfcbe, - 0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, 0xac6145bb, 0x187de2a7, 0xf720e574, 0xd76619b6, - 0x51d1dc80, 0xc3bdbdf6, 0xa833ea44, 0x20e70f32, 0xee57aa21, 0xdc71898d, 0x4fd288dc, 0xc2c17d52, - 0xa5ed18e0, 0x2899e64a, 0xe5b9f755, 0xe1d4a2c8, 0x4da1fab5, 0xc1eb0209, 0xa5996f52, 0x2f6bbe45, - 0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060, 0xa73abd3b, 0x3536cc52, 0xd5558381, 0xed6bf9d1, - 0x48b2b335, 0xc0b15502, 0xaac7fa0e, 0x39daf5e8, 0xcdb72c7e, 0xf383a3e2, 0x45f704f7, 0xc04ee4b8, - 0xb02d7724, 0x3d3e82ae, 0xc694ce67, 0xf9ba1651, 0x43103085, 0xc013bc39, 0xb74d4ccb, 0x3f4eaafe, - - 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x418d2621, 0xfe6deaa1, - 0x40c7d2bd, 0xff36f170, 0x424ff28f, 0xfda4f351, 0x43103085, 0xfcdc1342, 0x418d2621, 0xfe6deaa1, - 0x4488e37f, 0xfb4ab7db, 0x4488e37f, 0xfb4ab7db, 0x424ff28f, 0xfda4f351, 0x46aa0d6d, 0xf8f21e8e, - 0x45f704f7, 0xf9ba1651, 0x43103085, 0xfcdc1342, 0x48b2b335, 0xf69bf7c9, 0x475a5c77, 0xf82a6c6a, - 0x43cdd89a, 0xfc135231, 0x4aa22036, 0xf4491311, 0x48b2b335, 0xf69bf7c9, 0x4488e37f, 0xfb4ab7db, - 0x4c77a88e, 0xf1fa3ecb, 0x49ffd417, 0xf50ef5de, 0x454149fc, 0xfa824bfd, 0x4e32a956, 0xefb047f2, - 0x4b418bbe, 0xf383a3e2, 0x45f704f7, 0xf9ba1651, 0x4fd288dc, 0xed6bf9d1, 0x4c77a88e, 0xf1fa3ecb, - 0x46aa0d6d, 0xf8f21e8e, 0x5156b6d9, 0xeb2e1dbe, 0x4da1fab5, 0xf0730342, 0x475a5c77, 0xf82a6c6a, - 0x52beac9f, 0xe8f77acf, 0x4ec05432, 0xeeee2d9d, 0x4807eb4b, 0xf7630799, 0x5409ed4b, 0xe6c8d59c, - 0x4fd288dc, 0xed6bf9d1, 0x48b2b335, 0xf69bf7c9, 0x553805f2, 0xe4a2eff6, 0x50d86e6d, 0xebeca36c, - 0x495aada2, 0xf5d544a7, 0x56488dc5, 0xe28688a4, 0x51d1dc80, 0xea70658a, 0x49ffd417, 0xf50ef5de, - 0x573b2635, 0xe0745b24, 0x52beac9f, 0xe8f77acf, 0x4aa22036, 0xf4491311, 0x580f7b19, 0xde6d1f65, - 0x539eba45, 0xe7821d59, 0x4b418bbe, 0xf383a3e2, 0x58c542c5, 0xdc71898d, 0x5471e2e6, 0xe61086bc, - 0x4bde1089, 0xf2beafed, 0x595c3e2a, 0xda8249b4, 0x553805f2, 0xe4a2eff6, 0x4c77a88e, 0xf1fa3ecb, - 0x59d438e5, 0xd8a00bae, 0x55f104dc, 0xe3399167, 0x4d0e4de2, 0xf136580d, 0x5a2d0957, 0xd6cb76c9, - 0x569cc31b, 0xe1d4a2c8, 0x4da1fab5, 0xf0730342, 0x5a6690ae, 0xd5052d97, 0x573b2635, 0xe0745b24, - 0x4e32a956, 0xefb047f2, 0x5a80baf6, 0xd34dcdb4, 0x57cc15bc, 0xdf18f0ce, 0x4ec05432, 0xeeee2d9d, - 0x5a7b7f1a, 0xd1a5ef90, 0x584f7b58, 0xddc29958, 0x4f4af5d1, 0xee2cbbc1, 0x5a56deec, 0xd00e2639, - 0x58c542c5, 0xdc71898d, 0x4fd288dc, 0xed6bf9d1, 0x5a12e720, 0xce86ff2a, 0x592d59da, 0xdb25f566, - 0x50570819, 0xecabef3d, 0x59afaf4c, 0xcd110216, 0x5987b08a, 0xd9e01006, 0x50d86e6d, 0xebeca36c, - 0x592d59da, 0xcbacb0bf, 0x59d438e5, 0xd8a00bae, 0x5156b6d9, 0xeb2e1dbe, 0x588c1404, 0xca5a86c4, - 0x5a12e720, 0xd76619b6, 0x51d1dc80, 0xea70658a, 0x57cc15bc, 0xc91af976, 0x5a43b190, 0xd6326a88, - 0x5249daa2, 0xe9b38223, 0x56eda1a0, 0xc7ee77b3, 0x5a6690ae, 0xd5052d97, 0x52beac9f, 0xe8f77acf, - 0x55f104dc, 0xc6d569be, 0x5a7b7f1a, 0xd3de9156, 0x53304df6, 0xe83c56cf, 0x54d69714, 0xc5d03118, - 0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59, 0x539eba45, 0xc4df2862, 0x5a7b7f1a, 0xd1a5ef90, - 0x5409ed4b, 0xe6c8d59c, 0x5249daa2, 0xc402a33c, 0x5a6690ae, 0xd09441bb, 0x5471e2e6, 0xe61086bc, - 0x50d86e6d, 0xc33aee27, 0x5a43b190, 0xcf89e3e8, 0x54d69714, 0xe55937d5, 0x4f4af5d1, 0xc2884e6e, - 0x5a12e720, 0xce86ff2a, 0x553805f2, 0xe4a2eff6, 0x4da1fab5, 0xc1eb0209, 0x59d438e5, 0xcd8bbb6d, - 0x55962bc0, 0xe3edb628, 0x4bde1089, 0xc1633f8a, 0x5987b08a, 0xcc983f70, 0x55f104dc, 0xe3399167, - 0x49ffd417, 0xc0f1360b, 0x592d59da, 0xcbacb0bf, 0x56488dc5, 0xe28688a4, 0x4807eb4b, 0xc0950d1d, - 0x58c542c5, 0xcac933ae, 0x569cc31b, 0xe1d4a2c8, 0x45f704f7, 0xc04ee4b8, 0x584f7b58, 0xc9edeb50, - 0x56eda1a0, 0xe123e6ad, 0x43cdd89a, 0xc01ed535, 0x57cc15bc, 0xc91af976, 0x573b2635, 0xe0745b24, - 0x418d2621, 0xc004ef3f, 0x573b2635, 0xc8507ea7, 0x57854ddd, 0xdfc606f1, 0x3f35b59d, 0xc0013bd3, - 0x569cc31b, 0xc78e9a1d, 0x57cc15bc, 0xdf18f0ce, 0x3cc85709, 0xc013bc39, 0x55f104dc, 0xc6d569be, - 0x580f7b19, 0xde6d1f65, 0x3a45e1f7, 0xc03c6a07, 0x553805f2, 0xc6250a18, 0x584f7b58, 0xddc29958, - 0x37af354c, 0xc07b371e, 0x5471e2e6, 0xc57d965d, 0x588c1404, 0xdd196538, 0x350536f1, 0xc0d00db6, - 0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d, 0x3248d382, 0xc13ad060, 0x52beac9f, 0xc449d892, - 0x58fb0568, 0xdbcb0cce, 0x2f7afdfc, 0xc1bb5a11, 0x51d1dc80, 0xc3bdbdf6, 0x592d59da, 0xdb25f566, - 0x2c9caf6c, 0xc2517e31, 0x50d86e6d, 0xc33aee27, 0x595c3e2a, 0xda8249b4, 0x29aee694, 0xc2fd08a9, - 0x4fd288dc, 0xc2c17d52, 0x5987b08a, 0xd9e01006, 0x26b2a794, 0xc3bdbdf6, 0x4ec05432, 0xc2517e31, - 0x59afaf4c, 0xd93f4e9e, 0x23a8fb93, 0xc4935b3c, 0x4da1fab5, 0xc1eb0209, 0x59d438e5, 0xd8a00bae, - 0x2092f05f, 0xc57d965d, 0x4c77a88e, 0xc18e18a7, 0x59f54bee, 0xd8024d59, 0x1d719810, 0xc67c1e18, - 0x4b418bbe, 0xc13ad060, 0x5a12e720, 0xd76619b6, 0x1a4608ab, 0xc78e9a1d, 0x49ffd417, 0xc0f1360b, - 0x5a2d0957, 0xd6cb76c9, 0x17115bc0, 0xc8b4ab32, 0x48b2b335, 0xc0b15502, 0x5a43b190, 0xd6326a88, - 0x13d4ae08, 0xc9edeb50, 0x475a5c77, 0xc07b371e, 0x5a56deec, 0xd59afadb, 0x10911f04, 0xcb39edca, - 0x45f704f7, 0xc04ee4b8, 0x5a6690ae, 0xd5052d97, 0x0d47d096, 0xcc983f70, 0x4488e37f, 0xc02c64a6, - 0x5a72c63b, 0xd4710883, 0x09f9e6a1, 0xce0866b8, 0x43103085, 0xc013bc39, 0x5a7b7f1a, 0xd3de9156, - 0x06a886a0, 0xcf89e3e8, 0x418d2621, 0xc004ef3f, 0x5a80baf6, 0xd34dcdb4, 0x0354d741, 0xd11c3142, - 0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x3e68fb62, 0xc004ef3f, - 0x5a80baf6, 0xd2317756, 0xfcab28bf, 0xd4710883, 0x3cc85709, 0xc013bc39, 0x5a7b7f1a, 0xd1a5ef90, - 0xf9577960, 0xd6326a88, 0x3b1e5335, 0xc02c64a6, 0x5a72c63b, 0xd11c3142, 0xf606195f, 0xd8024d59, - 0x396b3199, 0xc04ee4b8, 0x5a6690ae, 0xd09441bb, 0xf2b82f6a, 0xd9e01006, 0x37af354c, 0xc07b371e, - 0x5a56deec, 0xd00e2639, 0xef6ee0fc, 0xdbcb0cce, 0x35eaa2c7, 0xc0b15502, 0x5a43b190, 0xcf89e3e8, - 0xec2b51f8, 0xddc29958, 0x341dbfd3, 0xc0f1360b, 0x5a2d0957, 0xcf077fe1, 0xe8eea440, 0xdfc606f1, - 0x3248d382, 0xc13ad060, 0x5a12e720, 0xce86ff2a, 0xe5b9f755, 0xe1d4a2c8, 0x306c2624, 0xc18e18a7, - 0x59f54bee, 0xce0866b8, 0xe28e67f0, 0xe3edb628, 0x2e88013a, 0xc1eb0209, 0x59d438e5, 0xcd8bbb6d, - 0xdf6d0fa1, 0xe61086bc, 0x2c9caf6c, 0xc2517e31, 0x59afaf4c, 0xcd110216, 0xdc57046d, 0xe83c56cf, - 0x2aaa7c7f, 0xc2c17d52, 0x5987b08a, 0xcc983f70, 0xd94d586c, 0xea70658a, 0x28b1b544, 0xc33aee27, - 0x595c3e2a, 0xcc217822, 0xd651196c, 0xecabef3d, 0x26b2a794, 0xc3bdbdf6, 0x592d59da, 0xcbacb0bf, - 0xd3635094, 0xeeee2d9d, 0x24ada23d, 0xc449d892, 0x58fb0568, 0xcb39edca, 0xd0850204, 0xf136580d, - 0x22a2f4f8, 0xc4df2862, 0x58c542c5, 0xcac933ae, 0xcdb72c7e, 0xf383a3e2, 0x2092f05f, 0xc57d965d, - 0x588c1404, 0xca5a86c4, 0xcafac90f, 0xf5d544a7, 0x1e7de5df, 0xc6250a18, 0x584f7b58, 0xc9edeb50, - 0xc850cab4, 0xf82a6c6a, 0x1c6427a9, 0xc6d569be, 0x580f7b19, 0xc9836582, 0xc5ba1e09, 0xfa824bfd, - 0x1a4608ab, 0xc78e9a1d, 0x57cc15bc, 0xc91af976, 0xc337a8f7, 0xfcdc1342, 0x1823dc7d, 0xc8507ea7, - 0x57854ddd, 0xc8b4ab32, 0xc0ca4a63, 0xff36f170, 0x15fdf758, 0xc91af976, 0x573b2635, 0xc8507ea7, - 0xbe72d9df, 0x0192155f, 0x13d4ae08, 0xc9edeb50, 0x56eda1a0, 0xc7ee77b3, 0xbc322766, 0x03ecadcf, - 0x11a855df, 0xcac933ae, 0x569cc31b, 0xc78e9a1d, 0xba08fb09, 0x0645e9af, 0x0f7944a7, 0xcbacb0bf, - 0x56488dc5, 0xc730e997, 0xb7f814b5, 0x089cf867, 0x0d47d096, 0xcc983f70, 0x55f104dc, 0xc6d569be, - 0xb6002be9, 0x0af10a22, 0x0b145041, 0xcd8bbb6d, 0x55962bc0, 0xc67c1e18, 0xb421ef77, 0x0d415013, - 0x08df1a8c, 0xce86ff2a, 0x553805f2, 0xc6250a18, 0xb25e054b, 0x0f8cfcbe, 0x06a886a0, 0xcf89e3e8, - 0x54d69714, 0xc5d03118, 0xb0b50a2f, 0x11d3443f, 0x0470ebdc, 0xd09441bb, 0x5471e2e6, 0xc57d965d, - 0xaf279193, 0x14135c94, 0x0238a1c6, 0xd1a5ef90, 0x5409ed4b, 0xc52d3d18, 0xadb6255e, 0x164c7ddd, - 0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, 0xac6145bb, 0x187de2a7, 0xfdc75e3a, 0xd3de9156, - 0x53304df6, 0xc4935b3c, 0xab2968ec, 0x1aa6c82b, 0xfb8f1424, 0xd5052d97, 0x52beac9f, 0xc449d892, - 0xaa0efb24, 0x1cc66e99, 0xf9577960, 0xd6326a88, 0x5249daa2, 0xc402a33c, 0xa9125e60, 0x1edc1953, - 0xf720e574, 0xd76619b6, 0x51d1dc80, 0xc3bdbdf6, 0xa833ea44, 0x20e70f32, 0xf4ebafbf, 0xd8a00bae, - 0x5156b6d9, 0xc37b2b6a, 0xa773ebfc, 0x22e69ac8, 0xf2b82f6a, 0xd9e01006, 0x50d86e6d, 0xc33aee27, - 0xa6d2a626, 0x24da0a9a, 0xf086bb59, 0xdb25f566, 0x50570819, 0xc2fd08a9, 0xa65050b4, 0x26c0b162, - 0xee57aa21, 0xdc71898d, 0x4fd288dc, 0xc2c17d52, 0xa5ed18e0, 0x2899e64a, 0xec2b51f8, 0xddc29958, - 0x4f4af5d1, 0xc2884e6e, 0xa5a92114, 0x2a650525, 0xea0208a8, 0xdf18f0ce, 0x4ec05432, 0xc2517e31, - 0xa58480e6, 0x2c216eaa, 0xe7dc2383, 0xe0745b24, 0x4e32a956, 0xc21d0eb8, 0xa57f450a, 0x2dce88aa, - 0xe5b9f755, 0xe1d4a2c8, 0x4da1fab5, 0xc1eb0209, 0xa5996f52, 0x2f6bbe45, 0xe39bd857, 0xe3399167, - 0x4d0e4de2, 0xc1bb5a11, 0xa5d2f6a9, 0x30f8801f, 0xe1821a21, 0xe4a2eff6, 0x4c77a88e, 0xc18e18a7, - 0xa62bc71b, 0x32744493, 0xdf6d0fa1, 0xe61086bc, 0x4bde1089, 0xc1633f8a, 0xa6a3c1d6, 0x33de87de, - 0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060, 0xa73abd3b, 0x3536cc52, 0xdb525dc3, 0xe8f77acf, - 0x4aa22036, 0xc114ccb9, 0xa7f084e7, 0x367c9a7e, 0xd94d586c, 0xea70658a, 0x49ffd417, 0xc0f1360b, - 0xa8c4d9cb, 0x37af8159, 0xd74e4abc, 0xebeca36c, 0x495aada2, 0xc0d00db6, 0xa9b7723b, 0x38cf1669, - 0xd5558381, 0xed6bf9d1, 0x48b2b335, 0xc0b15502, 0xaac7fa0e, 0x39daf5e8, 0xd3635094, 0xeeee2d9d, - 0x4807eb4b, 0xc0950d1d, 0xabf612b5, 0x3ad2c2e8, 0xd177fec6, 0xf0730342, 0x475a5c77, 0xc07b371e, - 0xad415361, 0x3bb6276e, 0xcf93d9dc, 0xf1fa3ecb, 0x46aa0d6d, 0xc063d405, 0xaea94927, 0x3c84d496, - 0xcdb72c7e, 0xf383a3e2, 0x45f704f7, 0xc04ee4b8, 0xb02d7724, 0x3d3e82ae, 0xcbe2402d, 0xf50ef5de, - 0x454149fc, 0xc03c6a07, 0xb1cd56aa, 0x3de2f148, 0xca155d39, 0xf69bf7c9, 0x4488e37f, 0xc02c64a6, - 0xb3885772, 0x3e71e759, 0xc850cab4, 0xf82a6c6a, 0x43cdd89a, 0xc01ed535, 0xb55ddfca, 0x3eeb3347, - 0xc694ce67, 0xf9ba1651, 0x43103085, 0xc013bc39, 0xb74d4ccb, 0x3f4eaafe, 0xc4e1accb, 0xfb4ab7db, - 0x424ff28f, 0xc00b1a20, 0xb955f293, 0x3f9c2bfb, 0xc337a8f7, 0xfcdc1342, 0x418d2621, 0xc004ef3f, - 0xbb771c81, 0x3fd39b5a, 0xc197049e, 0xfe6deaa1, 0x40c7d2bd, 0xc0013bd3, 0xbdb00d71, 0x3ff4e5e0, +const unsigned char uniqueIDTab[8] DPROGMEM = {0x5f, 0x4b, 0x43, 0x5f, 0x5f, 0x4a, 0x52, 0x5f}; + +/* Twiddle tables for FFT + format = Q30 + + for (k = 4; k <= N/4; k <<= 1) { + for (j = 0; j < k; j++) { + double wr1, wi1, wr2, wi2, wr3, wi3; + + wr1 = cos(1.0 * M_PI * j / (2*k)); + wi1 = sin(1.0 * M_PI * j / (2*k)); + wr1 = (wr1 + wi1); + wi1 = -wi1; + + wr2 = cos(2.0 * M_PI * j / (2*k)); + wi2 = sin(2.0 * M_PI * j / (2*k)); + wr2 = (wr2 + wi2); + wi2 = -wi2; + + wr3 = cos(3.0 * M_PI * j / (2*k)); + wi3 = sin(3.0 * M_PI * j / (2*k)); + wr3 = (wr3 + wi3); + wi3 = -wi3; + + if (k & 0xaaaaaaaa) { + w_odd[iodd++] = (float)wr2; + w_odd[iodd++] = (float)wi2; + w_odd[iodd++] = (float)wr1; + w_odd[iodd++] = (float)wi1; + w_odd[iodd++] = (float)wr3; + w_odd[iodd++] = (float)wi3; + } else { + w_even[ieven++] = (float)wr2; + w_even[ieven++] = (float)wi2; + w_even[ieven++] = (float)wr1; + w_even[ieven++] = (float)wi1; + w_even[ieven++] = (float)wr3; + w_even[ieven++] = (float)wi3; + } + } + } +*/ +const int twidTabOdd[8 * 6 + 32 * 6 + 128 * 6] DPROGMEM = { + 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x539eba45, 0xe7821d59, + 0x4b418bbe, 0xf383a3e2, 0x58c542c5, 0xdc71898d, 0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59, + 0x539eba45, 0xc4df2862, 0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d, 0x3248d382, 0xc13ad060, + 0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x22a2f4f8, 0xc4df2862, + 0x58c542c5, 0xcac933ae, 0xcdb72c7e, 0xf383a3e2, 0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, + 0xac6145bb, 0x187de2a7, 0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060, 0xa73abd3b, 0x3536cc52, + + 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x45f704f7, 0xf9ba1651, + 0x43103085, 0xfcdc1342, 0x48b2b335, 0xf69bf7c9, 0x4b418bbe, 0xf383a3e2, 0x45f704f7, 0xf9ba1651, + 0x4fd288dc, 0xed6bf9d1, 0x4fd288dc, 0xed6bf9d1, 0x48b2b335, 0xf69bf7c9, 0x553805f2, 0xe4a2eff6, + 0x539eba45, 0xe7821d59, 0x4b418bbe, 0xf383a3e2, 0x58c542c5, 0xdc71898d, 0x569cc31b, 0xe1d4a2c8, + 0x4da1fab5, 0xf0730342, 0x5a6690ae, 0xd5052d97, 0x58c542c5, 0xdc71898d, 0x4fd288dc, 0xed6bf9d1, + 0x5a12e720, 0xce86ff2a, 0x5a12e720, 0xd76619b6, 0x51d1dc80, 0xea70658a, 0x57cc15bc, 0xc91af976, + 0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59, 0x539eba45, 0xc4df2862, 0x5a12e720, 0xce86ff2a, + 0x553805f2, 0xe4a2eff6, 0x4da1fab5, 0xc1eb0209, 0x58c542c5, 0xcac933ae, 0x569cc31b, 0xe1d4a2c8, + 0x45f704f7, 0xc04ee4b8, 0x569cc31b, 0xc78e9a1d, 0x57cc15bc, 0xdf18f0ce, 0x3cc85709, 0xc013bc39, + 0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d, 0x3248d382, 0xc13ad060, 0x4fd288dc, 0xc2c17d52, + 0x5987b08a, 0xd9e01006, 0x26b2a794, 0xc3bdbdf6, 0x4b418bbe, 0xc13ad060, 0x5a12e720, 0xd76619b6, + 0x1a4608ab, 0xc78e9a1d, 0x45f704f7, 0xc04ee4b8, 0x5a6690ae, 0xd5052d97, 0x0d47d096, 0xcc983f70, + 0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x396b3199, 0xc04ee4b8, + 0x5a6690ae, 0xd09441bb, 0xf2b82f6a, 0xd9e01006, 0x3248d382, 0xc13ad060, 0x5a12e720, 0xce86ff2a, + 0xe5b9f755, 0xe1d4a2c8, 0x2aaa7c7f, 0xc2c17d52, 0x5987b08a, 0xcc983f70, 0xd94d586c, 0xea70658a, + 0x22a2f4f8, 0xc4df2862, 0x58c542c5, 0xcac933ae, 0xcdb72c7e, 0xf383a3e2, 0x1a4608ab, 0xc78e9a1d, + 0x57cc15bc, 0xc91af976, 0xc337a8f7, 0xfcdc1342, 0x11a855df, 0xcac933ae, 0x569cc31b, 0xc78e9a1d, + 0xba08fb09, 0x0645e9af, 0x08df1a8c, 0xce86ff2a, 0x553805f2, 0xc6250a18, 0xb25e054b, 0x0f8cfcbe, + 0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, 0xac6145bb, 0x187de2a7, 0xf720e574, 0xd76619b6, + 0x51d1dc80, 0xc3bdbdf6, 0xa833ea44, 0x20e70f32, 0xee57aa21, 0xdc71898d, 0x4fd288dc, 0xc2c17d52, + 0xa5ed18e0, 0x2899e64a, 0xe5b9f755, 0xe1d4a2c8, 0x4da1fab5, 0xc1eb0209, 0xa5996f52, 0x2f6bbe45, + 0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060, 0xa73abd3b, 0x3536cc52, 0xd5558381, 0xed6bf9d1, + 0x48b2b335, 0xc0b15502, 0xaac7fa0e, 0x39daf5e8, 0xcdb72c7e, 0xf383a3e2, 0x45f704f7, 0xc04ee4b8, + 0xb02d7724, 0x3d3e82ae, 0xc694ce67, 0xf9ba1651, 0x43103085, 0xc013bc39, 0xb74d4ccb, 0x3f4eaafe, + + 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x418d2621, 0xfe6deaa1, + 0x40c7d2bd, 0xff36f170, 0x424ff28f, 0xfda4f351, 0x43103085, 0xfcdc1342, 0x418d2621, 0xfe6deaa1, + 0x4488e37f, 0xfb4ab7db, 0x4488e37f, 0xfb4ab7db, 0x424ff28f, 0xfda4f351, 0x46aa0d6d, 0xf8f21e8e, + 0x45f704f7, 0xf9ba1651, 0x43103085, 0xfcdc1342, 0x48b2b335, 0xf69bf7c9, 0x475a5c77, 0xf82a6c6a, + 0x43cdd89a, 0xfc135231, 0x4aa22036, 0xf4491311, 0x48b2b335, 0xf69bf7c9, 0x4488e37f, 0xfb4ab7db, + 0x4c77a88e, 0xf1fa3ecb, 0x49ffd417, 0xf50ef5de, 0x454149fc, 0xfa824bfd, 0x4e32a956, 0xefb047f2, + 0x4b418bbe, 0xf383a3e2, 0x45f704f7, 0xf9ba1651, 0x4fd288dc, 0xed6bf9d1, 0x4c77a88e, 0xf1fa3ecb, + 0x46aa0d6d, 0xf8f21e8e, 0x5156b6d9, 0xeb2e1dbe, 0x4da1fab5, 0xf0730342, 0x475a5c77, 0xf82a6c6a, + 0x52beac9f, 0xe8f77acf, 0x4ec05432, 0xeeee2d9d, 0x4807eb4b, 0xf7630799, 0x5409ed4b, 0xe6c8d59c, + 0x4fd288dc, 0xed6bf9d1, 0x48b2b335, 0xf69bf7c9, 0x553805f2, 0xe4a2eff6, 0x50d86e6d, 0xebeca36c, + 0x495aada2, 0xf5d544a7, 0x56488dc5, 0xe28688a4, 0x51d1dc80, 0xea70658a, 0x49ffd417, 0xf50ef5de, + 0x573b2635, 0xe0745b24, 0x52beac9f, 0xe8f77acf, 0x4aa22036, 0xf4491311, 0x580f7b19, 0xde6d1f65, + 0x539eba45, 0xe7821d59, 0x4b418bbe, 0xf383a3e2, 0x58c542c5, 0xdc71898d, 0x5471e2e6, 0xe61086bc, + 0x4bde1089, 0xf2beafed, 0x595c3e2a, 0xda8249b4, 0x553805f2, 0xe4a2eff6, 0x4c77a88e, 0xf1fa3ecb, + 0x59d438e5, 0xd8a00bae, 0x55f104dc, 0xe3399167, 0x4d0e4de2, 0xf136580d, 0x5a2d0957, 0xd6cb76c9, + 0x569cc31b, 0xe1d4a2c8, 0x4da1fab5, 0xf0730342, 0x5a6690ae, 0xd5052d97, 0x573b2635, 0xe0745b24, + 0x4e32a956, 0xefb047f2, 0x5a80baf6, 0xd34dcdb4, 0x57cc15bc, 0xdf18f0ce, 0x4ec05432, 0xeeee2d9d, + 0x5a7b7f1a, 0xd1a5ef90, 0x584f7b58, 0xddc29958, 0x4f4af5d1, 0xee2cbbc1, 0x5a56deec, 0xd00e2639, + 0x58c542c5, 0xdc71898d, 0x4fd288dc, 0xed6bf9d1, 0x5a12e720, 0xce86ff2a, 0x592d59da, 0xdb25f566, + 0x50570819, 0xecabef3d, 0x59afaf4c, 0xcd110216, 0x5987b08a, 0xd9e01006, 0x50d86e6d, 0xebeca36c, + 0x592d59da, 0xcbacb0bf, 0x59d438e5, 0xd8a00bae, 0x5156b6d9, 0xeb2e1dbe, 0x588c1404, 0xca5a86c4, + 0x5a12e720, 0xd76619b6, 0x51d1dc80, 0xea70658a, 0x57cc15bc, 0xc91af976, 0x5a43b190, 0xd6326a88, + 0x5249daa2, 0xe9b38223, 0x56eda1a0, 0xc7ee77b3, 0x5a6690ae, 0xd5052d97, 0x52beac9f, 0xe8f77acf, + 0x55f104dc, 0xc6d569be, 0x5a7b7f1a, 0xd3de9156, 0x53304df6, 0xe83c56cf, 0x54d69714, 0xc5d03118, + 0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59, 0x539eba45, 0xc4df2862, 0x5a7b7f1a, 0xd1a5ef90, + 0x5409ed4b, 0xe6c8d59c, 0x5249daa2, 0xc402a33c, 0x5a6690ae, 0xd09441bb, 0x5471e2e6, 0xe61086bc, + 0x50d86e6d, 0xc33aee27, 0x5a43b190, 0xcf89e3e8, 0x54d69714, 0xe55937d5, 0x4f4af5d1, 0xc2884e6e, + 0x5a12e720, 0xce86ff2a, 0x553805f2, 0xe4a2eff6, 0x4da1fab5, 0xc1eb0209, 0x59d438e5, 0xcd8bbb6d, + 0x55962bc0, 0xe3edb628, 0x4bde1089, 0xc1633f8a, 0x5987b08a, 0xcc983f70, 0x55f104dc, 0xe3399167, + 0x49ffd417, 0xc0f1360b, 0x592d59da, 0xcbacb0bf, 0x56488dc5, 0xe28688a4, 0x4807eb4b, 0xc0950d1d, + 0x58c542c5, 0xcac933ae, 0x569cc31b, 0xe1d4a2c8, 0x45f704f7, 0xc04ee4b8, 0x584f7b58, 0xc9edeb50, + 0x56eda1a0, 0xe123e6ad, 0x43cdd89a, 0xc01ed535, 0x57cc15bc, 0xc91af976, 0x573b2635, 0xe0745b24, + 0x418d2621, 0xc004ef3f, 0x573b2635, 0xc8507ea7, 0x57854ddd, 0xdfc606f1, 0x3f35b59d, 0xc0013bd3, + 0x569cc31b, 0xc78e9a1d, 0x57cc15bc, 0xdf18f0ce, 0x3cc85709, 0xc013bc39, 0x55f104dc, 0xc6d569be, + 0x580f7b19, 0xde6d1f65, 0x3a45e1f7, 0xc03c6a07, 0x553805f2, 0xc6250a18, 0x584f7b58, 0xddc29958, + 0x37af354c, 0xc07b371e, 0x5471e2e6, 0xc57d965d, 0x588c1404, 0xdd196538, 0x350536f1, 0xc0d00db6, + 0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d, 0x3248d382, 0xc13ad060, 0x52beac9f, 0xc449d892, + 0x58fb0568, 0xdbcb0cce, 0x2f7afdfc, 0xc1bb5a11, 0x51d1dc80, 0xc3bdbdf6, 0x592d59da, 0xdb25f566, + 0x2c9caf6c, 0xc2517e31, 0x50d86e6d, 0xc33aee27, 0x595c3e2a, 0xda8249b4, 0x29aee694, 0xc2fd08a9, + 0x4fd288dc, 0xc2c17d52, 0x5987b08a, 0xd9e01006, 0x26b2a794, 0xc3bdbdf6, 0x4ec05432, 0xc2517e31, + 0x59afaf4c, 0xd93f4e9e, 0x23a8fb93, 0xc4935b3c, 0x4da1fab5, 0xc1eb0209, 0x59d438e5, 0xd8a00bae, + 0x2092f05f, 0xc57d965d, 0x4c77a88e, 0xc18e18a7, 0x59f54bee, 0xd8024d59, 0x1d719810, 0xc67c1e18, + 0x4b418bbe, 0xc13ad060, 0x5a12e720, 0xd76619b6, 0x1a4608ab, 0xc78e9a1d, 0x49ffd417, 0xc0f1360b, + 0x5a2d0957, 0xd6cb76c9, 0x17115bc0, 0xc8b4ab32, 0x48b2b335, 0xc0b15502, 0x5a43b190, 0xd6326a88, + 0x13d4ae08, 0xc9edeb50, 0x475a5c77, 0xc07b371e, 0x5a56deec, 0xd59afadb, 0x10911f04, 0xcb39edca, + 0x45f704f7, 0xc04ee4b8, 0x5a6690ae, 0xd5052d97, 0x0d47d096, 0xcc983f70, 0x4488e37f, 0xc02c64a6, + 0x5a72c63b, 0xd4710883, 0x09f9e6a1, 0xce0866b8, 0x43103085, 0xc013bc39, 0x5a7b7f1a, 0xd3de9156, + 0x06a886a0, 0xcf89e3e8, 0x418d2621, 0xc004ef3f, 0x5a80baf6, 0xd34dcdb4, 0x0354d741, 0xd11c3142, + 0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x3e68fb62, 0xc004ef3f, + 0x5a80baf6, 0xd2317756, 0xfcab28bf, 0xd4710883, 0x3cc85709, 0xc013bc39, 0x5a7b7f1a, 0xd1a5ef90, + 0xf9577960, 0xd6326a88, 0x3b1e5335, 0xc02c64a6, 0x5a72c63b, 0xd11c3142, 0xf606195f, 0xd8024d59, + 0x396b3199, 0xc04ee4b8, 0x5a6690ae, 0xd09441bb, 0xf2b82f6a, 0xd9e01006, 0x37af354c, 0xc07b371e, + 0x5a56deec, 0xd00e2639, 0xef6ee0fc, 0xdbcb0cce, 0x35eaa2c7, 0xc0b15502, 0x5a43b190, 0xcf89e3e8, + 0xec2b51f8, 0xddc29958, 0x341dbfd3, 0xc0f1360b, 0x5a2d0957, 0xcf077fe1, 0xe8eea440, 0xdfc606f1, + 0x3248d382, 0xc13ad060, 0x5a12e720, 0xce86ff2a, 0xe5b9f755, 0xe1d4a2c8, 0x306c2624, 0xc18e18a7, + 0x59f54bee, 0xce0866b8, 0xe28e67f0, 0xe3edb628, 0x2e88013a, 0xc1eb0209, 0x59d438e5, 0xcd8bbb6d, + 0xdf6d0fa1, 0xe61086bc, 0x2c9caf6c, 0xc2517e31, 0x59afaf4c, 0xcd110216, 0xdc57046d, 0xe83c56cf, + 0x2aaa7c7f, 0xc2c17d52, 0x5987b08a, 0xcc983f70, 0xd94d586c, 0xea70658a, 0x28b1b544, 0xc33aee27, + 0x595c3e2a, 0xcc217822, 0xd651196c, 0xecabef3d, 0x26b2a794, 0xc3bdbdf6, 0x592d59da, 0xcbacb0bf, + 0xd3635094, 0xeeee2d9d, 0x24ada23d, 0xc449d892, 0x58fb0568, 0xcb39edca, 0xd0850204, 0xf136580d, + 0x22a2f4f8, 0xc4df2862, 0x58c542c5, 0xcac933ae, 0xcdb72c7e, 0xf383a3e2, 0x2092f05f, 0xc57d965d, + 0x588c1404, 0xca5a86c4, 0xcafac90f, 0xf5d544a7, 0x1e7de5df, 0xc6250a18, 0x584f7b58, 0xc9edeb50, + 0xc850cab4, 0xf82a6c6a, 0x1c6427a9, 0xc6d569be, 0x580f7b19, 0xc9836582, 0xc5ba1e09, 0xfa824bfd, + 0x1a4608ab, 0xc78e9a1d, 0x57cc15bc, 0xc91af976, 0xc337a8f7, 0xfcdc1342, 0x1823dc7d, 0xc8507ea7, + 0x57854ddd, 0xc8b4ab32, 0xc0ca4a63, 0xff36f170, 0x15fdf758, 0xc91af976, 0x573b2635, 0xc8507ea7, + 0xbe72d9df, 0x0192155f, 0x13d4ae08, 0xc9edeb50, 0x56eda1a0, 0xc7ee77b3, 0xbc322766, 0x03ecadcf, + 0x11a855df, 0xcac933ae, 0x569cc31b, 0xc78e9a1d, 0xba08fb09, 0x0645e9af, 0x0f7944a7, 0xcbacb0bf, + 0x56488dc5, 0xc730e997, 0xb7f814b5, 0x089cf867, 0x0d47d096, 0xcc983f70, 0x55f104dc, 0xc6d569be, + 0xb6002be9, 0x0af10a22, 0x0b145041, 0xcd8bbb6d, 0x55962bc0, 0xc67c1e18, 0xb421ef77, 0x0d415013, + 0x08df1a8c, 0xce86ff2a, 0x553805f2, 0xc6250a18, 0xb25e054b, 0x0f8cfcbe, 0x06a886a0, 0xcf89e3e8, + 0x54d69714, 0xc5d03118, 0xb0b50a2f, 0x11d3443f, 0x0470ebdc, 0xd09441bb, 0x5471e2e6, 0xc57d965d, + 0xaf279193, 0x14135c94, 0x0238a1c6, 0xd1a5ef90, 0x5409ed4b, 0xc52d3d18, 0xadb6255e, 0x164c7ddd, + 0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, 0xac6145bb, 0x187de2a7, 0xfdc75e3a, 0xd3de9156, + 0x53304df6, 0xc4935b3c, 0xab2968ec, 0x1aa6c82b, 0xfb8f1424, 0xd5052d97, 0x52beac9f, 0xc449d892, + 0xaa0efb24, 0x1cc66e99, 0xf9577960, 0xd6326a88, 0x5249daa2, 0xc402a33c, 0xa9125e60, 0x1edc1953, + 0xf720e574, 0xd76619b6, 0x51d1dc80, 0xc3bdbdf6, 0xa833ea44, 0x20e70f32, 0xf4ebafbf, 0xd8a00bae, + 0x5156b6d9, 0xc37b2b6a, 0xa773ebfc, 0x22e69ac8, 0xf2b82f6a, 0xd9e01006, 0x50d86e6d, 0xc33aee27, + 0xa6d2a626, 0x24da0a9a, 0xf086bb59, 0xdb25f566, 0x50570819, 0xc2fd08a9, 0xa65050b4, 0x26c0b162, + 0xee57aa21, 0xdc71898d, 0x4fd288dc, 0xc2c17d52, 0xa5ed18e0, 0x2899e64a, 0xec2b51f8, 0xddc29958, + 0x4f4af5d1, 0xc2884e6e, 0xa5a92114, 0x2a650525, 0xea0208a8, 0xdf18f0ce, 0x4ec05432, 0xc2517e31, + 0xa58480e6, 0x2c216eaa, 0xe7dc2383, 0xe0745b24, 0x4e32a956, 0xc21d0eb8, 0xa57f450a, 0x2dce88aa, + 0xe5b9f755, 0xe1d4a2c8, 0x4da1fab5, 0xc1eb0209, 0xa5996f52, 0x2f6bbe45, 0xe39bd857, 0xe3399167, + 0x4d0e4de2, 0xc1bb5a11, 0xa5d2f6a9, 0x30f8801f, 0xe1821a21, 0xe4a2eff6, 0x4c77a88e, 0xc18e18a7, + 0xa62bc71b, 0x32744493, 0xdf6d0fa1, 0xe61086bc, 0x4bde1089, 0xc1633f8a, 0xa6a3c1d6, 0x33de87de, + 0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060, 0xa73abd3b, 0x3536cc52, 0xdb525dc3, 0xe8f77acf, + 0x4aa22036, 0xc114ccb9, 0xa7f084e7, 0x367c9a7e, 0xd94d586c, 0xea70658a, 0x49ffd417, 0xc0f1360b, + 0xa8c4d9cb, 0x37af8159, 0xd74e4abc, 0xebeca36c, 0x495aada2, 0xc0d00db6, 0xa9b7723b, 0x38cf1669, + 0xd5558381, 0xed6bf9d1, 0x48b2b335, 0xc0b15502, 0xaac7fa0e, 0x39daf5e8, 0xd3635094, 0xeeee2d9d, + 0x4807eb4b, 0xc0950d1d, 0xabf612b5, 0x3ad2c2e8, 0xd177fec6, 0xf0730342, 0x475a5c77, 0xc07b371e, + 0xad415361, 0x3bb6276e, 0xcf93d9dc, 0xf1fa3ecb, 0x46aa0d6d, 0xc063d405, 0xaea94927, 0x3c84d496, + 0xcdb72c7e, 0xf383a3e2, 0x45f704f7, 0xc04ee4b8, 0xb02d7724, 0x3d3e82ae, 0xcbe2402d, 0xf50ef5de, + 0x454149fc, 0xc03c6a07, 0xb1cd56aa, 0x3de2f148, 0xca155d39, 0xf69bf7c9, 0x4488e37f, 0xc02c64a6, + 0xb3885772, 0x3e71e759, 0xc850cab4, 0xf82a6c6a, 0x43cdd89a, 0xc01ed535, 0xb55ddfca, 0x3eeb3347, + 0xc694ce67, 0xf9ba1651, 0x43103085, 0xc013bc39, 0xb74d4ccb, 0x3f4eaafe, 0xc4e1accb, 0xfb4ab7db, + 0x424ff28f, 0xc00b1a20, 0xb955f293, 0x3f9c2bfb, 0xc337a8f7, 0xfcdc1342, 0x418d2621, 0xc004ef3f, + 0xbb771c81, 0x3fd39b5a, 0xc197049e, 0xfe6deaa1, 0x40c7d2bd, 0xc0013bd3, 0xbdb00d71, 0x3ff4e5e0, }; -const int twidTabEven[4*6 + 16*6 + 64*6] PROGMEM = { - 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x5a82799a, 0xd2bec333, - 0x539eba45, 0xe7821d59, 0x539eba45, 0xc4df2862, 0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, - 0x00000000, 0xd2bec333, 0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, 0xac6145bb, 0x187de2a7, - - 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x4b418bbe, 0xf383a3e2, - 0x45f704f7, 0xf9ba1651, 0x4fd288dc, 0xed6bf9d1, 0x539eba45, 0xe7821d59, 0x4b418bbe, 0xf383a3e2, - 0x58c542c5, 0xdc71898d, 0x58c542c5, 0xdc71898d, 0x4fd288dc, 0xed6bf9d1, 0x5a12e720, 0xce86ff2a, - 0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59, 0x539eba45, 0xc4df2862, 0x58c542c5, 0xcac933ae, - 0x569cc31b, 0xe1d4a2c8, 0x45f704f7, 0xc04ee4b8, 0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d, - 0x3248d382, 0xc13ad060, 0x4b418bbe, 0xc13ad060, 0x5a12e720, 0xd76619b6, 0x1a4608ab, 0xc78e9a1d, - 0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x3248d382, 0xc13ad060, - 0x5a12e720, 0xce86ff2a, 0xe5b9f755, 0xe1d4a2c8, 0x22a2f4f8, 0xc4df2862, 0x58c542c5, 0xcac933ae, - 0xcdb72c7e, 0xf383a3e2, 0x11a855df, 0xcac933ae, 0x569cc31b, 0xc78e9a1d, 0xba08fb09, 0x0645e9af, - 0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, 0xac6145bb, 0x187de2a7, 0xee57aa21, 0xdc71898d, - 0x4fd288dc, 0xc2c17d52, 0xa5ed18e0, 0x2899e64a, 0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060, - 0xa73abd3b, 0x3536cc52, 0xcdb72c7e, 0xf383a3e2, 0x45f704f7, 0xc04ee4b8, 0xb02d7724, 0x3d3e82ae, - - 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x43103085, 0xfcdc1342, - 0x418d2621, 0xfe6deaa1, 0x4488e37f, 0xfb4ab7db, 0x45f704f7, 0xf9ba1651, 0x43103085, 0xfcdc1342, - 0x48b2b335, 0xf69bf7c9, 0x48b2b335, 0xf69bf7c9, 0x4488e37f, 0xfb4ab7db, 0x4c77a88e, 0xf1fa3ecb, - 0x4b418bbe, 0xf383a3e2, 0x45f704f7, 0xf9ba1651, 0x4fd288dc, 0xed6bf9d1, 0x4da1fab5, 0xf0730342, - 0x475a5c77, 0xf82a6c6a, 0x52beac9f, 0xe8f77acf, 0x4fd288dc, 0xed6bf9d1, 0x48b2b335, 0xf69bf7c9, - 0x553805f2, 0xe4a2eff6, 0x51d1dc80, 0xea70658a, 0x49ffd417, 0xf50ef5de, 0x573b2635, 0xe0745b24, - 0x539eba45, 0xe7821d59, 0x4b418bbe, 0xf383a3e2, 0x58c542c5, 0xdc71898d, 0x553805f2, 0xe4a2eff6, - 0x4c77a88e, 0xf1fa3ecb, 0x59d438e5, 0xd8a00bae, 0x569cc31b, 0xe1d4a2c8, 0x4da1fab5, 0xf0730342, - 0x5a6690ae, 0xd5052d97, 0x57cc15bc, 0xdf18f0ce, 0x4ec05432, 0xeeee2d9d, 0x5a7b7f1a, 0xd1a5ef90, - 0x58c542c5, 0xdc71898d, 0x4fd288dc, 0xed6bf9d1, 0x5a12e720, 0xce86ff2a, 0x5987b08a, 0xd9e01006, - 0x50d86e6d, 0xebeca36c, 0x592d59da, 0xcbacb0bf, 0x5a12e720, 0xd76619b6, 0x51d1dc80, 0xea70658a, - 0x57cc15bc, 0xc91af976, 0x5a6690ae, 0xd5052d97, 0x52beac9f, 0xe8f77acf, 0x55f104dc, 0xc6d569be, - 0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59, 0x539eba45, 0xc4df2862, 0x5a6690ae, 0xd09441bb, - 0x5471e2e6, 0xe61086bc, 0x50d86e6d, 0xc33aee27, 0x5a12e720, 0xce86ff2a, 0x553805f2, 0xe4a2eff6, - 0x4da1fab5, 0xc1eb0209, 0x5987b08a, 0xcc983f70, 0x55f104dc, 0xe3399167, 0x49ffd417, 0xc0f1360b, - 0x58c542c5, 0xcac933ae, 0x569cc31b, 0xe1d4a2c8, 0x45f704f7, 0xc04ee4b8, 0x57cc15bc, 0xc91af976, - 0x573b2635, 0xe0745b24, 0x418d2621, 0xc004ef3f, 0x569cc31b, 0xc78e9a1d, 0x57cc15bc, 0xdf18f0ce, - 0x3cc85709, 0xc013bc39, 0x553805f2, 0xc6250a18, 0x584f7b58, 0xddc29958, 0x37af354c, 0xc07b371e, - 0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d, 0x3248d382, 0xc13ad060, 0x51d1dc80, 0xc3bdbdf6, - 0x592d59da, 0xdb25f566, 0x2c9caf6c, 0xc2517e31, 0x4fd288dc, 0xc2c17d52, 0x5987b08a, 0xd9e01006, - 0x26b2a794, 0xc3bdbdf6, 0x4da1fab5, 0xc1eb0209, 0x59d438e5, 0xd8a00bae, 0x2092f05f, 0xc57d965d, - 0x4b418bbe, 0xc13ad060, 0x5a12e720, 0xd76619b6, 0x1a4608ab, 0xc78e9a1d, 0x48b2b335, 0xc0b15502, - 0x5a43b190, 0xd6326a88, 0x13d4ae08, 0xc9edeb50, 0x45f704f7, 0xc04ee4b8, 0x5a6690ae, 0xd5052d97, - 0x0d47d096, 0xcc983f70, 0x43103085, 0xc013bc39, 0x5a7b7f1a, 0xd3de9156, 0x06a886a0, 0xcf89e3e8, - 0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x3cc85709, 0xc013bc39, - 0x5a7b7f1a, 0xd1a5ef90, 0xf9577960, 0xd6326a88, 0x396b3199, 0xc04ee4b8, 0x5a6690ae, 0xd09441bb, - 0xf2b82f6a, 0xd9e01006, 0x35eaa2c7, 0xc0b15502, 0x5a43b190, 0xcf89e3e8, 0xec2b51f8, 0xddc29958, - 0x3248d382, 0xc13ad060, 0x5a12e720, 0xce86ff2a, 0xe5b9f755, 0xe1d4a2c8, 0x2e88013a, 0xc1eb0209, - 0x59d438e5, 0xcd8bbb6d, 0xdf6d0fa1, 0xe61086bc, 0x2aaa7c7f, 0xc2c17d52, 0x5987b08a, 0xcc983f70, - 0xd94d586c, 0xea70658a, 0x26b2a794, 0xc3bdbdf6, 0x592d59da, 0xcbacb0bf, 0xd3635094, 0xeeee2d9d, - 0x22a2f4f8, 0xc4df2862, 0x58c542c5, 0xcac933ae, 0xcdb72c7e, 0xf383a3e2, 0x1e7de5df, 0xc6250a18, - 0x584f7b58, 0xc9edeb50, 0xc850cab4, 0xf82a6c6a, 0x1a4608ab, 0xc78e9a1d, 0x57cc15bc, 0xc91af976, - 0xc337a8f7, 0xfcdc1342, 0x15fdf758, 0xc91af976, 0x573b2635, 0xc8507ea7, 0xbe72d9df, 0x0192155f, - 0x11a855df, 0xcac933ae, 0x569cc31b, 0xc78e9a1d, 0xba08fb09, 0x0645e9af, 0x0d47d096, 0xcc983f70, - 0x55f104dc, 0xc6d569be, 0xb6002be9, 0x0af10a22, 0x08df1a8c, 0xce86ff2a, 0x553805f2, 0xc6250a18, - 0xb25e054b, 0x0f8cfcbe, 0x0470ebdc, 0xd09441bb, 0x5471e2e6, 0xc57d965d, 0xaf279193, 0x14135c94, - 0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, 0xac6145bb, 0x187de2a7, 0xfb8f1424, 0xd5052d97, - 0x52beac9f, 0xc449d892, 0xaa0efb24, 0x1cc66e99, 0xf720e574, 0xd76619b6, 0x51d1dc80, 0xc3bdbdf6, - 0xa833ea44, 0x20e70f32, 0xf2b82f6a, 0xd9e01006, 0x50d86e6d, 0xc33aee27, 0xa6d2a626, 0x24da0a9a, - 0xee57aa21, 0xdc71898d, 0x4fd288dc, 0xc2c17d52, 0xa5ed18e0, 0x2899e64a, 0xea0208a8, 0xdf18f0ce, - 0x4ec05432, 0xc2517e31, 0xa58480e6, 0x2c216eaa, 0xe5b9f755, 0xe1d4a2c8, 0x4da1fab5, 0xc1eb0209, - 0xa5996f52, 0x2f6bbe45, 0xe1821a21, 0xe4a2eff6, 0x4c77a88e, 0xc18e18a7, 0xa62bc71b, 0x32744493, - 0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060, 0xa73abd3b, 0x3536cc52, 0xd94d586c, 0xea70658a, - 0x49ffd417, 0xc0f1360b, 0xa8c4d9cb, 0x37af8159, 0xd5558381, 0xed6bf9d1, 0x48b2b335, 0xc0b15502, - 0xaac7fa0e, 0x39daf5e8, 0xd177fec6, 0xf0730342, 0x475a5c77, 0xc07b371e, 0xad415361, 0x3bb6276e, - 0xcdb72c7e, 0xf383a3e2, 0x45f704f7, 0xc04ee4b8, 0xb02d7724, 0x3d3e82ae, 0xca155d39, 0xf69bf7c9, - 0x4488e37f, 0xc02c64a6, 0xb3885772, 0x3e71e759, 0xc694ce67, 0xf9ba1651, 0x43103085, 0xc013bc39, - 0xb74d4ccb, 0x3f4eaafe, 0xc337a8f7, 0xfcdc1342, 0x418d2621, 0xc004ef3f, 0xbb771c81, 0x3fd39b5a, +const int twidTabEven[4 * 6 + 16 * 6 + 64 * 6] DPROGMEM = { + 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x5a82799a, 0xd2bec333, + 0x539eba45, 0xe7821d59, 0x539eba45, 0xc4df2862, 0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, + 0x00000000, 0xd2bec333, 0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, 0xac6145bb, 0x187de2a7, + + 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x4b418bbe, 0xf383a3e2, + 0x45f704f7, 0xf9ba1651, 0x4fd288dc, 0xed6bf9d1, 0x539eba45, 0xe7821d59, 0x4b418bbe, 0xf383a3e2, + 0x58c542c5, 0xdc71898d, 0x58c542c5, 0xdc71898d, 0x4fd288dc, 0xed6bf9d1, 0x5a12e720, 0xce86ff2a, + 0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59, 0x539eba45, 0xc4df2862, 0x58c542c5, 0xcac933ae, + 0x569cc31b, 0xe1d4a2c8, 0x45f704f7, 0xc04ee4b8, 0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d, + 0x3248d382, 0xc13ad060, 0x4b418bbe, 0xc13ad060, 0x5a12e720, 0xd76619b6, 0x1a4608ab, 0xc78e9a1d, + 0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x3248d382, 0xc13ad060, + 0x5a12e720, 0xce86ff2a, 0xe5b9f755, 0xe1d4a2c8, 0x22a2f4f8, 0xc4df2862, 0x58c542c5, 0xcac933ae, + 0xcdb72c7e, 0xf383a3e2, 0x11a855df, 0xcac933ae, 0x569cc31b, 0xc78e9a1d, 0xba08fb09, 0x0645e9af, + 0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, 0xac6145bb, 0x187de2a7, 0xee57aa21, 0xdc71898d, + 0x4fd288dc, 0xc2c17d52, 0xa5ed18e0, 0x2899e64a, 0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060, + 0xa73abd3b, 0x3536cc52, 0xcdb72c7e, 0xf383a3e2, 0x45f704f7, 0xc04ee4b8, 0xb02d7724, 0x3d3e82ae, + + 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x43103085, 0xfcdc1342, + 0x418d2621, 0xfe6deaa1, 0x4488e37f, 0xfb4ab7db, 0x45f704f7, 0xf9ba1651, 0x43103085, 0xfcdc1342, + 0x48b2b335, 0xf69bf7c9, 0x48b2b335, 0xf69bf7c9, 0x4488e37f, 0xfb4ab7db, 0x4c77a88e, 0xf1fa3ecb, + 0x4b418bbe, 0xf383a3e2, 0x45f704f7, 0xf9ba1651, 0x4fd288dc, 0xed6bf9d1, 0x4da1fab5, 0xf0730342, + 0x475a5c77, 0xf82a6c6a, 0x52beac9f, 0xe8f77acf, 0x4fd288dc, 0xed6bf9d1, 0x48b2b335, 0xf69bf7c9, + 0x553805f2, 0xe4a2eff6, 0x51d1dc80, 0xea70658a, 0x49ffd417, 0xf50ef5de, 0x573b2635, 0xe0745b24, + 0x539eba45, 0xe7821d59, 0x4b418bbe, 0xf383a3e2, 0x58c542c5, 0xdc71898d, 0x553805f2, 0xe4a2eff6, + 0x4c77a88e, 0xf1fa3ecb, 0x59d438e5, 0xd8a00bae, 0x569cc31b, 0xe1d4a2c8, 0x4da1fab5, 0xf0730342, + 0x5a6690ae, 0xd5052d97, 0x57cc15bc, 0xdf18f0ce, 0x4ec05432, 0xeeee2d9d, 0x5a7b7f1a, 0xd1a5ef90, + 0x58c542c5, 0xdc71898d, 0x4fd288dc, 0xed6bf9d1, 0x5a12e720, 0xce86ff2a, 0x5987b08a, 0xd9e01006, + 0x50d86e6d, 0xebeca36c, 0x592d59da, 0xcbacb0bf, 0x5a12e720, 0xd76619b6, 0x51d1dc80, 0xea70658a, + 0x57cc15bc, 0xc91af976, 0x5a6690ae, 0xd5052d97, 0x52beac9f, 0xe8f77acf, 0x55f104dc, 0xc6d569be, + 0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59, 0x539eba45, 0xc4df2862, 0x5a6690ae, 0xd09441bb, + 0x5471e2e6, 0xe61086bc, 0x50d86e6d, 0xc33aee27, 0x5a12e720, 0xce86ff2a, 0x553805f2, 0xe4a2eff6, + 0x4da1fab5, 0xc1eb0209, 0x5987b08a, 0xcc983f70, 0x55f104dc, 0xe3399167, 0x49ffd417, 0xc0f1360b, + 0x58c542c5, 0xcac933ae, 0x569cc31b, 0xe1d4a2c8, 0x45f704f7, 0xc04ee4b8, 0x57cc15bc, 0xc91af976, + 0x573b2635, 0xe0745b24, 0x418d2621, 0xc004ef3f, 0x569cc31b, 0xc78e9a1d, 0x57cc15bc, 0xdf18f0ce, + 0x3cc85709, 0xc013bc39, 0x553805f2, 0xc6250a18, 0x584f7b58, 0xddc29958, 0x37af354c, 0xc07b371e, + 0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d, 0x3248d382, 0xc13ad060, 0x51d1dc80, 0xc3bdbdf6, + 0x592d59da, 0xdb25f566, 0x2c9caf6c, 0xc2517e31, 0x4fd288dc, 0xc2c17d52, 0x5987b08a, 0xd9e01006, + 0x26b2a794, 0xc3bdbdf6, 0x4da1fab5, 0xc1eb0209, 0x59d438e5, 0xd8a00bae, 0x2092f05f, 0xc57d965d, + 0x4b418bbe, 0xc13ad060, 0x5a12e720, 0xd76619b6, 0x1a4608ab, 0xc78e9a1d, 0x48b2b335, 0xc0b15502, + 0x5a43b190, 0xd6326a88, 0x13d4ae08, 0xc9edeb50, 0x45f704f7, 0xc04ee4b8, 0x5a6690ae, 0xd5052d97, + 0x0d47d096, 0xcc983f70, 0x43103085, 0xc013bc39, 0x5a7b7f1a, 0xd3de9156, 0x06a886a0, 0xcf89e3e8, + 0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x3cc85709, 0xc013bc39, + 0x5a7b7f1a, 0xd1a5ef90, 0xf9577960, 0xd6326a88, 0x396b3199, 0xc04ee4b8, 0x5a6690ae, 0xd09441bb, + 0xf2b82f6a, 0xd9e01006, 0x35eaa2c7, 0xc0b15502, 0x5a43b190, 0xcf89e3e8, 0xec2b51f8, 0xddc29958, + 0x3248d382, 0xc13ad060, 0x5a12e720, 0xce86ff2a, 0xe5b9f755, 0xe1d4a2c8, 0x2e88013a, 0xc1eb0209, + 0x59d438e5, 0xcd8bbb6d, 0xdf6d0fa1, 0xe61086bc, 0x2aaa7c7f, 0xc2c17d52, 0x5987b08a, 0xcc983f70, + 0xd94d586c, 0xea70658a, 0x26b2a794, 0xc3bdbdf6, 0x592d59da, 0xcbacb0bf, 0xd3635094, 0xeeee2d9d, + 0x22a2f4f8, 0xc4df2862, 0x58c542c5, 0xcac933ae, 0xcdb72c7e, 0xf383a3e2, 0x1e7de5df, 0xc6250a18, + 0x584f7b58, 0xc9edeb50, 0xc850cab4, 0xf82a6c6a, 0x1a4608ab, 0xc78e9a1d, 0x57cc15bc, 0xc91af976, + 0xc337a8f7, 0xfcdc1342, 0x15fdf758, 0xc91af976, 0x573b2635, 0xc8507ea7, 0xbe72d9df, 0x0192155f, + 0x11a855df, 0xcac933ae, 0x569cc31b, 0xc78e9a1d, 0xba08fb09, 0x0645e9af, 0x0d47d096, 0xcc983f70, + 0x55f104dc, 0xc6d569be, 0xb6002be9, 0x0af10a22, 0x08df1a8c, 0xce86ff2a, 0x553805f2, 0xc6250a18, + 0xb25e054b, 0x0f8cfcbe, 0x0470ebdc, 0xd09441bb, 0x5471e2e6, 0xc57d965d, 0xaf279193, 0x14135c94, + 0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, 0xac6145bb, 0x187de2a7, 0xfb8f1424, 0xd5052d97, + 0x52beac9f, 0xc449d892, 0xaa0efb24, 0x1cc66e99, 0xf720e574, 0xd76619b6, 0x51d1dc80, 0xc3bdbdf6, + 0xa833ea44, 0x20e70f32, 0xf2b82f6a, 0xd9e01006, 0x50d86e6d, 0xc33aee27, 0xa6d2a626, 0x24da0a9a, + 0xee57aa21, 0xdc71898d, 0x4fd288dc, 0xc2c17d52, 0xa5ed18e0, 0x2899e64a, 0xea0208a8, 0xdf18f0ce, + 0x4ec05432, 0xc2517e31, 0xa58480e6, 0x2c216eaa, 0xe5b9f755, 0xe1d4a2c8, 0x4da1fab5, 0xc1eb0209, + 0xa5996f52, 0x2f6bbe45, 0xe1821a21, 0xe4a2eff6, 0x4c77a88e, 0xc18e18a7, 0xa62bc71b, 0x32744493, + 0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060, 0xa73abd3b, 0x3536cc52, 0xd94d586c, 0xea70658a, + 0x49ffd417, 0xc0f1360b, 0xa8c4d9cb, 0x37af8159, 0xd5558381, 0xed6bf9d1, 0x48b2b335, 0xc0b15502, + 0xaac7fa0e, 0x39daf5e8, 0xd177fec6, 0xf0730342, 0x475a5c77, 0xc07b371e, 0xad415361, 0x3bb6276e, + 0xcdb72c7e, 0xf383a3e2, 0x45f704f7, 0xc04ee4b8, 0xb02d7724, 0x3d3e82ae, 0xca155d39, 0xf69bf7c9, + 0x4488e37f, 0xc02c64a6, 0xb3885772, 0x3e71e759, 0xc694ce67, 0xf9ba1651, 0x43103085, 0xc013bc39, + 0xb74d4ccb, 0x3f4eaafe, 0xc337a8f7, 0xfcdc1342, 0x418d2621, 0xc004ef3f, 0xbb771c81, 0x3fd39b5a, }; -/* for reference, here's the code to generate the bitreverse tables - short blocks: nbits = 4 (nfft = 64) - long blocks: nbits = 7 (nfft = 512) +/* for reference, here's the code to generate the bitreverse tables + short blocks: nbits = 4 (nfft = 64) + long blocks: nbits = 7 (nfft = 512) -static int bitrev(int n, int nbits) -{ + static int bitrev(int n, int nbits) + { int r, i; r = 0; @@ -900,37 +906,37 @@ static int bitrev(int n, int nbits) } return r; -} + } -static void InitBitrevTable(unsigned char *out, int nbits) -{ + static void InitBitrevTable(unsigned char *out, int nbits) + { int i, t; for (i = 0; i < (1< KBD_THRESH); return i0; -} + } -static double CalcW(double nRef, double n, double a) -{ + static double CalcW(double nRef, double n, double a) + { double i0Base, i0Curr, nTemp; i0Base = CalcI0(M_PI * a); @@ -961,10 +967,10 @@ static double CalcW(double nRef, double n, double a) i0Curr = CalcI0( M_PI * a * sqrt(1.0 - nTemp*nTemp) ); return i0Curr / i0Base; -} + } -void InitKBDWindow(int nmdct) -{ + void InitKBDWindow(int nmdct) + { int n, nRef; double a, wBase, wCurr; @@ -988,17 +994,17 @@ void InitKBDWindow(int nmdct) } / *** - * symmetry: - * kbd_right(n) = kbd_ldef(N_REF - 1 - n), n = [N_REF/2, N_REF - 1] - * - * wCurr = 0; - * for (n = N_REF-1; n >= N_REF/2; n--) { - * wCurr += CalcW(N_REF-n-1, a); - * kbdWindowRef[n] = sqrt(wCurr / wBase); - * } - * + symmetry: + kbd_right(n) = kbd_ldef(N_REF - 1 - n), n = [N_REF/2, N_REF - 1] + + wCurr = 0; + for (n = N_REF-1; n >= N_REF/2; n--) { + wCurr += CalcW(N_REF-n-1, a); + kbdWindowRef[n] = sqrt(wCurr / wBase); + } + *** / return; -} + } */ #pragma GCC diagnostic pop diff --git a/src/libhelix-mp3/RCSL.txt b/src/libhelix-mp3/RCSL.txt index a809759a..4947e535 100644 --- a/src/libhelix-mp3/RCSL.txt +++ b/src/libhelix-mp3/RCSL.txt @@ -801,7 +801,7 @@ REQUIRED IN ALL CASES Notice to be included in header file of all Error Corrections and Shared Modifications: -Portions Copyright 1994-2003 © RealNetworks, Inc. All rights reserved. +Portions Copyright 1994-2003 (c) RealNetworks, Inc. All rights reserved. The contents of this file, and the files included with this file, are subject to the current version of RealNetworks Community Source License diff --git a/src/libhelix-mp3/RPSL.txt b/src/libhelix-mp3/RPSL.txt index d040a452..94b44586 100644 --- a/src/libhelix-mp3/RPSL.txt +++ b/src/libhelix-mp3/RPSL.txt @@ -201,7 +201,7 @@ and 3, above. 4.2 Compatible Source Licenses. Software modules that have been independently developed without any use of Covered Code and which contain no portion of the Covered Code, Modifications or other Derivative Works, but are used or combined -in any way wtih the Covered Code or any Derivative Work to form a larger +in any way with the Covered Code or any Derivative Work to form a larger Derivative Work, are exempt from the conditions described in Section 4.1 but only to the extent that: the software module, including any software that is linked to, integrated with, or part of the same applications as, the software diff --git a/src/libhelix-mp3/assembly.h b/src/libhelix-mp3/assembly.h index 9c10c4da..085adb1d 100644 --- a/src/libhelix-mp3/assembly.h +++ b/src/libhelix-mp3/assembly.h @@ -1,57 +1,57 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * assembly.h - assembly language functions and prototypes for supported platforms - * - * - inline rountines with access to 64-bit multiply results - * - x86 (_WIN32) and ARM (ARM_ADS, _WIN32_WCE) versions included - * - some inline functions are mix of asm and C for speed - * - some functions are in native asm files, so only the prototype is given here - * - * MULSHIFT32(x, y) signed multiply of two 32-bit integers (x and y), returns top 32 bits of 64-bit result - * FASTABS(x) branchless absolute value of signed integer x - * CLZ(x) count leading zeros in x - * MADD64(sum, x, y) (Windows only) sum [64-bit] += x [32-bit] * y [32-bit] - * SHL64(sum, x, y) (Windows only) 64-bit left shift using __int64 - * SAR64(sum, x, y) (Windows only) 64-bit right shift using __int64 - */ + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + assembly.h - assembly language functions and prototypes for supported platforms + + - inline routines with access to 64-bit multiply results + - x86 (_WIN32) and ARM (ARM_ADS, _WIN32_WCE) versions included + - some inline functions are mix of asm and C for speed + - some functions are in native asm files, so only the prototype is given here + + MULSHIFT32(x, y) signed multiply of two 32-bit integers (x and y), returns top 32 bits of 64-bit result + FASTABS(x) branchless absolute value of signed integer x + CLZ(x) count leading zeros in x + MADD64(sum, x, y) (Windows only) sum [64-bit] += x [32-bit] * y [32-bit] + SHL64(sum, x, y) (Windows only) 64-bit left shift using __int64 + SAR64(sum, x, y) (Windows only) 64-bit right shift using __int64 +*/ #ifndef _ASSEMBLY_H #define _ASSEMBLY_H @@ -60,128 +60,123 @@ #pragma warning( disable : 4035 ) /* complains about inline asm not returning a value */ -static __inline int MULSHIFT32(int x, int y) -{ +static __inline int MULSHIFT32(int x, int y) { __asm { - mov eax, x - imul y - mov eax, edx - } + mov eax, x + imul y + mov eax, edx + } } -static __inline int FASTABS(int x) -{ - int sign; +static __inline int FASTABS(int x) { + int sign; - sign = x >> (sizeof(int) * 8 - 1); - x ^= sign; - x -= sign; + sign = x >> (sizeof(int) * 8 - 1); + x ^= sign; + x -= sign; - return x; + return x; } -static __inline int CLZ(int x) -{ - int numZeros; +static __inline int CLZ(int x) { + int numZeros; - if (!x) - return (sizeof(int) * 8); + if (!x) { + return (sizeof(int) * 8); + } - numZeros = 0; - while (!(x & 0x80000000)) { - numZeros++; - x <<= 1; - } + numZeros = 0; + while (!(x & 0x80000000)) { + numZeros++; + x <<= 1; + } - return numZeros; + return numZeros; } -/* MADD64, SHL64, SAR64: - * write in assembly to avoid dependency on run-time lib for 64-bit shifts, muls - * (sometimes compiler thunks to function calls instead of code generating) - * required for Symbian emulator - */ +/* MADD64, SHL64, SAR64: + write in assembly to avoid dependency on run-time lib for 64-bit shifts, muls + (sometimes compiler thunks to function calls instead of code generating) + required for Symbian emulator +*/ #ifdef __CW32__ typedef long long Word64; #else typedef __int64 Word64; #endif -static __inline Word64 MADD64(Word64 sum, int x, int y) -{ - unsigned int sumLo = ((unsigned int *)&sum)[0]; - int sumHi = ((int *)&sum)[1]; +static __inline Word64 MADD64(Word64 sum, int x, int y) { + unsigned int sumLo = ((unsigned int *)&sum)[0]; + int sumHi = ((int *)&sum)[1]; - __asm { - mov eax, x - imul y - add eax, sumLo - adc edx, sumHi - } + __asm { + mov eax, x + imul y + add eax, sumLo + adc edx, sumHi + } - /* equivalent to return (sum + ((__int64)x * y)); */ + /* equivalent to return (sum + ((__int64)x * y)); */ } -static __inline Word64 SHL64(Word64 x, int n) -{ - unsigned int xLo = ((unsigned int *)&x)[0]; - int xHi = ((int *)&x)[1]; - unsigned char nb = (unsigned char)n; - - if (n < 32) { - __asm { - mov edx, xHi - mov eax, xLo - mov cl, nb - shld edx, eax, cl - shl eax, cl - } - } else if (n < 64) { - /* shl masks cl to 0x1f */ - __asm { - mov edx, xLo - mov cl, nb - xor eax, eax - shl edx, cl - } - } else { - __asm { - xor edx, edx - xor eax, eax - } - } +static __inline Word64 SHL64(Word64 x, int n) { + unsigned int xLo = ((unsigned int *)&x)[0]; + int xHi = ((int *)&x)[1]; + unsigned char nb = (unsigned char)n; + + if (n < 32) { + __asm { + mov edx, xHi + mov eax, xLo + mov cl, nb + shld edx, eax, cl + shl eax, cl + } + } else if (n < 64) { + /* shl masks cl to 0x1f */ + __asm { + mov edx, xLo + mov cl, nb + xor eax, eax + shl edx, cl + } + } else { + __asm { + xor edx, edx + xor eax, eax + } + } } -static __inline Word64 SAR64(Word64 x, int n) -{ - unsigned int xLo = ((unsigned int *)&x)[0]; - int xHi = ((int *)&x)[1]; - unsigned char nb = (unsigned char)n; - - if (n < 32) { - __asm { - mov edx, xHi - mov eax, xLo - mov cl, nb - shrd eax, edx, cl - sar edx, cl - } - } else if (n < 64) { - /* sar masks cl to 0x1f */ - __asm { - mov edx, xHi - mov eax, xHi - mov cl, nb - sar edx, 31 - sar eax, cl - } - } else { - __asm { - sar xHi, 31 - mov eax, xHi - mov edx, xHi - } - } +static __inline Word64 SAR64(Word64 x, int n) { + unsigned int xLo = ((unsigned int *)&x)[0]; + int xHi = ((int *)&x)[1]; + unsigned char nb = (unsigned char)n; + + if (n < 32) { + __asm { + mov edx, xHi + mov eax, xLo + mov cl, nb + shrd eax, edx, cl + sar edx, cl + } + } else if (n < 64) { + /* sar masks cl to 0x1f */ + __asm { + mov edx, xHi + mov eax, xHi + mov cl, nb + sar edx, 31 + sar eax, cl + } + } else { + __asm { + sar xHi, 31 + mov eax, xHi + mov edx, xHi + } + } } #elif (defined _WIN32) && (defined _WIN32_WCE) @@ -190,180 +185,167 @@ static __inline Word64 SAR64(Word64 x, int n) #define MULSHIFT32 xmp3_MULSHIFT32 int MULSHIFT32(int x, int y); -static __inline int FASTABS(int x) -{ - int sign; +static __inline int FASTABS(int x) { + int sign; - sign = x >> (sizeof(int) * 8 - 1); - x ^= sign; - x -= sign; + sign = x >> (sizeof(int) * 8 - 1); + x ^= sign; + x -= sign; - return x; + return x; } -static __inline int CLZ(int x) -{ - int numZeros; +static __inline int CLZ(int x) { + int numZeros; - if (!x) - return (sizeof(int) * 8); + if (!x) { + return (sizeof(int) * 8); + } - numZeros = 0; - while (!(x & 0x80000000)) { - numZeros++; - x <<= 1; - } + numZeros = 0; + while (!(x & 0x80000000)) { + numZeros++; + x <<= 1; + } - return numZeros; + return numZeros; } -#elif defined ARM_ADS - -static __inline int MULSHIFT32(int x, int y) -{ - /* important rules for smull RdLo, RdHi, Rm, Rs: - * RdHi and Rm can't be the same register - * RdLo and Rm can't be the same register - * RdHi and RdLo can't be the same register - * Note: Rs determines early termination (leading sign bits) so if you want to specify - * which operand is Rs, put it in the SECOND argument (y) - * For inline assembly, x and y are not assumed to be R0, R1 so it shouldn't matter - * which one is returned. (If this were a function call, returning y (R1) would - * require an extra "mov r0, r1") - */ +#elif defined XXXARM_ADS + +static __inline int MULSHIFT32(int x, int y) { + /* important rules for smull RdLo, RdHi, Rm, Rs: + RdHi and Rm can't be the same register + RdLo and Rm can't be the same register + RdHi and RdLo can't be the same register + Note: Rs determines early termination (leading sign bits) so if you want to specify + which operand is Rs, put it in the SECOND argument (y) + For inline assembly, x and y are not assumed to be R0, R1 so it shouldn't matter + which one is returned. (If this were a function call, returning y (R1) would + require an extra "mov r0, r1") + */ int zlow; __asm { - smull zlow,y,x,y - } + smull zlow, y, x, y + } return y; } -static __inline int FASTABS(int x) -{ - int t=0; /*Really is not necessary to initialiaze only to avoid warning*/ +static __inline int FASTABS(int x) { + int t = 0; /*Really is not necessary to initialize only to avoid warning*/ - __asm { - eor t, x, x, asr #31 - sub t, t, x, asr #31 - } + __asm { + eor t, x, x, asr #31 + sub t, t, x, asr #31 + } - return t; + return t; } -static __inline int CLZ(int x) -{ - int numZeros; +static __inline int CLZ(int x) { + int numZeros; - if (!x) - return (sizeof(int) * 8); + if (!x) { + return (sizeof(int) * 8); + } - numZeros = 0; - while (!(x & 0x80000000)) { - numZeros++; - x <<= 1; - } + numZeros = 0; + while (!(x & 0x80000000)) { + numZeros++; + x <<= 1; + } - return numZeros; + return numZeros; } -#elif defined(__GNUC__) && defined(__thumb__) +#elif defined(__GNUC__) && defined(XXXX__thumb__) -static __inline int MULSHIFT32(int x, int y) -{ +static __inline int MULSHIFT32(int x, int y) { // important rules for smull RdLo, RdHi, Rm, Rs: // RdHi and Rm can't be the same register // RdLo and Rm can't be the same register // RdHi and RdLo can't be the same register // Note: Rs determines early termination (leading sign bits) so if you want to specify // which operand is Rs, put it in the SECOND argument (y) - // For inline assembly, x and y are not assumed to be R0, R1 so it shouldn't matter - // which one is returned. (If this were a function call, returning y (R1) would - // require an extra "mov r0, r1") + // For inline assembly, x and y are not assumed to be R0, R1 so it shouldn't matter + // which one is returned. (If this were a function call, returning y (R1) would + // require an extra "mov r0, r1") int zlow; - __asm__ volatile ("smull %0,%1,%2,%3" : "=&r" (zlow), "=r" (y) : "r" (x), "1" (y)) ; + __asm__ volatile("smull %0,%1,%2,%3" : "=&r"(zlow), "=r"(y) : "r"(x), "1"(y)) ; return y; } //fb #include -static __inline int FASTABS(int x) -{ - return abs(x); +static __inline int FASTABS(int x) { + return abs(x); } -static __inline int CLZ(int x) -{ - return __builtin_clz(x); +static __inline int CLZ(int x) { + return __builtin_clz(x); } //fb //mw //TODO: Check Compiler output on these.. (fb) -static __inline Word64 xMADD64(Word64 sum, int x, int y) -{ - return (sum + ((int64_t)x * y)); +static __inline Word64 xMADD64(Word64 sum, int x, int y) { + return (sum + ((int64_t)x * y)); } -static __inline Word64 xHL64(Word64 x, int n) -{ - return x << n; +static __inline Word64 xHL64(Word64 x, int n) { + return x << n; } -static __inline Word64 xSAR64(Word64 x, int n) -{ - return x >> n; +static __inline Word64 xSAR64(Word64 x, int n) { + return x >> n; } //mw #elif defined(ARDUINO) -static __inline int FASTABS(int x) -{ - int sign; +static __inline int FASTABS(int x) { + int sign; - sign = x >> (sizeof(int) * 8 - 1); - x ^= sign; - x -= sign; + sign = x >> (sizeof(int) * 8 - 1); + x ^= sign; + x -= sign; - return x; + return x; } -static __inline int CLZ(int x) -{ - int numZeros; +static __inline int CLZ(int x) { + int numZeros; - if (!x) - return (sizeof(int) * 8); + if (!x) { + return (sizeof(int) * 8); + } - numZeros = 0; - while (!(x & 0x80000000)) { - numZeros++; - x <<= 1; - } + numZeros = 0; + while (!(x & 0x80000000)) { + numZeros++; + x <<= 1; + } - return numZeros; + return numZeros; } /* returns 64-bit value in [edx:eax] */ -static __inline Word64 MADD64(Word64 sum64, int x, int y) -{ +static __inline Word64 MADD64(Word64 sum64, int x, int y) { sum64 += (Word64)x * (Word64)y; return sum64; } -static __inline__ int MULSHIFT32(int x, int y) -{ +static __inline__ int MULSHIFT32(int x, int y) { int z; z = (Word64)x * (Word64)y >> 32; - return z; + return z; } -static __inline Word64 SAR64(Word64 x, int n) -{ - return x >> n; +static __inline Word64 SAR64(Word64 x, int n) { + return x >> n; } #else diff --git a/src/libhelix-mp3/bitstream.c b/src/libhelix-mp3/bitstream.c index 608c39cc..130c6463 100644 --- a/src/libhelix-mp3/bitstream.c +++ b/src/libhelix-mp3/bitstream.c @@ -1,389 +1,388 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * bitstream.c - bitstream unpacking, frame header parsing, side info parsing + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + bitstream.c - bitstream unpacking, frame header parsing, side info parsing **************************************************************************************/ #include "coder.h" #include "assembly.h" /************************************************************************************** - * Function: SetBitstreamPointer - * - * Description: initialize bitstream reader - * - * Inputs: pointer to BitStreamInfo struct - * number of bytes in bitstream - * pointer to byte-aligned buffer of data to read from - * - * Outputs: filled bitstream info struct - * - * Return: none + Function: SetBitstreamPointer + + Description: initialize bitstream reader + + Inputs: pointer to BitStreamInfo struct + number of bytes in bitstream + pointer to byte-aligned buffer of data to read from + + Outputs: filled bitstream info struct + + Return: none **************************************************************************************/ -void SetBitstreamPointer(BitStreamInfo *bsi, int nBytes, unsigned char *buf) -{ - /* init bitstream */ - bsi->bytePtr = buf; - bsi->iCache = 0; /* 4-byte unsigned int */ - bsi->cachedBits = 0; /* i.e. zero bits in cache */ - bsi->nBytes = nBytes; +void SetBitstreamPointer(BitStreamInfo *bsi, int nBytes, unsigned char *buf) { + /* init bitstream */ + bsi->bytePtr = buf; + bsi->iCache = 0; /* 4-byte unsigned int */ + bsi->cachedBits = 0; /* i.e. zero bits in cache */ + bsi->nBytes = nBytes; } /************************************************************************************** - * Function: RefillBitstreamCache - * - * Description: read new data from bitstream buffer into bsi cache - * - * Inputs: pointer to initialized BitStreamInfo struct - * - * Outputs: updated bitstream info struct - * - * Return: none - * - * Notes: only call when iCache is completely drained (resets bitOffset to 0) - * always loads 4 new bytes except when bsi->nBytes < 4 (end of buffer) - * stores data as big-endian in cache, regardless of machine endian-ness - * - * TODO: optimize for ARM - * possibly add little/big-endian modes for doing 32-bit loads + Function: RefillBitstreamCache + + Description: read new data from bitstream buffer into bsi cache + + Inputs: pointer to initialized BitStreamInfo struct + + Outputs: updated bitstream info struct + + Return: none + + Notes: only call when iCache is completely drained (resets bitOffset to 0) + always loads 4 new bytes except when bsi->nBytes < 4 (end of buffer) + stores data as big-endian in cache, regardless of machine endian-ness + + TODO: optimize for ARM + possibly add little/big-endian modes for doing 32-bit loads **************************************************************************************/ -static __inline void RefillBitstreamCache(BitStreamInfo *bsi) -{ - int nBytes = bsi->nBytes; - - /* optimize for common case, independent of machine endian-ness */ - if (nBytes >= 4) { - bsi->iCache = (*bsi->bytePtr++) << 24; - bsi->iCache |= (*bsi->bytePtr++) << 16; - bsi->iCache |= (*bsi->bytePtr++) << 8; - bsi->iCache |= (*bsi->bytePtr++); - bsi->cachedBits = 32; - bsi->nBytes -= 4; - } else { - bsi->iCache = 0; - while (nBytes--) { - bsi->iCache |= (*bsi->bytePtr++); - bsi->iCache <<= 8; - } - bsi->iCache <<= ((3 - bsi->nBytes)*8); - bsi->cachedBits = 8*bsi->nBytes; - bsi->nBytes = 0; - } +static __inline void RefillBitstreamCache(BitStreamInfo *bsi) { + int nBytes = bsi->nBytes; + + /* optimize for common case, independent of machine endian-ness */ + if (nBytes >= 4) { + bsi->iCache = (*bsi->bytePtr++) << 24; + bsi->iCache |= (*bsi->bytePtr++) << 16; + bsi->iCache |= (*bsi->bytePtr++) << 8; + bsi->iCache |= (*bsi->bytePtr++); + bsi->cachedBits = 32; + bsi->nBytes -= 4; + } else { + bsi->iCache = 0; + while (nBytes--) { + bsi->iCache |= (*bsi->bytePtr++); + bsi->iCache <<= 8; + } + bsi->iCache <<= ((3 - bsi->nBytes) * 8); + bsi->cachedBits = 8 * bsi->nBytes; + bsi->nBytes = 0; + } } /************************************************************************************** - * Function: GetBits - * - * Description: get bits from bitstream, advance bitstream pointer - * - * Inputs: pointer to initialized BitStreamInfo struct - * number of bits to get from bitstream - * - * Outputs: updated bitstream info struct - * - * Return: the next nBits bits of data from bitstream buffer - * - * Notes: nBits must be in range [0, 31], nBits outside this range masked by 0x1f - * for speed, does not indicate error if you overrun bit buffer - * if nBits = 0, returns 0 (useful for scalefactor unpacking) - * - * TODO: optimize for ARM + Function: GetBits + + Description: get bits from bitstream, advance bitstream pointer + + Inputs: pointer to initialized BitStreamInfo struct + number of bits to get from bitstream + + Outputs: updated bitstream info struct + + Return: the next nBits bits of data from bitstream buffer + + Notes: nBits must be in range [0, 31], nBits outside this range masked by 0x1f + for speed, does not indicate error if you overrun bit buffer + if nBits = 0, returns 0 (useful for scalefactor unpacking) + + TODO: optimize for ARM **************************************************************************************/ -unsigned int GetBits(BitStreamInfo *bsi, int nBits) -{ - unsigned int data, lowBits; - - nBits &= 0x1f; /* nBits mod 32 to avoid unpredictable results like >> by negative amount */ - data = bsi->iCache >> (31 - nBits); /* unsigned >> so zero-extend */ - data >>= 1; /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */ - bsi->iCache <<= nBits; /* left-justify cache */ - bsi->cachedBits -= nBits; /* how many bits have we drawn from the cache so far */ - - /* if we cross an int boundary, refill the cache */ - if (bsi->cachedBits < 0) { - lowBits = -bsi->cachedBits; - RefillBitstreamCache(bsi); - data |= bsi->iCache >> (32 - lowBits); /* get the low-order bits */ - - bsi->cachedBits -= lowBits; /* how many bits have we drawn from the cache so far */ - bsi->iCache <<= lowBits; /* left-justify cache */ - } - - return data; +unsigned int GetBits(BitStreamInfo *bsi, int nBits) { + unsigned int data, lowBits; + + nBits &= 0x1f; /* nBits mod 32 to avoid unpredictable results like >> by negative amount */ + data = bsi->iCache >> (31 - nBits); /* unsigned >> so zero-extend */ + data >>= 1; /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */ + bsi->iCache <<= nBits; /* left-justify cache */ + bsi->cachedBits -= nBits; /* how many bits have we drawn from the cache so far */ + + /* if we cross an int boundary, refill the cache */ + if (bsi->cachedBits < 0) { + lowBits = -bsi->cachedBits; + RefillBitstreamCache(bsi); + data |= bsi->iCache >> (32 - lowBits); /* get the low-order bits */ + + bsi->cachedBits -= lowBits; /* how many bits have we drawn from the cache so far */ + bsi->iCache <<= lowBits; /* left-justify cache */ + } + + return data; } /************************************************************************************** - * Function: CalcBitsUsed - * - * Description: calculate how many bits have been read from bitstream - * - * Inputs: pointer to initialized BitStreamInfo struct - * pointer to start of bitstream buffer - * bit offset into first byte of startBuf (0-7) - * - * Outputs: none - * - * Return: number of bits read from bitstream, as offset from startBuf:startOffset + Function: CalcBitsUsed + + Description: calculate how many bits have been read from bitstream + + Inputs: pointer to initialized BitStreamInfo struct + pointer to start of bitstream buffer + bit offset into first byte of startBuf (0-7) + + Outputs: none + + Return: number of bits read from bitstream, as offset from startBuf:startOffset **************************************************************************************/ -int CalcBitsUsed(BitStreamInfo *bsi, unsigned char *startBuf, int startOffset) -{ - int bitsUsed; +int CalcBitsUsed(BitStreamInfo *bsi, unsigned char *startBuf, int startOffset) { + int bitsUsed; - bitsUsed = (bsi->bytePtr - startBuf) * 8; - bitsUsed -= bsi->cachedBits; - bitsUsed -= startOffset; + bitsUsed = (bsi->bytePtr - startBuf) * 8; + bitsUsed -= bsi->cachedBits; + bitsUsed -= startOffset; - return bitsUsed; + return bitsUsed; } /************************************************************************************** - * Function: CheckPadBit - * - * Description: check whether padding byte is present in an MP3 frame - * - * Inputs: MP3DecInfo struct with valid FrameHeader struct - * (filled by UnpackFrameHeader()) - * - * Outputs: none - * - * Return: 1 if pad bit is set, 0 if not, -1 if null input pointer + Function: CheckPadBit + + Description: check whether padding byte is present in an MP3 frame + + Inputs: MP3DecInfo struct with valid FrameHeader struct + (filled by UnpackFrameHeader()) + + Outputs: none + + Return: 1 if pad bit is set, 0 if not, -1 if null input pointer **************************************************************************************/ -int CheckPadBit(MP3DecInfo *mp3DecInfo) -{ - FrameHeader *fh; +int CheckPadBit(MP3DecInfo *mp3DecInfo) { + FrameHeader *fh; - /* validate pointers */ - if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS) - return -1; + /* validate pointers */ + if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS) { + return -1; + } - fh = ((FrameHeader *)(mp3DecInfo->FrameHeaderPS)); + fh = ((FrameHeader *)(mp3DecInfo->FrameHeaderPS)); - return (fh->paddingBit ? 1 : 0); + return (fh->paddingBit ? 1 : 0); } /************************************************************************************** - * Function: UnpackFrameHeader - * - * Description: parse the fields of the MP3 frame header - * - * Inputs: buffer pointing to a complete MP3 frame header (4 bytes, plus 2 if CRC) - * - * Outputs: filled frame header info in the MP3DecInfo structure - * updated platform-specific FrameHeader struct - * - * Return: length (in bytes) of frame header (for caller to calculate offset to - * first byte following frame header) - * -1 if null frameHeader or invalid header - * - * TODO: check for valid modes, depending on capabilities of decoder - * test CRC on actual stream (verify no endian problems) + Function: UnpackFrameHeader + + Description: parse the fields of the MP3 frame header + + Inputs: buffer pointing to a complete MP3 frame header (4 bytes, plus 2 if CRC) + + Outputs: filled frame header info in the MP3DecInfo structure + updated platform-specific FrameHeader struct + + Return: length (in bytes) of frame header (for caller to calculate offset to + first byte following frame header) + -1 if null frameHeader or invalid header + + TODO: check for valid modes, depending on capabilities of decoder + test CRC on actual stream (verify no endian problems) **************************************************************************************/ -int UnpackFrameHeader(MP3DecInfo *mp3DecInfo, unsigned char *buf) -{ - - int verIdx; - FrameHeader *fh; - - /* validate pointers and sync word */ - if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || (buf[0] & SYNCWORDH) != SYNCWORDH || (buf[1] & SYNCWORDL) != SYNCWORDL) - return -1; - - fh = ((FrameHeader *)(mp3DecInfo->FrameHeaderPS)); - - /* read header fields - use bitmasks instead of GetBits() for speed, since format never varies */ - verIdx = (buf[1] >> 3) & 0x03; - fh->ver = (MPEGVersion)( verIdx == 0 ? MPEG25 : ((verIdx & 0x01) ? MPEG1 : MPEG2) ); - fh->layer = 4 - ((buf[1] >> 1) & 0x03); /* easy mapping of index to layer number, 4 = error */ - fh->crc = 1 - ((buf[1] >> 0) & 0x01); - fh->brIdx = (buf[2] >> 4) & 0x0f; - fh->srIdx = (buf[2] >> 2) & 0x03; - fh->paddingBit = (buf[2] >> 1) & 0x01; - fh->privateBit = (buf[2] >> 0) & 0x01; - fh->sMode = (StereoMode)((buf[3] >> 6) & 0x03); /* maps to correct enum (see definition) */ - fh->modeExt = (buf[3] >> 4) & 0x03; - fh->copyFlag = (buf[3] >> 3) & 0x01; - fh->origFlag = (buf[3] >> 2) & 0x01; - fh->emphasis = (buf[3] >> 0) & 0x03; - - /* check parameters to avoid indexing tables with bad values */ - if (fh->srIdx == 3 || fh->layer == 4 || fh->brIdx == 15) - return -1; - - fh->sfBand = &sfBandTable[fh->ver][fh->srIdx]; /* for readability (we reference sfBandTable many times in decoder) */ - if (fh->sMode != Joint) /* just to be safe (dequant, stproc check fh->modeExt) */ - fh->modeExt = 0; - - /* init user-accessible data */ - mp3DecInfo->nChans = (fh->sMode == Mono ? 1 : 2); - mp3DecInfo->samprate = samplerateTab[fh->ver][fh->srIdx]; - mp3DecInfo->nGrans = (fh->ver == MPEG1 ? NGRANS_MPEG1 : NGRANS_MPEG2); - mp3DecInfo->nGranSamps = ((int)samplesPerFrameTab[fh->ver][fh->layer - 1]) / mp3DecInfo->nGrans; - mp3DecInfo->layer = fh->layer; - mp3DecInfo->version = fh->ver; - - /* get bitrate and nSlots from table, unless brIdx == 0 (free mode) in which case caller must figure it out himself - * question - do we want to overwrite mp3DecInfo->bitrate with 0 each time if it's free mode, and - * copy the pre-calculated actual free bitrate into it in mp3dec.c (according to the spec, - * this shouldn't be necessary, since it should be either all frames free or none free) - */ - if (fh->brIdx) { - mp3DecInfo->bitrate = ((int)bitrateTab[fh->ver][fh->layer - 1][fh->brIdx]) * 1000; - - /* nSlots = total frame bytes (from table) - sideInfo bytes - header - CRC (if present) + pad (if present) */ - mp3DecInfo->nSlots = (int)slotTab[fh->ver][fh->srIdx][fh->brIdx] - - (int)sideBytesTab[fh->ver][(fh->sMode == Mono ? 0 : 1)] - - 4 - (fh->crc ? 2 : 0) + (fh->paddingBit ? 1 : 0); - } - - /* load crc word, if enabled, and return length of frame header (in bytes) */ - if (fh->crc) { - fh->CRCWord = ((int)buf[4] << 8 | (int)buf[5] << 0); - return 6; - } else { - fh->CRCWord = 0; - return 4; - } +int UnpackFrameHeader(MP3DecInfo *mp3DecInfo, unsigned char *buf) { + + int verIdx; + FrameHeader *fh; + + /* validate pointers and sync word */ + if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || (buf[0] & SYNCWORDH) != SYNCWORDH || (buf[1] & SYNCWORDL) != SYNCWORDL) { + return -1; + } + + fh = ((FrameHeader *)(mp3DecInfo->FrameHeaderPS)); + + /* read header fields - use bitmasks instead of GetBits() for speed, since format never varies */ + verIdx = (buf[1] >> 3) & 0x03; + fh->ver = (MPEGVersion)(verIdx == 0 ? MPEG25 : ((verIdx & 0x01) ? MPEG1 : MPEG2)); + fh->layer = 4 - ((buf[1] >> 1) & 0x03); /* easy mapping of index to layer number, 4 = error */ + fh->crc = 1 - ((buf[1] >> 0) & 0x01); + fh->brIdx = (buf[2] >> 4) & 0x0f; + fh->srIdx = (buf[2] >> 2) & 0x03; + fh->paddingBit = (buf[2] >> 1) & 0x01; + fh->privateBit = (buf[2] >> 0) & 0x01; + fh->sMode = (StereoMode)((buf[3] >> 6) & 0x03); /* maps to correct enum (see definition) */ + fh->modeExt = (buf[3] >> 4) & 0x03; + fh->copyFlag = (buf[3] >> 3) & 0x01; + fh->origFlag = (buf[3] >> 2) & 0x01; + fh->emphasis = (buf[3] >> 0) & 0x03; + + /* check parameters to avoid indexing tables with bad values */ + if (fh->srIdx == 3 || fh->layer == 4 || fh->brIdx == 15) { + return -1; + } + + fh->sfBand = &sfBandTable[fh->ver][fh->srIdx]; /* for readability (we reference sfBandTable many times in decoder) */ + if (fh->sMode != Joint) { /* just to be safe (dequant, stproc check fh->modeExt) */ + fh->modeExt = 0; + } + + /* init user-accessible data */ + mp3DecInfo->nChans = (fh->sMode == Mono ? 1 : 2); + mp3DecInfo->samprate = samplerateTab[fh->ver][fh->srIdx]; + mp3DecInfo->nGrans = (fh->ver == MPEG1 ? NGRANS_MPEG1 : NGRANS_MPEG2); + mp3DecInfo->nGranSamps = ((int)samplesPerFrameTab[fh->ver][fh->layer - 1]) / mp3DecInfo->nGrans; + mp3DecInfo->layer = fh->layer; + mp3DecInfo->version = fh->ver; + + /* get bitrate and nSlots from table, unless brIdx == 0 (free mode) in which case caller must figure it out himself + question - do we want to overwrite mp3DecInfo->bitrate with 0 each time if it's free mode, and + copy the pre-calculated actual free bitrate into it in mp3dec.c (according to the spec, + this shouldn't be necessary, since it should be either all frames free or none free) + */ + if (fh->brIdx) { + mp3DecInfo->bitrate = ((int)bitrateTab[fh->ver][fh->layer - 1][fh->brIdx]) * 1000; + + /* nSlots = total frame bytes (from table) - sideInfo bytes - header - CRC (if present) + pad (if present) */ + mp3DecInfo->nSlots = (int)slotTab[fh->ver][fh->srIdx][fh->brIdx] - + (int)sideBytesTab[fh->ver][(fh->sMode == Mono ? 0 : 1)] - + 4 - (fh->crc ? 2 : 0) + (fh->paddingBit ? 1 : 0); + } + + /* load crc word, if enabled, and return length of frame header (in bytes) */ + if (fh->crc) { + fh->CRCWord = ((int)buf[4] << 8 | (int)buf[5] << 0); + return 6; + } else { + fh->CRCWord = 0; + return 4; + } } /************************************************************************************** - * Function: UnpackSideInfo - * - * Description: parse the fields of the MP3 side info header - * - * Inputs: MP3DecInfo structure filled by UnpackFrameHeader() - * buffer pointing to the MP3 side info data - * - * Outputs: updated mainDataBegin in MP3DecInfo struct - * updated private (platform-specific) SideInfo struct - * - * Return: length (in bytes) of side info data - * -1 if null input pointers + Function: UnpackSideInfo + + Description: parse the fields of the MP3 side info header + + Inputs: MP3DecInfo structure filled by UnpackFrameHeader() + buffer pointing to the MP3 side info data + + Outputs: updated mainDataBegin in MP3DecInfo struct + updated private (platform-specific) SideInfo struct + + Return: length (in bytes) of side info data + -1 if null input pointers **************************************************************************************/ -int UnpackSideInfo(MP3DecInfo *mp3DecInfo, unsigned char *buf) -{ - int gr, ch, bd, nBytes; - BitStreamInfo bitStreamInfo, *bsi; - FrameHeader *fh; - SideInfo *si; - SideInfoSub *sis; - - /* validate pointers and sync word */ - if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || !mp3DecInfo->SideInfoPS) - return -1; - - fh = ((FrameHeader *)(mp3DecInfo->FrameHeaderPS)); - si = ((SideInfo *)(mp3DecInfo->SideInfoPS)); - - bsi = &bitStreamInfo; - if (fh->ver == MPEG1) { - /* MPEG 1 */ - nBytes = (fh->sMode == Mono ? SIBYTES_MPEG1_MONO : SIBYTES_MPEG1_STEREO); - SetBitstreamPointer(bsi, nBytes, buf); - si->mainDataBegin = GetBits(bsi, 9); - si->privateBits = GetBits(bsi, (fh->sMode == Mono ? 5 : 3)); - - for (ch = 0; ch < mp3DecInfo->nChans; ch++) - for (bd = 0; bd < MAX_SCFBD; bd++) - si->scfsi[ch][bd] = GetBits(bsi, 1); - } else { - /* MPEG 2, MPEG 2.5 */ - nBytes = (fh->sMode == Mono ? SIBYTES_MPEG2_MONO : SIBYTES_MPEG2_STEREO); - SetBitstreamPointer(bsi, nBytes, buf); - si->mainDataBegin = GetBits(bsi, 8); - si->privateBits = GetBits(bsi, (fh->sMode == Mono ? 1 : 2)); - } - - for(gr =0; gr < mp3DecInfo->nGrans; gr++) { - for (ch = 0; ch < mp3DecInfo->nChans; ch++) { - sis = &si->sis[gr][ch]; /* side info subblock for this granule, channel */ - - sis->part23Length = GetBits(bsi, 12); - sis->nBigvals = GetBits(bsi, 9); - sis->globalGain = GetBits(bsi, 8); - sis->sfCompress = GetBits(bsi, (fh->ver == MPEG1 ? 4 : 9)); - sis->winSwitchFlag = GetBits(bsi, 1); - - if(sis->winSwitchFlag) { - /* this is a start, stop, short, or mixed block */ - sis->blockType = GetBits(bsi, 2); /* 0 = normal, 1 = start, 2 = short, 3 = stop */ - sis->mixedBlock = GetBits(bsi, 1); /* 0 = not mixed, 1 = mixed */ - sis->tableSelect[0] = GetBits(bsi, 5); - sis->tableSelect[1] = GetBits(bsi, 5); - sis->tableSelect[2] = 0; /* unused */ - sis->subBlockGain[0] = GetBits(bsi, 3); - sis->subBlockGain[1] = GetBits(bsi, 3); - sis->subBlockGain[2] = GetBits(bsi, 3); - - /* TODO - check logic */ - if (sis->blockType == 0) { - /* this should not be allowed, according to spec */ - sis->nBigvals = 0; - sis->part23Length = 0; - sis->sfCompress = 0; - } else if (sis->blockType == 2 && sis->mixedBlock == 0) { - /* short block, not mixed */ - sis->region0Count = 8; - } else { - /* start, stop, or short-mixed */ - sis->region0Count = 7; - } - sis->region1Count = 20 - sis->region0Count; - } else { - /* this is a normal block */ - sis->blockType = 0; - sis->mixedBlock = 0; - sis->tableSelect[0] = GetBits(bsi, 5); - sis->tableSelect[1] = GetBits(bsi, 5); - sis->tableSelect[2] = GetBits(bsi, 5); - sis->region0Count = GetBits(bsi, 4); - sis->region1Count = GetBits(bsi, 3); - } - sis->preFlag = (fh->ver == MPEG1 ? GetBits(bsi, 1) : 0); - sis->sfactScale = GetBits(bsi, 1); - sis->count1TableSelect = GetBits(bsi, 1); - } - } - mp3DecInfo->mainDataBegin = si->mainDataBegin; /* needed by main decode loop */ - - ASSERT(nBytes == CalcBitsUsed(bsi, buf, 0) >> 3); - - return nBytes; +int UnpackSideInfo(MP3DecInfo *mp3DecInfo, unsigned char *buf) { + int gr, ch, bd, nBytes; + BitStreamInfo bitStreamInfo, *bsi; + FrameHeader *fh; + SideInfo *si; + SideInfoSub *sis; + + /* validate pointers and sync word */ + if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || !mp3DecInfo->SideInfoPS) { + return -1; + } + + fh = ((FrameHeader *)(mp3DecInfo->FrameHeaderPS)); + si = ((SideInfo *)(mp3DecInfo->SideInfoPS)); + + bsi = &bitStreamInfo; + if (fh->ver == MPEG1) { + /* MPEG 1 */ + nBytes = (fh->sMode == Mono ? SIBYTES_MPEG1_MONO : SIBYTES_MPEG1_STEREO); + SetBitstreamPointer(bsi, nBytes, buf); + si->mainDataBegin = GetBits(bsi, 9); + si->privateBits = GetBits(bsi, (fh->sMode == Mono ? 5 : 3)); + + for (ch = 0; ch < mp3DecInfo->nChans; ch++) + for (bd = 0; bd < MAX_SCFBD; bd++) { + si->scfsi[ch][bd] = GetBits(bsi, 1); + } + } else { + /* MPEG 2, MPEG 2.5 */ + nBytes = (fh->sMode == Mono ? SIBYTES_MPEG2_MONO : SIBYTES_MPEG2_STEREO); + SetBitstreamPointer(bsi, nBytes, buf); + si->mainDataBegin = GetBits(bsi, 8); + si->privateBits = GetBits(bsi, (fh->sMode == Mono ? 1 : 2)); + } + + for (gr = 0; gr < mp3DecInfo->nGrans; gr++) { + for (ch = 0; ch < mp3DecInfo->nChans; ch++) { + sis = &si->sis[gr][ch]; /* side info subblock for this granule, channel */ + + sis->part23Length = GetBits(bsi, 12); + sis->nBigvals = GetBits(bsi, 9); + sis->globalGain = GetBits(bsi, 8); + sis->sfCompress = GetBits(bsi, (fh->ver == MPEG1 ? 4 : 9)); + sis->winSwitchFlag = GetBits(bsi, 1); + + if (sis->winSwitchFlag) { + /* this is a start, stop, short, or mixed block */ + sis->blockType = GetBits(bsi, 2); /* 0 = normal, 1 = start, 2 = short, 3 = stop */ + sis->mixedBlock = GetBits(bsi, 1); /* 0 = not mixed, 1 = mixed */ + sis->tableSelect[0] = GetBits(bsi, 5); + sis->tableSelect[1] = GetBits(bsi, 5); + sis->tableSelect[2] = 0; /* unused */ + sis->subBlockGain[0] = GetBits(bsi, 3); + sis->subBlockGain[1] = GetBits(bsi, 3); + sis->subBlockGain[2] = GetBits(bsi, 3); + + /* TODO - check logic */ + if (sis->blockType == 0) { + /* this should not be allowed, according to spec */ + sis->nBigvals = 0; + sis->part23Length = 0; + sis->sfCompress = 0; + } else if (sis->blockType == 2 && sis->mixedBlock == 0) { + /* short block, not mixed */ + sis->region0Count = 8; + } else { + /* start, stop, or short-mixed */ + sis->region0Count = 7; + } + sis->region1Count = 20 - sis->region0Count; + } else { + /* this is a normal block */ + sis->blockType = 0; + sis->mixedBlock = 0; + sis->tableSelect[0] = GetBits(bsi, 5); + sis->tableSelect[1] = GetBits(bsi, 5); + sis->tableSelect[2] = GetBits(bsi, 5); + sis->region0Count = GetBits(bsi, 4); + sis->region1Count = GetBits(bsi, 3); + } + sis->preFlag = (fh->ver == MPEG1 ? GetBits(bsi, 1) : 0); + sis->sfactScale = GetBits(bsi, 1); + sis->count1TableSelect = GetBits(bsi, 1); + } + } + mp3DecInfo->mainDataBegin = si->mainDataBegin; /* needed by main decode loop */ + + ASSERT(nBytes == CalcBitsUsed(bsi, buf, 0) >> 3); + + return nBytes; } diff --git a/src/libhelix-mp3/buffers.c b/src/libhelix-mp3/buffers.c index 52b9bcf7..184abbf1 100644 --- a/src/libhelix-mp3/buffers.c +++ b/src/libhelix-mp3/buffers.c @@ -1,73 +1,73 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * buffers.c - allocation and freeing of internal MP3 decoder buffers - * - * All memory allocation for the codec is done in this file, so if you don't want - * to use other the default system malloc() and free() for heap management this is - * the only file you'll need to change. + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + buffers.c - allocation and freeing of internal MP3 decoder buffers + + All memory allocation for the codec is done in this file, so if you don't want + to use other the default system malloc() and free() for heap management this is + the only file you'll need to change. **************************************************************************************/ -//#include "hlxclib/stdlib.h" /* for malloc, free */ +//#include "hlxclib/stdlib.h" /* for malloc, free */ #include #include #include "coder.h" /************************************************************************************** - * Function: ClearBuffer - * - * Description: fill buffer with 0's - * - * Inputs: pointer to buffer - * number of bytes to fill with 0 - * - * Outputs: cleared buffer - * - * Return: none - * - * Notes: slow, platform-independent equivalent to memset(buf, 0, nBytes) + Function: ClearBuffer + + Description: fill buffer with 0's + + Inputs: pointer to buffer + number of bytes to fill with 0 + + Outputs: cleared buffer + + Return: none + + Notes: slow, platform-independent equivalent to memset(buf, 0, nBytes) **************************************************************************************/ #define ClearBuffer(buf, nBytes) memset(buf, 0, nBytes) //fb /* -static void ClearBuffer(void *buf, int nBytes) -{ + static void ClearBuffer(void *buf, int nBytes) + { int i; unsigned char *cbuf = (unsigned char *)buf; @@ -76,102 +76,102 @@ static void ClearBuffer(void *buf, int nBytes) //fb memset(buf, 0, nBytes) - + return; -} + } */ /************************************************************************************** - * Function: AllocateBuffers - * - * Description: allocate all the memory needed for the MP3 decoder - * - * Inputs: none - * - * Outputs: none - * - * Return: pointer to MP3DecInfo structure (initialized with pointers to all - * the internal buffers needed for decoding, all other members of - * MP3DecInfo structure set to 0) - * - * Notes: if one or more mallocs fail, function frees any buffers already - * allocated before returning + Function: AllocateBuffers + + Description: allocate all the memory needed for the MP3 decoder + + Inputs: none + + Outputs: none + + Return: pointer to MP3DecInfo structure (initialized with pointers to all + the internal buffers needed for decoding, all other members of + MP3DecInfo structure set to 0) + + Notes: if one or more mallocs fail, function frees any buffers already + allocated before returning **************************************************************************************/ -MP3DecInfo *AllocateBuffers(void) -{ - MP3DecInfo *mp3DecInfo; - FrameHeader *fh; - SideInfo *si; - ScaleFactorInfo *sfi; - HuffmanInfo *hi; - DequantInfo *di; - IMDCTInfo *mi; - SubbandInfo *sbi; - - mp3DecInfo = (MP3DecInfo *)malloc(sizeof(MP3DecInfo)); - if (!mp3DecInfo) - return 0; - ClearBuffer(mp3DecInfo, sizeof(MP3DecInfo)); - - fh = (FrameHeader *) malloc(sizeof(FrameHeader)); - si = (SideInfo *) malloc(sizeof(SideInfo)); - sfi = (ScaleFactorInfo *) malloc(sizeof(ScaleFactorInfo)); - hi = (HuffmanInfo *) malloc(sizeof(HuffmanInfo)); - di = (DequantInfo *) malloc(sizeof(DequantInfo)); - mi = (IMDCTInfo *) malloc(sizeof(IMDCTInfo)); - sbi = (SubbandInfo *) malloc(sizeof(SubbandInfo)); - - mp3DecInfo->FrameHeaderPS = (void *)fh; - mp3DecInfo->SideInfoPS = (void *)si; - mp3DecInfo->ScaleFactorInfoPS = (void *)sfi; - mp3DecInfo->HuffmanInfoPS = (void *)hi; - mp3DecInfo->DequantInfoPS = (void *)di; - mp3DecInfo->IMDCTInfoPS = (void *)mi; - mp3DecInfo->SubbandInfoPS = (void *)sbi; - - if (!fh || !si || !sfi || !hi || !di || !mi || !sbi) { - FreeBuffers(mp3DecInfo); /* safe to call - only frees memory that was successfully allocated */ - return 0; - } - - /* important to do this - DSP primitives assume a bunch of state variables are 0 on first use */ - ClearBuffer(fh, sizeof(FrameHeader)); - ClearBuffer(si, sizeof(SideInfo)); - ClearBuffer(sfi, sizeof(ScaleFactorInfo)); - ClearBuffer(hi, sizeof(HuffmanInfo)); - ClearBuffer(di, sizeof(DequantInfo)); - ClearBuffer(mi, sizeof(IMDCTInfo)); - ClearBuffer(sbi, sizeof(SubbandInfo)); - - return mp3DecInfo; +MP3DecInfo *AllocateBuffers(void) { + MP3DecInfo *mp3DecInfo; + FrameHeader *fh; + SideInfo *si; + ScaleFactorInfo *sfi; + HuffmanInfo *hi; + DequantInfo *di; + IMDCTInfo *mi; + SubbandInfo *sbi; + + mp3DecInfo = (MP3DecInfo *)malloc(sizeof(MP3DecInfo)); + if (!mp3DecInfo) { + return 0; + } + ClearBuffer(mp3DecInfo, sizeof(MP3DecInfo)); + + fh = (FrameHeader *) malloc(sizeof(FrameHeader)); + si = (SideInfo *) malloc(sizeof(SideInfo)); + sfi = (ScaleFactorInfo *) malloc(sizeof(ScaleFactorInfo)); + hi = (HuffmanInfo *) malloc(sizeof(HuffmanInfo)); + di = (DequantInfo *) malloc(sizeof(DequantInfo)); + mi = (IMDCTInfo *) malloc(sizeof(IMDCTInfo)); + sbi = (SubbandInfo *) malloc(sizeof(SubbandInfo)); + + mp3DecInfo->FrameHeaderPS = (void *)fh; + mp3DecInfo->SideInfoPS = (void *)si; + mp3DecInfo->ScaleFactorInfoPS = (void *)sfi; + mp3DecInfo->HuffmanInfoPS = (void *)hi; + mp3DecInfo->DequantInfoPS = (void *)di; + mp3DecInfo->IMDCTInfoPS = (void *)mi; + mp3DecInfo->SubbandInfoPS = (void *)sbi; + + if (!fh || !si || !sfi || !hi || !di || !mi || !sbi) { + FreeBuffers(mp3DecInfo); /* safe to call - only frees memory that was successfully allocated */ + return 0; + } + + /* important to do this - DSP primitives assume a bunch of state variables are 0 on first use */ + ClearBuffer(fh, sizeof(FrameHeader)); + ClearBuffer(si, sizeof(SideInfo)); + ClearBuffer(sfi, sizeof(ScaleFactorInfo)); + ClearBuffer(hi, sizeof(HuffmanInfo)); + ClearBuffer(di, sizeof(DequantInfo)); + ClearBuffer(mi, sizeof(IMDCTInfo)); + ClearBuffer(sbi, sizeof(SubbandInfo)); + + return mp3DecInfo; } #define SAFE_FREE(x) {if (x) free(x); (x) = 0;} /* helper macro */ /************************************************************************************** - * Function: FreeBuffers - * - * Description: frees all the memory used by the MP3 decoder - * - * Inputs: pointer to initialized MP3DecInfo structure - * - * Outputs: none - * - * Return: none - * - * Notes: safe to call even if some buffers were not allocated (uses SAFE_FREE) + Function: FreeBuffers + + Description: frees all the memory used by the MP3 decoder + + Inputs: pointer to initialized MP3DecInfo structure + + Outputs: none + + Return: none + + Notes: safe to call even if some buffers were not allocated (uses SAFE_FREE) **************************************************************************************/ -void FreeBuffers(MP3DecInfo *mp3DecInfo) -{ - if (!mp3DecInfo) - return; - - SAFE_FREE(mp3DecInfo->FrameHeaderPS); - SAFE_FREE(mp3DecInfo->SideInfoPS); - SAFE_FREE(mp3DecInfo->ScaleFactorInfoPS); - SAFE_FREE(mp3DecInfo->HuffmanInfoPS); - SAFE_FREE(mp3DecInfo->DequantInfoPS); - SAFE_FREE(mp3DecInfo->IMDCTInfoPS); - SAFE_FREE(mp3DecInfo->SubbandInfoPS); - - SAFE_FREE(mp3DecInfo); +void FreeBuffers(MP3DecInfo *mp3DecInfo) { + if (!mp3DecInfo) { + return; + } + + SAFE_FREE(mp3DecInfo->FrameHeaderPS); + SAFE_FREE(mp3DecInfo->SideInfoPS); + SAFE_FREE(mp3DecInfo->ScaleFactorInfoPS); + SAFE_FREE(mp3DecInfo->HuffmanInfoPS); + SAFE_FREE(mp3DecInfo->DequantInfoPS); + SAFE_FREE(mp3DecInfo->IMDCTInfoPS); + SAFE_FREE(mp3DecInfo->SubbandInfoPS); + + SAFE_FREE(mp3DecInfo); } diff --git a/src/libhelix-mp3/coder.h b/src/libhelix-mp3/coder.h index 5cc3ae43..fb2f031c 100644 --- a/src/libhelix-mp3/coder.h +++ b/src/libhelix-mp3/coder.h @@ -1,44 +1,44 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * coder.h - private, implementation-specific header file + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + coder.h - private, implementation-specific header file **************************************************************************************/ #ifndef _CODER_H @@ -121,17 +121,17 @@ /* map these to the corresponding 2-bit values in the frame header */ typedef enum { - Stereo = 0x00, /* two independent channels, but L and R frames might have different # of bits */ - Joint = 0x01, /* coupled channels - layer III: mix of M-S and intensity, Layers I/II: intensity and direct coding only */ - Dual = 0x02, /* two independent channels, L and R always have exactly 1/2 the total bitrate */ - Mono = 0x03 /* one channel */ + Stereo = 0x00, /* two independent channels, but L and R frames might have different # of bits */ + Joint = 0x01, /* coupled channels - layer III: mix of M-S and intensity, Layers I/II: intensity and direct coding only */ + Dual = 0x02, /* two independent channels, L and R always have exactly 1/2 the total bitrate */ + Mono = 0x03 /* one channel */ } StereoMode; typedef struct _BitStreamInfo { - unsigned char *bytePtr; - unsigned int iCache; - int cachedBits; - int nBytes; + unsigned char *bytePtr; + unsigned int iCache; + int cachedBits; + int nBytes; } BitStreamInfo; typedef struct _FrameHeader { @@ -149,11 +149,11 @@ typedef struct _FrameHeader { int emphasis; /* deemphasis mode */ int CRCWord; /* CRC word (16 bits, 0 if crc not enabled) */ - const SFBandTable *sfBand; + const SFBandTable *sfBand; } FrameHeader; typedef struct _SideInfoSub { - int part23Length; /* number of bits in main data */ + int part23Length; /* number of bits in main data */ int nBigvals; /* 2x this = first set of Huffman cw's (maximum amplitude can be > 1) */ int globalGain; /* overall gain for dequantizer */ int sfCompress; /* unpacked to figure out number of bits in scale factors */ @@ -170,91 +170,91 @@ typedef struct _SideInfoSub { } SideInfoSub; typedef struct _SideInfo { - int mainDataBegin; - int privateBits; - int scfsi[MAX_NCHAN][MAX_SCFBD]; /* 4 scalefactor bands per channel */ - - SideInfoSub sis[MAX_NGRAN][MAX_NCHAN]; + int mainDataBegin; + int privateBits; + int scfsi[MAX_NCHAN][MAX_SCFBD]; /* 4 scalefactor bands per channel */ + + SideInfoSub sis[MAX_NGRAN][MAX_NCHAN]; } SideInfo; typedef struct { int cbType; /* pure long = 0, pure short = 1, mixed = 2 */ int cbEndS[3]; /* number nonzero short cb's, per subbblock */ - int cbEndSMax; /* max of cbEndS[] */ + int cbEndSMax; /* max of cbEndS[] */ int cbEndL; /* number nonzero long cb's */ } CriticalBandInfo; typedef struct _DequantInfo { - int workBuf[MAX_REORDER_SAMPS]; /* workbuf for reordering short blocks */ - CriticalBandInfo cbi[MAX_NCHAN]; /* filled in dequantizer, used in joint stereo reconstruction */ + int workBuf[MAX_REORDER_SAMPS]; /* workbuf for reordering short blocks */ + CriticalBandInfo cbi[MAX_NCHAN]; /* filled in dequantizer, used in joint stereo reconstruction */ } DequantInfo; typedef struct _HuffmanInfo { - int huffDecBuf[MAX_NCHAN][MAX_NSAMP]; /* used both for decoded Huffman values and dequantized coefficients */ - int nonZeroBound[MAX_NCHAN]; /* number of coeffs in huffDecBuf[ch] which can be > 0 */ - int gb[MAX_NCHAN]; /* minimum number of guard bits in huffDecBuf[ch] */ + int huffDecBuf[MAX_NCHAN][MAX_NSAMP]; /* used both for decoded Huffman values and dequantized coefficients */ + int nonZeroBound[MAX_NCHAN]; /* number of coeffs in huffDecBuf[ch] which can be > 0 */ + int gb[MAX_NCHAN]; /* minimum number of guard bits in huffDecBuf[ch] */ } HuffmanInfo; typedef enum _HuffTabType { - noBits, - oneShot, - loopNoLinbits, - loopLinbits, - quadA, - quadB, - invalidTab + noBits, + oneShot, + loopNoLinbits, + loopLinbits, + quadA, + quadB, + invalidTab } HuffTabType; typedef struct _HuffTabLookup { - int linBits; - int /*HuffTabType*/ tabType; + int linBits; + int /*HuffTabType*/ tabType; } HuffTabLookup; typedef struct _IMDCTInfo { - int outBuf[MAX_NCHAN][BLOCK_SIZE][NBANDS]; /* output of IMDCT */ - int overBuf[MAX_NCHAN][MAX_NSAMP / 2]; /* overlap-add buffer (by symmetry, only need 1/2 size) */ - int numPrevIMDCT[MAX_NCHAN]; /* how many IMDCT's calculated in this channel on prev. granule */ - int prevType[MAX_NCHAN]; - int prevWinSwitch[MAX_NCHAN]; - int gb[MAX_NCHAN]; + int outBuf[MAX_NCHAN][BLOCK_SIZE][NBANDS]; /* output of IMDCT */ + int overBuf[MAX_NCHAN][MAX_NSAMP / 2]; /* overlap-add buffer (by symmetry, only need 1/2 size) */ + int numPrevIMDCT[MAX_NCHAN]; /* how many IMDCT's calculated in this channel on prev. granule */ + int prevType[MAX_NCHAN]; + int prevWinSwitch[MAX_NCHAN]; + int gb[MAX_NCHAN]; } IMDCTInfo; typedef struct _BlockCount { - int nBlocksLong; - int nBlocksTotal; - int nBlocksPrev; - int prevType; - int prevWinSwitch; - int currWinSwitch; - int gbIn; - int gbOut; + int nBlocksLong; + int nBlocksTotal; + int nBlocksPrev; + int prevType; + int prevWinSwitch; + int currWinSwitch; + int gbIn; + int gbOut; } BlockCount; /* max bits in scalefactors = 5, so use char's to save space */ typedef struct _ScaleFactorInfoSub { - char l[23]; /* [band] */ - char s[13][3]; /* [band][window] */ -} ScaleFactorInfoSub; + char l[23]; /* [band] */ + char s[13][3]; /* [band][window] */ +} ScaleFactorInfoSub; /* used in MPEG 2, 2.5 intensity (joint) stereo only */ typedef struct _ScaleFactorJS { - int intensityScale; - int slen[4]; - int nr[4]; + int intensityScale; + int slen[4]; + int nr[4]; } ScaleFactorJS; typedef struct _ScaleFactorInfo { - ScaleFactorInfoSub sfis[MAX_NGRAN][MAX_NCHAN]; - ScaleFactorJS sfjs; + ScaleFactorInfoSub sfis[MAX_NGRAN][MAX_NCHAN]; + ScaleFactorJS sfjs; } ScaleFactorInfo; -/* NOTE - could get by with smaller vbuf if memory is more important than speed - * (in Subband, instead of replicating each block in FDCT32 you would do a memmove on the - * last 15 blocks to shift them down one, a hardware style FIFO) - */ +/* NOTE - could get by with smaller vbuf if memory is more important than speed + (in Subband, instead of replicating each block in FDCT32 you would do a memmove on the + last 15 blocks to shift them down one, a hardware style FIFO) +*/ typedef struct _SubbandInfo { - int vbuf[MAX_NCHAN * VBUF_LENGTH]; /* vbuf for fast DCT-based synthesis PQMF - double size for speed (no modulo indexing) */ - int vindex; /* internal index for tracking position in vbuf */ + int vbuf[MAX_NCHAN * VBUF_LENGTH]; /* vbuf for fast DCT-based synthesis PQMF - double size for speed (no modulo indexing) */ + int vindex; /* internal index for tracking position in vbuf */ } SubbandInfo; /* bitstream.c */ @@ -263,13 +263,13 @@ unsigned int GetBits(BitStreamInfo *bsi, int nBits); int CalcBitsUsed(BitStreamInfo *bsi, unsigned char *startBuf, int startOffset); /* dequant.c, dqchan.c, stproc.c */ -int DequantChannel(int *sampleBuf, int *workBuf, int *nonZeroBound, FrameHeader *fh, SideInfoSub *sis, - ScaleFactorInfoSub *sfis, CriticalBandInfo *cbi); +int DequantChannel(int *sampleBuf, int *workBuf, int *nonZeroBound, FrameHeader *fh, SideInfoSub *sis, + ScaleFactorInfoSub *sfis, CriticalBandInfo *cbi); void MidSideProc(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, int mOut[2]); -void IntensityProcMPEG1(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, FrameHeader *fh, ScaleFactorInfoSub *sfis, - CriticalBandInfo *cbi, int midSideFlag, int mixFlag, int mOut[2]); -void IntensityProcMPEG2(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, FrameHeader *fh, ScaleFactorInfoSub *sfis, - CriticalBandInfo *cbi, ScaleFactorJS *sfjs, int midSideFlag, int mixFlag, int mOut[2]); +void IntensityProcMPEG1(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, FrameHeader *fh, ScaleFactorInfoSub *sfis, + CriticalBandInfo *cbi, int midSideFlag, int mixFlag, int mOut[2]); +void IntensityProcMPEG2(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, FrameHeader *fh, ScaleFactorInfoSub *sfis, + CriticalBandInfo *cbi, ScaleFactorJS *sfjs, int midSideFlag, int mixFlag, int mOut[2]); /* dct32.c */ // about 1 ms faster in RAM, but very large @@ -279,15 +279,15 @@ void FDCT32(int *x, int *d, int offset, int oddBlock, int gb);// __attribute__ ( extern const HuffTabLookup huffTabLookup[HUFF_PAIRTABS]; extern const int huffTabOffset[HUFF_PAIRTABS]; extern const unsigned short huffTable[]; -extern const unsigned char quadTable[64+16]; +extern const unsigned char quadTable[64 + 16]; extern const int quadTabOffset[2]; extern const int quadTabMaxBits[2]; -/* polyphase.c (or asmpoly.s) - * some platforms require a C++ compile of all source files, - * so if we're compiling C as C++ and using native assembly - * for these functions we need to prevent C++ name mangling. - */ +/* polyphase.c (or asmpoly.s) + some platforms require a C++ compile of all source files, + so if we're compiling C as C++ and using native assembly + for these functions we need to prevent C++ name mangling. +*/ #ifdef __cplusplus extern "C" { #endif diff --git a/src/libhelix-mp3/dct32.c b/src/libhelix-mp3/dct32.c index 978ffb43..d872dc34 100644 --- a/src/libhelix-mp3/dct32.c +++ b/src/libhelix-mp3/dct32.c @@ -1,45 +1,45 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * dct32.c - optimized implementations of 32-point DCT for matrixing stage of - * polyphase filter + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + dct32.c - optimized implementations of 32-point DCT for matrixing stage of + polyphase filter **************************************************************************************/ #include "coder.h" @@ -84,24 +84,24 @@ // faster in ROM static const int dcttab[48] PROGMEM = { - /* first pass */ - COS0_0, COS0_15, COS1_0, /* 31, 27, 31 */ - COS0_1, COS0_14, COS1_1, /* 31, 29, 31 */ - COS0_2, COS0_13, COS1_2, /* 31, 29, 31 */ - COS0_3, COS0_12, COS1_3, /* 31, 30, 31 */ - COS0_4, COS0_11, COS1_4, /* 31, 30, 31 */ - COS0_5, COS0_10, COS1_5, /* 31, 31, 30 */ - COS0_6, COS0_9, COS1_6, /* 31, 31, 30 */ - COS0_7, COS0_8, COS1_7, /* 31, 31, 28 */ - /* second pass */ - COS2_0, COS2_3, COS3_0, /* 31, 29, 31 */ - COS2_1, COS2_2, COS3_1, /* 31, 31, 30 */ - -COS2_0, -COS2_3, COS3_0, /* 31, 29, 31 */ - -COS2_1, -COS2_2, COS3_1, /* 31, 31, 30 */ - COS2_0, COS2_3, COS3_0, /* 31, 29, 31 */ - COS2_1, COS2_2, COS3_1, /* 31, 31, 30 */ - -COS2_0, -COS2_3, COS3_0, /* 31, 29, 31 */ - -COS2_1, -COS2_2, COS3_1, /* 31, 31, 30 */ + /* first pass */ + COS0_0, COS0_15, COS1_0, /* 31, 27, 31 */ + COS0_1, COS0_14, COS1_1, /* 31, 29, 31 */ + COS0_2, COS0_13, COS1_2, /* 31, 29, 31 */ + COS0_3, COS0_12, COS1_3, /* 31, 30, 31 */ + COS0_4, COS0_11, COS1_4, /* 31, 30, 31 */ + COS0_5, COS0_10, COS1_5, /* 31, 31, 30 */ + COS0_6, COS0_9, COS1_6, /* 31, 31, 30 */ + COS0_7, COS0_8, COS1_7, /* 31, 31, 28 */ + /* second pass */ + COS2_0, COS2_3, COS3_0, /* 31, 29, 31 */ + COS2_1, COS2_2, COS3_1, /* 31, 31, 30 */ + -COS2_0, -COS2_3, COS3_0, /* 31, 29, 31 */ + -COS2_1, -COS2_2, COS3_1, /* 31, 31, 30 */ + COS2_0, COS2_3, COS3_0, /* 31, 29, 31 */ + COS2_1, COS2_2, COS3_1, /* 31, 31, 30 */ + -COS2_0, -COS2_3, COS3_0, /* 31, 29, 31 */ + -COS2_1, -COS2_2, COS3_1, /* 31, 31, 30 */ }; #define D32FP(i, s0, s1, s2) { \ @@ -114,168 +114,168 @@ static const int dcttab[48] PROGMEM = { } /************************************************************************************** - * Function: FDCT32 - * - * Description: Ken's highly-optimized 32-point DCT (radix-4 + radix-8) - * - * Inputs: input buffer, length = 32 samples - * require at least 6 guard bits in input vector x to avoid possibility - * of overflow in internal calculations (see bbtest_imdct test app) - * buffer offset and oddblock flag for polyphase filter input buffer - * number of guard bits in input - * - * Outputs: output buffer, data copied and interleaved for polyphase filter - * no guarantees about number of guard bits in output - * - * Return: none - * - * Notes: number of muls = 4*8 + 12*4 = 80 - * final stage of DCT is hardcoded to shuffle data into the proper order - * for the polyphase filterbank - * fully unrolled stage 1, for max precision (scale the 1/cos() factors - * differently, depending on magnitude) - * guard bit analysis verified by exhaustive testing of all 2^32 - * combinations of max pos/max neg values in x[] - * - * TODO: code organization and optimization for ARM - * possibly interleave stereo (cut # of coef loads in half - may not have - * enough registers) + Function: FDCT32 + + Description: Ken's highly-optimized 32-point DCT (radix-4 + radix-8) + + Inputs: input buffer, length = 32 samples + require at least 6 guard bits in input vector x to avoid possibility + of overflow in internal calculations (see bbtest_imdct test app) + buffer offset and oddblock flag for polyphase filter input buffer + number of guard bits in input + + Outputs: output buffer, data copied and interleaved for polyphase filter + no guarantees about number of guard bits in output + + Return: none + + Notes: number of muls = 4*8 + 12*4 = 80 + final stage of DCT is hardcoded to shuffle data into the proper order + for the polyphase filterbank + fully unrolled stage 1, for max precision (scale the 1/cos() factors + differently, depending on magnitude) + guard bit analysis verified by exhaustive testing of all 2^32 + combinations of max pos/max neg values in x[] + + TODO: code organization and optimization for ARM + possibly interleave stereo (cut # of coef loads in half - may not have + enough registers) **************************************************************************************/ // about 1ms faster in RAM -/* attribute__ ((section (".data"))) */ void FDCT32(int *buf, int *dest, int offset, int oddBlock, int gb) -{ +/* attribute__ ((section (".data"))) */ void FDCT32(int *buf, int *dest, int offset, int oddBlock, int gb) { int i, s, tmp, es; const int *cptr = dcttab; int a0, a1, a2, a3, a4, a5, a6, a7; int b0, b1, b2, b3, b4, b5, b6, b7; - int *d; - - /* scaling - ensure at least 6 guard bits for DCT - * (in practice this is already true 99% of time, so this code is - * almost never triggered) - */ - es = 0; - if (gb < 6) { - es = 6 - gb; - for (i = 0; i < 32; i++) - buf[i] >>= es; - } - - /* first pass */ - D32FP(0, 1, 5, 1); - D32FP(1, 1, 3, 1); - D32FP(2, 1, 3, 1); - D32FP(3, 1, 2, 1); - D32FP(4, 1, 2, 1); - D32FP(5, 1, 1, 2); - D32FP(6, 1, 1, 2); - D32FP(7, 1, 1, 4); - - /* second pass */ - for (i = 4; i > 0; i--) { - a0 = buf[0]; a7 = buf[7]; a3 = buf[3]; a4 = buf[4]; - b0 = a0 + a7; b7 = MULSHIFT32(*cptr++, a0 - a7) << 1; - b3 = a3 + a4; b4 = MULSHIFT32(*cptr++, a3 - a4) << 3; - a0 = b0 + b3; a3 = MULSHIFT32(*cptr, b0 - b3) << 1; - a4 = b4 + b7; a7 = MULSHIFT32(*cptr++, b7 - b4) << 1; - - a1 = buf[1]; a6 = buf[6]; a2 = buf[2]; a5 = buf[5]; - b1 = a1 + a6; b6 = MULSHIFT32(*cptr++, a1 - a6) << 1; - b2 = a2 + a5; b5 = MULSHIFT32(*cptr++, a2 - a5) << 1; - a1 = b1 + b2; a2 = MULSHIFT32(*cptr, b1 - b2) << 2; - a5 = b5 + b6; a6 = MULSHIFT32(*cptr++, b6 - b5) << 2; - - b0 = a0 + a1; b1 = MULSHIFT32(COS4_0, a0 - a1) << 1; - b2 = a2 + a3; b3 = MULSHIFT32(COS4_0, a3 - a2) << 1; - buf[0] = b0; buf[1] = b1; - buf[2] = b2 + b3; buf[3] = b3; - - b4 = a4 + a5; b5 = MULSHIFT32(COS4_0, a4 - a5) << 1; - b6 = a6 + a7; b7 = MULSHIFT32(COS4_0, a7 - a6) << 1; - b6 += b7; - buf[4] = b4 + b6; buf[5] = b5 + b7; - buf[6] = b5 + b6; buf[7] = b7; - - buf += 8; - } - buf -= 32; /* reset */ - - /* sample 0 - always delayed one block */ - d = dest + 64*16 + ((offset - oddBlock) & 7) + (oddBlock ? 0 : VBUF_LENGTH); - s = buf[ 0]; d[0] = d[8] = s; - - /* samples 16 to 31 */ - d = dest + offset + (oddBlock ? VBUF_LENGTH : 0); - - s = buf[ 1]; d[0] = d[8] = s; d += 64; - - tmp = buf[25] + buf[29]; - s = buf[17] + tmp; d[0] = d[8] = s; d += 64; - s = buf[ 9] + buf[13]; d[0] = d[8] = s; d += 64; - s = buf[21] + tmp; d[0] = d[8] = s; d += 64; - - tmp = buf[29] + buf[27]; - s = buf[ 5]; d[0] = d[8] = s; d += 64; - s = buf[21] + tmp; d[0] = d[8] = s; d += 64; - s = buf[13] + buf[11]; d[0] = d[8] = s; d += 64; - s = buf[19] + tmp; d[0] = d[8] = s; d += 64; - - tmp = buf[27] + buf[31]; - s = buf[ 3]; d[0] = d[8] = s; d += 64; - s = buf[19] + tmp; d[0] = d[8] = s; d += 64; - s = buf[11] + buf[15]; d[0] = d[8] = s; d += 64; - s = buf[23] + tmp; d[0] = d[8] = s; d += 64; - - tmp = buf[31]; - s = buf[ 7]; d[0] = d[8] = s; d += 64; - s = buf[23] + tmp; d[0] = d[8] = s; d += 64; - s = buf[15]; d[0] = d[8] = s; d += 64; - s = tmp; d[0] = d[8] = s; - - /* samples 16 to 1 (sample 16 used again) */ - d = dest + 16 + ((offset - oddBlock) & 7) + (oddBlock ? 0 : VBUF_LENGTH); - - s = buf[ 1]; d[0] = d[8] = s; d += 64; - - tmp = buf[30] + buf[25]; - s = buf[17] + tmp; d[0] = d[8] = s; d += 64; - s = buf[14] + buf[ 9]; d[0] = d[8] = s; d += 64; - s = buf[22] + tmp; d[0] = d[8] = s; d += 64; - s = buf[ 6]; d[0] = d[8] = s; d += 64; - - tmp = buf[26] + buf[30]; - s = buf[22] + tmp; d[0] = d[8] = s; d += 64; - s = buf[10] + buf[14]; d[0] = d[8] = s; d += 64; - s = buf[18] + tmp; d[0] = d[8] = s; d += 64; - s = buf[ 2]; d[0] = d[8] = s; d += 64; - - tmp = buf[28] + buf[26]; - s = buf[18] + tmp; d[0] = d[8] = s; d += 64; - s = buf[12] + buf[10]; d[0] = d[8] = s; d += 64; - s = buf[20] + tmp; d[0] = d[8] = s; d += 64; - s = buf[ 4]; d[0] = d[8] = s; d += 64; - - tmp = buf[24] + buf[28]; - s = buf[20] + tmp; d[0] = d[8] = s; d += 64; - s = buf[ 8] + buf[12]; d[0] = d[8] = s; d += 64; - s = buf[16] + tmp; d[0] = d[8] = s; - - /* this is so rarely invoked that it's not worth making two versions of the output - * shuffle code (one for no shift, one for clip + variable shift) like in IMDCT - * here we just load, clip, shift, and store on the rare instances that es != 0 - */ - if (es) { - d = dest + 64*16 + ((offset - oddBlock) & 7) + (oddBlock ? 0 : VBUF_LENGTH); - s = d[0]; CLIP_2N(s, 31 - es); d[0] = d[8] = (s << es); - - d = dest + offset + (oddBlock ? VBUF_LENGTH : 0); - for (i = 16; i <= 31; i++) { - s = d[0]; CLIP_2N(s, 31 - es); d[0] = d[8] = (s << es); d += 64; - } - - d = dest + 16 + ((offset - oddBlock) & 7) + (oddBlock ? 0 : VBUF_LENGTH); - for (i = 15; i >= 0; i--) { - s = d[0]; CLIP_2N(s, 31 - es); d[0] = d[8] = (s << es); d += 64; - } - } + int *d; + + /* scaling - ensure at least 6 guard bits for DCT + (in practice this is already true 99% of time, so this code is + almost never triggered) + */ + es = 0; + if (gb < 6) { + es = 6 - gb; + for (i = 0; i < 32; i++) { + buf[i] >>= es; + } + } + + /* first pass */ + D32FP(0, 1, 5, 1); + D32FP(1, 1, 3, 1); + D32FP(2, 1, 3, 1); + D32FP(3, 1, 2, 1); + D32FP(4, 1, 2, 1); + D32FP(5, 1, 1, 2); + D32FP(6, 1, 1, 2); + D32FP(7, 1, 1, 4); + + /* second pass */ + for (i = 4; i > 0; i--) { + a0 = buf[0]; a7 = buf[7]; a3 = buf[3]; a4 = buf[4]; + b0 = a0 + a7; b7 = MULSHIFT32(*cptr++, a0 - a7) << 1; + b3 = a3 + a4; b4 = MULSHIFT32(*cptr++, a3 - a4) << 3; + a0 = b0 + b3; a3 = MULSHIFT32(*cptr, b0 - b3) << 1; + a4 = b4 + b7; a7 = MULSHIFT32(*cptr++, b7 - b4) << 1; + + a1 = buf[1]; a6 = buf[6]; a2 = buf[2]; a5 = buf[5]; + b1 = a1 + a6; b6 = MULSHIFT32(*cptr++, a1 - a6) << 1; + b2 = a2 + a5; b5 = MULSHIFT32(*cptr++, a2 - a5) << 1; + a1 = b1 + b2; a2 = MULSHIFT32(*cptr, b1 - b2) << 2; + a5 = b5 + b6; a6 = MULSHIFT32(*cptr++, b6 - b5) << 2; + + b0 = a0 + a1; b1 = MULSHIFT32(COS4_0, a0 - a1) << 1; + b2 = a2 + a3; b3 = MULSHIFT32(COS4_0, a3 - a2) << 1; + buf[0] = b0; buf[1] = b1; + buf[2] = b2 + b3; buf[3] = b3; + + b4 = a4 + a5; b5 = MULSHIFT32(COS4_0, a4 - a5) << 1; + b6 = a6 + a7; b7 = MULSHIFT32(COS4_0, a7 - a6) << 1; + b6 += b7; + buf[4] = b4 + b6; buf[5] = b5 + b7; + buf[6] = b5 + b6; buf[7] = b7; + + buf += 8; + } + buf -= 32; /* reset */ + + /* sample 0 - always delayed one block */ + d = dest + 64 * 16 + ((offset - oddBlock) & 7) + (oddBlock ? 0 : VBUF_LENGTH); + s = buf[ 0]; d[0] = d[8] = s; + + /* samples 16 to 31 */ + d = dest + offset + (oddBlock ? VBUF_LENGTH : 0); + + s = buf[ 1]; d[0] = d[8] = s; d += 64; + + tmp = buf[25] + buf[29]; + s = buf[17] + tmp; d[0] = d[8] = s; d += 64; + s = buf[ 9] + buf[13]; d[0] = d[8] = s; d += 64; + s = buf[21] + tmp; d[0] = d[8] = s; d += 64; + + tmp = buf[29] + buf[27]; + s = buf[ 5]; d[0] = d[8] = s; d += 64; + s = buf[21] + tmp; d[0] = d[8] = s; d += 64; + s = buf[13] + buf[11]; d[0] = d[8] = s; d += 64; + s = buf[19] + tmp; d[0] = d[8] = s; d += 64; + + tmp = buf[27] + buf[31]; + s = buf[ 3]; d[0] = d[8] = s; d += 64; + s = buf[19] + tmp; d[0] = d[8] = s; d += 64; + s = buf[11] + buf[15]; d[0] = d[8] = s; d += 64; + s = buf[23] + tmp; d[0] = d[8] = s; d += 64; + + tmp = buf[31]; + s = buf[ 7]; d[0] = d[8] = s; d += 64; + s = buf[23] + tmp; d[0] = d[8] = s; d += 64; + s = buf[15]; d[0] = d[8] = s; d += 64; + s = tmp; d[0] = d[8] = s; + + /* samples 16 to 1 (sample 16 used again) */ + d = dest + 16 + ((offset - oddBlock) & 7) + (oddBlock ? 0 : VBUF_LENGTH); + + s = buf[ 1]; d[0] = d[8] = s; d += 64; + + tmp = buf[30] + buf[25]; + s = buf[17] + tmp; d[0] = d[8] = s; d += 64; + s = buf[14] + buf[ 9]; d[0] = d[8] = s; d += 64; + s = buf[22] + tmp; d[0] = d[8] = s; d += 64; + s = buf[ 6]; d[0] = d[8] = s; d += 64; + + tmp = buf[26] + buf[30]; + s = buf[22] + tmp; d[0] = d[8] = s; d += 64; + s = buf[10] + buf[14]; d[0] = d[8] = s; d += 64; + s = buf[18] + tmp; d[0] = d[8] = s; d += 64; + s = buf[ 2]; d[0] = d[8] = s; d += 64; + + tmp = buf[28] + buf[26]; + s = buf[18] + tmp; d[0] = d[8] = s; d += 64; + s = buf[12] + buf[10]; d[0] = d[8] = s; d += 64; + s = buf[20] + tmp; d[0] = d[8] = s; d += 64; + s = buf[ 4]; d[0] = d[8] = s; d += 64; + + tmp = buf[24] + buf[28]; + s = buf[20] + tmp; d[0] = d[8] = s; d += 64; + s = buf[ 8] + buf[12]; d[0] = d[8] = s; d += 64; + s = buf[16] + tmp; d[0] = d[8] = s; + + /* this is so rarely invoked that it's not worth making two versions of the output + shuffle code (one for no shift, one for clip + variable shift) like in IMDCT + here we just load, clip, shift, and store on the rare instances that es != 0 + */ + if (es) { + d = dest + 64 * 16 + ((offset - oddBlock) & 7) + (oddBlock ? 0 : VBUF_LENGTH); + s = d[0]; CLIP_2N(s, 31 - es); d[0] = d[8] = (s << es); + + d = dest + offset + (oddBlock ? VBUF_LENGTH : 0); + for (i = 16; i <= 31; i++) { + s = d[0]; CLIP_2N(s, 31 - es); d[0] = d[8] = (s << es); d += 64; + } + + d = dest + 16 + ((offset - oddBlock) & 7) + (oddBlock ? 0 : VBUF_LENGTH); + for (i = 15; i >= 0; i--) { + s = d[0]; CLIP_2N(s, 31 - es); d[0] = d[8] = (s << es); d += 64; + } + } } diff --git a/src/libhelix-mp3/dequant.c b/src/libhelix-mp3/dequant.c index b989b7de..e10c5e14 100644 --- a/src/libhelix-mp3/dequant.c +++ b/src/libhelix-mp3/dequant.c @@ -1,158 +1,167 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * dequant.c - dequantization, stereo processing (intensity, mid-side), short-block - * coefficient reordering + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + dequant.c - dequantization, stereo processing (intensity, mid-side), short-block + coefficient reordering **************************************************************************************/ #include "coder.h" #include "assembly.h" /************************************************************************************** - * Function: Dequantize - * - * Description: dequantize coefficients, decode stereo, reorder short blocks - * (one granule-worth) - * - * Inputs: MP3DecInfo structure filled by UnpackFrameHeader(), UnpackSideInfo(), - * UnpackScaleFactors(), and DecodeHuffman() (for this granule) - * index of current granule - * - * Outputs: dequantized and reordered coefficients in hi->huffDecBuf - * (one granule-worth, all channels), format = Q26 - * operates in-place on huffDecBuf but also needs di->workBuf - * updated hi->nonZeroBound index for both channels - * - * Return: 0 on success, -1 if null input pointers - * - * Notes: In calling output Q(DQ_FRACBITS_OUT), we assume an implicit bias - * of 2^15. Some (floating-point) reference implementations factor this - * into the 2^(0.25 * gain) scaling explicitly. But to avoid precision - * loss, we don't do that. Instead take it into account in the final - * round to PCM (>> by 15 less than we otherwise would have). - * Equivalently, we can think of the dequantized coefficients as - * Q(DQ_FRACBITS_OUT - 15) with no implicit bias. + Function: Dequantize + + Description: dequantize coefficients, decode stereo, reorder short blocks + (one granule-worth) + + Inputs: MP3DecInfo structure filled by UnpackFrameHeader(), UnpackSideInfo(), + UnpackScaleFactors(), and DecodeHuffman() (for this granule) + index of current granule + + Outputs: dequantized and reordered coefficients in hi->huffDecBuf + (one granule-worth, all channels), format = Q26 + operates in-place on huffDecBuf but also needs di->workBuf + updated hi->nonZeroBound index for both channels + + Return: 0 on success, -1 if null input pointers + + Notes: In calling output Q(DQ_FRACBITS_OUT), we assume an implicit bias + of 2^15. Some (floating-point) reference implementations factor this + into the 2^(0.25 * gain) scaling explicitly. But to avoid precision + loss, we don't do that. Instead take it into account in the final + round to PCM (>> by 15 less than we otherwise would have). + Equivalently, we can think of the dequantized coefficients as + Q(DQ_FRACBITS_OUT - 15) with no implicit bias. **************************************************************************************/ -int Dequantize(MP3DecInfo *mp3DecInfo, int gr) -{ - int i, ch, nSamps, mOut[2]; - FrameHeader *fh; - SideInfo *si; - ScaleFactorInfo *sfi; - HuffmanInfo *hi; - DequantInfo *di; - CriticalBandInfo *cbi; - - /* validate pointers */ - if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || !mp3DecInfo->SideInfoPS || !mp3DecInfo->ScaleFactorInfoPS || - !mp3DecInfo->HuffmanInfoPS || !mp3DecInfo->DequantInfoPS) - return -1; - - fh = (FrameHeader *)(mp3DecInfo->FrameHeaderPS); - - /* si is an array of up to 4 structs, stored as gr0ch0, gr0ch1, gr1ch0, gr1ch1 */ - si = (SideInfo *)(mp3DecInfo->SideInfoPS); - sfi = (ScaleFactorInfo *)(mp3DecInfo->ScaleFactorInfoPS); - hi = (HuffmanInfo *)mp3DecInfo->HuffmanInfoPS; - di = (DequantInfo *)mp3DecInfo->DequantInfoPS; - cbi = di->cbi; - mOut[0] = mOut[1] = 0; - - /* dequantize all the samples in each channel */ - for (ch = 0; ch < mp3DecInfo->nChans; ch++) { - hi->gb[ch] = DequantChannel(hi->huffDecBuf[ch], di->workBuf, &hi->nonZeroBound[ch], fh, - &si->sis[gr][ch], &sfi->sfis[gr][ch], &cbi[ch]); - } - - /* joint stereo processing assumes one guard bit in input samples - * it's extremely rare not to have at least one gb, so if this is the case - * just make a pass over the data and clip to [-2^30+1, 2^30-1] - * in practice this may never happen - */ - if (fh->modeExt && (hi->gb[0] < 1 || hi->gb[1] < 1)) { - for (i = 0; i < hi->nonZeroBound[0]; i++) { - if (hi->huffDecBuf[0][i] < -0x3fffffff) hi->huffDecBuf[0][i] = -0x3fffffff; - if (hi->huffDecBuf[0][i] > 0x3fffffff) hi->huffDecBuf[0][i] = 0x3fffffff; - } - for (i = 0; i < hi->nonZeroBound[1]; i++) { - if (hi->huffDecBuf[1][i] < -0x3fffffff) hi->huffDecBuf[1][i] = -0x3fffffff; - if (hi->huffDecBuf[1][i] > 0x3fffffff) hi->huffDecBuf[1][i] = 0x3fffffff; - } - } - - /* do mid-side stereo processing, if enabled */ - if (fh->modeExt >> 1) { - if (fh->modeExt & 0x01) { - /* intensity stereo enabled - run mid-side up to start of right zero region */ - if (cbi[1].cbType == 0) - nSamps = fh->sfBand->l[cbi[1].cbEndL + 1]; - else - nSamps = 3 * fh->sfBand->s[cbi[1].cbEndSMax + 1]; - } else { - /* intensity stereo disabled - run mid-side on whole spectrum */ - nSamps = MAX(hi->nonZeroBound[0], hi->nonZeroBound[1]); - } - MidSideProc(hi->huffDecBuf, nSamps, mOut); - } - - /* do intensity stereo processing, if enabled */ - if (fh->modeExt & 0x01) { - nSamps = hi->nonZeroBound[0]; - if (fh->ver == MPEG1) { - IntensityProcMPEG1(hi->huffDecBuf, nSamps, fh, &sfi->sfis[gr][1], di->cbi, - fh->modeExt >> 1, si->sis[gr][1].mixedBlock, mOut); - } else { - IntensityProcMPEG2(hi->huffDecBuf, nSamps, fh, &sfi->sfis[gr][1], di->cbi, &sfi->sfjs, - fh->modeExt >> 1, si->sis[gr][1].mixedBlock, mOut); - } - } - - /* adjust guard bit count and nonZeroBound if we did any stereo processing */ - if (fh->modeExt) { - hi->gb[0] = CLZ(mOut[0]) - 1; - hi->gb[1] = CLZ(mOut[1]) - 1; - nSamps = MAX(hi->nonZeroBound[0], hi->nonZeroBound[1]); - hi->nonZeroBound[0] = nSamps; - hi->nonZeroBound[1] = nSamps; - } - - /* output format Q(DQ_FRACBITS_OUT) */ - return 0; +int Dequantize(MP3DecInfo *mp3DecInfo, int gr) { + int i, ch, nSamps, mOut[2]; + FrameHeader *fh; + SideInfo *si; + ScaleFactorInfo *sfi; + HuffmanInfo *hi; + DequantInfo *di; + CriticalBandInfo *cbi; + + /* validate pointers */ + if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || !mp3DecInfo->SideInfoPS || !mp3DecInfo->ScaleFactorInfoPS || + !mp3DecInfo->HuffmanInfoPS || !mp3DecInfo->DequantInfoPS) { + return -1; + } + + fh = (FrameHeader *)(mp3DecInfo->FrameHeaderPS); + + /* si is an array of up to 4 structs, stored as gr0ch0, gr0ch1, gr1ch0, gr1ch1 */ + si = (SideInfo *)(mp3DecInfo->SideInfoPS); + sfi = (ScaleFactorInfo *)(mp3DecInfo->ScaleFactorInfoPS); + hi = (HuffmanInfo *)mp3DecInfo->HuffmanInfoPS; + di = (DequantInfo *)mp3DecInfo->DequantInfoPS; + cbi = di->cbi; + mOut[0] = mOut[1] = 0; + + /* dequantize all the samples in each channel */ + for (ch = 0; ch < mp3DecInfo->nChans; ch++) { + hi->gb[ch] = DequantChannel(hi->huffDecBuf[ch], di->workBuf, &hi->nonZeroBound[ch], fh, + &si->sis[gr][ch], &sfi->sfis[gr][ch], &cbi[ch]); + } + + /* joint stereo processing assumes one guard bit in input samples + it's extremely rare not to have at least one gb, so if this is the case + just make a pass over the data and clip to [-2^30+1, 2^30-1] + in practice this may never happen + */ + if (fh->modeExt && (hi->gb[0] < 1 || hi->gb[1] < 1)) { + for (i = 0; i < hi->nonZeroBound[0]; i++) { + if (hi->huffDecBuf[0][i] < -0x3fffffff) { + hi->huffDecBuf[0][i] = -0x3fffffff; + } + if (hi->huffDecBuf[0][i] > 0x3fffffff) { + hi->huffDecBuf[0][i] = 0x3fffffff; + } + } + for (i = 0; i < hi->nonZeroBound[1]; i++) { + if (hi->huffDecBuf[1][i] < -0x3fffffff) { + hi->huffDecBuf[1][i] = -0x3fffffff; + } + if (hi->huffDecBuf[1][i] > 0x3fffffff) { + hi->huffDecBuf[1][i] = 0x3fffffff; + } + } + } + + /* do mid-side stereo processing, if enabled */ + if (fh->modeExt >> 1) { + if (fh->modeExt & 0x01) { + /* intensity stereo enabled - run mid-side up to start of right zero region */ + if (cbi[1].cbType == 0) { + nSamps = fh->sfBand->l[cbi[1].cbEndL + 1]; + } else { + nSamps = 3 * fh->sfBand->s[cbi[1].cbEndSMax + 1]; + } + } else { + /* intensity stereo disabled - run mid-side on whole spectrum */ + nSamps = MAX(hi->nonZeroBound[0], hi->nonZeroBound[1]); + } + MidSideProc(hi->huffDecBuf, nSamps, mOut); + } + + /* do intensity stereo processing, if enabled */ + if (fh->modeExt & 0x01) { + nSamps = hi->nonZeroBound[0]; + if (fh->ver == MPEG1) { + IntensityProcMPEG1(hi->huffDecBuf, nSamps, fh, &sfi->sfis[gr][1], di->cbi, + fh->modeExt >> 1, si->sis[gr][1].mixedBlock, mOut); + } else { + IntensityProcMPEG2(hi->huffDecBuf, nSamps, fh, &sfi->sfis[gr][1], di->cbi, &sfi->sfjs, + fh->modeExt >> 1, si->sis[gr][1].mixedBlock, mOut); + } + } + + /* adjust guard bit count and nonZeroBound if we did any stereo processing */ + if (fh->modeExt) { + hi->gb[0] = CLZ(mOut[0]) - 1; + hi->gb[1] = CLZ(mOut[1]) - 1; + nSamps = MAX(hi->nonZeroBound[0], hi->nonZeroBound[1]); + hi->nonZeroBound[0] = nSamps; + hi->nonZeroBound[1] = nSamps; + } + + /* output format Q(DQ_FRACBITS_OUT) */ + return 0; } diff --git a/src/libhelix-mp3/dqchan.c b/src/libhelix-mp3/dqchan.c index 8e4cb76d..9335493f 100644 --- a/src/libhelix-mp3/dqchan.c +++ b/src/libhelix-mp3/dqchan.c @@ -1,44 +1,44 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * August 2003 - * - * dqchan.c - dequantization of transform coefficients + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + August 2003 + + dqchan.c - dequantization of transform coefficients **************************************************************************************/ #include "coder.h" @@ -48,63 +48,71 @@ typedef int ARRAY3[3]; /* for short-block reordering */ /* optional pre-emphasis for high-frequency scale factor bands */ -static const char preTab[22] = { 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0 }; +static const char preTab[22] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 }; /* pow(2,-i/4) for i=0..3, Q31 format */ -const int pow14[4] PROGMEM = { - 0x7fffffff, 0x6ba27e65, 0x5a82799a, 0x4c1bf829 +const int pow14[4] PROGMEM = { + 0x7fffffff, 0x6ba27e65, 0x5a82799a, 0x4c1bf829 }; /* pow(2,-i/4) * pow(j,4/3) for i=0..3 j=0..15, Q25 format */ const int pow43_14[4][16] PROGMEM = { -{ 0x00000000, 0x10000000, 0x285145f3, 0x453a5cdb, /* Q28 */ - 0x0cb2ff53, 0x111989d6, 0x15ce31c8, 0x1ac7f203, - 0x20000000, 0x257106b9, 0x2b16b4a3, 0x30ed74b4, - 0x36f23fa5, 0x3d227bd3, 0x437be656, 0x49fc823c, }, - -{ 0x00000000, 0x0d744fcd, 0x21e71f26, 0x3a36abd9, - 0x0aadc084, 0x0e610e6e, 0x12560c1d, 0x168523cf, - 0x1ae89f99, 0x1f7c03a4, 0x243bae49, 0x29249c67, - 0x2e34420f, 0x33686f85, 0x38bf3dff, 0x3e370182, }, - -{ 0x00000000, 0x0b504f33, 0x1c823e07, 0x30f39a55, - 0x08facd62, 0x0c176319, 0x0f6b3522, 0x12efe2ad, - 0x16a09e66, 0x1a79a317, 0x1e77e301, 0x2298d5b4, - 0x26da56fc, 0x2b3a902a, 0x2fb7e7e7, 0x3450f650, }, - -{ 0x00000000, 0x09837f05, 0x17f910d7, 0x2929c7a9, - 0x078d0dfa, 0x0a2ae661, 0x0cf73154, 0x0fec91cb, - 0x1306fe0a, 0x16434a6c, 0x199ee595, 0x1d17ae3d, - 0x20abd76a, 0x2459d551, 0x28204fbb, 0x2bfe1808, }, + { + 0x00000000, 0x10000000, 0x285145f3, 0x453a5cdb, /* Q28 */ + 0x0cb2ff53, 0x111989d6, 0x15ce31c8, 0x1ac7f203, + 0x20000000, 0x257106b9, 0x2b16b4a3, 0x30ed74b4, + 0x36f23fa5, 0x3d227bd3, 0x437be656, 0x49fc823c, + }, + + { + 0x00000000, 0x0d744fcd, 0x21e71f26, 0x3a36abd9, + 0x0aadc084, 0x0e610e6e, 0x12560c1d, 0x168523cf, + 0x1ae89f99, 0x1f7c03a4, 0x243bae49, 0x29249c67, + 0x2e34420f, 0x33686f85, 0x38bf3dff, 0x3e370182, + }, + + { + 0x00000000, 0x0b504f33, 0x1c823e07, 0x30f39a55, + 0x08facd62, 0x0c176319, 0x0f6b3522, 0x12efe2ad, + 0x16a09e66, 0x1a79a317, 0x1e77e301, 0x2298d5b4, + 0x26da56fc, 0x2b3a902a, 0x2fb7e7e7, 0x3450f650, + }, + + { + 0x00000000, 0x09837f05, 0x17f910d7, 0x2929c7a9, + 0x078d0dfa, 0x0a2ae661, 0x0cf73154, 0x0fec91cb, + 0x1306fe0a, 0x16434a6c, 0x199ee595, 0x1d17ae3d, + 0x20abd76a, 0x2459d551, 0x28204fbb, 0x2bfe1808, + }, }; /* pow(j,4/3) for j=16..63, Q23 format */ const int pow43[] PROGMEM = { - 0x1428a2fa, 0x15db1bd6, 0x1796302c, 0x19598d85, - 0x1b24e8bb, 0x1cf7fcfa, 0x1ed28af2, 0x20b4582a, - 0x229d2e6e, 0x248cdb55, 0x26832fda, 0x28800000, - 0x2a832287, 0x2c8c70a8, 0x2e9bc5d8, 0x30b0ff99, - 0x32cbfd4a, 0x34eca001, 0x3712ca62, 0x393e6088, - 0x3b6f47e0, 0x3da56717, 0x3fe0a5fc, 0x4220ed72, - 0x44662758, 0x46b03e7c, 0x48ff1e87, 0x4b52b3f3, - 0x4daaebfd, 0x5007b497, 0x5268fc62, 0x54ceb29c, - 0x5738c721, 0x59a72a59, 0x5c19cd35, 0x5e90a129, - 0x610b9821, 0x638aa47f, 0x660db90f, 0x6894c90b, - 0x6b1fc80c, 0x6daeaa0d, 0x70416360, 0x72d7e8b0, - 0x75722ef9, 0x78102b85, 0x7ab1d3ec, 0x7d571e09, + 0x1428a2fa, 0x15db1bd6, 0x1796302c, 0x19598d85, + 0x1b24e8bb, 0x1cf7fcfa, 0x1ed28af2, 0x20b4582a, + 0x229d2e6e, 0x248cdb55, 0x26832fda, 0x28800000, + 0x2a832287, 0x2c8c70a8, 0x2e9bc5d8, 0x30b0ff99, + 0x32cbfd4a, 0x34eca001, 0x3712ca62, 0x393e6088, + 0x3b6f47e0, 0x3da56717, 0x3fe0a5fc, 0x4220ed72, + 0x44662758, 0x46b03e7c, 0x48ff1e87, 0x4b52b3f3, + 0x4daaebfd, 0x5007b497, 0x5268fc62, 0x54ceb29c, + 0x5738c721, 0x59a72a59, 0x5c19cd35, 0x5e90a129, + 0x610b9821, 0x638aa47f, 0x660db90f, 0x6894c90b, + 0x6b1fc80c, 0x6daeaa0d, 0x70416360, 0x72d7e8b0, + 0x75722ef9, 0x78102b85, 0x7ab1d3ec, 0x7d571e09, }; /* sqrt(0.5) in Q31 format */ #define SQRTHALF 0x5a82799a /* - * Minimax polynomial approximation to pow(x, 4/3), over the range - * poly43lo: x = [0.5, 0.7071] - * poly43hi: x = [0.7071, 1.0] - * - * Relative error < 1E-7 - * Coefs are scaled by 4, 2, 1, 0.5, 0.25 - */ + Minimax polynomial approximation to pow(x, 4/3), over the range + poly43lo: x = [0.5, 0.7071] + poly43hi: x = [0.7071, 1.0] + + Relative error < 1E-7 + Coefs are scaled by 4, 2, 1, 0.5, 0.25 +*/ static const unsigned int poly43lo[5] PROGMEM = { 0x29a0bda9, 0xb02e4828, 0x5957aa1b, 0x236c498d, 0xff581859 }; static const unsigned int poly43hi[5] PROGMEM = { 0x10852163, 0xd333f6a4, 0x46e9408b, 0x27c2cef0, 0xfef577b4 }; @@ -112,266 +120,274 @@ static const unsigned int poly43hi[5] PROGMEM = { 0x10852163, 0xd333f6a4, 0x46e9 const int pow2exp[8] PROGMEM = { 14, 13, 11, 10, 9, 7, 6, 5 }; const int pow2frac[8] PROGMEM = { - 0x6597fa94, 0x50a28be6, 0x7fffffff, 0x6597fa94, - 0x50a28be6, 0x7fffffff, 0x6597fa94, 0x50a28be6 + 0x6597fa94, 0x50a28be6, 0x7fffffff, 0x6597fa94, + 0x50a28be6, 0x7fffffff, 0x6597fa94, 0x50a28be6 }; /************************************************************************************** - * Function: DequantBlock - * - * Description: Ken's highly-optimized, low memory dequantizer performing the operation - * y = pow(x, 4.0/3.0) * pow(2, 25 - scale/4.0) - * - * Inputs: input buffer of decode Huffman codewords (signed-magnitude) - * output buffer of same length (in-place (outbuf = inbuf) is allowed) - * number of samples - * - * Outputs: dequantized samples in Q25 format - * - * Return: bitwise-OR of the unsigned outputs (for guard bit calculations) + Function: DequantBlock + + Description: Ken's highly-optimized, low memory dequantizer performing the operation + y = pow(x, 4.0/3.0) * pow(2, 25 - scale/4.0) + + Inputs: input buffer of decode Huffman codewords (signed-magnitude) + output buffer of same length (in-place (outbuf = inbuf) is allowed) + number of samples + + Outputs: dequantized samples in Q25 format + + Return: bitwise-OR of the unsigned outputs (for guard bit calculations) **************************************************************************************/ -/* __attribute__ ((section (".data"))) */ static int DequantBlock(int *inbuf, int *outbuf, int num, int scale) -{ - int tab4[4]; - int scalef, scalei, shift; - int sx, x, y; - int mask = 0; - const int *tab16; - const unsigned int *coef; - - tab16 = pow43_14[scale & 0x3]; - scalef = pow14[scale & 0x3]; - scalei = MIN(scale >> 2, 31); /* smallest input scale = -47, so smallest scalei = -12 */ - - /* cache first 4 values */ - shift = MIN(scalei + 3, 31); - shift = MAX(shift, 0); - tab4[0] = 0; - tab4[1] = tab16[1] >> shift; - tab4[2] = tab16[2] >> shift; - tab4[3] = tab16[3] >> shift; - - do { - - sx = *inbuf++; - x = sx & 0x7fffffff; /* sx = sign|mag */ - - if (x < 4) { - - y = tab4[x]; - - } else if (x < 16) { - - y = tab16[x]; - y = (scalei < 0) ? y << -scalei : y >> scalei; - - } else { - - if (x < 64) { - - y = pow43[x-16]; - - /* fractional scale */ - y = MULSHIFT32(y, scalef); - shift = scalei - 3; - - } else { - - /* normalize to [0x40000000, 0x7fffffff] */ - x <<= 17; - shift = 0; - if (x < 0x08000000) - x <<= 4, shift += 4; - if (x < 0x20000000) - x <<= 2, shift += 2; - if (x < 0x40000000) - x <<= 1, shift += 1; - - coef = (x < SQRTHALF) ? poly43lo : poly43hi; - - /* polynomial */ - y = coef[0]; - y = MULSHIFT32(y, x) + coef[1]; - y = MULSHIFT32(y, x) + coef[2]; - y = MULSHIFT32(y, x) + coef[3]; - y = MULSHIFT32(y, x) + coef[4]; - y = MULSHIFT32(y, pow2frac[shift]) << 3; - - /* fractional scale */ - y = MULSHIFT32(y, scalef); - shift = scalei - pow2exp[shift]; - } - - /* integer scale */ - if (shift < 0) { - shift = -shift; - if (y > (0x7fffffff >> shift)) - y = 0x7fffffff; /* clip */ - else - y <<= shift; - } else { - y >>= shift; - } - } - - /* sign and store */ - mask |= y; - *outbuf++ = (sx < 0) ? -y : y; - - } while (--num); - - return mask; +/* __attribute__ ((section (".data"))) */ static int DequantBlock(int *inbuf, int *outbuf, int num, int scale) { + int tab4[4]; + int scalef, scalei, shift; + int sx, x, y; + int mask = 0; + const int *tab16; + const unsigned int *coef; + + tab16 = pow43_14[scale & 0x3]; + scalef = pow14[scale & 0x3]; + scalei = MIN(scale >> 2, 31); /* smallest input scale = -47, so smallest scalei = -12 */ + + /* cache first 4 values */ + shift = MIN(scalei + 3, 31); + shift = MAX(shift, 0); + tab4[0] = 0; + tab4[1] = tab16[1] >> shift; + tab4[2] = tab16[2] >> shift; + tab4[3] = tab16[3] >> shift; + + do { + + sx = *inbuf++; + x = sx & 0x7fffffff; /* sx = sign|mag */ + + if (x < 4) { + + y = tab4[x]; + + } else if (x < 16) { + + y = tab16[x]; + y = (scalei < 0) ? y << -scalei : y >> scalei; + + } else { + + if (x < 64) { + + y = pow43[x - 16]; + + /* fractional scale */ + y = MULSHIFT32(y, scalef); + shift = scalei - 3; + + } else { + + /* normalize to [0x40000000, 0x7fffffff] */ + x <<= 17; + shift = 0; + if (x < 0x08000000) { + x <<= 4, shift += 4; + } + if (x < 0x20000000) { + x <<= 2, shift += 2; + } + if (x < 0x40000000) { + x <<= 1, shift += 1; + } + + coef = (x < SQRTHALF) ? poly43lo : poly43hi; + + /* polynomial */ + y = coef[0]; + y = MULSHIFT32(y, x) + coef[1]; + y = MULSHIFT32(y, x) + coef[2]; + y = MULSHIFT32(y, x) + coef[3]; + y = MULSHIFT32(y, x) + coef[4]; + y = MULSHIFT32(y, pow2frac[shift]) << 3; + + /* fractional scale */ + y = MULSHIFT32(y, scalef); + shift = scalei - pow2exp[shift]; + } + + /* integer scale */ + if (shift < 0) { + shift = -shift; + if (y > (0x7fffffff >> shift)) { + y = 0x7fffffff; /* clip */ + } else { + y <<= shift; + } + } else { + y >>= shift; + } + } + + /* sign and store */ + mask |= y; + *outbuf++ = (sx < 0) ? -y : y; + + } while (--num); + + return mask; } /************************************************************************************** - * Function: DequantChannel - * - * Description: dequantize one granule, one channel worth of decoded Huffman codewords - * - * Inputs: sample buffer (decoded Huffman codewords), length = MAX_NSAMP samples - * work buffer for reordering short-block, length = MAX_REORDER_SAMPS - * samples (3 * width of largest short-block critical band) - * non-zero bound for this channel/granule - * valid FrameHeader, SideInfoSub, ScaleFactorInfoSub, and CriticalBandInfo - * structures for this channel/granule - * - * Outputs: MAX_NSAMP dequantized samples in sampleBuf - * updated non-zero bound (indicating which samples are != 0 after DQ) - * filled-in cbi structure indicating start and end critical bands - * - * Return: minimum number of guard bits in dequantized sampleBuf - * - * Notes: dequantized samples in Q(DQ_FRACBITS_OUT) format + Function: DequantChannel + + Description: dequantize one granule, one channel worth of decoded Huffman codewords + + Inputs: sample buffer (decoded Huffman codewords), length = MAX_NSAMP samples + work buffer for reordering short-block, length = MAX_REORDER_SAMPS + samples (3 * width of largest short-block critical band) + non-zero bound for this channel/granule + valid FrameHeader, SideInfoSub, ScaleFactorInfoSub, and CriticalBandInfo + structures for this channel/granule + + Outputs: MAX_NSAMP dequantized samples in sampleBuf + updated non-zero bound (indicating which samples are != 0 after DQ) + filled-in cbi structure indicating start and end critical bands + + Return: minimum number of guard bits in dequantized sampleBuf + + Notes: dequantized samples in Q(DQ_FRACBITS_OUT) format **************************************************************************************/ -/* __attribute__ ((section (".data"))) */ int DequantChannel(int *sampleBuf, int *workBuf, int *nonZeroBound, FrameHeader *fh, SideInfoSub *sis, - ScaleFactorInfoSub *sfis, CriticalBandInfo *cbi) -{ - int i, j, w, cb; - int /* cbStartL, */ cbEndL, cbStartS, cbEndS; - int nSamps, nonZero, sfactMultiplier, gbMask; - int globalGain, gainI; - int cbMax[3]; - ARRAY3 *buf; /* short block reorder */ - - /* set default start/end points for short/long blocks - will update with non-zero cb info */ - if (sis->blockType == 2) { - // cbStartL = 0; - if (sis->mixedBlock) { - cbEndL = (fh->ver == MPEG1 ? 8 : 6); - cbStartS = 3; - } else { - cbEndL = 0; - cbStartS = 0; - } - cbEndS = 13; - } else { - /* long block */ - //cbStartL = 0; - cbEndL = 22; - cbStartS = 13; - cbEndS = 13; - } - cbMax[2] = cbMax[1] = cbMax[0] = 0; - gbMask = 0; - i = 0; - - /* sfactScale = 0 --> quantizer step size = 2 - * sfactScale = 1 --> quantizer step size = sqrt(2) - * so sfactMultiplier = 2 or 4 (jump through globalGain by powers of 2 or sqrt(2)) - */ - sfactMultiplier = 2 * (sis->sfactScale + 1); - - /* offset globalGain by -2 if midSide enabled, for 1/sqrt(2) used in MidSideProc() - * (DequantBlock() does 0.25 * gainI so knocking it down by two is the same as - * dividing every sample by sqrt(2) = multiplying by 2^-.5) - */ - globalGain = sis->globalGain; - if (fh->modeExt >> 1) - globalGain -= 2; - globalGain += IMDCT_SCALE; /* scale everything by sqrt(2), for fast IMDCT36 */ - - /* long blocks */ - for (cb = 0; cb < cbEndL; cb++) { - - nonZero = 0; - nSamps = fh->sfBand->l[cb + 1] - fh->sfBand->l[cb]; - gainI = 210 - globalGain + sfactMultiplier * (sfis->l[cb] + (sis->preFlag ? (int)preTab[cb] : 0)); - - nonZero |= DequantBlock(sampleBuf + i, sampleBuf + i, nSamps, gainI); - i += nSamps; - - /* update highest non-zero critical band */ - if (nonZero) - cbMax[0] = cb; - gbMask |= nonZero; - - if (i >= *nonZeroBound) - break; - } - - /* set cbi (Type, EndS[], EndSMax will be overwritten if we proceed to do short blocks) */ - cbi->cbType = 0; /* long only */ - cbi->cbEndL = cbMax[0]; - cbi->cbEndS[0] = cbi->cbEndS[1] = cbi->cbEndS[2] = 0; - cbi->cbEndSMax = 0; - - /* early exit if no short blocks */ - if (cbStartS >= 12) - return CLZ(gbMask) - 1; - - /* short blocks */ - cbMax[2] = cbMax[1] = cbMax[0] = cbStartS; - for (cb = cbStartS; cb < cbEndS; cb++) { - - nSamps = fh->sfBand->s[cb + 1] - fh->sfBand->s[cb]; - for (w = 0; w < 3; w++) { - nonZero = 0; - gainI = 210 - globalGain + 8*sis->subBlockGain[w] + sfactMultiplier*(sfis->s[cb][w]); - - nonZero |= DequantBlock(sampleBuf + i + nSamps*w, workBuf + nSamps*w, nSamps, gainI); - - /* update highest non-zero critical band */ - if (nonZero) - cbMax[w] = cb; - gbMask |= nonZero; - } - - /* reorder blocks */ - buf = (ARRAY3 *)(sampleBuf + i); - i += 3*nSamps; - for (j = 0; j < nSamps; j++) { - buf[j][0] = workBuf[0*nSamps + j]; - buf[j][1] = workBuf[1*nSamps + j]; - buf[j][2] = workBuf[2*nSamps + j]; - } - - ASSERT(3*nSamps <= MAX_REORDER_SAMPS); - - if (i >= *nonZeroBound) - break; - } - - /* i = last non-zero INPUT sample processed, which corresponds to highest possible non-zero - * OUTPUT sample (after reorder) - * however, the original nzb is no longer necessarily true - * for each cb, buf[][] is updated with 3*nSamps samples (i increases 3*nSamps each time) - * (buf[j + 1][0] = 3 (input) samples ahead of buf[j][0]) - * so update nonZeroBound to i - */ - *nonZeroBound = i; - - ASSERT(*nonZeroBound <= MAX_NSAMP); - - cbi->cbType = (sis->mixedBlock ? 2 : 1); /* 2 = mixed short/long, 1 = short only */ - - cbi->cbEndS[0] = cbMax[0]; - cbi->cbEndS[1] = cbMax[1]; - cbi->cbEndS[2] = cbMax[2]; - - cbi->cbEndSMax = cbMax[0]; - cbi->cbEndSMax = MAX(cbi->cbEndSMax, cbMax[1]); - cbi->cbEndSMax = MAX(cbi->cbEndSMax, cbMax[2]); - - return CLZ(gbMask) - 1; +/* __attribute__ ((section (".data"))) */ int DequantChannel(int *sampleBuf, int *workBuf, int *nonZeroBound, FrameHeader *fh, SideInfoSub *sis, + ScaleFactorInfoSub *sfis, CriticalBandInfo *cbi) { + int i, j, w, cb; + int /* cbStartL, */ cbEndL, cbStartS, cbEndS; + int nSamps, nonZero, sfactMultiplier, gbMask; + int globalGain, gainI; + int cbMax[3]; + ARRAY3 *buf; /* short block reorder */ + + /* set default start/end points for short/long blocks - will update with non-zero cb info */ + if (sis->blockType == 2) { + // cbStartL = 0; + if (sis->mixedBlock) { + cbEndL = (fh->ver == MPEG1 ? 8 : 6); + cbStartS = 3; + } else { + cbEndL = 0; + cbStartS = 0; + } + cbEndS = 13; + } else { + /* long block */ + //cbStartL = 0; + cbEndL = 22; + cbStartS = 13; + cbEndS = 13; + } + cbMax[2] = cbMax[1] = cbMax[0] = 0; + gbMask = 0; + i = 0; + + /* sfactScale = 0 --> quantizer step size = 2 + sfactScale = 1 --> quantizer step size = sqrt(2) + so sfactMultiplier = 2 or 4 (jump through globalGain by powers of 2 or sqrt(2)) + */ + sfactMultiplier = 2 * (sis->sfactScale + 1); + + /* offset globalGain by -2 if midSide enabled, for 1/sqrt(2) used in MidSideProc() + (DequantBlock() does 0.25 * gainI so knocking it down by two is the same as + dividing every sample by sqrt(2) = multiplying by 2^-.5) + */ + globalGain = sis->globalGain; + if (fh->modeExt >> 1) { + globalGain -= 2; + } + globalGain += IMDCT_SCALE; /* scale everything by sqrt(2), for fast IMDCT36 */ + + /* long blocks */ + for (cb = 0; cb < cbEndL; cb++) { + + nonZero = 0; + nSamps = fh->sfBand->l[cb + 1] - fh->sfBand->l[cb]; + gainI = 210 - globalGain + sfactMultiplier * (sfis->l[cb] + (sis->preFlag ? (int)preTab[cb] : 0)); + + nonZero |= DequantBlock(sampleBuf + i, sampleBuf + i, nSamps, gainI); + i += nSamps; + + /* update highest non-zero critical band */ + if (nonZero) { + cbMax[0] = cb; + } + gbMask |= nonZero; + + if (i >= *nonZeroBound) { + break; + } + } + + /* set cbi (Type, EndS[], EndSMax will be overwritten if we proceed to do short blocks) */ + cbi->cbType = 0; /* long only */ + cbi->cbEndL = cbMax[0]; + cbi->cbEndS[0] = cbi->cbEndS[1] = cbi->cbEndS[2] = 0; + cbi->cbEndSMax = 0; + + /* early exit if no short blocks */ + if (cbStartS >= 12) { + return CLZ(gbMask) - 1; + } + + /* short blocks */ + cbMax[2] = cbMax[1] = cbMax[0] = cbStartS; + for (cb = cbStartS; cb < cbEndS; cb++) { + + nSamps = fh->sfBand->s[cb + 1] - fh->sfBand->s[cb]; + for (w = 0; w < 3; w++) { + nonZero = 0; + gainI = 210 - globalGain + 8 * sis->subBlockGain[w] + sfactMultiplier * (sfis->s[cb][w]); + + nonZero |= DequantBlock(sampleBuf + i + nSamps * w, workBuf + nSamps * w, nSamps, gainI); + + /* update highest non-zero critical band */ + if (nonZero) { + cbMax[w] = cb; + } + gbMask |= nonZero; + } + + /* reorder blocks */ + buf = (ARRAY3 *)(sampleBuf + i); + i += 3 * nSamps; + for (j = 0; j < nSamps; j++) { + buf[j][0] = workBuf[0 * nSamps + j]; + buf[j][1] = workBuf[1 * nSamps + j]; + buf[j][2] = workBuf[2 * nSamps + j]; + } + + ASSERT(3 * nSamps <= MAX_REORDER_SAMPS); + + if (i >= *nonZeroBound) { + break; + } + } + + /* i = last non-zero INPUT sample processed, which corresponds to highest possible non-zero + OUTPUT sample (after reorder) + however, the original nzb is no longer necessarily true + for each cb, buf[][] is updated with 3*nSamps samples (i increases 3*nSamps each time) + (buf[j + 1][0] = 3 (input) samples ahead of buf[j][0]) + so update nonZeroBound to i + */ + *nonZeroBound = i; + + ASSERT(*nonZeroBound <= MAX_NSAMP); + + cbi->cbType = (sis->mixedBlock ? 2 : 1); /* 2 = mixed short/long, 1 = short only */ + + cbi->cbEndS[0] = cbMax[0]; + cbi->cbEndS[1] = cbMax[1]; + cbi->cbEndS[2] = cbMax[2]; + + cbi->cbEndSMax = cbMax[0]; + cbi->cbEndSMax = MAX(cbi->cbEndSMax, cbMax[1]); + cbi->cbEndSMax = MAX(cbi->cbEndSMax, cbMax[2]); + + return CLZ(gbMask) - 1; } diff --git a/src/libhelix-mp3/huffman.c b/src/libhelix-mp3/huffman.c index 7d9d3f13..3ac84f5d 100644 --- a/src/libhelix-mp3/huffman.c +++ b/src/libhelix-mp3/huffman.c @@ -1,44 +1,44 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * July 2003 - * - * huffman.c - Huffman decoding of transform coefficients + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + July 2003 + + huffman.c - Huffman decoding of transform coefficients **************************************************************************************/ #include "coder.h" @@ -62,402 +62,463 @@ #define ApplySign(x, s) { (x) |= ((s) & 0x80000000); } /************************************************************************************** - * Function: DecodeHuffmanPairs - * - * Description: decode 2-way vector Huffman codes in the "bigValues" region of spectrum - * - * Inputs: valid BitStreamInfo struct, pointing to start of pair-wise codes - * pointer to xy buffer to received decoded values - * number of codewords to decode - * index of Huffman table to use - * number of bits remaining in bitstream - * - * Outputs: pairs of decoded coefficients in vwxy - * updated BitStreamInfo struct - * - * Return: number of bits used, or -1 if out of bits - * - * Notes: assumes that nVals is an even number - * si_huff.bit tests every Huffman codeword in every table (though not - * necessarily all linBits outputs for x,y > 15) + Function: DecodeHuffmanPairs + + Description: decode 2-way vector Huffman codes in the "bigValues" region of spectrum + + Inputs: valid BitStreamInfo struct, pointing to start of pair-wise codes + pointer to xy buffer to received decoded values + number of codewords to decode + index of Huffman table to use + number of bits remaining in bitstream + + Outputs: pairs of decoded coefficients in vwxy + updated BitStreamInfo struct + + Return: number of bits used, or -1 if out of bits + + Notes: assumes that nVals is an even number + si_huff.bit tests every Huffman codeword in every table (though not + necessarily all linBits outputs for x,y > 15) **************************************************************************************/ // no improvement with section=data -static int DecodeHuffmanPairs(int *xy, int nVals, int tabIdx, int bitsLeft, unsigned char *buf, int bitOffset) -{ - int i, x, y; - int cachedBits, padBits, len, startBits, linBits, maxBits, minBits; - HuffTabType tabType; - unsigned short cw, *tBase, *tCurr; - unsigned int cache; - - if(nVals <= 0) - return 0; - - if (bitsLeft < 0) - return -1; - startBits = bitsLeft; - - tBase = (unsigned short *)(huffTable + huffTabOffset[tabIdx]); - linBits = huffTabLookup[tabIdx].linBits; - tabType = huffTabLookup[tabIdx].tabType; - - ASSERT(!(nVals & 0x01)); - ASSERT(tabIdx < HUFF_PAIRTABS); - ASSERT(tabIdx >= 0); - ASSERT(tabType != invalidTab); - - /* initially fill cache with any partial byte */ - cache = 0; - cachedBits = (8 - bitOffset) & 0x07; - if (cachedBits) - cache = (unsigned int)(*buf++) << (32 - cachedBits); - bitsLeft -= cachedBits; - - if (tabType == noBits) { - /* table 0, no data, x = y = 0 */ - for (i = 0; i < nVals; i+=2) { - xy[i+0] = 0; - xy[i+1] = 0; - } - return 0; - } else if (tabType == oneShot) { - /* single lookup, no escapes */ - maxBits = GetMaxbits(pgm_read_word(&tBase[0])); - tBase++; - padBits = 0; - while (nVals > 0) { - /* refill cache - assumes cachedBits <= 16 */ - if (bitsLeft >= 16) { - /* load 2 new bytes into left-justified cache */ - cache |= (unsigned int)(*buf++) << (24 - cachedBits); - cache |= (unsigned int)(*buf++) << (16 - cachedBits); - cachedBits += 16; - bitsLeft -= 16; - } else { - /* last time through, pad cache with zeros and drain cache */ - if (cachedBits + bitsLeft <= 0) return -1; - if (bitsLeft > 0) cache |= (unsigned int)(*buf++) << (24 - cachedBits); - if (bitsLeft > 8) cache |= (unsigned int)(*buf++) << (16 - cachedBits); - cachedBits += bitsLeft; - bitsLeft = 0; - - cache &= (signed int)0x80000000 >> (cachedBits - 1); - padBits = 11; - cachedBits += padBits; /* okay if this is > 32 (0's automatically shifted in from right) */ - } - - /* largest maxBits = 9, plus 2 for sign bits, so make sure cache has at least 11 bits */ - while (nVals > 0 && cachedBits >= 11 ) { - cw = pgm_read_word(&tBase[cache >> (32 - maxBits)]); - len = GetHLen(cw); - cachedBits -= len; - cache <<= len; - - x = GetCWX(cw); if (x) {ApplySign(x, cache); cache <<= 1; cachedBits--;} - y = GetCWY(cw); if (y) {ApplySign(y, cache); cache <<= 1; cachedBits--;} - - /* ran out of bits - should never have consumed padBits */ - if (cachedBits < padBits) - return -1; - - *xy++ = x; - *xy++ = y; - nVals -= 2; - } - } - bitsLeft += (cachedBits - padBits); - return (startBits - bitsLeft); - } else if (tabType == loopLinbits || tabType == loopNoLinbits) { - tCurr = tBase; - padBits = 0; - while (nVals > 0) { - /* refill cache - assumes cachedBits <= 16 */ - if (bitsLeft >= 16) { - /* load 2 new bytes into left-justified cache */ - cache |= (unsigned int)(*buf++) << (24 - cachedBits); - cache |= (unsigned int)(*buf++) << (16 - cachedBits); - cachedBits += 16; - bitsLeft -= 16; - } else { - /* last time through, pad cache with zeros and drain cache */ - if (cachedBits + bitsLeft <= 0) return -1; - if (bitsLeft > 0) cache |= (unsigned int)(*buf++) << (24 - cachedBits); - if (bitsLeft > 8) cache |= (unsigned int)(*buf++) << (16 - cachedBits); - cachedBits += bitsLeft; - bitsLeft = 0; - - cache &= (signed int)0x80000000 >> (cachedBits - 1); - padBits = 11; - cachedBits += padBits; /* okay if this is > 32 (0's automatically shifted in from right) */ - } - - /* largest maxBits = 9, plus 2 for sign bits, so make sure cache has at least 11 bits */ - while (nVals > 0 && cachedBits >= 11 ) { - maxBits = GetMaxbits(pgm_read_word(&tCurr[0])); - cw = pgm_read_word(&tCurr[(cache >> (32 - maxBits)) + 1]); - len = GetHLen(cw); - if (!len) { - cachedBits -= maxBits; - cache <<= maxBits; - tCurr += cw; - continue; - } - cachedBits -= len; - cache <<= len; - - x = GetCWX(cw); - y = GetCWY(cw); - - if (x == 15 && tabType == loopLinbits) { - minBits = linBits + 1 + (y ? 1 : 0); - if (cachedBits + bitsLeft < minBits) - return -1; - while (cachedBits < minBits) { - cache |= (unsigned int)(*buf++) << (24 - cachedBits); - cachedBits += 8; - bitsLeft -= 8; - } - if (bitsLeft < 0) { - cachedBits += bitsLeft; - bitsLeft = 0; - cache &= (signed int)0x80000000 >> (cachedBits - 1); - } - x += (int)(cache >> (32 - linBits)); - cachedBits -= linBits; - cache <<= linBits; - } - if (x) {ApplySign(x, cache); cache <<= 1; cachedBits--;} - - if (y == 15 && tabType == loopLinbits) { - minBits = linBits + 1; - if (cachedBits + bitsLeft < minBits) - return -1; - while (cachedBits < minBits) { - cache |= (unsigned int)(*buf++) << (24 - cachedBits); - cachedBits += 8; - bitsLeft -= 8; - } - if (bitsLeft < 0) { - cachedBits += bitsLeft; - bitsLeft = 0; - cache &= (signed int)0x80000000 >> (cachedBits - 1); - } - y += (int)(cache >> (32 - linBits)); - cachedBits -= linBits; - cache <<= linBits; - } - if (y) {ApplySign(y, cache); cache <<= 1; cachedBits--;} - - /* ran out of bits - should never have consumed padBits */ - if (cachedBits < padBits) - return -1; - - *xy++ = x; - *xy++ = y; - nVals -= 2; - tCurr = tBase; - } - } - bitsLeft += (cachedBits - padBits); - return (startBits - bitsLeft); - } - - /* error in bitstream - trying to access unused Huffman table */ - return -1; +static int DecodeHuffmanPairs(int *xy, int nVals, int tabIdx, int bitsLeft, unsigned char *buf, int bitOffset) { + int i, x, y; + int cachedBits, padBits, len, startBits, linBits, maxBits, minBits; + HuffTabType tabType; + unsigned short cw, *tBase, *tCurr; + unsigned int cache; + + if (nVals <= 0) { + return 0; + } + + if (bitsLeft < 0) { + return -1; + } + startBits = bitsLeft; + + tBase = (unsigned short *)(huffTable + huffTabOffset[tabIdx]); + linBits = huffTabLookup[tabIdx].linBits; + tabType = huffTabLookup[tabIdx].tabType; + + ASSERT(!(nVals & 0x01)); + ASSERT(tabIdx < HUFF_PAIRTABS); + ASSERT(tabIdx >= 0); + ASSERT(tabType != invalidTab); + + /* initially fill cache with any partial byte */ + cache = 0; + cachedBits = (8 - bitOffset) & 0x07; + if (cachedBits) { + cache = (unsigned int)(*buf++) << (32 - cachedBits); + } + bitsLeft -= cachedBits; + + if (tabType == noBits) { + /* table 0, no data, x = y = 0 */ + for (i = 0; i < nVals; i += 2) { + xy[i + 0] = 0; + xy[i + 1] = 0; + } + return 0; + } else if (tabType == oneShot) { + /* single lookup, no escapes */ + maxBits = GetMaxbits(pgm_read_word(&tBase[0])); + tBase++; + padBits = 0; + while (nVals > 0) { + /* refill cache - assumes cachedBits <= 16 */ + if (bitsLeft >= 16) { + /* load 2 new bytes into left-justified cache */ + cache |= (unsigned int)(*buf++) << (24 - cachedBits); + cache |= (unsigned int)(*buf++) << (16 - cachedBits); + cachedBits += 16; + bitsLeft -= 16; + } else { + /* last time through, pad cache with zeros and drain cache */ + if (cachedBits + bitsLeft <= 0) { + return -1; + } + if (bitsLeft > 0) { + cache |= (unsigned int)(*buf++) << (24 - cachedBits); + } + if (bitsLeft > 8) { + cache |= (unsigned int)(*buf++) << (16 - cachedBits); + } + cachedBits += bitsLeft; + bitsLeft = 0; + + cache &= (signed int)0x80000000 >> (cachedBits - 1); + padBits = 11; + cachedBits += padBits; /* okay if this is > 32 (0's automatically shifted in from right) */ + } + + /* largest maxBits = 9, plus 2 for sign bits, so make sure cache has at least 11 bits */ + while (nVals > 0 && cachedBits >= 11) { + cw = pgm_read_word(&tBase[cache >> (32 - maxBits)]); + len = GetHLen(cw); + cachedBits -= len; + cache <<= len; + + x = GetCWX(cw); if (x) { + ApplySign(x, cache); + cache <<= 1; + cachedBits--; + } + y = GetCWY(cw); if (y) { + ApplySign(y, cache); + cache <<= 1; + cachedBits--; + } + + /* ran out of bits - should never have consumed padBits */ + if (cachedBits < padBits) { + return -1; + } + + *xy++ = x; + *xy++ = y; + nVals -= 2; + } + } + bitsLeft += (cachedBits - padBits); + return (startBits - bitsLeft); + } else if (tabType == loopLinbits || tabType == loopNoLinbits) { + tCurr = tBase; + padBits = 0; + while (nVals > 0) { + /* refill cache - assumes cachedBits <= 16 */ + if (bitsLeft >= 16) { + /* load 2 new bytes into left-justified cache */ + cache |= (unsigned int)(*buf++) << (24 - cachedBits); + cache |= (unsigned int)(*buf++) << (16 - cachedBits); + cachedBits += 16; + bitsLeft -= 16; + } else { + /* last time through, pad cache with zeros and drain cache */ + if (cachedBits + bitsLeft <= 0) { + return -1; + } + if (bitsLeft > 0) { + cache |= (unsigned int)(*buf++) << (24 - cachedBits); + } + if (bitsLeft > 8) { + cache |= (unsigned int)(*buf++) << (16 - cachedBits); + } + cachedBits += bitsLeft; + bitsLeft = 0; + + cache &= (signed int)0x80000000 >> (cachedBits - 1); + padBits = 11; + cachedBits += padBits; /* okay if this is > 32 (0's automatically shifted in from right) */ + } + + /* largest maxBits = 9, plus 2 for sign bits, so make sure cache has at least 11 bits */ + while (nVals > 0 && cachedBits >= 11) { + maxBits = GetMaxbits(pgm_read_word(&tCurr[0])); + cw = pgm_read_word(&tCurr[(cache >> (32 - maxBits)) + 1]); + len = GetHLen(cw); + if (!len) { + cachedBits -= maxBits; + cache <<= maxBits; + tCurr += cw; + continue; + } + cachedBits -= len; + cache <<= len; + + x = GetCWX(cw); + y = GetCWY(cw); + + if (x == 15 && tabType == loopLinbits) { + minBits = linBits + 1 + (y ? 1 : 0); + if (cachedBits + bitsLeft < minBits) { + return -1; + } + while (cachedBits < minBits) { + cache |= (unsigned int)(*buf++) << (24 - cachedBits); + cachedBits += 8; + bitsLeft -= 8; + } + if (bitsLeft < 0) { + cachedBits += bitsLeft; + bitsLeft = 0; + cache &= (signed int)0x80000000 >> (cachedBits - 1); + } + x += (int)(cache >> (32 - linBits)); + cachedBits -= linBits; + cache <<= linBits; + } + if (x) { + ApplySign(x, cache); + cache <<= 1; + cachedBits--; + } + + if (y == 15 && tabType == loopLinbits) { + minBits = linBits + 1; + if (cachedBits + bitsLeft < minBits) { + return -1; + } + while (cachedBits < minBits) { + cache |= (unsigned int)(*buf++) << (24 - cachedBits); + cachedBits += 8; + bitsLeft -= 8; + } + if (bitsLeft < 0) { + cachedBits += bitsLeft; + bitsLeft = 0; + cache &= (signed int)0x80000000 >> (cachedBits - 1); + } + y += (int)(cache >> (32 - linBits)); + cachedBits -= linBits; + cache <<= linBits; + } + if (y) { + ApplySign(y, cache); + cache <<= 1; + cachedBits--; + } + + /* ran out of bits - should never have consumed padBits */ + if (cachedBits < padBits) { + return -1; + } + + *xy++ = x; + *xy++ = y; + nVals -= 2; + tCurr = tBase; + } + } + bitsLeft += (cachedBits - padBits); + return (startBits - bitsLeft); + } + + /* error in bitstream - trying to access unused Huffman table */ + return -1; } /************************************************************************************** - * Function: DecodeHuffmanQuads - * - * Description: decode 4-way vector Huffman codes in the "count1" region of spectrum - * - * Inputs: valid BitStreamInfo struct, pointing to start of quadword codes - * pointer to vwxy buffer to received decoded values - * maximum number of codewords to decode - * index of quadword table (0 = table A, 1 = table B) - * number of bits remaining in bitstream - * - * Outputs: quadruples of decoded coefficients in vwxy - * updated BitStreamInfo struct - * - * Return: index of the first "zero_part" value (index of the first sample - * of the quad word after which all samples are 0) - * - * Notes: si_huff.bit tests every vwxy output in both quad tables + Function: DecodeHuffmanQuads + + Description: decode 4-way vector Huffman codes in the "count1" region of spectrum + + Inputs: valid BitStreamInfo struct, pointing to start of quadword codes + pointer to vwxy buffer to received decoded values + maximum number of codewords to decode + index of quadword table (0 = table A, 1 = table B) + number of bits remaining in bitstream + + Outputs: quadruples of decoded coefficients in vwxy + updated BitStreamInfo struct + + Return: index of the first "zero_part" value (index of the first sample + of the quad word after which all samples are 0) + + Notes: si_huff.bit tests every vwxy output in both quad tables **************************************************************************************/ // no improvement with section=data -static int DecodeHuffmanQuads(int *vwxy, int nVals, int tabIdx, int bitsLeft, unsigned char *buf, int bitOffset) -{ - int i, v, w, x, y; - int len, maxBits, cachedBits, padBits; - unsigned int cache; - unsigned char cw, *tBase; - - if (bitsLeft <= 0) - return 0; - - tBase = (unsigned char *)quadTable + quadTabOffset[tabIdx]; - maxBits = quadTabMaxBits[tabIdx]; - - /* initially fill cache with any partial byte */ - cache = 0; - cachedBits = (8 - bitOffset) & 0x07; - if (cachedBits) - cache = (unsigned int)(*buf++) << (32 - cachedBits); - bitsLeft -= cachedBits; - - i = padBits = 0; - while (i < (nVals - 3)) { - /* refill cache - assumes cachedBits <= 16 */ - if (bitsLeft >= 16) { - /* load 2 new bytes into left-justified cache */ - cache |= (unsigned int)(*buf++) << (24 - cachedBits); - cache |= (unsigned int)(*buf++) << (16 - cachedBits); - cachedBits += 16; - bitsLeft -= 16; - } else { - /* last time through, pad cache with zeros and drain cache */ - if (cachedBits + bitsLeft <= 0) return i; - if (bitsLeft > 0) cache |= (unsigned int)(*buf++) << (24 - cachedBits); - if (bitsLeft > 8) cache |= (unsigned int)(*buf++) << (16 - cachedBits); - cachedBits += bitsLeft; - bitsLeft = 0; - - cache &= (signed int)0x80000000 >> (cachedBits - 1); - padBits = 10; - cachedBits += padBits; /* okay if this is > 32 (0's automatically shifted in from right) */ - } - - /* largest maxBits = 6, plus 4 for sign bits, so make sure cache has at least 10 bits */ - while (i < (nVals - 3) && cachedBits >= 10 ) { - cw = pgm_read_byte(&tBase[cache >> (32 - maxBits)]); - len = GetHLenQ(cw); - cachedBits -= len; - cache <<= len; - - v = GetCWVQ(cw); if(v) {ApplySign(v, cache); cache <<= 1; cachedBits--;} - w = GetCWWQ(cw); if(w) {ApplySign(w, cache); cache <<= 1; cachedBits--;} - x = GetCWXQ(cw); if(x) {ApplySign(x, cache); cache <<= 1; cachedBits--;} - y = GetCWYQ(cw); if(y) {ApplySign(y, cache); cache <<= 1; cachedBits--;} - - /* ran out of bits - okay (means we're done) */ - if (cachedBits < padBits) - return i; - - *vwxy++ = v; - *vwxy++ = w; - *vwxy++ = x; - *vwxy++ = y; - i += 4; - } - } - - /* decoded max number of quad values */ - return i; +static int DecodeHuffmanQuads(int *vwxy, int nVals, int tabIdx, int bitsLeft, unsigned char *buf, int bitOffset) { + int i, v, w, x, y; + int len, maxBits, cachedBits, padBits; + unsigned int cache; + unsigned char cw, *tBase; + + if (bitsLeft <= 0) { + return 0; + } + + tBase = (unsigned char *)quadTable + quadTabOffset[tabIdx]; + maxBits = quadTabMaxBits[tabIdx]; + + /* initially fill cache with any partial byte */ + cache = 0; + cachedBits = (8 - bitOffset) & 0x07; + if (cachedBits) { + cache = (unsigned int)(*buf++) << (32 - cachedBits); + } + bitsLeft -= cachedBits; + + i = padBits = 0; + while (i < (nVals - 3)) { + /* refill cache - assumes cachedBits <= 16 */ + if (bitsLeft >= 16) { + /* load 2 new bytes into left-justified cache */ + cache |= (unsigned int)(*buf++) << (24 - cachedBits); + cache |= (unsigned int)(*buf++) << (16 - cachedBits); + cachedBits += 16; + bitsLeft -= 16; + } else { + /* last time through, pad cache with zeros and drain cache */ + if (cachedBits + bitsLeft <= 0) { + return i; + } + if (bitsLeft > 0) { + cache |= (unsigned int)(*buf++) << (24 - cachedBits); + } + if (bitsLeft > 8) { + cache |= (unsigned int)(*buf++) << (16 - cachedBits); + } + cachedBits += bitsLeft; + bitsLeft = 0; + + cache &= (signed int)0x80000000 >> (cachedBits - 1); + padBits = 10; + cachedBits += padBits; /* okay if this is > 32 (0's automatically shifted in from right) */ + } + + /* largest maxBits = 6, plus 4 for sign bits, so make sure cache has at least 10 bits */ + while (i < (nVals - 3) && cachedBits >= 10) { + cw = pgm_read_byte(&tBase[cache >> (32 - maxBits)]); + len = GetHLenQ(cw); + cachedBits -= len; + cache <<= len; + + v = GetCWVQ(cw); if (v) { + ApplySign(v, cache); + cache <<= 1; + cachedBits--; + } + w = GetCWWQ(cw); if (w) { + ApplySign(w, cache); + cache <<= 1; + cachedBits--; + } + x = GetCWXQ(cw); if (x) { + ApplySign(x, cache); + cache <<= 1; + cachedBits--; + } + y = GetCWYQ(cw); if (y) { + ApplySign(y, cache); + cache <<= 1; + cachedBits--; + } + + /* ran out of bits - okay (means we're done) */ + if (cachedBits < padBits) { + return i; + } + + *vwxy++ = v; + *vwxy++ = w; + *vwxy++ = x; + *vwxy++ = y; + i += 4; + } + } + + /* decoded max number of quad values */ + return i; } /************************************************************************************** - * Function: DecodeHuffman - * - * Description: decode one granule, one channel worth of Huffman codes - * - * Inputs: MP3DecInfo structure filled by UnpackFrameHeader(), UnpackSideInfo(), - * and UnpackScaleFactors() (for this granule) - * buffer pointing to start of Huffman data in MP3 frame - * pointer to bit offset (0-7) indicating starting bit in buf[0] - * number of bits in the Huffman data section of the frame - * (could include padding bits) - * index of current granule and channel - * - * Outputs: decoded coefficients in hi->huffDecBuf[ch] (hi pointer in mp3DecInfo) - * updated bitOffset - * - * Return: length (in bytes) of Huffman codes - * bitOffset also returned in parameter (0 = MSB, 7 = LSB of - * byte located at buf + offset) - * -1 if null input pointers, huffBlockBits < 0, or decoder runs - * out of bits prematurely (invalid bitstream) + Function: DecodeHuffman + + Description: decode one granule, one channel worth of Huffman codes + + Inputs: MP3DecInfo structure filled by UnpackFrameHeader(), UnpackSideInfo(), + and UnpackScaleFactors() (for this granule) + buffer pointing to start of Huffman data in MP3 frame + pointer to bit offset (0-7) indicating starting bit in buf[0] + number of bits in the Huffman data section of the frame + (could include padding bits) + index of current granule and channel + + Outputs: decoded coefficients in hi->huffDecBuf[ch] (hi pointer in mp3DecInfo) + updated bitOffset + + Return: length (in bytes) of Huffman codes + bitOffset also returned in parameter (0 = MSB, 7 = LSB of + byte located at buf + offset) + -1 if null input pointers, huffBlockBits < 0, or decoder runs + out of bits prematurely (invalid bitstream) **************************************************************************************/ // .data about 1ms faster per frame -/* __attribute__ ((section (".data"))) */ int DecodeHuffman(MP3DecInfo *mp3DecInfo, unsigned char *buf, int *bitOffset, int huffBlockBits, int gr, int ch) -{ - int r1Start, r2Start, rEnd[4]; /* region boundaries */ - int i, w, bitsUsed, bitsLeft; - unsigned char *startBuf = buf; - - FrameHeader *fh; - SideInfo *si; - SideInfoSub *sis; - //ScaleFactorInfo *sfi; - HuffmanInfo *hi; - - /* validate pointers */ - if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || !mp3DecInfo->SideInfoPS || !mp3DecInfo->ScaleFactorInfoPS || !mp3DecInfo->HuffmanInfoPS) - return -1; - - fh = ((FrameHeader *)(mp3DecInfo->FrameHeaderPS)); - si = ((SideInfo *)(mp3DecInfo->SideInfoPS)); - sis = &si->sis[gr][ch]; - //sfi = ((ScaleFactorInfo *)(mp3DecInfo->ScaleFactorInfoPS)); - hi = (HuffmanInfo*)(mp3DecInfo->HuffmanInfoPS); - - if (huffBlockBits < 0) - return -1; - - /* figure out region boundaries (the first 2*bigVals coefficients divided into 3 regions) */ - if (sis->winSwitchFlag && sis->blockType == 2) { - if (sis->mixedBlock == 0) { - r1Start = fh->sfBand->s[(sis->region0Count + 1)/3] * 3; - } else { - if (fh->ver == MPEG1) { - r1Start = fh->sfBand->l[sis->region0Count + 1]; - } else { - /* see MPEG2 spec for explanation */ - w = fh->sfBand->s[4] - fh->sfBand->s[3]; - r1Start = fh->sfBand->l[6] + 2*w; - } - } - r2Start = MAX_NSAMP; /* short blocks don't have region 2 */ - } else { - r1Start = fh->sfBand->l[sis->region0Count + 1]; - r2Start = fh->sfBand->l[sis->region0Count + 1 + sis->region1Count + 1]; - } - - /* offset rEnd index by 1 so first region = rEnd[1] - rEnd[0], etc. */ - rEnd[3] = MIN(MAX_NSAMP, 2 * sis->nBigvals); - rEnd[2] = MIN(r2Start, rEnd[3]); - rEnd[1] = MIN(r1Start, rEnd[3]); - rEnd[0] = 0; - - /* rounds up to first all-zero pair (we don't check last pair for (x,y) == (non-zero, zero)) */ - hi->nonZeroBound[ch] = rEnd[3]; - - /* decode Huffman pairs (rEnd[i] are always even numbers) */ - bitsLeft = huffBlockBits; - for (i = 0; i < 3; i++) { - bitsUsed = DecodeHuffmanPairs(hi->huffDecBuf[ch] + rEnd[i], rEnd[i+1] - rEnd[i], sis->tableSelect[i], bitsLeft, buf, *bitOffset); - if (bitsUsed < 0 || bitsUsed > bitsLeft) /* error - overran end of bitstream */ - return -1; - - /* update bitstream position */ - buf += (bitsUsed + *bitOffset) >> 3; - *bitOffset = (bitsUsed + *bitOffset) & 0x07; - bitsLeft -= bitsUsed; - } - - /* decode Huffman quads (if any) */ - hi->nonZeroBound[ch] += DecodeHuffmanQuads(hi->huffDecBuf[ch] + rEnd[3], MAX_NSAMP - rEnd[3], sis->count1TableSelect, bitsLeft, buf, *bitOffset); - - ASSERT(hi->nonZeroBound[ch] <= MAX_NSAMP); - for (i = hi->nonZeroBound[ch]; i < MAX_NSAMP; i++) - hi->huffDecBuf[ch][i] = 0; - - /* If bits used for 576 samples < huffBlockBits, then the extras are considered - * to be stuffing bits (throw away, but need to return correct bitstream position) - */ - buf += (bitsLeft + *bitOffset) >> 3; - *bitOffset = (bitsLeft + *bitOffset) & 0x07; - - return (buf - startBuf); +/* __attribute__ ((section (".data"))) */ int DecodeHuffman(MP3DecInfo *mp3DecInfo, unsigned char *buf, int *bitOffset, int huffBlockBits, int gr, int ch) { + int r1Start, r2Start, rEnd[4]; /* region boundaries */ + int i, w, bitsUsed, bitsLeft; + unsigned char *startBuf = buf; + + FrameHeader *fh; + SideInfo *si; + SideInfoSub *sis; + //ScaleFactorInfo *sfi; + HuffmanInfo *hi; + + /* validate pointers */ + if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || !mp3DecInfo->SideInfoPS || !mp3DecInfo->ScaleFactorInfoPS || !mp3DecInfo->HuffmanInfoPS) { + return -1; + } + + fh = ((FrameHeader *)(mp3DecInfo->FrameHeaderPS)); + si = ((SideInfo *)(mp3DecInfo->SideInfoPS)); + sis = &si->sis[gr][ch]; + //sfi = ((ScaleFactorInfo *)(mp3DecInfo->ScaleFactorInfoPS)); + hi = (HuffmanInfo*)(mp3DecInfo->HuffmanInfoPS); + + if (huffBlockBits < 0) { + return -1; + } + + /* figure out region boundaries (the first 2*bigVals coefficients divided into 3 regions) */ + if (sis->winSwitchFlag && sis->blockType == 2) { + if (sis->mixedBlock == 0) { + r1Start = fh->sfBand->s[(sis->region0Count + 1) / 3] * 3; + } else { + if (fh->ver == MPEG1) { + r1Start = fh->sfBand->l[sis->region0Count + 1]; + } else { + /* see MPEG2 spec for explanation */ + w = fh->sfBand->s[4] - fh->sfBand->s[3]; + r1Start = fh->sfBand->l[6] + 2 * w; + } + } + r2Start = MAX_NSAMP; /* short blocks don't have region 2 */ + } else { + r1Start = fh->sfBand->l[sis->region0Count + 1]; + r2Start = fh->sfBand->l[sis->region0Count + 1 + sis->region1Count + 1]; + } + + /* offset rEnd index by 1 so first region = rEnd[1] - rEnd[0], etc. */ + rEnd[3] = MIN(MAX_NSAMP, 2 * sis->nBigvals); + rEnd[2] = MIN(r2Start, rEnd[3]); + rEnd[1] = MIN(r1Start, rEnd[3]); + rEnd[0] = 0; + + /* rounds up to first all-zero pair (we don't check last pair for (x,y) == (non-zero, zero)) */ + hi->nonZeroBound[ch] = rEnd[3]; + + /* decode Huffman pairs (rEnd[i] are always even numbers) */ + bitsLeft = huffBlockBits; + for (i = 0; i < 3; i++) { + bitsUsed = DecodeHuffmanPairs(hi->huffDecBuf[ch] + rEnd[i], rEnd[i + 1] - rEnd[i], sis->tableSelect[i], bitsLeft, buf, *bitOffset); + if (bitsUsed < 0 || bitsUsed > bitsLeft) { /* error - overran end of bitstream */ + return -1; + } + + /* update bitstream position */ + buf += (bitsUsed + *bitOffset) >> 3; + *bitOffset = (bitsUsed + *bitOffset) & 0x07; + bitsLeft -= bitsUsed; + } + + /* decode Huffman quads (if any) */ + hi->nonZeroBound[ch] += DecodeHuffmanQuads(hi->huffDecBuf[ch] + rEnd[3], MAX_NSAMP - rEnd[3], sis->count1TableSelect, bitsLeft, buf, *bitOffset); + + ASSERT(hi->nonZeroBound[ch] <= MAX_NSAMP); + for (i = hi->nonZeroBound[ch]; i < MAX_NSAMP; i++) { + hi->huffDecBuf[ch][i] = 0; + } + + /* If bits used for 576 samples < huffBlockBits, then the extras are considered + to be stuffing bits (throw away, but need to return correct bitstream position) + */ + buf += (bitsLeft + *bitOffset) >> 3; + *bitOffset = (bitsLeft + *bitOffset) & 0x07; + + return (buf - startBuf); } diff --git a/src/libhelix-mp3/hufftabs.c b/src/libhelix-mp3/hufftabs.c index 7190159c..c1eecda4 100644 --- a/src/libhelix-mp3/hufftabs.c +++ b/src/libhelix-mp3/hufftabs.c @@ -1,649 +1,649 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * hufftabs.c - compressed Huffman code tables + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + hufftabs.c - compressed Huffman code tables **************************************************************************************/ #include #include "coder.h" -/* NOTE - regenerated tables to use shorts instead of ints - * (all needed data can fit in 16 bits - see below) - * - * format 0xABCD - * A = length of codeword - * B = y value - * C = x value - * D = number of sign bits (0, 1, or 2) - * - * to read a CW, the code reads maxbits from the stream (dep. on - * table index), but doesn't remove them from the bitstream reader - * then it gets the correct CW by direct lookup into the table - * of length (2^maxbits) (more complicated for non-oneShot...) - * for CW's with hlen < maxbits, there are multiple entries in the - * table (extra bits are don't cares) - * the bitstream reader then "purges" (or removes) only the correct - * number of bits for the chosen CW - * - * entries starting with F are special: D (signbits) is maxbits, - * so the decoder always checks huffTableXX[0] first, gets the - * signbits, and reads that many bits from the bitstream - * (sometimes it takes > 1 read to get the value, so maxbits is - * can get updated by jumping to another value starting with 0xF) - * entries starting with 0 are also special: A = hlen = 0, rest of - * value is an offset to jump higher in the table (for tables of - * type loopNoLinbits or loopLinbits) - */ - -/* store Huffman codes as one big table plus table of offsets, since some platforms - * don't properly support table-of-tables (table of pointers to other const tables) - */ +/* NOTE - regenerated tables to use shorts instead of ints + (all needed data can fit in 16 bits - see below) + + format 0xABCD + A = length of codeword + B = y value + C = x value + D = number of sign bits (0, 1, or 2) + + to read a CW, the code reads maxbits from the stream (dep. on + table index), but doesn't remove them from the bitstream reader + then it gets the correct CW by direct lookup into the table + of length (2^maxbits) (more complicated for non-oneShot...) + for CW's with hlen < maxbits, there are multiple entries in the + table (extra bits are don't cares) + the bitstream reader then "purges" (or removes) only the correct + number of bits for the chosen CW + + entries starting with F are special: D (signbits) is maxbits, + so the decoder always checks huffTableXX[0] first, gets the + signbits, and reads that many bits from the bitstream + (sometimes it takes > 1 read to get the value, so maxbits is + can get updated by jumping to another value starting with 0xF) + entries starting with 0 are also special: A = hlen = 0, rest of + value is an offset to jump higher in the table (for tables of + type loopNoLinbits or loopLinbits) +*/ + +/* store Huffman codes as one big table plus table of offsets, since some platforms + don't properly support table-of-tables (table of pointers to other const tables) +*/ const unsigned short huffTable[] PROGMEM = { - /* huffTable01[9] */ - 0xf003, 0x3112, 0x3101, 0x2011, 0x2011, 0x1000, 0x1000, 0x1000, - 0x1000, - - /* huffTable02[65] */ - 0xf006, 0x6222, 0x6201, 0x5212, 0x5212, 0x5122, 0x5122, 0x5021, - 0x5021, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, - 0x3112, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, - - /* huffTable03[65] */ - 0xf006, 0x6222, 0x6201, 0x5212, 0x5212, 0x5122, 0x5122, 0x5021, - 0x5021, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, - 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, - 0x2112, 0x2101, 0x2101, 0x2101, 0x2101, 0x2101, 0x2101, 0x2101, - 0x2101, 0x2101, 0x2101, 0x2101, 0x2101, 0x2101, 0x2101, 0x2101, - 0x2101, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, - - /* huffTable05[257] */ - 0xf008, 0x8332, 0x8322, 0x7232, 0x7232, 0x6132, 0x6132, 0x6132, - 0x6132, 0x7312, 0x7312, 0x7301, 0x7301, 0x7031, 0x7031, 0x7222, - 0x7222, 0x6212, 0x6212, 0x6212, 0x6212, 0x6122, 0x6122, 0x6122, - 0x6122, 0x6201, 0x6201, 0x6201, 0x6201, 0x6021, 0x6021, 0x6021, - 0x6021, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, - 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, - 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, - 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, - 0x3112, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, - - /* huffTable06[129] */ - 0xf007, 0x7332, 0x7301, 0x6322, 0x6322, 0x6232, 0x6232, 0x6031, - 0x6031, 0x5312, 0x5312, 0x5312, 0x5312, 0x5132, 0x5132, 0x5132, - 0x5132, 0x5222, 0x5222, 0x5222, 0x5222, 0x5201, 0x5201, 0x5201, - 0x5201, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, - 0x4212, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, - 0x4122, 0x4021, 0x4021, 0x4021, 0x4021, 0x4021, 0x4021, 0x4021, - 0x4021, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, - 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, - 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, - 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, - 0x2112, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, - 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, - 0x3000, - - /* huffTable07[110] */ - 0xf006, 0x0041, 0x0052, 0x005b, 0x0060, 0x0063, 0x0068, 0x006b, - 0x6212, 0x5122, 0x5122, 0x6201, 0x6021, 0x4112, 0x4112, 0x4112, - 0x4112, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0xf004, 0x4552, 0x4542, 0x4452, 0x4352, 0x3532, 0x3532, - 0x3442, 0x3442, 0x3522, 0x3522, 0x3252, 0x3252, 0x2512, 0x2512, - 0x2512, 0x2512, 0xf003, 0x2152, 0x2152, 0x3501, 0x3432, 0x2051, - 0x2051, 0x3342, 0x3332, 0xf002, 0x2422, 0x2242, 0x1412, 0x1412, - 0xf001, 0x1142, 0x1041, 0xf002, 0x2401, 0x2322, 0x2232, 0x2301, - 0xf001, 0x1312, 0x1132, 0xf001, 0x1031, 0x1222, - - /* huffTable08[280] */ - 0xf008, 0x0101, 0x010a, 0x010f, 0x8512, 0x8152, 0x0112, 0x0115, - 0x8422, 0x8242, 0x8412, 0x7142, 0x7142, 0x8401, 0x8041, 0x8322, - 0x8232, 0x8312, 0x8132, 0x8301, 0x8031, 0x6222, 0x6222, 0x6222, - 0x6222, 0x6201, 0x6201, 0x6201, 0x6201, 0x6021, 0x6021, 0x6021, - 0x6021, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, - 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, - 0x4212, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, - 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, - 0x4122, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, - 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, - 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, - 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, - 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, - 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, - 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, - 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, - 0x2112, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, 0xf003, 0x3552, 0x3452, 0x2542, 0x2542, 0x1352, 0x1352, - 0x1352, 0x1352, 0xf002, 0x2532, 0x2442, 0x1522, 0x1522, 0xf001, - 0x1252, 0x1501, 0xf001, 0x1432, 0x1342, 0xf001, 0x1051, 0x1332, - - /* huffTable09[93] */ - 0xf006, 0x0041, 0x004a, 0x004f, 0x0052, 0x0057, 0x005a, 0x6412, - 0x6142, 0x6322, 0x6232, 0x5312, 0x5312, 0x5132, 0x5132, 0x6301, - 0x6031, 0x5222, 0x5222, 0x5201, 0x5201, 0x4212, 0x4212, 0x4212, - 0x4212, 0x4122, 0x4122, 0x4122, 0x4122, 0x4021, 0x4021, 0x4021, - 0x4021, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, - 0x3112, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, - 0x3000, 0xf003, 0x3552, 0x3542, 0x2532, 0x2532, 0x2352, 0x2352, - 0x3452, 0x3501, 0xf002, 0x2442, 0x2522, 0x2252, 0x2512, 0xf001, - 0x1152, 0x1432, 0xf002, 0x1342, 0x1342, 0x2051, 0x2401, 0xf001, - 0x1422, 0x1242, 0xf001, 0x1332, 0x1041, - - /* huffTable10[320] */ - 0xf008, 0x0101, 0x010a, 0x010f, 0x0118, 0x011b, 0x0120, 0x0125, - 0x8712, 0x8172, 0x012a, 0x012d, 0x0132, 0x8612, 0x8162, 0x8061, - 0x0137, 0x013a, 0x013d, 0x8412, 0x8142, 0x8041, 0x8322, 0x8232, - 0x8301, 0x7312, 0x7312, 0x7132, 0x7132, 0x7031, 0x7031, 0x7222, - 0x7222, 0x6212, 0x6212, 0x6212, 0x6212, 0x6122, 0x6122, 0x6122, - 0x6122, 0x6201, 0x6201, 0x6201, 0x6201, 0x6021, 0x6021, 0x6021, - 0x6021, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, - 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, - 0x4112, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0xf003, 0x3772, 0x3762, 0x3672, 0x3752, 0x3572, 0x3662, - 0x2742, 0x2742, 0xf002, 0x2472, 0x2652, 0x2562, 0x2732, 0xf003, - 0x2372, 0x2372, 0x2642, 0x2642, 0x3552, 0x3452, 0x2362, 0x2362, - 0xf001, 0x1722, 0x1272, 0xf002, 0x2462, 0x2701, 0x1071, 0x1071, - 0xf002, 0x1262, 0x1262, 0x2542, 0x2532, 0xf002, 0x1601, 0x1601, - 0x2352, 0x2442, 0xf001, 0x1632, 0x1622, 0xf002, 0x2522, 0x2252, - 0x1512, 0x1512, 0xf002, 0x1152, 0x1152, 0x2432, 0x2342, 0xf001, - 0x1501, 0x1051, 0xf001, 0x1422, 0x1242, 0xf001, 0x1332, 0x1401, - - /* huffTable11[296] */ - 0xf008, 0x0101, 0x0106, 0x010f, 0x0114, 0x0117, 0x8722, 0x8272, - 0x011c, 0x7172, 0x7172, 0x8712, 0x8071, 0x8632, 0x8362, 0x8061, - 0x011f, 0x0122, 0x8512, 0x7262, 0x7262, 0x8622, 0x8601, 0x7612, - 0x7612, 0x7162, 0x7162, 0x8152, 0x8432, 0x8051, 0x0125, 0x8422, - 0x8242, 0x8412, 0x8142, 0x8401, 0x8041, 0x7322, 0x7322, 0x7232, - 0x7232, 0x6312, 0x6312, 0x6312, 0x6312, 0x6132, 0x6132, 0x6132, - 0x6132, 0x7301, 0x7301, 0x7031, 0x7031, 0x6222, 0x6222, 0x6222, - 0x6222, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, - 0x5122, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, - 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, - 0x4212, 0x5201, 0x5201, 0x5201, 0x5201, 0x5201, 0x5201, 0x5201, - 0x5201, 0x5021, 0x5021, 0x5021, 0x5021, 0x5021, 0x5021, 0x5021, - 0x5021, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, - 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, - 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, - 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, - 0x3112, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, - 0x2000, 0xf002, 0x2772, 0x2762, 0x2672, 0x2572, 0xf003, 0x2662, - 0x2662, 0x2742, 0x2742, 0x2472, 0x2472, 0x3752, 0x3552, 0xf002, - 0x2652, 0x2562, 0x1732, 0x1732, 0xf001, 0x1372, 0x1642, 0xf002, - 0x2542, 0x2452, 0x2532, 0x2352, 0xf001, 0x1462, 0x1701, 0xf001, - 0x1442, 0x1522, 0xf001, 0x1252, 0x1501, 0xf001, 0x1342, 0x1332, - - /* huffTable12[185] */ - 0xf007, 0x0081, 0x008a, 0x008f, 0x0092, 0x0097, 0x009a, 0x009d, - 0x00a2, 0x00a5, 0x00a8, 0x7622, 0x7262, 0x7162, 0x00ad, 0x00b0, - 0x00b3, 0x7512, 0x7152, 0x7432, 0x7342, 0x00b6, 0x7422, 0x7242, - 0x7412, 0x6332, 0x6332, 0x6142, 0x6142, 0x6322, 0x6322, 0x6232, - 0x6232, 0x7041, 0x7301, 0x6031, 0x6031, 0x5312, 0x5312, 0x5312, - 0x5312, 0x5132, 0x5132, 0x5132, 0x5132, 0x5222, 0x5222, 0x5222, - 0x5222, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, - 0x4212, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, - 0x4122, 0x5201, 0x5201, 0x5201, 0x5201, 0x5021, 0x5021, 0x5021, - 0x5021, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, - 0x4000, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, - 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, - 0x3112, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, - 0x3101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0xf003, 0x3772, 0x3762, 0x2672, 0x2672, 0x2752, 0x2752, - 0x2572, 0x2572, 0xf002, 0x2662, 0x2742, 0x2472, 0x2562, 0xf001, - 0x1652, 0x1732, 0xf002, 0x2372, 0x2552, 0x1722, 0x1722, 0xf001, - 0x1272, 0x1642, 0xf001, 0x1462, 0x1712, 0xf002, 0x1172, 0x1172, - 0x2701, 0x2071, 0xf001, 0x1632, 0x1362, 0xf001, 0x1542, 0x1452, - 0xf002, 0x1442, 0x1442, 0x2601, 0x2501, 0xf001, 0x1612, 0x1061, - 0xf001, 0x1532, 0x1352, 0xf001, 0x1522, 0x1252, 0xf001, 0x1051, - 0x1401, - - /* huffTable13[497] */ - 0xf006, 0x0041, 0x0082, 0x00c3, 0x00e4, 0x0105, 0x0116, 0x011f, - 0x0130, 0x0139, 0x013e, 0x0143, 0x0146, 0x6212, 0x6122, 0x6201, - 0x6021, 0x4112, 0x4112, 0x4112, 0x4112, 0x4101, 0x4101, 0x4101, - 0x4101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0xf006, 0x0108, 0x0111, 0x011a, 0x0123, 0x012c, 0x0131, - 0x0136, 0x013f, 0x0144, 0x0147, 0x014c, 0x0151, 0x0156, 0x015b, - 0x6f12, 0x61f2, 0x60f1, 0x0160, 0x0163, 0x0166, 0x62e2, 0x0169, - 0x6e12, 0x61e2, 0x016c, 0x016f, 0x0172, 0x0175, 0x0178, 0x017b, - 0x66c2, 0x6d32, 0x017e, 0x6d22, 0x62d2, 0x6d12, 0x67b2, 0x0181, - 0x0184, 0x63c2, 0x0187, 0x6b42, 0x51d2, 0x51d2, 0x6d01, 0x60d1, - 0x6a82, 0x68a2, 0x6c42, 0x64c2, 0x6b62, 0x66b2, 0x5c32, 0x5c32, - 0x5c22, 0x5c22, 0x52c2, 0x52c2, 0x5b52, 0x5b52, 0x65b2, 0x6982, - 0x5c12, 0x5c12, 0xf006, 0x51c2, 0x51c2, 0x6892, 0x6c01, 0x50c1, - 0x50c1, 0x64b2, 0x6a62, 0x66a2, 0x6972, 0x5b32, 0x5b32, 0x53b2, - 0x53b2, 0x6882, 0x6a52, 0x5b22, 0x5b22, 0x65a2, 0x6962, 0x54a2, - 0x54a2, 0x6872, 0x6782, 0x5492, 0x5492, 0x6772, 0x6672, 0x42b2, - 0x42b2, 0x42b2, 0x42b2, 0x4b12, 0x4b12, 0x4b12, 0x4b12, 0x41b2, - 0x41b2, 0x41b2, 0x41b2, 0x5b01, 0x5b01, 0x50b1, 0x50b1, 0x5692, - 0x5692, 0x5a42, 0x5a42, 0x5a32, 0x5a32, 0x53a2, 0x53a2, 0x5952, - 0x5952, 0x5592, 0x5592, 0x4a22, 0x4a22, 0x4a22, 0x4a22, 0x42a2, - 0x42a2, 0x42a2, 0x42a2, 0xf005, 0x4a12, 0x4a12, 0x41a2, 0x41a2, - 0x5a01, 0x5862, 0x40a1, 0x40a1, 0x5682, 0x5942, 0x4392, 0x4392, - 0x5932, 0x5852, 0x5582, 0x5762, 0x4922, 0x4922, 0x4292, 0x4292, - 0x5752, 0x5572, 0x4832, 0x4832, 0x4382, 0x4382, 0x5662, 0x5742, - 0x5472, 0x5652, 0x5562, 0x5372, 0xf005, 0x3912, 0x3912, 0x3912, - 0x3912, 0x3192, 0x3192, 0x3192, 0x3192, 0x4901, 0x4901, 0x4091, - 0x4091, 0x4842, 0x4842, 0x4482, 0x4482, 0x4272, 0x4272, 0x5642, - 0x5462, 0x3822, 0x3822, 0x3822, 0x3822, 0x3282, 0x3282, 0x3282, - 0x3282, 0x3812, 0x3812, 0x3812, 0x3812, 0xf004, 0x4732, 0x4722, - 0x3712, 0x3712, 0x3172, 0x3172, 0x4552, 0x4701, 0x4071, 0x4632, - 0x4362, 0x4542, 0x4452, 0x4622, 0x4262, 0x4532, 0xf003, 0x2182, - 0x2182, 0x3801, 0x3081, 0x3612, 0x3162, 0x3601, 0x3061, 0xf004, - 0x4352, 0x4442, 0x3522, 0x3522, 0x3252, 0x3252, 0x3501, 0x3501, - 0x2512, 0x2512, 0x2512, 0x2512, 0x2152, 0x2152, 0x2152, 0x2152, - 0xf003, 0x3432, 0x3342, 0x3051, 0x3422, 0x3242, 0x3332, 0x2412, - 0x2412, 0xf002, 0x1142, 0x1142, 0x2401, 0x2041, 0xf002, 0x2322, - 0x2232, 0x1312, 0x1312, 0xf001, 0x1132, 0x1301, 0xf001, 0x1031, - 0x1222, 0xf003, 0x0082, 0x008b, 0x008e, 0x0091, 0x0094, 0x0097, - 0x3ce2, 0x3dd2, 0xf003, 0x0093, 0x3eb2, 0x3be2, 0x3f92, 0x39f2, - 0x3ae2, 0x3db2, 0x3bd2, 0xf003, 0x3f82, 0x38f2, 0x3cc2, 0x008d, - 0x3e82, 0x0090, 0x27f2, 0x27f2, 0xf003, 0x2ad2, 0x2ad2, 0x3da2, - 0x3cb2, 0x3bc2, 0x36f2, 0x2f62, 0x2f62, 0xf002, 0x28e2, 0x2f52, - 0x2d92, 0x29d2, 0xf002, 0x25f2, 0x27e2, 0x2ca2, 0x2bb2, 0xf003, - 0x2f42, 0x2f42, 0x24f2, 0x24f2, 0x3ac2, 0x36e2, 0x23f2, 0x23f2, - 0xf002, 0x1f32, 0x1f32, 0x2d82, 0x28d2, 0xf001, 0x1f22, 0x12f2, - 0xf002, 0x2e62, 0x2c92, 0x1f01, 0x1f01, 0xf002, 0x29c2, 0x2e52, - 0x1ba2, 0x1ba2, 0xf002, 0x2d72, 0x27d2, 0x1e42, 0x1e42, 0xf002, - 0x28c2, 0x26d2, 0x1e32, 0x1e32, 0xf002, 0x19b2, 0x19b2, 0x2b92, - 0x2aa2, 0xf001, 0x1ab2, 0x15e2, 0xf001, 0x14e2, 0x1c82, 0xf001, - 0x1d62, 0x13e2, 0xf001, 0x1e22, 0x1e01, 0xf001, 0x10e1, 0x1d52, - 0xf001, 0x15d2, 0x1c72, 0xf001, 0x17c2, 0x1d42, 0xf001, 0x1b82, - 0x18b2, 0xf001, 0x14d2, 0x1a92, 0xf001, 0x19a2, 0x1c62, 0xf001, - 0x13d2, 0x1b72, 0xf001, 0x1c52, 0x15c2, 0xf001, 0x1992, 0x1a72, - 0xf001, 0x17a2, 0x1792, 0xf003, 0x0023, 0x3df2, 0x2de2, 0x2de2, - 0x1ff2, 0x1ff2, 0x1ff2, 0x1ff2, 0xf001, 0x1fe2, 0x1fd2, 0xf001, - 0x1ee2, 0x1fc2, 0xf001, 0x1ed2, 0x1fb2, 0xf001, 0x1bf2, 0x1ec2, - 0xf002, 0x1cd2, 0x1cd2, 0x2fa2, 0x29e2, 0xf001, 0x1af2, 0x1dc2, - 0xf001, 0x1ea2, 0x1e92, 0xf001, 0x1f72, 0x1e72, 0xf001, 0x1ef2, - 0x1cf2, - - /* huffTable15[580] */ - 0xf008, 0x0101, 0x0122, 0x0143, 0x0154, 0x0165, 0x0176, 0x017f, - 0x0188, 0x0199, 0x01a2, 0x01ab, 0x01b4, 0x01bd, 0x01c2, 0x01cb, - 0x01d4, 0x01d9, 0x01de, 0x01e3, 0x01e8, 0x01ed, 0x01f2, 0x01f7, - 0x01fc, 0x0201, 0x0204, 0x0207, 0x020a, 0x020f, 0x0212, 0x0215, - 0x021a, 0x021d, 0x0220, 0x8192, 0x0223, 0x0226, 0x0229, 0x022c, - 0x022f, 0x8822, 0x8282, 0x8812, 0x8182, 0x0232, 0x0235, 0x0238, - 0x023b, 0x8722, 0x8272, 0x8462, 0x8712, 0x8552, 0x8172, 0x023e, - 0x8632, 0x8362, 0x8542, 0x8452, 0x8622, 0x8262, 0x8612, 0x0241, - 0x8532, 0x7162, 0x7162, 0x8352, 0x8442, 0x7522, 0x7522, 0x7252, - 0x7252, 0x7512, 0x7512, 0x7152, 0x7152, 0x8501, 0x8051, 0x7432, - 0x7432, 0x7342, 0x7342, 0x7422, 0x7422, 0x7242, 0x7242, 0x7332, - 0x7332, 0x6142, 0x6142, 0x6142, 0x6142, 0x7412, 0x7412, 0x7401, - 0x7401, 0x6322, 0x6322, 0x6322, 0x6322, 0x6232, 0x6232, 0x6232, - 0x6232, 0x7041, 0x7041, 0x7301, 0x7301, 0x6312, 0x6312, 0x6312, - 0x6312, 0x6132, 0x6132, 0x6132, 0x6132, 0x6031, 0x6031, 0x6031, - 0x6031, 0x5222, 0x5222, 0x5222, 0x5222, 0x5222, 0x5222, 0x5222, - 0x5222, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, - 0x5212, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, - 0x5122, 0x5201, 0x5201, 0x5201, 0x5201, 0x5201, 0x5201, 0x5201, - 0x5201, 0x5021, 0x5021, 0x5021, 0x5021, 0x5021, 0x5021, 0x5021, - 0x5021, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, - 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, - 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, - 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, - 0x3112, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, - 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, - 0x4101, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, - 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, - 0x4011, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, - 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, - 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, - 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, - 0x3000, 0xf005, 0x5ff2, 0x5fe2, 0x5ef2, 0x5fd2, 0x4ee2, 0x4ee2, - 0x5df2, 0x5fc2, 0x5cf2, 0x5ed2, 0x5de2, 0x5fb2, 0x4bf2, 0x4bf2, - 0x5ec2, 0x5ce2, 0x4dd2, 0x4dd2, 0x4fa2, 0x4fa2, 0x4af2, 0x4af2, - 0x4eb2, 0x4eb2, 0x4be2, 0x4be2, 0x4dc2, 0x4dc2, 0x4cd2, 0x4cd2, - 0x4f92, 0x4f92, 0xf005, 0x49f2, 0x49f2, 0x4ae2, 0x4ae2, 0x4db2, - 0x4db2, 0x4bd2, 0x4bd2, 0x4f82, 0x4f82, 0x48f2, 0x48f2, 0x4cc2, - 0x4cc2, 0x4e92, 0x4e92, 0x49e2, 0x49e2, 0x4f72, 0x4f72, 0x47f2, - 0x47f2, 0x4da2, 0x4da2, 0x4ad2, 0x4ad2, 0x4cb2, 0x4cb2, 0x4f62, - 0x4f62, 0x5ea2, 0x5f01, 0xf004, 0x3bc2, 0x3bc2, 0x36f2, 0x36f2, - 0x4e82, 0x48e2, 0x4f52, 0x4d92, 0x35f2, 0x35f2, 0x3e72, 0x3e72, - 0x37e2, 0x37e2, 0x3ca2, 0x3ca2, 0xf004, 0x3ac2, 0x3ac2, 0x3bb2, - 0x3bb2, 0x49d2, 0x4d82, 0x3f42, 0x3f42, 0x34f2, 0x34f2, 0x3f32, - 0x3f32, 0x33f2, 0x33f2, 0x38d2, 0x38d2, 0xf004, 0x36e2, 0x36e2, - 0x3f22, 0x3f22, 0x32f2, 0x32f2, 0x4e62, 0x40f1, 0x3f12, 0x3f12, - 0x31f2, 0x31f2, 0x3c92, 0x3c92, 0x39c2, 0x39c2, 0xf003, 0x3e52, - 0x3ba2, 0x3ab2, 0x35e2, 0x3d72, 0x37d2, 0x3e42, 0x34e2, 0xf003, - 0x3c82, 0x38c2, 0x3e32, 0x3d62, 0x36d2, 0x33e2, 0x3b92, 0x39b2, - 0xf004, 0x3e22, 0x3e22, 0x3aa2, 0x3aa2, 0x32e2, 0x32e2, 0x3e12, - 0x3e12, 0x31e2, 0x31e2, 0x4e01, 0x40e1, 0x3d52, 0x3d52, 0x35d2, - 0x35d2, 0xf003, 0x3c72, 0x37c2, 0x3d42, 0x3b82, 0x24d2, 0x24d2, - 0x38b2, 0x3a92, 0xf003, 0x39a2, 0x3c62, 0x36c2, 0x3d32, 0x23d2, - 0x23d2, 0x22d2, 0x22d2, 0xf003, 0x3d22, 0x3d01, 0x2d12, 0x2d12, - 0x2b72, 0x2b72, 0x27b2, 0x27b2, 0xf003, 0x21d2, 0x21d2, 0x3c52, - 0x30d1, 0x25c2, 0x25c2, 0x2a82, 0x2a82, 0xf002, 0x28a2, 0x2c42, - 0x24c2, 0x2b62, 0xf003, 0x26b2, 0x26b2, 0x3992, 0x3c01, 0x2c32, - 0x2c32, 0x23c2, 0x23c2, 0xf003, 0x2a72, 0x2a72, 0x27a2, 0x27a2, - 0x26a2, 0x26a2, 0x30c1, 0x3b01, 0xf002, 0x12c2, 0x12c2, 0x2c22, - 0x2b52, 0xf002, 0x25b2, 0x2c12, 0x2982, 0x2892, 0xf002, 0x21c2, - 0x2b42, 0x24b2, 0x2a62, 0xf002, 0x2b32, 0x2972, 0x13b2, 0x13b2, - 0xf002, 0x2792, 0x2882, 0x2b22, 0x2a52, 0xf002, 0x12b2, 0x12b2, - 0x25a2, 0x2b12, 0xf002, 0x11b2, 0x11b2, 0x20b1, 0x2962, 0xf002, - 0x2692, 0x2a42, 0x24a2, 0x2872, 0xf002, 0x2782, 0x2a32, 0x13a2, - 0x13a2, 0xf001, 0x1952, 0x1592, 0xf001, 0x1a22, 0x12a2, 0xf001, - 0x1a12, 0x11a2, 0xf002, 0x2a01, 0x20a1, 0x1862, 0x1862, 0xf001, - 0x1682, 0x1942, 0xf001, 0x1492, 0x1932, 0xf002, 0x1392, 0x1392, - 0x2772, 0x2901, 0xf001, 0x1852, 0x1582, 0xf001, 0x1922, 0x1762, - 0xf001, 0x1672, 0x1292, 0xf001, 0x1912, 0x1091, 0xf001, 0x1842, - 0x1482, 0xf001, 0x1752, 0x1572, 0xf001, 0x1832, 0x1382, 0xf001, - 0x1662, 0x1742, 0xf001, 0x1472, 0x1801, 0xf001, 0x1081, 0x1652, - 0xf001, 0x1562, 0x1732, 0xf001, 0x1372, 0x1642, 0xf001, 0x1701, - 0x1071, 0xf001, 0x1601, 0x1061, - - /* huffTable16[651] */ - 0xf008, 0x0101, 0x010a, 0x0113, 0x8ff2, 0x0118, 0x011d, 0x0120, - 0x82f2, 0x0131, 0x8f12, 0x81f2, 0x0134, 0x0145, 0x0156, 0x0167, - 0x0178, 0x0189, 0x019a, 0x01a3, 0x01ac, 0x01b5, 0x01be, 0x01c7, - 0x01d0, 0x01d9, 0x01de, 0x01e3, 0x01e6, 0x01eb, 0x01f0, 0x8152, - 0x01f3, 0x01f6, 0x01f9, 0x01fc, 0x8412, 0x8142, 0x01ff, 0x8322, - 0x8232, 0x7312, 0x7312, 0x7132, 0x7132, 0x8301, 0x8031, 0x7222, - 0x7222, 0x6212, 0x6212, 0x6212, 0x6212, 0x6122, 0x6122, 0x6122, - 0x6122, 0x6201, 0x6201, 0x6201, 0x6201, 0x6021, 0x6021, 0x6021, - 0x6021, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, - 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, - 0x4112, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, - 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, - 0x4101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, - 0x3011, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0xf003, 0x3fe2, 0x3ef2, 0x3fd2, 0x3df2, 0x3fc2, 0x3cf2, - 0x3fb2, 0x3bf2, 0xf003, 0x2fa2, 0x2fa2, 0x3af2, 0x3f92, 0x39f2, - 0x38f2, 0x2f82, 0x2f82, 0xf002, 0x2f72, 0x27f2, 0x2f62, 0x26f2, - 0xf002, 0x2f52, 0x25f2, 0x1f42, 0x1f42, 0xf001, 0x14f2, 0x13f2, - 0xf004, 0x10f1, 0x10f1, 0x10f1, 0x10f1, 0x10f1, 0x10f1, 0x10f1, - 0x10f1, 0x2f32, 0x2f32, 0x2f32, 0x2f32, 0x00e2, 0x00f3, 0x00fc, - 0x0105, 0xf001, 0x1f22, 0x1f01, 0xf004, 0x00fa, 0x00ff, 0x0104, - 0x0109, 0x010c, 0x0111, 0x0116, 0x0119, 0x011e, 0x0123, 0x0128, - 0x43e2, 0x012d, 0x0130, 0x0133, 0x0136, 0xf004, 0x0128, 0x012b, - 0x012e, 0x4d01, 0x0131, 0x0134, 0x0137, 0x4c32, 0x013a, 0x4c12, - 0x40c1, 0x013d, 0x32e2, 0x32e2, 0x4e22, 0x4e12, 0xf004, 0x43d2, - 0x4d22, 0x42d2, 0x41d2, 0x4b32, 0x012f, 0x3d12, 0x3d12, 0x44c2, - 0x4b62, 0x43c2, 0x47a2, 0x3c22, 0x3c22, 0x42c2, 0x45b2, 0xf004, - 0x41c2, 0x4c01, 0x4b42, 0x44b2, 0x4a62, 0x46a2, 0x33b2, 0x33b2, - 0x4a52, 0x45a2, 0x3b22, 0x3b22, 0x32b2, 0x32b2, 0x3b12, 0x3b12, - 0xf004, 0x31b2, 0x31b2, 0x4b01, 0x40b1, 0x4962, 0x4692, 0x4a42, - 0x44a2, 0x4872, 0x4782, 0x33a2, 0x33a2, 0x4a32, 0x4952, 0x3a22, - 0x3a22, 0xf004, 0x4592, 0x4862, 0x31a2, 0x31a2, 0x4682, 0x4772, - 0x3492, 0x3492, 0x4942, 0x4752, 0x3762, 0x3762, 0x22a2, 0x22a2, - 0x22a2, 0x22a2, 0xf003, 0x2a12, 0x2a12, 0x3a01, 0x30a1, 0x3932, - 0x3392, 0x3852, 0x3582, 0xf003, 0x2922, 0x2922, 0x2292, 0x2292, - 0x3672, 0x3901, 0x2912, 0x2912, 0xf003, 0x2192, 0x2192, 0x3091, - 0x3842, 0x3482, 0x3572, 0x3832, 0x3382, 0xf003, 0x3662, 0x3822, - 0x2282, 0x2282, 0x3742, 0x3472, 0x2812, 0x2812, 0xf003, 0x2182, - 0x2182, 0x2081, 0x2081, 0x3801, 0x3652, 0x2732, 0x2732, 0xf003, - 0x2372, 0x2372, 0x3562, 0x3642, 0x2722, 0x2722, 0x2272, 0x2272, - 0xf003, 0x3462, 0x3552, 0x2701, 0x2701, 0x1712, 0x1712, 0x1712, - 0x1712, 0xf002, 0x1172, 0x1172, 0x2071, 0x2632, 0xf002, 0x2362, - 0x2542, 0x2452, 0x2622, 0xf001, 0x1262, 0x1612, 0xf002, 0x1162, - 0x1162, 0x2601, 0x2061, 0xf002, 0x1352, 0x1352, 0x2532, 0x2442, - 0xf001, 0x1522, 0x1252, 0xf001, 0x1512, 0x1501, 0xf001, 0x1432, - 0x1342, 0xf001, 0x1051, 0x1422, 0xf001, 0x1242, 0x1332, 0xf001, - 0x1401, 0x1041, 0xf004, 0x4ec2, 0x0086, 0x3ed2, 0x3ed2, 0x39e2, - 0x39e2, 0x4ae2, 0x49d2, 0x2ee2, 0x2ee2, 0x2ee2, 0x2ee2, 0x3de2, - 0x3de2, 0x3be2, 0x3be2, 0xf003, 0x2eb2, 0x2eb2, 0x2dc2, 0x2dc2, - 0x3cd2, 0x3bd2, 0x2ea2, 0x2ea2, 0xf003, 0x2cc2, 0x2cc2, 0x3da2, - 0x3ad2, 0x3e72, 0x3ca2, 0x2ac2, 0x2ac2, 0xf003, 0x39c2, 0x3d72, - 0x2e52, 0x2e52, 0x1db2, 0x1db2, 0x1db2, 0x1db2, 0xf002, 0x1e92, - 0x1e92, 0x2cb2, 0x2bc2, 0xf002, 0x2e82, 0x28e2, 0x2d92, 0x27e2, - 0xf002, 0x2bb2, 0x2d82, 0x28d2, 0x2e62, 0xf001, 0x16e2, 0x1c92, - 0xf002, 0x2ba2, 0x2ab2, 0x25e2, 0x27d2, 0xf002, 0x1e42, 0x1e42, - 0x24e2, 0x2c82, 0xf001, 0x18c2, 0x1e32, 0xf002, 0x1d62, 0x1d62, - 0x26d2, 0x2b92, 0xf002, 0x29b2, 0x2aa2, 0x11e2, 0x11e2, 0xf002, - 0x14d2, 0x14d2, 0x28b2, 0x29a2, 0xf002, 0x1b72, 0x1b72, 0x27b2, - 0x20d1, 0xf001, 0x1e01, 0x10e1, 0xf001, 0x1d52, 0x15d2, 0xf001, - 0x1c72, 0x17c2, 0xf001, 0x1d42, 0x1b82, 0xf001, 0x1a92, 0x1c62, - 0xf001, 0x16c2, 0x1d32, 0xf001, 0x1c52, 0x15c2, 0xf001, 0x1a82, - 0x18a2, 0xf001, 0x1992, 0x1c42, 0xf001, 0x16b2, 0x1a72, 0xf001, - 0x1b52, 0x1982, 0xf001, 0x1892, 0x1972, 0xf001, 0x1792, 0x1882, - 0xf001, 0x1ce2, 0x1dd2, - - /* huffTable24[705] */ - 0xf009, 0x8fe2, 0x8fe2, 0x8ef2, 0x8ef2, 0x8fd2, 0x8fd2, 0x8df2, - 0x8df2, 0x8fc2, 0x8fc2, 0x8cf2, 0x8cf2, 0x8fb2, 0x8fb2, 0x8bf2, - 0x8bf2, 0x7af2, 0x7af2, 0x7af2, 0x7af2, 0x8fa2, 0x8fa2, 0x8f92, - 0x8f92, 0x79f2, 0x79f2, 0x79f2, 0x79f2, 0x78f2, 0x78f2, 0x78f2, - 0x78f2, 0x8f82, 0x8f82, 0x8f72, 0x8f72, 0x77f2, 0x77f2, 0x77f2, - 0x77f2, 0x7f62, 0x7f62, 0x7f62, 0x7f62, 0x76f2, 0x76f2, 0x76f2, - 0x76f2, 0x7f52, 0x7f52, 0x7f52, 0x7f52, 0x75f2, 0x75f2, 0x75f2, - 0x75f2, 0x7f42, 0x7f42, 0x7f42, 0x7f42, 0x74f2, 0x74f2, 0x74f2, - 0x74f2, 0x7f32, 0x7f32, 0x7f32, 0x7f32, 0x73f2, 0x73f2, 0x73f2, - 0x73f2, 0x7f22, 0x7f22, 0x7f22, 0x7f22, 0x72f2, 0x72f2, 0x72f2, - 0x72f2, 0x71f2, 0x71f2, 0x71f2, 0x71f2, 0x8f12, 0x8f12, 0x80f1, - 0x80f1, 0x9f01, 0x0201, 0x0206, 0x020b, 0x0210, 0x0215, 0x021a, - 0x021f, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, - 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, - 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, - 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, - 0x4ff2, 0x0224, 0x0229, 0x0232, 0x0237, 0x023a, 0x023f, 0x0242, - 0x0245, 0x024a, 0x024d, 0x0250, 0x0253, 0x0256, 0x0259, 0x025c, - 0x025f, 0x0262, 0x0265, 0x0268, 0x026b, 0x026e, 0x0271, 0x0274, - 0x0277, 0x027a, 0x027d, 0x0280, 0x0283, 0x0288, 0x028b, 0x028e, - 0x0291, 0x0294, 0x0297, 0x029a, 0x029f, 0x94b2, 0x02a4, 0x02a7, - 0x02aa, 0x93b2, 0x9882, 0x02af, 0x92b2, 0x02b2, 0x02b5, 0x9692, - 0x94a2, 0x02b8, 0x9782, 0x9a32, 0x93a2, 0x9952, 0x9592, 0x9a22, - 0x92a2, 0x91a2, 0x9862, 0x9682, 0x9772, 0x9942, 0x9492, 0x9932, - 0x9392, 0x9852, 0x9582, 0x9922, 0x9762, 0x9672, 0x9292, 0x9912, - 0x9192, 0x9842, 0x9482, 0x9752, 0x9572, 0x9832, 0x9382, 0x9662, - 0x9822, 0x9282, 0x9812, 0x9742, 0x9472, 0x9182, 0x02bb, 0x9652, - 0x9562, 0x9712, 0x02be, 0x8372, 0x8372, 0x9732, 0x9722, 0x8272, - 0x8272, 0x8642, 0x8642, 0x8462, 0x8462, 0x8552, 0x8552, 0x8172, - 0x8172, 0x8632, 0x8632, 0x8362, 0x8362, 0x8542, 0x8542, 0x8452, - 0x8452, 0x8622, 0x8622, 0x8262, 0x8262, 0x8612, 0x8612, 0x8162, - 0x8162, 0x9601, 0x9061, 0x8532, 0x8532, 0x8352, 0x8352, 0x8442, - 0x8442, 0x8522, 0x8522, 0x8252, 0x8252, 0x8512, 0x8512, 0x9501, - 0x9051, 0x7152, 0x7152, 0x7152, 0x7152, 0x8432, 0x8432, 0x8342, - 0x8342, 0x7422, 0x7422, 0x7422, 0x7422, 0x7242, 0x7242, 0x7242, - 0x7242, 0x7332, 0x7332, 0x7332, 0x7332, 0x7412, 0x7412, 0x7412, - 0x7412, 0x7142, 0x7142, 0x7142, 0x7142, 0x8401, 0x8401, 0x8041, - 0x8041, 0x7322, 0x7322, 0x7322, 0x7322, 0x7232, 0x7232, 0x7232, - 0x7232, 0x6312, 0x6312, 0x6312, 0x6312, 0x6312, 0x6312, 0x6312, - 0x6312, 0x6132, 0x6132, 0x6132, 0x6132, 0x6132, 0x6132, 0x6132, - 0x6132, 0x7301, 0x7301, 0x7301, 0x7301, 0x7031, 0x7031, 0x7031, - 0x7031, 0x6222, 0x6222, 0x6222, 0x6222, 0x6222, 0x6222, 0x6222, - 0x6222, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, - 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, - 0x5212, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, - 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, - 0x5122, 0x6201, 0x6201, 0x6201, 0x6201, 0x6201, 0x6201, 0x6201, - 0x6201, 0x6021, 0x6021, 0x6021, 0x6021, 0x6021, 0x6021, 0x6021, - 0x6021, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, - 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, - 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, - 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, - 0x4112, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, - 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, - 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, - 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, - 0x4101, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, - 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, - 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, - 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, - 0x4011, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, - 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, - 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, - 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, - 0x4000, 0xf002, 0x2ee2, 0x2ed2, 0x2de2, 0x2ec2, 0xf002, 0x2ce2, - 0x2dd2, 0x2eb2, 0x2be2, 0xf002, 0x2dc2, 0x2cd2, 0x2ea2, 0x2ae2, - 0xf002, 0x2db2, 0x2bd2, 0x2cc2, 0x2e92, 0xf002, 0x29e2, 0x2da2, - 0x2ad2, 0x2cb2, 0xf002, 0x2bc2, 0x2e82, 0x28e2, 0x2d92, 0xf002, - 0x29d2, 0x2e72, 0x27e2, 0x2ca2, 0xf002, 0x2ac2, 0x2bb2, 0x2d82, - 0x28d2, 0xf003, 0x3e01, 0x30e1, 0x2d01, 0x2d01, 0x16e2, 0x16e2, - 0x16e2, 0x16e2, 0xf002, 0x2e62, 0x2c92, 0x19c2, 0x19c2, 0xf001, - 0x1e52, 0x1ab2, 0xf002, 0x15e2, 0x15e2, 0x2ba2, 0x2d72, 0xf001, - 0x17d2, 0x14e2, 0xf001, 0x1c82, 0x18c2, 0xf002, 0x2e42, 0x2e22, - 0x1e32, 0x1e32, 0xf001, 0x1d62, 0x16d2, 0xf001, 0x13e2, 0x1b92, - 0xf001, 0x19b2, 0x1aa2, 0xf001, 0x12e2, 0x1e12, 0xf001, 0x11e2, - 0x1d52, 0xf001, 0x15d2, 0x1c72, 0xf001, 0x17c2, 0x1d42, 0xf001, - 0x1b82, 0x18b2, 0xf001, 0x14d2, 0x1a92, 0xf001, 0x19a2, 0x1c62, - 0xf001, 0x16c2, 0x1d32, 0xf001, 0x13d2, 0x1d22, 0xf001, 0x12d2, - 0x1d12, 0xf001, 0x1b72, 0x17b2, 0xf001, 0x11d2, 0x1c52, 0xf001, - 0x15c2, 0x1a82, 0xf001, 0x18a2, 0x1992, 0xf001, 0x1c42, 0x14c2, - 0xf001, 0x1b62, 0x16b2, 0xf002, 0x20d1, 0x2c01, 0x1c32, 0x1c32, - 0xf001, 0x13c2, 0x1a72, 0xf001, 0x17a2, 0x1c22, 0xf001, 0x12c2, - 0x1b52, 0xf001, 0x15b2, 0x1c12, 0xf001, 0x1982, 0x1892, 0xf001, - 0x11c2, 0x1b42, 0xf002, 0x20c1, 0x2b01, 0x1b32, 0x1b32, 0xf002, - 0x20b1, 0x2a01, 0x1a12, 0x1a12, 0xf001, 0x1a62, 0x16a2, 0xf001, - 0x1972, 0x1792, 0xf002, 0x20a1, 0x2901, 0x1091, 0x1091, 0xf001, - 0x1b22, 0x1a52, 0xf001, 0x15a2, 0x1b12, 0xf001, 0x11b2, 0x1962, - 0xf001, 0x1a42, 0x1872, 0xf001, 0x1801, 0x1081, 0xf001, 0x1701, - 0x1071, + /* huffTable01[9] */ + 0xf003, 0x3112, 0x3101, 0x2011, 0x2011, 0x1000, 0x1000, 0x1000, + 0x1000, + + /* huffTable02[65] */ + 0xf006, 0x6222, 0x6201, 0x5212, 0x5212, 0x5122, 0x5122, 0x5021, + 0x5021, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, + 0x3112, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, + + /* huffTable03[65] */ + 0xf006, 0x6222, 0x6201, 0x5212, 0x5212, 0x5122, 0x5122, 0x5021, + 0x5021, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, + 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, + 0x2112, 0x2101, 0x2101, 0x2101, 0x2101, 0x2101, 0x2101, 0x2101, + 0x2101, 0x2101, 0x2101, 0x2101, 0x2101, 0x2101, 0x2101, 0x2101, + 0x2101, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, + + /* huffTable05[257] */ + 0xf008, 0x8332, 0x8322, 0x7232, 0x7232, 0x6132, 0x6132, 0x6132, + 0x6132, 0x7312, 0x7312, 0x7301, 0x7301, 0x7031, 0x7031, 0x7222, + 0x7222, 0x6212, 0x6212, 0x6212, 0x6212, 0x6122, 0x6122, 0x6122, + 0x6122, 0x6201, 0x6201, 0x6201, 0x6201, 0x6021, 0x6021, 0x6021, + 0x6021, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, + 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, + 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, + 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, + 0x3112, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, + + /* huffTable06[129] */ + 0xf007, 0x7332, 0x7301, 0x6322, 0x6322, 0x6232, 0x6232, 0x6031, + 0x6031, 0x5312, 0x5312, 0x5312, 0x5312, 0x5132, 0x5132, 0x5132, + 0x5132, 0x5222, 0x5222, 0x5222, 0x5222, 0x5201, 0x5201, 0x5201, + 0x5201, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, + 0x4212, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, + 0x4122, 0x4021, 0x4021, 0x4021, 0x4021, 0x4021, 0x4021, 0x4021, + 0x4021, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, + 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, + 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, + 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, + 0x2112, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, + 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, + 0x3000, + + /* huffTable07[110] */ + 0xf006, 0x0041, 0x0052, 0x005b, 0x0060, 0x0063, 0x0068, 0x006b, + 0x6212, 0x5122, 0x5122, 0x6201, 0x6021, 0x4112, 0x4112, 0x4112, + 0x4112, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0xf004, 0x4552, 0x4542, 0x4452, 0x4352, 0x3532, 0x3532, + 0x3442, 0x3442, 0x3522, 0x3522, 0x3252, 0x3252, 0x2512, 0x2512, + 0x2512, 0x2512, 0xf003, 0x2152, 0x2152, 0x3501, 0x3432, 0x2051, + 0x2051, 0x3342, 0x3332, 0xf002, 0x2422, 0x2242, 0x1412, 0x1412, + 0xf001, 0x1142, 0x1041, 0xf002, 0x2401, 0x2322, 0x2232, 0x2301, + 0xf001, 0x1312, 0x1132, 0xf001, 0x1031, 0x1222, + + /* huffTable08[280] */ + 0xf008, 0x0101, 0x010a, 0x010f, 0x8512, 0x8152, 0x0112, 0x0115, + 0x8422, 0x8242, 0x8412, 0x7142, 0x7142, 0x8401, 0x8041, 0x8322, + 0x8232, 0x8312, 0x8132, 0x8301, 0x8031, 0x6222, 0x6222, 0x6222, + 0x6222, 0x6201, 0x6201, 0x6201, 0x6201, 0x6021, 0x6021, 0x6021, + 0x6021, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, + 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, + 0x4212, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, + 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, + 0x4122, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, + 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, + 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, + 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, + 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, + 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, + 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, + 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, 0x2112, + 0x2112, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, 0xf003, 0x3552, 0x3452, 0x2542, 0x2542, 0x1352, 0x1352, + 0x1352, 0x1352, 0xf002, 0x2532, 0x2442, 0x1522, 0x1522, 0xf001, + 0x1252, 0x1501, 0xf001, 0x1432, 0x1342, 0xf001, 0x1051, 0x1332, + + /* huffTable09[93] */ + 0xf006, 0x0041, 0x004a, 0x004f, 0x0052, 0x0057, 0x005a, 0x6412, + 0x6142, 0x6322, 0x6232, 0x5312, 0x5312, 0x5132, 0x5132, 0x6301, + 0x6031, 0x5222, 0x5222, 0x5201, 0x5201, 0x4212, 0x4212, 0x4212, + 0x4212, 0x4122, 0x4122, 0x4122, 0x4122, 0x4021, 0x4021, 0x4021, + 0x4021, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, + 0x3112, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, + 0x3000, 0xf003, 0x3552, 0x3542, 0x2532, 0x2532, 0x2352, 0x2352, + 0x3452, 0x3501, 0xf002, 0x2442, 0x2522, 0x2252, 0x2512, 0xf001, + 0x1152, 0x1432, 0xf002, 0x1342, 0x1342, 0x2051, 0x2401, 0xf001, + 0x1422, 0x1242, 0xf001, 0x1332, 0x1041, + + /* huffTable10[320] */ + 0xf008, 0x0101, 0x010a, 0x010f, 0x0118, 0x011b, 0x0120, 0x0125, + 0x8712, 0x8172, 0x012a, 0x012d, 0x0132, 0x8612, 0x8162, 0x8061, + 0x0137, 0x013a, 0x013d, 0x8412, 0x8142, 0x8041, 0x8322, 0x8232, + 0x8301, 0x7312, 0x7312, 0x7132, 0x7132, 0x7031, 0x7031, 0x7222, + 0x7222, 0x6212, 0x6212, 0x6212, 0x6212, 0x6122, 0x6122, 0x6122, + 0x6122, 0x6201, 0x6201, 0x6201, 0x6201, 0x6021, 0x6021, 0x6021, + 0x6021, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, + 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, + 0x4112, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0xf003, 0x3772, 0x3762, 0x3672, 0x3752, 0x3572, 0x3662, + 0x2742, 0x2742, 0xf002, 0x2472, 0x2652, 0x2562, 0x2732, 0xf003, + 0x2372, 0x2372, 0x2642, 0x2642, 0x3552, 0x3452, 0x2362, 0x2362, + 0xf001, 0x1722, 0x1272, 0xf002, 0x2462, 0x2701, 0x1071, 0x1071, + 0xf002, 0x1262, 0x1262, 0x2542, 0x2532, 0xf002, 0x1601, 0x1601, + 0x2352, 0x2442, 0xf001, 0x1632, 0x1622, 0xf002, 0x2522, 0x2252, + 0x1512, 0x1512, 0xf002, 0x1152, 0x1152, 0x2432, 0x2342, 0xf001, + 0x1501, 0x1051, 0xf001, 0x1422, 0x1242, 0xf001, 0x1332, 0x1401, + + /* huffTable11[296] */ + 0xf008, 0x0101, 0x0106, 0x010f, 0x0114, 0x0117, 0x8722, 0x8272, + 0x011c, 0x7172, 0x7172, 0x8712, 0x8071, 0x8632, 0x8362, 0x8061, + 0x011f, 0x0122, 0x8512, 0x7262, 0x7262, 0x8622, 0x8601, 0x7612, + 0x7612, 0x7162, 0x7162, 0x8152, 0x8432, 0x8051, 0x0125, 0x8422, + 0x8242, 0x8412, 0x8142, 0x8401, 0x8041, 0x7322, 0x7322, 0x7232, + 0x7232, 0x6312, 0x6312, 0x6312, 0x6312, 0x6132, 0x6132, 0x6132, + 0x6132, 0x7301, 0x7301, 0x7031, 0x7031, 0x6222, 0x6222, 0x6222, + 0x6222, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, + 0x5122, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, + 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, + 0x4212, 0x5201, 0x5201, 0x5201, 0x5201, 0x5201, 0x5201, 0x5201, + 0x5201, 0x5021, 0x5021, 0x5021, 0x5021, 0x5021, 0x5021, 0x5021, + 0x5021, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, + 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, + 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, + 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, + 0x3112, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, + 0x2000, 0xf002, 0x2772, 0x2762, 0x2672, 0x2572, 0xf003, 0x2662, + 0x2662, 0x2742, 0x2742, 0x2472, 0x2472, 0x3752, 0x3552, 0xf002, + 0x2652, 0x2562, 0x1732, 0x1732, 0xf001, 0x1372, 0x1642, 0xf002, + 0x2542, 0x2452, 0x2532, 0x2352, 0xf001, 0x1462, 0x1701, 0xf001, + 0x1442, 0x1522, 0xf001, 0x1252, 0x1501, 0xf001, 0x1342, 0x1332, + + /* huffTable12[185] */ + 0xf007, 0x0081, 0x008a, 0x008f, 0x0092, 0x0097, 0x009a, 0x009d, + 0x00a2, 0x00a5, 0x00a8, 0x7622, 0x7262, 0x7162, 0x00ad, 0x00b0, + 0x00b3, 0x7512, 0x7152, 0x7432, 0x7342, 0x00b6, 0x7422, 0x7242, + 0x7412, 0x6332, 0x6332, 0x6142, 0x6142, 0x6322, 0x6322, 0x6232, + 0x6232, 0x7041, 0x7301, 0x6031, 0x6031, 0x5312, 0x5312, 0x5312, + 0x5312, 0x5132, 0x5132, 0x5132, 0x5132, 0x5222, 0x5222, 0x5222, + 0x5222, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, 0x4212, + 0x4212, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, 0x4122, + 0x4122, 0x5201, 0x5201, 0x5201, 0x5201, 0x5021, 0x5021, 0x5021, + 0x5021, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, + 0x4000, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, + 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, + 0x3112, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, 0x3101, + 0x3101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0xf003, 0x3772, 0x3762, 0x2672, 0x2672, 0x2752, 0x2752, + 0x2572, 0x2572, 0xf002, 0x2662, 0x2742, 0x2472, 0x2562, 0xf001, + 0x1652, 0x1732, 0xf002, 0x2372, 0x2552, 0x1722, 0x1722, 0xf001, + 0x1272, 0x1642, 0xf001, 0x1462, 0x1712, 0xf002, 0x1172, 0x1172, + 0x2701, 0x2071, 0xf001, 0x1632, 0x1362, 0xf001, 0x1542, 0x1452, + 0xf002, 0x1442, 0x1442, 0x2601, 0x2501, 0xf001, 0x1612, 0x1061, + 0xf001, 0x1532, 0x1352, 0xf001, 0x1522, 0x1252, 0xf001, 0x1051, + 0x1401, + + /* huffTable13[497] */ + 0xf006, 0x0041, 0x0082, 0x00c3, 0x00e4, 0x0105, 0x0116, 0x011f, + 0x0130, 0x0139, 0x013e, 0x0143, 0x0146, 0x6212, 0x6122, 0x6201, + 0x6021, 0x4112, 0x4112, 0x4112, 0x4112, 0x4101, 0x4101, 0x4101, + 0x4101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0xf006, 0x0108, 0x0111, 0x011a, 0x0123, 0x012c, 0x0131, + 0x0136, 0x013f, 0x0144, 0x0147, 0x014c, 0x0151, 0x0156, 0x015b, + 0x6f12, 0x61f2, 0x60f1, 0x0160, 0x0163, 0x0166, 0x62e2, 0x0169, + 0x6e12, 0x61e2, 0x016c, 0x016f, 0x0172, 0x0175, 0x0178, 0x017b, + 0x66c2, 0x6d32, 0x017e, 0x6d22, 0x62d2, 0x6d12, 0x67b2, 0x0181, + 0x0184, 0x63c2, 0x0187, 0x6b42, 0x51d2, 0x51d2, 0x6d01, 0x60d1, + 0x6a82, 0x68a2, 0x6c42, 0x64c2, 0x6b62, 0x66b2, 0x5c32, 0x5c32, + 0x5c22, 0x5c22, 0x52c2, 0x52c2, 0x5b52, 0x5b52, 0x65b2, 0x6982, + 0x5c12, 0x5c12, 0xf006, 0x51c2, 0x51c2, 0x6892, 0x6c01, 0x50c1, + 0x50c1, 0x64b2, 0x6a62, 0x66a2, 0x6972, 0x5b32, 0x5b32, 0x53b2, + 0x53b2, 0x6882, 0x6a52, 0x5b22, 0x5b22, 0x65a2, 0x6962, 0x54a2, + 0x54a2, 0x6872, 0x6782, 0x5492, 0x5492, 0x6772, 0x6672, 0x42b2, + 0x42b2, 0x42b2, 0x42b2, 0x4b12, 0x4b12, 0x4b12, 0x4b12, 0x41b2, + 0x41b2, 0x41b2, 0x41b2, 0x5b01, 0x5b01, 0x50b1, 0x50b1, 0x5692, + 0x5692, 0x5a42, 0x5a42, 0x5a32, 0x5a32, 0x53a2, 0x53a2, 0x5952, + 0x5952, 0x5592, 0x5592, 0x4a22, 0x4a22, 0x4a22, 0x4a22, 0x42a2, + 0x42a2, 0x42a2, 0x42a2, 0xf005, 0x4a12, 0x4a12, 0x41a2, 0x41a2, + 0x5a01, 0x5862, 0x40a1, 0x40a1, 0x5682, 0x5942, 0x4392, 0x4392, + 0x5932, 0x5852, 0x5582, 0x5762, 0x4922, 0x4922, 0x4292, 0x4292, + 0x5752, 0x5572, 0x4832, 0x4832, 0x4382, 0x4382, 0x5662, 0x5742, + 0x5472, 0x5652, 0x5562, 0x5372, 0xf005, 0x3912, 0x3912, 0x3912, + 0x3912, 0x3192, 0x3192, 0x3192, 0x3192, 0x4901, 0x4901, 0x4091, + 0x4091, 0x4842, 0x4842, 0x4482, 0x4482, 0x4272, 0x4272, 0x5642, + 0x5462, 0x3822, 0x3822, 0x3822, 0x3822, 0x3282, 0x3282, 0x3282, + 0x3282, 0x3812, 0x3812, 0x3812, 0x3812, 0xf004, 0x4732, 0x4722, + 0x3712, 0x3712, 0x3172, 0x3172, 0x4552, 0x4701, 0x4071, 0x4632, + 0x4362, 0x4542, 0x4452, 0x4622, 0x4262, 0x4532, 0xf003, 0x2182, + 0x2182, 0x3801, 0x3081, 0x3612, 0x3162, 0x3601, 0x3061, 0xf004, + 0x4352, 0x4442, 0x3522, 0x3522, 0x3252, 0x3252, 0x3501, 0x3501, + 0x2512, 0x2512, 0x2512, 0x2512, 0x2152, 0x2152, 0x2152, 0x2152, + 0xf003, 0x3432, 0x3342, 0x3051, 0x3422, 0x3242, 0x3332, 0x2412, + 0x2412, 0xf002, 0x1142, 0x1142, 0x2401, 0x2041, 0xf002, 0x2322, + 0x2232, 0x1312, 0x1312, 0xf001, 0x1132, 0x1301, 0xf001, 0x1031, + 0x1222, 0xf003, 0x0082, 0x008b, 0x008e, 0x0091, 0x0094, 0x0097, + 0x3ce2, 0x3dd2, 0xf003, 0x0093, 0x3eb2, 0x3be2, 0x3f92, 0x39f2, + 0x3ae2, 0x3db2, 0x3bd2, 0xf003, 0x3f82, 0x38f2, 0x3cc2, 0x008d, + 0x3e82, 0x0090, 0x27f2, 0x27f2, 0xf003, 0x2ad2, 0x2ad2, 0x3da2, + 0x3cb2, 0x3bc2, 0x36f2, 0x2f62, 0x2f62, 0xf002, 0x28e2, 0x2f52, + 0x2d92, 0x29d2, 0xf002, 0x25f2, 0x27e2, 0x2ca2, 0x2bb2, 0xf003, + 0x2f42, 0x2f42, 0x24f2, 0x24f2, 0x3ac2, 0x36e2, 0x23f2, 0x23f2, + 0xf002, 0x1f32, 0x1f32, 0x2d82, 0x28d2, 0xf001, 0x1f22, 0x12f2, + 0xf002, 0x2e62, 0x2c92, 0x1f01, 0x1f01, 0xf002, 0x29c2, 0x2e52, + 0x1ba2, 0x1ba2, 0xf002, 0x2d72, 0x27d2, 0x1e42, 0x1e42, 0xf002, + 0x28c2, 0x26d2, 0x1e32, 0x1e32, 0xf002, 0x19b2, 0x19b2, 0x2b92, + 0x2aa2, 0xf001, 0x1ab2, 0x15e2, 0xf001, 0x14e2, 0x1c82, 0xf001, + 0x1d62, 0x13e2, 0xf001, 0x1e22, 0x1e01, 0xf001, 0x10e1, 0x1d52, + 0xf001, 0x15d2, 0x1c72, 0xf001, 0x17c2, 0x1d42, 0xf001, 0x1b82, + 0x18b2, 0xf001, 0x14d2, 0x1a92, 0xf001, 0x19a2, 0x1c62, 0xf001, + 0x13d2, 0x1b72, 0xf001, 0x1c52, 0x15c2, 0xf001, 0x1992, 0x1a72, + 0xf001, 0x17a2, 0x1792, 0xf003, 0x0023, 0x3df2, 0x2de2, 0x2de2, + 0x1ff2, 0x1ff2, 0x1ff2, 0x1ff2, 0xf001, 0x1fe2, 0x1fd2, 0xf001, + 0x1ee2, 0x1fc2, 0xf001, 0x1ed2, 0x1fb2, 0xf001, 0x1bf2, 0x1ec2, + 0xf002, 0x1cd2, 0x1cd2, 0x2fa2, 0x29e2, 0xf001, 0x1af2, 0x1dc2, + 0xf001, 0x1ea2, 0x1e92, 0xf001, 0x1f72, 0x1e72, 0xf001, 0x1ef2, + 0x1cf2, + + /* huffTable15[580] */ + 0xf008, 0x0101, 0x0122, 0x0143, 0x0154, 0x0165, 0x0176, 0x017f, + 0x0188, 0x0199, 0x01a2, 0x01ab, 0x01b4, 0x01bd, 0x01c2, 0x01cb, + 0x01d4, 0x01d9, 0x01de, 0x01e3, 0x01e8, 0x01ed, 0x01f2, 0x01f7, + 0x01fc, 0x0201, 0x0204, 0x0207, 0x020a, 0x020f, 0x0212, 0x0215, + 0x021a, 0x021d, 0x0220, 0x8192, 0x0223, 0x0226, 0x0229, 0x022c, + 0x022f, 0x8822, 0x8282, 0x8812, 0x8182, 0x0232, 0x0235, 0x0238, + 0x023b, 0x8722, 0x8272, 0x8462, 0x8712, 0x8552, 0x8172, 0x023e, + 0x8632, 0x8362, 0x8542, 0x8452, 0x8622, 0x8262, 0x8612, 0x0241, + 0x8532, 0x7162, 0x7162, 0x8352, 0x8442, 0x7522, 0x7522, 0x7252, + 0x7252, 0x7512, 0x7512, 0x7152, 0x7152, 0x8501, 0x8051, 0x7432, + 0x7432, 0x7342, 0x7342, 0x7422, 0x7422, 0x7242, 0x7242, 0x7332, + 0x7332, 0x6142, 0x6142, 0x6142, 0x6142, 0x7412, 0x7412, 0x7401, + 0x7401, 0x6322, 0x6322, 0x6322, 0x6322, 0x6232, 0x6232, 0x6232, + 0x6232, 0x7041, 0x7041, 0x7301, 0x7301, 0x6312, 0x6312, 0x6312, + 0x6312, 0x6132, 0x6132, 0x6132, 0x6132, 0x6031, 0x6031, 0x6031, + 0x6031, 0x5222, 0x5222, 0x5222, 0x5222, 0x5222, 0x5222, 0x5222, + 0x5222, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, + 0x5212, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, + 0x5122, 0x5201, 0x5201, 0x5201, 0x5201, 0x5201, 0x5201, 0x5201, + 0x5201, 0x5021, 0x5021, 0x5021, 0x5021, 0x5021, 0x5021, 0x5021, + 0x5021, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, + 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, + 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, + 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, 0x3112, + 0x3112, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, + 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, + 0x4101, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, + 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, + 0x4011, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, + 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, + 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, + 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, + 0x3000, 0xf005, 0x5ff2, 0x5fe2, 0x5ef2, 0x5fd2, 0x4ee2, 0x4ee2, + 0x5df2, 0x5fc2, 0x5cf2, 0x5ed2, 0x5de2, 0x5fb2, 0x4bf2, 0x4bf2, + 0x5ec2, 0x5ce2, 0x4dd2, 0x4dd2, 0x4fa2, 0x4fa2, 0x4af2, 0x4af2, + 0x4eb2, 0x4eb2, 0x4be2, 0x4be2, 0x4dc2, 0x4dc2, 0x4cd2, 0x4cd2, + 0x4f92, 0x4f92, 0xf005, 0x49f2, 0x49f2, 0x4ae2, 0x4ae2, 0x4db2, + 0x4db2, 0x4bd2, 0x4bd2, 0x4f82, 0x4f82, 0x48f2, 0x48f2, 0x4cc2, + 0x4cc2, 0x4e92, 0x4e92, 0x49e2, 0x49e2, 0x4f72, 0x4f72, 0x47f2, + 0x47f2, 0x4da2, 0x4da2, 0x4ad2, 0x4ad2, 0x4cb2, 0x4cb2, 0x4f62, + 0x4f62, 0x5ea2, 0x5f01, 0xf004, 0x3bc2, 0x3bc2, 0x36f2, 0x36f2, + 0x4e82, 0x48e2, 0x4f52, 0x4d92, 0x35f2, 0x35f2, 0x3e72, 0x3e72, + 0x37e2, 0x37e2, 0x3ca2, 0x3ca2, 0xf004, 0x3ac2, 0x3ac2, 0x3bb2, + 0x3bb2, 0x49d2, 0x4d82, 0x3f42, 0x3f42, 0x34f2, 0x34f2, 0x3f32, + 0x3f32, 0x33f2, 0x33f2, 0x38d2, 0x38d2, 0xf004, 0x36e2, 0x36e2, + 0x3f22, 0x3f22, 0x32f2, 0x32f2, 0x4e62, 0x40f1, 0x3f12, 0x3f12, + 0x31f2, 0x31f2, 0x3c92, 0x3c92, 0x39c2, 0x39c2, 0xf003, 0x3e52, + 0x3ba2, 0x3ab2, 0x35e2, 0x3d72, 0x37d2, 0x3e42, 0x34e2, 0xf003, + 0x3c82, 0x38c2, 0x3e32, 0x3d62, 0x36d2, 0x33e2, 0x3b92, 0x39b2, + 0xf004, 0x3e22, 0x3e22, 0x3aa2, 0x3aa2, 0x32e2, 0x32e2, 0x3e12, + 0x3e12, 0x31e2, 0x31e2, 0x4e01, 0x40e1, 0x3d52, 0x3d52, 0x35d2, + 0x35d2, 0xf003, 0x3c72, 0x37c2, 0x3d42, 0x3b82, 0x24d2, 0x24d2, + 0x38b2, 0x3a92, 0xf003, 0x39a2, 0x3c62, 0x36c2, 0x3d32, 0x23d2, + 0x23d2, 0x22d2, 0x22d2, 0xf003, 0x3d22, 0x3d01, 0x2d12, 0x2d12, + 0x2b72, 0x2b72, 0x27b2, 0x27b2, 0xf003, 0x21d2, 0x21d2, 0x3c52, + 0x30d1, 0x25c2, 0x25c2, 0x2a82, 0x2a82, 0xf002, 0x28a2, 0x2c42, + 0x24c2, 0x2b62, 0xf003, 0x26b2, 0x26b2, 0x3992, 0x3c01, 0x2c32, + 0x2c32, 0x23c2, 0x23c2, 0xf003, 0x2a72, 0x2a72, 0x27a2, 0x27a2, + 0x26a2, 0x26a2, 0x30c1, 0x3b01, 0xf002, 0x12c2, 0x12c2, 0x2c22, + 0x2b52, 0xf002, 0x25b2, 0x2c12, 0x2982, 0x2892, 0xf002, 0x21c2, + 0x2b42, 0x24b2, 0x2a62, 0xf002, 0x2b32, 0x2972, 0x13b2, 0x13b2, + 0xf002, 0x2792, 0x2882, 0x2b22, 0x2a52, 0xf002, 0x12b2, 0x12b2, + 0x25a2, 0x2b12, 0xf002, 0x11b2, 0x11b2, 0x20b1, 0x2962, 0xf002, + 0x2692, 0x2a42, 0x24a2, 0x2872, 0xf002, 0x2782, 0x2a32, 0x13a2, + 0x13a2, 0xf001, 0x1952, 0x1592, 0xf001, 0x1a22, 0x12a2, 0xf001, + 0x1a12, 0x11a2, 0xf002, 0x2a01, 0x20a1, 0x1862, 0x1862, 0xf001, + 0x1682, 0x1942, 0xf001, 0x1492, 0x1932, 0xf002, 0x1392, 0x1392, + 0x2772, 0x2901, 0xf001, 0x1852, 0x1582, 0xf001, 0x1922, 0x1762, + 0xf001, 0x1672, 0x1292, 0xf001, 0x1912, 0x1091, 0xf001, 0x1842, + 0x1482, 0xf001, 0x1752, 0x1572, 0xf001, 0x1832, 0x1382, 0xf001, + 0x1662, 0x1742, 0xf001, 0x1472, 0x1801, 0xf001, 0x1081, 0x1652, + 0xf001, 0x1562, 0x1732, 0xf001, 0x1372, 0x1642, 0xf001, 0x1701, + 0x1071, 0xf001, 0x1601, 0x1061, + + /* huffTable16[651] */ + 0xf008, 0x0101, 0x010a, 0x0113, 0x8ff2, 0x0118, 0x011d, 0x0120, + 0x82f2, 0x0131, 0x8f12, 0x81f2, 0x0134, 0x0145, 0x0156, 0x0167, + 0x0178, 0x0189, 0x019a, 0x01a3, 0x01ac, 0x01b5, 0x01be, 0x01c7, + 0x01d0, 0x01d9, 0x01de, 0x01e3, 0x01e6, 0x01eb, 0x01f0, 0x8152, + 0x01f3, 0x01f6, 0x01f9, 0x01fc, 0x8412, 0x8142, 0x01ff, 0x8322, + 0x8232, 0x7312, 0x7312, 0x7132, 0x7132, 0x8301, 0x8031, 0x7222, + 0x7222, 0x6212, 0x6212, 0x6212, 0x6212, 0x6122, 0x6122, 0x6122, + 0x6122, 0x6201, 0x6201, 0x6201, 0x6201, 0x6021, 0x6021, 0x6021, + 0x6021, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, + 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, + 0x4112, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, + 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, + 0x4101, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, 0x3011, + 0x3011, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0xf003, 0x3fe2, 0x3ef2, 0x3fd2, 0x3df2, 0x3fc2, 0x3cf2, + 0x3fb2, 0x3bf2, 0xf003, 0x2fa2, 0x2fa2, 0x3af2, 0x3f92, 0x39f2, + 0x38f2, 0x2f82, 0x2f82, 0xf002, 0x2f72, 0x27f2, 0x2f62, 0x26f2, + 0xf002, 0x2f52, 0x25f2, 0x1f42, 0x1f42, 0xf001, 0x14f2, 0x13f2, + 0xf004, 0x10f1, 0x10f1, 0x10f1, 0x10f1, 0x10f1, 0x10f1, 0x10f1, + 0x10f1, 0x2f32, 0x2f32, 0x2f32, 0x2f32, 0x00e2, 0x00f3, 0x00fc, + 0x0105, 0xf001, 0x1f22, 0x1f01, 0xf004, 0x00fa, 0x00ff, 0x0104, + 0x0109, 0x010c, 0x0111, 0x0116, 0x0119, 0x011e, 0x0123, 0x0128, + 0x43e2, 0x012d, 0x0130, 0x0133, 0x0136, 0xf004, 0x0128, 0x012b, + 0x012e, 0x4d01, 0x0131, 0x0134, 0x0137, 0x4c32, 0x013a, 0x4c12, + 0x40c1, 0x013d, 0x32e2, 0x32e2, 0x4e22, 0x4e12, 0xf004, 0x43d2, + 0x4d22, 0x42d2, 0x41d2, 0x4b32, 0x012f, 0x3d12, 0x3d12, 0x44c2, + 0x4b62, 0x43c2, 0x47a2, 0x3c22, 0x3c22, 0x42c2, 0x45b2, 0xf004, + 0x41c2, 0x4c01, 0x4b42, 0x44b2, 0x4a62, 0x46a2, 0x33b2, 0x33b2, + 0x4a52, 0x45a2, 0x3b22, 0x3b22, 0x32b2, 0x32b2, 0x3b12, 0x3b12, + 0xf004, 0x31b2, 0x31b2, 0x4b01, 0x40b1, 0x4962, 0x4692, 0x4a42, + 0x44a2, 0x4872, 0x4782, 0x33a2, 0x33a2, 0x4a32, 0x4952, 0x3a22, + 0x3a22, 0xf004, 0x4592, 0x4862, 0x31a2, 0x31a2, 0x4682, 0x4772, + 0x3492, 0x3492, 0x4942, 0x4752, 0x3762, 0x3762, 0x22a2, 0x22a2, + 0x22a2, 0x22a2, 0xf003, 0x2a12, 0x2a12, 0x3a01, 0x30a1, 0x3932, + 0x3392, 0x3852, 0x3582, 0xf003, 0x2922, 0x2922, 0x2292, 0x2292, + 0x3672, 0x3901, 0x2912, 0x2912, 0xf003, 0x2192, 0x2192, 0x3091, + 0x3842, 0x3482, 0x3572, 0x3832, 0x3382, 0xf003, 0x3662, 0x3822, + 0x2282, 0x2282, 0x3742, 0x3472, 0x2812, 0x2812, 0xf003, 0x2182, + 0x2182, 0x2081, 0x2081, 0x3801, 0x3652, 0x2732, 0x2732, 0xf003, + 0x2372, 0x2372, 0x3562, 0x3642, 0x2722, 0x2722, 0x2272, 0x2272, + 0xf003, 0x3462, 0x3552, 0x2701, 0x2701, 0x1712, 0x1712, 0x1712, + 0x1712, 0xf002, 0x1172, 0x1172, 0x2071, 0x2632, 0xf002, 0x2362, + 0x2542, 0x2452, 0x2622, 0xf001, 0x1262, 0x1612, 0xf002, 0x1162, + 0x1162, 0x2601, 0x2061, 0xf002, 0x1352, 0x1352, 0x2532, 0x2442, + 0xf001, 0x1522, 0x1252, 0xf001, 0x1512, 0x1501, 0xf001, 0x1432, + 0x1342, 0xf001, 0x1051, 0x1422, 0xf001, 0x1242, 0x1332, 0xf001, + 0x1401, 0x1041, 0xf004, 0x4ec2, 0x0086, 0x3ed2, 0x3ed2, 0x39e2, + 0x39e2, 0x4ae2, 0x49d2, 0x2ee2, 0x2ee2, 0x2ee2, 0x2ee2, 0x3de2, + 0x3de2, 0x3be2, 0x3be2, 0xf003, 0x2eb2, 0x2eb2, 0x2dc2, 0x2dc2, + 0x3cd2, 0x3bd2, 0x2ea2, 0x2ea2, 0xf003, 0x2cc2, 0x2cc2, 0x3da2, + 0x3ad2, 0x3e72, 0x3ca2, 0x2ac2, 0x2ac2, 0xf003, 0x39c2, 0x3d72, + 0x2e52, 0x2e52, 0x1db2, 0x1db2, 0x1db2, 0x1db2, 0xf002, 0x1e92, + 0x1e92, 0x2cb2, 0x2bc2, 0xf002, 0x2e82, 0x28e2, 0x2d92, 0x27e2, + 0xf002, 0x2bb2, 0x2d82, 0x28d2, 0x2e62, 0xf001, 0x16e2, 0x1c92, + 0xf002, 0x2ba2, 0x2ab2, 0x25e2, 0x27d2, 0xf002, 0x1e42, 0x1e42, + 0x24e2, 0x2c82, 0xf001, 0x18c2, 0x1e32, 0xf002, 0x1d62, 0x1d62, + 0x26d2, 0x2b92, 0xf002, 0x29b2, 0x2aa2, 0x11e2, 0x11e2, 0xf002, + 0x14d2, 0x14d2, 0x28b2, 0x29a2, 0xf002, 0x1b72, 0x1b72, 0x27b2, + 0x20d1, 0xf001, 0x1e01, 0x10e1, 0xf001, 0x1d52, 0x15d2, 0xf001, + 0x1c72, 0x17c2, 0xf001, 0x1d42, 0x1b82, 0xf001, 0x1a92, 0x1c62, + 0xf001, 0x16c2, 0x1d32, 0xf001, 0x1c52, 0x15c2, 0xf001, 0x1a82, + 0x18a2, 0xf001, 0x1992, 0x1c42, 0xf001, 0x16b2, 0x1a72, 0xf001, + 0x1b52, 0x1982, 0xf001, 0x1892, 0x1972, 0xf001, 0x1792, 0x1882, + 0xf001, 0x1ce2, 0x1dd2, + + /* huffTable24[705] */ + 0xf009, 0x8fe2, 0x8fe2, 0x8ef2, 0x8ef2, 0x8fd2, 0x8fd2, 0x8df2, + 0x8df2, 0x8fc2, 0x8fc2, 0x8cf2, 0x8cf2, 0x8fb2, 0x8fb2, 0x8bf2, + 0x8bf2, 0x7af2, 0x7af2, 0x7af2, 0x7af2, 0x8fa2, 0x8fa2, 0x8f92, + 0x8f92, 0x79f2, 0x79f2, 0x79f2, 0x79f2, 0x78f2, 0x78f2, 0x78f2, + 0x78f2, 0x8f82, 0x8f82, 0x8f72, 0x8f72, 0x77f2, 0x77f2, 0x77f2, + 0x77f2, 0x7f62, 0x7f62, 0x7f62, 0x7f62, 0x76f2, 0x76f2, 0x76f2, + 0x76f2, 0x7f52, 0x7f52, 0x7f52, 0x7f52, 0x75f2, 0x75f2, 0x75f2, + 0x75f2, 0x7f42, 0x7f42, 0x7f42, 0x7f42, 0x74f2, 0x74f2, 0x74f2, + 0x74f2, 0x7f32, 0x7f32, 0x7f32, 0x7f32, 0x73f2, 0x73f2, 0x73f2, + 0x73f2, 0x7f22, 0x7f22, 0x7f22, 0x7f22, 0x72f2, 0x72f2, 0x72f2, + 0x72f2, 0x71f2, 0x71f2, 0x71f2, 0x71f2, 0x8f12, 0x8f12, 0x80f1, + 0x80f1, 0x9f01, 0x0201, 0x0206, 0x020b, 0x0210, 0x0215, 0x021a, + 0x021f, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, + 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, + 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, + 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, 0x4ff2, + 0x4ff2, 0x0224, 0x0229, 0x0232, 0x0237, 0x023a, 0x023f, 0x0242, + 0x0245, 0x024a, 0x024d, 0x0250, 0x0253, 0x0256, 0x0259, 0x025c, + 0x025f, 0x0262, 0x0265, 0x0268, 0x026b, 0x026e, 0x0271, 0x0274, + 0x0277, 0x027a, 0x027d, 0x0280, 0x0283, 0x0288, 0x028b, 0x028e, + 0x0291, 0x0294, 0x0297, 0x029a, 0x029f, 0x94b2, 0x02a4, 0x02a7, + 0x02aa, 0x93b2, 0x9882, 0x02af, 0x92b2, 0x02b2, 0x02b5, 0x9692, + 0x94a2, 0x02b8, 0x9782, 0x9a32, 0x93a2, 0x9952, 0x9592, 0x9a22, + 0x92a2, 0x91a2, 0x9862, 0x9682, 0x9772, 0x9942, 0x9492, 0x9932, + 0x9392, 0x9852, 0x9582, 0x9922, 0x9762, 0x9672, 0x9292, 0x9912, + 0x9192, 0x9842, 0x9482, 0x9752, 0x9572, 0x9832, 0x9382, 0x9662, + 0x9822, 0x9282, 0x9812, 0x9742, 0x9472, 0x9182, 0x02bb, 0x9652, + 0x9562, 0x9712, 0x02be, 0x8372, 0x8372, 0x9732, 0x9722, 0x8272, + 0x8272, 0x8642, 0x8642, 0x8462, 0x8462, 0x8552, 0x8552, 0x8172, + 0x8172, 0x8632, 0x8632, 0x8362, 0x8362, 0x8542, 0x8542, 0x8452, + 0x8452, 0x8622, 0x8622, 0x8262, 0x8262, 0x8612, 0x8612, 0x8162, + 0x8162, 0x9601, 0x9061, 0x8532, 0x8532, 0x8352, 0x8352, 0x8442, + 0x8442, 0x8522, 0x8522, 0x8252, 0x8252, 0x8512, 0x8512, 0x9501, + 0x9051, 0x7152, 0x7152, 0x7152, 0x7152, 0x8432, 0x8432, 0x8342, + 0x8342, 0x7422, 0x7422, 0x7422, 0x7422, 0x7242, 0x7242, 0x7242, + 0x7242, 0x7332, 0x7332, 0x7332, 0x7332, 0x7412, 0x7412, 0x7412, + 0x7412, 0x7142, 0x7142, 0x7142, 0x7142, 0x8401, 0x8401, 0x8041, + 0x8041, 0x7322, 0x7322, 0x7322, 0x7322, 0x7232, 0x7232, 0x7232, + 0x7232, 0x6312, 0x6312, 0x6312, 0x6312, 0x6312, 0x6312, 0x6312, + 0x6312, 0x6132, 0x6132, 0x6132, 0x6132, 0x6132, 0x6132, 0x6132, + 0x6132, 0x7301, 0x7301, 0x7301, 0x7301, 0x7031, 0x7031, 0x7031, + 0x7031, 0x6222, 0x6222, 0x6222, 0x6222, 0x6222, 0x6222, 0x6222, + 0x6222, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, + 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, 0x5212, + 0x5212, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, + 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, 0x5122, + 0x5122, 0x6201, 0x6201, 0x6201, 0x6201, 0x6201, 0x6201, 0x6201, + 0x6201, 0x6021, 0x6021, 0x6021, 0x6021, 0x6021, 0x6021, 0x6021, + 0x6021, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, + 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, + 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, + 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, 0x4112, + 0x4112, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, + 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, + 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, + 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, 0x4101, + 0x4101, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, + 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, + 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, + 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, 0x4011, + 0x4011, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, + 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, + 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, + 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, + 0x4000, 0xf002, 0x2ee2, 0x2ed2, 0x2de2, 0x2ec2, 0xf002, 0x2ce2, + 0x2dd2, 0x2eb2, 0x2be2, 0xf002, 0x2dc2, 0x2cd2, 0x2ea2, 0x2ae2, + 0xf002, 0x2db2, 0x2bd2, 0x2cc2, 0x2e92, 0xf002, 0x29e2, 0x2da2, + 0x2ad2, 0x2cb2, 0xf002, 0x2bc2, 0x2e82, 0x28e2, 0x2d92, 0xf002, + 0x29d2, 0x2e72, 0x27e2, 0x2ca2, 0xf002, 0x2ac2, 0x2bb2, 0x2d82, + 0x28d2, 0xf003, 0x3e01, 0x30e1, 0x2d01, 0x2d01, 0x16e2, 0x16e2, + 0x16e2, 0x16e2, 0xf002, 0x2e62, 0x2c92, 0x19c2, 0x19c2, 0xf001, + 0x1e52, 0x1ab2, 0xf002, 0x15e2, 0x15e2, 0x2ba2, 0x2d72, 0xf001, + 0x17d2, 0x14e2, 0xf001, 0x1c82, 0x18c2, 0xf002, 0x2e42, 0x2e22, + 0x1e32, 0x1e32, 0xf001, 0x1d62, 0x16d2, 0xf001, 0x13e2, 0x1b92, + 0xf001, 0x19b2, 0x1aa2, 0xf001, 0x12e2, 0x1e12, 0xf001, 0x11e2, + 0x1d52, 0xf001, 0x15d2, 0x1c72, 0xf001, 0x17c2, 0x1d42, 0xf001, + 0x1b82, 0x18b2, 0xf001, 0x14d2, 0x1a92, 0xf001, 0x19a2, 0x1c62, + 0xf001, 0x16c2, 0x1d32, 0xf001, 0x13d2, 0x1d22, 0xf001, 0x12d2, + 0x1d12, 0xf001, 0x1b72, 0x17b2, 0xf001, 0x11d2, 0x1c52, 0xf001, + 0x15c2, 0x1a82, 0xf001, 0x18a2, 0x1992, 0xf001, 0x1c42, 0x14c2, + 0xf001, 0x1b62, 0x16b2, 0xf002, 0x20d1, 0x2c01, 0x1c32, 0x1c32, + 0xf001, 0x13c2, 0x1a72, 0xf001, 0x17a2, 0x1c22, 0xf001, 0x12c2, + 0x1b52, 0xf001, 0x15b2, 0x1c12, 0xf001, 0x1982, 0x1892, 0xf001, + 0x11c2, 0x1b42, 0xf002, 0x20c1, 0x2b01, 0x1b32, 0x1b32, 0xf002, + 0x20b1, 0x2a01, 0x1a12, 0x1a12, 0xf001, 0x1a62, 0x16a2, 0xf001, + 0x1972, 0x1792, 0xf002, 0x20a1, 0x2901, 0x1091, 0x1091, 0xf001, + 0x1b22, 0x1a52, 0xf001, 0x15a2, 0x1b12, 0xf001, 0x11b2, 0x1962, + 0xf001, 0x1a42, 0x1872, 0xf001, 0x1801, 0x1081, 0xf001, 0x1701, + 0x1071, }; #define HUFF_OFFSET_01 0 @@ -663,93 +663,93 @@ const unsigned short huffTable[] PROGMEM = { #define HUFF_OFFSET_24 (651 + HUFF_OFFSET_16) const int huffTabOffset[HUFF_PAIRTABS] PROGMEM = { - 0, - HUFF_OFFSET_01, - HUFF_OFFSET_02, - HUFF_OFFSET_03, - 0, - HUFF_OFFSET_05, - HUFF_OFFSET_06, - HUFF_OFFSET_07, - HUFF_OFFSET_08, - HUFF_OFFSET_09, - HUFF_OFFSET_10, - HUFF_OFFSET_11, - HUFF_OFFSET_12, - HUFF_OFFSET_13, - 0, - HUFF_OFFSET_15, - HUFF_OFFSET_16, - HUFF_OFFSET_16, - HUFF_OFFSET_16, - HUFF_OFFSET_16, - HUFF_OFFSET_16, - HUFF_OFFSET_16, - HUFF_OFFSET_16, - HUFF_OFFSET_16, - HUFF_OFFSET_24, - HUFF_OFFSET_24, - HUFF_OFFSET_24, - HUFF_OFFSET_24, - HUFF_OFFSET_24, - HUFF_OFFSET_24, - HUFF_OFFSET_24, - HUFF_OFFSET_24, + 0, + HUFF_OFFSET_01, + HUFF_OFFSET_02, + HUFF_OFFSET_03, + 0, + HUFF_OFFSET_05, + HUFF_OFFSET_06, + HUFF_OFFSET_07, + HUFF_OFFSET_08, + HUFF_OFFSET_09, + HUFF_OFFSET_10, + HUFF_OFFSET_11, + HUFF_OFFSET_12, + HUFF_OFFSET_13, + 0, + HUFF_OFFSET_15, + HUFF_OFFSET_16, + HUFF_OFFSET_16, + HUFF_OFFSET_16, + HUFF_OFFSET_16, + HUFF_OFFSET_16, + HUFF_OFFSET_16, + HUFF_OFFSET_16, + HUFF_OFFSET_16, + HUFF_OFFSET_24, + HUFF_OFFSET_24, + HUFF_OFFSET_24, + HUFF_OFFSET_24, + HUFF_OFFSET_24, + HUFF_OFFSET_24, + HUFF_OFFSET_24, + HUFF_OFFSET_24, }; const HuffTabLookup huffTabLookup[HUFF_PAIRTABS] PROGMEM = { - { 0, noBits }, - { 0, oneShot }, - { 0, oneShot }, - { 0, oneShot }, - { 0, invalidTab }, - { 0, oneShot }, - { 0, oneShot }, - { 0, loopNoLinbits }, - { 0, loopNoLinbits }, - { 0, loopNoLinbits }, - { 0, loopNoLinbits }, - { 0, loopNoLinbits }, - { 0, loopNoLinbits }, - { 0, loopNoLinbits }, - { 0, invalidTab }, - { 0, loopNoLinbits }, - { 1, loopLinbits }, - { 2, loopLinbits }, - { 3, loopLinbits }, - { 4, loopLinbits }, - { 6, loopLinbits }, - { 8, loopLinbits }, - { 10, loopLinbits }, - { 13, loopLinbits }, - { 4, loopLinbits }, - { 5, loopLinbits }, - { 6, loopLinbits }, - { 7, loopLinbits }, - { 8, loopLinbits }, - { 9, loopLinbits }, - { 11, loopLinbits }, - { 13, loopLinbits }, + { 0, noBits }, + { 0, oneShot }, + { 0, oneShot }, + { 0, oneShot }, + { 0, invalidTab }, + { 0, oneShot }, + { 0, oneShot }, + { 0, loopNoLinbits }, + { 0, loopNoLinbits }, + { 0, loopNoLinbits }, + { 0, loopNoLinbits }, + { 0, loopNoLinbits }, + { 0, loopNoLinbits }, + { 0, loopNoLinbits }, + { 0, invalidTab }, + { 0, loopNoLinbits }, + { 1, loopLinbits }, + { 2, loopLinbits }, + { 3, loopLinbits }, + { 4, loopLinbits }, + { 6, loopLinbits }, + { 8, loopLinbits }, + { 10, loopLinbits }, + { 13, loopLinbits }, + { 4, loopLinbits }, + { 5, loopLinbits }, + { 6, loopLinbits }, + { 7, loopLinbits }, + { 8, loopLinbits }, + { 9, loopLinbits }, + { 11, loopLinbits }, + { 13, loopLinbits }, }; -/* tables for quadruples - * format 0xAB - * A = length of codeword - * B = codeword - */ -const unsigned char quadTable[64+16] PROGMEM = { - /* table A */ - 0x6b, 0x6f, 0x6d, 0x6e, 0x67, 0x65, 0x59, 0x59, - 0x56, 0x56, 0x53, 0x53, 0x5a, 0x5a, 0x5c, 0x5c, - 0x42, 0x42, 0x42, 0x42, 0x41, 0x41, 0x41, 0x41, - 0x44, 0x44, 0x44, 0x44, 0x48, 0x48, 0x48, 0x48, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - /* table B */ - 0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, - 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, +/* tables for quadruples + format 0xAB + A = length of codeword + B = codeword +*/ +const unsigned char quadTable[64 + 16] PROGMEM = { + /* table A */ + 0x6b, 0x6f, 0x6d, 0x6e, 0x67, 0x65, 0x59, 0x59, + 0x56, 0x56, 0x53, 0x53, 0x5a, 0x5a, 0x5c, 0x5c, + 0x42, 0x42, 0x42, 0x42, 0x41, 0x41, 0x41, 0x41, + 0x44, 0x44, 0x44, 0x44, 0x48, 0x48, 0x48, 0x48, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + /* table B */ + 0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, + 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, }; const int quadTabOffset[2] PROGMEM = {0, 64}; diff --git a/src/libhelix-mp3/imdct.c b/src/libhelix-mp3/imdct.c index e24c50ae..3761ab59 100644 --- a/src/libhelix-mp3/imdct.c +++ b/src/libhelix-mp3/imdct.c @@ -1,45 +1,45 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * imdct.c - antialias, inverse transform (short/long/mixed), windowing, - * overlap-add, frequency inversion + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + imdct.c - antialias, inverse transform (short/long/mixed), windowing, + overlap-add, frequency inversion **************************************************************************************/ #include "coder.h" @@ -47,204 +47,201 @@ #include /************************************************************************************** - * Function: AntiAlias - * - * Description: smooth transition across DCT block boundaries (every 18 coefficients) - * - * Inputs: vector of dequantized coefficients, length = (nBfly+1) * 18 - * number of "butterflies" to perform (one butterfly means one - * inter-block smoothing operation) - * - * Outputs: updated coefficient vector x - * - * Return: none - * - * Notes: weighted average of opposite bands (pairwise) from the 8 samples - * before and after each block boundary - * nBlocks = (nonZeroBound + 7) / 18, since nZB is the first ZERO sample - * above which all other samples are also zero - * max gain per sample = 1.372 - * MAX(i) (abs(csa[i][0]) + abs(csa[i][1])) - * bits gained = 0 - * assume at least 1 guard bit in x[] to avoid overflow - * (should be guaranteed from dequant, and max gain from stproc * max - * gain from AntiAlias < 2.0) + Function: AntiAlias + + Description: smooth transition across DCT block boundaries (every 18 coefficients) + + Inputs: vector of dequantized coefficients, length = (nBfly+1) * 18 + number of "butterflies" to perform (one butterfly means one + inter-block smoothing operation) + + Outputs: updated coefficient vector x + + Return: none + + Notes: weighted average of opposite bands (pairwise) from the 8 samples + before and after each block boundary + nBlocks = (nonZeroBound + 7) / 18, since nZB is the first ZERO sample + above which all other samples are also zero + max gain per sample = 1.372 + MAX(i) (abs(csa[i][0]) + abs(csa[i][1])) + bits gained = 0 + assume at least 1 guard bit in x[] to avoid overflow + (should be guaranteed from dequant, and max gain from stproc * max + gain from AntiAlias < 2.0) **************************************************************************************/ // a little bit faster in RAM (< 1 ms per block) -/* __attribute__ ((section (".data"))) */ static void AntiAlias(int *x, int nBfly) -{ - int k, a0, b0, c0, c1; - const int *c; - - /* csa = Q31 */ - for (k = nBfly; k > 0; k--) { - c = csa[0]; - x += 18; - - a0 = x[-1]; c0 = *c; c++; b0 = x[0]; c1 = *c; c++; - x[-1] = (MULSHIFT32(c0, a0) - MULSHIFT32(c1, b0)) << 1; - x[0] = (MULSHIFT32(c0, b0) + MULSHIFT32(c1, a0)) << 1; - - a0 = x[-2]; c0 = *c; c++; b0 = x[1]; c1 = *c; c++; - x[-2] = (MULSHIFT32(c0, a0) - MULSHIFT32(c1, b0)) << 1; - x[1] = (MULSHIFT32(c0, b0) + MULSHIFT32(c1, a0)) << 1; - - a0 = x[-3]; c0 = *c; c++; b0 = x[2]; c1 = *c; c++; - x[-3] = (MULSHIFT32(c0, a0) - MULSHIFT32(c1, b0)) << 1; - x[2] = (MULSHIFT32(c0, b0) + MULSHIFT32(c1, a0)) << 1; - - a0 = x[-4]; c0 = *c; c++; b0 = x[3]; c1 = *c; c++; - x[-4] = (MULSHIFT32(c0, a0) - MULSHIFT32(c1, b0)) << 1; - x[3] = (MULSHIFT32(c0, b0) + MULSHIFT32(c1, a0)) << 1; - - a0 = x[-5]; c0 = *c; c++; b0 = x[4]; c1 = *c; c++; - x[-5] = (MULSHIFT32(c0, a0) - MULSHIFT32(c1, b0)) << 1; - x[4] = (MULSHIFT32(c0, b0) + MULSHIFT32(c1, a0)) << 1; - - a0 = x[-6]; c0 = *c; c++; b0 = x[5]; c1 = *c; c++; - x[-6] = (MULSHIFT32(c0, a0) - MULSHIFT32(c1, b0)) << 1; - x[5] = (MULSHIFT32(c0, b0) + MULSHIFT32(c1, a0)) << 1; - - a0 = x[-7]; c0 = *c; c++; b0 = x[6]; c1 = *c; c++; - x[-7] = (MULSHIFT32(c0, a0) - MULSHIFT32(c1, b0)) << 1; - x[6] = (MULSHIFT32(c0, b0) + MULSHIFT32(c1, a0)) << 1; - - a0 = x[-8]; c0 = *c; c++; b0 = x[7]; c1 = *c; c++; - x[-8] = (MULSHIFT32(c0, a0) - MULSHIFT32(c1, b0)) << 1; - x[7] = (MULSHIFT32(c0, b0) + MULSHIFT32(c1, a0)) << 1; - } +/* __attribute__ ((section (".data"))) */ static void AntiAlias(int *x, int nBfly) { + int k, a0, b0, c0, c1; + const int *c; + + /* csa = Q31 */ + for (k = nBfly; k > 0; k--) { + c = csa[0]; + x += 18; + + a0 = x[-1]; c0 = *c; c++; b0 = x[0]; c1 = *c; c++; + x[-1] = (MULSHIFT32(c0, a0) - MULSHIFT32(c1, b0)) << 1; + x[0] = (MULSHIFT32(c0, b0) + MULSHIFT32(c1, a0)) << 1; + + a0 = x[-2]; c0 = *c; c++; b0 = x[1]; c1 = *c; c++; + x[-2] = (MULSHIFT32(c0, a0) - MULSHIFT32(c1, b0)) << 1; + x[1] = (MULSHIFT32(c0, b0) + MULSHIFT32(c1, a0)) << 1; + + a0 = x[-3]; c0 = *c; c++; b0 = x[2]; c1 = *c; c++; + x[-3] = (MULSHIFT32(c0, a0) - MULSHIFT32(c1, b0)) << 1; + x[2] = (MULSHIFT32(c0, b0) + MULSHIFT32(c1, a0)) << 1; + + a0 = x[-4]; c0 = *c; c++; b0 = x[3]; c1 = *c; c++; + x[-4] = (MULSHIFT32(c0, a0) - MULSHIFT32(c1, b0)) << 1; + x[3] = (MULSHIFT32(c0, b0) + MULSHIFT32(c1, a0)) << 1; + + a0 = x[-5]; c0 = *c; c++; b0 = x[4]; c1 = *c; c++; + x[-5] = (MULSHIFT32(c0, a0) - MULSHIFT32(c1, b0)) << 1; + x[4] = (MULSHIFT32(c0, b0) + MULSHIFT32(c1, a0)) << 1; + + a0 = x[-6]; c0 = *c; c++; b0 = x[5]; c1 = *c; c++; + x[-6] = (MULSHIFT32(c0, a0) - MULSHIFT32(c1, b0)) << 1; + x[5] = (MULSHIFT32(c0, b0) + MULSHIFT32(c1, a0)) << 1; + + a0 = x[-7]; c0 = *c; c++; b0 = x[6]; c1 = *c; c++; + x[-7] = (MULSHIFT32(c0, a0) - MULSHIFT32(c1, b0)) << 1; + x[6] = (MULSHIFT32(c0, b0) + MULSHIFT32(c1, a0)) << 1; + + a0 = x[-8]; c0 = *c; c++; b0 = x[7]; c1 = *c; c++; + x[-8] = (MULSHIFT32(c0, a0) - MULSHIFT32(c1, b0)) << 1; + x[7] = (MULSHIFT32(c0, b0) + MULSHIFT32(c1, a0)) << 1; + } } /************************************************************************************** - * Function: WinPrevious - * - * Description: apply specified window to second half of previous IMDCT (overlap part) - * - * Inputs: vector of 9 coefficients (xPrev) - * - * Outputs: 18 windowed output coefficients (gain 1 integer bit) - * window type (0, 1, 2, 3) - * - * Return: none - * - * Notes: produces 9 output samples from 18 input samples via symmetry - * all blocks gain at least 1 guard bit via window (long blocks get extra - * sign bit, short blocks can have one addition but max gain < 1.0) + Function: WinPrevious + + Description: apply specified window to second half of previous IMDCT (overlap part) + + Inputs: vector of 9 coefficients (xPrev) + + Outputs: 18 windowed output coefficients (gain 1 integer bit) + window type (0, 1, 2, 3) + + Return: none + + Notes: produces 9 output samples from 18 input samples via symmetry + all blocks gain at least 1 guard bit via window (long blocks get extra + sign bit, short blocks can have one addition but max gain < 1.0) **************************************************************************************/ -/*__attribute__ ((section (".data"))) */ static void WinPrevious(int *xPrev, int *xPrevWin, int btPrev) -{ - int i, x, *xp, *xpwLo, *xpwHi, wLo, wHi; - const int *wpLo, *wpHi; - - xp = xPrev; - /* mapping (see IMDCT12x3): xPrev[0-2] = sum[6-8], xPrev[3-8] = sum[12-17] */ - if (btPrev == 2) { - /* this could be reordered for minimum loads/stores */ - wpLo = imdctWin[btPrev]; - xPrevWin[ 0] = MULSHIFT32(wpLo[ 6], xPrev[2]) + MULSHIFT32(wpLo[0], xPrev[6]); - xPrevWin[ 1] = MULSHIFT32(wpLo[ 7], xPrev[1]) + MULSHIFT32(wpLo[1], xPrev[7]); - xPrevWin[ 2] = MULSHIFT32(wpLo[ 8], xPrev[0]) + MULSHIFT32(wpLo[2], xPrev[8]); - xPrevWin[ 3] = MULSHIFT32(wpLo[ 9], xPrev[0]) + MULSHIFT32(wpLo[3], xPrev[8]); - xPrevWin[ 4] = MULSHIFT32(wpLo[10], xPrev[1]) + MULSHIFT32(wpLo[4], xPrev[7]); - xPrevWin[ 5] = MULSHIFT32(wpLo[11], xPrev[2]) + MULSHIFT32(wpLo[5], xPrev[6]); - xPrevWin[ 6] = MULSHIFT32(wpLo[ 6], xPrev[5]); - xPrevWin[ 7] = MULSHIFT32(wpLo[ 7], xPrev[4]); - xPrevWin[ 8] = MULSHIFT32(wpLo[ 8], xPrev[3]); - xPrevWin[ 9] = MULSHIFT32(wpLo[ 9], xPrev[3]); - xPrevWin[10] = MULSHIFT32(wpLo[10], xPrev[4]); - xPrevWin[11] = MULSHIFT32(wpLo[11], xPrev[5]); - xPrevWin[12] = xPrevWin[13] = xPrevWin[14] = xPrevWin[15] = xPrevWin[16] = xPrevWin[17] = 0; - } else { - /* use ARM-style pointers (*ptr++) so that ADS compiles well */ - wpLo = imdctWin[btPrev] + 18; - wpHi = wpLo + 17; - xpwLo = xPrevWin; - xpwHi = xPrevWin + 17; - for (i = 9; i > 0; i--) { - x = *xp++; wLo = *wpLo++; wHi = *wpHi--; - *xpwLo++ = MULSHIFT32(wLo, x); - *xpwHi-- = MULSHIFT32(wHi, x); - } - } +/*__attribute__ ((section (".data"))) */ static void WinPrevious(int *xPrev, int *xPrevWin, int btPrev) { + int i, x, *xp, *xpwLo, *xpwHi, wLo, wHi; + const int *wpLo, *wpHi; + + xp = xPrev; + /* mapping (see IMDCT12x3): xPrev[0-2] = sum[6-8], xPrev[3-8] = sum[12-17] */ + if (btPrev == 2) { + /* this could be reordered for minimum loads/stores */ + wpLo = imdctWin[btPrev]; + xPrevWin[ 0] = MULSHIFT32(wpLo[ 6], xPrev[2]) + MULSHIFT32(wpLo[0], xPrev[6]); + xPrevWin[ 1] = MULSHIFT32(wpLo[ 7], xPrev[1]) + MULSHIFT32(wpLo[1], xPrev[7]); + xPrevWin[ 2] = MULSHIFT32(wpLo[ 8], xPrev[0]) + MULSHIFT32(wpLo[2], xPrev[8]); + xPrevWin[ 3] = MULSHIFT32(wpLo[ 9], xPrev[0]) + MULSHIFT32(wpLo[3], xPrev[8]); + xPrevWin[ 4] = MULSHIFT32(wpLo[10], xPrev[1]) + MULSHIFT32(wpLo[4], xPrev[7]); + xPrevWin[ 5] = MULSHIFT32(wpLo[11], xPrev[2]) + MULSHIFT32(wpLo[5], xPrev[6]); + xPrevWin[ 6] = MULSHIFT32(wpLo[ 6], xPrev[5]); + xPrevWin[ 7] = MULSHIFT32(wpLo[ 7], xPrev[4]); + xPrevWin[ 8] = MULSHIFT32(wpLo[ 8], xPrev[3]); + xPrevWin[ 9] = MULSHIFT32(wpLo[ 9], xPrev[3]); + xPrevWin[10] = MULSHIFT32(wpLo[10], xPrev[4]); + xPrevWin[11] = MULSHIFT32(wpLo[11], xPrev[5]); + xPrevWin[12] = xPrevWin[13] = xPrevWin[14] = xPrevWin[15] = xPrevWin[16] = xPrevWin[17] = 0; + } else { + /* use ARM-style pointers (*ptr++) so that ADS compiles well */ + wpLo = imdctWin[btPrev] + 18; + wpHi = wpLo + 17; + xpwLo = xPrevWin; + xpwHi = xPrevWin + 17; + for (i = 9; i > 0; i--) { + x = *xp++; wLo = *wpLo++; wHi = *wpHi--; + *xpwLo++ = MULSHIFT32(wLo, x); + *xpwHi-- = MULSHIFT32(wHi, x); + } + } } /************************************************************************************** - * Function: FreqInvertRescale - * - * Description: do frequency inversion (odd samples of odd blocks) and rescale - * if necessary (extra guard bits added before IMDCT) - * - * Inputs: output vector y (18 new samples, spaced NBANDS apart) - * previous sample vector xPrev (9 samples) - * index of current block - * number of extra shifts added before IMDCT (usually 0) - * - * Outputs: inverted and rescaled (as necessary) outputs - * rescaled (as necessary) previous samples - * - * Return: updated mOut (from new outputs y) + Function: FreqInvertRescale + + Description: do frequency inversion (odd samples of odd blocks) and rescale + if necessary (extra guard bits added before IMDCT) + + Inputs: output vector y (18 new samples, spaced NBANDS apart) + previous sample vector xPrev (9 samples) + index of current block + number of extra shifts added before IMDCT (usually 0) + + Outputs: inverted and rescaled (as necessary) outputs + rescaled (as necessary) previous samples + + Return: updated mOut (from new outputs y) **************************************************************************************/ -/*__attribute__ ((section (".data")))*/ static int FreqInvertRescale(int *y, int *xPrev, int blockIdx, int es) -{ - int i, d, mOut; - int y0, y1, y2, y3, y4, y5, y6, y7, y8; - - if (es == 0) { - /* fast case - frequency invert only (no rescaling) - can fuse into overlap-add for speed, if desired */ - if (blockIdx & 0x01) { - y += NBANDS; - y0 = *y; y += 2*NBANDS; - y1 = *y; y += 2*NBANDS; - y2 = *y; y += 2*NBANDS; - y3 = *y; y += 2*NBANDS; - y4 = *y; y += 2*NBANDS; - y5 = *y; y += 2*NBANDS; - y6 = *y; y += 2*NBANDS; - y7 = *y; y += 2*NBANDS; - y8 = *y; y += 2*NBANDS; - - y -= 18*NBANDS; - *y = -y0; y += 2*NBANDS; - *y = -y1; y += 2*NBANDS; - *y = -y2; y += 2*NBANDS; - *y = -y3; y += 2*NBANDS; - *y = -y4; y += 2*NBANDS; - *y = -y5; y += 2*NBANDS; - *y = -y6; y += 2*NBANDS; - *y = -y7; y += 2*NBANDS; - *y = -y8; y += 2*NBANDS; - } - return 0; - } else { - /* undo pre-IMDCT scaling, clipping if necessary */ - mOut = 0; - if (blockIdx & 0x01) { - /* frequency invert */ - for (i = 0; i < 18; i+=2) { - d = *y; CLIP_2N(d, 31 - es); *y = d << es; mOut |= FASTABS(*y); y += NBANDS; - d = -*y; CLIP_2N(d, 31 - es); *y = d << es; mOut |= FASTABS(*y); y += NBANDS; - d = *xPrev; CLIP_2N(d, 31 - es); *xPrev++ = d << es; - } - } else { - for (i = 0; i < 18; i+=2) { - d = *y; CLIP_2N(d, 31 - es); *y = d << es; mOut |= FASTABS(*y); y += NBANDS; - d = *y; CLIP_2N(d, 31 - es); *y = d << es; mOut |= FASTABS(*y); y += NBANDS; - d = *xPrev; CLIP_2N(d, 31 - es); *xPrev++ = d << es; - } - } - return mOut; - } +/*__attribute__ ((section (".data")))*/ static int FreqInvertRescale(int *y, int *xPrev, int blockIdx, int es) { + int i, d, mOut; + int y0, y1, y2, y3, y4, y5, y6, y7, y8; + + if (es == 0) { + /* fast case - frequency invert only (no rescaling) - can fuse into overlap-add for speed, if desired */ + if (blockIdx & 0x01) { + y += NBANDS; + y0 = *y; y += 2 * NBANDS; + y1 = *y; y += 2 * NBANDS; + y2 = *y; y += 2 * NBANDS; + y3 = *y; y += 2 * NBANDS; + y4 = *y; y += 2 * NBANDS; + y5 = *y; y += 2 * NBANDS; + y6 = *y; y += 2 * NBANDS; + y7 = *y; y += 2 * NBANDS; + y8 = *y; y += 2 * NBANDS; + + y -= 18 * NBANDS; + *y = -y0; y += 2 * NBANDS; + *y = -y1; y += 2 * NBANDS; + *y = -y2; y += 2 * NBANDS; + *y = -y3; y += 2 * NBANDS; + *y = -y4; y += 2 * NBANDS; + *y = -y5; y += 2 * NBANDS; + *y = -y6; y += 2 * NBANDS; + *y = -y7; y += 2 * NBANDS; + *y = -y8; y += 2 * NBANDS; + } + return 0; + } else { + /* undo pre-IMDCT scaling, clipping if necessary */ + mOut = 0; + if (blockIdx & 0x01) { + /* frequency invert */ + for (i = 0; i < 18; i += 2) { + d = *y; CLIP_2N(d, 31 - es); *y = d << es; mOut |= FASTABS(*y); y += NBANDS; + d = -*y; CLIP_2N(d, 31 - es); *y = d << es; mOut |= FASTABS(*y); y += NBANDS; + d = *xPrev; CLIP_2N(d, 31 - es); *xPrev++ = d << es; + } + } else { + for (i = 0; i < 18; i += 2) { + d = *y; CLIP_2N(d, 31 - es); *y = d << es; mOut |= FASTABS(*y); y += NBANDS; + d = *y; CLIP_2N(d, 31 - es); *y = d << es; mOut |= FASTABS(*y); y += NBANDS; + d = *xPrev; CLIP_2N(d, 31 - es); *xPrev++ = d << es; + } + } + return mOut; + } } -/* format = Q31 - * #define M_PI 3.14159265358979323846 - * double u = 2.0 * M_PI / 9.0; - * float c0 = sqrt(3.0) / 2.0; - * float c1 = cos(u); - * float c2 = cos(2*u); - * float c3 = sin(u); - * float c4 = sin(2*u); - */ +/* format = Q31 + #define M_PI 3.14159265358979323846 + double u = 2.0 * M_PI / 9.0; + float c0 = sqrt(3.0) / 2.0; + float c1 = cos(u); + float c2 = cos(2*u); + float c3 = sin(u); + float c4 = sin(2*u); +*/ static const int c9_0 = 0x6ed9eba1; static const int c9_1 = 0x620dbe8b; @@ -252,536 +249,539 @@ static const int c9_2 = 0x163a1a7e; static const int c9_3 = 0x5246dd49; static const int c9_4 = 0x7e0e2e32; -/* format = Q31 - * cos(((0:8) + 0.5) * (pi/18)) - */ +/* format = Q31 + cos(((0:8) + 0.5) * (pi/18)) +*/ static const int c18[9] PROGMEM = { - 0x7f834ed0, 0x7ba3751d, 0x7401e4c1, 0x68d9f964, 0x5a82799a, 0x496af3e2, 0x36185aee, 0x2120fb83, 0x0b27eb5c, + 0x7f834ed0, 0x7ba3751d, 0x7401e4c1, 0x68d9f964, 0x5a82799a, 0x496af3e2, 0x36185aee, 0x2120fb83, 0x0b27eb5c, }; /* require at least 3 guard bits in x[] to ensure no overflow */ -static __inline void idct9(int *x) -{ - int a1, a2, a3, a4, a5, a6, a7, a8, a9; - int a10, a11, a12, a13, a14, a15, a16, a17, a18; - int a19, a20, a21, a22, a23, a24, a25, a26, a27; - int m1, m3, m5, m6, m7, m8, m9, m10, m11, m12; - int x0, x1, x2, x3, x4, x5, x6, x7, x8; - - x0 = x[0]; x1 = x[1]; x2 = x[2]; x3 = x[3]; x4 = x[4]; - x5 = x[5]; x6 = x[6]; x7 = x[7]; x8 = x[8]; - - a1 = x0 - x6; - a2 = x1 - x5; - a3 = x1 + x5; - a4 = x2 - x4; - a5 = x2 + x4; - a6 = x2 + x8; - a7 = x1 + x7; - - a8 = a6 - a5; /* ie x[8] - x[4] */ - a9 = a3 - a7; /* ie x[5] - x[7] */ - a10 = a2 - x7; /* ie x[1] - x[5] - x[7] */ - a11 = a4 - x8; /* ie x[2] - x[4] - x[8] */ - - /* do the << 1 as constant shifts where mX is actually used (free, no stall or extra inst.) */ - m1 = MULSHIFT32(c9_0, x3); - m3 = MULSHIFT32(c9_0, a10); - m5 = MULSHIFT32(c9_1, a5); - m6 = MULSHIFT32(c9_2, a6); - m7 = MULSHIFT32(c9_1, a8); - m8 = MULSHIFT32(c9_2, a5); - m9 = MULSHIFT32(c9_3, a9); - m10 = MULSHIFT32(c9_4, a7); - m11 = MULSHIFT32(c9_3, a3); - m12 = MULSHIFT32(c9_4, a9); - - a12 = x[0] + (x[6] >> 1); - a13 = a12 + ( m1 << 1); - a14 = a12 - ( m1 << 1); - a15 = a1 + ( a11 >> 1); - a16 = ( m5 << 1) + (m6 << 1); - a17 = ( m7 << 1) - (m8 << 1); - a18 = a16 + a17; - a19 = ( m9 << 1) + (m10 << 1); - a20 = (m11 << 1) - (m12 << 1); - - a21 = a20 - a19; - a22 = a13 + a16; - a23 = a14 + a16; - a24 = a14 + a17; - a25 = a13 + a17; - a26 = a14 - a18; - a27 = a13 - a18; - - x0 = a22 + a19; x[0] = x0; - x1 = a15 + (m3 << 1); x[1] = x1; - x2 = a24 + a20; x[2] = x2; - x3 = a26 - a21; x[3] = x3; - x4 = a1 - a11; x[4] = x4; - x5 = a27 + a21; x[5] = x5; - x6 = a25 - a20; x[6] = x6; - x7 = a15 - (m3 << 1); x[7] = x7; - x8 = a23 - a19; x[8] = x8; +static __inline void idct9(int *x) { + int a1, a2, a3, a4, a5, a6, a7, a8, a9; + int a10, a11, a12, a13, a14, a15, a16, a17, a18; + int a19, a20, a21, a22, a23, a24, a25, a26, a27; + int m1, m3, m5, m6, m7, m8, m9, m10, m11, m12; + int x0, x1, x2, x3, x4, x5, x6, x7, x8; + + x0 = x[0]; x1 = x[1]; x2 = x[2]; x3 = x[3]; x4 = x[4]; + x5 = x[5]; x6 = x[6]; x7 = x[7]; x8 = x[8]; + + a1 = x0 - x6; + a2 = x1 - x5; + a3 = x1 + x5; + a4 = x2 - x4; + a5 = x2 + x4; + a6 = x2 + x8; + a7 = x1 + x7; + + a8 = a6 - a5; /* ie x[8] - x[4] */ + a9 = a3 - a7; /* ie x[5] - x[7] */ + a10 = a2 - x7; /* ie x[1] - x[5] - x[7] */ + a11 = a4 - x8; /* ie x[2] - x[4] - x[8] */ + + /* do the << 1 as constant shifts where mX is actually used (free, no stall or extra inst.) */ + m1 = MULSHIFT32(c9_0, x3); + m3 = MULSHIFT32(c9_0, a10); + m5 = MULSHIFT32(c9_1, a5); + m6 = MULSHIFT32(c9_2, a6); + m7 = MULSHIFT32(c9_1, a8); + m8 = MULSHIFT32(c9_2, a5); + m9 = MULSHIFT32(c9_3, a9); + m10 = MULSHIFT32(c9_4, a7); + m11 = MULSHIFT32(c9_3, a3); + m12 = MULSHIFT32(c9_4, a9); + + a12 = x[0] + (x[6] >> 1); + a13 = a12 + (m1 << 1); + a14 = a12 - (m1 << 1); + a15 = a1 + (a11 >> 1); + a16 = (m5 << 1) + (m6 << 1); + a17 = (m7 << 1) - (m8 << 1); + a18 = a16 + a17; + a19 = (m9 << 1) + (m10 << 1); + a20 = (m11 << 1) - (m12 << 1); + + a21 = a20 - a19; + a22 = a13 + a16; + a23 = a14 + a16; + a24 = a14 + a17; + a25 = a13 + a17; + a26 = a14 - a18; + a27 = a13 - a18; + + x0 = a22 + a19; x[0] = x0; + x1 = a15 + (m3 << 1); x[1] = x1; + x2 = a24 + a20; x[2] = x2; + x3 = a26 - a21; x[3] = x3; + x4 = a1 - a11; x[4] = x4; + x5 = a27 + a21; x[5] = x5; + x6 = a25 - a20; x[6] = x6; + x7 = a15 - (m3 << 1); x[7] = x7; + x8 = a23 - a19; x[8] = x8; } -/* let c(j) = cos(M_PI/36 * ((j)+0.5)), s(j) = sin(M_PI/36 * ((j)+0.5)) - * then fastWin[2*j+0] = c(j)*(s(j) + c(j)), j = [0, 8] - * fastWin[2*j+1] = c(j)*(s(j) - c(j)) - * format = Q30 - */ +/* let c(j) = cos(M_PI/36 * ((j)+0.5)), s(j) = sin(M_PI/36 * ((j)+0.5)) + then fastWin[2*j+0] = c(j)*(s(j) + c(j)), j = [0, 8] + fastWin[2*j+1] = c(j)*(s(j) - c(j)) + format = Q30 +*/ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnarrowing" const int fastWin36[18] PROGMEM = { - 0x42aace8b, 0xc2e92724, 0x47311c28, 0xc95f619a, 0x4a868feb, 0xd0859d8c, - 0x4c913b51, 0xd8243ea0, 0x4d413ccc, 0xe0000000, 0x4c913b51, 0xe7dbc161, - 0x4a868feb, 0xef7a6275, 0x47311c28, 0xf6a09e67, 0x42aace8b, 0xfd16d8dd, + 0x42aace8b, 0xc2e92724, 0x47311c28, 0xc95f619a, 0x4a868feb, 0xd0859d8c, + 0x4c913b51, 0xd8243ea0, 0x4d413ccc, 0xe0000000, 0x4c913b51, 0xe7dbc161, + 0x4a868feb, 0xef7a6275, 0x47311c28, 0xf6a09e67, 0x42aace8b, 0xfd16d8dd, }; #pragma GCC diagnostic pop /************************************************************************************** - * Function: IMDCT36 - * - * Description: 36-point modified DCT, with windowing and overlap-add (50% overlap) - * - * Inputs: vector of 18 coefficients (N/2 inputs produces N outputs, by symmetry) - * overlap part of last IMDCT (9 samples - see output comments) - * window type (0,1,2,3) of current and previous block - * current block index (for deciding whether to do frequency inversion) - * number of guard bits in input vector - * - * Outputs: 18 output samples, after windowing and overlap-add with last frame - * second half of (unwindowed) 36-point IMDCT - save for next time - * only save 9 xPrev samples, using symmetry (see WinPrevious()) - * - * Notes: this is Ken's hyper-fast algorithm, including symmetric sin window - * optimization, if applicable - * total number of multiplies, general case: - * 2*10 (idct9) + 9 (last stage imdct) + 36 (for windowing) = 65 - * total number of multiplies, btCurr == 0 && btPrev == 0: - * 2*10 (idct9) + 9 (last stage imdct) + 18 (for windowing) = 47 - * - * blockType == 0 is by far the most common case, so it should be - * possible to use the fast path most of the time - * this is the fastest known algorithm for performing - * long IMDCT + windowing + overlap-add in MP3 - * - * Return: mOut (OR of abs(y) for all y calculated here) - * - * TODO: optimize for ARM (reorder window coefs, ARM-style pointers in C, - * inline asm may or may not be helpful) + Function: IMDCT36 + + Description: 36-point modified DCT, with windowing and overlap-add (50% overlap) + + Inputs: vector of 18 coefficients (N/2 inputs produces N outputs, by symmetry) + overlap part of last IMDCT (9 samples - see output comments) + window type (0,1,2,3) of current and previous block + current block index (for deciding whether to do frequency inversion) + number of guard bits in input vector + + Outputs: 18 output samples, after windowing and overlap-add with last frame + second half of (unwindowed) 36-point IMDCT - save for next time + only save 9 xPrev samples, using symmetry (see WinPrevious()) + + Notes: this is Ken's hyper-fast algorithm, including symmetric sin window + optimization, if applicable + total number of multiplies, general case: + 2*10 (idct9) + 9 (last stage imdct) + 36 (for windowing) = 65 + total number of multiplies, btCurr == 0 && btPrev == 0: + 2*10 (idct9) + 9 (last stage imdct) + 18 (for windowing) = 47 + + blockType == 0 is by far the most common case, so it should be + possible to use the fast path most of the time + this is the fastest known algorithm for performing + long IMDCT + windowing + overlap-add in MP3 + + Return: mOut (OR of abs(y) for all y calculated here) + + TODO: optimize for ARM (reorder window coefs, ARM-style pointers in C, + inline asm may or may not be helpful) **************************************************************************************/ // barely faster in RAM -/*__attribute__ ((section (".data")))*/ static int IMDCT36(int *xCurr, int *xPrev, int *y, int btCurr, int btPrev, int blockIdx, int gb) -{ - int i, es, xBuf[18], xPrevWin[18]; - int acc1, acc2, s, d, t, mOut; - int xo, xe, c, *xp, yLo, yHi; - const int *cp, *wp; - - acc1 = acc2 = 0; - xCurr += 17; - - /* 7 gb is always adequate for antialias + accumulator loop + idct9 */ - if (gb < 7) { - /* rarely triggered - 5% to 10% of the time on normal clips (with Q25 input) */ - es = 7 - gb; - for (i = 8; i >= 0; i--) { - acc1 = ((*xCurr--) >> es) - acc1; - acc2 = acc1 - acc2; - acc1 = ((*xCurr--) >> es) - acc1; - xBuf[i+9] = acc2; /* odd */ - xBuf[i+0] = acc1; /* even */ - xPrev[i] >>= es; - } - } else { - es = 0; - /* max gain = 18, assume adequate guard bits */ - for (i = 8; i >= 0; i--) { - acc1 = (*xCurr--) - acc1; - acc2 = acc1 - acc2; - acc1 = (*xCurr--) - acc1; - xBuf[i+9] = acc2; /* odd */ - xBuf[i+0] = acc1; /* even */ - } - } - /* xEven[0] and xOdd[0] scaled by 0.5 */ - xBuf[9] >>= 1; - xBuf[0] >>= 1; - - /* do 9-point IDCT on even and odd */ - idct9(xBuf+0); /* even */ - idct9(xBuf+9); /* odd */ - - xp = xBuf + 8; - cp = c18 + 8; - mOut = 0; - if (btPrev == 0 && btCurr == 0) { - /* fast path - use symmetry of sin window to reduce windowing multiplies to 18 (N/2) */ - wp = fastWin36; - for (i = 0; i < 9; i++) { - /* do ARM-style pointer arithmetic (i still needed for y[] indexing - compiler spills if 2 y pointers) */ - c = *cp--; xo = *(xp + 9); xe = *xp--; - /* gain 2 int bits here */ - xo = MULSHIFT32(c, xo); /* 2*c18*xOdd (mul by 2 implicit in scaling) */ - xe >>= 2; - - s = -(*xPrev); /* sum from last block (always at least 2 guard bits) */ - d = -(xe - xo); /* gain 2 int bits, don't shift xo (effective << 1 to eat sign bit, << 1 for mul by 2) */ - (*xPrev++) = xe + xo; /* symmetry - xPrev[i] = xPrev[17-i] for long blocks */ - t = s - d; - - yLo = (d + (MULSHIFT32(t, *wp++) << 2)); - yHi = (s + (MULSHIFT32(t, *wp++) << 2)); - y[(i)*NBANDS] = yLo; - y[(17-i)*NBANDS] = yHi; - mOut |= FASTABS(yLo); - mOut |= FASTABS(yHi); - } - } else { - /* slower method - either prev or curr is using window type != 0 so do full 36-point window - * output xPrevWin has at least 3 guard bits (xPrev has 2, gain 1 in WinPrevious) - */ - WinPrevious(xPrev, xPrevWin, btPrev); - - wp = imdctWin[btCurr]; - for (i = 0; i < 9; i++) { - c = *cp--; xo = *(xp + 9); xe = *xp--; - /* gain 2 int bits here */ - xo = MULSHIFT32(c, xo); /* 2*c18*xOdd (mul by 2 implicit in scaling) */ - xe >>= 2; - - d = xe - xo; - (*xPrev++) = xe + xo; /* symmetry - xPrev[i] = xPrev[17-i] for long blocks */ - - yLo = (xPrevWin[i] + MULSHIFT32(d, wp[i])) << 2; - yHi = (xPrevWin[17-i] + MULSHIFT32(d, wp[17-i])) << 2; - y[(i)*NBANDS] = yLo; - y[(17-i)*NBANDS] = yHi; - mOut |= FASTABS(yLo); - mOut |= FASTABS(yHi); - } - } - - xPrev -= 9; - mOut |= FreqInvertRescale(y, xPrev, blockIdx, es); - - return mOut; +/*__attribute__ ((section (".data")))*/ static int IMDCT36(int *xCurr, int *xPrev, int *y, int btCurr, int btPrev, int blockIdx, int gb) { + int i, es, xBuf[18], xPrevWin[18]; + int acc1, acc2, s, d, t, mOut; + int xo, xe, c, *xp, yLo, yHi; + const int *cp, *wp; + + acc1 = acc2 = 0; + xCurr += 17; + + /* 7 gb is always adequate for antialias + accumulator loop + idct9 */ + if (gb < 7) { + /* rarely triggered - 5% to 10% of the time on normal clips (with Q25 input) */ + es = 7 - gb; + for (i = 8; i >= 0; i--) { + acc1 = ((*xCurr--) >> es) - acc1; + acc2 = acc1 - acc2; + acc1 = ((*xCurr--) >> es) - acc1; + xBuf[i + 9] = acc2; /* odd */ + xBuf[i + 0] = acc1; /* even */ + xPrev[i] >>= es; + } + } else { + es = 0; + /* max gain = 18, assume adequate guard bits */ + for (i = 8; i >= 0; i--) { + acc1 = (*xCurr--) - acc1; + acc2 = acc1 - acc2; + acc1 = (*xCurr--) - acc1; + xBuf[i + 9] = acc2; /* odd */ + xBuf[i + 0] = acc1; /* even */ + } + } + /* xEven[0] and xOdd[0] scaled by 0.5 */ + xBuf[9] >>= 1; + xBuf[0] >>= 1; + + /* do 9-point IDCT on even and odd */ + idct9(xBuf + 0); /* even */ + idct9(xBuf + 9); /* odd */ + + xp = xBuf + 8; + cp = c18 + 8; + mOut = 0; + if (btPrev == 0 && btCurr == 0) { + /* fast path - use symmetry of sin window to reduce windowing multiplies to 18 (N/2) */ + wp = fastWin36; + for (i = 0; i < 9; i++) { + /* do ARM-style pointer arithmetic (i still needed for y[] indexing - compiler spills if 2 y pointers) */ + c = *cp--; xo = *(xp + 9); xe = *xp--; + /* gain 2 int bits here */ + xo = MULSHIFT32(c, xo); /* 2*c18*xOdd (mul by 2 implicit in scaling) */ + xe >>= 2; + + s = -(*xPrev); /* sum from last block (always at least 2 guard bits) */ + d = -(xe - xo); /* gain 2 int bits, don't shift xo (effective << 1 to eat sign bit, << 1 for mul by 2) */ + (*xPrev++) = xe + xo; /* symmetry - xPrev[i] = xPrev[17-i] for long blocks */ + t = s - d; + + yLo = (d + (MULSHIFT32(t, *wp++) << 2)); + yHi = (s + (MULSHIFT32(t, *wp++) << 2)); + y[(i)*NBANDS] = yLo; + y[(17 - i)*NBANDS] = yHi; + mOut |= FASTABS(yLo); + mOut |= FASTABS(yHi); + } + } else { + /* slower method - either prev or curr is using window type != 0 so do full 36-point window + output xPrevWin has at least 3 guard bits (xPrev has 2, gain 1 in WinPrevious) + */ + WinPrevious(xPrev, xPrevWin, btPrev); + + wp = imdctWin[btCurr]; + for (i = 0; i < 9; i++) { + c = *cp--; xo = *(xp + 9); xe = *xp--; + /* gain 2 int bits here */ + xo = MULSHIFT32(c, xo); /* 2*c18*xOdd (mul by 2 implicit in scaling) */ + xe >>= 2; + + d = xe - xo; + (*xPrev++) = xe + xo; /* symmetry - xPrev[i] = xPrev[17-i] for long blocks */ + + yLo = (xPrevWin[i] + MULSHIFT32(d, wp[i])) << 2; + yHi = (xPrevWin[17 - i] + MULSHIFT32(d, wp[17 - i])) << 2; + y[(i)*NBANDS] = yLo; + y[(17 - i)*NBANDS] = yHi; + mOut |= FASTABS(yLo); + mOut |= FASTABS(yHi); + } + } + + xPrev -= 9; + mOut |= FreqInvertRescale(y, xPrev, blockIdx, es); + + return mOut; } static int c3_0 = 0x6ed9eba1; /* format = Q31, cos(pi/6) */ static int c6[3] = { 0x7ba3751d, 0x5a82799a, 0x2120fb83 }; /* format = Q31, cos(((0:2) + 0.5) * (pi/6)) */ -/* 12-point inverse DCT, used in IMDCT12x3() - * 4 input guard bits will ensure no overflow - */ -static __inline void imdct12 (int *x, int *out) -{ - int a0, a1, a2; - int x0, x1, x2, x3, x4, x5; - - x0 = *x; x+=3; x1 = *x; x+=3; - x2 = *x; x+=3; x3 = *x; x+=3; - x4 = *x; x+=3; x5 = *x; x+=3; - - x4 -= x5; - x3 -= x4; - x2 -= x3; - x3 -= x5; - x1 -= x2; - x0 -= x1; - x1 -= x3; - - x0 >>= 1; - x1 >>= 1; - - a0 = MULSHIFT32(c3_0, x2) << 1; - a1 = x0 + (x4 >> 1); - a2 = x0 - x4; - x0 = a1 + a0; - x2 = a2; - x4 = a1 - a0; - - a0 = MULSHIFT32(c3_0, x3) << 1; - a1 = x1 + (x5 >> 1); - a2 = x1 - x5; - - /* cos window odd samples, mul by 2, eat sign bit */ - x1 = MULSHIFT32(c6[0], a1 + a0) << 2; - x3 = MULSHIFT32(c6[1], a2) << 2; - x5 = MULSHIFT32(c6[2], a1 - a0) << 2; - - *out = x0 + x1; out++; - *out = x2 + x3; out++; - *out = x4 + x5; out++; - *out = x4 - x5; out++; - *out = x2 - x3; out++; - *out = x0 - x1; +/* 12-point inverse DCT, used in IMDCT12x3() + 4 input guard bits will ensure no overflow +*/ +static __inline void imdct12(int *x, int *out) { + int a0, a1, a2; + int x0, x1, x2, x3, x4, x5; + + x0 = *x; x += 3; x1 = *x; x += 3; + x2 = *x; x += 3; x3 = *x; x += 3; + x4 = *x; x += 3; x5 = *x; x += 3; + + x4 -= x5; + x3 -= x4; + x2 -= x3; + x3 -= x5; + x1 -= x2; + x0 -= x1; + x1 -= x3; + + x0 >>= 1; + x1 >>= 1; + + a0 = MULSHIFT32(c3_0, x2) << 1; + a1 = x0 + (x4 >> 1); + a2 = x0 - x4; + x0 = a1 + a0; + x2 = a2; + x4 = a1 - a0; + + a0 = MULSHIFT32(c3_0, x3) << 1; + a1 = x1 + (x5 >> 1); + a2 = x1 - x5; + + /* cos window odd samples, mul by 2, eat sign bit */ + x1 = MULSHIFT32(c6[0], a1 + a0) << 2; + x3 = MULSHIFT32(c6[1], a2) << 2; + x5 = MULSHIFT32(c6[2], a1 - a0) << 2; + + *out = x0 + x1; out++; + *out = x2 + x3; out++; + *out = x4 + x5; out++; + *out = x4 - x5; out++; + *out = x2 - x3; out++; + *out = x0 - x1; } /************************************************************************************** - * Function: IMDCT12x3 - * - * Description: three 12-point modified DCT's for short blocks, with windowing, - * short block concatenation, and overlap-add - * - * Inputs: 3 interleaved vectors of 6 samples each - * (block0[0], block1[0], block2[0], block0[1], block1[1]....) - * overlap part of last IMDCT (9 samples - see output comments) - * window type (0,1,2,3) of previous block - * current block index (for deciding whether to do frequency inversion) - * number of guard bits in input vector - * - * Outputs: updated sample vector x, net gain of 1 integer bit - * second half of (unwindowed) IMDCT's - save for next time - * only save 9 xPrev samples, using symmetry (see WinPrevious()) - * - * Return: mOut (OR of abs(y) for all y calculated here) - * - * TODO: optimize for ARM + Function: IMDCT12x3 + + Description: three 12-point modified DCT's for short blocks, with windowing, + short block concatenation, and overlap-add + + Inputs: 3 interleaved vectors of 6 samples each + (block0[0], block1[0], block2[0], block0[1], block1[1]....) + overlap part of last IMDCT (9 samples - see output comments) + window type (0,1,2,3) of previous block + current block index (for deciding whether to do frequency inversion) + number of guard bits in input vector + + Outputs: updated sample vector x, net gain of 1 integer bit + second half of (unwindowed) IMDCT's - save for next time + only save 9 xPrev samples, using symmetry (see WinPrevious()) + + Return: mOut (OR of abs(y) for all y calculated here) + + TODO: optimize for ARM **************************************************************************************/ - // barely faster in RAM -/*__attribute__ ((section (".data")))*/ static int IMDCT12x3(int *xCurr, int *xPrev, int *y, int btPrev, int blockIdx, int gb) -{ - int i, es, mOut, yLo, xBuf[18], xPrevWin[18]; /* need temp buffer for reordering short blocks */ - const int *wp; - - es = 0; - /* 7 gb is always adequate for accumulator loop + idct12 + window + overlap */ - if (gb < 7) { - es = 7 - gb; - for (i = 0; i < 18; i+=2) { - xCurr[i+0] >>= es; - xCurr[i+1] >>= es; - *xPrev++ >>= es; - } - xPrev -= 9; - } - - /* requires 4 input guard bits for each imdct12 */ - imdct12(xCurr + 0, xBuf + 0); - imdct12(xCurr + 1, xBuf + 6); - imdct12(xCurr + 2, xBuf + 12); - - /* window previous from last time */ - WinPrevious(xPrev, xPrevWin, btPrev); - - /* could unroll this for speed, minimum loads (short blocks usually rare, so doesn't make much overall difference) - * xPrevWin[i] << 2 still has 1 gb always, max gain of windowed xBuf stuff also < 1.0 and gain the sign bit - * so y calculations won't overflow - */ - wp = imdctWin[2]; - mOut = 0; - for (i = 0; i < 3; i++) { - yLo = (xPrevWin[ 0+i] << 2); - mOut |= FASTABS(yLo); y[( 0+i)*NBANDS] = yLo; - yLo = (xPrevWin[ 3+i] << 2); - mOut |= FASTABS(yLo); y[( 3+i)*NBANDS] = yLo; - yLo = (xPrevWin[ 6+i] << 2) + (MULSHIFT32(wp[0+i], xBuf[3+i])); - mOut |= FASTABS(yLo); y[( 6+i)*NBANDS] = yLo; - yLo = (xPrevWin[ 9+i] << 2) + (MULSHIFT32(wp[3+i], xBuf[5-i])); - mOut |= FASTABS(yLo); y[( 9+i)*NBANDS] = yLo; - yLo = (xPrevWin[12+i] << 2) + (MULSHIFT32(wp[6+i], xBuf[2-i]) + MULSHIFT32(wp[0+i], xBuf[(6+3)+i])); - mOut |= FASTABS(yLo); y[(12+i)*NBANDS] = yLo; - yLo = (xPrevWin[15+i] << 2) + (MULSHIFT32(wp[9+i], xBuf[0+i]) + MULSHIFT32(wp[3+i], xBuf[(6+5)-i])); - mOut |= FASTABS(yLo); y[(15+i)*NBANDS] = yLo; - } - - /* save previous (unwindowed) for overlap - only need samples 6-8, 12-17 */ - for (i = 6; i < 9; i++) - *xPrev++ = xBuf[i] >> 2; - for (i = 12; i < 18; i++) - *xPrev++ = xBuf[i] >> 2; - - xPrev -= 9; - mOut |= FreqInvertRescale(y, xPrev, blockIdx, es); - - return mOut; +// barely faster in RAM +/*__attribute__ ((section (".data")))*/ static int IMDCT12x3(int *xCurr, int *xPrev, int *y, int btPrev, int blockIdx, int gb) { + int i, es, mOut, yLo, xBuf[18], xPrevWin[18]; /* need temp buffer for reordering short blocks */ + const int *wp; + + es = 0; + /* 7 gb is always adequate for accumulator loop + idct12 + window + overlap */ + if (gb < 7) { + es = 7 - gb; + for (i = 0; i < 18; i += 2) { + xCurr[i + 0] >>= es; + xCurr[i + 1] >>= es; + *xPrev++ >>= es; + } + xPrev -= 9; + } + + /* requires 4 input guard bits for each imdct12 */ + imdct12(xCurr + 0, xBuf + 0); + imdct12(xCurr + 1, xBuf + 6); + imdct12(xCurr + 2, xBuf + 12); + + /* window previous from last time */ + WinPrevious(xPrev, xPrevWin, btPrev); + + /* could unroll this for speed, minimum loads (short blocks usually rare, so doesn't make much overall difference) + xPrevWin[i] << 2 still has 1 gb always, max gain of windowed xBuf stuff also < 1.0 and gain the sign bit + so y calculations won't overflow + */ + wp = imdctWin[2]; + mOut = 0; + for (i = 0; i < 3; i++) { + yLo = (xPrevWin[ 0 + i] << 2); + mOut |= FASTABS(yLo); y[(0 + i)*NBANDS] = yLo; + yLo = (xPrevWin[ 3 + i] << 2); + mOut |= FASTABS(yLo); y[(3 + i)*NBANDS] = yLo; + yLo = (xPrevWin[ 6 + i] << 2) + (MULSHIFT32(wp[0 + i], xBuf[3 + i])); + mOut |= FASTABS(yLo); y[(6 + i)*NBANDS] = yLo; + yLo = (xPrevWin[ 9 + i] << 2) + (MULSHIFT32(wp[3 + i], xBuf[5 - i])); + mOut |= FASTABS(yLo); y[(9 + i)*NBANDS] = yLo; + yLo = (xPrevWin[12 + i] << 2) + (MULSHIFT32(wp[6 + i], xBuf[2 - i]) + MULSHIFT32(wp[0 + i], xBuf[(6 + 3) + i])); + mOut |= FASTABS(yLo); y[(12 + i)*NBANDS] = yLo; + yLo = (xPrevWin[15 + i] << 2) + (MULSHIFT32(wp[9 + i], xBuf[0 + i]) + MULSHIFT32(wp[3 + i], xBuf[(6 + 5) - i])); + mOut |= FASTABS(yLo); y[(15 + i)*NBANDS] = yLo; + } + + /* save previous (unwindowed) for overlap - only need samples 6-8, 12-17 */ + for (i = 6; i < 9; i++) { + *xPrev++ = xBuf[i] >> 2; + } + for (i = 12; i < 18; i++) { + *xPrev++ = xBuf[i] >> 2; + } + + xPrev -= 9; + mOut |= FreqInvertRescale(y, xPrev, blockIdx, es); + + return mOut; } /************************************************************************************** - * Function: HybridTransform - * - * Description: IMDCT's, windowing, and overlap-add on long/short/mixed blocks - * - * Inputs: vector of input coefficients, length = nBlocksTotal * 18) - * vector of overlap samples from last time, length = nBlocksPrev * 9) - * buffer for output samples, length = MAXNSAMP - * SideInfoSub struct for this granule/channel - * BlockCount struct with necessary info - * number of non-zero input and overlap blocks - * number of long blocks in input vector (rest assumed to be short blocks) - * number of blocks which use long window (type) 0 in case of mixed block - * (bc->currWinSwitch, 0 for non-mixed blocks) - * - * Outputs: transformed, windowed, and overlapped sample buffer - * does frequency inversion on odd blocks - * updated buffer of samples for overlap - * - * Return: number of non-zero IMDCT blocks calculated in this call - * (including overlap-add) - * - * TODO: examine mixedBlock/winSwitch logic carefully (test he_mode.bit) + Function: HybridTransform + + Description: IMDCT's, windowing, and overlap-add on long/short/mixed blocks + + Inputs: vector of input coefficients, length = nBlocksTotal * 18) + vector of overlap samples from last time, length = nBlocksPrev * 9) + buffer for output samples, length = MAXNSAMP + SideInfoSub struct for this granule/channel + BlockCount struct with necessary info + number of non-zero input and overlap blocks + number of long blocks in input vector (rest assumed to be short blocks) + number of blocks which use long window (type) 0 in case of mixed block + (bc->currWinSwitch, 0 for non-mixed blocks) + + Outputs: transformed, windowed, and overlapped sample buffer + does frequency inversion on odd blocks + updated buffer of samples for overlap + + Return: number of non-zero IMDCT blocks calculated in this call + (including overlap-add) + + TODO: examine mixedBlock/winSwitch logic carefully (test he_mode.bit) **************************************************************************************/ -/* __attribute__ ((section (".data"))) */ static int HybridTransform(int *xCurr, int *xPrev, int y[BLOCK_SIZE][NBANDS], SideInfoSub *sis, BlockCount *bc) -{ - int xPrevWin[18], currWinIdx, prevWinIdx; - int i, j, nBlocksOut, nonZero, mOut; - int fiBit, xp; - - ASSERT(bc->nBlocksLong <= NBANDS); - ASSERT(bc->nBlocksTotal <= NBANDS); - ASSERT(bc->nBlocksPrev <= NBANDS); - - mOut = 0; - - /* do long blocks, if any */ - for(i = 0; i < bc->nBlocksLong; i++) { - /* currWinIdx picks the right window for long blocks (if mixed, long blocks use window type 0) */ - currWinIdx = sis->blockType; - if (sis->mixedBlock && i < bc->currWinSwitch) - currWinIdx = 0; - - prevWinIdx = bc->prevType; - if (i < bc->prevWinSwitch) - prevWinIdx = 0; - - /* do 36-point IMDCT, including windowing and overlap-add */ - mOut |= IMDCT36(xCurr, xPrev, &(y[0][i]), currWinIdx, prevWinIdx, i, bc->gbIn); - xCurr += 18; - xPrev += 9; - } - - /* do short blocks (if any) */ - for ( ; i < bc->nBlocksTotal; i++) { - ASSERT(sis->blockType == 2); - - prevWinIdx = bc->prevType; - if (i < bc->prevWinSwitch) - prevWinIdx = 0; - - mOut |= IMDCT12x3(xCurr, xPrev, &(y[0][i]), prevWinIdx, i, bc->gbIn); - xCurr += 18; - xPrev += 9; - } - nBlocksOut = i; - - /* window and overlap prev if prev longer that current */ - for ( ; i < bc->nBlocksPrev; i++) { - prevWinIdx = bc->prevType; - if (i < bc->prevWinSwitch) - prevWinIdx = 0; - WinPrevious(xPrev, xPrevWin, prevWinIdx); - - nonZero = 0; - fiBit = i << 31; - for (j = 0; j < 9; j++) { - xp = xPrevWin[2*j+0] << 2; /* << 2 temp for scaling */ - nonZero |= xp; - y[2*j+0][i] = xp; - mOut |= FASTABS(xp); - - /* frequency inversion on odd blocks/odd samples (flip sign if i odd, j odd) */ - xp = xPrevWin[2*j+1] << 2; - xp = (xp ^ (fiBit >> 31)) + (i & 0x01); - nonZero |= xp; - y[2*j+1][i] = xp; - mOut |= FASTABS(xp); - - xPrev[j] = 0; - } - xPrev += 9; - if (nonZero) - nBlocksOut = i; - } - - /* clear rest of blocks */ - for ( ; i < 32; i++) { - for (j = 0; j < 18; j++) - y[j][i] = 0; - } - - bc->gbOut = CLZ(mOut) - 1; - - return nBlocksOut; +/* __attribute__ ((section (".data"))) */ static int HybridTransform(int *xCurr, int *xPrev, int y[BLOCK_SIZE][NBANDS], SideInfoSub *sis, BlockCount *bc) { + int xPrevWin[18], currWinIdx, prevWinIdx; + int i, j, nBlocksOut, nonZero, mOut; + int fiBit, xp; + + ASSERT(bc->nBlocksLong <= NBANDS); + ASSERT(bc->nBlocksTotal <= NBANDS); + ASSERT(bc->nBlocksPrev <= NBANDS); + + mOut = 0; + + /* do long blocks, if any */ + for (i = 0; i < bc->nBlocksLong; i++) { + /* currWinIdx picks the right window for long blocks (if mixed, long blocks use window type 0) */ + currWinIdx = sis->blockType; + if (sis->mixedBlock && i < bc->currWinSwitch) { + currWinIdx = 0; + } + + prevWinIdx = bc->prevType; + if (i < bc->prevWinSwitch) { + prevWinIdx = 0; + } + + /* do 36-point IMDCT, including windowing and overlap-add */ + mOut |= IMDCT36(xCurr, xPrev, &(y[0][i]), currWinIdx, prevWinIdx, i, bc->gbIn); + xCurr += 18; + xPrev += 9; + } + + /* do short blocks (if any) */ + for (; i < bc->nBlocksTotal; i++) { + ASSERT(sis->blockType == 2); + + prevWinIdx = bc->prevType; + if (i < bc->prevWinSwitch) { + prevWinIdx = 0; + } + + mOut |= IMDCT12x3(xCurr, xPrev, &(y[0][i]), prevWinIdx, i, bc->gbIn); + xCurr += 18; + xPrev += 9; + } + nBlocksOut = i; + + /* window and overlap prev if prev longer that current */ + for (; i < bc->nBlocksPrev; i++) { + prevWinIdx = bc->prevType; + if (i < bc->prevWinSwitch) { + prevWinIdx = 0; + } + WinPrevious(xPrev, xPrevWin, prevWinIdx); + + nonZero = 0; + fiBit = i << 31; + for (j = 0; j < 9; j++) { + xp = xPrevWin[2 * j + 0] << 2; /* << 2 temp for scaling */ + nonZero |= xp; + y[2 * j + 0][i] = xp; + mOut |= FASTABS(xp); + + /* frequency inversion on odd blocks/odd samples (flip sign if i odd, j odd) */ + xp = xPrevWin[2 * j + 1] << 2; + xp = (xp ^ (fiBit >> 31)) + (i & 0x01); + nonZero |= xp; + y[2 * j + 1][i] = xp; + mOut |= FASTABS(xp); + + xPrev[j] = 0; + } + xPrev += 9; + if (nonZero) { + nBlocksOut = i; + } + } + + /* clear rest of blocks */ + for (; i < 32; i++) { + for (j = 0; j < 18; j++) { + y[j][i] = 0; + } + } + + bc->gbOut = CLZ(mOut) - 1; + + return nBlocksOut; } /************************************************************************************** - * Function: IMDCT - * - * Description: do alias reduction, inverse MDCT, overlap-add, and frequency inversion - * - * Inputs: MP3DecInfo structure filled by UnpackFrameHeader(), UnpackSideInfo(), - * UnpackScaleFactors(), and DecodeHuffman() (for this granule, channel) - * includes PCM samples in overBuf (from last call to IMDCT) for OLA - * index of current granule and channel - * - * Outputs: PCM samples in outBuf, for input to subband transform - * PCM samples in overBuf, for OLA next time - * updated hi->nonZeroBound index for this channel - * - * Return: 0 on success, -1 if null input pointers + Function: IMDCT + + Description: do alias reduction, inverse MDCT, overlap-add, and frequency inversion + + Inputs: MP3DecInfo structure filled by UnpackFrameHeader(), UnpackSideInfo(), + UnpackScaleFactors(), and DecodeHuffman() (for this granule, channel) + includes PCM samples in overBuf (from last call to IMDCT) for OLA + index of current granule and channel + + Outputs: PCM samples in outBuf, for input to subband transform + PCM samples in overBuf, for OLA next time + updated hi->nonZeroBound index for this channel + + Return: 0 on success, -1 if null input pointers **************************************************************************************/ - // a bit faster in RAM -/*__attribute__ ((section (".data")))*/ int IMDCT(MP3DecInfo *mp3DecInfo, int gr, int ch) -{ - int nBfly, blockCutoff; - FrameHeader *fh; - SideInfo *si; - HuffmanInfo *hi; - IMDCTInfo *mi; - BlockCount bc; - - /* validate pointers */ - if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || !mp3DecInfo->SideInfoPS || - !mp3DecInfo->HuffmanInfoPS || !mp3DecInfo->IMDCTInfoPS) - return -1; - - /* si is an array of up to 4 structs, stored as gr0ch0, gr0ch1, gr1ch0, gr1ch1 */ - fh = (FrameHeader *)(mp3DecInfo->FrameHeaderPS); - si = (SideInfo *)(mp3DecInfo->SideInfoPS); - hi = (HuffmanInfo*)(mp3DecInfo->HuffmanInfoPS); - mi = (IMDCTInfo *)(mp3DecInfo->IMDCTInfoPS); - - /* anti-aliasing done on whole long blocks only - * for mixed blocks, nBfly always 1, except 3 for 8 kHz MPEG 2.5 (see sfBandTab) - * nLongBlocks = number of blocks with (possibly) non-zero power - * nBfly = number of butterflies to do (nLongBlocks - 1, unless no long blocks) - */ - blockCutoff = fh->sfBand->l[(fh->ver == MPEG1 ? 8 : 6)] / 18; /* same as 3* num short sfb's in spec */ - if (si->sis[gr][ch].blockType != 2) { - /* all long transforms */ - bc.nBlocksLong = MIN((hi->nonZeroBound[ch] + 7) / 18 + 1, 32); - nBfly = bc.nBlocksLong - 1; - } else if (si->sis[gr][ch].blockType == 2 && si->sis[gr][ch].mixedBlock) { - /* mixed block - long transforms until cutoff, then short transforms */ - bc.nBlocksLong = blockCutoff; - nBfly = bc.nBlocksLong - 1; - } else { - /* all short transforms */ - bc.nBlocksLong = 0; - nBfly = 0; - } - - AntiAlias(hi->huffDecBuf[ch], nBfly); - hi->nonZeroBound[ch] = MAX(hi->nonZeroBound[ch], (nBfly * 18) + 8); - - ASSERT(hi->nonZeroBound[ch] <= MAX_NSAMP); - - /* for readability, use a struct instead of passing a million parameters to HybridTransform() */ - bc.nBlocksTotal = (hi->nonZeroBound[ch] + 17) / 18; - bc.nBlocksPrev = mi->numPrevIMDCT[ch]; - bc.prevType = mi->prevType[ch]; - bc.prevWinSwitch = mi->prevWinSwitch[ch]; - bc.currWinSwitch = (si->sis[gr][ch].mixedBlock ? blockCutoff : 0); /* where WINDOW switches (not nec. transform) */ - bc.gbIn = hi->gb[ch]; - - mi->numPrevIMDCT[ch] = HybridTransform(hi->huffDecBuf[ch], mi->overBuf[ch], mi->outBuf[ch], &si->sis[gr][ch], &bc); - mi->prevType[ch] = si->sis[gr][ch].blockType; - mi->prevWinSwitch[ch] = bc.currWinSwitch; /* 0 means not a mixed block (either all short or all long) */ - mi->gb[ch] = bc.gbOut; - - ASSERT(mi->numPrevIMDCT[ch] <= NBANDS); - - /* output has gained 2 int bits */ - return 0; +// a bit faster in RAM +/*__attribute__ ((section (".data")))*/ int IMDCT(MP3DecInfo *mp3DecInfo, int gr, int ch) { + int nBfly, blockCutoff; + FrameHeader *fh; + SideInfo *si; + HuffmanInfo *hi; + IMDCTInfo *mi; + BlockCount bc; + + /* validate pointers */ + if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || !mp3DecInfo->SideInfoPS || + !mp3DecInfo->HuffmanInfoPS || !mp3DecInfo->IMDCTInfoPS) { + return -1; + } + + /* si is an array of up to 4 structs, stored as gr0ch0, gr0ch1, gr1ch0, gr1ch1 */ + fh = (FrameHeader *)(mp3DecInfo->FrameHeaderPS); + si = (SideInfo *)(mp3DecInfo->SideInfoPS); + hi = (HuffmanInfo*)(mp3DecInfo->HuffmanInfoPS); + mi = (IMDCTInfo *)(mp3DecInfo->IMDCTInfoPS); + + /* anti-aliasing done on whole long blocks only + for mixed blocks, nBfly always 1, except 3 for 8 kHz MPEG 2.5 (see sfBandTab) + nLongBlocks = number of blocks with (possibly) non-zero power + nBfly = number of butterflies to do (nLongBlocks - 1, unless no long blocks) + */ + blockCutoff = fh->sfBand->l[(fh->ver == MPEG1 ? 8 : 6)] / 18; /* same as 3* num short sfb's in spec */ + if (si->sis[gr][ch].blockType != 2) { + /* all long transforms */ + bc.nBlocksLong = MIN((hi->nonZeroBound[ch] + 7) / 18 + 1, 32); + nBfly = bc.nBlocksLong - 1; + } else if (si->sis[gr][ch].blockType == 2 && si->sis[gr][ch].mixedBlock) { + /* mixed block - long transforms until cutoff, then short transforms */ + bc.nBlocksLong = blockCutoff; + nBfly = bc.nBlocksLong - 1; + } else { + /* all short transforms */ + bc.nBlocksLong = 0; + nBfly = 0; + } + + AntiAlias(hi->huffDecBuf[ch], nBfly); + hi->nonZeroBound[ch] = MAX(hi->nonZeroBound[ch], (nBfly * 18) + 8); + + ASSERT(hi->nonZeroBound[ch] <= MAX_NSAMP); + + /* for readability, use a struct instead of passing a million parameters to HybridTransform() */ + bc.nBlocksTotal = (hi->nonZeroBound[ch] + 17) / 18; + bc.nBlocksPrev = mi->numPrevIMDCT[ch]; + bc.prevType = mi->prevType[ch]; + bc.prevWinSwitch = mi->prevWinSwitch[ch]; + bc.currWinSwitch = (si->sis[gr][ch].mixedBlock ? blockCutoff : 0); /* where WINDOW switches (not nec. transform) */ + bc.gbIn = hi->gb[ch]; + + mi->numPrevIMDCT[ch] = HybridTransform(hi->huffDecBuf[ch], mi->overBuf[ch], mi->outBuf[ch], &si->sis[gr][ch], &bc); + mi->prevType[ch] = si->sis[gr][ch].blockType; + mi->prevWinSwitch[ch] = bc.currWinSwitch; /* 0 means not a mixed block (either all short or all long) */ + mi->gb[ch] = bc.gbOut; + + ASSERT(mi->numPrevIMDCT[ch] <= NBANDS); + + /* output has gained 2 int bits */ + return 0; } diff --git a/src/libhelix-mp3/mp3common.h b/src/libhelix-mp3/mp3common.h index 07548abf..695da056 100644 --- a/src/libhelix-mp3/mp3common.h +++ b/src/libhelix-mp3/mp3common.h @@ -1,44 +1,44 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * mp3common.h - implementation-independent API's, datatypes, and definitions + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + mp3common.h - implementation-independent API's, datatypes, and definitions **************************************************************************************/ #ifndef _MP3COMMON_H @@ -53,8 +53,8 @@ /* 11-bit syncword if MPEG 2.5 extensions are enabled */ /* -#define SYNCWORDH 0xff -#define SYNCWORDL 0xe0 + #define SYNCWORDH 0xff + #define SYNCWORDL 0xe0 */ /* 12-bit syncword if MPEG 1,2 only are supported */ @@ -62,42 +62,42 @@ #define SYNCWORDL 0xf0 typedef struct _MP3DecInfo { - /* pointers to platform-specific data structures */ - void *FrameHeaderPS; - void *SideInfoPS; - void *ScaleFactorInfoPS; - void *HuffmanInfoPS; - void *DequantInfoPS; - void *IMDCTInfoPS; - void *SubbandInfoPS; - - /* buffer which must be large enough to hold largest possible main_data section */ - unsigned char mainBuf[MAINBUF_SIZE]; - - /* special info for "free" bitrate files */ - int freeBitrateFlag; - int freeBitrateSlots; - - /* user-accessible info */ - int bitrate; - int nChans; - int samprate; - int nGrans; /* granules per frame */ - int nGranSamps; /* samples per granule */ - int nSlots; - int layer; - MPEGVersion version; - - int mainDataBegin; - int mainDataBytes; - - int part23Length[MAX_NGRAN][MAX_NCHAN]; + /* pointers to platform-specific data structures */ + void *FrameHeaderPS; + void *SideInfoPS; + void *ScaleFactorInfoPS; + void *HuffmanInfoPS; + void *DequantInfoPS; + void *IMDCTInfoPS; + void *SubbandInfoPS; + + /* buffer which must be large enough to hold largest possible main_data section */ + unsigned char mainBuf[MAINBUF_SIZE]; + + /* special info for "free" bitrate files */ + int freeBitrateFlag; + int freeBitrateSlots; + + /* user-accessible info */ + int bitrate; + int nChans; + int samprate; + int nGrans; /* granules per frame */ + int nGranSamps; /* samples per granule */ + int nSlots; + int layer; + MPEGVersion version; + + int mainDataBegin; + int mainDataBytes; + + int part23Length[MAX_NGRAN][MAX_NCHAN]; } MP3DecInfo; typedef struct _SFBandTable { - int/*short*/ l[23]; - int/*short*/ s[14]; + int/*short*/ l[23]; + int/*short*/ s[14]; } SFBandTable; /* decoder functions which must be implemented for each platform */ diff --git a/src/libhelix-mp3/mp3dec.c b/src/libhelix-mp3/mp3dec.c index 5e68c7af..a6ebd330 100644 --- a/src/libhelix-mp3/mp3dec.c +++ b/src/libhelix-mp3/mp3dec.c @@ -1,44 +1,44 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * mp3dec.c - platform-independent top level MP3 decoder API + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + mp3dec.c - platform-independent top level MP3 decoder API **************************************************************************************/ #include "string.h" @@ -52,433 +52,433 @@ #endif /************************************************************************************** - * Function: MP3InitDecoder - * - * Description: allocate memory for platform-specific data - * clear all the user-accessible fields - * - * Inputs: none - * - * Outputs: none - * - * Return: handle to mp3 decoder instance, 0 if malloc fails + Function: MP3InitDecoder + + Description: allocate memory for platform-specific data + clear all the user-accessible fields + + Inputs: none + + Outputs: none + + Return: handle to mp3 decoder instance, 0 if malloc fails **************************************************************************************/ -HMP3Decoder MP3InitDecoder(void) -{ - MP3DecInfo *mp3DecInfo; +HMP3Decoder MP3InitDecoder(void) { + MP3DecInfo *mp3DecInfo; - mp3DecInfo = AllocateBuffers(); + mp3DecInfo = AllocateBuffers(); - return (HMP3Decoder)mp3DecInfo; + return (HMP3Decoder)mp3DecInfo; } /************************************************************************************** - * Function: MP3FreeDecoder - * - * Description: free platform-specific data allocated by InitMP3Decoder - * zero out the contents of MP3DecInfo struct - * - * Inputs: valid MP3 decoder instance pointer (HMP3Decoder) - * - * Outputs: none - * - * Return: none + Function: MP3FreeDecoder + + Description: free platform-specific data allocated by InitMP3Decoder + zero out the contents of MP3DecInfo struct + + Inputs: valid MP3 decoder instance pointer (HMP3Decoder) + + Outputs: none + + Return: none **************************************************************************************/ -void MP3FreeDecoder(HMP3Decoder hMP3Decoder) -{ - MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder; +void MP3FreeDecoder(HMP3Decoder hMP3Decoder) { + MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder; - if (!mp3DecInfo) - return; + if (!mp3DecInfo) { + return; + } - FreeBuffers(mp3DecInfo); + FreeBuffers(mp3DecInfo); } /************************************************************************************** - * Function: MP3FindSyncWord - * - * Description: locate the next byte-alinged sync word in the raw mp3 stream - * - * Inputs: buffer to search for sync word - * max number of bytes to search in buffer - * - * Outputs: none - * - * Return: offset to first sync word (bytes from start of buf) - * -1 if sync not found after searching nBytes + Function: MP3FindSyncWord + + Description: locate the next byte-alinged sync word in the raw mp3 stream + + Inputs: buffer to search for sync word + max number of bytes to search in buffer + + Outputs: none + + Return: offset to first sync word (bytes from start of buf) + -1 if sync not found after searching nBytes **************************************************************************************/ -int MP3FindSyncWord(unsigned char *buf, int nBytes) -{ - int i; - - /* find byte-aligned syncword - need 12 (MPEG 1,2) or 11 (MPEG 2.5) matching bits */ - for (i = 0; i < nBytes - 1; i++) { - if ( (buf[i+0] & SYNCWORDH) == SYNCWORDH && (buf[i+1] & SYNCWORDL) == SYNCWORDL ) - return i; - } - - return -1; +int MP3FindSyncWord(unsigned char *buf, int nBytes) { + int i; + + /* find byte-aligned syncword - need 12 (MPEG 1,2) or 11 (MPEG 2.5) matching bits */ + for (i = 0; i < nBytes - 1; i++) { + if ((buf[i + 0] & SYNCWORDH) == SYNCWORDH && (buf[i + 1] & SYNCWORDL) == SYNCWORDL) { + return i; + } + } + + return -1; } /************************************************************************************** - * Function: MP3FindFreeSync - * - * Description: figure out number of bytes between adjacent sync words in "free" mode - * - * Inputs: buffer to search for next sync word - * the 4-byte frame header starting at the current sync word - * max number of bytes to search in buffer - * - * Outputs: none - * - * Return: offset to next sync word, minus any pad byte (i.e. nSlots) - * -1 if sync not found after searching nBytes - * - * Notes: this checks that the first 22 bits of the next frame header are the - * same as the current frame header, but it's still not foolproof - * (could accidentally find a sequence in the bitstream which - * appears to match but is not actually the next frame header) - * this could be made more error-resilient by checking several frames - * in a row and verifying that nSlots is the same in each case - * since free mode requires CBR (see spec) we generally only call - * this function once (first frame) then store the result (nSlots) - * and just use it from then on + Function: MP3FindFreeSync + + Description: figure out number of bytes between adjacent sync words in "free" mode + + Inputs: buffer to search for next sync word + the 4-byte frame header starting at the current sync word + max number of bytes to search in buffer + + Outputs: none + + Return: offset to next sync word, minus any pad byte (i.e. nSlots) + -1 if sync not found after searching nBytes + + Notes: this checks that the first 22 bits of the next frame header are the + same as the current frame header, but it's still not foolproof + (could accidentally find a sequence in the bitstream which + appears to match but is not actually the next frame header) + this could be made more error-resilient by checking several frames + in a row and verifying that nSlots is the same in each case + since free mode requires CBR (see spec) we generally only call + this function once (first frame) then store the result (nSlots) + and just use it from then on **************************************************************************************/ -static int MP3FindFreeSync(unsigned char *buf, unsigned char firstFH[4], int nBytes) -{ - int offset = 0; - unsigned char *bufPtr = buf; - - /* loop until we either: - * - run out of nBytes (FindMP3SyncWord() returns -1) - * - find the next valid frame header (sync word, version, layer, CRC flag, bitrate, and sample rate - * in next header must match current header) - */ - while (1) { - offset = MP3FindSyncWord(bufPtr, nBytes); - bufPtr += offset; - if (offset < 0) { - return -1; - } else if ( (bufPtr[0] == firstFH[0]) && (bufPtr[1] == firstFH[1]) && ((bufPtr[2] & 0xfc) == (firstFH[2] & 0xfc)) ) { - /* want to return number of bytes per frame, NOT counting the padding byte, so subtract one if padFlag == 1 */ - if ((firstFH[2] >> 1) & 0x01) - bufPtr--; - return bufPtr - buf; - } - bufPtr += 3; - nBytes -= (offset + 3); - }; - - return -1; +static int MP3FindFreeSync(unsigned char *buf, unsigned char firstFH[4], int nBytes) { + int offset = 0; + unsigned char *bufPtr = buf; + + /* loop until we either: + - run out of nBytes (FindMP3SyncWord() returns -1) + - find the next valid frame header (sync word, version, layer, CRC flag, bitrate, and sample rate + in next header must match current header) + */ + while (1) { + offset = MP3FindSyncWord(bufPtr, nBytes); + bufPtr += offset; + if (offset < 0) { + return -1; + } else if ((bufPtr[0] == firstFH[0]) && (bufPtr[1] == firstFH[1]) && ((bufPtr[2] & 0xfc) == (firstFH[2] & 0xfc))) { + /* want to return number of bytes per frame, NOT counting the padding byte, so subtract one if padFlag == 1 */ + if ((firstFH[2] >> 1) & 0x01) { + bufPtr--; + } + return bufPtr - buf; + } + bufPtr += 3; + nBytes -= (offset + 3); + }; + + return -1; } /************************************************************************************** - * Function: MP3GetLastFrameInfo - * - * Description: get info about last MP3 frame decoded (number of sampled decoded, - * sample rate, bitrate, etc.) - * - * Inputs: valid MP3 decoder instance pointer (HMP3Decoder) - * pointer to MP3FrameInfo struct - * - * Outputs: filled-in MP3FrameInfo struct - * - * Return: none - * - * Notes: call this right after calling MP3Decode + Function: MP3GetLastFrameInfo + + Description: get info about last MP3 frame decoded (number of sampled decoded, + sample rate, bitrate, etc.) + + Inputs: valid MP3 decoder instance pointer (HMP3Decoder) + pointer to MP3FrameInfo struct + + Outputs: filled-in MP3FrameInfo struct + + Return: none + + Notes: call this right after calling MP3Decode **************************************************************************************/ -void MP3GetLastFrameInfo(HMP3Decoder hMP3Decoder, MP3FrameInfo *mp3FrameInfo) -{ - MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder; - - if (!mp3DecInfo || mp3DecInfo->layer != 3) { - mp3FrameInfo->bitrate = 0; - mp3FrameInfo->nChans = 0; - mp3FrameInfo->samprate = 0; - mp3FrameInfo->bitsPerSample = 0; - mp3FrameInfo->outputSamps = 0; - mp3FrameInfo->layer = 0; - mp3FrameInfo->version = 0; - } else { - mp3FrameInfo->bitrate = mp3DecInfo->bitrate; - mp3FrameInfo->nChans = mp3DecInfo->nChans; - mp3FrameInfo->samprate = mp3DecInfo->samprate; - mp3FrameInfo->bitsPerSample = 16; - mp3FrameInfo->outputSamps = mp3DecInfo->nChans * (int)samplesPerFrameTab[mp3DecInfo->version][mp3DecInfo->layer - 1]; - mp3FrameInfo->layer = mp3DecInfo->layer; - mp3FrameInfo->version = mp3DecInfo->version; - } +void MP3GetLastFrameInfo(HMP3Decoder hMP3Decoder, MP3FrameInfo *mp3FrameInfo) { + MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder; + + if (!mp3DecInfo || mp3DecInfo->layer != 3) { + mp3FrameInfo->bitrate = 0; + mp3FrameInfo->nChans = 0; + mp3FrameInfo->samprate = 0; + mp3FrameInfo->bitsPerSample = 0; + mp3FrameInfo->outputSamps = 0; + mp3FrameInfo->layer = 0; + mp3FrameInfo->version = 0; + } else { + mp3FrameInfo->bitrate = mp3DecInfo->bitrate; + mp3FrameInfo->nChans = mp3DecInfo->nChans; + mp3FrameInfo->samprate = mp3DecInfo->samprate; + mp3FrameInfo->bitsPerSample = 16; + mp3FrameInfo->outputSamps = mp3DecInfo->nChans * (int)samplesPerFrameTab[mp3DecInfo->version][mp3DecInfo->layer - 1]; + mp3FrameInfo->layer = mp3DecInfo->layer; + mp3FrameInfo->version = mp3DecInfo->version; + } } /************************************************************************************** - * Function: MP3GetNextFrameInfo - * - * Description: parse MP3 frame header - * - * Inputs: valid MP3 decoder instance pointer (HMP3Decoder) - * pointer to MP3FrameInfo struct - * pointer to buffer containing valid MP3 frame header (located using - * MP3FindSyncWord(), above) - * - * Outputs: filled-in MP3FrameInfo struct - * - * Return: error code, defined in mp3dec.h (0 means no error, < 0 means error) + Function: MP3GetNextFrameInfo + + Description: parse MP3 frame header + + Inputs: valid MP3 decoder instance pointer (HMP3Decoder) + pointer to MP3FrameInfo struct + pointer to buffer containing valid MP3 frame header (located using + MP3FindSyncWord(), above) + + Outputs: filled-in MP3FrameInfo struct + + Return: error code, defined in mp3dec.h (0 means no error, < 0 means error) **************************************************************************************/ -int MP3GetNextFrameInfo(HMP3Decoder hMP3Decoder, MP3FrameInfo *mp3FrameInfo, unsigned char *buf) -{ - MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder; +int MP3GetNextFrameInfo(HMP3Decoder hMP3Decoder, MP3FrameInfo *mp3FrameInfo, unsigned char *buf) { + MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder; - if (!mp3DecInfo) - return ERR_MP3_NULL_POINTER; + if (!mp3DecInfo) { + return ERR_MP3_NULL_POINTER; + } - if (UnpackFrameHeader(mp3DecInfo, buf) == -1 || mp3DecInfo->layer != 3) - return ERR_MP3_INVALID_FRAMEHEADER; + if (UnpackFrameHeader(mp3DecInfo, buf) == -1 || mp3DecInfo->layer != 3) { + return ERR_MP3_INVALID_FRAMEHEADER; + } - MP3GetLastFrameInfo(mp3DecInfo, mp3FrameInfo); + MP3GetLastFrameInfo(mp3DecInfo, mp3FrameInfo); - return ERR_MP3_NONE; + return ERR_MP3_NONE; } /************************************************************************************** - * Function: MP3ClearBadFrame - * - * Description: zero out pcm buffer if error decoding MP3 frame - * - * Inputs: mp3DecInfo struct with correct frame size parameters filled in - * pointer pcm output buffer - * - * Outputs: zeroed out pcm buffer - * - * Return: none + Function: MP3ClearBadFrame + + Description: zero out pcm buffer if error decoding MP3 frame + + Inputs: mp3DecInfo struct with correct frame size parameters filled in + pointer pcm output buffer + + Outputs: zeroed out pcm buffer + + Return: none **************************************************************************************/ -static void MP3ClearBadFrame(MP3DecInfo *mp3DecInfo, short *outbuf) -{ - int i; +static void MP3ClearBadFrame(MP3DecInfo *mp3DecInfo, short *outbuf) { + int i; - if (!mp3DecInfo) - return; + if (!mp3DecInfo) { + return; + } - for (i = 0; i < mp3DecInfo->nGrans * mp3DecInfo->nGranSamps * mp3DecInfo->nChans; i++) - outbuf[i] = 0; + for (i = 0; i < mp3DecInfo->nGrans * mp3DecInfo->nGranSamps * mp3DecInfo->nChans; i++) { + outbuf[i] = 0; + } } /************************************************************************************** - * Function: MP3Decode - * - * Description: decode one frame of MP3 data - * - * Inputs: valid MP3 decoder instance pointer (HMP3Decoder) - * double pointer to buffer of MP3 data (containing headers + mainData) - * number of valid bytes remaining in inbuf - * pointer to outbuf, big enough to hold one frame of decoded PCM samples - * flag indicating whether MP3 data is normal MPEG format (useSize = 0) - * or reformatted as "self-contained" frames (useSize = 1) - * - * Outputs: PCM data in outbuf, interleaved LRLRLR... if stereo - * number of output samples = nGrans * nGranSamps * nChans - * updated inbuf pointer, updated bytesLeft - * - * Return: error code, defined in mp3dec.h (0 means no error, < 0 means error) - * - * Notes: switching useSize on and off between frames in the same stream - * is not supported (bit reservoir is not maintained if useSize on) + Function: MP3Decode + + Description: decode one frame of MP3 data + + Inputs: valid MP3 decoder instance pointer (HMP3Decoder) + double pointer to buffer of MP3 data (containing headers + mainData) + number of valid bytes remaining in inbuf + pointer to outbuf, big enough to hold one frame of decoded PCM samples + flag indicating whether MP3 data is normal MPEG format (useSize = 0) + or reformatted as "self-contained" frames (useSize = 1) + + Outputs: PCM data in outbuf, interleaved LRLRLR... if stereo + number of output samples = nGrans * nGranSamps * nChans + updated inbuf pointer, updated bytesLeft + + Return: error code, defined in mp3dec.h (0 means no error, < 0 means error) + + Notes: switching useSize on and off between frames in the same stream + is not supported (bit reservoir is not maintained if useSize on) **************************************************************************************/ -int MP3Decode(HMP3Decoder hMP3Decoder, unsigned char **inbuf, int *bytesLeft, short *outbuf, int useSize) -{ - int offset, bitOffset, mainBits, gr, ch, fhBytes, siBytes, freeFrameBytes; - int prevBitOffset, sfBlockBits, huffBlockBits; - unsigned char *mainPtr; - MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder; - - #ifdef PROFILE - long time; - #endif - - if (!mp3DecInfo) - return ERR_MP3_NULL_POINTER; - - /* unpack frame header */ - fhBytes = UnpackFrameHeader(mp3DecInfo, *inbuf); - if (fhBytes < 0) - return ERR_MP3_INVALID_FRAMEHEADER; /* don't clear outbuf since we don't know size (failed to parse header) */ - *inbuf += fhBytes; - +int MP3Decode(HMP3Decoder hMP3Decoder, unsigned char **inbuf, int *bytesLeft, short *outbuf, int useSize) { + int offset, bitOffset, mainBits, gr, ch, fhBytes, siBytes, freeFrameBytes; + int prevBitOffset, sfBlockBits, huffBlockBits; + unsigned char *mainPtr; + MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder; + +#ifdef PROFILE + long time; +#endif + + if (!mp3DecInfo) { + return ERR_MP3_NULL_POINTER; + } + + /* unpack frame header */ + fhBytes = UnpackFrameHeader(mp3DecInfo, *inbuf); + if (fhBytes < 0) { + return ERR_MP3_INVALID_FRAMEHEADER; /* don't clear outbuf since we don't know size (failed to parse header) */ + } + *inbuf += fhBytes; + +#ifdef PROFILE + time = systime_get(); +#endif + /* unpack side info */ + siBytes = UnpackSideInfo(mp3DecInfo, *inbuf); + if (siBytes < 0) { + MP3ClearBadFrame(mp3DecInfo, outbuf); + return ERR_MP3_INVALID_SIDEINFO; + } + *inbuf += siBytes; + *bytesLeft -= (fhBytes + siBytes); +#ifdef PROFILE + time = systime_get() - time; + printf("UnpackSideInfo: %i ms\n", time); +#endif + + + /* if free mode, need to calculate bitrate and nSlots manually, based on frame size */ + if (mp3DecInfo->bitrate == 0 || mp3DecInfo->freeBitrateFlag) { + if (!mp3DecInfo->freeBitrateFlag) { + /* first time through, need to scan for next sync word and figure out frame size */ + mp3DecInfo->freeBitrateFlag = 1; + mp3DecInfo->freeBitrateSlots = MP3FindFreeSync(*inbuf, *inbuf - fhBytes - siBytes, *bytesLeft); + if (mp3DecInfo->freeBitrateSlots < 0) { + MP3ClearBadFrame(mp3DecInfo, outbuf); + return ERR_MP3_FREE_BITRATE_SYNC; + } + freeFrameBytes = mp3DecInfo->freeBitrateSlots + fhBytes + siBytes; + mp3DecInfo->bitrate = (freeFrameBytes * mp3DecInfo->samprate * 8) / (mp3DecInfo->nGrans * mp3DecInfo->nGranSamps); + } + mp3DecInfo->nSlots = mp3DecInfo->freeBitrateSlots + CheckPadBit(mp3DecInfo); /* add pad byte, if required */ + } + + /* useSize != 0 means we're getting reformatted (RTP) packets (see RFC 3119) + - calling function assembles "self-contained" MP3 frames by shifting any main_data + from the bit reservoir (in previous frames) to AFTER the sync word and side info + - calling function should set mainDataBegin to 0, and tell us exactly how large this + frame is (in bytesLeft) + */ + if (useSize) { + mp3DecInfo->nSlots = *bytesLeft; + if (mp3DecInfo->mainDataBegin != 0 || mp3DecInfo->nSlots <= 0) { + /* error - non self-contained frame, or missing frame (size <= 0), could do loss concealment here */ + MP3ClearBadFrame(mp3DecInfo, outbuf); + return ERR_MP3_INVALID_FRAMEHEADER; + } + + /* can operate in-place on reformatted frames */ + mp3DecInfo->mainDataBytes = mp3DecInfo->nSlots; + mainPtr = *inbuf; + *inbuf += mp3DecInfo->nSlots; + *bytesLeft -= (mp3DecInfo->nSlots); + } else { + /* out of data - assume last or truncated frame */ + if (mp3DecInfo->nSlots > *bytesLeft) { + MP3ClearBadFrame(mp3DecInfo, outbuf); + return ERR_MP3_INDATA_UNDERFLOW; + } + +#ifdef PROFILE + time = systime_get(); +#endif + /* fill main data buffer with enough new data for this frame */ + if (mp3DecInfo->mainDataBytes >= mp3DecInfo->mainDataBegin) { + /* adequate "old" main data available (i.e. bit reservoir) */ + memmove(mp3DecInfo->mainBuf, mp3DecInfo->mainBuf + mp3DecInfo->mainDataBytes - mp3DecInfo->mainDataBegin, mp3DecInfo->mainDataBegin); + memcpy(mp3DecInfo->mainBuf + mp3DecInfo->mainDataBegin, *inbuf, mp3DecInfo->nSlots); + + mp3DecInfo->mainDataBytes = mp3DecInfo->mainDataBegin + mp3DecInfo->nSlots; + *inbuf += mp3DecInfo->nSlots; + *bytesLeft -= (mp3DecInfo->nSlots); + mainPtr = mp3DecInfo->mainBuf; + } else { + /* not enough data in bit reservoir from previous frames (perhaps starting in middle of file) */ + memcpy(mp3DecInfo->mainBuf + mp3DecInfo->mainDataBytes, *inbuf, mp3DecInfo->nSlots); + mp3DecInfo->mainDataBytes += mp3DecInfo->nSlots; + *inbuf += mp3DecInfo->nSlots; + *bytesLeft -= (mp3DecInfo->nSlots); + MP3ClearBadFrame(mp3DecInfo, outbuf); + return ERR_MP3_MAINDATA_UNDERFLOW; + } +#ifdef PROFILE + time = systime_get() - time; + printf("data buffer filling: %i ms\n", time); +#endif + + } + bitOffset = 0; + mainBits = mp3DecInfo->mainDataBytes * 8; + + /* decode one complete frame */ + for (gr = 0; gr < mp3DecInfo->nGrans; gr++) { + for (ch = 0; ch < mp3DecInfo->nChans; ch++) { + +#ifdef PROFILE + time = systime_get(); +#endif + /* unpack scale factors and compute size of scale factor block */ + prevBitOffset = bitOffset; + offset = UnpackScaleFactors(mp3DecInfo, mainPtr, &bitOffset, mainBits, gr, ch); +#ifdef PROFILE + time = systime_get() - time; + printf("UnpackScaleFactors: %i ms\n", time); +#endif + + sfBlockBits = 8 * offset - prevBitOffset + bitOffset; + huffBlockBits = mp3DecInfo->part23Length[gr][ch] - sfBlockBits; + mainPtr += offset; + mainBits -= sfBlockBits; + + if (offset < 0 || mainBits < huffBlockBits) { + MP3ClearBadFrame(mp3DecInfo, outbuf); + return ERR_MP3_INVALID_SCALEFACT; + } + +#ifdef PROFILE + time = systime_get(); +#endif + /* decode Huffman code words */ + prevBitOffset = bitOffset; + offset = DecodeHuffman(mp3DecInfo, mainPtr, &bitOffset, huffBlockBits, gr, ch); + if (offset < 0) { + MP3ClearBadFrame(mp3DecInfo, outbuf); + return ERR_MP3_INVALID_HUFFCODES; + } +#ifdef PROFILE + time = systime_get() - time; + printf("Huffman: %i ms\n", time); +#endif + + mainPtr += offset; + mainBits -= (8 * offset - prevBitOffset + bitOffset); + } + +#ifdef PROFILE + time = systime_get(); +#endif + /* dequantize coefficients, decode stereo, reorder short blocks */ + if (Dequantize(mp3DecInfo, gr) < 0) { + MP3ClearBadFrame(mp3DecInfo, outbuf); + return ERR_MP3_INVALID_DEQUANTIZE; + } +#ifdef PROFILE + time = systime_get() - time; + printf("Dequantize: %i ms\n", time); +#endif + + /* alias reduction, inverse MDCT, overlap-add, frequency inversion */ + for (ch = 0; ch < mp3DecInfo->nChans; ch++) { #ifdef PROFILE - time = systime_get(); + time = systime_get(); #endif - /* unpack side info */ - siBytes = UnpackSideInfo(mp3DecInfo, *inbuf); - if (siBytes < 0) { - MP3ClearBadFrame(mp3DecInfo, outbuf); - return ERR_MP3_INVALID_SIDEINFO; - } - *inbuf += siBytes; - *bytesLeft -= (fhBytes + siBytes); + if (IMDCT(mp3DecInfo, gr, ch) < 0) { + MP3ClearBadFrame(mp3DecInfo, outbuf); + return ERR_MP3_INVALID_IMDCT; + } #ifdef PROFILE - time = systime_get() - time; - printf("UnpackSideInfo: %i ms\n", time); + time = systime_get() - time; + printf("IMDCT: %i ms\n", time); #endif - - - /* if free mode, need to calculate bitrate and nSlots manually, based on frame size */ - if (mp3DecInfo->bitrate == 0 || mp3DecInfo->freeBitrateFlag) { - if (!mp3DecInfo->freeBitrateFlag) { - /* first time through, need to scan for next sync word and figure out frame size */ - mp3DecInfo->freeBitrateFlag = 1; - mp3DecInfo->freeBitrateSlots = MP3FindFreeSync(*inbuf, *inbuf - fhBytes - siBytes, *bytesLeft); - if (mp3DecInfo->freeBitrateSlots < 0) { - MP3ClearBadFrame(mp3DecInfo, outbuf); - return ERR_MP3_FREE_BITRATE_SYNC; - } - freeFrameBytes = mp3DecInfo->freeBitrateSlots + fhBytes + siBytes; - mp3DecInfo->bitrate = (freeFrameBytes * mp3DecInfo->samprate * 8) / (mp3DecInfo->nGrans * mp3DecInfo->nGranSamps); - } - mp3DecInfo->nSlots = mp3DecInfo->freeBitrateSlots + CheckPadBit(mp3DecInfo); /* add pad byte, if required */ - } - - /* useSize != 0 means we're getting reformatted (RTP) packets (see RFC 3119) - * - calling function assembles "self-contained" MP3 frames by shifting any main_data - * from the bit reservoir (in previous frames) to AFTER the sync word and side info - * - calling function should set mainDataBegin to 0, and tell us exactly how large this - * frame is (in bytesLeft) - */ - if (useSize) { - mp3DecInfo->nSlots = *bytesLeft; - if (mp3DecInfo->mainDataBegin != 0 || mp3DecInfo->nSlots <= 0) { - /* error - non self-contained frame, or missing frame (size <= 0), could do loss concealment here */ - MP3ClearBadFrame(mp3DecInfo, outbuf); - return ERR_MP3_INVALID_FRAMEHEADER; - } - - /* can operate in-place on reformatted frames */ - mp3DecInfo->mainDataBytes = mp3DecInfo->nSlots; - mainPtr = *inbuf; - *inbuf += mp3DecInfo->nSlots; - *bytesLeft -= (mp3DecInfo->nSlots); - } else { - /* out of data - assume last or truncated frame */ - if (mp3DecInfo->nSlots > *bytesLeft) { - MP3ClearBadFrame(mp3DecInfo, outbuf); - return ERR_MP3_INDATA_UNDERFLOW; - } + } #ifdef PROFILE - time = systime_get(); + time = systime_get(); #endif - /* fill main data buffer with enough new data for this frame */ - if (mp3DecInfo->mainDataBytes >= mp3DecInfo->mainDataBegin) { - /* adequate "old" main data available (i.e. bit reservoir) */ - memmove(mp3DecInfo->mainBuf, mp3DecInfo->mainBuf + mp3DecInfo->mainDataBytes - mp3DecInfo->mainDataBegin, mp3DecInfo->mainDataBegin); - memcpy(mp3DecInfo->mainBuf + mp3DecInfo->mainDataBegin, *inbuf, mp3DecInfo->nSlots); - - mp3DecInfo->mainDataBytes = mp3DecInfo->mainDataBegin + mp3DecInfo->nSlots; - *inbuf += mp3DecInfo->nSlots; - *bytesLeft -= (mp3DecInfo->nSlots); - mainPtr = mp3DecInfo->mainBuf; - } else { - /* not enough data in bit reservoir from previous frames (perhaps starting in middle of file) */ - memcpy(mp3DecInfo->mainBuf + mp3DecInfo->mainDataBytes, *inbuf, mp3DecInfo->nSlots); - mp3DecInfo->mainDataBytes += mp3DecInfo->nSlots; - *inbuf += mp3DecInfo->nSlots; - *bytesLeft -= (mp3DecInfo->nSlots); - MP3ClearBadFrame(mp3DecInfo, outbuf); - return ERR_MP3_MAINDATA_UNDERFLOW; - } + /* subband transform - if stereo, interleaves pcm LRLRLR */ + if (Subband(mp3DecInfo, outbuf + gr * mp3DecInfo->nGranSamps * mp3DecInfo->nChans) < 0) { + MP3ClearBadFrame(mp3DecInfo, outbuf); + return ERR_MP3_INVALID_SUBBAND; + } #ifdef PROFILE - time = systime_get() - time; - printf("data buffer filling: %i ms\n", time); + time = systime_get() - time; + printf("Subband: %i ms\n", time); #endif - } - bitOffset = 0; - mainBits = mp3DecInfo->mainDataBytes * 8; - - /* decode one complete frame */ - for (gr = 0; gr < mp3DecInfo->nGrans; gr++) { - for (ch = 0; ch < mp3DecInfo->nChans; ch++) { - - #ifdef PROFILE - time = systime_get(); - #endif - /* unpack scale factors and compute size of scale factor block */ - prevBitOffset = bitOffset; - offset = UnpackScaleFactors(mp3DecInfo, mainPtr, &bitOffset, mainBits, gr, ch); - #ifdef PROFILE - time = systime_get() - time; - printf("UnpackScaleFactors: %i ms\n", time); - #endif - - sfBlockBits = 8*offset - prevBitOffset + bitOffset; - huffBlockBits = mp3DecInfo->part23Length[gr][ch] - sfBlockBits; - mainPtr += offset; - mainBits -= sfBlockBits; - - if (offset < 0 || mainBits < huffBlockBits) { - MP3ClearBadFrame(mp3DecInfo, outbuf); - return ERR_MP3_INVALID_SCALEFACT; - } - - #ifdef PROFILE - time = systime_get(); - #endif - /* decode Huffman code words */ - prevBitOffset = bitOffset; - offset = DecodeHuffman(mp3DecInfo, mainPtr, &bitOffset, huffBlockBits, gr, ch); - if (offset < 0) { - MP3ClearBadFrame(mp3DecInfo, outbuf); - return ERR_MP3_INVALID_HUFFCODES; - } - #ifdef PROFILE - time = systime_get() - time; - printf("Huffman: %i ms\n", time); - #endif - - mainPtr += offset; - mainBits -= (8*offset - prevBitOffset + bitOffset); - } - - #ifdef PROFILE - time = systime_get(); - #endif - /* dequantize coefficients, decode stereo, reorder short blocks */ - if (Dequantize(mp3DecInfo, gr) < 0) { - MP3ClearBadFrame(mp3DecInfo, outbuf); - return ERR_MP3_INVALID_DEQUANTIZE; - } - #ifdef PROFILE - time = systime_get() - time; - printf("Dequantize: %i ms\n", time); - #endif - - /* alias reduction, inverse MDCT, overlap-add, frequency inversion */ - for (ch = 0; ch < mp3DecInfo->nChans; ch++) - { - #ifdef PROFILE - time = systime_get(); - #endif - if (IMDCT(mp3DecInfo, gr, ch) < 0) { - MP3ClearBadFrame(mp3DecInfo, outbuf); - return ERR_MP3_INVALID_IMDCT; - } - #ifdef PROFILE - time = systime_get() - time; - printf("IMDCT: %i ms\n", time); - #endif - } - - #ifdef PROFILE - time = systime_get(); - #endif - /* subband transform - if stereo, interleaves pcm LRLRLR */ - if (Subband(mp3DecInfo, outbuf + gr*mp3DecInfo->nGranSamps*mp3DecInfo->nChans) < 0) { - MP3ClearBadFrame(mp3DecInfo, outbuf); - return ERR_MP3_INVALID_SUBBAND; - } - #ifdef PROFILE - time = systime_get() - time; - printf("Subband: %i ms\n", time); - #endif - - } - return ERR_MP3_NONE; + } + return ERR_MP3_NONE; } diff --git a/src/libhelix-mp3/mp3dec.h b/src/libhelix-mp3/mp3dec.h index 04c4b653..98b30423 100644 --- a/src/libhelix-mp3/mp3dec.h +++ b/src/libhelix-mp3/mp3dec.h @@ -1,49 +1,49 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * mp3dec.h - public C API for MP3 decoder + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + mp3dec.h - public C API for MP3 decoder **************************************************************************************/ #include #define Word64 uint64_t - + #ifndef _MP3DEC_H #define _MP3DEC_H @@ -72,11 +72,11 @@ extern "C" { #endif -/* determining MAINBUF_SIZE: - * max mainDataBegin = (2^9 - 1) bytes (since 9-bit offset) = 511 - * max nSlots (concatenated with mainDataBegin bytes from before) = 1440 - 9 - 4 + 1 = 1428 - * 511 + 1428 = 1939, round up to 1940 (4-byte align) - */ +/* determining MAINBUF_SIZE: + max mainDataBegin = (2^9 - 1) bytes (since 9-bit offset) = 511 + max nSlots (concatenated with mainDataBegin bytes from before) = 1440 - 9 - 4 + 1 = 1428 + 511 + 1428 = 1939, round up to 1940 (4-byte align) +*/ #define MAINBUF_SIZE 1940 #define MAX_NGRAN 2 /* max granules */ @@ -85,39 +85,39 @@ extern "C" { /* map to 0,1,2 to make table indexing easier */ typedef enum { - MPEG1 = 0, - MPEG2 = 1, - MPEG25 = 2 + MPEG1 = 0, + MPEG2 = 1, + MPEG25 = 2 } MPEGVersion; typedef void *HMP3Decoder; enum { - ERR_MP3_NONE = 0, - ERR_MP3_INDATA_UNDERFLOW = -1, - ERR_MP3_MAINDATA_UNDERFLOW = -2, - ERR_MP3_FREE_BITRATE_SYNC = -3, - ERR_MP3_OUT_OF_MEMORY = -4, - ERR_MP3_NULL_POINTER = -5, - ERR_MP3_INVALID_FRAMEHEADER = -6, - ERR_MP3_INVALID_SIDEINFO = -7, - ERR_MP3_INVALID_SCALEFACT = -8, - ERR_MP3_INVALID_HUFFCODES = -9, - ERR_MP3_INVALID_DEQUANTIZE = -10, - ERR_MP3_INVALID_IMDCT = -11, - ERR_MP3_INVALID_SUBBAND = -12, - - ERR_UNKNOWN = -9999 + ERR_MP3_NONE = 0, + ERR_MP3_INDATA_UNDERFLOW = -1, + ERR_MP3_MAINDATA_UNDERFLOW = -2, + ERR_MP3_FREE_BITRATE_SYNC = -3, + ERR_MP3_OUT_OF_MEMORY = -4, + ERR_MP3_NULL_POINTER = -5, + ERR_MP3_INVALID_FRAMEHEADER = -6, + ERR_MP3_INVALID_SIDEINFO = -7, + ERR_MP3_INVALID_SCALEFACT = -8, + ERR_MP3_INVALID_HUFFCODES = -9, + ERR_MP3_INVALID_DEQUANTIZE = -10, + ERR_MP3_INVALID_IMDCT = -11, + ERR_MP3_INVALID_SUBBAND = -12, + + ERR_UNKNOWN = -9999 }; typedef struct _MP3FrameInfo { - int bitrate; - int nChans; - int samprate; - int bitsPerSample; - int outputSamps; - int layer; - int version; + int bitrate; + int nChans; + int samprate; + int bitsPerSample; + int outputSamps; + int layer; + int version; } MP3FrameInfo; /* public API */ diff --git a/src/libhelix-mp3/mp3tabs.c b/src/libhelix-mp3/mp3tabs.c index 7d5fec22..5da48baf 100644 --- a/src/libhelix-mp3/mp3tabs.c +++ b/src/libhelix-mp3/mp3tabs.c @@ -1,182 +1,182 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * mp3tabs.c - platform-independent tables for MP3 decoder (global, read-only) + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + mp3tabs.c - platform-independent tables for MP3 decoder (global, read-only) **************************************************************************************/ #include "mp3common.h" #include -/* indexing = [version][samplerate index] - * sample rate of frame (Hz) - */ +/* indexing = [version][samplerate index] + sample rate of frame (Hz) +*/ const int samplerateTab[3][3] PROGMEM = { - {44100, 48000, 32000}, /* MPEG-1 */ - {22050, 24000, 16000}, /* MPEG-2 */ - {11025, 12000, 8000}, /* MPEG-2.5 */ + {44100, 48000, 32000}, /* MPEG-1 */ + {22050, 24000, 16000}, /* MPEG-2 */ + {11025, 12000, 8000}, /* MPEG-2.5 */ }; -/* indexing = [version][layer][bitrate index] - * bitrate (kbps) of frame - * - bitrate index == 0 is "free" mode (bitrate determined on the fly by - * counting bits between successive sync words) - */ +/* indexing = [version][layer][bitrate index] + bitrate (kbps) of frame + - bitrate index == 0 is "free" mode (bitrate determined on the fly by + counting bits between successive sync words) +*/ const int/*short*/ bitrateTab[3][3][15] PROGMEM = { - { - /* MPEG-1 */ - { 0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448}, /* Layer 1 */ - { 0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384}, /* Layer 2 */ - { 0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320}, /* Layer 3 */ - }, - { - /* MPEG-2 */ - { 0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256}, /* Layer 1 */ - { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160}, /* Layer 2 */ - { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160}, /* Layer 3 */ - }, - { - /* MPEG-2.5 */ - { 0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256}, /* Layer 1 */ - { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160}, /* Layer 2 */ - { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160}, /* Layer 3 */ - }, + { + /* MPEG-1 */ + { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448}, /* Layer 1 */ + { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384}, /* Layer 2 */ + { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320}, /* Layer 3 */ + }, + { + /* MPEG-2 */ + { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, /* Layer 1 */ + { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 2 */ + { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 3 */ + }, + { + /* MPEG-2.5 */ + { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, /* Layer 1 */ + { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 2 */ + { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 3 */ + }, }; -/* indexing = [version][layer] - * number of samples in one frame (per channel) - */ +/* indexing = [version][layer] + number of samples in one frame (per channel) +*/ const int/*short*/ samplesPerFrameTab[3][3] PROGMEM = { - {384, 1152, 1152 }, /* MPEG1 */ - {384, 1152, 576 }, /* MPEG2 */ - {384, 1152, 576 }, /* MPEG2.5 */ + {384, 1152, 1152 }, /* MPEG1 */ + {384, 1152, 576 }, /* MPEG2 */ + {384, 1152, 576 }, /* MPEG2.5 */ }; /* layers 1, 2, 3 */ const short bitsPerSlotTab[3] = {32, 8, 8}; -/* indexing = [version][mono/stereo] - * number of bytes in side info section of bitstream - */ +/* indexing = [version][mono/stereo] + number of bytes in side info section of bitstream +*/ const int/*short*/ sideBytesTab[3][2] PROGMEM = { - {17, 32}, /* MPEG-1: mono, stereo */ - { 9, 17}, /* MPEG-2: mono, stereo */ - { 9, 17}, /* MPEG-2.5: mono, stereo */ + {17, 32}, /* MPEG-1: mono, stereo */ + { 9, 17}, /* MPEG-2: mono, stereo */ + { 9, 17}, /* MPEG-2.5: mono, stereo */ }; -/* indexing = [version][sampleRate][bitRate] - * for layer3, nSlots = floor(samps/frame * bitRate / sampleRate / 8) - * - add one pad slot if necessary - */ +/* indexing = [version][sampleRate][bitRate] + for layer3, nSlots = floor(samps/frame * bitRate / sampleRate / 8) + - add one pad slot if necessary +*/ const int/*short*/ slotTab[3][3][15] PROGMEM = { - { - /* MPEG-1 */ - { 0, 104, 130, 156, 182, 208, 261, 313, 365, 417, 522, 626, 731, 835,1044 }, /* 44 kHz */ - { 0, 96, 120, 144, 168, 192, 240, 288, 336, 384, 480, 576, 672, 768, 960 }, /* 48 kHz */ - { 0, 144, 180, 216, 252, 288, 360, 432, 504, 576, 720, 864,1008,1152,1440 }, /* 32 kHz */ - }, - { - /* MPEG-2 */ - { 0, 26, 52, 78, 104, 130, 156, 182, 208, 261, 313, 365, 417, 470, 522 }, /* 22 kHz */ - { 0, 24, 48, 72, 96, 120, 144, 168, 192, 240, 288, 336, 384, 432, 480 }, /* 24 kHz */ - { 0, 36, 72, 108, 144, 180, 216, 252, 288, 360, 432, 504, 576, 648, 720 }, /* 16 kHz */ - }, - { - /* MPEG-2.5 */ - { 0, 52, 104, 156, 208, 261, 313, 365, 417, 522, 626, 731, 835, 940,1044 }, /* 11 kHz */ - { 0, 48, 96, 144, 192, 240, 288, 336, 384, 480, 576, 672, 768, 864, 960 }, /* 12 kHz */ - { 0, 72, 144, 216, 288, 360, 432, 504, 576, 720, 864,1008,1152,1296,1440 }, /* 8 kHz */ - }, + { + /* MPEG-1 */ + { 0, 104, 130, 156, 182, 208, 261, 313, 365, 417, 522, 626, 731, 835, 1044 }, /* 44 kHz */ + { 0, 96, 120, 144, 168, 192, 240, 288, 336, 384, 480, 576, 672, 768, 960 }, /* 48 kHz */ + { 0, 144, 180, 216, 252, 288, 360, 432, 504, 576, 720, 864, 1008, 1152, 1440 }, /* 32 kHz */ + }, + { + /* MPEG-2 */ + { 0, 26, 52, 78, 104, 130, 156, 182, 208, 261, 313, 365, 417, 470, 522 }, /* 22 kHz */ + { 0, 24, 48, 72, 96, 120, 144, 168, 192, 240, 288, 336, 384, 432, 480 }, /* 24 kHz */ + { 0, 36, 72, 108, 144, 180, 216, 252, 288, 360, 432, 504, 576, 648, 720 }, /* 16 kHz */ + }, + { + /* MPEG-2.5 */ + { 0, 52, 104, 156, 208, 261, 313, 365, 417, 522, 626, 731, 835, 940, 1044 }, /* 11 kHz */ + { 0, 48, 96, 144, 192, 240, 288, 336, 384, 480, 576, 672, 768, 864, 960 }, /* 12 kHz */ + { 0, 72, 144, 216, 288, 360, 432, 504, 576, 720, 864, 1008, 1152, 1296, 1440 }, /* 8 kHz */ + }, }; -/* indexing = [version][sampleRate][long (.l) or short (.s) block] - * sfBandTable[v][s].l[cb] = index of first bin in critical band cb (long blocks) - * sfBandTable[v][s].s[cb] = index of first bin in critical band cb (short blocks) - */ +/* indexing = [version][sampleRate][long (.l) or short (.s) block] + sfBandTable[v][s].l[cb] = index of first bin in critical band cb (long blocks) + sfBandTable[v][s].s[cb] = index of first bin in critical band cb (short blocks) +*/ const SFBandTable sfBandTable[3][3] PROGMEM = { - { - /* MPEG-1 (44, 48, 32 kHz) */ - { - { 0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90,110,134,162,196,238,288,342,418,576 }, - { 0, 4, 8, 12, 16, 22, 30, 40, 52, 66, 84,106,136,192 } - }, - { - { 0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60, 72, 88,106,128,156,190,230,276,330,384,576 }, - { 0, 4, 8, 12, 16, 22, 28, 38, 50, 64, 80,100,126,192 } - }, - { - { 0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66, 82,102,126,156,194,240,296,364,448,550,576 }, - { 0, 4, 8, 12, 16, 22, 30, 42, 58, 78,104,138,180,192 } - } - }, - - { - /* MPEG-2 (22, 24, 16 kHz) */ - { - { 0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96,116,140,168,200,238,284,336,396,464,522,576 }, - { 0, 4, 8, 12, 18, 24, 32, 42, 56, 74,100,132,174,192 } - }, - { - { 0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96,114,136,162,194,232,278,332,394,464,540,576 }, - { 0, 4, 8, 12, 18, 26, 36, 48, 62, 80,104,136,180,192 } - }, - { - { 0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96,116,140,168,200,238,284,336,396,464,522,576 }, - { 0, 4, 8, 12, 18, 26, 36, 48, 62, 80,104,134,174,192 } - }, - }, - - { - /* MPEG-2.5 (11, 12, 8 kHz) */ - { - { 0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96,116,140,168,200,238,284,336,396,464,522,576 }, - { 0, 4, 8, 12, 18, 26, 36, 48, 62, 80,104,134,174,192 } - }, - { - { 0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96,116,140,168,200,238,284,336,396,464,522,576 }, - { 0, 4, 8, 12, 18, 26, 36, 48, 62, 80,104,134,174,192 } - }, - { - { 0, 12, 24, 36, 48, 60, 72, 88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576 }, - { 0, 8, 16, 24, 36, 52, 72, 96,124,160,162,164,166,192 } - }, - }, + { + /* MPEG-1 (44, 48, 32 kHz) */ + { + { 0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342, 418, 576 }, + { 0, 4, 8, 12, 16, 22, 30, 40, 52, 66, 84, 106, 136, 192 } + }, + { + { 0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60, 72, 88, 106, 128, 156, 190, 230, 276, 330, 384, 576 }, + { 0, 4, 8, 12, 16, 22, 28, 38, 50, 64, 80, 100, 126, 192 } + }, + { + { 0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66, 82, 102, 126, 156, 194, 240, 296, 364, 448, 550, 576 }, + { 0, 4, 8, 12, 16, 22, 30, 42, 58, 78, 104, 138, 180, 192 } + } + }, + + { + /* MPEG-2 (22, 24, 16 kHz) */ + { + { 0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576 }, + { 0, 4, 8, 12, 18, 24, 32, 42, 56, 74, 100, 132, 174, 192 } + }, + { + { 0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 114, 136, 162, 194, 232, 278, 332, 394, 464, 540, 576 }, + { 0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 136, 180, 192 } + }, + { + { 0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576 }, + { 0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192 } + }, + }, + + { + /* MPEG-2.5 (11, 12, 8 kHz) */ + { + { 0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576 }, + { 0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192 } + }, + { + { 0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576 }, + { 0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192 } + }, + { + { 0, 12, 24, 36, 48, 60, 72, 88, 108, 132, 160, 192, 232, 280, 336, 400, 476, 566, 568, 570, 572, 574, 576 }, + { 0, 8, 16, 24, 36, 52, 72, 96, 124, 160, 162, 164, 166, 192 } + }, + }, }; diff --git a/src/libhelix-mp3/mpadecobjfixpt.h b/src/libhelix-mp3/mpadecobjfixpt.h index a8a5c40f..904c983f 100644 --- a/src/libhelix-mp3/mpadecobjfixpt.h +++ b/src/libhelix-mp3/mpadecobjfixpt.h @@ -1,45 +1,44 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ #ifndef _MPADECOBJFIXPT_H_ #define _MPADECOBJFIXPT_H_ #include "mp3dec.h" /* public C API for new MP3 decoder */ -class CMpaDecObj -{ +class CMpaDecObj { public: CMpaDecObj(); ~CMpaDecObj(); @@ -59,7 +58,7 @@ class CMpaDecObj /////////////////////////////////////////////////////////////////////////// int Init_n(unsigned char *pSync, unsigned long ulSize, - unsigned char bUseSize=0); + unsigned char bUseSize = 0); /////////////////////////////////////////////////////////////////////////// // Function: DecodeFrame_v @@ -70,39 +69,41 @@ class CMpaDecObj // return. // pPCM pointer to a buffer to decode into // pulPCMSize size of the PCM buffer. It will contain the - // number of PCM bytes prodced upon return. + // number of PCM bytes produced upon return. /////////////////////////////////////////////////////////////////////////// void DecodeFrame_v(unsigned char *pSource, - unsigned long *pulSize, - unsigned char *pPCM, - unsigned long *pulPCMSize); + unsigned long *pulSize, + unsigned char *pPCM, + unsigned long *pulPCMSize); - // overloaded new version that returns error code in errCode + // overloaded new version that returns error code in errCode void DecodeFrame_v(unsigned char *pSource, - unsigned long *pulSize, - unsigned char *pPCM, - unsigned long *pulPCMSize, - int *errCode); + unsigned long *pulSize, + unsigned char *pPCM, + unsigned long *pulPCMSize, + int *errCode); void GetPCMInfo_v(unsigned long &ulSampRate, int &nChannels, int &nBitsPerSample); - // return number of samples per frame, PER CHANNEL (renderer multiplies this result by nChannels) + // return number of samples per frame, PER CHANNEL (renderer multiplies this result by nChannels) int GetSamplesPerFrame_n(); - void SetTrustPackets(unsigned char bTrust) { m_bTrustPackets = bTrust; } + void SetTrustPackets(unsigned char bTrust) { + m_bTrustPackets = bTrust; + } private: - void * m_pDec; // generic void ptr + void * m_pDec; // generic void ptr - void * m_pDecL1; // not implemented (could use old Xing mpadecl1.cpp) - void * m_pDecL2; // not implemented (could use old Xing mpadecl2.cpp) - HMP3Decoder m_pDecL3; + void * m_pDecL1; // not implemented (could use old Xing mpadecl1.cpp) + void * m_pDecL2; // not implemented (could use old Xing mpadecl2.cpp) + HMP3Decoder m_pDecL3; - MP3FrameInfo m_lastMP3FrameInfo; - unsigned char m_bUseFrameSize; - unsigned char m_bTrustPackets; + MP3FrameInfo m_lastMP3FrameInfo; + unsigned char m_bUseFrameSize; + unsigned char m_bTrustPackets; }; #endif /* _MPADECOBJFIXPT_H_ */ diff --git a/src/libhelix-mp3/polyphase.c b/src/libhelix-mp3/polyphase.c index bd331dfe..df944ed2 100644 --- a/src/libhelix-mp3/polyphase.c +++ b/src/libhelix-mp3/polyphase.c @@ -1,74 +1,74 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * polyphase.c - final stage of subband transform (polyphase synthesis filter) - * - * This is the C reference version using __int64 - * Look in the appropriate subdirectories for optimized asm implementations - * (e.g. arm/asmpoly.s) + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + polyphase.c - final stage of subband transform (polyphase synthesis filter) + + This is the C reference version using __int64 + Look in the appropriate subdirectories for optimized asm implementations + (e.g. arm/asmpoly.s) **************************************************************************************/ #include "coder.h" #include "assembly.h" -/* input to Polyphase = Q(DQ_FRACBITS_OUT-2), gain 2 bits in convolution - * we also have the implicit bias of 2^15 to add back, so net fraction bits = - * DQ_FRACBITS_OUT - 2 - 2 - 15 - * (see comment on Dequantize() for more info) - */ -#define DEF_NFRACBITS (DQ_FRACBITS_OUT - 2 - 2 - 15) -#define CSHIFT 12 /* coefficients have 12 leading sign bits for early-terminating mulitplies */ - -static __inline short ClipToShort(int x, int fracBits) -{ - int sign; - - /* assumes you've already rounded (x += (1 << (fracBits-1))) */ - x >>= fracBits; - - /* Ken's trick: clips to [-32768, 32767] */ - sign = x >> 31; - if (sign != (x >> 15)) - x = sign ^ ((1 << 15) - 1); - - return (short)x; +/* input to Polyphase = Q(DQ_FRACBITS_OUT-2), gain 2 bits in convolution + we also have the implicit bias of 2^15 to add back, so net fraction bits = + DQ_FRACBITS_OUT - 2 - 2 - 15 + (see comment on Dequantize() for more info) +*/ +#define DEF_NFRACBITS (DQ_FRACBITS_OUT - 2 - 2 - 15) +#define CSHIFT 12 /* coefficients have 12 leading sign bits for early-terminating multiplies */ + +static __inline short ClipToShort(int x, int fracBits) { + int sign; + + /* assumes you've already rounded (x += (1 << (fracBits-1))) */ + x >>= fracBits; + + /* Ken's trick: clips to [-32768, 32767] */ + sign = x >> 31; + if (sign != (x >> 15)) { + x = sign ^ ((1 << 15) - 1); + } + + return (short)x; } #define MC0M(x) { \ @@ -91,89 +91,88 @@ static __inline short ClipToShort(int x, int fracBits) } /************************************************************************************** - * Function: PolyphaseMono - * - * Description: filter one subband and produce 32 output PCM samples for one channel - * - * Inputs: pointer to PCM output buffer - * number of "extra shifts" (vbuf format = Q(DQ_FRACBITS_OUT-2)) - * pointer to start of vbuf (preserved from last call) - * start of filter coefficient table (in proper, shuffled order) - * no minimum number of guard bits is required for input vbuf - * (see additional scaling comments below) - * - * Outputs: 32 samples of one channel of decoded PCM data, (i.e. Q16.0) - * - * Return: none - * - * TODO: add 32-bit version for platforms where 64-bit mul-acc is not supported - * (note max filter gain - see polyCoef[] comments) + Function: PolyphaseMono + + Description: filter one subband and produce 32 output PCM samples for one channel + + Inputs: pointer to PCM output buffer + number of "extra shifts" (vbuf format = Q(DQ_FRACBITS_OUT-2)) + pointer to start of vbuf (preserved from last call) + start of filter coefficient table (in proper, shuffled order) + no minimum number of guard bits is required for input vbuf + (see additional scaling comments below) + + Outputs: 32 samples of one channel of decoded PCM data, (i.e. Q16.0) + + Return: none + + TODO: add 32-bit version for platforms where 64-bit mul-acc is not supported + (note max filter gain - see polyCoef[] comments) **************************************************************************************/ -void PolyphaseMono(short *pcm, int *vbuf, const int *coefBase) -{ - int i; - const int *coef; - int *vb1; - int vLo, vHi, c1, c2; - Word64 sum1L, sum2L, rndVal; - - rndVal = (Word64)( 1 << (DEF_NFRACBITS - 1 + (32 - CSHIFT)) ); - - /* special case, output sample 0 */ - coef = coefBase; - vb1 = vbuf; - sum1L = rndVal; - - MC0M(0) - MC0M(1) - MC0M(2) - MC0M(3) - MC0M(4) - MC0M(5) - MC0M(6) - MC0M(7) - - *(pcm + 0) = ClipToShort((int)SAR64(sum1L, (32-CSHIFT)), DEF_NFRACBITS); - - /* special case, output sample 16 */ - coef = coefBase + 256; - vb1 = vbuf + 64*16; - sum1L = rndVal; - - MC1M(0) - MC1M(1) - MC1M(2) - MC1M(3) - MC1M(4) - MC1M(5) - MC1M(6) - MC1M(7) - - *(pcm + 16) = ClipToShort((int)SAR64(sum1L, (32-CSHIFT)), DEF_NFRACBITS); - - /* main convolution loop: sum1L = samples 1, 2, 3, ... 15 sum2L = samples 31, 30, ... 17 */ - coef = coefBase + 16; - vb1 = vbuf + 64; - pcm++; - - /* right now, the compiler creates bad asm from this... */ - for (i = 15; i > 0; i--) { - sum1L = sum2L = rndVal; - - MC2M(0) - MC2M(1) - MC2M(2) - MC2M(3) - MC2M(4) - MC2M(5) - MC2M(6) - MC2M(7) - - vb1 += 64; - *(pcm) = ClipToShort((int)SAR64(sum1L, (32-CSHIFT)), DEF_NFRACBITS); - *(pcm + 2*i) = ClipToShort((int)SAR64(sum2L, (32-CSHIFT)), DEF_NFRACBITS); - pcm++; - } +void PolyphaseMono(short *pcm, int *vbuf, const int *coefBase) { + int i; + const int *coef; + int *vb1; + int vLo, vHi, c1, c2; + Word64 sum1L, sum2L, rndVal; + + rndVal = (Word64)(1 << (DEF_NFRACBITS - 1 + (32 - CSHIFT))); + + /* special case, output sample 0 */ + coef = coefBase; + vb1 = vbuf; + sum1L = rndVal; + + MC0M(0) + MC0M(1) + MC0M(2) + MC0M(3) + MC0M(4) + MC0M(5) + MC0M(6) + MC0M(7) + + *(pcm + 0) = ClipToShort((int)SAR64(sum1L, (32 - CSHIFT)), DEF_NFRACBITS); + + /* special case, output sample 16 */ + coef = coefBase + 256; + vb1 = vbuf + 64 * 16; + sum1L = rndVal; + + MC1M(0) + MC1M(1) + MC1M(2) + MC1M(3) + MC1M(4) + MC1M(5) + MC1M(6) + MC1M(7) + + *(pcm + 16) = ClipToShort((int)SAR64(sum1L, (32 - CSHIFT)), DEF_NFRACBITS); + + /* main convolution loop: sum1L = samples 1, 2, 3, ... 15 sum2L = samples 31, 30, ... 17 */ + coef = coefBase + 16; + vb1 = vbuf + 64; + pcm++; + + /* right now, the compiler creates bad asm from this... */ + for (i = 15; i > 0; i--) { + sum1L = sum2L = rndVal; + + MC2M(0) + MC2M(1) + MC2M(2) + MC2M(3) + MC2M(4) + MC2M(5) + MC2M(6) + MC2M(7) + + vb1 += 64; + *(pcm) = ClipToShort((int)SAR64(sum1L, (32 - CSHIFT)), DEF_NFRACBITS); + *(pcm + 2 * i) = ClipToShort((int)SAR64(sum2L, (32 - CSHIFT)), DEF_NFRACBITS); + pcm++; + } } #define MC0S(x) { \ @@ -203,93 +202,92 @@ void PolyphaseMono(short *pcm, int *vbuf, const int *coefBase) } /************************************************************************************** - * Function: PolyphaseStereo - * - * Description: filter one subband and produce 32 output PCM samples for each channel - * - * Inputs: pointer to PCM output buffer - * number of "extra shifts" (vbuf format = Q(DQ_FRACBITS_OUT-2)) - * pointer to start of vbuf (preserved from last call) - * start of filter coefficient table (in proper, shuffled order) - * no minimum number of guard bits is required for input vbuf - * (see additional scaling comments below) - * - * Outputs: 32 samples of two channels of decoded PCM data, (i.e. Q16.0) - * - * Return: none - * - * Notes: interleaves PCM samples LRLRLR... - * - * TODO: add 32-bit version for platforms where 64-bit mul-acc is not supported + Function: PolyphaseStereo + + Description: filter one subband and produce 32 output PCM samples for each channel + + Inputs: pointer to PCM output buffer + number of "extra shifts" (vbuf format = Q(DQ_FRACBITS_OUT-2)) + pointer to start of vbuf (preserved from last call) + start of filter coefficient table (in proper, shuffled order) + no minimum number of guard bits is required for input vbuf + (see additional scaling comments below) + + Outputs: 32 samples of two channels of decoded PCM data, (i.e. Q16.0) + + Return: none + + Notes: interleaves PCM samples LRLRLR... + + TODO: add 32-bit version for platforms where 64-bit mul-acc is not supported **************************************************************************************/ -void PolyphaseStereo(short *pcm, int *vbuf, const int *coefBase) -{ - int i; - const int *coef; - int *vb1; - int vLo, vHi, c1, c2; - Word64 sum1L, sum2L, sum1R, sum2R, rndVal; - - rndVal = (Word64)( 1 << (DEF_NFRACBITS - 1 + (32 - CSHIFT)) ); - - /* special case, output sample 0 */ - coef = coefBase; - vb1 = vbuf; - sum1L = sum1R = rndVal; - - MC0S(0) - MC0S(1) - MC0S(2) - MC0S(3) - MC0S(4) - MC0S(5) - MC0S(6) - MC0S(7) - - *(pcm + 0) = ClipToShort((int)SAR64(sum1L, (32-CSHIFT)), DEF_NFRACBITS); - *(pcm + 1) = ClipToShort((int)SAR64(sum1R, (32-CSHIFT)), DEF_NFRACBITS); - - /* special case, output sample 16 */ - coef = coefBase + 256; - vb1 = vbuf + 64*16; - sum1L = sum1R = rndVal; - - MC1S(0) - MC1S(1) - MC1S(2) - MC1S(3) - MC1S(4) - MC1S(5) - MC1S(6) - MC1S(7) - - *(pcm + 2*16 + 0) = ClipToShort((int)SAR64(sum1L, (32-CSHIFT)), DEF_NFRACBITS); - *(pcm + 2*16 + 1) = ClipToShort((int)SAR64(sum1R, (32-CSHIFT)), DEF_NFRACBITS); - - /* main convolution loop: sum1L = samples 1, 2, 3, ... 15 sum2L = samples 31, 30, ... 17 */ - coef = coefBase + 16; - vb1 = vbuf + 64; - pcm += 2; - - /* right now, the compiler creates bad asm from this... */ - for (i = 15; i > 0; i--) { - sum1L = sum2L = rndVal; - sum1R = sum2R = rndVal; - - MC2S(0) - MC2S(1) - MC2S(2) - MC2S(3) - MC2S(4) - MC2S(5) - MC2S(6) - MC2S(7) - - vb1 += 64; - *(pcm + 0) = ClipToShort((int)SAR64(sum1L, (32-CSHIFT)), DEF_NFRACBITS); - *(pcm + 1) = ClipToShort((int)SAR64(sum1R, (32-CSHIFT)), DEF_NFRACBITS); - *(pcm + 2*2*i + 0) = ClipToShort((int)SAR64(sum2L, (32-CSHIFT)), DEF_NFRACBITS); - *(pcm + 2*2*i + 1) = ClipToShort((int)SAR64(sum2R, (32-CSHIFT)), DEF_NFRACBITS); - pcm += 2; - } +void PolyphaseStereo(short *pcm, int *vbuf, const int *coefBase) { + int i; + const int *coef; + int *vb1; + int vLo, vHi, c1, c2; + Word64 sum1L, sum2L, sum1R, sum2R, rndVal; + + rndVal = (Word64)(1 << (DEF_NFRACBITS - 1 + (32 - CSHIFT))); + + /* special case, output sample 0 */ + coef = coefBase; + vb1 = vbuf; + sum1L = sum1R = rndVal; + + MC0S(0) + MC0S(1) + MC0S(2) + MC0S(3) + MC0S(4) + MC0S(5) + MC0S(6) + MC0S(7) + + *(pcm + 0) = ClipToShort((int)SAR64(sum1L, (32 - CSHIFT)), DEF_NFRACBITS); + *(pcm + 1) = ClipToShort((int)SAR64(sum1R, (32 - CSHIFT)), DEF_NFRACBITS); + + /* special case, output sample 16 */ + coef = coefBase + 256; + vb1 = vbuf + 64 * 16; + sum1L = sum1R = rndVal; + + MC1S(0) + MC1S(1) + MC1S(2) + MC1S(3) + MC1S(4) + MC1S(5) + MC1S(6) + MC1S(7) + + *(pcm + 2 * 16 + 0) = ClipToShort((int)SAR64(sum1L, (32 - CSHIFT)), DEF_NFRACBITS); + *(pcm + 2 * 16 + 1) = ClipToShort((int)SAR64(sum1R, (32 - CSHIFT)), DEF_NFRACBITS); + + /* main convolution loop: sum1L = samples 1, 2, 3, ... 15 sum2L = samples 31, 30, ... 17 */ + coef = coefBase + 16; + vb1 = vbuf + 64; + pcm += 2; + + /* right now, the compiler creates bad asm from this... */ + for (i = 15; i > 0; i--) { + sum1L = sum2L = rndVal; + sum1R = sum2R = rndVal; + + MC2S(0) + MC2S(1) + MC2S(2) + MC2S(3) + MC2S(4) + MC2S(5) + MC2S(6) + MC2S(7) + + vb1 += 64; + *(pcm + 0) = ClipToShort((int)SAR64(sum1L, (32 - CSHIFT)), DEF_NFRACBITS); + *(pcm + 1) = ClipToShort((int)SAR64(sum1R, (32 - CSHIFT)), DEF_NFRACBITS); + *(pcm + 2 * 2 * i + 0) = ClipToShort((int)SAR64(sum2L, (32 - CSHIFT)), DEF_NFRACBITS); + *(pcm + 2 * 2 * i + 1) = ClipToShort((int)SAR64(sum2R, (32 - CSHIFT)), DEF_NFRACBITS); + pcm += 2; + } } diff --git a/src/libhelix-mp3/scalfact.c b/src/libhelix-mp3/scalfact.c index 4937e453..0d4e81b4 100644 --- a/src/libhelix-mp3/scalfact.c +++ b/src/libhelix-mp3/scalfact.c @@ -1,392 +1,409 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * scalfact.c - scalefactor unpacking functions + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + scalfact.c - scalefactor unpacking functions **************************************************************************************/ #include "coder.h" /* scale factor lengths (num bits) */ static const char SFLenTab[16][2] = { - {0, 0}, {0, 1}, - {0, 2}, {0, 3}, - {3, 0}, {1, 1}, - {1, 2}, {1, 3}, - {2, 1}, {2, 2}, - {2, 3}, {3, 1}, - {3, 2}, {3, 3}, - {4, 2}, {4, 3}, + {0, 0}, {0, 1}, + {0, 2}, {0, 3}, + {3, 0}, {1, 1}, + {1, 2}, {1, 3}, + {2, 1}, {2, 2}, + {2, 3}, {3, 1}, + {3, 2}, {3, 3}, + {4, 2}, {4, 3}, }; /************************************************************************************** - * Function: UnpackSFMPEG1 - * - * Description: unpack MPEG 1 scalefactors from bitstream - * - * Inputs: BitStreamInfo, SideInfoSub, ScaleFactorInfoSub structs for this - * granule/channel - * vector of scfsi flags from side info, length = 4 (MAX_SCFBD) - * index of current granule - * ScaleFactorInfoSub from granule 0 (for granule 1, if scfsi[i] is set, - * then we just replicate the scale factors from granule 0 in the - * i'th set of scalefactor bands) - * - * Outputs: updated BitStreamInfo struct - * scalefactors in sfis (short and/or long arrays, as appropriate) - * - * Return: none - * - * Notes: set order of short blocks to s[band][window] instead of s[window][band] - * so that we index through consectutive memory locations when unpacking - * (make sure dequantizer follows same convention) - * Illegal Intensity Position = 7 (always) for MPEG1 scale factors + Function: UnpackSFMPEG1 + + Description: unpack MPEG 1 scalefactors from bitstream + + Inputs: BitStreamInfo, SideInfoSub, ScaleFactorInfoSub structs for this + granule/channel + vector of scfsi flags from side info, length = 4 (MAX_SCFBD) + index of current granule + ScaleFactorInfoSub from granule 0 (for granule 1, if scfsi[i] is set, + then we just replicate the scale factors from granule 0 in the + i'th set of scalefactor bands) + + Outputs: updated BitStreamInfo struct + scalefactors in sfis (short and/or long arrays, as appropriate) + + Return: none + + Notes: set order of short blocks to s[band][window] instead of s[window][band] + so that we index through consecutive memory locations when unpacking + (make sure dequantizer follows same convention) + Illegal Intensity Position = 7 (always) for MPEG1 scale factors **************************************************************************************/ -static void UnpackSFMPEG1(BitStreamInfo *bsi, SideInfoSub *sis, ScaleFactorInfoSub *sfis, int *scfsi, int gr, ScaleFactorInfoSub *sfisGr0) -{ - int sfb; - int slen0, slen1; - - /* these can be 0, so make sure GetBits(bsi, 0) returns 0 (no >> 32 or anything) */ - slen0 = (int)SFLenTab[sis->sfCompress][0]; - slen1 = (int)SFLenTab[sis->sfCompress][1]; - - if (sis->blockType == 2) { - /* short block, type 2 (implies winSwitchFlag == 1) */ - if (sis->mixedBlock) { - /* do long block portion */ - for (sfb = 0; sfb < 8; sfb++) - sfis->l[sfb] = (char)GetBits(bsi, slen0); - sfb = 3; - } else { - /* all short blocks */ - sfb = 0; - } - - for ( ; sfb < 6; sfb++) { - sfis->s[sfb][0] = (char)GetBits(bsi, slen0); - sfis->s[sfb][1] = (char)GetBits(bsi, slen0); - sfis->s[sfb][2] = (char)GetBits(bsi, slen0); - } - - for ( ; sfb < 12; sfb++) { - sfis->s[sfb][0] = (char)GetBits(bsi, slen1); - sfis->s[sfb][1] = (char)GetBits(bsi, slen1); - sfis->s[sfb][2] = (char)GetBits(bsi, slen1); - } - - /* last sf band not transmitted */ - sfis->s[12][0] = sfis->s[12][1] = sfis->s[12][2] = 0; - } else { - /* long blocks, type 0, 1, or 3 */ - if(gr == 0) { - /* first granule */ - for (sfb = 0; sfb < 11; sfb++) - sfis->l[sfb] = (char)GetBits(bsi, slen0); - for (sfb = 11; sfb < 21; sfb++) - sfis->l[sfb] = (char)GetBits(bsi, slen1); - return; - } else { - /* second granule - * scfsi: 0 = different scalefactors for each granule, 1 = copy sf's from granule 0 into granule 1 - * for block type == 2, scfsi is always 0 - */ - sfb = 0; - if(scfsi[0]) for( ; sfb < 6 ; sfb++) sfis->l[sfb] = sfisGr0->l[sfb]; - else for( ; sfb < 6 ; sfb++) sfis->l[sfb] = (char)GetBits(bsi, slen0); - if(scfsi[1]) for( ; sfb <11 ; sfb++) sfis->l[sfb] = sfisGr0->l[sfb]; - else for( ; sfb <11 ; sfb++) sfis->l[sfb] = (char)GetBits(bsi, slen0); - if(scfsi[2]) for( ; sfb <16 ; sfb++) sfis->l[sfb] = sfisGr0->l[sfb]; - else for( ; sfb <16 ; sfb++) sfis->l[sfb] = (char)GetBits(bsi, slen1); - if(scfsi[3]) for( ; sfb <21 ; sfb++) sfis->l[sfb] = sfisGr0->l[sfb]; - else for( ; sfb <21 ; sfb++) sfis->l[sfb] = (char)GetBits(bsi, slen1); - } - /* last sf band not transmitted */ - sfis->l[21] = 0; - sfis->l[22] = 0; - } +static void UnpackSFMPEG1(BitStreamInfo *bsi, SideInfoSub *sis, ScaleFactorInfoSub *sfis, int *scfsi, int gr, ScaleFactorInfoSub *sfisGr0) { + int sfb; + int slen0, slen1; + + /* these can be 0, so make sure GetBits(bsi, 0) returns 0 (no >> 32 or anything) */ + slen0 = (int)SFLenTab[sis->sfCompress][0]; + slen1 = (int)SFLenTab[sis->sfCompress][1]; + + if (sis->blockType == 2) { + /* short block, type 2 (implies winSwitchFlag == 1) */ + if (sis->mixedBlock) { + /* do long block portion */ + for (sfb = 0; sfb < 8; sfb++) { + sfis->l[sfb] = (char)GetBits(bsi, slen0); + } + sfb = 3; + } else { + /* all short blocks */ + sfb = 0; + } + + for (; sfb < 6; sfb++) { + sfis->s[sfb][0] = (char)GetBits(bsi, slen0); + sfis->s[sfb][1] = (char)GetBits(bsi, slen0); + sfis->s[sfb][2] = (char)GetBits(bsi, slen0); + } + + for (; sfb < 12; sfb++) { + sfis->s[sfb][0] = (char)GetBits(bsi, slen1); + sfis->s[sfb][1] = (char)GetBits(bsi, slen1); + sfis->s[sfb][2] = (char)GetBits(bsi, slen1); + } + + /* last sf band not transmitted */ + sfis->s[12][0] = sfis->s[12][1] = sfis->s[12][2] = 0; + } else { + /* long blocks, type 0, 1, or 3 */ + if (gr == 0) { + /* first granule */ + for (sfb = 0; sfb < 11; sfb++) { + sfis->l[sfb] = (char)GetBits(bsi, slen0); + } + for (sfb = 11; sfb < 21; sfb++) { + sfis->l[sfb] = (char)GetBits(bsi, slen1); + } + return; + } else { + /* second granule + scfsi: 0 = different scalefactors for each granule, 1 = copy sf's from granule 0 into granule 1 + for block type == 2, scfsi is always 0 + */ + sfb = 0; + if (scfsi[0]) for (; sfb < 6 ; sfb++) { + sfis->l[sfb] = sfisGr0->l[sfb]; + } else for (; sfb < 6 ; sfb++) { + sfis->l[sfb] = (char)GetBits(bsi, slen0); + } + if (scfsi[1]) for (; sfb < 11 ; sfb++) { + sfis->l[sfb] = sfisGr0->l[sfb]; + } else for (; sfb < 11 ; sfb++) { + sfis->l[sfb] = (char)GetBits(bsi, slen0); + } + if (scfsi[2]) for (; sfb < 16 ; sfb++) { + sfis->l[sfb] = sfisGr0->l[sfb]; + } else for (; sfb < 16 ; sfb++) { + sfis->l[sfb] = (char)GetBits(bsi, slen1); + } + if (scfsi[3]) for (; sfb < 21 ; sfb++) { + sfis->l[sfb] = sfisGr0->l[sfb]; + } else for (; sfb < 21 ; sfb++) { + sfis->l[sfb] = (char)GetBits(bsi, slen1); + } + } + /* last sf band not transmitted */ + sfis->l[21] = 0; + sfis->l[22] = 0; + } } -/* NRTab[size + 3*is_right][block type][partition] - * block type index: 0 = (bt0,bt1,bt3), 1 = bt2 non-mixed, 2 = bt2 mixed - * partition: scale factor groups (sfb1 through sfb4) - * for block type = 2 (mixed or non-mixed) / by 3 is rolled into this table - * (for 3 short blocks per long block) - * see 2.4.3.2 in MPEG 2 (low sample rate) spec - * stuff rolled into this table: - * NRTab[x][1][y] --> (NRTab[x][1][y]) / 3 - * NRTab[x][2][>=1] --> (NRTab[x][2][>=1]) / 3 (first partition is long block) - */ +/* NRTab[size + 3*is_right][block type][partition] + block type index: 0 = (bt0,bt1,bt3), 1 = bt2 non-mixed, 2 = bt2 mixed + partition: scale factor groups (sfb1 through sfb4) + for block type = 2 (mixed or non-mixed) / by 3 is rolled into this table + (for 3 short blocks per long block) + see 2.4.3.2 in MPEG 2 (low sample rate) spec + stuff rolled into this table: + NRTab[x][1][y] --> (NRTab[x][1][y]) / 3 + NRTab[x][2][>=1] --> (NRTab[x][2][>=1]) / 3 (first partition is long block) +*/ static const char NRTab[6][3][4] = { - /* non-intensity stereo */ - { {6, 5, 5, 5}, - {3, 3, 3, 3}, /* includes / 3 */ - {6, 3, 3, 3}, /* includes / 3 except for first entry */ - }, - { {6, 5, 7, 3}, - {3, 3, 4, 2}, - {6, 3, 4, 2}, - }, - { {11, 10, 0, 0}, - {6, 6, 0, 0}, - {6, 3, 6, 0}, /* spec = [15,18,0,0], but 15 = 6L + 9S, so move 9/3=3 into col 1, 18/3=6 into col 2 and adj. slen[1,2] below */ - }, - /* intensity stereo, right chan */ - { {7, 7, 7, 0}, - {4, 4, 4, 0}, - {6, 5, 4, 0}, - }, - { {6, 6, 6, 3}, - {4, 3, 3, 2}, - {6, 4, 3, 2}, - }, - { {8, 8, 5, 0}, - {5, 4, 3, 0}, - {6, 6, 3, 0}, - } + /* non-intensity stereo */ + { {6, 5, 5, 5}, + {3, 3, 3, 3}, /* includes / 3 */ + {6, 3, 3, 3}, /* includes / 3 except for first entry */ + }, + { {6, 5, 7, 3}, + {3, 3, 4, 2}, + {6, 3, 4, 2}, + }, + { {11, 10, 0, 0}, + {6, 6, 0, 0}, + {6, 3, 6, 0}, /* spec = [15,18,0,0], but 15 = 6L + 9S, so move 9/3=3 into col 1, 18/3=6 into col 2 and adj. slen[1,2] below */ + }, + /* intensity stereo, right chan */ + { {7, 7, 7, 0}, + {4, 4, 4, 0}, + {6, 5, 4, 0}, + }, + { {6, 6, 6, 3}, + {4, 3, 3, 2}, + {6, 4, 3, 2}, + }, + { {8, 8, 5, 0}, + {5, 4, 3, 0}, + {6, 6, 3, 0}, + } }; /************************************************************************************** - * Function: UnpackSFMPEG2 - * - * Description: unpack MPEG 2 scalefactors from bitstream - * - * Inputs: BitStreamInfo, SideInfoSub, ScaleFactorInfoSub structs for this - * granule/channel - * index of current granule and channel - * ScaleFactorInfoSub from this granule - * modeExt field from frame header, to tell whether intensity stereo is on - * ScaleFactorJS struct for storing IIP info used in Dequant() - * - * Outputs: updated BitStreamInfo struct - * scalefactors in sfis (short and/or long arrays, as appropriate) - * updated intensityScale and preFlag flags - * - * Return: none - * - * Notes: Illegal Intensity Position = (2^slen) - 1 for MPEG2 scale factors - * - * TODO: optimize the / and % stuff (only do one divide, get modulo x - * with (x / m) * m, etc.) + Function: UnpackSFMPEG2 + + Description: unpack MPEG 2 scalefactors from bitstream + + Inputs: BitStreamInfo, SideInfoSub, ScaleFactorInfoSub structs for this + granule/channel + index of current granule and channel + ScaleFactorInfoSub from this granule + modeExt field from frame header, to tell whether intensity stereo is on + ScaleFactorJS struct for storing IIP info used in Dequant() + + Outputs: updated BitStreamInfo struct + scalefactors in sfis (short and/or long arrays, as appropriate) + updated intensityScale and preFlag flags + + Return: none + + Notes: Illegal Intensity Position = (2^slen) - 1 for MPEG2 scale factors + + TODO: optimize the / and % stuff (only do one divide, get modulo x + with (x / m) * m, etc.) **************************************************************************************/ -static void UnpackSFMPEG2(BitStreamInfo *bsi, SideInfoSub *sis, ScaleFactorInfoSub *sfis, int gr, int ch, int modeExt, ScaleFactorJS *sfjs) -{ - - int i, sfb, sfcIdx, btIdx, nrIdx;// iipTest; - int slen[4], nr[4]; - int sfCompress, preFlag, intensityScale; - (void)gr; - - sfCompress = sis->sfCompress; - preFlag = 0; - intensityScale = 0; - - /* stereo mode bits (1 = on): bit 1 = mid-side on/off, bit 0 = intensity on/off */ - if (! ((modeExt & 0x01) && (ch == 1)) ) { - /* in other words: if ((modeExt & 0x01) == 0 || ch == 0) */ - if (sfCompress < 400) { - /* max slen = floor[(399/16) / 5] = 4 */ - slen[0] = (sfCompress >> 4) / 5; - slen[1]= (sfCompress >> 4) % 5; - slen[2]= (sfCompress & 0x0f) >> 2; - slen[3]= (sfCompress & 0x03); - sfcIdx = 0; - } else if (sfCompress < 500) { - /* max slen = floor[(99/4) / 5] = 4 */ - sfCompress -= 400; - slen[0] = (sfCompress >> 2) / 5; - slen[1]= (sfCompress >> 2) % 5; - slen[2]= (sfCompress & 0x03); - slen[3]= 0; - sfcIdx = 1; - } else { - /* max slen = floor[11/3] = 3 (sfCompress = 9 bits in MPEG2) */ - sfCompress -= 500; - slen[0] = sfCompress / 3; - slen[1] = sfCompress % 3; - slen[2] = slen[3] = 0; - if (sis->mixedBlock) { - /* adjust for long/short mix logic (see comment above in NRTab[] definition) */ - slen[2] = slen[1]; - slen[1] = slen[0]; - } - preFlag = 1; - sfcIdx = 2; - } - } else { - /* intensity stereo ch = 1 (right) */ - intensityScale = sfCompress & 0x01; - sfCompress >>= 1; - if (sfCompress < 180) { - /* max slen = floor[35/6] = 5 (from mod 36) */ - slen[0] = (sfCompress / 36); - slen[1] = (sfCompress % 36) / 6; - slen[2] = (sfCompress % 36) % 6; - slen[3] = 0; - sfcIdx = 3; - } else if (sfCompress < 244) { - /* max slen = floor[63/16] = 3 */ - sfCompress -= 180; - slen[0] = (sfCompress & 0x3f) >> 4; - slen[1] = (sfCompress & 0x0f) >> 2; - slen[2] = (sfCompress & 0x03); - slen[3] = 0; - sfcIdx = 4; - } else { - /* max slen = floor[11/3] = 3 (max sfCompress >> 1 = 511/2 = 255) */ - sfCompress -= 244; - slen[0] = (sfCompress / 3); - slen[1] = (sfCompress % 3); - slen[2] = slen[3] = 0; - sfcIdx = 5; - } - } - - /* set index based on block type: (0,1,3) --> 0, (2 non-mixed) --> 1, (2 mixed) ---> 2 */ - btIdx = 0; - if (sis->blockType == 2) - btIdx = (sis->mixedBlock ? 2 : 1); - for (i = 0; i < 4; i++) - nr[i] = (int)NRTab[sfcIdx][btIdx][i]; - - /* save intensity stereo scale factor info */ - if( (modeExt & 0x01) && (ch == 1) ) { - for (i = 0; i < 4; i++) { - sfjs->slen[i] = slen[i]; - sfjs->nr[i] = nr[i]; - } - sfjs->intensityScale = intensityScale; - } - sis->preFlag = preFlag; - - /* short blocks */ - if(sis->blockType == 2) { - if(sis->mixedBlock) { - /* do long block portion */ - //iipTest = (1 << slen[0]) - 1; - for (sfb=0; sfb < 6; sfb++) { - sfis->l[sfb] = (char)GetBits(bsi, slen[0]); - } - sfb = 3; /* start sfb for short */ - nrIdx = 1; - } else { - /* all short blocks, so start nr, sfb at 0 */ - sfb = 0; - nrIdx = 0; - } - - /* remaining short blocks, sfb just keeps incrementing */ - for ( ; nrIdx <= 3; nrIdx++) { - //iipTest = (1 << slen[nrIdx]) - 1; - for (i=0; i < nr[nrIdx]; i++, sfb++) { - sfis->s[sfb][0] = (char)GetBits(bsi, slen[nrIdx]); - sfis->s[sfb][1] = (char)GetBits(bsi, slen[nrIdx]); - sfis->s[sfb][2] = (char)GetBits(bsi, slen[nrIdx]); - } - } - /* last sf band not transmitted */ - sfis->s[12][0] = sfis->s[12][1] = sfis->s[12][2] = 0; - } else { - /* long blocks */ - sfb = 0; - for (nrIdx = 0; nrIdx <= 3; nrIdx++) { - //iipTest = (1 << slen[nrIdx]) - 1; - for(i=0; i < nr[nrIdx]; i++, sfb++) { - sfis->l[sfb] = (char)GetBits(bsi, slen[nrIdx]); - } - } - /* last sf band not transmitted */ - sfis->l[21] = sfis->l[22] = 0; - - } +static void UnpackSFMPEG2(BitStreamInfo *bsi, SideInfoSub *sis, ScaleFactorInfoSub *sfis, int gr, int ch, int modeExt, ScaleFactorJS *sfjs) { + + int i, sfb, sfcIdx, btIdx, nrIdx;// iipTest; + int slen[4], nr[4]; + int sfCompress, preFlag, intensityScale; + (void)gr; + + sfCompress = sis->sfCompress; + preFlag = 0; + intensityScale = 0; + + /* stereo mode bits (1 = on): bit 1 = mid-side on/off, bit 0 = intensity on/off */ + if (!((modeExt & 0x01) && (ch == 1))) { + /* in other words: if ((modeExt & 0x01) == 0 || ch == 0) */ + if (sfCompress < 400) { + /* max slen = floor[(399/16) / 5] = 4 */ + slen[0] = (sfCompress >> 4) / 5; + slen[1] = (sfCompress >> 4) % 5; + slen[2] = (sfCompress & 0x0f) >> 2; + slen[3] = (sfCompress & 0x03); + sfcIdx = 0; + } else if (sfCompress < 500) { + /* max slen = floor[(99/4) / 5] = 4 */ + sfCompress -= 400; + slen[0] = (sfCompress >> 2) / 5; + slen[1] = (sfCompress >> 2) % 5; + slen[2] = (sfCompress & 0x03); + slen[3] = 0; + sfcIdx = 1; + } else { + /* max slen = floor[11/3] = 3 (sfCompress = 9 bits in MPEG2) */ + sfCompress -= 500; + slen[0] = sfCompress / 3; + slen[1] = sfCompress % 3; + slen[2] = slen[3] = 0; + if (sis->mixedBlock) { + /* adjust for long/short mix logic (see comment above in NRTab[] definition) */ + slen[2] = slen[1]; + slen[1] = slen[0]; + } + preFlag = 1; + sfcIdx = 2; + } + } else { + /* intensity stereo ch = 1 (right) */ + intensityScale = sfCompress & 0x01; + sfCompress >>= 1; + if (sfCompress < 180) { + /* max slen = floor[35/6] = 5 (from mod 36) */ + slen[0] = (sfCompress / 36); + slen[1] = (sfCompress % 36) / 6; + slen[2] = (sfCompress % 36) % 6; + slen[3] = 0; + sfcIdx = 3; + } else if (sfCompress < 244) { + /* max slen = floor[63/16] = 3 */ + sfCompress -= 180; + slen[0] = (sfCompress & 0x3f) >> 4; + slen[1] = (sfCompress & 0x0f) >> 2; + slen[2] = (sfCompress & 0x03); + slen[3] = 0; + sfcIdx = 4; + } else { + /* max slen = floor[11/3] = 3 (max sfCompress >> 1 = 511/2 = 255) */ + sfCompress -= 244; + slen[0] = (sfCompress / 3); + slen[1] = (sfCompress % 3); + slen[2] = slen[3] = 0; + sfcIdx = 5; + } + } + + /* set index based on block type: (0,1,3) --> 0, (2 non-mixed) --> 1, (2 mixed) ---> 2 */ + btIdx = 0; + if (sis->blockType == 2) { + btIdx = (sis->mixedBlock ? 2 : 1); + } + for (i = 0; i < 4; i++) { + nr[i] = (int)NRTab[sfcIdx][btIdx][i]; + } + + /* save intensity stereo scale factor info */ + if ((modeExt & 0x01) && (ch == 1)) { + for (i = 0; i < 4; i++) { + sfjs->slen[i] = slen[i]; + sfjs->nr[i] = nr[i]; + } + sfjs->intensityScale = intensityScale; + } + sis->preFlag = preFlag; + + /* short blocks */ + if (sis->blockType == 2) { + if (sis->mixedBlock) { + /* do long block portion */ + //iipTest = (1 << slen[0]) - 1; + for (sfb = 0; sfb < 6; sfb++) { + sfis->l[sfb] = (char)GetBits(bsi, slen[0]); + } + sfb = 3; /* start sfb for short */ + nrIdx = 1; + } else { + /* all short blocks, so start nr, sfb at 0 */ + sfb = 0; + nrIdx = 0; + } + + /* remaining short blocks, sfb just keeps incrementing */ + for (; nrIdx <= 3; nrIdx++) { + //iipTest = (1 << slen[nrIdx]) - 1; + for (i = 0; i < nr[nrIdx]; i++, sfb++) { + sfis->s[sfb][0] = (char)GetBits(bsi, slen[nrIdx]); + sfis->s[sfb][1] = (char)GetBits(bsi, slen[nrIdx]); + sfis->s[sfb][2] = (char)GetBits(bsi, slen[nrIdx]); + } + } + /* last sf band not transmitted */ + sfis->s[12][0] = sfis->s[12][1] = sfis->s[12][2] = 0; + } else { + /* long blocks */ + sfb = 0; + for (nrIdx = 0; nrIdx <= 3; nrIdx++) { + //iipTest = (1 << slen[nrIdx]) - 1; + for (i = 0; i < nr[nrIdx]; i++, sfb++) { + sfis->l[sfb] = (char)GetBits(bsi, slen[nrIdx]); + } + } + /* last sf band not transmitted */ + sfis->l[21] = sfis->l[22] = 0; + + } } /************************************************************************************** - * Function: UnpackScaleFactors - * - * Description: parse the fields of the MP3 scale factor data section - * - * Inputs: MP3DecInfo structure filled by UnpackFrameHeader() and UnpackSideInfo() - * buffer pointing to the MP3 scale factor data - * pointer to bit offset (0-7) indicating starting bit in buf[0] - * number of bits available in data buffer - * index of current granule and channel - * - * Outputs: updated platform-specific ScaleFactorInfo struct - * updated bitOffset - * - * Return: length (in bytes) of scale factor data, -1 if null input pointers + Function: UnpackScaleFactors + + Description: parse the fields of the MP3 scale factor data section + + Inputs: MP3DecInfo structure filled by UnpackFrameHeader() and UnpackSideInfo() + buffer pointing to the MP3 scale factor data + pointer to bit offset (0-7) indicating starting bit in buf[0] + number of bits available in data buffer + index of current granule and channel + + Outputs: updated platform-specific ScaleFactorInfo struct + updated bitOffset + + Return: length (in bytes) of scale factor data, -1 if null input pointers **************************************************************************************/ -int UnpackScaleFactors(MP3DecInfo *mp3DecInfo, unsigned char *buf, int *bitOffset, int bitsAvail, int gr, int ch) -{ - int bitsUsed; - unsigned char *startBuf; - BitStreamInfo bitStreamInfo, *bsi; - FrameHeader *fh; - SideInfo *si; - ScaleFactorInfo *sfi; - - /* validate pointers */ - if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || !mp3DecInfo->SideInfoPS || !mp3DecInfo->ScaleFactorInfoPS) - return -1; - fh = ((FrameHeader *)(mp3DecInfo->FrameHeaderPS)); - si = ((SideInfo *)(mp3DecInfo->SideInfoPS)); - sfi = ((ScaleFactorInfo *)(mp3DecInfo->ScaleFactorInfoPS)); - - /* init GetBits reader */ - startBuf = buf; - bsi = &bitStreamInfo; - SetBitstreamPointer(bsi, (bitsAvail + *bitOffset + 7) / 8, buf); - if (*bitOffset) - GetBits(bsi, *bitOffset); - - if (fh->ver == MPEG1) - UnpackSFMPEG1(bsi, &si->sis[gr][ch], &sfi->sfis[gr][ch], si->scfsi[ch], gr, &sfi->sfis[0][ch]); - else - UnpackSFMPEG2(bsi, &si->sis[gr][ch], &sfi->sfis[gr][ch], gr, ch, fh->modeExt, &sfi->sfjs); - - mp3DecInfo->part23Length[gr][ch] = si->sis[gr][ch].part23Length; - - bitsUsed = CalcBitsUsed(bsi, buf, *bitOffset); - buf += (bitsUsed + *bitOffset) >> 3; - *bitOffset = (bitsUsed + *bitOffset) & 0x07; - - return (buf - startBuf); +int UnpackScaleFactors(MP3DecInfo *mp3DecInfo, unsigned char *buf, int *bitOffset, int bitsAvail, int gr, int ch) { + int bitsUsed; + unsigned char *startBuf; + BitStreamInfo bitStreamInfo, *bsi; + FrameHeader *fh; + SideInfo *si; + ScaleFactorInfo *sfi; + + /* validate pointers */ + if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || !mp3DecInfo->SideInfoPS || !mp3DecInfo->ScaleFactorInfoPS) { + return -1; + } + fh = ((FrameHeader *)(mp3DecInfo->FrameHeaderPS)); + si = ((SideInfo *)(mp3DecInfo->SideInfoPS)); + sfi = ((ScaleFactorInfo *)(mp3DecInfo->ScaleFactorInfoPS)); + + /* init GetBits reader */ + startBuf = buf; + bsi = &bitStreamInfo; + SetBitstreamPointer(bsi, (bitsAvail + *bitOffset + 7) / 8, buf); + if (*bitOffset) { + GetBits(bsi, *bitOffset); + } + + if (fh->ver == MPEG1) { + UnpackSFMPEG1(bsi, &si->sis[gr][ch], &sfi->sfis[gr][ch], si->scfsi[ch], gr, &sfi->sfis[0][ch]); + } else { + UnpackSFMPEG2(bsi, &si->sis[gr][ch], &sfi->sfis[gr][ch], gr, ch, fh->modeExt, &sfi->sfjs); + } + + mp3DecInfo->part23Length[gr][ch] = si->sis[gr][ch].part23Length; + + bitsUsed = CalcBitsUsed(bsi, buf, *bitOffset); + buf += (bitsUsed + *bitOffset) >> 3; + *bitOffset = (bitsUsed + *bitOffset) & 0x07; + + return (buf - startBuf); } diff --git a/src/libhelix-mp3/statname.h b/src/libhelix-mp3/statname.h index c7f985ea..8f39a484 100644 --- a/src/libhelix-mp3/statname.h +++ b/src/libhelix-mp3/statname.h @@ -1,58 +1,58 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * statname.h - name mangling macros for static linking + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + statname.h - name mangling macros for static linking **************************************************************************************/ #ifndef _STATNAME_H #define _STATNAME_H -/* define STAT_PREFIX to a unique name for static linking - * all the C functions and global variables will be mangled by the preprocessor - * e.g. void FFT(int *fftbuf) becomes void cook_FFT(int *fftbuf) - */ +/* define STAT_PREFIX to a unique name for static linking + all the C functions and global variables will be mangled by the preprocessor + e.g. void FFT(int *fftbuf) becomes void cook_FFT(int *fftbuf) +*/ #define STAT_PREFIX xmp3 #define STATCC1(x,y,z) STATCC2(x,y,z) -#define STATCC2(x,y,z) x##y##z +#define STATCC2(x,y,z) x##y##z #ifdef STAT_PREFIX #define STATNAME(func) STATCC1(STAT_PREFIX, _, func) @@ -80,10 +80,10 @@ #define slotTab STATNAME(slotTab) #define sfBandTable STATNAME(sfBandTable) -/* in your implementation's top-level include file (e.g. real\coder.h) you should - * add new #define sym STATNAME(sym) lines for all the - * additional global functions or variables which your - * implementation uses - */ +/* in your implementation's top-level include file (e.g. real\coder.h) you should + add new #define sym STATNAME(sym) lines for all the + additional global functions or variables which your + implementation uses +*/ #endif /* _STATNAME_H */ diff --git a/src/libhelix-mp3/stproc.c b/src/libhelix-mp3/stproc.c index 7782a21b..6c84093d 100644 --- a/src/libhelix-mp3/stproc.c +++ b/src/libhelix-mp3/stproc.c @@ -1,299 +1,298 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * stproc.c - mid-side and intensity (MPEG1 and MPEG2) stereo processing + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + stproc.c - mid-side and intensity (MPEG1 and MPEG2) stereo processing **************************************************************************************/ #include "coder.h" #include "assembly.h" /************************************************************************************** - * Function: MidSideProc - * - * Description: sum-difference stereo reconstruction - * - * Inputs: vector x with dequantized samples from left and right channels - * number of non-zero samples (MAX of left and right) - * assume 1 guard bit in input - * guard bit mask (left and right channels) - * - * Outputs: updated sample vector x - * updated guard bit mask - * - * Return: none - * - * Notes: assume at least 1 GB in input + Function: MidSideProc + + Description: sum-difference stereo reconstruction + + Inputs: vector x with dequantized samples from left and right channels + number of non-zero samples (MAX of left and right) + assume 1 guard bit in input + guard bit mask (left and right channels) + + Outputs: updated sample vector x + updated guard bit mask + + Return: none + + Notes: assume at least 1 GB in input **************************************************************************************/ -void MidSideProc(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, int mOut[2]) -{ - int i, xr, xl, mOutL, mOutR; - - /* L = (M+S)/sqrt(2), R = (M-S)/sqrt(2) - * NOTE: 1/sqrt(2) done in DequantChannel() - see comments there - */ - mOutL = mOutR = 0; - for(i = 0; i < nSamps; i++) { - xl = x[0][i]; - xr = x[1][i]; - x[0][i] = xl + xr; - x[1][i] = xl - xr; - mOutL |= FASTABS(x[0][i]); - mOutR |= FASTABS(x[1][i]); - } - mOut[0] |= mOutL; - mOut[1] |= mOutR; +void MidSideProc(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, int mOut[2]) { + int i, xr, xl, mOutL, mOutR; + + /* L = (M+S)/sqrt(2), R = (M-S)/sqrt(2) + NOTE: 1/sqrt(2) done in DequantChannel() - see comments there + */ + mOutL = mOutR = 0; + for (i = 0; i < nSamps; i++) { + xl = x[0][i]; + xr = x[1][i]; + x[0][i] = xl + xr; + x[1][i] = xl - xr; + mOutL |= FASTABS(x[0][i]); + mOutR |= FASTABS(x[1][i]); + } + mOut[0] |= mOutL; + mOut[1] |= mOutR; } /************************************************************************************** - * Function: IntensityProcMPEG1 - * - * Description: intensity stereo processing for MPEG1 - * - * Inputs: vector x with dequantized samples from left and right channels - * number of non-zero samples in left channel - * valid FrameHeader struct - * two each of ScaleFactorInfoSub, CriticalBandInfo structs (both channels) - * flags indicating midSide on/off, mixedBlock on/off - * guard bit mask (left and right channels) - * - * Outputs: updated sample vector x - * updated guard bit mask - * - * Return: none - * - * Notes: assume at least 1 GB in input - * - * TODO: combine MPEG1/2 into one function (maybe) - * make sure all the mixed-block and IIP logic is right + Function: IntensityProcMPEG1 + + Description: intensity stereo processing for MPEG1 + + Inputs: vector x with dequantized samples from left and right channels + number of non-zero samples in left channel + valid FrameHeader struct + two each of ScaleFactorInfoSub, CriticalBandInfo structs (both channels) + flags indicating midSide on/off, mixedBlock on/off + guard bit mask (left and right channels) + + Outputs: updated sample vector x + updated guard bit mask + + Return: none + + Notes: assume at least 1 GB in input + + TODO: combine MPEG1/2 into one function (maybe) + make sure all the mixed-block and IIP logic is right **************************************************************************************/ -void IntensityProcMPEG1(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, FrameHeader *fh, ScaleFactorInfoSub *sfis, - CriticalBandInfo *cbi, int midSideFlag, int mixFlag, int mOut[2]) -{ - int i=0, j=0, n=0, cb=0, w=0; - int sampsLeft, isf, mOutL, mOutR, xl, xr; - int fl, fr, fls[3], frs[3]; - int cbStartL=0, cbStartS=0, cbEndL=0, cbEndS=0; - int *isfTab; - (void)mixFlag; - - /* NOTE - this works fine for mixed blocks, as long as the switch point starts in the - * short block section (i.e. on or after sample 36 = sfBand->l[8] = 3*sfBand->s[3] - * is this a safe assumption? - * TODO - intensity + mixed not quite right (diff = 11 on he_mode) - * figure out correct implementation (spec ambiguous about when to do short block reorder) - */ - if (cbi[1].cbType == 0) { - /* long block */ - cbStartL = cbi[1].cbEndL + 1; - cbEndL = cbi[0].cbEndL + 1; - cbStartS = cbEndS = 0; - i = fh->sfBand->l[cbStartL]; - } else if (cbi[1].cbType == 1 || cbi[1].cbType == 2) { - /* short or mixed block */ - cbStartS = cbi[1].cbEndSMax + 1; - cbEndS = cbi[0].cbEndSMax + 1; - cbStartL = cbEndL = 0; - i = 3 * fh->sfBand->s[cbStartS]; - } - - sampsLeft = nSamps - i; /* process to length of left */ - isfTab = (int *)ISFMpeg1[midSideFlag]; - mOutL = mOutR = 0; - - /* long blocks */ - for (cb = cbStartL; cb < cbEndL && sampsLeft > 0; cb++) { - isf = sfis->l[cb]; - if (isf == 7) { - fl = ISFIIP[midSideFlag][0]; - fr = ISFIIP[midSideFlag][1]; - } else { - fl = isfTab[isf]; - fr = isfTab[6] - isfTab[isf]; - } - - n = fh->sfBand->l[cb + 1] - fh->sfBand->l[cb]; - for (j = 0; j < n && sampsLeft > 0; j++, i++) { - xr = MULSHIFT32(fr, x[0][i]) << 2; x[1][i] = xr; mOutR |= FASTABS(xr); - xl = MULSHIFT32(fl, x[0][i]) << 2; x[0][i] = xl; mOutL |= FASTABS(xl); - sampsLeft--; - } - } - - /* short blocks */ - for (cb = cbStartS; cb < cbEndS && sampsLeft >= 3; cb++) { - for (w = 0; w < 3; w++) { - isf = sfis->s[cb][w]; - if (isf == 7) { - fls[w] = ISFIIP[midSideFlag][0]; - frs[w] = ISFIIP[midSideFlag][1]; - } else { - fls[w] = isfTab[isf]; - frs[w] = isfTab[6] - isfTab[isf]; - } - } - - n = fh->sfBand->s[cb + 1] - fh->sfBand->s[cb]; - for (j = 0; j < n && sampsLeft >= 3; j++, i+=3) { - xr = MULSHIFT32(frs[0], x[0][i+0]) << 2; x[1][i+0] = xr; mOutR |= FASTABS(xr); - xl = MULSHIFT32(fls[0], x[0][i+0]) << 2; x[0][i+0] = xl; mOutL |= FASTABS(xl); - xr = MULSHIFT32(frs[1], x[0][i+1]) << 2; x[1][i+1] = xr; mOutR |= FASTABS(xr); - xl = MULSHIFT32(fls[1], x[0][i+1]) << 2; x[0][i+1] = xl; mOutL |= FASTABS(xl); - xr = MULSHIFT32(frs[2], x[0][i+2]) << 2; x[1][i+2] = xr; mOutR |= FASTABS(xr); - xl = MULSHIFT32(fls[2], x[0][i+2]) << 2; x[0][i+2] = xl; mOutL |= FASTABS(xl); - sampsLeft -= 3; - } - } - mOut[0] = mOutL; - mOut[1] = mOutR; - - return; +void IntensityProcMPEG1(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, FrameHeader *fh, ScaleFactorInfoSub *sfis, + CriticalBandInfo *cbi, int midSideFlag, int mixFlag, int mOut[2]) { + int i = 0, j = 0, n = 0, cb = 0, w = 0; + int sampsLeft, isf, mOutL, mOutR, xl, xr; + int fl, fr, fls[3], frs[3]; + int cbStartL = 0, cbStartS = 0, cbEndL = 0, cbEndS = 0; + int *isfTab; + (void)mixFlag; + + /* NOTE - this works fine for mixed blocks, as long as the switch point starts in the + short block section (i.e. on or after sample 36 = sfBand->l[8] = 3*sfBand->s[3] + is this a safe assumption? + TODO - intensity + mixed not quite right (diff = 11 on he_mode) + figure out correct implementation (spec ambiguous about when to do short block reorder) + */ + if (cbi[1].cbType == 0) { + /* long block */ + cbStartL = cbi[1].cbEndL + 1; + cbEndL = cbi[0].cbEndL + 1; + cbStartS = cbEndS = 0; + i = fh->sfBand->l[cbStartL]; + } else if (cbi[1].cbType == 1 || cbi[1].cbType == 2) { + /* short or mixed block */ + cbStartS = cbi[1].cbEndSMax + 1; + cbEndS = cbi[0].cbEndSMax + 1; + cbStartL = cbEndL = 0; + i = 3 * fh->sfBand->s[cbStartS]; + } + + sampsLeft = nSamps - i; /* process to length of left */ + isfTab = (int *)ISFMpeg1[midSideFlag]; + mOutL = mOutR = 0; + + /* long blocks */ + for (cb = cbStartL; cb < cbEndL && sampsLeft > 0; cb++) { + isf = sfis->l[cb]; + if (isf == 7) { + fl = ISFIIP[midSideFlag][0]; + fr = ISFIIP[midSideFlag][1]; + } else { + fl = isfTab[isf]; + fr = isfTab[6] - isfTab[isf]; + } + + n = fh->sfBand->l[cb + 1] - fh->sfBand->l[cb]; + for (j = 0; j < n && sampsLeft > 0; j++, i++) { + xr = MULSHIFT32(fr, x[0][i]) << 2; x[1][i] = xr; mOutR |= FASTABS(xr); + xl = MULSHIFT32(fl, x[0][i]) << 2; x[0][i] = xl; mOutL |= FASTABS(xl); + sampsLeft--; + } + } + + /* short blocks */ + for (cb = cbStartS; cb < cbEndS && sampsLeft >= 3; cb++) { + for (w = 0; w < 3; w++) { + isf = sfis->s[cb][w]; + if (isf == 7) { + fls[w] = ISFIIP[midSideFlag][0]; + frs[w] = ISFIIP[midSideFlag][1]; + } else { + fls[w] = isfTab[isf]; + frs[w] = isfTab[6] - isfTab[isf]; + } + } + + n = fh->sfBand->s[cb + 1] - fh->sfBand->s[cb]; + for (j = 0; j < n && sampsLeft >= 3; j++, i += 3) { + xr = MULSHIFT32(frs[0], x[0][i + 0]) << 2; x[1][i + 0] = xr; mOutR |= FASTABS(xr); + xl = MULSHIFT32(fls[0], x[0][i + 0]) << 2; x[0][i + 0] = xl; mOutL |= FASTABS(xl); + xr = MULSHIFT32(frs[1], x[0][i + 1]) << 2; x[1][i + 1] = xr; mOutR |= FASTABS(xr); + xl = MULSHIFT32(fls[1], x[0][i + 1]) << 2; x[0][i + 1] = xl; mOutL |= FASTABS(xl); + xr = MULSHIFT32(frs[2], x[0][i + 2]) << 2; x[1][i + 2] = xr; mOutR |= FASTABS(xr); + xl = MULSHIFT32(fls[2], x[0][i + 2]) << 2; x[0][i + 2] = xl; mOutL |= FASTABS(xl); + sampsLeft -= 3; + } + } + mOut[0] = mOutL; + mOut[1] = mOutR; + + return; } /************************************************************************************** - * Function: IntensityProcMPEG2 - * - * Description: intensity stereo processing for MPEG2 - * - * Inputs: vector x with dequantized samples from left and right channels - * number of non-zero samples in left channel - * valid FrameHeader struct - * two each of ScaleFactorInfoSub, CriticalBandInfo structs (both channels) - * ScaleFactorJS struct with joint stereo info from UnpackSFMPEG2() - * flags indicating midSide on/off, mixedBlock on/off - * guard bit mask (left and right channels) - * - * Outputs: updated sample vector x - * updated guard bit mask - * - * Return: none - * - * Notes: assume at least 1 GB in input - * - * TODO: combine MPEG1/2 into one function (maybe) - * make sure all the mixed-block and IIP logic is right - * probably redo IIP logic to be simpler + Function: IntensityProcMPEG2 + + Description: intensity stereo processing for MPEG2 + + Inputs: vector x with dequantized samples from left and right channels + number of non-zero samples in left channel + valid FrameHeader struct + two each of ScaleFactorInfoSub, CriticalBandInfo structs (both channels) + ScaleFactorJS struct with joint stereo info from UnpackSFMPEG2() + flags indicating midSide on/off, mixedBlock on/off + guard bit mask (left and right channels) + + Outputs: updated sample vector x + updated guard bit mask + + Return: none + + Notes: assume at least 1 GB in input + + TODO: combine MPEG1/2 into one function (maybe) + make sure all the mixed-block and IIP logic is right + probably redo IIP logic to be simpler **************************************************************************************/ -void IntensityProcMPEG2(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, FrameHeader *fh, ScaleFactorInfoSub *sfis, - CriticalBandInfo *cbi, ScaleFactorJS *sfjs, int midSideFlag, int mixFlag, int mOut[2]) -{ - int i, j, k, n, r, cb, w; - int fl, fr, mOutL, mOutR, xl, xr; - int sampsLeft; - int isf, sfIdx, tmp, il[23]; - int *isfTab; - int cbStartL, cbStartS, cbEndL, cbEndS; - - (void)mixFlag; - - isfTab = (int *)ISFMpeg2[sfjs->intensityScale][midSideFlag]; - mOutL = mOutR = 0; - - /* fill buffer with illegal intensity positions (depending on slen) */ - for (k = r = 0; r < 4; r++) { - tmp = (1 << sfjs->slen[r]) - 1; - for (j = 0; j < sfjs->nr[r]; j++, k++) - il[k] = tmp; - } - - if (cbi[1].cbType == 0) { - /* long blocks */ - il[21] = il[22] = 1; - cbStartL = cbi[1].cbEndL + 1; /* start at end of right */ - cbEndL = cbi[0].cbEndL + 1; /* process to end of left */ - i = fh->sfBand->l[cbStartL]; - sampsLeft = nSamps - i; - - for(cb = cbStartL; cb < cbEndL; cb++) { - sfIdx = sfis->l[cb]; - if (sfIdx == il[cb]) { - fl = ISFIIP[midSideFlag][0]; - fr = ISFIIP[midSideFlag][1]; - } else { - isf = (sfis->l[cb] + 1) >> 1; - fl = isfTab[(sfIdx & 0x01 ? isf : 0)]; - fr = isfTab[(sfIdx & 0x01 ? 0 : isf)]; - } - n = MIN(fh->sfBand->l[cb + 1] - fh->sfBand->l[cb], sampsLeft); - - for(j = 0; j < n; j++, i++) { - xr = MULSHIFT32(fr, x[0][i]) << 2; x[1][i] = xr; mOutR |= FASTABS(xr); - xl = MULSHIFT32(fl, x[0][i]) << 2; x[0][i] = xl; mOutL |= FASTABS(xl); - } - - /* early exit once we've used all the non-zero samples */ - sampsLeft -= n; - if (sampsLeft == 0) - break; - } - } else { - /* short or mixed blocks */ - il[12] = 1; - - for(w = 0; w < 3; w++) { - cbStartS = cbi[1].cbEndS[w] + 1; /* start at end of right */ - cbEndS = cbi[0].cbEndS[w] + 1; /* process to end of left */ - i = 3 * fh->sfBand->s[cbStartS] + w; - - /* skip through sample array by 3, so early-exit logic would be more tricky */ - for(cb = cbStartS; cb < cbEndS; cb++) { - sfIdx = sfis->s[cb][w]; - if (sfIdx == il[cb]) { - fl = ISFIIP[midSideFlag][0]; - fr = ISFIIP[midSideFlag][1]; - } else { - isf = (sfis->s[cb][w] + 1) >> 1; - fl = isfTab[(sfIdx & 0x01 ? isf : 0)]; - fr = isfTab[(sfIdx & 0x01 ? 0 : isf)]; - } - n = fh->sfBand->s[cb + 1] - fh->sfBand->s[cb]; - - for(j = 0; j < n; j++, i+=3) { - xr = MULSHIFT32(fr, x[0][i]) << 2; x[1][i] = xr; mOutR |= FASTABS(xr); - xl = MULSHIFT32(fl, x[0][i]) << 2; x[0][i] = xl; mOutL |= FASTABS(xl); - } - } - } - } - mOut[0] = mOutL; - mOut[1] = mOutR; - - return; +void IntensityProcMPEG2(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, FrameHeader *fh, ScaleFactorInfoSub *sfis, + CriticalBandInfo *cbi, ScaleFactorJS *sfjs, int midSideFlag, int mixFlag, int mOut[2]) { + int i, j, k, n, r, cb, w; + int fl, fr, mOutL, mOutR, xl, xr; + int sampsLeft; + int isf, sfIdx, tmp, il[23]; + int *isfTab; + int cbStartL, cbStartS, cbEndL, cbEndS; + + (void)mixFlag; + + isfTab = (int *)ISFMpeg2[sfjs->intensityScale][midSideFlag]; + mOutL = mOutR = 0; + + /* fill buffer with illegal intensity positions (depending on slen) */ + for (k = r = 0; r < 4; r++) { + tmp = (1 << sfjs->slen[r]) - 1; + for (j = 0; j < sfjs->nr[r]; j++, k++) { + il[k] = tmp; + } + } + + if (cbi[1].cbType == 0) { + /* long blocks */ + il[21] = il[22] = 1; + cbStartL = cbi[1].cbEndL + 1; /* start at end of right */ + cbEndL = cbi[0].cbEndL + 1; /* process to end of left */ + i = fh->sfBand->l[cbStartL]; + sampsLeft = nSamps - i; + + for (cb = cbStartL; cb < cbEndL; cb++) { + sfIdx = sfis->l[cb]; + if (sfIdx == il[cb]) { + fl = ISFIIP[midSideFlag][0]; + fr = ISFIIP[midSideFlag][1]; + } else { + isf = (sfis->l[cb] + 1) >> 1; + fl = isfTab[(sfIdx & 0x01 ? isf : 0)]; + fr = isfTab[(sfIdx & 0x01 ? 0 : isf)]; + } + n = MIN(fh->sfBand->l[cb + 1] - fh->sfBand->l[cb], sampsLeft); + + for (j = 0; j < n; j++, i++) { + xr = MULSHIFT32(fr, x[0][i]) << 2; x[1][i] = xr; mOutR |= FASTABS(xr); + xl = MULSHIFT32(fl, x[0][i]) << 2; x[0][i] = xl; mOutL |= FASTABS(xl); + } + + /* early exit once we've used all the non-zero samples */ + sampsLeft -= n; + if (sampsLeft == 0) { + break; + } + } + } else { + /* short or mixed blocks */ + il[12] = 1; + + for (w = 0; w < 3; w++) { + cbStartS = cbi[1].cbEndS[w] + 1; /* start at end of right */ + cbEndS = cbi[0].cbEndS[w] + 1; /* process to end of left */ + i = 3 * fh->sfBand->s[cbStartS] + w; + + /* skip through sample array by 3, so early-exit logic would be more tricky */ + for (cb = cbStartS; cb < cbEndS; cb++) { + sfIdx = sfis->s[cb][w]; + if (sfIdx == il[cb]) { + fl = ISFIIP[midSideFlag][0]; + fr = ISFIIP[midSideFlag][1]; + } else { + isf = (sfis->s[cb][w] + 1) >> 1; + fl = isfTab[(sfIdx & 0x01 ? isf : 0)]; + fr = isfTab[(sfIdx & 0x01 ? 0 : isf)]; + } + n = fh->sfBand->s[cb + 1] - fh->sfBand->s[cb]; + + for (j = 0; j < n; j++, i += 3) { + xr = MULSHIFT32(fr, x[0][i]) << 2; x[1][i] = xr; mOutR |= FASTABS(xr); + xl = MULSHIFT32(fl, x[0][i]) << 2; x[0][i] = xl; mOutL |= FASTABS(xl); + } + } + } + } + mOut[0] = mOutL; + mOut[1] = mOutR; + + return; } diff --git a/src/libhelix-mp3/subband.c b/src/libhelix-mp3/subband.c index e982a9fe..0bfd71cc 100644 --- a/src/libhelix-mp3/subband.c +++ b/src/libhelix-mp3/subband.c @@ -1,96 +1,96 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * subband.c - subband transform (synthesis filterbank implemented via 32-point DCT - * followed by polyphase filter) + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + subband.c - subband transform (synthesis filterbank implemented via 32-point DCT + followed by polyphase filter) **************************************************************************************/ #include "coder.h" #include "assembly.h" /************************************************************************************** - * Function: Subband - * - * Description: do subband transform on all the blocks in one granule, all channels - * - * Inputs: filled MP3DecInfo structure, after calling IMDCT for all channels - * vbuf[ch] and vindex[ch] must be preserved between calls - * - * Outputs: decoded PCM data, interleaved LRLRLR... if stereo - * - * Return: 0 on success, -1 if null input pointers + Function: Subband + + Description: do subband transform on all the blocks in one granule, all channels + + Inputs: filled MP3DecInfo structure, after calling IMDCT for all channels + vbuf[ch] and vindex[ch] must be preserved between calls + + Outputs: decoded PCM data, interleaved LRLRLR... if stereo + + Return: 0 on success, -1 if null input pointers **************************************************************************************/ -/*__attribute__ ((section (".data"))) */ int Subband(MP3DecInfo *mp3DecInfo, short *pcmBuf) -{ - int b; - //HuffmanInfo *hi; - IMDCTInfo *mi; - SubbandInfo *sbi; - - /* validate pointers */ - if (!mp3DecInfo || !mp3DecInfo->HuffmanInfoPS || !mp3DecInfo->IMDCTInfoPS || !mp3DecInfo->SubbandInfoPS) - return -1; - - //hi = (HuffmanInfo *)mp3DecInfo->HuffmanInfoPS; - mi = (IMDCTInfo *)(mp3DecInfo->IMDCTInfoPS); - sbi = (SubbandInfo*)(mp3DecInfo->SubbandInfoPS); - - if (mp3DecInfo->nChans == 2) { - /* stereo */ - for (b = 0; b < BLOCK_SIZE; b++) { - FDCT32(mi->outBuf[0][b], sbi->vbuf + 0*32, sbi->vindex, (b & 0x01), mi->gb[0]); - FDCT32(mi->outBuf[1][b], sbi->vbuf + 1*32, sbi->vindex, (b & 0x01), mi->gb[1]); - PolyphaseStereo(pcmBuf, sbi->vbuf + sbi->vindex + VBUF_LENGTH * (b & 0x01), polyCoef); - sbi->vindex = (sbi->vindex - (b & 0x01)) & 7; - pcmBuf += (2 * NBANDS); - } - } else { - /* mono */ - for (b = 0; b < BLOCK_SIZE; b++) { - FDCT32(mi->outBuf[0][b], sbi->vbuf + 0*32, sbi->vindex, (b & 0x01), mi->gb[0]); - PolyphaseMono(pcmBuf, sbi->vbuf + sbi->vindex + VBUF_LENGTH * (b & 0x01), polyCoef); - sbi->vindex = (sbi->vindex - (b & 0x01)) & 7; - pcmBuf += NBANDS; - } - } - - return 0; +/*__attribute__ ((section (".data"))) */ int Subband(MP3DecInfo *mp3DecInfo, short *pcmBuf) { + int b; + //HuffmanInfo *hi; + IMDCTInfo *mi; + SubbandInfo *sbi; + + /* validate pointers */ + if (!mp3DecInfo || !mp3DecInfo->HuffmanInfoPS || !mp3DecInfo->IMDCTInfoPS || !mp3DecInfo->SubbandInfoPS) { + return -1; + } + + //hi = (HuffmanInfo *)mp3DecInfo->HuffmanInfoPS; + mi = (IMDCTInfo *)(mp3DecInfo->IMDCTInfoPS); + sbi = (SubbandInfo*)(mp3DecInfo->SubbandInfoPS); + + if (mp3DecInfo->nChans == 2) { + /* stereo */ + for (b = 0; b < BLOCK_SIZE; b++) { + FDCT32(mi->outBuf[0][b], sbi->vbuf + 0 * 32, sbi->vindex, (b & 0x01), mi->gb[0]); + FDCT32(mi->outBuf[1][b], sbi->vbuf + 1 * 32, sbi->vindex, (b & 0x01), mi->gb[1]); + PolyphaseStereo(pcmBuf, sbi->vbuf + sbi->vindex + VBUF_LENGTH * (b & 0x01), polyCoef); + sbi->vindex = (sbi->vindex - (b & 0x01)) & 7; + pcmBuf += (2 * NBANDS); + } + } else { + /* mono */ + for (b = 0; b < BLOCK_SIZE; b++) { + FDCT32(mi->outBuf[0][b], sbi->vbuf + 0 * 32, sbi->vindex, (b & 0x01), mi->gb[0]); + PolyphaseMono(pcmBuf, sbi->vbuf + sbi->vindex + VBUF_LENGTH * (b & 0x01), polyCoef); + sbi->vindex = (sbi->vindex - (b & 0x01)) & 7; + pcmBuf += NBANDS; + } + } + + return 0; } diff --git a/src/libhelix-mp3/trigtabs.c b/src/libhelix-mp3/trigtabs.c index 8686e816..95e2529d 100644 --- a/src/libhelix-mp3/trigtabs.c +++ b/src/libhelix-mp3/trigtabs.c @@ -1,44 +1,44 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: RCSL 1.0/RPSL 1.0 - * - * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. - * - * The contents of this file, and the files included with this file, are - * subject to the current version of the RealNetworks Public Source License - * Version 1.0 (the "RPSL") available at - * http://www.helixcommunity.org/content/rpsl unless you have licensed - * the file under the RealNetworks Community Source License Version 1.0 - * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, - * in which case the RCSL will apply. You may also obtain the license terms - * directly from RealNetworks. You may not use this file except in - * compliance with the RPSL or, if you have a valid RCSL with RealNetworks - * applicable to this file, the RCSL. Please see the applicable RPSL or - * RCSL for the rights, obligations and limitations governing use of the - * contents of the file. - * - * This file is part of the Helix DNA Technology. RealNetworks is the - * developer of the Original Code and owns the copyrights in the portions - * it created. - * - * This file, and the files included with this file, is distributed and made - * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * - * Technology Compatibility Kit Test Suite(s) Location: - * http://www.helixcommunity.org/content/tck - * - * Contributor(s): - * - * ***** END LICENSE BLOCK ***** */ +/* ***** BEGIN LICENSE BLOCK ***** + Version: RCSL 1.0/RPSL 1.0 + + Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. + + The contents of this file, and the files included with this file, are + subject to the current version of the RealNetworks Public Source License + Version 1.0 (the "RPSL") available at + http://www.helixcommunity.org/content/rpsl unless you have licensed + the file under the RealNetworks Community Source License Version 1.0 + (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, + in which case the RCSL will apply. You may also obtain the license terms + directly from RealNetworks. You may not use this file except in + compliance with the RPSL or, if you have a valid RCSL with RealNetworks + applicable to this file, the RCSL. Please see the applicable RPSL or + RCSL for the rights, obligations and limitations governing use of the + contents of the file. + + This file is part of the Helix DNA Technology. RealNetworks is the + developer of the Original Code and owns the copyrights in the portions + it created. + + This file, and the files included with this file, is distributed and made + available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, + INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + + Technology Compatibility Kit Test Suite(s) Location: + http://www.helixcommunity.org/content/tck + + Contributor(s): + + * ***** END LICENSE BLOCK ***** */ /************************************************************************************** - * Fixed-point MP3 decoder - * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) - * June 2003 - * - * trigtabs.c - global ROM tables for pre-calculated trig coefficients + Fixed-point MP3 decoder + Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) + June 2003 + + trigtabs.c - global ROM tables for pre-calculated trig coefficients **************************************************************************************/ // constants in RAM are not significantly faster @@ -49,271 +49,271 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnarrowing" -/* post-IMDCT window, win[blockType][i] - * format = Q31 - * Fused sin window with final stage of IMDCT - * includes 1/sqrt(2) scaling, since we scale by sqrt(2) in dequant in order - * for fast IMDCT36 to be usable - * - * for(i=0;i<9;i++) win[0][i] = sin(pi/36 *(i+0.5)); - * for(i=9;i<36;i++) win[0][i] = -sin(pi/36 *(i+0.5)); - * - * for(i=0;i<9;i++) win[1][i] = sin(pi/36 *(i+0.5)); - * for(i=9;i<18;i++) win[1][i] = -sin(pi/36 *(i+0.5)); - * for(i=18;i<24;i++) win[1][i] = -1; - * for(i=24;i<30;i++) win[1][i] = -sin(pi/12 *(i+0.5-18)); - * for(i=30;i<36;i++) win[1][i] = 0; - * - * for(i=0;i<6;i++) win[3][i] = 0; - * for(i=6;i<9;i++) win[3][i] = sin(pi/12 *(i+0.5-6)); - * for(i=9;i<12;i++) win[3][i] = -sin(pi/12 *(i+0.5-6)); - * for(i=12;i<18;i++) win[3][i] = -1; - * for(i=18;i<36;i++) win[3][i] = -sin(pi/36*(i+0.5)); - * - * for(i=0;i<3;i++) win[2][i] = sin(pi/12*(i+0.5)); - * for(i=3;i<12;i++) win[2][i] = -sin(pi/12*(i+0.5)); - * for(i=12;i<36;i++) win[2][i] = 0; - * - * for (i = 0; i < 4; i++) { - * if (i == 2) { - * win[i][8] *= cos(pi/12 * (0+0.5)); - * win[i][9] *= cos(pi/12 * (0+0.5)); - * win[i][7] *= cos(pi/12 * (1+0.5)); - * win[i][10] *= cos(pi/12 * (1+0.5)); - * win[i][6] *= cos(pi/12 * (2+0.5)); - * win[i][11] *= cos(pi/12 * (2+0.5)); - * win[i][0] *= cos(pi/12 * (3+0.5)); - * win[i][5] *= cos(pi/12 * (3+0.5)); - * win[i][1] *= cos(pi/12 * (4+0.5)); - * win[i][4] *= cos(pi/12 * (4+0.5)); - * win[i][2] *= cos(pi/12 * (5+0.5)); - * win[i][3] *= cos(pi/12 * (5+0.5)); - * } else { - * for (j = 0; j < 9; j++) { - * win[i][8-j] *= cos(pi/36 * (17-j+0.5)); - * win[i][9+j] *= cos(pi/36 * (17-j+0.5)); - * } - * for (j = 0; j < 9; j++) { - * win[i][18+8-j] *= cos(pi/36 * (j+0.5)); - * win[i][18+9+j] *= cos(pi/36 * (j+0.5)); - * } - * } - * } - * for (i = 0; i < 4; i++) - * for (j = 0; j < 36; j++) - * win[i][j] *= 1.0 / sqrt(2); - */ - +/* post-IMDCT window, win[blockType][i] + format = Q31 + Fused sin window with final stage of IMDCT + includes 1/sqrt(2) scaling, since we scale by sqrt(2) in dequant in order + for fast IMDCT36 to be usable + + for(i=0;i<9;i++) win[0][i] = sin(pi/36 *(i+0.5)); + for(i=9;i<36;i++) win[0][i] = -sin(pi/36 *(i+0.5)); + + for(i=0;i<9;i++) win[1][i] = sin(pi/36 *(i+0.5)); + for(i=9;i<18;i++) win[1][i] = -sin(pi/36 *(i+0.5)); + for(i=18;i<24;i++) win[1][i] = -1; + for(i=24;i<30;i++) win[1][i] = -sin(pi/12 *(i+0.5-18)); + for(i=30;i<36;i++) win[1][i] = 0; + + for(i=0;i<6;i++) win[3][i] = 0; + for(i=6;i<9;i++) win[3][i] = sin(pi/12 *(i+0.5-6)); + for(i=9;i<12;i++) win[3][i] = -sin(pi/12 *(i+0.5-6)); + for(i=12;i<18;i++) win[3][i] = -1; + for(i=18;i<36;i++) win[3][i] = -sin(pi/36*(i+0.5)); + + for(i=0;i<3;i++) win[2][i] = sin(pi/12*(i+0.5)); + for(i=3;i<12;i++) win[2][i] = -sin(pi/12*(i+0.5)); + for(i=12;i<36;i++) win[2][i] = 0; + + for (i = 0; i < 4; i++) { + if (i == 2) { + win[i][8] *= cos(pi/12 * (0+0.5)); + win[i][9] *= cos(pi/12 * (0+0.5)); + win[i][7] *= cos(pi/12 * (1+0.5)); + win[i][10] *= cos(pi/12 * (1+0.5)); + win[i][6] *= cos(pi/12 * (2+0.5)); + win[i][11] *= cos(pi/12 * (2+0.5)); + win[i][0] *= cos(pi/12 * (3+0.5)); + win[i][5] *= cos(pi/12 * (3+0.5)); + win[i][1] *= cos(pi/12 * (4+0.5)); + win[i][4] *= cos(pi/12 * (4+0.5)); + win[i][2] *= cos(pi/12 * (5+0.5)); + win[i][3] *= cos(pi/12 * (5+0.5)); + } else { + for (j = 0; j < 9; j++) { + win[i][8-j] *= cos(pi/36 * (17-j+0.5)); + win[i][9+j] *= cos(pi/36 * (17-j+0.5)); + } + for (j = 0; j < 9; j++) { + win[i][18+8-j] *= cos(pi/36 * (j+0.5)); + win[i][18+9+j] *= cos(pi/36 * (j+0.5)); + } + } + } + for (i = 0; i < 4; i++) + for (j = 0; j < 36; j++) + win[i][j] *= 1.0 / sqrt(2); +*/ + const int imdctWin[4][36] PROGMEM = { - { - 0x02aace8b, 0x07311c28, 0x0a868fec, 0x0c913b52, 0x0d413ccd, 0x0c913b52, 0x0a868fec, 0x07311c28, - 0x02aace8b, 0xfd16d8dd, 0xf6a09e66, 0xef7a6275, 0xe7dbc161, 0xe0000000, 0xd8243e9f, 0xd0859d8b, - 0xc95f619a, 0xc2e92723, 0xbd553175, 0xb8cee3d8, 0xb5797014, 0xb36ec4ae, 0xb2bec333, 0xb36ec4ae, - 0xb5797014, 0xb8cee3d8, 0xbd553175, 0xc2e92723, 0xc95f619a, 0xd0859d8b, 0xd8243e9f, 0xe0000000, - 0xe7dbc161, 0xef7a6275, 0xf6a09e66, 0xfd16d8dd, - }, - { - 0x02aace8b, 0x07311c28, 0x0a868fec, 0x0c913b52, 0x0d413ccd, 0x0c913b52, 0x0a868fec, 0x07311c28, - 0x02aace8b, 0xfd16d8dd, 0xf6a09e66, 0xef7a6275, 0xe7dbc161, 0xe0000000, 0xd8243e9f, 0xd0859d8b, - 0xc95f619a, 0xc2e92723, 0xbd44ef14, 0xb831a052, 0xb3aa3837, 0xafb789a4, 0xac6145bb, 0xa9adecdc, - 0xa864491f, 0xad1868f0, 0xb8431f49, 0xc8f42236, 0xdda8e6b1, 0xf47755dc, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - }, - { - 0x07311c28, 0x0d413ccd, 0x07311c28, 0xf6a09e66, 0xe0000000, 0xc95f619a, 0xb8cee3d8, 0xb2bec333, - 0xb8cee3d8, 0xc95f619a, 0xe0000000, 0xf6a09e66, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - }, - { - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x028e9709, 0x04855ec0, - 0x026743a1, 0xfcde2c10, 0xf515dc82, 0xec93e53b, 0xe4c880f8, 0xdd5d0b08, 0xd63510b7, 0xcf5e834a, - 0xc8e6b562, 0xc2da4105, 0xbd553175, 0xb8cee3d8, 0xb5797014, 0xb36ec4ae, 0xb2bec333, 0xb36ec4ae, - 0xb5797014, 0xb8cee3d8, 0xbd553175, 0xc2e92723, 0xc95f619a, 0xd0859d8b, 0xd8243e9f, 0xe0000000, - 0xe7dbc161, 0xef7a6275, 0xf6a09e66, 0xfd16d8dd, - }, + { + 0x02aace8b, 0x07311c28, 0x0a868fec, 0x0c913b52, 0x0d413ccd, 0x0c913b52, 0x0a868fec, 0x07311c28, + 0x02aace8b, 0xfd16d8dd, 0xf6a09e66, 0xef7a6275, 0xe7dbc161, 0xe0000000, 0xd8243e9f, 0xd0859d8b, + 0xc95f619a, 0xc2e92723, 0xbd553175, 0xb8cee3d8, 0xb5797014, 0xb36ec4ae, 0xb2bec333, 0xb36ec4ae, + 0xb5797014, 0xb8cee3d8, 0xbd553175, 0xc2e92723, 0xc95f619a, 0xd0859d8b, 0xd8243e9f, 0xe0000000, + 0xe7dbc161, 0xef7a6275, 0xf6a09e66, 0xfd16d8dd, + }, + { + 0x02aace8b, 0x07311c28, 0x0a868fec, 0x0c913b52, 0x0d413ccd, 0x0c913b52, 0x0a868fec, 0x07311c28, + 0x02aace8b, 0xfd16d8dd, 0xf6a09e66, 0xef7a6275, 0xe7dbc161, 0xe0000000, 0xd8243e9f, 0xd0859d8b, + 0xc95f619a, 0xc2e92723, 0xbd44ef14, 0xb831a052, 0xb3aa3837, 0xafb789a4, 0xac6145bb, 0xa9adecdc, + 0xa864491f, 0xad1868f0, 0xb8431f49, 0xc8f42236, 0xdda8e6b1, 0xf47755dc, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + }, + { + 0x07311c28, 0x0d413ccd, 0x07311c28, 0xf6a09e66, 0xe0000000, 0xc95f619a, 0xb8cee3d8, 0xb2bec333, + 0xb8cee3d8, 0xc95f619a, 0xe0000000, 0xf6a09e66, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + }, + { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x028e9709, 0x04855ec0, + 0x026743a1, 0xfcde2c10, 0xf515dc82, 0xec93e53b, 0xe4c880f8, 0xdd5d0b08, 0xd63510b7, 0xcf5e834a, + 0xc8e6b562, 0xc2da4105, 0xbd553175, 0xb8cee3d8, 0xb5797014, 0xb36ec4ae, 0xb2bec333, 0xb36ec4ae, + 0xb5797014, 0xb8cee3d8, 0xbd553175, 0xc2e92723, 0xc95f619a, 0xd0859d8b, 0xd8243e9f, 0xe0000000, + 0xe7dbc161, 0xef7a6275, 0xf6a09e66, 0xfd16d8dd, + }, }; -/* indexing = [mid-side off/on][intensity scale factor] - * format = Q30, range = [0.0, 1.414] - * - * mid-side off: - * ISFMpeg1[0][i] = tan(i*pi/12) / [1 + tan(i*pi/12)] (left scalefactor) - * = 1 / [1 + tan(i*pi/12)] (right scalefactor) - * - * mid-side on: - * ISFMpeg1[1][i] = sqrt(2) * ISFMpeg1[0][i] - * - * output L = ISFMpeg1[midSide][isf][0] * input L - * output R = ISFMpeg1[midSide][isf][1] * input L - * - * obviously left scalefactor + right scalefactor = 1 (m-s off) or sqrt(2) (m-s on) - * so just store left and calculate right as 1 - left - * (can derive as right = ISFMpeg1[x][6] - left) - * - * if mid-side enabled, multiply joint stereo scale factors by sqrt(2) - * - we scaled whole spectrum by 1/sqrt(2) in Dequant for the M+S/sqrt(2) in MidSideProc - * - but the joint stereo part of the spectrum doesn't need this, so we have to undo it - * - * if scale factor is and illegal intensity position, this becomes a passthrough - * - gain = [1, 0] if mid-side off, since L is coded directly and R = 0 in this region - * - gain = [1, 1] if mid-side on, since L = (M+S)/sqrt(2), R = (M-S)/sqrt(2) - * - and since S = 0 in the joint stereo region (above NZB right) then L = R = M * 1.0 - */ +/* indexing = [mid-side off/on][intensity scale factor] + format = Q30, range = [0.0, 1.414] + + mid-side off: + ISFMpeg1[0][i] = tan(i*pi/12) / [1 + tan(i*pi/12)] (left scalefactor) + = 1 / [1 + tan(i*pi/12)] (right scalefactor) + + mid-side on: + ISFMpeg1[1][i] = sqrt(2) * ISFMpeg1[0][i] + + output L = ISFMpeg1[midSide][isf][0] * input L + output R = ISFMpeg1[midSide][isf][1] * input L + + obviously left scalefactor + right scalefactor = 1 (m-s off) or sqrt(2) (m-s on) + so just store left and calculate right as 1 - left + (can derive as right = ISFMpeg1[x][6] - left) + + if mid-side enabled, multiply joint stereo scale factors by sqrt(2) + - we scaled whole spectrum by 1/sqrt(2) in Dequant for the M+S/sqrt(2) in MidSideProc + - but the joint stereo part of the spectrum doesn't need this, so we have to undo it + + if scale factor is and illegal intensity position, this becomes a passthrough + - gain = [1, 0] if mid-side off, since L is coded directly and R = 0 in this region + - gain = [1, 1] if mid-side on, since L = (M+S)/sqrt(2), R = (M-S)/sqrt(2) + - and since S = 0 in the joint stereo region (above NZB right) then L = R = M * 1.0 +*/ const int ISFMpeg1[2][7] PROGMEM = { - {0x00000000, 0x0d8658ba, 0x176cf5d0, 0x20000000, 0x28930a2f, 0x3279a745, 0x40000000}, - {0x00000000, 0x13207f5c, 0x2120fb83, 0x2d413ccc, 0x39617e16, 0x4761fa3d, 0x5a827999} + {0x00000000, 0x0d8658ba, 0x176cf5d0, 0x20000000, 0x28930a2f, 0x3279a745, 0x40000000}, + {0x00000000, 0x13207f5c, 0x2120fb83, 0x2d413ccc, 0x39617e16, 0x4761fa3d, 0x5a827999} }; -/* indexing = [intensity scale on/off][mid-side off/on][intensity scale factor] - * format = Q30, range = [0.0, 1.414] - * - * if (isf == 0) kl = 1.0 kr = 1.0 - * else if (isf & 0x01 == 0x01) kl = i0^((isf+1)/2), kr = 1.0 - * else if (isf & 0x01 == 0x00) kl = 1.0, kr = i0^(isf/2) - * - * if (intensityScale == 1) i0 = 1/sqrt(2) = 0x2d413ccc (Q30) - * else i0 = 1/sqrt(sqrt(2)) = 0x35d13f32 (Q30) - * - * see comments for ISFMpeg1 (just above) regarding scaling, sqrt(2), etc. - * - * compress the MPEG2 table using the obvious identities above... - * for isf = [0, 1, 2, ... 30], let sf = table[(isf+1) >> 1] - * - if isf odd, L = sf*L, R = tab[0]*R - * - if isf even, L = tab[0]*L, R = sf*R - */ +/* indexing = [intensity scale on/off][mid-side off/on][intensity scale factor] + format = Q30, range = [0.0, 1.414] + + if (isf == 0) kl = 1.0 kr = 1.0 + else if (isf & 0x01 == 0x01) kl = i0^((isf+1)/2), kr = 1.0 + else if (isf & 0x01 == 0x00) kl = 1.0, kr = i0^(isf/2) + + if (intensityScale == 1) i0 = 1/sqrt(2) = 0x2d413ccc (Q30) + else i0 = 1/sqrt(sqrt(2)) = 0x35d13f32 (Q30) + + see comments for ISFMpeg1 (just above) regarding scaling, sqrt(2), etc. + + compress the MPEG2 table using the obvious identities above... + for isf = [0, 1, 2, ... 30], let sf = table[(isf+1) >> 1] + - if isf odd, L = sf*L, R = tab[0]*R + - if isf even, L = tab[0]*L, R = sf*R +*/ const int ISFMpeg2[2][2][16] PROGMEM = { -{ - { - /* intensityScale off, mid-side off */ - 0x40000000, 0x35d13f32, 0x2d413ccc, 0x260dfc14, 0x1fffffff, 0x1ae89f99, 0x16a09e66, 0x1306fe0a, - 0x0fffffff, 0x0d744fcc, 0x0b504f33, 0x09837f05, 0x07ffffff, 0x06ba27e6, 0x05a82799, 0x04c1bf82, - }, - { - /* intensityScale off, mid-side on */ - 0x5a827999, 0x4c1bf827, 0x3fffffff, 0x35d13f32, 0x2d413ccc, 0x260dfc13, 0x1fffffff, 0x1ae89f99, - 0x16a09e66, 0x1306fe09, 0x0fffffff, 0x0d744fcc, 0x0b504f33, 0x09837f04, 0x07ffffff, 0x06ba27e6, - }, -}, -{ - { - /* intensityScale on, mid-side off */ - 0x40000000, 0x2d413ccc, 0x20000000, 0x16a09e66, 0x10000000, 0x0b504f33, 0x08000000, 0x05a82799, - 0x04000000, 0x02d413cc, 0x02000000, 0x016a09e6, 0x01000000, 0x00b504f3, 0x00800000, 0x005a8279, - }, - /* intensityScale on, mid-side on */ - { - 0x5a827999, 0x3fffffff, 0x2d413ccc, 0x1fffffff, 0x16a09e66, 0x0fffffff, 0x0b504f33, 0x07ffffff, - 0x05a82799, 0x03ffffff, 0x02d413cc, 0x01ffffff, 0x016a09e6, 0x00ffffff, 0x00b504f3, 0x007fffff, - } -} + { + { + /* intensityScale off, mid-side off */ + 0x40000000, 0x35d13f32, 0x2d413ccc, 0x260dfc14, 0x1fffffff, 0x1ae89f99, 0x16a09e66, 0x1306fe0a, + 0x0fffffff, 0x0d744fcc, 0x0b504f33, 0x09837f05, 0x07ffffff, 0x06ba27e6, 0x05a82799, 0x04c1bf82, + }, + { + /* intensityScale off, mid-side on */ + 0x5a827999, 0x4c1bf827, 0x3fffffff, 0x35d13f32, 0x2d413ccc, 0x260dfc13, 0x1fffffff, 0x1ae89f99, + 0x16a09e66, 0x1306fe09, 0x0fffffff, 0x0d744fcc, 0x0b504f33, 0x09837f04, 0x07ffffff, 0x06ba27e6, + }, + }, + { + { + /* intensityScale on, mid-side off */ + 0x40000000, 0x2d413ccc, 0x20000000, 0x16a09e66, 0x10000000, 0x0b504f33, 0x08000000, 0x05a82799, + 0x04000000, 0x02d413cc, 0x02000000, 0x016a09e6, 0x01000000, 0x00b504f3, 0x00800000, 0x005a8279, + }, + /* intensityScale on, mid-side on */ + { + 0x5a827999, 0x3fffffff, 0x2d413ccc, 0x1fffffff, 0x16a09e66, 0x0fffffff, 0x0b504f33, 0x07ffffff, + 0x05a82799, 0x03ffffff, 0x02d413cc, 0x01ffffff, 0x016a09e6, 0x00ffffff, 0x00b504f3, 0x007fffff, + } + } }; -/* indexing = [intensity scale on/off][left/right] - * format = Q30, range = [0.0, 1.414] - * - * illegal intensity position scalefactors (see comments on ISFMpeg1) - */ +/* indexing = [intensity scale on/off][left/right] + format = Q30, range = [0.0, 1.414] + + illegal intensity position scalefactors (see comments on ISFMpeg1) +*/ const int ISFIIP[2][2] PROGMEM = { - {0x40000000, 0x00000000}, /* mid-side off */ - {0x40000000, 0x40000000}, /* mid-side on */ + {0x40000000, 0x00000000}, /* mid-side off */ + {0x40000000, 0x40000000}, /* mid-side on */ }; const unsigned char uniqueIDTab[8] = {0x5f, 0x4b, 0x43, 0x5f, 0x5f, 0x4a, 0x52, 0x5f}; -/* anti-alias coefficients - see spec Annex B, table 3-B.9 - * csa[0][i] = CSi, csa[1][i] = CAi - * format = Q31 - */ +/* anti-alias coefficients - see spec Annex B, table 3-B.9 + csa[0][i] = CSi, csa[1][i] = CAi + format = Q31 +*/ const int csa[8][2] PROGMEM = { - {0x6dc253f0, 0xbe2500aa}, - {0x70dcebe4, 0xc39e4949}, - {0x798d6e73, 0xd7e33f4a}, - {0x7ddd40a7, 0xe8b71176}, - {0x7f6d20b7, 0xf3e4fe2f}, - {0x7fe47e40, 0xfac1a3c7}, - {0x7ffcb263, 0xfe2ebdc6}, - {0x7fffc694, 0xff86c25d}, + {0x6dc253f0, 0xbe2500aa}, + {0x70dcebe4, 0xc39e4949}, + {0x798d6e73, 0xd7e33f4a}, + {0x7ddd40a7, 0xe8b71176}, + {0x7f6d20b7, 0xf3e4fe2f}, + {0x7fe47e40, 0xfac1a3c7}, + {0x7ffcb263, 0xfe2ebdc6}, + {0x7fffc694, 0xff86c25d}, }; -/* format = Q30, range = [0.0981, 1.9976] - * - * n = 16; - * k = 0; - * for(i=0; i<5; i++, n=n/2) { - * for(p=0; pinit() - * DESCRIPTION: initialize bit pointer struct - */ -void mad_bit_init(struct mad_bitptr *bitptr, unsigned char const *byte) -{ - stack(__FUNCTION__, __FILE__, __LINE__); - bitptr->byte = byte; - bitptr->cache = 0; - bitptr->left = CHAR_BIT; + NAME: bit->init() + DESCRIPTION: initialize bit pointer struct +*/ +void mad_bit_init(struct mad_bitptr *bitptr, unsigned char const *byte) { + stackenter(__FUNCTION__, __FILE__, __LINE__); + bitptr->byte = byte; + bitptr->cache = 0; + bitptr->left = CHAR_BIT; } /* - * NAME: bit->length() - * DESCRIPTION: return number of bits between start and end points - */ + NAME: bit->length() + DESCRIPTION: return number of bits between start and end points +*/ unsigned int mad_bit_length(struct mad_bitptr const *begin, - struct mad_bitptr const *end) -{ -stack(__FUNCTION__, __FILE__, __LINE__); - return begin->left + - CHAR_BIT * (end->byte - (begin->byte + 1)) + (CHAR_BIT - end->left); + struct mad_bitptr const *end) { + stackenter(__FUNCTION__, __FILE__, __LINE__); + return begin->left + + CHAR_BIT * (end->byte - (begin->byte + 1)) + (CHAR_BIT - end->left); } /* - * NAME: bit->nextbyte() - * DESCRIPTION: return pointer to next unprocessed byte - */ -unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *bitptr) -{ -stack(__FUNCTION__, __FILE__, __LINE__); - return bitptr->left == CHAR_BIT ? bitptr->byte : bitptr->byte + 1; + NAME: bit->nextbyte() + DESCRIPTION: return pointer to next unprocessed byte +*/ +unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *bitptr) { + stackenter(__FUNCTION__, __FILE__, __LINE__); + return bitptr->left == CHAR_BIT ? bitptr->byte : bitptr->byte + 1; } /* - * NAME: bit->skip() - * DESCRIPTION: advance bit pointer - */ -void mad_bit_skip(struct mad_bitptr *bitptr, unsigned int len) -{ -stack(__FUNCTION__, __FILE__, __LINE__); - bitptr->byte += len / CHAR_BIT; - bitptr->left -= len % CHAR_BIT; - - if (bitptr->left > CHAR_BIT) { - bitptr->byte++; - bitptr->left += CHAR_BIT; - } - - if (bitptr->left < CHAR_BIT) - bitptr->cache = *bitptr->byte; + NAME: bit->skip() + DESCRIPTION: advance bit pointer +*/ +void mad_bit_skip(struct mad_bitptr *bitptr, unsigned int len) { + stackenter(__FUNCTION__, __FILE__, __LINE__); + bitptr->byte += len / CHAR_BIT; + bitptr->left -= len % CHAR_BIT; + + if (bitptr->left > CHAR_BIT) { + bitptr->byte++; + bitptr->left += CHAR_BIT; + } + + if (bitptr->left < CHAR_BIT) { + bitptr->cache = *bitptr->byte; + } } /* - * NAME: bit->read() - * DESCRIPTION: read an arbitrary number of bits and return their UIMSBF value - */ -unsigned long mad_bit_read(struct mad_bitptr *bitptr, unsigned int len) -{ - unsigned long value; + NAME: bit->read() + DESCRIPTION: read an arbitrary number of bits and return their UIMSBF value +*/ +unsigned long mad_bit_read(struct mad_bitptr *bitptr, unsigned int len) { + unsigned long value; - if (bitptr->left == CHAR_BIT) - bitptr->cache = *bitptr->byte; + if (bitptr->left == CHAR_BIT) { + bitptr->cache = *bitptr->byte; + } - if (len < bitptr->left) { - value = (bitptr->cache & ((1 << bitptr->left) - 1)) >> - (bitptr->left - len); - bitptr->left -= len; + if (len < bitptr->left) { + value = (bitptr->cache & ((1 << bitptr->left) - 1)) >> + (bitptr->left - len); + bitptr->left -= len; - return value; - } + return value; + } - /* remaining bits in current byte */ + /* remaining bits in current byte */ - value = bitptr->cache & ((1 << bitptr->left) - 1); - len -= bitptr->left; + value = bitptr->cache & ((1 << bitptr->left) - 1); + len -= bitptr->left; - bitptr->byte++; - bitptr->left = CHAR_BIT; + bitptr->byte++; + bitptr->left = CHAR_BIT; - /* more bytes */ + /* more bytes */ - while (len >= CHAR_BIT) { - value = (value << CHAR_BIT) | *bitptr->byte++; - len -= CHAR_BIT; - } + while (len >= CHAR_BIT) { + value = (value << CHAR_BIT) | *bitptr->byte++; + len -= CHAR_BIT; + } - if (len > 0) { - bitptr->cache = *bitptr->byte; + if (len > 0) { + bitptr->cache = *bitptr->byte; - value = (value << len) | (bitptr->cache >> (CHAR_BIT - len)); - bitptr->left -= len; - } + value = (value << len) | (bitptr->cache >> (CHAR_BIT - len)); + bitptr->left -= len; + } - return value; + return value; } # if 0 /* - * NAME: bit->write() - * DESCRIPTION: write an arbitrary number of bits - */ + NAME: bit->write() + DESCRIPTION: write an arbitrary number of bits +*/ void mad_bit_write(struct mad_bitptr *bitptr, unsigned int len, - unsigned long value) -{ - unsigned char *ptr; -stack(__FUNCTION__, __FILE__, __LINE__); + unsigned long value) { + unsigned char *ptr; + stackenter(__FUNCTION__, __FILE__, __LINE__); - ptr = (unsigned char *) bitptr->byte; + ptr = (unsigned char *) bitptr->byte; - /* ... */ + /* ... */ } # endif /* - * NAME: bit->crc() - * DESCRIPTION: compute CRC-check word - */ + NAME: bit->crc() + DESCRIPTION: compute CRC-check word +*/ unsigned short mad_bit_crc(struct mad_bitptr bitptr, unsigned int len, - unsigned short init) -{ - unsigned int crc; -stack(__FUNCTION__, __FILE__, __LINE__); + unsigned short init) { + unsigned int crc; + stackenter(__FUNCTION__, __FILE__, __LINE__); - for (crc = init; len >= 32; len -= 32) { - unsigned long data; + for (crc = init; len >= 32; len -= 32) { + unsigned long data; - data = mad_bit_read(&bitptr, 32); + data = mad_bit_read(&bitptr, 32); - crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 24)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 16)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 8)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 0)) & 0xff]; - } + crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 24)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 16)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 8)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 0)) & 0xff]; + } - switch (len / 8) { - case 3: crc = (crc << 8) ^ - crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; - /* Falls Through. */ - case 2: crc = (crc << 8) ^ - crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; - /* Falls Through. */ - case 1: crc = (crc << 8) ^ - crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; + switch (len / 8) { + case 3: crc = (crc << 8) ^ + crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; + /* Falls Through. */ + case 2: crc = (crc << 8) ^ + crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; + /* Falls Through. */ + case 1: crc = (crc << 8) ^ + crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; - len %= 8; - /* Falls Through. */ + len %= 8; + /* Falls Through. */ - case 0: break; - } + case 0: break; + } - while (len--) { - unsigned int msb; + while (len--) { + unsigned int msb; - msb = mad_bit_read(&bitptr, 1) ^ (crc >> 15); + msb = mad_bit_read(&bitptr, 1) ^ (crc >> 15); - crc <<= 1; - if (msb & 1) - crc ^= CRC_POLY; - } + crc <<= 1; + if (msb & 1) { + crc ^= CRC_POLY; + } + } - return crc & 0xffff; + return crc & 0xffff; } diff --git a/src/libmad/bit.h b/src/libmad/bit.h index 5a51570b..17ec824e 100644 --- a/src/libmad/bit.h +++ b/src/libmad/bit.h @@ -1,31 +1,31 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: bit.h,v 1.12 2004/01/23 09:41:32 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: bit.h,v 1.12 2004/01/23 09:41:32 rob Exp $ +*/ # ifndef LIBMAD_BIT_H # define LIBMAD_BIT_H struct mad_bitptr { - unsigned char const *byte; - unsigned short cache; - unsigned short left; + unsigned char const *byte; + unsigned short cache; + unsigned short left; }; void mad_bit_init(struct mad_bitptr *, unsigned char const *); @@ -33,7 +33,7 @@ void mad_bit_init(struct mad_bitptr *, unsigned char const *); # define mad_bit_finish(bitptr) /* nothing */ unsigned int mad_bit_length(struct mad_bitptr const *, - struct mad_bitptr const *); + struct mad_bitptr const *); # define mad_bit_bitsleft(bitptr) ((bitptr)->left) unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *); diff --git a/src/libmad/config.h b/src/libmad/config.h index 0b50c3a9..219c12bd 100644 --- a/src/libmad/config.h +++ b/src/libmad/config.h @@ -5,7 +5,7 @@ /* #undef DEBUG */ // Uncomment to show heap and stack space on entry -#define stack(a,b,c) +#define stackenter(a,b,c) // Helper function to see if we can allocate one chunk on the stack # ifdef __cplusplus @@ -96,8 +96,8 @@ extern int stackfree(); /* Define to enable a fast subband synthesis approximation optimization. */ #define OPT_SSO 1 -/* Define to influence a strict interpretation of the ISO/IEC standards, even - if this is in opposition with best accepted practices. */ +/* Define to influence a strict interpretation of the ISO/IEC standards, even + if this is in opposition with best accepted practices. */ #undef OPT_STRICT /* Name of package */ @@ -133,15 +133,15 @@ extern int stackfree(); /* Version number of package */ #define VERSION "0.15.1b-esp8266" -/* Define to 1 if your processor stores words with the most significant byte - first (like Motorola and SPARC, unlike Intel and VAX). */ +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ #undef WORDS_BIGENDIAN /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus /* #undef inline */ #endif diff --git a/src/libmad/decoder.c b/src/libmad/decoder.c index 22c62b8f..0d8134c7 100644 --- a/src/libmad/decoder.c +++ b/src/libmad/decoder.c @@ -1,22 +1,22 @@ /* - libmad - MPEG audio decoder library - Copyright (C) 2000-2004 Underbit Technologies, Inc. + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - $Id: decoder.c,v 1.22 2004/01/23 09:41:32 rob Exp $ + $Id: decoder.c,v 1.22 2004/01/23 09:41:32 rob Exp $ */ #pragma GCC optimize ("O3") @@ -53,533 +53,538 @@ # include "decoder.h" /* - NAME: decoder->init() - DESCRIPTION: initialize a decoder object with callback routines + NAME: decoder->init() + DESCRIPTION: initialize a decoder object with callback routines */ void mad_decoder_init(struct mad_decoder *decoder, void *data, - enum mad_flow (*input_func)(void *, - struct mad_stream *), - enum mad_flow (*header_func)(void *, - struct mad_header const *), - enum mad_flow (*filter_func)(void *, - struct mad_stream const *, - struct mad_frame *), - enum mad_flow (*output_func)(void *, - struct mad_header const *, - struct mad_pcm *), - enum mad_flow (*error_func)(void *, - struct mad_stream *, - struct mad_frame *), - enum mad_flow (*message_func)(void *, - void *, unsigned int *)) -{ - decoder->mode = -1; - - decoder->options = 0; - - decoder->async.pid = 0; - decoder->async.in = -1; - decoder->async.out = -1; - - decoder->sync = 0; - - decoder->cb_data = data; - - decoder->input_func = input_func; - decoder->header_func = header_func; - decoder->filter_func = filter_func; - decoder->output_func = output_func; - decoder->error_func = error_func; - decoder->message_func = message_func; + enum mad_flow(*input_func)(void *, + struct mad_stream *), + enum mad_flow(*header_func)(void *, + struct mad_header const *), + enum mad_flow(*filter_func)(void *, + struct mad_stream const *, + struct mad_frame *), + enum mad_flow(*output_func)(void *, + struct mad_header const *, + struct mad_pcm *), + enum mad_flow(*error_func)(void *, + struct mad_stream *, + struct mad_frame *), + enum mad_flow(*message_func)(void *, + void *, unsigned int *)) { + decoder->mode = -1; + + decoder->options = 0; + + decoder->async.pid = 0; + decoder->async.in = -1; + decoder->async.out = -1; + + decoder->sync = 0; + + decoder->cb_data = data; + + decoder->input_func = input_func; + decoder->header_func = header_func; + decoder->filter_func = filter_func; + decoder->output_func = output_func; + decoder->error_func = error_func; + decoder->message_func = message_func; } -int mad_decoder_finish(struct mad_decoder *decoder) -{ +int mad_decoder_finish(struct mad_decoder *decoder) { (void)decoder; # if defined(USE_ASYNC) - if (decoder->mode == MAD_DECODER_MODE_ASYNC && decoder->async.pid) { - pid_t pid; - int status; + if (decoder->mode == MAD_DECODER_MODE_ASYNC && decoder->async.pid) { + pid_t pid; + int status; - close(decoder->async.in); + close(decoder->async.in); - do - pid = waitpid(decoder->async.pid, &status, 0); - while (pid == -1 && errno == EINTR); + do { + pid = waitpid(decoder->async.pid, &status, 0); + } while (pid == -1 && errno == EINTR); - decoder->mode = -1; + decoder->mode = -1; - close(decoder->async.out); + close(decoder->async.out); - decoder->async.pid = 0; - decoder->async.in = -1; - decoder->async.out = -1; + decoder->async.pid = 0; + decoder->async.in = -1; + decoder->async.out = -1; - if (pid == -1) - return -1; + if (pid == -1) { + return -1; + } - return (!WIFEXITED(status) || WEXITSTATUS(status)) ? -1 : 0; - } + return (!WIFEXITED(status) || WEXITSTATUS(status)) ? -1 : 0; + } # endif - return 0; + return 0; } # if defined(USE_ASYNC) static -enum mad_flow send_io(int fd, void const *data, size_t len) -{ - char const *ptr = data; - ssize_t count; +enum mad_flow send_io(int fd, void const *data, size_t len) { + char const *ptr = data; + ssize_t count; - while (len) { - do - count = write(fd, ptr, len); - while (count == -1 && errno == EINTR); + while (len) { + do { + count = write(fd, ptr, len); + } while (count == -1 && errno == EINTR); - if (count == -1) - return MAD_FLOW_BREAK; + if (count == -1) { + return MAD_FLOW_BREAK; + } - len -= count; - ptr += count; - } + len -= count; + ptr += count; + } - return MAD_FLOW_CONTINUE; + return MAD_FLOW_CONTINUE; } static -enum mad_flow receive_io(int fd, void *buffer, size_t len) -{ - char *ptr = buffer; - ssize_t count; - - while (len) { - do - count = read(fd, ptr, len); - while (count == -1 && errno == EINTR); - - if (count == -1) - return (errno == EAGAIN) ? MAD_FLOW_IGNORE : MAD_FLOW_BREAK; - else if (count == 0) - return MAD_FLOW_STOP; - - len -= count; - ptr += count; - } - - return MAD_FLOW_CONTINUE; +enum mad_flow receive_io(int fd, void *buffer, size_t len) { + char *ptr = buffer; + ssize_t count; + + while (len) { + do { + count = read(fd, ptr, len); + } while (count == -1 && errno == EINTR); + + if (count == -1) { + return (errno == EAGAIN) ? MAD_FLOW_IGNORE : MAD_FLOW_BREAK; + } else if (count == 0) { + return MAD_FLOW_STOP; + } + + len -= count; + ptr += count; + } + + return MAD_FLOW_CONTINUE; } static -enum mad_flow receive_io_blocking(int fd, void *buffer, size_t len) -{ - int flags, blocking; - enum mad_flow result; +enum mad_flow receive_io_blocking(int fd, void *buffer, size_t len) { + int flags, blocking; + enum mad_flow result; - flags = fcntl(fd, F_GETFL); - if (flags == -1) - return MAD_FLOW_BREAK; + flags = fcntl(fd, F_GETFL); + if (flags == -1) { + return MAD_FLOW_BREAK; + } - blocking = flags & ~O_NONBLOCK; + blocking = flags & ~O_NONBLOCK; - if (blocking != flags && - fcntl(fd, F_SETFL, blocking) == -1) - return MAD_FLOW_BREAK; + if (blocking != flags && + fcntl(fd, F_SETFL, blocking) == -1) { + return MAD_FLOW_BREAK; + } - result = receive_io(fd, buffer, len); + result = receive_io(fd, buffer, len); - if (flags != blocking && - fcntl(fd, F_SETFL, flags) == -1) - return MAD_FLOW_BREAK; + if (flags != blocking && + fcntl(fd, F_SETFL, flags) == -1) { + return MAD_FLOW_BREAK; + } - return result; + return result; } static -enum mad_flow send(int fd, void const *message, unsigned int size) -{ - enum mad_flow result; +enum mad_flow send(int fd, void const *message, unsigned int size) { + enum mad_flow result; - /* send size */ + /* send size */ - result = send_io(fd, &size, sizeof(size)); + result = send_io(fd, &size, sizeof(size)); - /* send message */ + /* send message */ - if (result == MAD_FLOW_CONTINUE) - result = send_io(fd, message, size); + if (result == MAD_FLOW_CONTINUE) { + result = send_io(fd, message, size); + } - return result; + return result; } static -enum mad_flow receive(int fd, void **message, unsigned int *size) -{ - enum mad_flow result; - unsigned int actual; +enum mad_flow receive(int fd, void **message, unsigned int *size) { + enum mad_flow result; + unsigned int actual; - if (*message == 0) - *size = 0; + if (*message == 0) { + *size = 0; + } - /* receive size */ + /* receive size */ - result = receive_io(fd, &actual, sizeof(actual)); + result = receive_io(fd, &actual, sizeof(actual)); - /* receive message */ + /* receive message */ - if (result == MAD_FLOW_CONTINUE) { - if (actual > *size) - actual -= *size; - else { - *size = actual; - actual = 0; - } + if (result == MAD_FLOW_CONTINUE) { + if (actual > *size) { + actual -= *size; + } else { + *size = actual; + actual = 0; + } - if (*size > 0) { - if (*message == 0) { - *message = malloc(*size); - if (*message == 0) - return MAD_FLOW_BREAK; - } + if (*size > 0) { + if (*message == 0) { + *message = malloc(*size); + if (*message == 0) { + return MAD_FLOW_BREAK; + } + } - result = receive_io_blocking(fd, *message, *size); - } + result = receive_io_blocking(fd, *message, *size); + } - /* throw away remainder of message */ + /* throw away remainder of message */ - while (actual && result == MAD_FLOW_CONTINUE) { - char sink[256]; - unsigned int len; + while (actual && result == MAD_FLOW_CONTINUE) { + char sink[256]; + unsigned int len; - len = actual > sizeof(sink) ? sizeof(sink) : actual; + len = actual > sizeof(sink) ? sizeof(sink) : actual; - result = receive_io_blocking(fd, sink, len); + result = receive_io_blocking(fd, sink, len); - actual -= len; + actual -= len; + } } - } - return result; + return result; } static -enum mad_flow check_message(struct mad_decoder *decoder) -{ - enum mad_flow result; - void *message = 0; - unsigned int size; - - result = receive(decoder->async.in, &message, &size); - - if (result == MAD_FLOW_CONTINUE) { - if (decoder->message_func == 0) - size = 0; - else { - result = decoder->message_func(decoder->cb_data, message, &size); - - if (result == MAD_FLOW_IGNORE || - result == MAD_FLOW_BREAK) - size = 0; - } +enum mad_flow check_message(struct mad_decoder *decoder) { + enum mad_flow result; + void *message = 0; + unsigned int size; + + result = receive(decoder->async.in, &message, &size); + + if (result == MAD_FLOW_CONTINUE) { + if (decoder->message_func == 0) { + size = 0; + } else { + result = decoder->message_func(decoder->cb_data, message, &size); + + if (result == MAD_FLOW_IGNORE || + result == MAD_FLOW_BREAK) { + size = 0; + } + } - if (send(decoder->async.out, message, size) != MAD_FLOW_CONTINUE) - result = MAD_FLOW_BREAK; - } + if (send(decoder->async.out, message, size) != MAD_FLOW_CONTINUE) { + result = MAD_FLOW_BREAK; + } + } - if (message) - free(message); + if (message) { + free(message); + } - return result; + return result; } # endif static enum mad_flow error_default(void *data, struct mad_stream *stream, - struct mad_frame *frame) -{ - int *bad_last_frame = data; + struct mad_frame *frame) { + int *bad_last_frame = data; - switch (stream->error) { + switch (stream->error) { case MAD_ERROR_BADCRC: - if (*bad_last_frame) - mad_frame_mute(frame); - else - *bad_last_frame = 1; + if (*bad_last_frame) { + mad_frame_mute(frame); + } else { + *bad_last_frame = 1; + } - return MAD_FLOW_IGNORE; + return MAD_FLOW_IGNORE; default: - return MAD_FLOW_CONTINUE; - } + return MAD_FLOW_CONTINUE; + } } static -int run_sync(struct mad_decoder *decoder) -{ - enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); - void *error_data; - int bad_last_frame = 0; - struct mad_stream *stream; - struct mad_frame *frame; - struct mad_synth *synth; - int result = 0; - stack(__FUNCTION__, __FILE__, __LINE__); - - if (decoder->input_func == 0) - return 0; +int run_sync(struct mad_decoder *decoder) { + enum mad_flow(*error_func)(void *, struct mad_stream *, struct mad_frame *); + void *error_data; + int bad_last_frame = 0; + struct mad_stream *stream; + struct mad_frame *frame; + struct mad_synth *synth; + int result = 0; + stackenter(__FUNCTION__, __FILE__, __LINE__); + + if (decoder->input_func == 0) { + return 0; + } - if (decoder->error_func) { - error_func = decoder->error_func; - error_data = decoder->cb_data; - } - else { - error_func = error_default; - error_data = &bad_last_frame; - } - - stream = &decoder->sync->stream; - frame = &decoder->sync->frame; - synth = &decoder->sync->synth; - - mad_stream_init(stream); - mad_frame_init(frame); - mad_synth_init(synth); - - mad_stream_options(stream, decoder->options); - - do { - switch (decoder->input_func(decoder->cb_data, stream)) { - case MAD_FLOW_STOP: - goto done; - case MAD_FLOW_BREAK: - goto fail; - case MAD_FLOW_IGNORE: - continue; - case MAD_FLOW_CONTINUE: - break; + if (decoder->error_func) { + error_func = decoder->error_func; + error_data = decoder->cb_data; + } else { + error_func = error_default; + error_data = &bad_last_frame; } - while (1) { -# if defined(USE_ASYNC) - if (decoder->mode == MAD_DECODER_MODE_ASYNC) { - switch (check_message(decoder)) { - case MAD_FLOW_IGNORE: - case MAD_FLOW_CONTINUE: - break; - case MAD_FLOW_BREAK: - goto fail; - case MAD_FLOW_STOP: - goto done; - } - } -# endif + stream = &decoder->sync->stream; + frame = &decoder->sync->frame; + synth = &decoder->sync->synth; - if (decoder->header_func) { - if (mad_header_decode(&frame->header, stream) == -1) { - if (!MAD_RECOVERABLE(stream->error)) - break; + mad_stream_init(stream); + mad_frame_init(frame); + mad_synth_init(synth); - switch (error_func(error_data, stream, frame)) { - case MAD_FLOW_STOP: - goto done; - case MAD_FLOW_BREAK: - goto fail; - case MAD_FLOW_IGNORE: - case MAD_FLOW_CONTINUE: - default: - continue; - } - } + mad_stream_options(stream, decoder->options); - switch (decoder->header_func(decoder->cb_data, &frame->header)) { - case MAD_FLOW_STOP: + do { + switch (decoder->input_func(decoder->cb_data, stream)) { + case MAD_FLOW_STOP: goto done; - case MAD_FLOW_BREAK: + case MAD_FLOW_BREAK: goto fail; - case MAD_FLOW_IGNORE: + case MAD_FLOW_IGNORE: continue; - case MAD_FLOW_CONTINUE: + case MAD_FLOW_CONTINUE: break; } - } - if (mad_frame_decode(frame, stream) == -1) { - if (!MAD_RECOVERABLE(stream->error)) - break; - switch (error_func(error_data, stream, frame)) { - case MAD_FLOW_STOP: - goto done; - case MAD_FLOW_BREAK: - goto fail; - case MAD_FLOW_IGNORE: - break; - case MAD_FLOW_CONTINUE: - default: - continue; - } - } - else - bad_last_frame = 0; + while (1) { +# if defined(USE_ASYNC) + if (decoder->mode == MAD_DECODER_MODE_ASYNC) { + switch (check_message(decoder)) { + case MAD_FLOW_IGNORE: + case MAD_FLOW_CONTINUE: + break; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_STOP: + goto done; + } + } +# endif - if (decoder->filter_func) { - switch (decoder->filter_func(decoder->cb_data, stream, frame)) { - case MAD_FLOW_STOP: - goto done; - case MAD_FLOW_BREAK: - goto fail; - case MAD_FLOW_IGNORE: - continue; - case MAD_FLOW_CONTINUE: - break; + if (decoder->header_func) { + if (mad_header_decode(&frame->header, stream) == -1) { + if (!MAD_RECOVERABLE(stream->error)) { + break; + } + + switch (error_func(error_data, stream, frame)) { + case MAD_FLOW_STOP: + goto done; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_IGNORE: + case MAD_FLOW_CONTINUE: + default: + continue; + } + } + + switch (decoder->header_func(decoder->cb_data, &frame->header)) { + case MAD_FLOW_STOP: + goto done; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_IGNORE: + continue; + case MAD_FLOW_CONTINUE: + break; + } + } + if (mad_frame_decode(frame, stream) == -1) { + if (!MAD_RECOVERABLE(stream->error)) { + break; + } + + switch (error_func(error_data, stream, frame)) { + case MAD_FLOW_STOP: + goto done; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_IGNORE: + break; + case MAD_FLOW_CONTINUE: + default: + continue; + } + } else { + bad_last_frame = 0; + } + + if (decoder->filter_func) { + switch (decoder->filter_func(decoder->cb_data, stream, frame)) { + case MAD_FLOW_STOP: + goto done; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_IGNORE: + continue; + case MAD_FLOW_CONTINUE: + break; + } + } + + // mad_synth_frame(synth, frame, decoder->output_func); + if (decoder->output_func) { + // switch (decoder->output_func(decoder->cb_data, &frame->header, &synth->pcm)) { + switch (mad_synth_frame(synth, frame, decoder->output_func, decoder->cb_data)) { //decoder->output_func(decoder->cb_data, &frame->header, &synth->pcm)) { + case MAD_FLOW_STOP: + goto done; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_IGNORE: + case MAD_FLOW_CONTINUE: + break; + } + } } - } - - // mad_synth_frame(synth, frame, decoder->output_func); - if (decoder->output_func) { - // switch (decoder->output_func(decoder->cb_data, &frame->header, &synth->pcm)) { - switch (mad_synth_frame(synth, frame, decoder->output_func, decoder->cb_data)) { //decoder->output_func(decoder->cb_data, &frame->header, &synth->pcm)) { - case MAD_FLOW_STOP: - goto done; - case MAD_FLOW_BREAK: - goto fail; - case MAD_FLOW_IGNORE: - case MAD_FLOW_CONTINUE: - break; - } - } - } - } - while (stream->error == MAD_ERROR_BUFLEN); + } while (stream->error == MAD_ERROR_BUFLEN); fail: - result = -1; + result = -1; done: - mad_synth_finish(synth); - mad_frame_finish(frame); - mad_stream_finish(stream); + mad_synth_finish(synth); + mad_frame_finish(frame); + mad_stream_finish(stream); - return result; + return result; } # if defined(USE_ASYNC) static -int run_async(struct mad_decoder *decoder) -{ - pid_t pid; - int ptoc[2], ctop[2], flags; +int run_async(struct mad_decoder *decoder) { + pid_t pid; + int ptoc[2], ctop[2], flags; - if (pipe(ptoc) == -1) - return -1; + if (pipe(ptoc) == -1) { + return -1; + } - if (pipe(ctop) == -1) { - close(ptoc[0]); - close(ptoc[1]); - return -1; - } + if (pipe(ctop) == -1) { + close(ptoc[0]); + close(ptoc[1]); + return -1; + } - flags = fcntl(ptoc[0], F_GETFL); - if (flags == -1 || - fcntl(ptoc[0], F_SETFL, flags | O_NONBLOCK) == -1) { - close(ctop[0]); - close(ctop[1]); - close(ptoc[0]); - close(ptoc[1]); - return -1; - } + flags = fcntl(ptoc[0], F_GETFL); + if (flags == -1 || + fcntl(ptoc[0], F_SETFL, flags | O_NONBLOCK) == -1) { + close(ctop[0]); + close(ctop[1]); + close(ptoc[0]); + close(ptoc[1]); + return -1; + } - pid = fork(); - if (pid == -1) { - close(ctop[0]); - close(ctop[1]); - close(ptoc[0]); - close(ptoc[1]); - return -1; - } + pid = fork(); + if (pid == -1) { + close(ctop[0]); + close(ctop[1]); + close(ptoc[0]); + close(ptoc[1]); + return -1; + } - decoder->async.pid = pid; + decoder->async.pid = pid; - if (pid) { - /* parent */ + if (pid) { + /* parent */ - close(ptoc[0]); - close(ctop[1]); + close(ptoc[0]); + close(ctop[1]); - decoder->async.in = ctop[0]; - decoder->async.out = ptoc[1]; + decoder->async.in = ctop[0]; + decoder->async.out = ptoc[1]; - return 0; - } + return 0; + } - /* child */ + /* child */ - close(ptoc[1]); - close(ctop[0]); + close(ptoc[1]); + close(ctop[0]); - decoder->async.in = ptoc[0]; - decoder->async.out = ctop[1]; + decoder->async.in = ptoc[0]; + decoder->async.out = ctop[1]; - _exit(run_sync(decoder)); + _exit(run_sync(decoder)); - /* not reached */ - return -1; + /* not reached */ + return -1; } # endif /* - NAME: decoder->run() - DESCRIPTION: run the decoder thread either synchronously or asynchronously + NAME: decoder->run() + DESCRIPTION: run the decoder thread either synchronously or asynchronously */ -int mad_decoder_run(struct mad_decoder *decoder, enum mad_decoder_mode mode) -{ - int result; - int (*run)(struct mad_decoder *) = 0; +int mad_decoder_run(struct mad_decoder *decoder, enum mad_decoder_mode mode) { + int result; + int (*run)(struct mad_decoder *) = 0; - switch (decoder->mode = mode) { + switch (decoder->mode = mode) { case MAD_DECODER_MODE_SYNC: - run = run_sync; - break; + run = run_sync; + break; case MAD_DECODER_MODE_ASYNC: # if defined(USE_ASYNC) - run = run_async; + run = run_async; # endif - break; - } + break; + } - if (run == 0) - return -1; + if (run == 0) { + return -1; + } - decoder->sync = malloc(sizeof(*decoder->sync)); - if (decoder->sync == 0) - return -1; + decoder->sync = malloc(sizeof(*decoder->sync)); + if (decoder->sync == 0) { + return -1; + } - result = run(decoder); + result = run(decoder); - free(decoder->sync); - decoder->sync = 0; + free(decoder->sync); + decoder->sync = 0; - return result; + return result; } /* - NAME: decoder->message() - DESCRIPTION: send a message to and receive a reply from the decoder process + NAME: decoder->message() + DESCRIPTION: send a message to and receive a reply from the decoder process */ int mad_decoder_message(struct mad_decoder *decoder, - void *message, unsigned int *len) -{ + void *message, unsigned int *len) { # if defined(USE_ASYNC) - if (decoder->mode != MAD_DECODER_MODE_ASYNC || - send(decoder->async.out, message, *len) != MAD_FLOW_CONTINUE || - receive(decoder->async.in, &message, len) != MAD_FLOW_CONTINUE) - return -1; + if (decoder->mode != MAD_DECODER_MODE_ASYNC || + send(decoder->async.out, message, *len) != MAD_FLOW_CONTINUE || + receive(decoder->async.in, &message, len) != MAD_FLOW_CONTINUE) { + return -1; + } - return 0; + return 0; # else - (void) decoder; - (void) message; - (void) len; - return -1; + (void) decoder; + (void) message; + (void) len; + return -1; # endif } diff --git a/src/libmad/decoder.h b/src/libmad/decoder.h index f0ad758d..b5056db2 100644 --- a/src/libmad/decoder.h +++ b/src/libmad/decoder.h @@ -1,23 +1,23 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: decoder.h,v 1.17 2004/01/23 09:41:32 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: decoder.h,v 1.17 2004/01/23 09:41:32 rob Exp $ +*/ # ifndef LIBMAD_DECODER_H # define LIBMAD_DECODER_H @@ -27,59 +27,59 @@ # include "synth.h" enum mad_decoder_mode { - MAD_DECODER_MODE_SYNC = 0, - MAD_DECODER_MODE_ASYNC + MAD_DECODER_MODE_SYNC = 0, + MAD_DECODER_MODE_ASYNC }; enum mad_flow { - MAD_FLOW_CONTINUE = 0x0000, /* continue normally */ - MAD_FLOW_STOP = 0x0010, /* stop decoding normally */ - MAD_FLOW_BREAK = 0x0011, /* stop decoding and signal an error */ - MAD_FLOW_IGNORE = 0x0020 /* ignore the current frame */ + MAD_FLOW_CONTINUE = 0x0000, /* continue normally */ + MAD_FLOW_STOP = 0x0010, /* stop decoding normally */ + MAD_FLOW_BREAK = 0x0011, /* stop decoding and signal an error */ + MAD_FLOW_IGNORE = 0x0020 /* ignore the current frame */ }; struct mad_decoder { - enum mad_decoder_mode mode; - - int options; - - struct { - long pid; - int in; - int out; - } async; - - struct { - struct mad_stream stream; - struct mad_frame frame; - struct mad_synth synth; - } *sync; - - void *cb_data; - - enum mad_flow (*input_func)(void *, struct mad_stream *); - enum mad_flow (*header_func)(void *, struct mad_header const *); - enum mad_flow (*filter_func)(void *, - struct mad_stream const *, struct mad_frame *); - enum mad_flow (*output_func)(void *, - struct mad_header const *, struct mad_pcm *); - enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); - enum mad_flow (*message_func)(void *, void *, unsigned int *); + enum mad_decoder_mode mode; + + int options; + + struct { + long pid; + int in; + int out; + } async; + + struct { + struct mad_stream stream; + struct mad_frame frame; + struct mad_synth synth; + } *sync; + + void *cb_data; + + enum mad_flow(*input_func)(void *, struct mad_stream *); + enum mad_flow(*header_func)(void *, struct mad_header const *); + enum mad_flow(*filter_func)(void *, + struct mad_stream const *, struct mad_frame *); + enum mad_flow(*output_func)(void *, + struct mad_header const *, struct mad_pcm *); + enum mad_flow(*error_func)(void *, struct mad_stream *, struct mad_frame *); + enum mad_flow(*message_func)(void *, void *, unsigned int *); }; void mad_decoder_init(struct mad_decoder *, void *, - enum mad_flow (*)(void *, struct mad_stream *), - enum mad_flow (*)(void *, struct mad_header const *), - enum mad_flow (*)(void *, - struct mad_stream const *, - struct mad_frame *), - enum mad_flow (*)(void *, - struct mad_header const *, - struct mad_pcm *), - enum mad_flow (*)(void *, - struct mad_stream *, - struct mad_frame *), - enum mad_flow (*)(void *, void *, unsigned int *)); + enum mad_flow(*)(void *, struct mad_stream *), + enum mad_flow(*)(void *, struct mad_header const *), + enum mad_flow(*)(void *, + struct mad_stream const *, + struct mad_frame *), + enum mad_flow(*)(void *, + struct mad_header const *, + struct mad_pcm *), + enum mad_flow(*)(void *, + struct mad_stream *, + struct mad_frame *), + enum mad_flow(*)(void *, void *, unsigned int *)); int mad_decoder_finish(struct mad_decoder *); # define mad_decoder_options(decoder, opts) \ diff --git a/src/libmad/fixed.c b/src/libmad/fixed.c index 928c011b..22cf782d 100644 --- a/src/libmad/fixed.c +++ b/src/libmad/fixed.c @@ -1,23 +1,23 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: fixed.c,v 1.13 2004/01/23 09:41:32 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: fixed.c,v 1.13 2004/01/23 09:41:32 rob Exp $ +*/ #pragma GCC optimize ("O3") @@ -28,54 +28,56 @@ # include "fixed.h" /* - * NAME: fixed->abs() - * DESCRIPTION: return absolute value of a fixed-point number - */ -mad_fixed_t mad_f_abs(mad_fixed_t x) -{ - return x < 0 ? -x : x; + NAME: fixed->abs() + DESCRIPTION: return absolute value of a fixed-point number +*/ +mad_fixed_t mad_f_abs(mad_fixed_t x) { + return x < 0 ? -x : x; } /* - * NAME: fixed->div() - * DESCRIPTION: perform division using fixed-point math - */ -mad_fixed_t mad_f_div(mad_fixed_t x, mad_fixed_t y) -{ - mad_fixed_t q, r; - unsigned int bits; - - q = mad_f_abs(x / y); - - if (x < 0) { - x = -x; - y = -y; - } - - r = x % y; - - if (y < 0) { - x = -x; - y = -y; - } - - if (q > mad_f_intpart(MAD_F_MAX) && - !(q == -mad_f_intpart(MAD_F_MIN) && r == 0 && (x < 0) != (y < 0))) - return 0; - - for (bits = MAD_F_FRACBITS; bits && r; --bits) { - q <<= 1, r <<= 1; - if (r >= y) - r -= y, ++q; - } - - /* round */ - if (2 * r >= y) - ++q; - - /* fix sign */ - if ((x < 0) != (y < 0)) - q = -q; - - return q << bits; + NAME: fixed->div() + DESCRIPTION: perform division using fixed-point math +*/ +mad_fixed_t mad_f_div(mad_fixed_t x, mad_fixed_t y) { + mad_fixed_t q, r; + unsigned int bits; + + q = mad_f_abs(x / y); + + if (x < 0) { + x = -x; + y = -y; + } + + r = x % y; + + if (y < 0) { + x = -x; + y = -y; + } + + if (q > mad_f_intpart(MAD_F_MAX) && + !(q == -mad_f_intpart(MAD_F_MIN) && r == 0 && (x < 0) != (y < 0))) { + return 0; + } + + for (bits = MAD_F_FRACBITS; bits && r; --bits) { + q <<= 1, r <<= 1; + if (r >= y) { + r -= y, ++q; + } + } + + /* round */ + if (2 * r >= y) { + ++q; + } + + /* fix sign */ + if ((x < 0) != (y < 0)) { + q = -q; + } + + return q << bits; } diff --git a/src/libmad/fixed.h b/src/libmad/fixed.h index 4b58abf5..89364798 100644 --- a/src/libmad/fixed.h +++ b/src/libmad/fixed.h @@ -1,23 +1,23 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: fixed.h,v 1.38 2004/02/17 02:02:03 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: fixed.h,v 1.38 2004/02/17 02:02:03 rob Exp $ +*/ # ifndef LIBMAD_FIXED_H # define LIBMAD_FIXED_H @@ -47,27 +47,27 @@ typedef mad_fixed_t mad_sample_t; # endif /* - * Fixed-point format: 0xABBBBBBB - * A == whole part (sign + 3 bits) - * B == fractional part (28 bits) - * - * Values are signed two's complement, so the effective range is: - * 0x80000000 to 0x7fffffff - * -8.0 to +7.9999999962747097015380859375 - * - * The smallest representable value is: - * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9) - * - * 28 bits of fractional accuracy represent about - * 8.6 digits of decimal accuracy. - * - * Fixed-point numbers can be added or subtracted as normal - * integers, but multiplication requires shifting the 64-bit result - * from 56 fractional bits back to 28 (and rounding.) - * - * Changing the definition of MAD_F_FRACBITS is only partially - * supported, and must be done with care. - */ + Fixed-point format: 0xABBBBBBB + A == whole part (sign + 3 bits) + B == fractional part (28 bits) + + Values are signed two's complement, so the effective range is: + 0x80000000 to 0x7fffffff + -8.0 to +7.9999999962747097015380859375 + + The smallest representable value is: + 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9) + + 28 bits of fractional accuracy represent about + 8.6 digits of decimal accuracy. + + Fixed-point numbers can be added or subtracted as normal + integers, but multiplication requires shifting the 64-bit result + from 56 fractional bits back to 28 (and rounding.) + + Changing the definition of MAD_F_FRACBITS is only partially + supported, and must be done with care. +*/ # define MAD_F_FRACBITS 28 @@ -99,7 +99,7 @@ typedef mad_fixed_t mad_sample_t; # define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS) # define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1)) - /* (x should be positive) */ +/* (x should be positive) */ # define mad_f_fromint(x) ((x) << MAD_F_FRACBITS) @@ -120,9 +120,9 @@ typedef mad_fixed_t mad_sample_t; # elif defined(FPM_64BIT) /* - * This version should be the most accurate if 64-bit types are supported by - * the compiler, although it may not be the most efficient. - */ + This version should be the most accurate if 64-bit types are supported by + the compiler, although it may not be the most efficient. +*/ # if defined(OPT_ACCURACY) # define mad_f_mul(x, y) \ ((mad_fixed_t) \ @@ -143,19 +143,18 @@ typedef mad_fixed_t mad_sample_t; # pragma warning(push) # pragma warning(disable: 4035) /* no return value */ static __forceinline -mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) -{ - enum { - fracbits = MAD_F_FRACBITS - }; - - __asm { - mov eax, x - imul y - shrd eax, edx, fracbits - } - - /* implicit return of eax */ +mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) { + enum { + fracbits = MAD_F_FRACBITS + }; + + __asm { + mov eax, x + imul y + shrd eax, edx, fracbits + } + + /* implicit return of eax */ } # pragma warning(pop) @@ -163,9 +162,9 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # define mad_f_scale64 # else /* - * This Intel version is fast and accurate; the disposition of the least - * significant bit depends on OPT_ACCURACY via mad_f_scale64(). - */ + This Intel version is fast and accurate; the disposition of the least + significant bit depends on OPT_ACCURACY via mad_f_scale64(). +*/ # define MAD_F_MLX(hi, lo, x, y) \ asm ("imull %3" \ : "=a" (lo), "=d" (hi) \ @@ -174,8 +173,8 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # if defined(OPT_ACCURACY) /* - * This gives best accuracy but is not very fast. - */ + This gives best accuracy but is not very fast. +*/ # define MAD_F_MLA(hi, lo, x, y) \ ({ mad_fixed64hi_t __hi; \ mad_fixed64lo_t __lo; \ @@ -190,8 +189,8 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # if defined(OPT_ACCURACY) /* - * Surprisingly, this is faster than SHRD followed by ADC. - */ + Surprisingly, this is faster than SHRD followed by ADC. +*/ # define mad_f_scale64(hi, lo) \ ({ mad_fixed64hi_t __hi_; \ mad_fixed64lo_t __lo_; \ @@ -210,8 +209,8 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) }) # elif defined(OPT_INTEL) /* - * Alternate Intel scaling that may or may not perform better. - */ + Alternate Intel scaling that may or may not perform better. +*/ # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result; \ asm ("shrl %3,%1\n\t" \ @@ -241,15 +240,15 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # elif defined(FPM_ARM) -/* - * This ARM V4 version is as accurate as FPM_64BIT but much faster. The - * least significant bit is properly rounded at no CPU cycle cost! - */ +/* + This ARM V4 version is as accurate as FPM_64BIT but much faster. The + least significant bit is properly rounded at no CPU cycle cost! +*/ # if 1 /* - * This is faster than the default implementation via MAD_F_MLX() and - * mad_f_scale64(). - */ + This is faster than the default implementation via MAD_F_MLX() and + mad_f_scale64(). +*/ # define mad_f_mul(x, y) \ ({ mad_fixed64hi_t __hi; \ mad_fixed64lo_t __lo; \ @@ -300,9 +299,9 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # elif defined(FPM_MIPS) /* - * This MIPS version is fast and accurate; the disposition of the least - * significant bit depends on OPT_ACCURACY via mad_f_scale64(). - */ + This MIPS version is fast and accurate; the disposition of the least + significant bit depends on OPT_ACCURACY via mad_f_scale64(). +*/ # define MAD_F_MLX(hi, lo, x, y) \ asm ("mult %2,%3" \ : "=l" (lo), "=h" (hi) \ @@ -315,9 +314,9 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) : "%r" (x), "r" (y)) # elif defined(HAVE_MADD16_ASM) /* - * This loses significant accuracy due to the 16-bit integer limit in the - * multiply/accumulate instruction. - */ + This loses significant accuracy due to the 16-bit integer limit in the + multiply/accumulate instruction. +*/ # define MAD_F_ML0(hi, lo, x, y) \ asm ("mult %2,%3" \ : "=l" (lo), "=h" (hi) \ @@ -340,9 +339,9 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # elif defined(FPM_SPARC) /* - * This SPARC V8 version is fast and accurate; the disposition of the least - * significant bit depends on OPT_ACCURACY via mad_f_scale64(). - */ + This SPARC V8 version is fast and accurate; the disposition of the least + significant bit depends on OPT_ACCURACY via mad_f_scale64(). +*/ # define MAD_F_MLX(hi, lo, x, y) \ asm ("smul %2, %3, %0\n\t" \ "rd %%y, %1" \ @@ -354,9 +353,9 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # elif defined(FPM_PPC) /* - * This PowerPC version is fast and accurate; the disposition of the least - * significant bit depends on OPT_ACCURACY via mad_f_scale64(). - */ + This PowerPC version is fast and accurate; the disposition of the least + significant bit depends on OPT_ACCURACY via mad_f_scale64(). +*/ # define MAD_F_MLX(hi, lo, x, y) \ do { \ asm ("mullw %0,%1,%2" \ @@ -370,8 +369,8 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # if defined(OPT_ACCURACY) /* - * This gives best accuracy but is not very fast. - */ + This gives best accuracy but is not very fast. +*/ # define MAD_F_MLA(hi, lo, x, y) \ ({ mad_fixed64hi_t __hi; \ mad_fixed64lo_t __lo; \ @@ -387,8 +386,8 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # if defined(OPT_ACCURACY) /* - * This is slower than the truncating version below it. - */ + This is slower than the truncating version below it. +*/ # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result, __round; \ asm ("rotrwi %0,%1,%2" \ @@ -425,14 +424,14 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # elif defined(FPM_DEFAULT) /* - * This version is the most portable but it loses significant accuracy. - * Furthermore, accuracy is biased against the second argument, so care - * should be taken when ordering operands. - * - * The scale factors are constant as this is not used with SSO. - * - * Pre-rounding is required to stay within the limits of compliance. - */ + This version is the most portable but it loses significant accuracy. + Furthermore, accuracy is biased against the second argument, so care + should be taken when ordering operands. + + The scale factors are constant as this is not used with SSO. + + Pre-rounding is required to stay within the limits of compliance. +*/ # if defined(OPT_SPEED) # define mad_f_mul(x, y) (((x) >> 12) * ((y) >> 16)) # else diff --git a/src/libmad/frame.c b/src/libmad/frame.c index 1facef81..a7bb316a 100644 --- a/src/libmad/frame.c +++ b/src/libmad/frame.c @@ -1,23 +1,23 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: frame.c,v 1.29 2004/02/04 22:59:19 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: frame.c,v 1.29 2004/02/04 22:59:19 rob Exp $ +*/ #pragma GCC optimize ("O3") @@ -36,19 +36,29 @@ static unsigned long const bitrate_table[5][15] PROGMEM = { - /* MPEG-1 */ - { 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, /* Layer I */ - 256000, 288000, 320000, 352000, 384000, 416000, 448000 }, - { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer II */ - 128000, 160000, 192000, 224000, 256000, 320000, 384000 }, - { 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, /* Layer III */ - 112000, 128000, 160000, 192000, 224000, 256000, 320000 }, - - /* MPEG-2 LSF */ - { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer I */ - 128000, 144000, 160000, 176000, 192000, 224000, 256000 }, - { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, /* Layers */ - 64000, 80000, 96000, 112000, 128000, 144000, 160000 } /* II & III */ + /* MPEG-1 */ + { + 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, /* Layer I */ + 256000, 288000, 320000, 352000, 384000, 416000, 448000 + }, + { + 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer II */ + 128000, 160000, 192000, 224000, 256000, 320000, 384000 + }, + { + 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, /* Layer III */ + 112000, 128000, 160000, 192000, 224000, 256000, 320000 + }, + + /* MPEG-2 LSF */ + { + 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer I */ + 128000, 144000, 160000, 176000, 192000, 224000, 256000 + }, + { + 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, /* Layers */ + 64000, 80000, 96000, 112000, 128000, 144000, 160000 + } /* II & III */ }; static @@ -56,447 +66,451 @@ unsigned int const samplerate_table[3] PROGMEM = { 44100, 48000, 32000 }; static int (*const decoder_table[3])(struct mad_stream *, struct mad_frame *) = { - NULL, //mad_layer_I, - NULL, //mad_layer_II, - mad_layer_III + NULL, //mad_layer_I, + NULL, //mad_layer_II, + mad_layer_III }; /* - * NAME: header->init() - * DESCRIPTION: initialize header struct - */ -void mad_header_init(struct mad_header *header) -{ - header->layer = 0; - header->mode = 0; - header->mode_extension = 0; - header->emphasis = 0; - - header->bitrate = 0; - header->samplerate = 0; - - header->crc_check = 0; - header->crc_target = 0; - - header->flags = 0; - header->private_bits = 0; - - header->duration = mad_timer_zero; + NAME: header->init() + DESCRIPTION: initialize header struct +*/ +void mad_header_init(struct mad_header *header) { + header->layer = 0; + header->mode = 0; + header->mode_extension = 0; + header->emphasis = 0; + + header->bitrate = 0; + header->samplerate = 0; + + header->crc_check = 0; + header->crc_target = 0; + + header->flags = 0; + header->private_bits = 0; + + header->duration = mad_timer_zero; } /* - * NAME: frame->init() - * DESCRIPTION: initialize frame struct - */ -void mad_frame_init(struct mad_frame *frame) -{ - stack(__FUNCTION__,__FILE__,__LINE__); - mad_header_init(&frame->header); + NAME: frame->init() + DESCRIPTION: initialize frame struct +*/ +void mad_frame_init(struct mad_frame *frame) { + stackenter(__FUNCTION__, __FILE__, __LINE__); + mad_header_init(&frame->header); - frame->options = 0; + frame->options = 0; - mad_frame_mute(frame); + mad_frame_mute(frame); } /* - * NAME: frame->finish() - * DESCRIPTION: deallocate any dynamic memory associated with frame - */ -void mad_frame_finish(struct mad_frame *frame) -{ - (void) frame; - mad_header_finish(&frame->header); + NAME: frame->finish() + DESCRIPTION: deallocate any dynamic memory associated with frame +*/ +void mad_frame_finish(struct mad_frame *frame) { + (void) frame; + mad_header_finish(&frame->header); } /* - * NAME: decode_header() - * DESCRIPTION: read header data and following CRC word - */ + NAME: decode_header() + DESCRIPTION: read header data and following CRC word +*/ static -int decode_header(struct mad_header *header, struct mad_stream *stream) -{ - unsigned int index; +int decode_header(struct mad_header *header, struct mad_stream *stream) { + unsigned int index; - header->flags = 0; - header->private_bits = 0; + header->flags = 0; + header->private_bits = 0; - /* header() */ + /* header() */ - /* syncword */ - mad_bit_skip(&stream->ptr, 11); + /* syncword */ + mad_bit_skip(&stream->ptr, 11); - /* MPEG 2.5 indicator (really part of syncword) */ - if (mad_bit_read(&stream->ptr, 1) == 0) - header->flags |= MAD_FLAG_MPEG_2_5_EXT; + /* MPEG 2.5 indicator (really part of syncword) */ + if (mad_bit_read(&stream->ptr, 1) == 0) { + header->flags |= MAD_FLAG_MPEG_2_5_EXT; + } - /* ID */ - if (mad_bit_read(&stream->ptr, 1) == 0) - header->flags |= MAD_FLAG_LSF_EXT; - else if (header->flags & MAD_FLAG_MPEG_2_5_EXT) { - stream->error = MAD_ERROR_LOSTSYNC; - return -1; - } + /* ID */ + if (mad_bit_read(&stream->ptr, 1) == 0) { + header->flags |= MAD_FLAG_LSF_EXT; + } else if (header->flags & MAD_FLAG_MPEG_2_5_EXT) { + stream->error = MAD_ERROR_LOSTSYNC; + return -1; + } - /* layer */ - header->layer = 4 - mad_bit_read(&stream->ptr, 2); + /* layer */ + header->layer = 4 - mad_bit_read(&stream->ptr, 2); - if (header->layer == 4) { - stream->error = MAD_ERROR_BADLAYER; - return -1; - } + if (header->layer == 4) { + stream->error = MAD_ERROR_BADLAYER; + return -1; + } - /* protection_bit */ - if (mad_bit_read(&stream->ptr, 1) == 0) { - header->flags |= MAD_FLAG_PROTECTION; - header->crc_check = mad_bit_crc(stream->ptr, 16, 0xffff); - } + /* protection_bit */ + if (mad_bit_read(&stream->ptr, 1) == 0) { + header->flags |= MAD_FLAG_PROTECTION; + header->crc_check = mad_bit_crc(stream->ptr, 16, 0xffff); + } - /* bitrate_index */ - index = mad_bit_read(&stream->ptr, 4); + /* bitrate_index */ + index = mad_bit_read(&stream->ptr, 4); - if (index == 15) { - stream->error = MAD_ERROR_BADBITRATE; - return -1; - } + if (index == 15) { + stream->error = MAD_ERROR_BADBITRATE; + return -1; + } - if (header->flags & MAD_FLAG_LSF_EXT) - header->bitrate = bitrate_table[3 + (header->layer >> 1)][index]; - else - header->bitrate = bitrate_table[header->layer - 1][index]; + if (header->flags & MAD_FLAG_LSF_EXT) { + header->bitrate = bitrate_table[3 + (header->layer >> 1)][index]; + } else { + header->bitrate = bitrate_table[header->layer - 1][index]; + } - /* sampling_frequency */ - index = mad_bit_read(&stream->ptr, 2); + /* sampling_frequency */ + index = mad_bit_read(&stream->ptr, 2); - if (index == 3) { - stream->error = MAD_ERROR_BADSAMPLERATE; - return -1; - } + if (index == 3) { + stream->error = MAD_ERROR_BADSAMPLERATE; + return -1; + } - header->samplerate = samplerate_table[index]; + header->samplerate = samplerate_table[index]; - if (header->flags & MAD_FLAG_LSF_EXT) { - header->samplerate /= 2; + if (header->flags & MAD_FLAG_LSF_EXT) { + header->samplerate /= 2; - if (header->flags & MAD_FLAG_MPEG_2_5_EXT) - header->samplerate /= 2; - } + if (header->flags & MAD_FLAG_MPEG_2_5_EXT) { + header->samplerate /= 2; + } + } - /* padding_bit */ - if (mad_bit_read(&stream->ptr, 1)) - header->flags |= MAD_FLAG_PADDING; + /* padding_bit */ + if (mad_bit_read(&stream->ptr, 1)) { + header->flags |= MAD_FLAG_PADDING; + } - /* private_bit */ - if (mad_bit_read(&stream->ptr, 1)) - header->private_bits |= MAD_PRIVATE_HEADER; + /* private_bit */ + if (mad_bit_read(&stream->ptr, 1)) { + header->private_bits |= MAD_PRIVATE_HEADER; + } - /* mode */ - header->mode = 3 - mad_bit_read(&stream->ptr, 2); + /* mode */ + header->mode = 3 - mad_bit_read(&stream->ptr, 2); - /* mode_extension */ - header->mode_extension = mad_bit_read(&stream->ptr, 2); + /* mode_extension */ + header->mode_extension = mad_bit_read(&stream->ptr, 2); - /* copyright */ - if (mad_bit_read(&stream->ptr, 1)) - header->flags |= MAD_FLAG_COPYRIGHT; + /* copyright */ + if (mad_bit_read(&stream->ptr, 1)) { + header->flags |= MAD_FLAG_COPYRIGHT; + } - /* original/copy */ - if (mad_bit_read(&stream->ptr, 1)) - header->flags |= MAD_FLAG_ORIGINAL; + /* original/copy */ + if (mad_bit_read(&stream->ptr, 1)) { + header->flags |= MAD_FLAG_ORIGINAL; + } - /* emphasis */ - header->emphasis = mad_bit_read(&stream->ptr, 2); + /* emphasis */ + header->emphasis = mad_bit_read(&stream->ptr, 2); # if defined(OPT_STRICT) - /* - * ISO/IEC 11172-3 says this is a reserved emphasis value, but - * streams exist which use it anyway. Since the value is not important - * to the decoder proper, we allow it unless OPT_STRICT is defined. - */ - if (header->emphasis == MAD_EMPHASIS_RESERVED) { - stream->error = MAD_ERROR_BADEMPHASIS; - return -1; - } + /* + ISO/IEC 11172-3 says this is a reserved emphasis value, but + streams exist which use it anyway. Since the value is not important + to the decoder proper, we allow it unless OPT_STRICT is defined. + */ + if (header->emphasis == MAD_EMPHASIS_RESERVED) { + stream->error = MAD_ERROR_BADEMPHASIS; + return -1; + } # endif - /* error_check() */ + /* error_check() */ - /* crc_check */ - if (header->flags & MAD_FLAG_PROTECTION) - header->crc_target = mad_bit_read(&stream->ptr, 16); + /* crc_check */ + if (header->flags & MAD_FLAG_PROTECTION) { + header->crc_target = mad_bit_read(&stream->ptr, 16); + } - return 0; + return 0; } /* - * NAME: free_bitrate() - * DESCRIPTION: attempt to discover the bitstream's free bitrate - */ + NAME: free_bitrate() + DESCRIPTION: attempt to discover the bitstream's free bitrate +*/ static -int free_bitrate(struct mad_stream *stream, struct mad_header const *header) -{ - struct mad_bitptr keep_ptr; - unsigned long rate = 0; - unsigned int pad_slot, slots_per_frame; - unsigned char const *ptr = 0; - - keep_ptr = stream->ptr; - - pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0; - slots_per_frame = (header->layer == MAD_LAYER_III && - (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144; - - while (mad_stream_sync(stream) == 0) { - struct mad_stream peek_stream; - struct mad_header peek_header; - - peek_stream = *stream; - peek_header = *header; - - if (decode_header(&peek_header, &peek_stream) == 0 && - peek_header.layer == header->layer && - peek_header.samplerate == header->samplerate) { - unsigned int N; - - ptr = mad_bit_nextbyte(&stream->ptr); - - N = ptr - stream->this_frame; - - if (header->layer == MAD_LAYER_I) { - rate = (unsigned long) header->samplerate * - (N - 4 * pad_slot + 4) / 48 / 1000; - } - else { - rate = (unsigned long) header->samplerate * - (N - pad_slot + 1) / slots_per_frame / 1000; - } - - if (rate >= 8) - break; - } +int free_bitrate(struct mad_stream *stream, struct mad_header const *header) { + struct mad_bitptr keep_ptr; + unsigned long rate = 0; + unsigned int pad_slot, slots_per_frame; + unsigned char const *ptr = 0; - mad_bit_skip(&stream->ptr, 8); - } + keep_ptr = stream->ptr; - stream->ptr = keep_ptr; + pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0; + slots_per_frame = (header->layer == MAD_LAYER_III && + (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144; - if (rate < 8 || (header->layer == MAD_LAYER_III && rate > 640)) { - stream->error = MAD_ERROR_LOSTSYNC; - return -1; - } + while (mad_stream_sync(stream) == 0) { + struct mad_stream peek_stream; + struct mad_header peek_header; - stream->freerate = rate * 1000; + peek_stream = *stream; + peek_header = *header; - return 0; -} + if (decode_header(&peek_header, &peek_stream) == 0 && + peek_header.layer == header->layer && + peek_header.samplerate == header->samplerate) { + unsigned int N; -/* - * NAME: header->decode() - * DESCRIPTION: read the next frame header from the stream - */ -int mad_header_decode(struct mad_header *header, struct mad_stream *stream) -{ - register unsigned char const *ptr, *end; - unsigned int pad_slot, N; - - ptr = stream->next_frame; - end = stream->bufend; - - if (ptr == 0) { - stream->error = MAD_ERROR_BUFPTR; - goto fail; - } - - /* stream skip */ - if (stream->skiplen) { - if (!stream->sync) - ptr = stream->this_frame; - - if ((unsigned int)(end - ptr) < stream->skiplen) { - stream->skiplen -= end - ptr; - stream->next_frame = end; - - stream->error = MAD_ERROR_BUFLEN; - goto fail; - } + ptr = mad_bit_nextbyte(&stream->ptr); - ptr += stream->skiplen; - stream->skiplen = 0; + N = ptr - stream->this_frame; - stream->sync = 1; - } + if (header->layer == MAD_LAYER_I) { + rate = (unsigned long) header->samplerate * + (N - 4 * pad_slot + 4) / 48 / 1000; + } else { + rate = (unsigned long) header->samplerate * + (N - pad_slot + 1) / slots_per_frame / 1000; + } - sync: - /* synchronize */ - if (stream->sync) { - if (end - ptr < MAD_BUFFER_GUARD) { - stream->next_frame = ptr; + if (rate >= 8) { + break; + } + } - stream->error = MAD_ERROR_BUFLEN; - goto fail; + mad_bit_skip(&stream->ptr, 8); } - else if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) { - /* mark point where frame sync word was expected */ - stream->this_frame = ptr; - stream->next_frame = ptr + 1; - stream->error = MAD_ERROR_LOSTSYNC; - goto fail; + stream->ptr = keep_ptr; + + if (rate < 8 || (header->layer == MAD_LAYER_III && rate > 640)) { + stream->error = MAD_ERROR_LOSTSYNC; + return -1; } - } - else { - mad_bit_init(&stream->ptr, ptr); - if (mad_stream_sync(stream) == -1) { - if (end - stream->next_frame >= MAD_BUFFER_GUARD) - stream->next_frame = end - MAD_BUFFER_GUARD; + stream->freerate = rate * 1000; + + return 0; +} + +/* + NAME: header->decode() + DESCRIPTION: read the next frame header from the stream +*/ +int mad_header_decode(struct mad_header *header, struct mad_stream *stream) { + register unsigned char const *ptr, *end; + unsigned int pad_slot, N; - stream->error = MAD_ERROR_BUFLEN; - goto fail; + ptr = stream->next_frame; + end = stream->bufend; + + if (ptr == 0) { + stream->error = MAD_ERROR_BUFPTR; + goto fail; } - ptr = mad_bit_nextbyte(&stream->ptr); - } + /* stream skip */ + if (stream->skiplen) { + if (!stream->sync) { + ptr = stream->this_frame; + } - /* begin processing */ - stream->this_frame = ptr; - stream->next_frame = ptr + 1; /* possibly bogus sync word */ + if ((unsigned int)(end - ptr) < stream->skiplen) { + stream->skiplen -= end - ptr; + stream->next_frame = end; - mad_bit_init(&stream->ptr, stream->this_frame); + stream->error = MAD_ERROR_BUFLEN; + goto fail; + } - if (decode_header(header, stream) == -1) - goto fail; + ptr += stream->skiplen; + stream->skiplen = 0; - /* calculate frame duration */ - mad_timer_set(&header->duration, 0, - 32 * MAD_NSBSAMPLES(header), header->samplerate); + stream->sync = 1; + } - /* calculate free bit rate */ - if (header->bitrate == 0) { - if ((stream->freerate == 0 || !stream->sync || - (header->layer == MAD_LAYER_III && stream->freerate > 640000)) && - free_bitrate(stream, header) == -1) - goto fail; +sync: + /* synchronize */ + if (stream->sync) { + if (end - ptr < MAD_BUFFER_GUARD) { + stream->next_frame = ptr; + + stream->error = MAD_ERROR_BUFLEN; + goto fail; + } else if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) { + /* mark point where frame sync word was expected */ + stream->this_frame = ptr; + stream->next_frame = ptr + 1; + + stream->error = MAD_ERROR_LOSTSYNC; + goto fail; + } + } else { + mad_bit_init(&stream->ptr, ptr); + + if (mad_stream_sync(stream) == -1) { + if (end - stream->next_frame >= MAD_BUFFER_GUARD) { + stream->next_frame = end - MAD_BUFFER_GUARD; + } + + stream->error = MAD_ERROR_BUFLEN; + goto fail; + } + + ptr = mad_bit_nextbyte(&stream->ptr); + } - header->bitrate = stream->freerate; - header->flags |= MAD_FLAG_FREEFORMAT; - } + /* begin processing */ + stream->this_frame = ptr; + stream->next_frame = ptr + 1; /* possibly bogus sync word */ - /* calculate beginning of next frame */ - pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0; + mad_bit_init(&stream->ptr, stream->this_frame); - if (header->layer == MAD_LAYER_I) - N = ((12 * header->bitrate / header->samplerate) + pad_slot) * 4; - else { - unsigned int slots_per_frame; + if (decode_header(header, stream) == -1) { + goto fail; + } - slots_per_frame = (header->layer == MAD_LAYER_III && - (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144; + /* calculate frame duration */ + mad_timer_set(&header->duration, 0, + 32 * MAD_NSBSAMPLES(header), header->samplerate); - N = (slots_per_frame * header->bitrate / header->samplerate) + pad_slot; - } + /* calculate free bit rate */ + if (header->bitrate == 0) { + if ((stream->freerate == 0 || !stream->sync || + (header->layer == MAD_LAYER_III && stream->freerate > 640000)) && + free_bitrate(stream, header) == -1) { + goto fail; + } - /* verify there is enough data left in buffer to decode this frame */ - if (N + MAD_BUFFER_GUARD > (unsigned int)(end - stream->this_frame)) { - stream->next_frame = stream->this_frame; + header->bitrate = stream->freerate; + header->flags |= MAD_FLAG_FREEFORMAT; + } - stream->error = MAD_ERROR_BUFLEN; - goto fail; - } + /* calculate beginning of next frame */ + pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0; - stream->next_frame = stream->this_frame + N; + if (header->layer == MAD_LAYER_I) { + N = ((12 * header->bitrate / header->samplerate) + pad_slot) * 4; + } else { + unsigned int slots_per_frame; - if (!stream->sync) { - /* check that a valid frame header follows this frame */ + slots_per_frame = (header->layer == MAD_LAYER_III && + (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144; - ptr = stream->next_frame; - if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) { - ptr = stream->next_frame = stream->this_frame + 1; - goto sync; + N = (slots_per_frame * header->bitrate / header->samplerate) + pad_slot; } - stream->sync = 1; - } + /* verify there is enough data left in buffer to decode this frame */ + if (N + MAD_BUFFER_GUARD > (unsigned int)(end - stream->this_frame)) { + stream->next_frame = stream->this_frame; - header->flags |= MAD_FLAG_INCOMPLETE; + stream->error = MAD_ERROR_BUFLEN; + goto fail; + } - return 0; + stream->next_frame = stream->this_frame + N; - fail: - stream->sync = 0; + if (!stream->sync) { + /* check that a valid frame header follows this frame */ - return -1; -} + ptr = stream->next_frame; + if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) { + ptr = stream->next_frame = stream->this_frame + 1; + goto sync; + } -/* - * NAME: frame->decode() - * DESCRIPTION: decode a single frame from a bitstream - */ -int mad_frame_decode(struct mad_frame *frame, struct mad_stream *stream) -{ - frame->options = stream->options; + stream->sync = 1; + } - /* header() */ - /* error_check() */ + header->flags |= MAD_FLAG_INCOMPLETE; - if (!(frame->header.flags & MAD_FLAG_INCOMPLETE) && - mad_header_decode(&frame->header, stream) == -1) - goto fail; + return 0; - /* audio_data() */ +fail: + stream->sync = 0; - frame->header.flags &= ~MAD_FLAG_INCOMPLETE; + return -1; +} - // EFP3 - On non-MP3 frames, abort instead of crash..we removed MP-II/MP-I decoders - if (!decoder_table[frame->header.layer - 1]) { - goto fail; - } +/* + NAME: frame->decode() + DESCRIPTION: decode a single frame from a bitstream +*/ +int mad_frame_decode(struct mad_frame *frame, struct mad_stream *stream) { + frame->options = stream->options; + + /* header() */ + /* error_check() */ + + if (!(frame->header.flags & MAD_FLAG_INCOMPLETE) && + mad_header_decode(&frame->header, stream) == -1) { + goto fail; + } - if (decoder_table[frame->header.layer - 1](stream, frame) == -1) { - if (!MAD_RECOVERABLE(stream->error)) - stream->next_frame = stream->this_frame; + /* audio_data() */ - goto fail; - } + frame->header.flags &= ~MAD_FLAG_INCOMPLETE; - /* ancillary_data() */ + // EFP3 - On non-MP3 frames, abort instead of crash..we removed MP-II/MP-I decoders + if (!decoder_table[frame->header.layer - 1]) { + goto fail; + } + + if (decoder_table[frame->header.layer - 1](stream, frame) == -1) { + if (!MAD_RECOVERABLE(stream->error)) { + stream->next_frame = stream->this_frame; + } - if (frame->header.layer != MAD_LAYER_III) { - struct mad_bitptr next_frame; + goto fail; + } - mad_bit_init(&next_frame, stream->next_frame); + /* ancillary_data() */ - stream->anc_ptr = stream->ptr; - stream->anc_bitlen = mad_bit_length(&stream->ptr, &next_frame); + if (frame->header.layer != MAD_LAYER_III) { + struct mad_bitptr next_frame; - mad_bit_finish(&next_frame); - } + mad_bit_init(&next_frame, stream->next_frame); - return 0; + stream->anc_ptr = stream->ptr; + stream->anc_bitlen = mad_bit_length(&stream->ptr, &next_frame); - fail: - stream->anc_bitlen = 0; - return -1; + mad_bit_finish(&next_frame); + } + + return 0; + +fail: + stream->anc_bitlen = 0; + return -1; } /* - * NAME: frame->mute() - * DESCRIPTION: zero all subband values so the frame becomes silent - */ -void mad_frame_mute(struct mad_frame *frame) -{ - unsigned int s, sb; - - for (s = 0; s < 36; ++s) { - for (sb = 0; sb < 32; ++sb) { - frame->sbsample[0][s][sb] = - frame->sbsample[1][s][sb] = 0; + NAME: frame->mute() + DESCRIPTION: zero all subband values so the frame becomes silent +*/ +void mad_frame_mute(struct mad_frame *frame) { + unsigned int s, sb; + + for (s = 0; s < 36; ++s) { + for (sb = 0; sb < 32; ++sb) { + frame->sbsample[0][s][sb] = + frame->sbsample[1][s][sb] = 0; + } } - } - for (s = 0; s < 18; ++s) { - for (sb = 0; sb < 32; ++sb) { - frame->overlap[0][sb][s] = - frame->overlap[1][sb][s] = 0; + for (s = 0; s < 18; ++s) { + for (sb = 0; sb < 32; ++sb) { + frame->overlap[0][sb][s] = + frame->overlap[1][sb][s] = 0; + } } - } } diff --git a/src/libmad/frame.h b/src/libmad/frame.h index b3dece6c..134c1a93 100644 --- a/src/libmad/frame.h +++ b/src/libmad/frame.h @@ -1,23 +1,23 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: frame.h,v 1.20 2004/01/23 09:41:32 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: frame.h,v 1.20 2004/01/23 09:41:32 rob Exp $ +*/ # ifndef LIBMAD_FRAME_H # define LIBMAD_FRAME_H @@ -27,53 +27,53 @@ # include "stream.h" enum mad_layer { - MAD_LAYER_I = 1, /* Layer I */ - MAD_LAYER_II = 2, /* Layer II */ - MAD_LAYER_III = 3 /* Layer III */ + MAD_LAYER_I = 1, /* Layer I */ + MAD_LAYER_II = 2, /* Layer II */ + MAD_LAYER_III = 3 /* Layer III */ }; enum mad_mode { - MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */ - MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */ - MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */ - MAD_MODE_STEREO = 3 /* normal LR stereo */ + MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */ + MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */ + MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */ + MAD_MODE_STEREO = 3 /* normal LR stereo */ }; enum mad_emphasis { - MAD_EMPHASIS_NONE = 0, /* no emphasis */ - MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */ - MAD_EMPHASIS_CCITT_J_17 = 3, /* CCITT J.17 emphasis */ - MAD_EMPHASIS_RESERVED = 2 /* unknown emphasis */ + MAD_EMPHASIS_NONE = 0, /* no emphasis */ + MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */ + MAD_EMPHASIS_CCITT_J_17 = 3, /* CCITT J.17 emphasis */ + MAD_EMPHASIS_RESERVED = 2 /* unknown emphasis */ }; struct mad_header { - enum mad_layer layer; /* audio layer (1, 2, or 3) */ - enum mad_mode mode; /* channel mode (see above) */ - int mode_extension; /* additional mode info */ - enum mad_emphasis emphasis; /* de-emphasis to use (see above) */ + enum mad_layer layer; /* audio layer (1, 2, or 3) */ + enum mad_mode mode; /* channel mode (see above) */ + int mode_extension; /* additional mode info */ + enum mad_emphasis emphasis; /* de-emphasis to use (see above) */ - unsigned long bitrate; /* stream bitrate (bps) */ - unsigned int samplerate; /* sampling frequency (Hz) */ + unsigned long bitrate; /* stream bitrate (bps) */ + unsigned int samplerate; /* sampling frequency (Hz) */ - unsigned short crc_check; /* frame CRC accumulator */ - unsigned short crc_target; /* final target CRC checksum */ + unsigned short crc_check; /* frame CRC accumulator */ + unsigned short crc_target; /* final target CRC checksum */ - int flags; /* flags (see below) */ - int private_bits; /* private bits (see below) */ + int flags; /* flags (see below) */ + int private_bits; /* private bits (see below) */ - mad_timer_t duration; /* audio playing time of frame */ + mad_timer_t duration; /* audio playing time of frame */ }; struct mad_frame { - struct mad_header header; /* MPEG audio header */ + struct mad_header header; /* MPEG audio header */ - int options; /* decoding options (from stream) */ + int options; /* decoding options (from stream) */ - mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */ - mad_fixed_t overlap[2][32][18]; /* Layer III block overlap data */ + mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */ + mad_fixed_t overlap[2][32][18]; /* Layer III block overlap data */ - mad_fixed_t xr_raw[576*2]; - mad_fixed_t tmp[576]; + mad_fixed_t xr_raw[576 * 2]; + mad_fixed_t tmp[576]; }; # define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1) @@ -83,26 +83,26 @@ struct mad_frame { ((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36)) enum { - MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */ - MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */ + MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */ + MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */ - MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */ - MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */ - MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */ - MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */ + MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */ + MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */ + MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */ + MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */ - MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */ - MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */ - MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */ + MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */ + MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */ + MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */ - MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */ - MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */ - MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */ + MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */ + MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */ + MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */ }; enum { - MAD_PRIVATE_HEADER = 0x0100, /* header private bit */ - MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */ + MAD_PRIVATE_HEADER = 0x0100, /* header private bit */ + MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */ }; void mad_header_init(struct mad_header *); diff --git a/src/libmad/global.h b/src/libmad/global.h index a6debfd8..e020ac89 100644 --- a/src/libmad/global.h +++ b/src/libmad/global.h @@ -1,23 +1,23 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: global.h,v 1.11 2004/01/23 09:41:32 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: global.h,v 1.11 2004/01/23 09:41:32 rob Exp $ +*/ # ifndef LIBMAD_GLOBAL_H # define LIBMAD_GLOBAL_H @@ -48,6 +48,7 @@ # endif # if !defined(HAVE_ASSERT_H) +# undef assert # if defined(NDEBUG) # define assert(x) /* nothing */ # else diff --git a/src/libmad/huffman.c b/src/libmad/huffman.c index 33870851..d58f3e2c 100644 --- a/src/libmad/huffman.c +++ b/src/libmad/huffman.c @@ -1,23 +1,23 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: huffman.c,v 1.10 2004/01/23 09:41:32 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: huffman.c,v 1.10 2004/01/23 09:41:32 rob Exp $ +*/ #pragma GCC optimize ("O3") @@ -29,11 +29,11 @@ # include "huffman.h" /* - * These are the Huffman code words for Layer III. - * The data for these tables are derived from Table B.7 of ISO/IEC 11172-3. - * - * These tables support decoding up to 4 Huffman code bits at a time. - */ + These are the Huffman code words for Layer III. + The data for these tables are derived from Table B.7 of ISO/IEC 11172-3. + + These tables support decoding up to 4 Huffman code bits at a time. +*/ # if defined(__GNUC__) || \ (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901) @@ -52,62 +52,62 @@ static union huffquad const hufftabA[] PROGMEM = { - /* 0000 */ PTR(16, 2), - /* 0001 */ PTR(20, 2), - /* 0010 */ PTR(24, 1), - /* 0011 */ PTR(26, 1), - /* 0100 */ V(0, 0, 1, 0, 4), - /* 0101 */ V(0, 0, 0, 1, 4), - /* 0110 */ V(0, 1, 0, 0, 4), - /* 0111 */ V(1, 0, 0, 0, 4), - /* 1000 */ V(0, 0, 0, 0, 1), - /* 1001 */ V(0, 0, 0, 0, 1), - /* 1010 */ V(0, 0, 0, 0, 1), - /* 1011 */ V(0, 0, 0, 0, 1), - /* 1100 */ V(0, 0, 0, 0, 1), - /* 1101 */ V(0, 0, 0, 0, 1), - /* 1110 */ V(0, 0, 0, 0, 1), - /* 1111 */ V(0, 0, 0, 0, 1), - - /* 0000 ... */ - /* 00 */ V(1, 0, 1, 1, 2), /* 16 */ - /* 01 */ V(1, 1, 1, 1, 2), - /* 10 */ V(1, 1, 0, 1, 2), - /* 11 */ V(1, 1, 1, 0, 2), - - /* 0001 ... */ - /* 00 */ V(0, 1, 1, 1, 2), /* 20 */ - /* 01 */ V(0, 1, 0, 1, 2), - /* 10 */ V(1, 0, 0, 1, 1), - /* 11 */ V(1, 0, 0, 1, 1), - - /* 0010 ... */ - /* 0 */ V(0, 1, 1, 0, 1), /* 24 */ - /* 1 */ V(0, 0, 1, 1, 1), - - /* 0011 ... */ - /* 0 */ V(1, 0, 1, 0, 1), /* 26 */ - /* 1 */ V(1, 1, 0, 0, 1) + /* 0000 */ PTR(16, 2), + /* 0001 */ PTR(20, 2), + /* 0010 */ PTR(24, 1), + /* 0011 */ PTR(26, 1), + /* 0100 */ V(0, 0, 1, 0, 4), + /* 0101 */ V(0, 0, 0, 1, 4), + /* 0110 */ V(0, 1, 0, 0, 4), + /* 0111 */ V(1, 0, 0, 0, 4), + /* 1000 */ V(0, 0, 0, 0, 1), + /* 1001 */ V(0, 0, 0, 0, 1), + /* 1010 */ V(0, 0, 0, 0, 1), + /* 1011 */ V(0, 0, 0, 0, 1), + /* 1100 */ V(0, 0, 0, 0, 1), + /* 1101 */ V(0, 0, 0, 0, 1), + /* 1110 */ V(0, 0, 0, 0, 1), + /* 1111 */ V(0, 0, 0, 0, 1), + + /* 0000 ... */ + /* 00 */ V(1, 0, 1, 1, 2), /* 16 */ + /* 01 */ V(1, 1, 1, 1, 2), + /* 10 */ V(1, 1, 0, 1, 2), + /* 11 */ V(1, 1, 1, 0, 2), + + /* 0001 ... */ + /* 00 */ V(0, 1, 1, 1, 2), /* 20 */ + /* 01 */ V(0, 1, 0, 1, 2), + /* 10 */ V(1, 0, 0, 1, 1), + /* 11 */ V(1, 0, 0, 1, 1), + + /* 0010 ... */ + /* 0 */ V(0, 1, 1, 0, 1), /* 24 */ + /* 1 */ V(0, 0, 1, 1, 1), + + /* 0011 ... */ + /* 0 */ V(1, 0, 1, 0, 1), /* 26 */ + /* 1 */ V(1, 1, 0, 0, 1) }; static union huffquad const hufftabB[] PROGMEM = { - /* 0000 */ V(1, 1, 1, 1, 4), - /* 0001 */ V(1, 1, 1, 0, 4), - /* 0010 */ V(1, 1, 0, 1, 4), - /* 0011 */ V(1, 1, 0, 0, 4), - /* 0100 */ V(1, 0, 1, 1, 4), - /* 0101 */ V(1, 0, 1, 0, 4), - /* 0110 */ V(1, 0, 0, 1, 4), - /* 0111 */ V(1, 0, 0, 0, 4), - /* 1000 */ V(0, 1, 1, 1, 4), - /* 1001 */ V(0, 1, 1, 0, 4), - /* 1010 */ V(0, 1, 0, 1, 4), - /* 1011 */ V(0, 1, 0, 0, 4), - /* 1100 */ V(0, 0, 1, 1, 4), - /* 1101 */ V(0, 0, 1, 0, 4), - /* 1110 */ V(0, 0, 0, 1, 4), - /* 1111 */ V(0, 0, 0, 0, 4) + /* 0000 */ V(1, 1, 1, 1, 4), + /* 0001 */ V(1, 1, 1, 0, 4), + /* 0010 */ V(1, 1, 0, 1, 4), + /* 0011 */ V(1, 1, 0, 0, 4), + /* 0100 */ V(1, 0, 1, 1, 4), + /* 0101 */ V(1, 0, 1, 0, 4), + /* 0110 */ V(1, 0, 0, 1, 4), + /* 0111 */ V(1, 0, 0, 0, 4), + /* 1000 */ V(0, 1, 1, 1, 4), + /* 1001 */ V(0, 1, 1, 0, 4), + /* 1010 */ V(0, 1, 0, 1, 4), + /* 1011 */ V(0, 1, 0, 0, 4), + /* 1100 */ V(0, 0, 1, 1, 4), + /* 1101 */ V(0, 0, 1, 0, 4), + /* 1110 */ V(0, 0, 0, 1, 4), + /* 1111 */ V(0, 0, 0, 0, 4) }; # undef V @@ -128,2943 +128,2943 @@ union huffquad const hufftabB[] PROGMEM = { static union huffpair const hufftab0[] PROGMEM = { - /* */ V(0, 0, 0) + /* */ V(0, 0, 0) }; static union huffpair const hufftab1[] PROGMEM = { - /* 000 */ V(1, 1, 3), - /* 001 */ V(0, 1, 3), - /* 010 */ V(1, 0, 2), - /* 011 */ V(1, 0, 2), - /* 100 */ V(0, 0, 1), - /* 101 */ V(0, 0, 1), - /* 110 */ V(0, 0, 1), - /* 111 */ V(0, 0, 1) + /* 000 */ V(1, 1, 3), + /* 001 */ V(0, 1, 3), + /* 010 */ V(1, 0, 2), + /* 011 */ V(1, 0, 2), + /* 100 */ V(0, 0, 1), + /* 101 */ V(0, 0, 1), + /* 110 */ V(0, 0, 1), + /* 111 */ V(0, 0, 1) }; static union huffpair const hufftab2[] PROGMEM = { - /* 000 */ PTR(8, 3), - /* 001 */ V(1, 1, 3), - /* 010 */ V(0, 1, 3), - /* 011 */ V(1, 0, 3), - /* 100 */ V(0, 0, 1), - /* 101 */ V(0, 0, 1), - /* 110 */ V(0, 0, 1), - /* 111 */ V(0, 0, 1), - - /* 000 ... */ - /* 000 */ V(2, 2, 3), /* 8 */ - /* 001 */ V(0, 2, 3), - /* 010 */ V(1, 2, 2), - /* 011 */ V(1, 2, 2), - /* 100 */ V(2, 1, 2), - /* 101 */ V(2, 1, 2), - /* 110 */ V(2, 0, 2), - /* 111 */ V(2, 0, 2) + /* 000 */ PTR(8, 3), + /* 001 */ V(1, 1, 3), + /* 010 */ V(0, 1, 3), + /* 011 */ V(1, 0, 3), + /* 100 */ V(0, 0, 1), + /* 101 */ V(0, 0, 1), + /* 110 */ V(0, 0, 1), + /* 111 */ V(0, 0, 1), + + /* 000 ... */ + /* 000 */ V(2, 2, 3), /* 8 */ + /* 001 */ V(0, 2, 3), + /* 010 */ V(1, 2, 2), + /* 011 */ V(1, 2, 2), + /* 100 */ V(2, 1, 2), + /* 101 */ V(2, 1, 2), + /* 110 */ V(2, 0, 2), + /* 111 */ V(2, 0, 2) }; static union huffpair const hufftab3[] PROGMEM = { - /* 000 */ PTR(8, 3), - /* 001 */ V(1, 0, 3), - /* 010 */ V(1, 1, 2), - /* 011 */ V(1, 1, 2), - /* 100 */ V(0, 1, 2), - /* 101 */ V(0, 1, 2), - /* 110 */ V(0, 0, 2), - /* 111 */ V(0, 0, 2), - - /* 000 ... */ - /* 000 */ V(2, 2, 3), /* 8 */ - /* 001 */ V(0, 2, 3), - /* 010 */ V(1, 2, 2), - /* 011 */ V(1, 2, 2), - /* 100 */ V(2, 1, 2), - /* 101 */ V(2, 1, 2), - /* 110 */ V(2, 0, 2), - /* 111 */ V(2, 0, 2) + /* 000 */ PTR(8, 3), + /* 001 */ V(1, 0, 3), + /* 010 */ V(1, 1, 2), + /* 011 */ V(1, 1, 2), + /* 100 */ V(0, 1, 2), + /* 101 */ V(0, 1, 2), + /* 110 */ V(0, 0, 2), + /* 111 */ V(0, 0, 2), + + /* 000 ... */ + /* 000 */ V(2, 2, 3), /* 8 */ + /* 001 */ V(0, 2, 3), + /* 010 */ V(1, 2, 2), + /* 011 */ V(1, 2, 2), + /* 100 */ V(2, 1, 2), + /* 101 */ V(2, 1, 2), + /* 110 */ V(2, 0, 2), + /* 111 */ V(2, 0, 2) }; static union huffpair const hufftab5[] PROGMEM = { - /* 000 */ PTR(8, 4), - /* 001 */ V(1, 1, 3), - /* 010 */ V(0, 1, 3), - /* 011 */ V(1, 0, 3), - /* 100 */ V(0, 0, 1), - /* 101 */ V(0, 0, 1), - /* 110 */ V(0, 0, 1), - /* 111 */ V(0, 0, 1), - - /* 000 ... */ - /* 0000 */ PTR(24, 1), /* 8 */ - /* 0001 */ V(3, 2, 4), - /* 0010 */ V(3, 1, 3), - /* 0011 */ V(3, 1, 3), - /* 0100 */ V(1, 3, 4), - /* 0101 */ V(0, 3, 4), - /* 0110 */ V(3, 0, 4), - /* 0111 */ V(2, 2, 4), - /* 1000 */ V(1, 2, 3), - /* 1001 */ V(1, 2, 3), - /* 1010 */ V(2, 1, 3), - /* 1011 */ V(2, 1, 3), - /* 1100 */ V(0, 2, 3), - /* 1101 */ V(0, 2, 3), - /* 1110 */ V(2, 0, 3), - /* 1111 */ V(2, 0, 3), - - /* 000 0000 ... */ - /* 0 */ V(3, 3, 1), /* 24 */ - /* 1 */ V(2, 3, 1) + /* 000 */ PTR(8, 4), + /* 001 */ V(1, 1, 3), + /* 010 */ V(0, 1, 3), + /* 011 */ V(1, 0, 3), + /* 100 */ V(0, 0, 1), + /* 101 */ V(0, 0, 1), + /* 110 */ V(0, 0, 1), + /* 111 */ V(0, 0, 1), + + /* 000 ... */ + /* 0000 */ PTR(24, 1), /* 8 */ + /* 0001 */ V(3, 2, 4), + /* 0010 */ V(3, 1, 3), + /* 0011 */ V(3, 1, 3), + /* 0100 */ V(1, 3, 4), + /* 0101 */ V(0, 3, 4), + /* 0110 */ V(3, 0, 4), + /* 0111 */ V(2, 2, 4), + /* 1000 */ V(1, 2, 3), + /* 1001 */ V(1, 2, 3), + /* 1010 */ V(2, 1, 3), + /* 1011 */ V(2, 1, 3), + /* 1100 */ V(0, 2, 3), + /* 1101 */ V(0, 2, 3), + /* 1110 */ V(2, 0, 3), + /* 1111 */ V(2, 0, 3), + + /* 000 0000 ... */ + /* 0 */ V(3, 3, 1), /* 24 */ + /* 1 */ V(2, 3, 1) }; static union huffpair const hufftab6[] PROGMEM = { - /* 0000 */ PTR(16, 3), - /* 0001 */ PTR(24, 1), - /* 0010 */ PTR(26, 1), - /* 0011 */ V(1, 2, 4), - /* 0100 */ V(2, 1, 4), - /* 0101 */ V(2, 0, 4), - /* 0110 */ V(0, 1, 3), - /* 0111 */ V(0, 1, 3), - /* 1000 */ V(1, 1, 2), - /* 1001 */ V(1, 1, 2), - /* 1010 */ V(1, 1, 2), - /* 1011 */ V(1, 1, 2), - /* 1100 */ V(1, 0, 3), - /* 1101 */ V(1, 0, 3), - /* 1110 */ V(0, 0, 3), - /* 1111 */ V(0, 0, 3), - - /* 0000 ... */ - /* 000 */ V(3, 3, 3), /* 16 */ - /* 001 */ V(0, 3, 3), - /* 010 */ V(2, 3, 2), - /* 011 */ V(2, 3, 2), - /* 100 */ V(3, 2, 2), - /* 101 */ V(3, 2, 2), - /* 110 */ V(3, 0, 2), - /* 111 */ V(3, 0, 2), - - /* 0001 ... */ - /* 0 */ V(1, 3, 1), /* 24 */ - /* 1 */ V(3, 1, 1), - - /* 0010 ... */ - /* 0 */ V(2, 2, 1), /* 26 */ - /* 1 */ V(0, 2, 1) + /* 0000 */ PTR(16, 3), + /* 0001 */ PTR(24, 1), + /* 0010 */ PTR(26, 1), + /* 0011 */ V(1, 2, 4), + /* 0100 */ V(2, 1, 4), + /* 0101 */ V(2, 0, 4), + /* 0110 */ V(0, 1, 3), + /* 0111 */ V(0, 1, 3), + /* 1000 */ V(1, 1, 2), + /* 1001 */ V(1, 1, 2), + /* 1010 */ V(1, 1, 2), + /* 1011 */ V(1, 1, 2), + /* 1100 */ V(1, 0, 3), + /* 1101 */ V(1, 0, 3), + /* 1110 */ V(0, 0, 3), + /* 1111 */ V(0, 0, 3), + + /* 0000 ... */ + /* 000 */ V(3, 3, 3), /* 16 */ + /* 001 */ V(0, 3, 3), + /* 010 */ V(2, 3, 2), + /* 011 */ V(2, 3, 2), + /* 100 */ V(3, 2, 2), + /* 101 */ V(3, 2, 2), + /* 110 */ V(3, 0, 2), + /* 111 */ V(3, 0, 2), + + /* 0001 ... */ + /* 0 */ V(1, 3, 1), /* 24 */ + /* 1 */ V(3, 1, 1), + + /* 0010 ... */ + /* 0 */ V(2, 2, 1), /* 26 */ + /* 1 */ V(0, 2, 1) }; static union huffpair const hufftab7[] PROGMEM = { - /* 0000 */ PTR(16, 4), - /* 0001 */ PTR(32, 4), - /* 0010 */ PTR(48, 2), - /* 0011 */ V(1, 1, 4), - /* 0100 */ V(0, 1, 3), - /* 0101 */ V(0, 1, 3), - /* 0110 */ V(1, 0, 3), - /* 0111 */ V(1, 0, 3), - /* 1000 */ V(0, 0, 1), - /* 1001 */ V(0, 0, 1), - /* 1010 */ V(0, 0, 1), - /* 1011 */ V(0, 0, 1), - /* 1100 */ V(0, 0, 1), - /* 1101 */ V(0, 0, 1), - /* 1110 */ V(0, 0, 1), - /* 1111 */ V(0, 0, 1), - - /* 0000 ... */ - /* 0000 */ PTR(52, 2), /* 16 */ - /* 0001 */ PTR(56, 1), - /* 0010 */ PTR(58, 1), - /* 0011 */ V(1, 5, 4), - /* 0100 */ V(5, 1, 4), - /* 0101 */ PTR(60, 1), - /* 0110 */ V(5, 0, 4), - /* 0111 */ PTR(62, 1), - /* 1000 */ V(2, 4, 4), - /* 1001 */ V(4, 2, 4), - /* 1010 */ V(1, 4, 3), - /* 1011 */ V(1, 4, 3), - /* 1100 */ V(4, 1, 3), - /* 1101 */ V(4, 1, 3), - /* 1110 */ V(4, 0, 3), - /* 1111 */ V(4, 0, 3), - - /* 0001 ... */ - /* 0000 */ V(0, 4, 4), /* 32 */ - /* 0001 */ V(2, 3, 4), - /* 0010 */ V(3, 2, 4), - /* 0011 */ V(0, 3, 4), - /* 0100 */ V(1, 3, 3), - /* 0101 */ V(1, 3, 3), - /* 0110 */ V(3, 1, 3), - /* 0111 */ V(3, 1, 3), - /* 1000 */ V(3, 0, 3), - /* 1001 */ V(3, 0, 3), - /* 1010 */ V(2, 2, 3), - /* 1011 */ V(2, 2, 3), - /* 1100 */ V(1, 2, 2), - /* 1101 */ V(1, 2, 2), - /* 1110 */ V(1, 2, 2), - /* 1111 */ V(1, 2, 2), - - /* 0010 ... */ - /* 00 */ V(2, 1, 1), /* 48 */ - /* 01 */ V(2, 1, 1), - /* 10 */ V(0, 2, 2), - /* 11 */ V(2, 0, 2), - - /* 0000 0000 ... */ - /* 00 */ V(5, 5, 2), /* 52 */ - /* 01 */ V(4, 5, 2), - /* 10 */ V(5, 4, 2), - /* 11 */ V(5, 3, 2), - - /* 0000 0001 ... */ - /* 0 */ V(3, 5, 1), /* 56 */ - /* 1 */ V(4, 4, 1), - - /* 0000 0010 ... */ - /* 0 */ V(2, 5, 1), /* 58 */ - /* 1 */ V(5, 2, 1), - - /* 0000 0101 ... */ - /* 0 */ V(0, 5, 1), /* 60 */ - /* 1 */ V(3, 4, 1), - - /* 0000 0111 ... */ - /* 0 */ V(4, 3, 1), /* 62 */ - /* 1 */ V(3, 3, 1) + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ PTR(48, 2), + /* 0011 */ V(1, 1, 4), + /* 0100 */ V(0, 1, 3), + /* 0101 */ V(0, 1, 3), + /* 0110 */ V(1, 0, 3), + /* 0111 */ V(1, 0, 3), + /* 1000 */ V(0, 0, 1), + /* 1001 */ V(0, 0, 1), + /* 1010 */ V(0, 0, 1), + /* 1011 */ V(0, 0, 1), + /* 1100 */ V(0, 0, 1), + /* 1101 */ V(0, 0, 1), + /* 1110 */ V(0, 0, 1), + /* 1111 */ V(0, 0, 1), + + /* 0000 ... */ + /* 0000 */ PTR(52, 2), /* 16 */ + /* 0001 */ PTR(56, 1), + /* 0010 */ PTR(58, 1), + /* 0011 */ V(1, 5, 4), + /* 0100 */ V(5, 1, 4), + /* 0101 */ PTR(60, 1), + /* 0110 */ V(5, 0, 4), + /* 0111 */ PTR(62, 1), + /* 1000 */ V(2, 4, 4), + /* 1001 */ V(4, 2, 4), + /* 1010 */ V(1, 4, 3), + /* 1011 */ V(1, 4, 3), + /* 1100 */ V(4, 1, 3), + /* 1101 */ V(4, 1, 3), + /* 1110 */ V(4, 0, 3), + /* 1111 */ V(4, 0, 3), + + /* 0001 ... */ + /* 0000 */ V(0, 4, 4), /* 32 */ + /* 0001 */ V(2, 3, 4), + /* 0010 */ V(3, 2, 4), + /* 0011 */ V(0, 3, 4), + /* 0100 */ V(1, 3, 3), + /* 0101 */ V(1, 3, 3), + /* 0110 */ V(3, 1, 3), + /* 0111 */ V(3, 1, 3), + /* 1000 */ V(3, 0, 3), + /* 1001 */ V(3, 0, 3), + /* 1010 */ V(2, 2, 3), + /* 1011 */ V(2, 2, 3), + /* 1100 */ V(1, 2, 2), + /* 1101 */ V(1, 2, 2), + /* 1110 */ V(1, 2, 2), + /* 1111 */ V(1, 2, 2), + + /* 0010 ... */ + /* 00 */ V(2, 1, 1), /* 48 */ + /* 01 */ V(2, 1, 1), + /* 10 */ V(0, 2, 2), + /* 11 */ V(2, 0, 2), + + /* 0000 0000 ... */ + /* 00 */ V(5, 5, 2), /* 52 */ + /* 01 */ V(4, 5, 2), + /* 10 */ V(5, 4, 2), + /* 11 */ V(5, 3, 2), + + /* 0000 0001 ... */ + /* 0 */ V(3, 5, 1), /* 56 */ + /* 1 */ V(4, 4, 1), + + /* 0000 0010 ... */ + /* 0 */ V(2, 5, 1), /* 58 */ + /* 1 */ V(5, 2, 1), + + /* 0000 0101 ... */ + /* 0 */ V(0, 5, 1), /* 60 */ + /* 1 */ V(3, 4, 1), + + /* 0000 0111 ... */ + /* 0 */ V(4, 3, 1), /* 62 */ + /* 1 */ V(3, 3, 1) }; # if 0 -/* this version saves 8 entries (16 bytes) at the expense of - an extra lookup in 4 out of 36 cases */ +/* this version saves 8 entries (16 bytes) at the expense of + an extra lookup in 4 out of 36 cases */ static union huffpair const hufftab8[] PROGMEM = { - /* 0000 */ PTR(16, 4), - /* 0001 */ PTR(32, 2), - /* 0010 */ V(1, 2, 4), - /* 0011 */ V(2, 1, 4), - /* 0100 */ V(1, 1, 2), - /* 0101 */ V(1, 1, 2), - /* 0110 */ V(1, 1, 2), - /* 0111 */ V(1, 1, 2), - /* 1000 */ V(0, 1, 3), - /* 1001 */ V(0, 1, 3), - /* 1010 */ V(1, 0, 3), - /* 1011 */ V(1, 0, 3), - /* 1100 */ V(0, 0, 2), - /* 1101 */ V(0, 0, 2), - /* 1110 */ V(0, 0, 2), - /* 1111 */ V(0, 0, 2), - - /* 0000 ... */ - /* 0000 */ PTR(36, 3), /* 16 */ - /* 0001 */ PTR(44, 2), - /* 0010 */ PTR(48, 1), - /* 0011 */ V(1, 5, 4), - /* 0100 */ V(5, 1, 4), - /* 0101 */ PTR(50, 1), - /* 0110 */ PTR(52, 1), - /* 0111 */ V(2, 4, 4), - /* 1000 */ V(4, 2, 4), - /* 1001 */ V(1, 4, 4), - /* 1010 */ V(4, 1, 3), - /* 1011 */ V(4, 1, 3), - /* 1100 */ V(0, 4, 4), - /* 1101 */ V(4, 0, 4), - /* 1110 */ V(2, 3, 4), - /* 1111 */ V(3, 2, 4), - - /* 0001 ... */ - /* 00 */ PTR(54, 2), /* 32 */ - /* 01 */ V(2, 2, 2), - /* 10 */ V(0, 2, 2), - /* 11 */ V(2, 0, 2), - - /* 0000 0000 ... */ - /* 000 */ V(5, 5, 3), /* 36 */ - /* 001 */ V(5, 4, 3), - /* 010 */ V(4, 5, 2), - /* 011 */ V(4, 5, 2), - /* 100 */ V(5, 3, 1), - /* 101 */ V(5, 3, 1), - /* 110 */ V(5, 3, 1), - /* 111 */ V(5, 3, 1), - - /* 0000 0001 ... */ - /* 00 */ V(3, 5, 2), /* 44 */ - /* 01 */ V(4, 4, 2), - /* 10 */ V(2, 5, 1), - /* 11 */ V(2, 5, 1), - - /* 0000 0010 ... */ - /* 0 */ V(5, 2, 1), /* 48 */ - /* 1 */ V(0, 5, 1), - - /* 0000 0101 ... */ - /* 0 */ V(3, 4, 1), /* 50 */ - /* 1 */ V(4, 3, 1), - - /* 0000 0110 ... */ - /* 0 */ V(5, 0, 1), /* 52 */ - /* 1 */ V(3, 3, 1), - - /* 0001 00 ... */ - /* 00 */ V(1, 3, 2), /* 54 */ - /* 01 */ V(3, 1, 2), - /* 10 */ V(0, 3, 2), - /* 11 */ V(3, 0, 2), + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 2), + /* 0010 */ V(1, 2, 4), + /* 0011 */ V(2, 1, 4), + /* 0100 */ V(1, 1, 2), + /* 0101 */ V(1, 1, 2), + /* 0110 */ V(1, 1, 2), + /* 0111 */ V(1, 1, 2), + /* 1000 */ V(0, 1, 3), + /* 1001 */ V(0, 1, 3), + /* 1010 */ V(1, 0, 3), + /* 1011 */ V(1, 0, 3), + /* 1100 */ V(0, 0, 2), + /* 1101 */ V(0, 0, 2), + /* 1110 */ V(0, 0, 2), + /* 1111 */ V(0, 0, 2), + + /* 0000 ... */ + /* 0000 */ PTR(36, 3), /* 16 */ + /* 0001 */ PTR(44, 2), + /* 0010 */ PTR(48, 1), + /* 0011 */ V(1, 5, 4), + /* 0100 */ V(5, 1, 4), + /* 0101 */ PTR(50, 1), + /* 0110 */ PTR(52, 1), + /* 0111 */ V(2, 4, 4), + /* 1000 */ V(4, 2, 4), + /* 1001 */ V(1, 4, 4), + /* 1010 */ V(4, 1, 3), + /* 1011 */ V(4, 1, 3), + /* 1100 */ V(0, 4, 4), + /* 1101 */ V(4, 0, 4), + /* 1110 */ V(2, 3, 4), + /* 1111 */ V(3, 2, 4), + + /* 0001 ... */ + /* 00 */ PTR(54, 2), /* 32 */ + /* 01 */ V(2, 2, 2), + /* 10 */ V(0, 2, 2), + /* 11 */ V(2, 0, 2), + + /* 0000 0000 ... */ + /* 000 */ V(5, 5, 3), /* 36 */ + /* 001 */ V(5, 4, 3), + /* 010 */ V(4, 5, 2), + /* 011 */ V(4, 5, 2), + /* 100 */ V(5, 3, 1), + /* 101 */ V(5, 3, 1), + /* 110 */ V(5, 3, 1), + /* 111 */ V(5, 3, 1), + + /* 0000 0001 ... */ + /* 00 */ V(3, 5, 2), /* 44 */ + /* 01 */ V(4, 4, 2), + /* 10 */ V(2, 5, 1), + /* 11 */ V(2, 5, 1), + + /* 0000 0010 ... */ + /* 0 */ V(5, 2, 1), /* 48 */ + /* 1 */ V(0, 5, 1), + + /* 0000 0101 ... */ + /* 0 */ V(3, 4, 1), /* 50 */ + /* 1 */ V(4, 3, 1), + + /* 0000 0110 ... */ + /* 0 */ V(5, 0, 1), /* 52 */ + /* 1 */ V(3, 3, 1), + + /* 0001 00 ... */ + /* 00 */ V(1, 3, 2), /* 54 */ + /* 01 */ V(3, 1, 2), + /* 10 */ V(0, 3, 2), + /* 11 */ V(3, 0, 2), }; # else static union huffpair const hufftab8[] PROGMEM = { - /* 0000 */ PTR(16, 4), - /* 0001 */ PTR(32, 4), - /* 0010 */ V(1, 2, 4), - /* 0011 */ V(2, 1, 4), - /* 0100 */ V(1, 1, 2), - /* 0101 */ V(1, 1, 2), - /* 0110 */ V(1, 1, 2), - /* 0111 */ V(1, 1, 2), - /* 1000 */ V(0, 1, 3), - /* 1001 */ V(0, 1, 3), - /* 1010 */ V(1, 0, 3), - /* 1011 */ V(1, 0, 3), - /* 1100 */ V(0, 0, 2), - /* 1101 */ V(0, 0, 2), - /* 1110 */ V(0, 0, 2), - /* 1111 */ V(0, 0, 2), - - /* 0000 ... */ - /* 0000 */ PTR(48, 3), /* 16 */ - /* 0001 */ PTR(56, 2), - /* 0010 */ PTR(60, 1), - /* 0011 */ V(1, 5, 4), - /* 0100 */ V(5, 1, 4), - /* 0101 */ PTR(62, 1), - /* 0110 */ PTR(64, 1), - /* 0111 */ V(2, 4, 4), - /* 1000 */ V(4, 2, 4), - /* 1001 */ V(1, 4, 4), - /* 1010 */ V(4, 1, 3), - /* 1011 */ V(4, 1, 3), - /* 1100 */ V(0, 4, 4), - /* 1101 */ V(4, 0, 4), - /* 1110 */ V(2, 3, 4), - /* 1111 */ V(3, 2, 4), - - /* 0001 ... */ - /* 0000 */ V(1, 3, 4), /* 32 */ - /* 0001 */ V(3, 1, 4), - /* 0010 */ V(0, 3, 4), - /* 0011 */ V(3, 0, 4), - /* 0100 */ V(2, 2, 2), - /* 0101 */ V(2, 2, 2), - /* 0110 */ V(2, 2, 2), - /* 0111 */ V(2, 2, 2), - /* 1000 */ V(0, 2, 2), - /* 1001 */ V(0, 2, 2), - /* 1010 */ V(0, 2, 2), - /* 1011 */ V(0, 2, 2), - /* 1100 */ V(2, 0, 2), - /* 1101 */ V(2, 0, 2), - /* 1110 */ V(2, 0, 2), - /* 1111 */ V(2, 0, 2), - - /* 0000 0000 ... */ - /* 000 */ V(5, 5, 3), /* 48 */ - /* 001 */ V(5, 4, 3), - /* 010 */ V(4, 5, 2), - /* 011 */ V(4, 5, 2), - /* 100 */ V(5, 3, 1), - /* 101 */ V(5, 3, 1), - /* 110 */ V(5, 3, 1), - /* 111 */ V(5, 3, 1), - - /* 0000 0001 ... */ - /* 00 */ V(3, 5, 2), /* 56 */ - /* 01 */ V(4, 4, 2), - /* 10 */ V(2, 5, 1), - /* 11 */ V(2, 5, 1), - - /* 0000 0010 ... */ - /* 0 */ V(5, 2, 1), /* 60 */ - /* 1 */ V(0, 5, 1), - - /* 0000 0101 ... */ - /* 0 */ V(3, 4, 1), /* 62 */ - /* 1 */ V(4, 3, 1), - - /* 0000 0110 ... */ - /* 0 */ V(5, 0, 1), /* 64 */ - /* 1 */ V(3, 3, 1) + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ V(1, 2, 4), + /* 0011 */ V(2, 1, 4), + /* 0100 */ V(1, 1, 2), + /* 0101 */ V(1, 1, 2), + /* 0110 */ V(1, 1, 2), + /* 0111 */ V(1, 1, 2), + /* 1000 */ V(0, 1, 3), + /* 1001 */ V(0, 1, 3), + /* 1010 */ V(1, 0, 3), + /* 1011 */ V(1, 0, 3), + /* 1100 */ V(0, 0, 2), + /* 1101 */ V(0, 0, 2), + /* 1110 */ V(0, 0, 2), + /* 1111 */ V(0, 0, 2), + + /* 0000 ... */ + /* 0000 */ PTR(48, 3), /* 16 */ + /* 0001 */ PTR(56, 2), + /* 0010 */ PTR(60, 1), + /* 0011 */ V(1, 5, 4), + /* 0100 */ V(5, 1, 4), + /* 0101 */ PTR(62, 1), + /* 0110 */ PTR(64, 1), + /* 0111 */ V(2, 4, 4), + /* 1000 */ V(4, 2, 4), + /* 1001 */ V(1, 4, 4), + /* 1010 */ V(4, 1, 3), + /* 1011 */ V(4, 1, 3), + /* 1100 */ V(0, 4, 4), + /* 1101 */ V(4, 0, 4), + /* 1110 */ V(2, 3, 4), + /* 1111 */ V(3, 2, 4), + + /* 0001 ... */ + /* 0000 */ V(1, 3, 4), /* 32 */ + /* 0001 */ V(3, 1, 4), + /* 0010 */ V(0, 3, 4), + /* 0011 */ V(3, 0, 4), + /* 0100 */ V(2, 2, 2), + /* 0101 */ V(2, 2, 2), + /* 0110 */ V(2, 2, 2), + /* 0111 */ V(2, 2, 2), + /* 1000 */ V(0, 2, 2), + /* 1001 */ V(0, 2, 2), + /* 1010 */ V(0, 2, 2), + /* 1011 */ V(0, 2, 2), + /* 1100 */ V(2, 0, 2), + /* 1101 */ V(2, 0, 2), + /* 1110 */ V(2, 0, 2), + /* 1111 */ V(2, 0, 2), + + /* 0000 0000 ... */ + /* 000 */ V(5, 5, 3), /* 48 */ + /* 001 */ V(5, 4, 3), + /* 010 */ V(4, 5, 2), + /* 011 */ V(4, 5, 2), + /* 100 */ V(5, 3, 1), + /* 101 */ V(5, 3, 1), + /* 110 */ V(5, 3, 1), + /* 111 */ V(5, 3, 1), + + /* 0000 0001 ... */ + /* 00 */ V(3, 5, 2), /* 56 */ + /* 01 */ V(4, 4, 2), + /* 10 */ V(2, 5, 1), + /* 11 */ V(2, 5, 1), + + /* 0000 0010 ... */ + /* 0 */ V(5, 2, 1), /* 60 */ + /* 1 */ V(0, 5, 1), + + /* 0000 0101 ... */ + /* 0 */ V(3, 4, 1), /* 62 */ + /* 1 */ V(4, 3, 1), + + /* 0000 0110 ... */ + /* 0 */ V(5, 0, 1), /* 64 */ + /* 1 */ V(3, 3, 1) }; # endif static union huffpair const hufftab9[] PROGMEM = { - /* 0000 */ PTR(16, 4), - /* 0001 */ PTR(32, 3), - /* 0010 */ PTR(40, 2), - /* 0011 */ PTR(44, 2), - /* 0100 */ PTR(48, 1), - /* 0101 */ V(1, 2, 4), - /* 0110 */ V(2, 1, 4), - /* 0111 */ V(2, 0, 4), - /* 1000 */ V(1, 1, 3), - /* 1001 */ V(1, 1, 3), - /* 1010 */ V(0, 1, 3), - /* 1011 */ V(0, 1, 3), - /* 1100 */ V(1, 0, 3), - /* 1101 */ V(1, 0, 3), - /* 1110 */ V(0, 0, 3), - /* 1111 */ V(0, 0, 3), - - /* 0000 ... */ - /* 0000 */ PTR(50, 1), /* 16 */ - /* 0001 */ V(3, 5, 4), - /* 0010 */ V(5, 3, 4), - /* 0011 */ PTR(52, 1), - /* 0100 */ V(4, 4, 4), - /* 0101 */ V(2, 5, 4), - /* 0110 */ V(5, 2, 4), - /* 0111 */ V(1, 5, 4), - /* 1000 */ V(5, 1, 3), - /* 1001 */ V(5, 1, 3), - /* 1010 */ V(3, 4, 3), - /* 1011 */ V(3, 4, 3), - /* 1100 */ V(4, 3, 3), - /* 1101 */ V(4, 3, 3), - /* 1110 */ V(5, 0, 4), - /* 1111 */ V(0, 4, 4), - - /* 0001 ... */ - /* 000 */ V(2, 4, 3), /* 32 */ - /* 001 */ V(4, 2, 3), - /* 010 */ V(3, 3, 3), - /* 011 */ V(4, 0, 3), - /* 100 */ V(1, 4, 2), - /* 101 */ V(1, 4, 2), - /* 110 */ V(4, 1, 2), - /* 111 */ V(4, 1, 2), - - /* 0010 ... */ - /* 00 */ V(2, 3, 2), /* 40 */ - /* 01 */ V(3, 2, 2), - /* 10 */ V(1, 3, 1), - /* 11 */ V(1, 3, 1), - - /* 0011 ... */ - /* 00 */ V(3, 1, 1), /* 44 */ - /* 01 */ V(3, 1, 1), - /* 10 */ V(0, 3, 2), - /* 11 */ V(3, 0, 2), - - /* 0100 ... */ - /* 0 */ V(2, 2, 1), /* 48 */ - /* 1 */ V(0, 2, 1), - - /* 0000 0000 ... */ - /* 0 */ V(5, 5, 1), /* 50 */ - /* 1 */ V(4, 5, 1), - - /* 0000 0011 ... */ - /* 0 */ V(5, 4, 1), /* 52 */ - /* 1 */ V(0, 5, 1) + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 3), + /* 0010 */ PTR(40, 2), + /* 0011 */ PTR(44, 2), + /* 0100 */ PTR(48, 1), + /* 0101 */ V(1, 2, 4), + /* 0110 */ V(2, 1, 4), + /* 0111 */ V(2, 0, 4), + /* 1000 */ V(1, 1, 3), + /* 1001 */ V(1, 1, 3), + /* 1010 */ V(0, 1, 3), + /* 1011 */ V(0, 1, 3), + /* 1100 */ V(1, 0, 3), + /* 1101 */ V(1, 0, 3), + /* 1110 */ V(0, 0, 3), + /* 1111 */ V(0, 0, 3), + + /* 0000 ... */ + /* 0000 */ PTR(50, 1), /* 16 */ + /* 0001 */ V(3, 5, 4), + /* 0010 */ V(5, 3, 4), + /* 0011 */ PTR(52, 1), + /* 0100 */ V(4, 4, 4), + /* 0101 */ V(2, 5, 4), + /* 0110 */ V(5, 2, 4), + /* 0111 */ V(1, 5, 4), + /* 1000 */ V(5, 1, 3), + /* 1001 */ V(5, 1, 3), + /* 1010 */ V(3, 4, 3), + /* 1011 */ V(3, 4, 3), + /* 1100 */ V(4, 3, 3), + /* 1101 */ V(4, 3, 3), + /* 1110 */ V(5, 0, 4), + /* 1111 */ V(0, 4, 4), + + /* 0001 ... */ + /* 000 */ V(2, 4, 3), /* 32 */ + /* 001 */ V(4, 2, 3), + /* 010 */ V(3, 3, 3), + /* 011 */ V(4, 0, 3), + /* 100 */ V(1, 4, 2), + /* 101 */ V(1, 4, 2), + /* 110 */ V(4, 1, 2), + /* 111 */ V(4, 1, 2), + + /* 0010 ... */ + /* 00 */ V(2, 3, 2), /* 40 */ + /* 01 */ V(3, 2, 2), + /* 10 */ V(1, 3, 1), + /* 11 */ V(1, 3, 1), + + /* 0011 ... */ + /* 00 */ V(3, 1, 1), /* 44 */ + /* 01 */ V(3, 1, 1), + /* 10 */ V(0, 3, 2), + /* 11 */ V(3, 0, 2), + + /* 0100 ... */ + /* 0 */ V(2, 2, 1), /* 48 */ + /* 1 */ V(0, 2, 1), + + /* 0000 0000 ... */ + /* 0 */ V(5, 5, 1), /* 50 */ + /* 1 */ V(4, 5, 1), + + /* 0000 0011 ... */ + /* 0 */ V(5, 4, 1), /* 52 */ + /* 1 */ V(0, 5, 1) }; static union huffpair const hufftab10[] PROGMEM = { - /* 0000 */ PTR(16, 4), - /* 0001 */ PTR(32, 4), - /* 0010 */ PTR(48, 2), - /* 0011 */ V(1, 1, 4), - /* 0100 */ V(0, 1, 3), - /* 0101 */ V(0, 1, 3), - /* 0110 */ V(1, 0, 3), - /* 0111 */ V(1, 0, 3), - /* 1000 */ V(0, 0, 1), - /* 1001 */ V(0, 0, 1), - /* 1010 */ V(0, 0, 1), - /* 1011 */ V(0, 0, 1), - /* 1100 */ V(0, 0, 1), - /* 1101 */ V(0, 0, 1), - /* 1110 */ V(0, 0, 1), - /* 1111 */ V(0, 0, 1), - - /* 0000 ... */ - /* 0000 */ PTR(52, 3), /* 16 */ - /* 0001 */ PTR(60, 2), - /* 0010 */ PTR(64, 3), - /* 0011 */ PTR(72, 1), - /* 0100 */ PTR(74, 2), - /* 0101 */ PTR(78, 2), - /* 0110 */ PTR(82, 2), - /* 0111 */ V(1, 7, 4), - /* 1000 */ V(7, 1, 4), - /* 1001 */ PTR(86, 1), - /* 1010 */ PTR(88, 2), - /* 1011 */ PTR(92, 2), - /* 1100 */ V(1, 6, 4), - /* 1101 */ V(6, 1, 4), - /* 1110 */ V(6, 0, 4), - /* 1111 */ PTR(96, 1), - - /* 0001 ... */ - /* 0000 */ PTR(98, 1), /* 32 */ - /* 0001 */ PTR(100, 1), - /* 0010 */ V(1, 4, 4), - /* 0011 */ V(4, 1, 4), - /* 0100 */ V(4, 0, 4), - /* 0101 */ V(2, 3, 4), - /* 0110 */ V(3, 2, 4), - /* 0111 */ V(0, 3, 4), - /* 1000 */ V(1, 3, 3), - /* 1001 */ V(1, 3, 3), - /* 1010 */ V(3, 1, 3), - /* 1011 */ V(3, 1, 3), - /* 1100 */ V(3, 0, 3), - /* 1101 */ V(3, 0, 3), - /* 1110 */ V(2, 2, 3), - /* 1111 */ V(2, 2, 3), - - /* 0010 ... */ - /* 00 */ V(1, 2, 2), /* 48 */ - /* 01 */ V(2, 1, 2), - /* 10 */ V(0, 2, 2), - /* 11 */ V(2, 0, 2), - - /* 0000 0000 ... */ - /* 000 */ V(7, 7, 3), /* 52 */ - /* 001 */ V(6, 7, 3), - /* 010 */ V(7, 6, 3), - /* 011 */ V(5, 7, 3), - /* 100 */ V(7, 5, 3), - /* 101 */ V(6, 6, 3), - /* 110 */ V(4, 7, 2), - /* 111 */ V(4, 7, 2), - - /* 0000 0001 ... */ - /* 00 */ V(7, 4, 2), /* 60 */ - /* 01 */ V(5, 6, 2), - /* 10 */ V(6, 5, 2), - /* 11 */ V(3, 7, 2), - - /* 0000 0010 ... */ - /* 000 */ V(7, 3, 2), /* 64 */ - /* 001 */ V(7, 3, 2), - /* 010 */ V(4, 6, 2), - /* 011 */ V(4, 6, 2), - /* 100 */ V(5, 5, 3), - /* 101 */ V(5, 4, 3), - /* 110 */ V(6, 3, 2), - /* 111 */ V(6, 3, 2), - - /* 0000 0011 ... */ - /* 0 */ V(2, 7, 1), /* 72 */ - /* 1 */ V(7, 2, 1), - - /* 0000 0100 ... */ - /* 00 */ V(6, 4, 2), /* 74 */ - /* 01 */ V(0, 7, 2), - /* 10 */ V(7, 0, 1), - /* 11 */ V(7, 0, 1), - - /* 0000 0101 ... */ - /* 00 */ V(6, 2, 1), /* 78 */ - /* 01 */ V(6, 2, 1), - /* 10 */ V(4, 5, 2), - /* 11 */ V(3, 5, 2), - - /* 0000 0110 ... */ - /* 00 */ V(0, 6, 1), /* 82 */ - /* 01 */ V(0, 6, 1), - /* 10 */ V(5, 3, 2), - /* 11 */ V(4, 4, 2), - - /* 0000 1001 ... */ - /* 0 */ V(3, 6, 1), /* 86 */ - /* 1 */ V(2, 6, 1), - - /* 0000 1010 ... */ - /* 00 */ V(2, 5, 2), /* 88 */ - /* 01 */ V(5, 2, 2), - /* 10 */ V(1, 5, 1), - /* 11 */ V(1, 5, 1), - - /* 0000 1011 ... */ - /* 00 */ V(5, 1, 1), /* 92 */ - /* 01 */ V(5, 1, 1), - /* 10 */ V(3, 4, 2), - /* 11 */ V(4, 3, 2), - - /* 0000 1111 ... */ - /* 0 */ V(0, 5, 1), /* 96 */ - /* 1 */ V(5, 0, 1), - - /* 0001 0000 ... */ - /* 0 */ V(2, 4, 1), /* 98 */ - /* 1 */ V(4, 2, 1), - - /* 0001 0001 ... */ - /* 0 */ V(3, 3, 1), /* 100 */ - /* 1 */ V(0, 4, 1) + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ PTR(48, 2), + /* 0011 */ V(1, 1, 4), + /* 0100 */ V(0, 1, 3), + /* 0101 */ V(0, 1, 3), + /* 0110 */ V(1, 0, 3), + /* 0111 */ V(1, 0, 3), + /* 1000 */ V(0, 0, 1), + /* 1001 */ V(0, 0, 1), + /* 1010 */ V(0, 0, 1), + /* 1011 */ V(0, 0, 1), + /* 1100 */ V(0, 0, 1), + /* 1101 */ V(0, 0, 1), + /* 1110 */ V(0, 0, 1), + /* 1111 */ V(0, 0, 1), + + /* 0000 ... */ + /* 0000 */ PTR(52, 3), /* 16 */ + /* 0001 */ PTR(60, 2), + /* 0010 */ PTR(64, 3), + /* 0011 */ PTR(72, 1), + /* 0100 */ PTR(74, 2), + /* 0101 */ PTR(78, 2), + /* 0110 */ PTR(82, 2), + /* 0111 */ V(1, 7, 4), + /* 1000 */ V(7, 1, 4), + /* 1001 */ PTR(86, 1), + /* 1010 */ PTR(88, 2), + /* 1011 */ PTR(92, 2), + /* 1100 */ V(1, 6, 4), + /* 1101 */ V(6, 1, 4), + /* 1110 */ V(6, 0, 4), + /* 1111 */ PTR(96, 1), + + /* 0001 ... */ + /* 0000 */ PTR(98, 1), /* 32 */ + /* 0001 */ PTR(100, 1), + /* 0010 */ V(1, 4, 4), + /* 0011 */ V(4, 1, 4), + /* 0100 */ V(4, 0, 4), + /* 0101 */ V(2, 3, 4), + /* 0110 */ V(3, 2, 4), + /* 0111 */ V(0, 3, 4), + /* 1000 */ V(1, 3, 3), + /* 1001 */ V(1, 3, 3), + /* 1010 */ V(3, 1, 3), + /* 1011 */ V(3, 1, 3), + /* 1100 */ V(3, 0, 3), + /* 1101 */ V(3, 0, 3), + /* 1110 */ V(2, 2, 3), + /* 1111 */ V(2, 2, 3), + + /* 0010 ... */ + /* 00 */ V(1, 2, 2), /* 48 */ + /* 01 */ V(2, 1, 2), + /* 10 */ V(0, 2, 2), + /* 11 */ V(2, 0, 2), + + /* 0000 0000 ... */ + /* 000 */ V(7, 7, 3), /* 52 */ + /* 001 */ V(6, 7, 3), + /* 010 */ V(7, 6, 3), + /* 011 */ V(5, 7, 3), + /* 100 */ V(7, 5, 3), + /* 101 */ V(6, 6, 3), + /* 110 */ V(4, 7, 2), + /* 111 */ V(4, 7, 2), + + /* 0000 0001 ... */ + /* 00 */ V(7, 4, 2), /* 60 */ + /* 01 */ V(5, 6, 2), + /* 10 */ V(6, 5, 2), + /* 11 */ V(3, 7, 2), + + /* 0000 0010 ... */ + /* 000 */ V(7, 3, 2), /* 64 */ + /* 001 */ V(7, 3, 2), + /* 010 */ V(4, 6, 2), + /* 011 */ V(4, 6, 2), + /* 100 */ V(5, 5, 3), + /* 101 */ V(5, 4, 3), + /* 110 */ V(6, 3, 2), + /* 111 */ V(6, 3, 2), + + /* 0000 0011 ... */ + /* 0 */ V(2, 7, 1), /* 72 */ + /* 1 */ V(7, 2, 1), + + /* 0000 0100 ... */ + /* 00 */ V(6, 4, 2), /* 74 */ + /* 01 */ V(0, 7, 2), + /* 10 */ V(7, 0, 1), + /* 11 */ V(7, 0, 1), + + /* 0000 0101 ... */ + /* 00 */ V(6, 2, 1), /* 78 */ + /* 01 */ V(6, 2, 1), + /* 10 */ V(4, 5, 2), + /* 11 */ V(3, 5, 2), + + /* 0000 0110 ... */ + /* 00 */ V(0, 6, 1), /* 82 */ + /* 01 */ V(0, 6, 1), + /* 10 */ V(5, 3, 2), + /* 11 */ V(4, 4, 2), + + /* 0000 1001 ... */ + /* 0 */ V(3, 6, 1), /* 86 */ + /* 1 */ V(2, 6, 1), + + /* 0000 1010 ... */ + /* 00 */ V(2, 5, 2), /* 88 */ + /* 01 */ V(5, 2, 2), + /* 10 */ V(1, 5, 1), + /* 11 */ V(1, 5, 1), + + /* 0000 1011 ... */ + /* 00 */ V(5, 1, 1), /* 92 */ + /* 01 */ V(5, 1, 1), + /* 10 */ V(3, 4, 2), + /* 11 */ V(4, 3, 2), + + /* 0000 1111 ... */ + /* 0 */ V(0, 5, 1), /* 96 */ + /* 1 */ V(5, 0, 1), + + /* 0001 0000 ... */ + /* 0 */ V(2, 4, 1), /* 98 */ + /* 1 */ V(4, 2, 1), + + /* 0001 0001 ... */ + /* 0 */ V(3, 3, 1), /* 100 */ + /* 1 */ V(0, 4, 1) }; static union huffpair const hufftab11[] PROGMEM = { - /* 0000 */ PTR(16, 4), - /* 0001 */ PTR(32, 4), - /* 0010 */ PTR(48, 4), - /* 0011 */ PTR(64, 3), - /* 0100 */ V(1, 2, 4), - /* 0101 */ PTR(72, 1), - /* 0110 */ V(1, 1, 3), - /* 0111 */ V(1, 1, 3), - /* 1000 */ V(0, 1, 3), - /* 1001 */ V(0, 1, 3), - /* 1010 */ V(1, 0, 3), - /* 1011 */ V(1, 0, 3), - /* 1100 */ V(0, 0, 2), - /* 1101 */ V(0, 0, 2), - /* 1110 */ V(0, 0, 2), - /* 1111 */ V(0, 0, 2), - - /* 0000 ... */ - /* 0000 */ PTR(74, 2), /* 16 */ - /* 0001 */ PTR(78, 3), - /* 0010 */ PTR(86, 2), - /* 0011 */ PTR(90, 1), - /* 0100 */ PTR(92, 2), - /* 0101 */ V(2, 7, 4), - /* 0110 */ V(7, 2, 4), - /* 0111 */ PTR(96, 1), - /* 1000 */ V(7, 1, 3), - /* 1001 */ V(7, 1, 3), - /* 1010 */ V(1, 7, 4), - /* 1011 */ V(7, 0, 4), - /* 1100 */ V(3, 6, 4), - /* 1101 */ V(6, 3, 4), - /* 1110 */ V(6, 0, 4), - /* 1111 */ PTR(98, 1), - - /* 0001 ... */ - /* 0000 */ PTR(100, 1), /* 32 */ - /* 0001 */ V(1, 5, 4), - /* 0010 */ V(6, 2, 3), - /* 0011 */ V(6, 2, 3), - /* 0100 */ V(2, 6, 4), - /* 0101 */ V(0, 6, 4), - /* 0110 */ V(1, 6, 3), - /* 0111 */ V(1, 6, 3), - /* 1000 */ V(6, 1, 3), - /* 1001 */ V(6, 1, 3), - /* 1010 */ V(5, 1, 4), - /* 1011 */ V(3, 4, 4), - /* 1100 */ V(5, 0, 4), - /* 1101 */ PTR(102, 1), - /* 1110 */ V(2, 4, 4), - /* 1111 */ V(4, 2, 4), - - /* 0010 ... */ - /* 0000 */ V(1, 4, 4), /* 48 */ - /* 0001 */ V(4, 1, 4), - /* 0010 */ V(0, 4, 4), - /* 0011 */ V(4, 0, 4), - /* 0100 */ V(2, 3, 3), - /* 0101 */ V(2, 3, 3), - /* 0110 */ V(3, 2, 3), - /* 0111 */ V(3, 2, 3), - /* 1000 */ V(1, 3, 2), - /* 1001 */ V(1, 3, 2), - /* 1010 */ V(1, 3, 2), - /* 1011 */ V(1, 3, 2), - /* 1100 */ V(3, 1, 2), - /* 1101 */ V(3, 1, 2), - /* 1110 */ V(3, 1, 2), - /* 1111 */ V(3, 1, 2), - - /* 0011 ... */ - /* 000 */ V(0, 3, 3), /* 64 */ - /* 001 */ V(3, 0, 3), - /* 010 */ V(2, 2, 2), - /* 011 */ V(2, 2, 2), - /* 100 */ V(2, 1, 1), - /* 101 */ V(2, 1, 1), - /* 110 */ V(2, 1, 1), - /* 111 */ V(2, 1, 1), - - /* 0101 ... */ - /* 0 */ V(0, 2, 1), /* 72 */ - /* 1 */ V(2, 0, 1), - - /* 0000 0000 ... */ - /* 00 */ V(7, 7, 2), /* 74 */ - /* 01 */ V(6, 7, 2), - /* 10 */ V(7, 6, 2), - /* 11 */ V(7, 5, 2), - - /* 0000 0001 ... */ - /* 000 */ V(6, 6, 2), /* 78 */ - /* 001 */ V(6, 6, 2), - /* 010 */ V(4, 7, 2), - /* 011 */ V(4, 7, 2), - /* 100 */ V(7, 4, 2), - /* 101 */ V(7, 4, 2), - /* 110 */ V(5, 7, 3), - /* 111 */ V(5, 5, 3), - - /* 0000 0010 ... */ - /* 00 */ V(5, 6, 2), /* 86 */ - /* 01 */ V(6, 5, 2), - /* 10 */ V(3, 7, 1), - /* 11 */ V(3, 7, 1), - - /* 0000 0011 ... */ - /* 0 */ V(7, 3, 1), /* 90 */ - /* 1 */ V(4, 6, 1), - - /* 0000 0100 ... */ - /* 00 */ V(4, 5, 2), /* 92 */ - /* 01 */ V(5, 4, 2), - /* 10 */ V(3, 5, 2), - /* 11 */ V(5, 3, 2), - - /* 0000 0111 ... */ - /* 0 */ V(6, 4, 1), /* 96 */ - /* 1 */ V(0, 7, 1), - - /* 0000 1111 ... */ - /* 0 */ V(4, 4, 1), /* 98 */ - /* 1 */ V(2, 5, 1), - - /* 0001 0000 ... */ - /* 0 */ V(5, 2, 1), /* 100 */ - /* 1 */ V(0, 5, 1), - - /* 0001 1101 ... */ - /* 0 */ V(4, 3, 1), /* 102 */ - /* 1 */ V(3, 3, 1) + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ PTR(48, 4), + /* 0011 */ PTR(64, 3), + /* 0100 */ V(1, 2, 4), + /* 0101 */ PTR(72, 1), + /* 0110 */ V(1, 1, 3), + /* 0111 */ V(1, 1, 3), + /* 1000 */ V(0, 1, 3), + /* 1001 */ V(0, 1, 3), + /* 1010 */ V(1, 0, 3), + /* 1011 */ V(1, 0, 3), + /* 1100 */ V(0, 0, 2), + /* 1101 */ V(0, 0, 2), + /* 1110 */ V(0, 0, 2), + /* 1111 */ V(0, 0, 2), + + /* 0000 ... */ + /* 0000 */ PTR(74, 2), /* 16 */ + /* 0001 */ PTR(78, 3), + /* 0010 */ PTR(86, 2), + /* 0011 */ PTR(90, 1), + /* 0100 */ PTR(92, 2), + /* 0101 */ V(2, 7, 4), + /* 0110 */ V(7, 2, 4), + /* 0111 */ PTR(96, 1), + /* 1000 */ V(7, 1, 3), + /* 1001 */ V(7, 1, 3), + /* 1010 */ V(1, 7, 4), + /* 1011 */ V(7, 0, 4), + /* 1100 */ V(3, 6, 4), + /* 1101 */ V(6, 3, 4), + /* 1110 */ V(6, 0, 4), + /* 1111 */ PTR(98, 1), + + /* 0001 ... */ + /* 0000 */ PTR(100, 1), /* 32 */ + /* 0001 */ V(1, 5, 4), + /* 0010 */ V(6, 2, 3), + /* 0011 */ V(6, 2, 3), + /* 0100 */ V(2, 6, 4), + /* 0101 */ V(0, 6, 4), + /* 0110 */ V(1, 6, 3), + /* 0111 */ V(1, 6, 3), + /* 1000 */ V(6, 1, 3), + /* 1001 */ V(6, 1, 3), + /* 1010 */ V(5, 1, 4), + /* 1011 */ V(3, 4, 4), + /* 1100 */ V(5, 0, 4), + /* 1101 */ PTR(102, 1), + /* 1110 */ V(2, 4, 4), + /* 1111 */ V(4, 2, 4), + + /* 0010 ... */ + /* 0000 */ V(1, 4, 4), /* 48 */ + /* 0001 */ V(4, 1, 4), + /* 0010 */ V(0, 4, 4), + /* 0011 */ V(4, 0, 4), + /* 0100 */ V(2, 3, 3), + /* 0101 */ V(2, 3, 3), + /* 0110 */ V(3, 2, 3), + /* 0111 */ V(3, 2, 3), + /* 1000 */ V(1, 3, 2), + /* 1001 */ V(1, 3, 2), + /* 1010 */ V(1, 3, 2), + /* 1011 */ V(1, 3, 2), + /* 1100 */ V(3, 1, 2), + /* 1101 */ V(3, 1, 2), + /* 1110 */ V(3, 1, 2), + /* 1111 */ V(3, 1, 2), + + /* 0011 ... */ + /* 000 */ V(0, 3, 3), /* 64 */ + /* 001 */ V(3, 0, 3), + /* 010 */ V(2, 2, 2), + /* 011 */ V(2, 2, 2), + /* 100 */ V(2, 1, 1), + /* 101 */ V(2, 1, 1), + /* 110 */ V(2, 1, 1), + /* 111 */ V(2, 1, 1), + + /* 0101 ... */ + /* 0 */ V(0, 2, 1), /* 72 */ + /* 1 */ V(2, 0, 1), + + /* 0000 0000 ... */ + /* 00 */ V(7, 7, 2), /* 74 */ + /* 01 */ V(6, 7, 2), + /* 10 */ V(7, 6, 2), + /* 11 */ V(7, 5, 2), + + /* 0000 0001 ... */ + /* 000 */ V(6, 6, 2), /* 78 */ + /* 001 */ V(6, 6, 2), + /* 010 */ V(4, 7, 2), + /* 011 */ V(4, 7, 2), + /* 100 */ V(7, 4, 2), + /* 101 */ V(7, 4, 2), + /* 110 */ V(5, 7, 3), + /* 111 */ V(5, 5, 3), + + /* 0000 0010 ... */ + /* 00 */ V(5, 6, 2), /* 86 */ + /* 01 */ V(6, 5, 2), + /* 10 */ V(3, 7, 1), + /* 11 */ V(3, 7, 1), + + /* 0000 0011 ... */ + /* 0 */ V(7, 3, 1), /* 90 */ + /* 1 */ V(4, 6, 1), + + /* 0000 0100 ... */ + /* 00 */ V(4, 5, 2), /* 92 */ + /* 01 */ V(5, 4, 2), + /* 10 */ V(3, 5, 2), + /* 11 */ V(5, 3, 2), + + /* 0000 0111 ... */ + /* 0 */ V(6, 4, 1), /* 96 */ + /* 1 */ V(0, 7, 1), + + /* 0000 1111 ... */ + /* 0 */ V(4, 4, 1), /* 98 */ + /* 1 */ V(2, 5, 1), + + /* 0001 0000 ... */ + /* 0 */ V(5, 2, 1), /* 100 */ + /* 1 */ V(0, 5, 1), + + /* 0001 1101 ... */ + /* 0 */ V(4, 3, 1), /* 102 */ + /* 1 */ V(3, 3, 1) }; static union huffpair const hufftab12[] PROGMEM = { - /* 0000 */ PTR(16, 4), - /* 0001 */ PTR(32, 4), - /* 0010 */ PTR(48, 4), - /* 0011 */ PTR(64, 2), - /* 0100 */ PTR(68, 3), - /* 0101 */ PTR(76, 1), - /* 0110 */ V(1, 2, 4), - /* 0111 */ V(2, 1, 4), - /* 1000 */ PTR(78, 1), - /* 1001 */ V(0, 0, 4), - /* 1010 */ V(1, 1, 3), - /* 1011 */ V(1, 1, 3), - /* 1100 */ V(0, 1, 3), - /* 1101 */ V(0, 1, 3), - /* 1110 */ V(1, 0, 3), - /* 1111 */ V(1, 0, 3), - - /* 0000 ... */ - /* 0000 */ PTR(80, 2), /* 16 */ - /* 0001 */ PTR(84, 1), - /* 0010 */ PTR(86, 1), - /* 0011 */ PTR(88, 1), - /* 0100 */ V(5, 6, 4), - /* 0101 */ V(3, 7, 4), - /* 0110 */ PTR(90, 1), - /* 0111 */ V(2, 7, 4), - /* 1000 */ V(7, 2, 4), - /* 1001 */ V(4, 6, 4), - /* 1010 */ V(6, 4, 4), - /* 1011 */ V(1, 7, 4), - /* 1100 */ V(7, 1, 4), - /* 1101 */ PTR(92, 1), - /* 1110 */ V(3, 6, 4), - /* 1111 */ V(6, 3, 4), - - /* 0001 ... */ - /* 0000 */ V(4, 5, 4), /* 32 */ - /* 0001 */ V(5, 4, 4), - /* 0010 */ V(4, 4, 4), - /* 0011 */ PTR(94, 1), - /* 0100 */ V(2, 6, 3), - /* 0101 */ V(2, 6, 3), - /* 0110 */ V(6, 2, 3), - /* 0111 */ V(6, 2, 3), - /* 1000 */ V(6, 1, 3), - /* 1001 */ V(6, 1, 3), - /* 1010 */ V(1, 6, 4), - /* 1011 */ V(6, 0, 4), - /* 1100 */ V(3, 5, 4), - /* 1101 */ V(5, 3, 4), - /* 1110 */ V(2, 5, 4), - /* 1111 */ V(5, 2, 4), - - /* 0010 ... */ - /* 0000 */ V(1, 5, 3), /* 48 */ - /* 0001 */ V(1, 5, 3), - /* 0010 */ V(5, 1, 3), - /* 0011 */ V(5, 1, 3), - /* 0100 */ V(3, 4, 3), - /* 0101 */ V(3, 4, 3), - /* 0110 */ V(4, 3, 3), - /* 0111 */ V(4, 3, 3), - /* 1000 */ V(5, 0, 4), - /* 1001 */ V(0, 4, 4), - /* 1010 */ V(2, 4, 3), - /* 1011 */ V(2, 4, 3), - /* 1100 */ V(4, 2, 3), - /* 1101 */ V(4, 2, 3), - /* 1110 */ V(1, 4, 3), - /* 1111 */ V(1, 4, 3), - - /* 0011 ... */ - /* 00 */ V(3, 3, 2), /* 64 */ - /* 01 */ V(4, 1, 2), - /* 10 */ V(2, 3, 2), - /* 11 */ V(3, 2, 2), - - /* 0100 ... */ - /* 000 */ V(4, 0, 3), /* 68 */ - /* 001 */ V(0, 3, 3), - /* 010 */ V(3, 0, 2), - /* 011 */ V(3, 0, 2), - /* 100 */ V(1, 3, 1), - /* 101 */ V(1, 3, 1), - /* 110 */ V(1, 3, 1), - /* 111 */ V(1, 3, 1), - - /* 0101 ... */ - /* 0 */ V(3, 1, 1), /* 76 */ - /* 1 */ V(2, 2, 1), - - /* 1000 ... */ - /* 0 */ V(0, 2, 1), /* 78 */ - /* 1 */ V(2, 0, 1), - - /* 0000 0000 ... */ - /* 00 */ V(7, 7, 2), /* 80 */ - /* 01 */ V(6, 7, 2), - /* 10 */ V(7, 6, 1), - /* 11 */ V(7, 6, 1), - - /* 0000 0001 ... */ - /* 0 */ V(5, 7, 1), /* 84 */ - /* 1 */ V(7, 5, 1), - - /* 0000 0010 ... */ - /* 0 */ V(6, 6, 1), /* 86 */ - /* 1 */ V(4, 7, 1), - - /* 0000 0011 ... */ - /* 0 */ V(7, 4, 1), /* 88 */ - /* 1 */ V(6, 5, 1), - - /* 0000 0110 ... */ - /* 0 */ V(7, 3, 1), /* 90 */ - /* 1 */ V(5, 5, 1), - - /* 0000 1101 ... */ - /* 0 */ V(0, 7, 1), /* 92 */ - /* 1 */ V(7, 0, 1), - - /* 0001 0011 ... */ - /* 0 */ V(0, 6, 1), /* 94 */ - /* 1 */ V(0, 5, 1) + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ PTR(48, 4), + /* 0011 */ PTR(64, 2), + /* 0100 */ PTR(68, 3), + /* 0101 */ PTR(76, 1), + /* 0110 */ V(1, 2, 4), + /* 0111 */ V(2, 1, 4), + /* 1000 */ PTR(78, 1), + /* 1001 */ V(0, 0, 4), + /* 1010 */ V(1, 1, 3), + /* 1011 */ V(1, 1, 3), + /* 1100 */ V(0, 1, 3), + /* 1101 */ V(0, 1, 3), + /* 1110 */ V(1, 0, 3), + /* 1111 */ V(1, 0, 3), + + /* 0000 ... */ + /* 0000 */ PTR(80, 2), /* 16 */ + /* 0001 */ PTR(84, 1), + /* 0010 */ PTR(86, 1), + /* 0011 */ PTR(88, 1), + /* 0100 */ V(5, 6, 4), + /* 0101 */ V(3, 7, 4), + /* 0110 */ PTR(90, 1), + /* 0111 */ V(2, 7, 4), + /* 1000 */ V(7, 2, 4), + /* 1001 */ V(4, 6, 4), + /* 1010 */ V(6, 4, 4), + /* 1011 */ V(1, 7, 4), + /* 1100 */ V(7, 1, 4), + /* 1101 */ PTR(92, 1), + /* 1110 */ V(3, 6, 4), + /* 1111 */ V(6, 3, 4), + + /* 0001 ... */ + /* 0000 */ V(4, 5, 4), /* 32 */ + /* 0001 */ V(5, 4, 4), + /* 0010 */ V(4, 4, 4), + /* 0011 */ PTR(94, 1), + /* 0100 */ V(2, 6, 3), + /* 0101 */ V(2, 6, 3), + /* 0110 */ V(6, 2, 3), + /* 0111 */ V(6, 2, 3), + /* 1000 */ V(6, 1, 3), + /* 1001 */ V(6, 1, 3), + /* 1010 */ V(1, 6, 4), + /* 1011 */ V(6, 0, 4), + /* 1100 */ V(3, 5, 4), + /* 1101 */ V(5, 3, 4), + /* 1110 */ V(2, 5, 4), + /* 1111 */ V(5, 2, 4), + + /* 0010 ... */ + /* 0000 */ V(1, 5, 3), /* 48 */ + /* 0001 */ V(1, 5, 3), + /* 0010 */ V(5, 1, 3), + /* 0011 */ V(5, 1, 3), + /* 0100 */ V(3, 4, 3), + /* 0101 */ V(3, 4, 3), + /* 0110 */ V(4, 3, 3), + /* 0111 */ V(4, 3, 3), + /* 1000 */ V(5, 0, 4), + /* 1001 */ V(0, 4, 4), + /* 1010 */ V(2, 4, 3), + /* 1011 */ V(2, 4, 3), + /* 1100 */ V(4, 2, 3), + /* 1101 */ V(4, 2, 3), + /* 1110 */ V(1, 4, 3), + /* 1111 */ V(1, 4, 3), + + /* 0011 ... */ + /* 00 */ V(3, 3, 2), /* 64 */ + /* 01 */ V(4, 1, 2), + /* 10 */ V(2, 3, 2), + /* 11 */ V(3, 2, 2), + + /* 0100 ... */ + /* 000 */ V(4, 0, 3), /* 68 */ + /* 001 */ V(0, 3, 3), + /* 010 */ V(3, 0, 2), + /* 011 */ V(3, 0, 2), + /* 100 */ V(1, 3, 1), + /* 101 */ V(1, 3, 1), + /* 110 */ V(1, 3, 1), + /* 111 */ V(1, 3, 1), + + /* 0101 ... */ + /* 0 */ V(3, 1, 1), /* 76 */ + /* 1 */ V(2, 2, 1), + + /* 1000 ... */ + /* 0 */ V(0, 2, 1), /* 78 */ + /* 1 */ V(2, 0, 1), + + /* 0000 0000 ... */ + /* 00 */ V(7, 7, 2), /* 80 */ + /* 01 */ V(6, 7, 2), + /* 10 */ V(7, 6, 1), + /* 11 */ V(7, 6, 1), + + /* 0000 0001 ... */ + /* 0 */ V(5, 7, 1), /* 84 */ + /* 1 */ V(7, 5, 1), + + /* 0000 0010 ... */ + /* 0 */ V(6, 6, 1), /* 86 */ + /* 1 */ V(4, 7, 1), + + /* 0000 0011 ... */ + /* 0 */ V(7, 4, 1), /* 88 */ + /* 1 */ V(6, 5, 1), + + /* 0000 0110 ... */ + /* 0 */ V(7, 3, 1), /* 90 */ + /* 1 */ V(5, 5, 1), + + /* 0000 1101 ... */ + /* 0 */ V(0, 7, 1), /* 92 */ + /* 1 */ V(7, 0, 1), + + /* 0001 0011 ... */ + /* 0 */ V(0, 6, 1), /* 94 */ + /* 1 */ V(0, 5, 1) }; static union huffpair const hufftab13[] PROGMEM = { - /* 0000 */ PTR(16, 4), - /* 0001 */ PTR(32, 4), - /* 0010 */ PTR(48, 4), - /* 0011 */ PTR(64, 2), - /* 0100 */ V(1, 1, 4), - /* 0101 */ V(0, 1, 4), - /* 0110 */ V(1, 0, 3), - /* 0111 */ V(1, 0, 3), - /* 1000 */ V(0, 0, 1), - /* 1001 */ V(0, 0, 1), - /* 1010 */ V(0, 0, 1), - /* 1011 */ V(0, 0, 1), - /* 1100 */ V(0, 0, 1), - /* 1101 */ V(0, 0, 1), - /* 1110 */ V(0, 0, 1), - /* 1111 */ V(0, 0, 1), - - /* 0000 ... */ - /* 0000 */ PTR(68, 4), /* 16 */ - /* 0001 */ PTR(84, 4), - /* 0010 */ PTR(100, 4), - /* 0011 */ PTR(116, 4), - /* 0100 */ PTR(132, 4), - /* 0101 */ PTR(148, 4), - /* 0110 */ PTR(164, 3), - /* 0111 */ PTR(172, 3), - /* 1000 */ PTR(180, 3), - /* 1001 */ PTR(188, 3), - /* 1010 */ PTR(196, 3), - /* 1011 */ PTR(204, 3), - /* 1100 */ PTR(212, 1), - /* 1101 */ PTR(214, 2), - /* 1110 */ PTR(218, 3), - /* 1111 */ PTR(226, 1), - - /* 0001 ... */ - /* 0000 */ PTR(228, 2), /* 32 */ - /* 0001 */ PTR(232, 2), - /* 0010 */ PTR(236, 2), - /* 0011 */ PTR(240, 2), - /* 0100 */ V(8, 1, 4), - /* 0101 */ PTR(244, 1), - /* 0110 */ PTR(246, 1), - /* 0111 */ PTR(248, 1), - /* 1000 */ PTR(250, 2), - /* 1001 */ PTR(254, 1), - /* 1010 */ V(1, 5, 4), - /* 1011 */ V(5, 1, 4), - /* 1100 */ PTR(256, 1), - /* 1101 */ PTR(258, 1), - /* 1110 */ PTR(260, 1), - /* 1111 */ V(1, 4, 4), - - /* 0010 ... */ - /* 0000 */ V(4, 1, 3), /* 48 */ - /* 0001 */ V(4, 1, 3), - /* 0010 */ V(0, 4, 4), - /* 0011 */ V(4, 0, 4), - /* 0100 */ V(2, 3, 4), - /* 0101 */ V(3, 2, 4), - /* 0110 */ V(1, 3, 3), - /* 0111 */ V(1, 3, 3), - /* 1000 */ V(3, 1, 3), - /* 1001 */ V(3, 1, 3), - /* 1010 */ V(0, 3, 3), - /* 1011 */ V(0, 3, 3), - /* 1100 */ V(3, 0, 3), - /* 1101 */ V(3, 0, 3), - /* 1110 */ V(2, 2, 3), - /* 1111 */ V(2, 2, 3), - - /* 0011 ... */ - /* 00 */ V(1, 2, 2), /* 64 */ - /* 01 */ V(2, 1, 2), - /* 10 */ V(0, 2, 2), - /* 11 */ V(2, 0, 2), - - /* 0000 0000 ... */ - /* 0000 */ PTR(262, 4), /* 68 */ - /* 0001 */ PTR(278, 4), - /* 0010 */ PTR(294, 4), - /* 0011 */ PTR(310, 3), - /* 0100 */ PTR(318, 2), - /* 0101 */ PTR(322, 2), - /* 0110 */ PTR(326, 3), - /* 0111 */ PTR(334, 2), - /* 1000 */ PTR(338, 1), - /* 1001 */ PTR(340, 2), - /* 1010 */ PTR(344, 2), - /* 1011 */ PTR(348, 2), - /* 1100 */ PTR(352, 2), - /* 1101 */ PTR(356, 2), - /* 1110 */ V(1, 15, 4), - /* 1111 */ V(15, 1, 4), - - /* 0000 0001 ... */ - /* 0000 */ V(15, 0, 4), /* 84 */ - /* 0001 */ PTR(360, 1), - /* 0010 */ PTR(362, 1), - /* 0011 */ PTR(364, 1), - /* 0100 */ V(14, 2, 4), - /* 0101 */ PTR(366, 1), - /* 0110 */ V(1, 14, 4), - /* 0111 */ V(14, 1, 4), - /* 1000 */ PTR(368, 1), - /* 1001 */ PTR(370, 1), - /* 1010 */ PTR(372, 1), - /* 1011 */ PTR(374, 1), - /* 1100 */ PTR(376, 1), - /* 1101 */ PTR(378, 1), - /* 1110 */ V(12, 6, 4), - /* 1111 */ V(3, 13, 4), - - /* 0000 0010 ... */ - /* 0000 */ PTR(380, 1), /* 100 */ - /* 0001 */ V(2, 13, 4), - /* 0010 */ V(13, 2, 4), - /* 0011 */ V(1, 13, 4), - /* 0100 */ V(11, 7, 4), - /* 0101 */ PTR(382, 1), - /* 0110 */ PTR(384, 1), - /* 0111 */ V(12, 3, 4), - /* 1000 */ PTR(386, 1), - /* 1001 */ V(4, 11, 4), - /* 1010 */ V(13, 1, 3), - /* 1011 */ V(13, 1, 3), - /* 1100 */ V(0, 13, 4), - /* 1101 */ V(13, 0, 4), - /* 1110 */ V(8, 10, 4), - /* 1111 */ V(10, 8, 4), - - /* 0000 0011 ... */ - /* 0000 */ V(4, 12, 4), /* 116 */ - /* 0001 */ V(12, 4, 4), - /* 0010 */ V(6, 11, 4), - /* 0011 */ V(11, 6, 4), - /* 0100 */ V(3, 12, 3), - /* 0101 */ V(3, 12, 3), - /* 0110 */ V(2, 12, 3), - /* 0111 */ V(2, 12, 3), - /* 1000 */ V(12, 2, 3), - /* 1001 */ V(12, 2, 3), - /* 1010 */ V(5, 11, 3), - /* 1011 */ V(5, 11, 3), - /* 1100 */ V(11, 5, 4), - /* 1101 */ V(8, 9, 4), - /* 1110 */ V(1, 12, 3), - /* 1111 */ V(1, 12, 3), - - /* 0000 0100 ... */ - /* 0000 */ V(12, 1, 3), /* 132 */ - /* 0001 */ V(12, 1, 3), - /* 0010 */ V(9, 8, 4), - /* 0011 */ V(0, 12, 4), - /* 0100 */ V(12, 0, 3), - /* 0101 */ V(12, 0, 3), - /* 0110 */ V(11, 4, 4), - /* 0111 */ V(6, 10, 4), - /* 1000 */ V(10, 6, 4), - /* 1001 */ V(7, 9, 4), - /* 1010 */ V(3, 11, 3), - /* 1011 */ V(3, 11, 3), - /* 1100 */ V(11, 3, 3), - /* 1101 */ V(11, 3, 3), - /* 1110 */ V(8, 8, 4), - /* 1111 */ V(5, 10, 4), - - /* 0000 0101 ... */ - /* 0000 */ V(2, 11, 3), /* 148 */ - /* 0001 */ V(2, 11, 3), - /* 0010 */ V(10, 5, 4), - /* 0011 */ V(6, 9, 4), - /* 0100 */ V(10, 4, 3), - /* 0101 */ V(10, 4, 3), - /* 0110 */ V(7, 8, 4), - /* 0111 */ V(8, 7, 4), - /* 1000 */ V(9, 4, 3), - /* 1001 */ V(9, 4, 3), - /* 1010 */ V(7, 7, 4), - /* 1011 */ V(7, 6, 4), - /* 1100 */ V(11, 2, 2), - /* 1101 */ V(11, 2, 2), - /* 1110 */ V(11, 2, 2), - /* 1111 */ V(11, 2, 2), - - /* 0000 0110 ... */ - /* 000 */ V(1, 11, 2), /* 164 */ - /* 001 */ V(1, 11, 2), - /* 010 */ V(11, 1, 2), - /* 011 */ V(11, 1, 2), - /* 100 */ V(0, 11, 3), - /* 101 */ V(11, 0, 3), - /* 110 */ V(9, 6, 3), - /* 111 */ V(4, 10, 3), - - /* 0000 0111 ... */ - /* 000 */ V(3, 10, 3), /* 172 */ - /* 001 */ V(10, 3, 3), - /* 010 */ V(5, 9, 3), - /* 011 */ V(9, 5, 3), - /* 100 */ V(2, 10, 2), - /* 101 */ V(2, 10, 2), - /* 110 */ V(10, 2, 2), - /* 111 */ V(10, 2, 2), - - /* 0000 1000 ... */ - /* 000 */ V(1, 10, 2), /* 180 */ - /* 001 */ V(1, 10, 2), - /* 010 */ V(10, 1, 2), - /* 011 */ V(10, 1, 2), - /* 100 */ V(0, 10, 3), - /* 101 */ V(6, 8, 3), - /* 110 */ V(10, 0, 2), - /* 111 */ V(10, 0, 2), - - /* 0000 1001 ... */ - /* 000 */ V(8, 6, 3), /* 188 */ - /* 001 */ V(4, 9, 3), - /* 010 */ V(9, 3, 2), - /* 011 */ V(9, 3, 2), - /* 100 */ V(3, 9, 3), - /* 101 */ V(5, 8, 3), - /* 110 */ V(8, 5, 3), - /* 111 */ V(6, 7, 3), - - /* 0000 1010 ... */ - /* 000 */ V(2, 9, 2), /* 196 */ - /* 001 */ V(2, 9, 2), - /* 010 */ V(9, 2, 2), - /* 011 */ V(9, 2, 2), - /* 100 */ V(5, 7, 3), - /* 101 */ V(7, 5, 3), - /* 110 */ V(3, 8, 2), - /* 111 */ V(3, 8, 2), - - /* 0000 1011 ... */ - /* 000 */ V(8, 3, 2), /* 204 */ - /* 001 */ V(8, 3, 2), - /* 010 */ V(6, 6, 3), - /* 011 */ V(4, 7, 3), - /* 100 */ V(7, 4, 3), - /* 101 */ V(5, 6, 3), - /* 110 */ V(6, 5, 3), - /* 111 */ V(7, 3, 3), - - /* 0000 1100 ... */ - /* 0 */ V(1, 9, 1), /* 212 */ - /* 1 */ V(9, 1, 1), - - /* 0000 1101 ... */ - /* 00 */ V(0, 9, 2), /* 214 */ - /* 01 */ V(9, 0, 2), - /* 10 */ V(4, 8, 2), - /* 11 */ V(8, 4, 2), - - /* 0000 1110 ... */ - /* 000 */ V(7, 2, 2), /* 218 */ - /* 001 */ V(7, 2, 2), - /* 010 */ V(4, 6, 3), - /* 011 */ V(6, 4, 3), - /* 100 */ V(2, 8, 1), - /* 101 */ V(2, 8, 1), - /* 110 */ V(2, 8, 1), - /* 111 */ V(2, 8, 1), - - /* 0000 1111 ... */ - /* 0 */ V(8, 2, 1), /* 226 */ - /* 1 */ V(1, 8, 1), - - /* 0001 0000 ... */ - /* 00 */ V(3, 7, 2), /* 228 */ - /* 01 */ V(2, 7, 2), - /* 10 */ V(1, 7, 1), - /* 11 */ V(1, 7, 1), - - /* 0001 0001 ... */ - /* 00 */ V(7, 1, 1), /* 232 */ - /* 01 */ V(7, 1, 1), - /* 10 */ V(5, 5, 2), - /* 11 */ V(0, 7, 2), - - /* 0001 0010 ... */ - /* 00 */ V(7, 0, 2), /* 236 */ - /* 01 */ V(3, 6, 2), - /* 10 */ V(6, 3, 2), - /* 11 */ V(4, 5, 2), - - /* 0001 0011 ... */ - /* 00 */ V(5, 4, 2), /* 240 */ - /* 01 */ V(2, 6, 2), - /* 10 */ V(6, 2, 2), - /* 11 */ V(3, 5, 2), - - /* 0001 0101 ... */ - /* 0 */ V(0, 8, 1), /* 244 */ - /* 1 */ V(8, 0, 1), - - /* 0001 0110 ... */ - /* 0 */ V(1, 6, 1), /* 246 */ - /* 1 */ V(6, 1, 1), - - /* 0001 0111 ... */ - /* 0 */ V(0, 6, 1), /* 248 */ - /* 1 */ V(6, 0, 1), - - /* 0001 1000 ... */ - /* 00 */ V(5, 3, 2), /* 250 */ - /* 01 */ V(4, 4, 2), - /* 10 */ V(2, 5, 1), - /* 11 */ V(2, 5, 1), - - /* 0001 1001 ... */ - /* 0 */ V(5, 2, 1), /* 254 */ - /* 1 */ V(0, 5, 1), - - /* 0001 1100 ... */ - /* 0 */ V(3, 4, 1), /* 256 */ - /* 1 */ V(4, 3, 1), - - /* 0001 1101 ... */ - /* 0 */ V(5, 0, 1), /* 258 */ - /* 1 */ V(2, 4, 1), - - /* 0001 1110 ... */ - /* 0 */ V(4, 2, 1), /* 260 */ - /* 1 */ V(3, 3, 1), - - /* 0000 0000 0000 ... */ - /* 0000 */ PTR(388, 3), /* 262 */ - /* 0001 */ V(15, 15, 4), - /* 0010 */ V(14, 15, 4), - /* 0011 */ V(13, 15, 4), - /* 0100 */ V(14, 14, 4), - /* 0101 */ V(12, 15, 4), - /* 0110 */ V(13, 14, 4), - /* 0111 */ V(11, 15, 4), - /* 1000 */ V(15, 11, 4), - /* 1001 */ V(12, 14, 4), - /* 1010 */ V(13, 12, 4), - /* 1011 */ PTR(396, 1), - /* 1100 */ V(14, 12, 3), - /* 1101 */ V(14, 12, 3), - /* 1110 */ V(13, 13, 3), - /* 1111 */ V(13, 13, 3), - - /* 0000 0000 0001 ... */ - /* 0000 */ V(15, 10, 4), /* 278 */ - /* 0001 */ V(12, 13, 4), - /* 0010 */ V(11, 14, 3), - /* 0011 */ V(11, 14, 3), - /* 0100 */ V(14, 11, 3), - /* 0101 */ V(14, 11, 3), - /* 0110 */ V(9, 15, 3), - /* 0111 */ V(9, 15, 3), - /* 1000 */ V(15, 9, 3), - /* 1001 */ V(15, 9, 3), - /* 1010 */ V(14, 10, 3), - /* 1011 */ V(14, 10, 3), - /* 1100 */ V(11, 13, 3), - /* 1101 */ V(11, 13, 3), - /* 1110 */ V(13, 11, 3), - /* 1111 */ V(13, 11, 3), - - /* 0000 0000 0010 ... */ - /* 0000 */ V(8, 15, 3), /* 294 */ - /* 0001 */ V(8, 15, 3), - /* 0010 */ V(15, 8, 3), - /* 0011 */ V(15, 8, 3), - /* 0100 */ V(12, 12, 3), - /* 0101 */ V(12, 12, 3), - /* 0110 */ V(10, 14, 4), - /* 0111 */ V(9, 14, 4), - /* 1000 */ V(8, 14, 3), - /* 1001 */ V(8, 14, 3), - /* 1010 */ V(7, 15, 4), - /* 1011 */ V(7, 14, 4), - /* 1100 */ V(15, 7, 2), - /* 1101 */ V(15, 7, 2), - /* 1110 */ V(15, 7, 2), - /* 1111 */ V(15, 7, 2), - - /* 0000 0000 0011 ... */ - /* 000 */ V(13, 10, 2), /* 310 */ - /* 001 */ V(13, 10, 2), - /* 010 */ V(10, 13, 3), - /* 011 */ V(11, 12, 3), - /* 100 */ V(12, 11, 3), - /* 101 */ V(15, 6, 3), - /* 110 */ V(6, 15, 2), - /* 111 */ V(6, 15, 2), - - /* 0000 0000 0100 ... */ - /* 00 */ V(14, 8, 2), /* 318 */ - /* 01 */ V(5, 15, 2), - /* 10 */ V(9, 13, 2), - /* 11 */ V(13, 9, 2), - - /* 0000 0000 0101 ... */ - /* 00 */ V(15, 5, 2), /* 322 */ - /* 01 */ V(14, 7, 2), - /* 10 */ V(10, 12, 2), - /* 11 */ V(11, 11, 2), - - /* 0000 0000 0110 ... */ - /* 000 */ V(4, 15, 2), /* 326 */ - /* 001 */ V(4, 15, 2), - /* 010 */ V(15, 4, 2), - /* 011 */ V(15, 4, 2), - /* 100 */ V(12, 10, 3), - /* 101 */ V(14, 6, 3), - /* 110 */ V(15, 3, 2), - /* 111 */ V(15, 3, 2), - - /* 0000 0000 0111 ... */ - /* 00 */ V(3, 15, 1), /* 334 */ - /* 01 */ V(3, 15, 1), - /* 10 */ V(8, 13, 2), - /* 11 */ V(13, 8, 2), - - /* 0000 0000 1000 ... */ - /* 0 */ V(2, 15, 1), /* 338 */ - /* 1 */ V(15, 2, 1), - - /* 0000 0000 1001 ... */ - /* 00 */ V(6, 14, 2), /* 340 */ - /* 01 */ V(9, 12, 2), - /* 10 */ V(0, 15, 1), - /* 11 */ V(0, 15, 1), - - /* 0000 0000 1010 ... */ - /* 00 */ V(12, 9, 2), /* 344 */ - /* 01 */ V(5, 14, 2), - /* 10 */ V(10, 11, 1), - /* 11 */ V(10, 11, 1), - - /* 0000 0000 1011 ... */ - /* 00 */ V(7, 13, 2), /* 348 */ - /* 01 */ V(13, 7, 2), - /* 10 */ V(4, 14, 1), - /* 11 */ V(4, 14, 1), - - /* 0000 0000 1100 ... */ - /* 00 */ V(12, 8, 2), /* 352 */ - /* 01 */ V(13, 6, 2), - /* 10 */ V(3, 14, 1), - /* 11 */ V(3, 14, 1), - - /* 0000 0000 1101 ... */ - /* 00 */ V(11, 9, 1), /* 356 */ - /* 01 */ V(11, 9, 1), - /* 10 */ V(9, 11, 2), - /* 11 */ V(10, 10, 2), - - /* 0000 0001 0001 ... */ - /* 0 */ V(11, 10, 1), /* 360 */ - /* 1 */ V(14, 5, 1), - - /* 0000 0001 0010 ... */ - /* 0 */ V(14, 4, 1), /* 362 */ - /* 1 */ V(8, 12, 1), - - /* 0000 0001 0011 ... */ - /* 0 */ V(6, 13, 1), /* 364 */ - /* 1 */ V(14, 3, 1), - - /* 0000 0001 0101 ... */ - /* 0 */ V(2, 14, 1), /* 366 */ - /* 1 */ V(0, 14, 1), - - /* 0000 0001 1000 ... */ - /* 0 */ V(14, 0, 1), /* 368 */ - /* 1 */ V(5, 13, 1), - - /* 0000 0001 1001 ... */ - /* 0 */ V(13, 5, 1), /* 370 */ - /* 1 */ V(7, 12, 1), - - /* 0000 0001 1010 ... */ - /* 0 */ V(12, 7, 1), /* 372 */ - /* 1 */ V(4, 13, 1), - - /* 0000 0001 1011 ... */ - /* 0 */ V(8, 11, 1), /* 374 */ - /* 1 */ V(11, 8, 1), - - /* 0000 0001 1100 ... */ - /* 0 */ V(13, 4, 1), /* 376 */ - /* 1 */ V(9, 10, 1), - - /* 0000 0001 1101 ... */ - /* 0 */ V(10, 9, 1), /* 378 */ - /* 1 */ V(6, 12, 1), - - /* 0000 0010 0000 ... */ - /* 0 */ V(13, 3, 1), /* 380 */ - /* 1 */ V(7, 11, 1), - - /* 0000 0010 0101 ... */ - /* 0 */ V(5, 12, 1), /* 382 */ - /* 1 */ V(12, 5, 1), - - /* 0000 0010 0110 ... */ - /* 0 */ V(9, 9, 1), /* 384 */ - /* 1 */ V(7, 10, 1), - - /* 0000 0010 1000 ... */ - /* 0 */ V(10, 7, 1), /* 386 */ - /* 1 */ V(9, 7, 1), - - /* 0000 0000 0000 0000 ... */ - /* 000 */ V(15, 14, 3), /* 388 */ - /* 001 */ V(15, 12, 3), - /* 010 */ V(15, 13, 2), - /* 011 */ V(15, 13, 2), - /* 100 */ V(14, 13, 1), - /* 101 */ V(14, 13, 1), - /* 110 */ V(14, 13, 1), - /* 111 */ V(14, 13, 1), - - /* 0000 0000 0000 1011 ... */ - /* 0 */ V(10, 15, 1), /* 396 */ - /* 1 */ V(14, 9, 1) + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ PTR(48, 4), + /* 0011 */ PTR(64, 2), + /* 0100 */ V(1, 1, 4), + /* 0101 */ V(0, 1, 4), + /* 0110 */ V(1, 0, 3), + /* 0111 */ V(1, 0, 3), + /* 1000 */ V(0, 0, 1), + /* 1001 */ V(0, 0, 1), + /* 1010 */ V(0, 0, 1), + /* 1011 */ V(0, 0, 1), + /* 1100 */ V(0, 0, 1), + /* 1101 */ V(0, 0, 1), + /* 1110 */ V(0, 0, 1), + /* 1111 */ V(0, 0, 1), + + /* 0000 ... */ + /* 0000 */ PTR(68, 4), /* 16 */ + /* 0001 */ PTR(84, 4), + /* 0010 */ PTR(100, 4), + /* 0011 */ PTR(116, 4), + /* 0100 */ PTR(132, 4), + /* 0101 */ PTR(148, 4), + /* 0110 */ PTR(164, 3), + /* 0111 */ PTR(172, 3), + /* 1000 */ PTR(180, 3), + /* 1001 */ PTR(188, 3), + /* 1010 */ PTR(196, 3), + /* 1011 */ PTR(204, 3), + /* 1100 */ PTR(212, 1), + /* 1101 */ PTR(214, 2), + /* 1110 */ PTR(218, 3), + /* 1111 */ PTR(226, 1), + + /* 0001 ... */ + /* 0000 */ PTR(228, 2), /* 32 */ + /* 0001 */ PTR(232, 2), + /* 0010 */ PTR(236, 2), + /* 0011 */ PTR(240, 2), + /* 0100 */ V(8, 1, 4), + /* 0101 */ PTR(244, 1), + /* 0110 */ PTR(246, 1), + /* 0111 */ PTR(248, 1), + /* 1000 */ PTR(250, 2), + /* 1001 */ PTR(254, 1), + /* 1010 */ V(1, 5, 4), + /* 1011 */ V(5, 1, 4), + /* 1100 */ PTR(256, 1), + /* 1101 */ PTR(258, 1), + /* 1110 */ PTR(260, 1), + /* 1111 */ V(1, 4, 4), + + /* 0010 ... */ + /* 0000 */ V(4, 1, 3), /* 48 */ + /* 0001 */ V(4, 1, 3), + /* 0010 */ V(0, 4, 4), + /* 0011 */ V(4, 0, 4), + /* 0100 */ V(2, 3, 4), + /* 0101 */ V(3, 2, 4), + /* 0110 */ V(1, 3, 3), + /* 0111 */ V(1, 3, 3), + /* 1000 */ V(3, 1, 3), + /* 1001 */ V(3, 1, 3), + /* 1010 */ V(0, 3, 3), + /* 1011 */ V(0, 3, 3), + /* 1100 */ V(3, 0, 3), + /* 1101 */ V(3, 0, 3), + /* 1110 */ V(2, 2, 3), + /* 1111 */ V(2, 2, 3), + + /* 0011 ... */ + /* 00 */ V(1, 2, 2), /* 64 */ + /* 01 */ V(2, 1, 2), + /* 10 */ V(0, 2, 2), + /* 11 */ V(2, 0, 2), + + /* 0000 0000 ... */ + /* 0000 */ PTR(262, 4), /* 68 */ + /* 0001 */ PTR(278, 4), + /* 0010 */ PTR(294, 4), + /* 0011 */ PTR(310, 3), + /* 0100 */ PTR(318, 2), + /* 0101 */ PTR(322, 2), + /* 0110 */ PTR(326, 3), + /* 0111 */ PTR(334, 2), + /* 1000 */ PTR(338, 1), + /* 1001 */ PTR(340, 2), + /* 1010 */ PTR(344, 2), + /* 1011 */ PTR(348, 2), + /* 1100 */ PTR(352, 2), + /* 1101 */ PTR(356, 2), + /* 1110 */ V(1, 15, 4), + /* 1111 */ V(15, 1, 4), + + /* 0000 0001 ... */ + /* 0000 */ V(15, 0, 4), /* 84 */ + /* 0001 */ PTR(360, 1), + /* 0010 */ PTR(362, 1), + /* 0011 */ PTR(364, 1), + /* 0100 */ V(14, 2, 4), + /* 0101 */ PTR(366, 1), + /* 0110 */ V(1, 14, 4), + /* 0111 */ V(14, 1, 4), + /* 1000 */ PTR(368, 1), + /* 1001 */ PTR(370, 1), + /* 1010 */ PTR(372, 1), + /* 1011 */ PTR(374, 1), + /* 1100 */ PTR(376, 1), + /* 1101 */ PTR(378, 1), + /* 1110 */ V(12, 6, 4), + /* 1111 */ V(3, 13, 4), + + /* 0000 0010 ... */ + /* 0000 */ PTR(380, 1), /* 100 */ + /* 0001 */ V(2, 13, 4), + /* 0010 */ V(13, 2, 4), + /* 0011 */ V(1, 13, 4), + /* 0100 */ V(11, 7, 4), + /* 0101 */ PTR(382, 1), + /* 0110 */ PTR(384, 1), + /* 0111 */ V(12, 3, 4), + /* 1000 */ PTR(386, 1), + /* 1001 */ V(4, 11, 4), + /* 1010 */ V(13, 1, 3), + /* 1011 */ V(13, 1, 3), + /* 1100 */ V(0, 13, 4), + /* 1101 */ V(13, 0, 4), + /* 1110 */ V(8, 10, 4), + /* 1111 */ V(10, 8, 4), + + /* 0000 0011 ... */ + /* 0000 */ V(4, 12, 4), /* 116 */ + /* 0001 */ V(12, 4, 4), + /* 0010 */ V(6, 11, 4), + /* 0011 */ V(11, 6, 4), + /* 0100 */ V(3, 12, 3), + /* 0101 */ V(3, 12, 3), + /* 0110 */ V(2, 12, 3), + /* 0111 */ V(2, 12, 3), + /* 1000 */ V(12, 2, 3), + /* 1001 */ V(12, 2, 3), + /* 1010 */ V(5, 11, 3), + /* 1011 */ V(5, 11, 3), + /* 1100 */ V(11, 5, 4), + /* 1101 */ V(8, 9, 4), + /* 1110 */ V(1, 12, 3), + /* 1111 */ V(1, 12, 3), + + /* 0000 0100 ... */ + /* 0000 */ V(12, 1, 3), /* 132 */ + /* 0001 */ V(12, 1, 3), + /* 0010 */ V(9, 8, 4), + /* 0011 */ V(0, 12, 4), + /* 0100 */ V(12, 0, 3), + /* 0101 */ V(12, 0, 3), + /* 0110 */ V(11, 4, 4), + /* 0111 */ V(6, 10, 4), + /* 1000 */ V(10, 6, 4), + /* 1001 */ V(7, 9, 4), + /* 1010 */ V(3, 11, 3), + /* 1011 */ V(3, 11, 3), + /* 1100 */ V(11, 3, 3), + /* 1101 */ V(11, 3, 3), + /* 1110 */ V(8, 8, 4), + /* 1111 */ V(5, 10, 4), + + /* 0000 0101 ... */ + /* 0000 */ V(2, 11, 3), /* 148 */ + /* 0001 */ V(2, 11, 3), + /* 0010 */ V(10, 5, 4), + /* 0011 */ V(6, 9, 4), + /* 0100 */ V(10, 4, 3), + /* 0101 */ V(10, 4, 3), + /* 0110 */ V(7, 8, 4), + /* 0111 */ V(8, 7, 4), + /* 1000 */ V(9, 4, 3), + /* 1001 */ V(9, 4, 3), + /* 1010 */ V(7, 7, 4), + /* 1011 */ V(7, 6, 4), + /* 1100 */ V(11, 2, 2), + /* 1101 */ V(11, 2, 2), + /* 1110 */ V(11, 2, 2), + /* 1111 */ V(11, 2, 2), + + /* 0000 0110 ... */ + /* 000 */ V(1, 11, 2), /* 164 */ + /* 001 */ V(1, 11, 2), + /* 010 */ V(11, 1, 2), + /* 011 */ V(11, 1, 2), + /* 100 */ V(0, 11, 3), + /* 101 */ V(11, 0, 3), + /* 110 */ V(9, 6, 3), + /* 111 */ V(4, 10, 3), + + /* 0000 0111 ... */ + /* 000 */ V(3, 10, 3), /* 172 */ + /* 001 */ V(10, 3, 3), + /* 010 */ V(5, 9, 3), + /* 011 */ V(9, 5, 3), + /* 100 */ V(2, 10, 2), + /* 101 */ V(2, 10, 2), + /* 110 */ V(10, 2, 2), + /* 111 */ V(10, 2, 2), + + /* 0000 1000 ... */ + /* 000 */ V(1, 10, 2), /* 180 */ + /* 001 */ V(1, 10, 2), + /* 010 */ V(10, 1, 2), + /* 011 */ V(10, 1, 2), + /* 100 */ V(0, 10, 3), + /* 101 */ V(6, 8, 3), + /* 110 */ V(10, 0, 2), + /* 111 */ V(10, 0, 2), + + /* 0000 1001 ... */ + /* 000 */ V(8, 6, 3), /* 188 */ + /* 001 */ V(4, 9, 3), + /* 010 */ V(9, 3, 2), + /* 011 */ V(9, 3, 2), + /* 100 */ V(3, 9, 3), + /* 101 */ V(5, 8, 3), + /* 110 */ V(8, 5, 3), + /* 111 */ V(6, 7, 3), + + /* 0000 1010 ... */ + /* 000 */ V(2, 9, 2), /* 196 */ + /* 001 */ V(2, 9, 2), + /* 010 */ V(9, 2, 2), + /* 011 */ V(9, 2, 2), + /* 100 */ V(5, 7, 3), + /* 101 */ V(7, 5, 3), + /* 110 */ V(3, 8, 2), + /* 111 */ V(3, 8, 2), + + /* 0000 1011 ... */ + /* 000 */ V(8, 3, 2), /* 204 */ + /* 001 */ V(8, 3, 2), + /* 010 */ V(6, 6, 3), + /* 011 */ V(4, 7, 3), + /* 100 */ V(7, 4, 3), + /* 101 */ V(5, 6, 3), + /* 110 */ V(6, 5, 3), + /* 111 */ V(7, 3, 3), + + /* 0000 1100 ... */ + /* 0 */ V(1, 9, 1), /* 212 */ + /* 1 */ V(9, 1, 1), + + /* 0000 1101 ... */ + /* 00 */ V(0, 9, 2), /* 214 */ + /* 01 */ V(9, 0, 2), + /* 10 */ V(4, 8, 2), + /* 11 */ V(8, 4, 2), + + /* 0000 1110 ... */ + /* 000 */ V(7, 2, 2), /* 218 */ + /* 001 */ V(7, 2, 2), + /* 010 */ V(4, 6, 3), + /* 011 */ V(6, 4, 3), + /* 100 */ V(2, 8, 1), + /* 101 */ V(2, 8, 1), + /* 110 */ V(2, 8, 1), + /* 111 */ V(2, 8, 1), + + /* 0000 1111 ... */ + /* 0 */ V(8, 2, 1), /* 226 */ + /* 1 */ V(1, 8, 1), + + /* 0001 0000 ... */ + /* 00 */ V(3, 7, 2), /* 228 */ + /* 01 */ V(2, 7, 2), + /* 10 */ V(1, 7, 1), + /* 11 */ V(1, 7, 1), + + /* 0001 0001 ... */ + /* 00 */ V(7, 1, 1), /* 232 */ + /* 01 */ V(7, 1, 1), + /* 10 */ V(5, 5, 2), + /* 11 */ V(0, 7, 2), + + /* 0001 0010 ... */ + /* 00 */ V(7, 0, 2), /* 236 */ + /* 01 */ V(3, 6, 2), + /* 10 */ V(6, 3, 2), + /* 11 */ V(4, 5, 2), + + /* 0001 0011 ... */ + /* 00 */ V(5, 4, 2), /* 240 */ + /* 01 */ V(2, 6, 2), + /* 10 */ V(6, 2, 2), + /* 11 */ V(3, 5, 2), + + /* 0001 0101 ... */ + /* 0 */ V(0, 8, 1), /* 244 */ + /* 1 */ V(8, 0, 1), + + /* 0001 0110 ... */ + /* 0 */ V(1, 6, 1), /* 246 */ + /* 1 */ V(6, 1, 1), + + /* 0001 0111 ... */ + /* 0 */ V(0, 6, 1), /* 248 */ + /* 1 */ V(6, 0, 1), + + /* 0001 1000 ... */ + /* 00 */ V(5, 3, 2), /* 250 */ + /* 01 */ V(4, 4, 2), + /* 10 */ V(2, 5, 1), + /* 11 */ V(2, 5, 1), + + /* 0001 1001 ... */ + /* 0 */ V(5, 2, 1), /* 254 */ + /* 1 */ V(0, 5, 1), + + /* 0001 1100 ... */ + /* 0 */ V(3, 4, 1), /* 256 */ + /* 1 */ V(4, 3, 1), + + /* 0001 1101 ... */ + /* 0 */ V(5, 0, 1), /* 258 */ + /* 1 */ V(2, 4, 1), + + /* 0001 1110 ... */ + /* 0 */ V(4, 2, 1), /* 260 */ + /* 1 */ V(3, 3, 1), + + /* 0000 0000 0000 ... */ + /* 0000 */ PTR(388, 3), /* 262 */ + /* 0001 */ V(15, 15, 4), + /* 0010 */ V(14, 15, 4), + /* 0011 */ V(13, 15, 4), + /* 0100 */ V(14, 14, 4), + /* 0101 */ V(12, 15, 4), + /* 0110 */ V(13, 14, 4), + /* 0111 */ V(11, 15, 4), + /* 1000 */ V(15, 11, 4), + /* 1001 */ V(12, 14, 4), + /* 1010 */ V(13, 12, 4), + /* 1011 */ PTR(396, 1), + /* 1100 */ V(14, 12, 3), + /* 1101 */ V(14, 12, 3), + /* 1110 */ V(13, 13, 3), + /* 1111 */ V(13, 13, 3), + + /* 0000 0000 0001 ... */ + /* 0000 */ V(15, 10, 4), /* 278 */ + /* 0001 */ V(12, 13, 4), + /* 0010 */ V(11, 14, 3), + /* 0011 */ V(11, 14, 3), + /* 0100 */ V(14, 11, 3), + /* 0101 */ V(14, 11, 3), + /* 0110 */ V(9, 15, 3), + /* 0111 */ V(9, 15, 3), + /* 1000 */ V(15, 9, 3), + /* 1001 */ V(15, 9, 3), + /* 1010 */ V(14, 10, 3), + /* 1011 */ V(14, 10, 3), + /* 1100 */ V(11, 13, 3), + /* 1101 */ V(11, 13, 3), + /* 1110 */ V(13, 11, 3), + /* 1111 */ V(13, 11, 3), + + /* 0000 0000 0010 ... */ + /* 0000 */ V(8, 15, 3), /* 294 */ + /* 0001 */ V(8, 15, 3), + /* 0010 */ V(15, 8, 3), + /* 0011 */ V(15, 8, 3), + /* 0100 */ V(12, 12, 3), + /* 0101 */ V(12, 12, 3), + /* 0110 */ V(10, 14, 4), + /* 0111 */ V(9, 14, 4), + /* 1000 */ V(8, 14, 3), + /* 1001 */ V(8, 14, 3), + /* 1010 */ V(7, 15, 4), + /* 1011 */ V(7, 14, 4), + /* 1100 */ V(15, 7, 2), + /* 1101 */ V(15, 7, 2), + /* 1110 */ V(15, 7, 2), + /* 1111 */ V(15, 7, 2), + + /* 0000 0000 0011 ... */ + /* 000 */ V(13, 10, 2), /* 310 */ + /* 001 */ V(13, 10, 2), + /* 010 */ V(10, 13, 3), + /* 011 */ V(11, 12, 3), + /* 100 */ V(12, 11, 3), + /* 101 */ V(15, 6, 3), + /* 110 */ V(6, 15, 2), + /* 111 */ V(6, 15, 2), + + /* 0000 0000 0100 ... */ + /* 00 */ V(14, 8, 2), /* 318 */ + /* 01 */ V(5, 15, 2), + /* 10 */ V(9, 13, 2), + /* 11 */ V(13, 9, 2), + + /* 0000 0000 0101 ... */ + /* 00 */ V(15, 5, 2), /* 322 */ + /* 01 */ V(14, 7, 2), + /* 10 */ V(10, 12, 2), + /* 11 */ V(11, 11, 2), + + /* 0000 0000 0110 ... */ + /* 000 */ V(4, 15, 2), /* 326 */ + /* 001 */ V(4, 15, 2), + /* 010 */ V(15, 4, 2), + /* 011 */ V(15, 4, 2), + /* 100 */ V(12, 10, 3), + /* 101 */ V(14, 6, 3), + /* 110 */ V(15, 3, 2), + /* 111 */ V(15, 3, 2), + + /* 0000 0000 0111 ... */ + /* 00 */ V(3, 15, 1), /* 334 */ + /* 01 */ V(3, 15, 1), + /* 10 */ V(8, 13, 2), + /* 11 */ V(13, 8, 2), + + /* 0000 0000 1000 ... */ + /* 0 */ V(2, 15, 1), /* 338 */ + /* 1 */ V(15, 2, 1), + + /* 0000 0000 1001 ... */ + /* 00 */ V(6, 14, 2), /* 340 */ + /* 01 */ V(9, 12, 2), + /* 10 */ V(0, 15, 1), + /* 11 */ V(0, 15, 1), + + /* 0000 0000 1010 ... */ + /* 00 */ V(12, 9, 2), /* 344 */ + /* 01 */ V(5, 14, 2), + /* 10 */ V(10, 11, 1), + /* 11 */ V(10, 11, 1), + + /* 0000 0000 1011 ... */ + /* 00 */ V(7, 13, 2), /* 348 */ + /* 01 */ V(13, 7, 2), + /* 10 */ V(4, 14, 1), + /* 11 */ V(4, 14, 1), + + /* 0000 0000 1100 ... */ + /* 00 */ V(12, 8, 2), /* 352 */ + /* 01 */ V(13, 6, 2), + /* 10 */ V(3, 14, 1), + /* 11 */ V(3, 14, 1), + + /* 0000 0000 1101 ... */ + /* 00 */ V(11, 9, 1), /* 356 */ + /* 01 */ V(11, 9, 1), + /* 10 */ V(9, 11, 2), + /* 11 */ V(10, 10, 2), + + /* 0000 0001 0001 ... */ + /* 0 */ V(11, 10, 1), /* 360 */ + /* 1 */ V(14, 5, 1), + + /* 0000 0001 0010 ... */ + /* 0 */ V(14, 4, 1), /* 362 */ + /* 1 */ V(8, 12, 1), + + /* 0000 0001 0011 ... */ + /* 0 */ V(6, 13, 1), /* 364 */ + /* 1 */ V(14, 3, 1), + + /* 0000 0001 0101 ... */ + /* 0 */ V(2, 14, 1), /* 366 */ + /* 1 */ V(0, 14, 1), + + /* 0000 0001 1000 ... */ + /* 0 */ V(14, 0, 1), /* 368 */ + /* 1 */ V(5, 13, 1), + + /* 0000 0001 1001 ... */ + /* 0 */ V(13, 5, 1), /* 370 */ + /* 1 */ V(7, 12, 1), + + /* 0000 0001 1010 ... */ + /* 0 */ V(12, 7, 1), /* 372 */ + /* 1 */ V(4, 13, 1), + + /* 0000 0001 1011 ... */ + /* 0 */ V(8, 11, 1), /* 374 */ + /* 1 */ V(11, 8, 1), + + /* 0000 0001 1100 ... */ + /* 0 */ V(13, 4, 1), /* 376 */ + /* 1 */ V(9, 10, 1), + + /* 0000 0001 1101 ... */ + /* 0 */ V(10, 9, 1), /* 378 */ + /* 1 */ V(6, 12, 1), + + /* 0000 0010 0000 ... */ + /* 0 */ V(13, 3, 1), /* 380 */ + /* 1 */ V(7, 11, 1), + + /* 0000 0010 0101 ... */ + /* 0 */ V(5, 12, 1), /* 382 */ + /* 1 */ V(12, 5, 1), + + /* 0000 0010 0110 ... */ + /* 0 */ V(9, 9, 1), /* 384 */ + /* 1 */ V(7, 10, 1), + + /* 0000 0010 1000 ... */ + /* 0 */ V(10, 7, 1), /* 386 */ + /* 1 */ V(9, 7, 1), + + /* 0000 0000 0000 0000 ... */ + /* 000 */ V(15, 14, 3), /* 388 */ + /* 001 */ V(15, 12, 3), + /* 010 */ V(15, 13, 2), + /* 011 */ V(15, 13, 2), + /* 100 */ V(14, 13, 1), + /* 101 */ V(14, 13, 1), + /* 110 */ V(14, 13, 1), + /* 111 */ V(14, 13, 1), + + /* 0000 0000 0000 1011 ... */ + /* 0 */ V(10, 15, 1), /* 396 */ + /* 1 */ V(14, 9, 1) }; static union huffpair const hufftab15[] PROGMEM = { - /* 0000 */ PTR(16, 4), - /* 0001 */ PTR(32, 4), - /* 0010 */ PTR(48, 4), - /* 0011 */ PTR(64, 4), - /* 0100 */ PTR(80, 4), - /* 0101 */ PTR(96, 3), - /* 0110 */ PTR(104, 3), - /* 0111 */ PTR(112, 2), - /* 1000 */ PTR(116, 1), - /* 1001 */ PTR(118, 1), - /* 1010 */ V(1, 1, 3), - /* 1011 */ V(1, 1, 3), - /* 1100 */ V(0, 1, 4), - /* 1101 */ V(1, 0, 4), - /* 1110 */ V(0, 0, 3), - /* 1111 */ V(0, 0, 3), - - /* 0000 ... */ - /* 0000 */ PTR(120, 4), /* 16 */ - /* 0001 */ PTR(136, 4), - /* 0010 */ PTR(152, 4), - /* 0011 */ PTR(168, 4), - /* 0100 */ PTR(184, 4), - /* 0101 */ PTR(200, 3), - /* 0110 */ PTR(208, 3), - /* 0111 */ PTR(216, 4), - /* 1000 */ PTR(232, 3), - /* 1001 */ PTR(240, 3), - /* 1010 */ PTR(248, 3), - /* 1011 */ PTR(256, 3), - /* 1100 */ PTR(264, 2), - /* 1101 */ PTR(268, 3), - /* 1110 */ PTR(276, 3), - /* 1111 */ PTR(284, 2), - - /* 0001 ... */ - /* 0000 */ PTR(288, 2), /* 32 */ - /* 0001 */ PTR(292, 2), - /* 0010 */ PTR(296, 2), - /* 0011 */ PTR(300, 2), - /* 0100 */ PTR(304, 2), - /* 0101 */ PTR(308, 2), - /* 0110 */ PTR(312, 2), - /* 0111 */ PTR(316, 2), - /* 1000 */ PTR(320, 1), - /* 1001 */ PTR(322, 1), - /* 1010 */ PTR(324, 1), - /* 1011 */ PTR(326, 2), - /* 1100 */ PTR(330, 1), - /* 1101 */ PTR(332, 1), - /* 1110 */ PTR(334, 2), - /* 1111 */ PTR(338, 1), - - /* 0010 ... */ - /* 0000 */ PTR(340, 1), /* 48 */ - /* 0001 */ PTR(342, 1), - /* 0010 */ V(9, 1, 4), - /* 0011 */ PTR(344, 1), - /* 0100 */ PTR(346, 1), - /* 0101 */ PTR(348, 1), - /* 0110 */ PTR(350, 1), - /* 0111 */ PTR(352, 1), - /* 1000 */ V(2, 8, 4), - /* 1001 */ V(8, 2, 4), - /* 1010 */ V(1, 8, 4), - /* 1011 */ V(8, 1, 4), - /* 1100 */ PTR(354, 1), - /* 1101 */ PTR(356, 1), - /* 1110 */ PTR(358, 1), - /* 1111 */ PTR(360, 1), - - /* 0011 ... */ - /* 0000 */ V(2, 7, 4), /* 64 */ - /* 0001 */ V(7, 2, 4), - /* 0010 */ V(6, 4, 4), - /* 0011 */ V(1, 7, 4), - /* 0100 */ V(5, 5, 4), - /* 0101 */ V(7, 1, 4), - /* 0110 */ PTR(362, 1), - /* 0111 */ V(3, 6, 4), - /* 1000 */ V(6, 3, 4), - /* 1001 */ V(4, 5, 4), - /* 1010 */ V(5, 4, 4), - /* 1011 */ V(2, 6, 4), - /* 1100 */ V(6, 2, 4), - /* 1101 */ V(1, 6, 4), - /* 1110 */ PTR(364, 1), - /* 1111 */ V(3, 5, 4), - - /* 0100 ... */ - /* 0000 */ V(6, 1, 3), /* 80 */ - /* 0001 */ V(6, 1, 3), - /* 0010 */ V(5, 3, 4), - /* 0011 */ V(4, 4, 4), - /* 0100 */ V(2, 5, 3), - /* 0101 */ V(2, 5, 3), - /* 0110 */ V(5, 2, 3), - /* 0111 */ V(5, 2, 3), - /* 1000 */ V(1, 5, 3), - /* 1001 */ V(1, 5, 3), - /* 1010 */ V(5, 1, 3), - /* 1011 */ V(5, 1, 3), - /* 1100 */ V(0, 5, 4), - /* 1101 */ V(5, 0, 4), - /* 1110 */ V(3, 4, 3), - /* 1111 */ V(3, 4, 3), - - /* 0101 ... */ - /* 000 */ V(4, 3, 3), /* 96 */ - /* 001 */ V(2, 4, 3), - /* 010 */ V(4, 2, 3), - /* 011 */ V(3, 3, 3), - /* 100 */ V(4, 1, 2), - /* 101 */ V(4, 1, 2), - /* 110 */ V(1, 4, 3), - /* 111 */ V(0, 4, 3), - - /* 0110 ... */ - /* 000 */ V(2, 3, 2), /* 104 */ - /* 001 */ V(2, 3, 2), - /* 010 */ V(3, 2, 2), - /* 011 */ V(3, 2, 2), - /* 100 */ V(4, 0, 3), - /* 101 */ V(0, 3, 3), - /* 110 */ V(1, 3, 2), - /* 111 */ V(1, 3, 2), - - /* 0111 ... */ - /* 00 */ V(3, 1, 2), /* 112 */ - /* 01 */ V(3, 0, 2), - /* 10 */ V(2, 2, 1), - /* 11 */ V(2, 2, 1), - - /* 1000 ... */ - /* 0 */ V(1, 2, 1), /* 116 */ - /* 1 */ V(2, 1, 1), - - /* 1001 ... */ - /* 0 */ V(0, 2, 1), /* 118 */ - /* 1 */ V(2, 0, 1), - - /* 0000 0000 ... */ - /* 0000 */ PTR(366, 1), /* 120 */ - /* 0001 */ PTR(368, 1), - /* 0010 */ V(14, 14, 4), - /* 0011 */ PTR(370, 1), - /* 0100 */ PTR(372, 1), - /* 0101 */ PTR(374, 1), - /* 0110 */ V(15, 11, 4), - /* 0111 */ PTR(376, 1), - /* 1000 */ V(13, 13, 4), - /* 1001 */ V(10, 15, 4), - /* 1010 */ V(15, 10, 4), - /* 1011 */ V(11, 14, 4), - /* 1100 */ V(14, 11, 4), - /* 1101 */ V(12, 13, 4), - /* 1110 */ V(13, 12, 4), - /* 1111 */ V(9, 15, 4), - - /* 0000 0001 ... */ - /* 0000 */ V(15, 9, 4), /* 136 */ - /* 0001 */ V(14, 10, 4), - /* 0010 */ V(11, 13, 4), - /* 0011 */ V(13, 11, 4), - /* 0100 */ V(8, 15, 4), - /* 0101 */ V(15, 8, 4), - /* 0110 */ V(12, 12, 4), - /* 0111 */ V(9, 14, 4), - /* 1000 */ V(14, 9, 4), - /* 1001 */ V(7, 15, 4), - /* 1010 */ V(15, 7, 4), - /* 1011 */ V(10, 13, 4), - /* 1100 */ V(13, 10, 4), - /* 1101 */ V(11, 12, 4), - /* 1110 */ V(6, 15, 4), - /* 1111 */ PTR(378, 1), - - /* 0000 0010 ... */ - /* 0000 */ V(12, 11, 3), /* 152 */ - /* 0001 */ V(12, 11, 3), - /* 0010 */ V(15, 6, 3), - /* 0011 */ V(15, 6, 3), - /* 0100 */ V(8, 14, 4), - /* 0101 */ V(14, 8, 4), - /* 0110 */ V(5, 15, 4), - /* 0111 */ V(9, 13, 4), - /* 1000 */ V(15, 5, 3), - /* 1001 */ V(15, 5, 3), - /* 1010 */ V(7, 14, 3), - /* 1011 */ V(7, 14, 3), - /* 1100 */ V(14, 7, 3), - /* 1101 */ V(14, 7, 3), - /* 1110 */ V(10, 12, 3), - /* 1111 */ V(10, 12, 3), - - /* 0000 0011 ... */ - /* 0000 */ V(12, 10, 3), /* 168 */ - /* 0001 */ V(12, 10, 3), - /* 0010 */ V(11, 11, 3), - /* 0011 */ V(11, 11, 3), - /* 0100 */ V(13, 9, 4), - /* 0101 */ V(8, 13, 4), - /* 0110 */ V(4, 15, 3), - /* 0111 */ V(4, 15, 3), - /* 1000 */ V(15, 4, 3), - /* 1001 */ V(15, 4, 3), - /* 1010 */ V(3, 15, 3), - /* 1011 */ V(3, 15, 3), - /* 1100 */ V(15, 3, 3), - /* 1101 */ V(15, 3, 3), - /* 1110 */ V(13, 8, 3), - /* 1111 */ V(13, 8, 3), - - /* 0000 0100 ... */ - /* 0000 */ V(14, 6, 3), /* 184 */ - /* 0001 */ V(14, 6, 3), - /* 0010 */ V(2, 15, 3), - /* 0011 */ V(2, 15, 3), - /* 0100 */ V(15, 2, 3), - /* 0101 */ V(15, 2, 3), - /* 0110 */ V(6, 14, 4), - /* 0111 */ V(15, 0, 4), - /* 1000 */ V(1, 15, 3), - /* 1001 */ V(1, 15, 3), - /* 1010 */ V(15, 1, 3), - /* 1011 */ V(15, 1, 3), - /* 1100 */ V(9, 12, 3), - /* 1101 */ V(9, 12, 3), - /* 1110 */ V(12, 9, 3), - /* 1111 */ V(12, 9, 3), - - /* 0000 0101 ... */ - /* 000 */ V(5, 14, 3), /* 200 */ - /* 001 */ V(10, 11, 3), - /* 010 */ V(11, 10, 3), - /* 011 */ V(14, 5, 3), - /* 100 */ V(7, 13, 3), - /* 101 */ V(13, 7, 3), - /* 110 */ V(4, 14, 3), - /* 111 */ V(14, 4, 3), - - /* 0000 0110 ... */ - /* 000 */ V(8, 12, 3), /* 208 */ - /* 001 */ V(12, 8, 3), - /* 010 */ V(3, 14, 3), - /* 011 */ V(6, 13, 3), - /* 100 */ V(13, 6, 3), - /* 101 */ V(14, 3, 3), - /* 110 */ V(9, 11, 3), - /* 111 */ V(11, 9, 3), - - /* 0000 0111 ... */ - /* 0000 */ V(2, 14, 3), /* 216 */ - /* 0001 */ V(2, 14, 3), - /* 0010 */ V(10, 10, 3), - /* 0011 */ V(10, 10, 3), - /* 0100 */ V(14, 2, 3), - /* 0101 */ V(14, 2, 3), - /* 0110 */ V(1, 14, 3), - /* 0111 */ V(1, 14, 3), - /* 1000 */ V(14, 1, 3), - /* 1001 */ V(14, 1, 3), - /* 1010 */ V(0, 14, 4), - /* 1011 */ V(14, 0, 4), - /* 1100 */ V(5, 13, 3), - /* 1101 */ V(5, 13, 3), - /* 1110 */ V(13, 5, 3), - /* 1111 */ V(13, 5, 3), - - /* 0000 1000 ... */ - /* 000 */ V(7, 12, 3), /* 232 */ - /* 001 */ V(12, 7, 3), - /* 010 */ V(4, 13, 3), - /* 011 */ V(8, 11, 3), - /* 100 */ V(13, 4, 2), - /* 101 */ V(13, 4, 2), - /* 110 */ V(11, 8, 3), - /* 111 */ V(9, 10, 3), - - /* 0000 1001 ... */ - /* 000 */ V(10, 9, 3), /* 240 */ - /* 001 */ V(6, 12, 3), - /* 010 */ V(12, 6, 3), - /* 011 */ V(3, 13, 3), - /* 100 */ V(13, 3, 2), - /* 101 */ V(13, 3, 2), - /* 110 */ V(13, 2, 2), - /* 111 */ V(13, 2, 2), - - /* 0000 1010 ... */ - /* 000 */ V(2, 13, 3), /* 248 */ - /* 001 */ V(0, 13, 3), - /* 010 */ V(1, 13, 2), - /* 011 */ V(1, 13, 2), - /* 100 */ V(7, 11, 2), - /* 101 */ V(7, 11, 2), - /* 110 */ V(11, 7, 2), - /* 111 */ V(11, 7, 2), - - /* 0000 1011 ... */ - /* 000 */ V(13, 1, 2), /* 256 */ - /* 001 */ V(13, 1, 2), - /* 010 */ V(5, 12, 3), - /* 011 */ V(13, 0, 3), - /* 100 */ V(12, 5, 2), - /* 101 */ V(12, 5, 2), - /* 110 */ V(8, 10, 2), - /* 111 */ V(8, 10, 2), - - /* 0000 1100 ... */ - /* 00 */ V(10, 8, 2), /* 264 */ - /* 01 */ V(4, 12, 2), - /* 10 */ V(12, 4, 2), - /* 11 */ V(6, 11, 2), - - /* 0000 1101 ... */ - /* 000 */ V(11, 6, 2), /* 268 */ - /* 001 */ V(11, 6, 2), - /* 010 */ V(9, 9, 3), - /* 011 */ V(0, 12, 3), - /* 100 */ V(3, 12, 2), - /* 101 */ V(3, 12, 2), - /* 110 */ V(12, 3, 2), - /* 111 */ V(12, 3, 2), - - /* 0000 1110 ... */ - /* 000 */ V(7, 10, 2), /* 276 */ - /* 001 */ V(7, 10, 2), - /* 010 */ V(10, 7, 2), - /* 011 */ V(10, 7, 2), - /* 100 */ V(10, 6, 2), - /* 101 */ V(10, 6, 2), - /* 110 */ V(12, 0, 3), - /* 111 */ V(0, 11, 3), - - /* 0000 1111 ... */ - /* 00 */ V(12, 2, 1), /* 284 */ - /* 01 */ V(12, 2, 1), - /* 10 */ V(2, 12, 2), - /* 11 */ V(5, 11, 2), - - /* 0001 0000 ... */ - /* 00 */ V(11, 5, 2), /* 288 */ - /* 01 */ V(1, 12, 2), - /* 10 */ V(8, 9, 2), - /* 11 */ V(9, 8, 2), - - /* 0001 0001 ... */ - /* 00 */ V(12, 1, 2), /* 292 */ - /* 01 */ V(4, 11, 2), - /* 10 */ V(11, 4, 2), - /* 11 */ V(6, 10, 2), - - /* 0001 0010 ... */ - /* 00 */ V(3, 11, 2), /* 296 */ - /* 01 */ V(7, 9, 2), - /* 10 */ V(11, 3, 1), - /* 11 */ V(11, 3, 1), - - /* 0001 0011 ... */ - /* 00 */ V(9, 7, 2), /* 300 */ - /* 01 */ V(8, 8, 2), - /* 10 */ V(2, 11, 2), - /* 11 */ V(5, 10, 2), - - /* 0001 0100 ... */ - /* 00 */ V(11, 2, 1), /* 304 */ - /* 01 */ V(11, 2, 1), - /* 10 */ V(10, 5, 2), - /* 11 */ V(1, 11, 2), - - /* 0001 0101 ... */ - /* 00 */ V(11, 1, 1), /* 308 */ - /* 01 */ V(11, 1, 1), - /* 10 */ V(11, 0, 2), - /* 11 */ V(6, 9, 2), - - /* 0001 0110 ... */ - /* 00 */ V(9, 6, 2), /* 312 */ - /* 01 */ V(4, 10, 2), - /* 10 */ V(10, 4, 2), - /* 11 */ V(7, 8, 2), - - /* 0001 0111 ... */ - /* 00 */ V(8, 7, 2), /* 316 */ - /* 01 */ V(3, 10, 2), - /* 10 */ V(10, 3, 1), - /* 11 */ V(10, 3, 1), - - /* 0001 1000 ... */ - /* 0 */ V(5, 9, 1), /* 320 */ - /* 1 */ V(9, 5, 1), - - /* 0001 1001 ... */ - /* 0 */ V(2, 10, 1), /* 322 */ - /* 1 */ V(10, 2, 1), - - /* 0001 1010 ... */ - /* 0 */ V(1, 10, 1), /* 324 */ - /* 1 */ V(10, 1, 1), - - /* 0001 1011 ... */ - /* 00 */ V(0, 10, 2), /* 326 */ - /* 01 */ V(10, 0, 2), - /* 10 */ V(6, 8, 1), - /* 11 */ V(6, 8, 1), - - /* 0001 1100 ... */ - /* 0 */ V(8, 6, 1), /* 330 */ - /* 1 */ V(4, 9, 1), - - /* 0001 1101 ... */ - /* 0 */ V(9, 4, 1), /* 332 */ - /* 1 */ V(3, 9, 1), - - /* 0001 1110 ... */ - /* 00 */ V(9, 3, 1), /* 334 */ - /* 01 */ V(9, 3, 1), - /* 10 */ V(7, 7, 2), - /* 11 */ V(0, 9, 2), - - /* 0001 1111 ... */ - /* 0 */ V(5, 8, 1), /* 338 */ - /* 1 */ V(8, 5, 1), - - /* 0010 0000 ... */ - /* 0 */ V(2, 9, 1), /* 340 */ - /* 1 */ V(6, 7, 1), - - /* 0010 0001 ... */ - /* 0 */ V(7, 6, 1), /* 342 */ - /* 1 */ V(9, 2, 1), - - /* 0010 0011 ... */ - /* 0 */ V(1, 9, 1), /* 344 */ - /* 1 */ V(9, 0, 1), - - /* 0010 0100 ... */ - /* 0 */ V(4, 8, 1), /* 346 */ - /* 1 */ V(8, 4, 1), - - /* 0010 0101 ... */ - /* 0 */ V(5, 7, 1), /* 348 */ - /* 1 */ V(7, 5, 1), - - /* 0010 0110 ... */ - /* 0 */ V(3, 8, 1), /* 350 */ - /* 1 */ V(8, 3, 1), - - /* 0010 0111 ... */ - /* 0 */ V(6, 6, 1), /* 352 */ - /* 1 */ V(4, 7, 1), - - /* 0010 1100 ... */ - /* 0 */ V(7, 4, 1), /* 354 */ - /* 1 */ V(0, 8, 1), - - /* 0010 1101 ... */ - /* 0 */ V(8, 0, 1), /* 356 */ - /* 1 */ V(5, 6, 1), - - /* 0010 1110 ... */ - /* 0 */ V(6, 5, 1), /* 358 */ - /* 1 */ V(3, 7, 1), - - /* 0010 1111 ... */ - /* 0 */ V(7, 3, 1), /* 360 */ - /* 1 */ V(4, 6, 1), - - /* 0011 0110 ... */ - /* 0 */ V(0, 7, 1), /* 362 */ - /* 1 */ V(7, 0, 1), - - /* 0011 1110 ... */ - /* 0 */ V(0, 6, 1), /* 364 */ - /* 1 */ V(6, 0, 1), - - /* 0000 0000 0000 ... */ - /* 0 */ V(15, 15, 1), /* 366 */ - /* 1 */ V(14, 15, 1), - - /* 0000 0000 0001 ... */ - /* 0 */ V(15, 14, 1), /* 368 */ - /* 1 */ V(13, 15, 1), - - /* 0000 0000 0011 ... */ - /* 0 */ V(15, 13, 1), /* 370 */ - /* 1 */ V(12, 15, 1), - - /* 0000 0000 0100 ... */ - /* 0 */ V(15, 12, 1), /* 372 */ - /* 1 */ V(13, 14, 1), - - /* 0000 0000 0101 ... */ - /* 0 */ V(14, 13, 1), /* 374 */ - /* 1 */ V(11, 15, 1), - - /* 0000 0000 0111 ... */ - /* 0 */ V(12, 14, 1), /* 376 */ - /* 1 */ V(14, 12, 1), - - /* 0000 0001 1111 ... */ - /* 0 */ V(10, 14, 1), /* 378 */ - /* 1 */ V(0, 15, 1) + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ PTR(48, 4), + /* 0011 */ PTR(64, 4), + /* 0100 */ PTR(80, 4), + /* 0101 */ PTR(96, 3), + /* 0110 */ PTR(104, 3), + /* 0111 */ PTR(112, 2), + /* 1000 */ PTR(116, 1), + /* 1001 */ PTR(118, 1), + /* 1010 */ V(1, 1, 3), + /* 1011 */ V(1, 1, 3), + /* 1100 */ V(0, 1, 4), + /* 1101 */ V(1, 0, 4), + /* 1110 */ V(0, 0, 3), + /* 1111 */ V(0, 0, 3), + + /* 0000 ... */ + /* 0000 */ PTR(120, 4), /* 16 */ + /* 0001 */ PTR(136, 4), + /* 0010 */ PTR(152, 4), + /* 0011 */ PTR(168, 4), + /* 0100 */ PTR(184, 4), + /* 0101 */ PTR(200, 3), + /* 0110 */ PTR(208, 3), + /* 0111 */ PTR(216, 4), + /* 1000 */ PTR(232, 3), + /* 1001 */ PTR(240, 3), + /* 1010 */ PTR(248, 3), + /* 1011 */ PTR(256, 3), + /* 1100 */ PTR(264, 2), + /* 1101 */ PTR(268, 3), + /* 1110 */ PTR(276, 3), + /* 1111 */ PTR(284, 2), + + /* 0001 ... */ + /* 0000 */ PTR(288, 2), /* 32 */ + /* 0001 */ PTR(292, 2), + /* 0010 */ PTR(296, 2), + /* 0011 */ PTR(300, 2), + /* 0100 */ PTR(304, 2), + /* 0101 */ PTR(308, 2), + /* 0110 */ PTR(312, 2), + /* 0111 */ PTR(316, 2), + /* 1000 */ PTR(320, 1), + /* 1001 */ PTR(322, 1), + /* 1010 */ PTR(324, 1), + /* 1011 */ PTR(326, 2), + /* 1100 */ PTR(330, 1), + /* 1101 */ PTR(332, 1), + /* 1110 */ PTR(334, 2), + /* 1111 */ PTR(338, 1), + + /* 0010 ... */ + /* 0000 */ PTR(340, 1), /* 48 */ + /* 0001 */ PTR(342, 1), + /* 0010 */ V(9, 1, 4), + /* 0011 */ PTR(344, 1), + /* 0100 */ PTR(346, 1), + /* 0101 */ PTR(348, 1), + /* 0110 */ PTR(350, 1), + /* 0111 */ PTR(352, 1), + /* 1000 */ V(2, 8, 4), + /* 1001 */ V(8, 2, 4), + /* 1010 */ V(1, 8, 4), + /* 1011 */ V(8, 1, 4), + /* 1100 */ PTR(354, 1), + /* 1101 */ PTR(356, 1), + /* 1110 */ PTR(358, 1), + /* 1111 */ PTR(360, 1), + + /* 0011 ... */ + /* 0000 */ V(2, 7, 4), /* 64 */ + /* 0001 */ V(7, 2, 4), + /* 0010 */ V(6, 4, 4), + /* 0011 */ V(1, 7, 4), + /* 0100 */ V(5, 5, 4), + /* 0101 */ V(7, 1, 4), + /* 0110 */ PTR(362, 1), + /* 0111 */ V(3, 6, 4), + /* 1000 */ V(6, 3, 4), + /* 1001 */ V(4, 5, 4), + /* 1010 */ V(5, 4, 4), + /* 1011 */ V(2, 6, 4), + /* 1100 */ V(6, 2, 4), + /* 1101 */ V(1, 6, 4), + /* 1110 */ PTR(364, 1), + /* 1111 */ V(3, 5, 4), + + /* 0100 ... */ + /* 0000 */ V(6, 1, 3), /* 80 */ + /* 0001 */ V(6, 1, 3), + /* 0010 */ V(5, 3, 4), + /* 0011 */ V(4, 4, 4), + /* 0100 */ V(2, 5, 3), + /* 0101 */ V(2, 5, 3), + /* 0110 */ V(5, 2, 3), + /* 0111 */ V(5, 2, 3), + /* 1000 */ V(1, 5, 3), + /* 1001 */ V(1, 5, 3), + /* 1010 */ V(5, 1, 3), + /* 1011 */ V(5, 1, 3), + /* 1100 */ V(0, 5, 4), + /* 1101 */ V(5, 0, 4), + /* 1110 */ V(3, 4, 3), + /* 1111 */ V(3, 4, 3), + + /* 0101 ... */ + /* 000 */ V(4, 3, 3), /* 96 */ + /* 001 */ V(2, 4, 3), + /* 010 */ V(4, 2, 3), + /* 011 */ V(3, 3, 3), + /* 100 */ V(4, 1, 2), + /* 101 */ V(4, 1, 2), + /* 110 */ V(1, 4, 3), + /* 111 */ V(0, 4, 3), + + /* 0110 ... */ + /* 000 */ V(2, 3, 2), /* 104 */ + /* 001 */ V(2, 3, 2), + /* 010 */ V(3, 2, 2), + /* 011 */ V(3, 2, 2), + /* 100 */ V(4, 0, 3), + /* 101 */ V(0, 3, 3), + /* 110 */ V(1, 3, 2), + /* 111 */ V(1, 3, 2), + + /* 0111 ... */ + /* 00 */ V(3, 1, 2), /* 112 */ + /* 01 */ V(3, 0, 2), + /* 10 */ V(2, 2, 1), + /* 11 */ V(2, 2, 1), + + /* 1000 ... */ + /* 0 */ V(1, 2, 1), /* 116 */ + /* 1 */ V(2, 1, 1), + + /* 1001 ... */ + /* 0 */ V(0, 2, 1), /* 118 */ + /* 1 */ V(2, 0, 1), + + /* 0000 0000 ... */ + /* 0000 */ PTR(366, 1), /* 120 */ + /* 0001 */ PTR(368, 1), + /* 0010 */ V(14, 14, 4), + /* 0011 */ PTR(370, 1), + /* 0100 */ PTR(372, 1), + /* 0101 */ PTR(374, 1), + /* 0110 */ V(15, 11, 4), + /* 0111 */ PTR(376, 1), + /* 1000 */ V(13, 13, 4), + /* 1001 */ V(10, 15, 4), + /* 1010 */ V(15, 10, 4), + /* 1011 */ V(11, 14, 4), + /* 1100 */ V(14, 11, 4), + /* 1101 */ V(12, 13, 4), + /* 1110 */ V(13, 12, 4), + /* 1111 */ V(9, 15, 4), + + /* 0000 0001 ... */ + /* 0000 */ V(15, 9, 4), /* 136 */ + /* 0001 */ V(14, 10, 4), + /* 0010 */ V(11, 13, 4), + /* 0011 */ V(13, 11, 4), + /* 0100 */ V(8, 15, 4), + /* 0101 */ V(15, 8, 4), + /* 0110 */ V(12, 12, 4), + /* 0111 */ V(9, 14, 4), + /* 1000 */ V(14, 9, 4), + /* 1001 */ V(7, 15, 4), + /* 1010 */ V(15, 7, 4), + /* 1011 */ V(10, 13, 4), + /* 1100 */ V(13, 10, 4), + /* 1101 */ V(11, 12, 4), + /* 1110 */ V(6, 15, 4), + /* 1111 */ PTR(378, 1), + + /* 0000 0010 ... */ + /* 0000 */ V(12, 11, 3), /* 152 */ + /* 0001 */ V(12, 11, 3), + /* 0010 */ V(15, 6, 3), + /* 0011 */ V(15, 6, 3), + /* 0100 */ V(8, 14, 4), + /* 0101 */ V(14, 8, 4), + /* 0110 */ V(5, 15, 4), + /* 0111 */ V(9, 13, 4), + /* 1000 */ V(15, 5, 3), + /* 1001 */ V(15, 5, 3), + /* 1010 */ V(7, 14, 3), + /* 1011 */ V(7, 14, 3), + /* 1100 */ V(14, 7, 3), + /* 1101 */ V(14, 7, 3), + /* 1110 */ V(10, 12, 3), + /* 1111 */ V(10, 12, 3), + + /* 0000 0011 ... */ + /* 0000 */ V(12, 10, 3), /* 168 */ + /* 0001 */ V(12, 10, 3), + /* 0010 */ V(11, 11, 3), + /* 0011 */ V(11, 11, 3), + /* 0100 */ V(13, 9, 4), + /* 0101 */ V(8, 13, 4), + /* 0110 */ V(4, 15, 3), + /* 0111 */ V(4, 15, 3), + /* 1000 */ V(15, 4, 3), + /* 1001 */ V(15, 4, 3), + /* 1010 */ V(3, 15, 3), + /* 1011 */ V(3, 15, 3), + /* 1100 */ V(15, 3, 3), + /* 1101 */ V(15, 3, 3), + /* 1110 */ V(13, 8, 3), + /* 1111 */ V(13, 8, 3), + + /* 0000 0100 ... */ + /* 0000 */ V(14, 6, 3), /* 184 */ + /* 0001 */ V(14, 6, 3), + /* 0010 */ V(2, 15, 3), + /* 0011 */ V(2, 15, 3), + /* 0100 */ V(15, 2, 3), + /* 0101 */ V(15, 2, 3), + /* 0110 */ V(6, 14, 4), + /* 0111 */ V(15, 0, 4), + /* 1000 */ V(1, 15, 3), + /* 1001 */ V(1, 15, 3), + /* 1010 */ V(15, 1, 3), + /* 1011 */ V(15, 1, 3), + /* 1100 */ V(9, 12, 3), + /* 1101 */ V(9, 12, 3), + /* 1110 */ V(12, 9, 3), + /* 1111 */ V(12, 9, 3), + + /* 0000 0101 ... */ + /* 000 */ V(5, 14, 3), /* 200 */ + /* 001 */ V(10, 11, 3), + /* 010 */ V(11, 10, 3), + /* 011 */ V(14, 5, 3), + /* 100 */ V(7, 13, 3), + /* 101 */ V(13, 7, 3), + /* 110 */ V(4, 14, 3), + /* 111 */ V(14, 4, 3), + + /* 0000 0110 ... */ + /* 000 */ V(8, 12, 3), /* 208 */ + /* 001 */ V(12, 8, 3), + /* 010 */ V(3, 14, 3), + /* 011 */ V(6, 13, 3), + /* 100 */ V(13, 6, 3), + /* 101 */ V(14, 3, 3), + /* 110 */ V(9, 11, 3), + /* 111 */ V(11, 9, 3), + + /* 0000 0111 ... */ + /* 0000 */ V(2, 14, 3), /* 216 */ + /* 0001 */ V(2, 14, 3), + /* 0010 */ V(10, 10, 3), + /* 0011 */ V(10, 10, 3), + /* 0100 */ V(14, 2, 3), + /* 0101 */ V(14, 2, 3), + /* 0110 */ V(1, 14, 3), + /* 0111 */ V(1, 14, 3), + /* 1000 */ V(14, 1, 3), + /* 1001 */ V(14, 1, 3), + /* 1010 */ V(0, 14, 4), + /* 1011 */ V(14, 0, 4), + /* 1100 */ V(5, 13, 3), + /* 1101 */ V(5, 13, 3), + /* 1110 */ V(13, 5, 3), + /* 1111 */ V(13, 5, 3), + + /* 0000 1000 ... */ + /* 000 */ V(7, 12, 3), /* 232 */ + /* 001 */ V(12, 7, 3), + /* 010 */ V(4, 13, 3), + /* 011 */ V(8, 11, 3), + /* 100 */ V(13, 4, 2), + /* 101 */ V(13, 4, 2), + /* 110 */ V(11, 8, 3), + /* 111 */ V(9, 10, 3), + + /* 0000 1001 ... */ + /* 000 */ V(10, 9, 3), /* 240 */ + /* 001 */ V(6, 12, 3), + /* 010 */ V(12, 6, 3), + /* 011 */ V(3, 13, 3), + /* 100 */ V(13, 3, 2), + /* 101 */ V(13, 3, 2), + /* 110 */ V(13, 2, 2), + /* 111 */ V(13, 2, 2), + + /* 0000 1010 ... */ + /* 000 */ V(2, 13, 3), /* 248 */ + /* 001 */ V(0, 13, 3), + /* 010 */ V(1, 13, 2), + /* 011 */ V(1, 13, 2), + /* 100 */ V(7, 11, 2), + /* 101 */ V(7, 11, 2), + /* 110 */ V(11, 7, 2), + /* 111 */ V(11, 7, 2), + + /* 0000 1011 ... */ + /* 000 */ V(13, 1, 2), /* 256 */ + /* 001 */ V(13, 1, 2), + /* 010 */ V(5, 12, 3), + /* 011 */ V(13, 0, 3), + /* 100 */ V(12, 5, 2), + /* 101 */ V(12, 5, 2), + /* 110 */ V(8, 10, 2), + /* 111 */ V(8, 10, 2), + + /* 0000 1100 ... */ + /* 00 */ V(10, 8, 2), /* 264 */ + /* 01 */ V(4, 12, 2), + /* 10 */ V(12, 4, 2), + /* 11 */ V(6, 11, 2), + + /* 0000 1101 ... */ + /* 000 */ V(11, 6, 2), /* 268 */ + /* 001 */ V(11, 6, 2), + /* 010 */ V(9, 9, 3), + /* 011 */ V(0, 12, 3), + /* 100 */ V(3, 12, 2), + /* 101 */ V(3, 12, 2), + /* 110 */ V(12, 3, 2), + /* 111 */ V(12, 3, 2), + + /* 0000 1110 ... */ + /* 000 */ V(7, 10, 2), /* 276 */ + /* 001 */ V(7, 10, 2), + /* 010 */ V(10, 7, 2), + /* 011 */ V(10, 7, 2), + /* 100 */ V(10, 6, 2), + /* 101 */ V(10, 6, 2), + /* 110 */ V(12, 0, 3), + /* 111 */ V(0, 11, 3), + + /* 0000 1111 ... */ + /* 00 */ V(12, 2, 1), /* 284 */ + /* 01 */ V(12, 2, 1), + /* 10 */ V(2, 12, 2), + /* 11 */ V(5, 11, 2), + + /* 0001 0000 ... */ + /* 00 */ V(11, 5, 2), /* 288 */ + /* 01 */ V(1, 12, 2), + /* 10 */ V(8, 9, 2), + /* 11 */ V(9, 8, 2), + + /* 0001 0001 ... */ + /* 00 */ V(12, 1, 2), /* 292 */ + /* 01 */ V(4, 11, 2), + /* 10 */ V(11, 4, 2), + /* 11 */ V(6, 10, 2), + + /* 0001 0010 ... */ + /* 00 */ V(3, 11, 2), /* 296 */ + /* 01 */ V(7, 9, 2), + /* 10 */ V(11, 3, 1), + /* 11 */ V(11, 3, 1), + + /* 0001 0011 ... */ + /* 00 */ V(9, 7, 2), /* 300 */ + /* 01 */ V(8, 8, 2), + /* 10 */ V(2, 11, 2), + /* 11 */ V(5, 10, 2), + + /* 0001 0100 ... */ + /* 00 */ V(11, 2, 1), /* 304 */ + /* 01 */ V(11, 2, 1), + /* 10 */ V(10, 5, 2), + /* 11 */ V(1, 11, 2), + + /* 0001 0101 ... */ + /* 00 */ V(11, 1, 1), /* 308 */ + /* 01 */ V(11, 1, 1), + /* 10 */ V(11, 0, 2), + /* 11 */ V(6, 9, 2), + + /* 0001 0110 ... */ + /* 00 */ V(9, 6, 2), /* 312 */ + /* 01 */ V(4, 10, 2), + /* 10 */ V(10, 4, 2), + /* 11 */ V(7, 8, 2), + + /* 0001 0111 ... */ + /* 00 */ V(8, 7, 2), /* 316 */ + /* 01 */ V(3, 10, 2), + /* 10 */ V(10, 3, 1), + /* 11 */ V(10, 3, 1), + + /* 0001 1000 ... */ + /* 0 */ V(5, 9, 1), /* 320 */ + /* 1 */ V(9, 5, 1), + + /* 0001 1001 ... */ + /* 0 */ V(2, 10, 1), /* 322 */ + /* 1 */ V(10, 2, 1), + + /* 0001 1010 ... */ + /* 0 */ V(1, 10, 1), /* 324 */ + /* 1 */ V(10, 1, 1), + + /* 0001 1011 ... */ + /* 00 */ V(0, 10, 2), /* 326 */ + /* 01 */ V(10, 0, 2), + /* 10 */ V(6, 8, 1), + /* 11 */ V(6, 8, 1), + + /* 0001 1100 ... */ + /* 0 */ V(8, 6, 1), /* 330 */ + /* 1 */ V(4, 9, 1), + + /* 0001 1101 ... */ + /* 0 */ V(9, 4, 1), /* 332 */ + /* 1 */ V(3, 9, 1), + + /* 0001 1110 ... */ + /* 00 */ V(9, 3, 1), /* 334 */ + /* 01 */ V(9, 3, 1), + /* 10 */ V(7, 7, 2), + /* 11 */ V(0, 9, 2), + + /* 0001 1111 ... */ + /* 0 */ V(5, 8, 1), /* 338 */ + /* 1 */ V(8, 5, 1), + + /* 0010 0000 ... */ + /* 0 */ V(2, 9, 1), /* 340 */ + /* 1 */ V(6, 7, 1), + + /* 0010 0001 ... */ + /* 0 */ V(7, 6, 1), /* 342 */ + /* 1 */ V(9, 2, 1), + + /* 0010 0011 ... */ + /* 0 */ V(1, 9, 1), /* 344 */ + /* 1 */ V(9, 0, 1), + + /* 0010 0100 ... */ + /* 0 */ V(4, 8, 1), /* 346 */ + /* 1 */ V(8, 4, 1), + + /* 0010 0101 ... */ + /* 0 */ V(5, 7, 1), /* 348 */ + /* 1 */ V(7, 5, 1), + + /* 0010 0110 ... */ + /* 0 */ V(3, 8, 1), /* 350 */ + /* 1 */ V(8, 3, 1), + + /* 0010 0111 ... */ + /* 0 */ V(6, 6, 1), /* 352 */ + /* 1 */ V(4, 7, 1), + + /* 0010 1100 ... */ + /* 0 */ V(7, 4, 1), /* 354 */ + /* 1 */ V(0, 8, 1), + + /* 0010 1101 ... */ + /* 0 */ V(8, 0, 1), /* 356 */ + /* 1 */ V(5, 6, 1), + + /* 0010 1110 ... */ + /* 0 */ V(6, 5, 1), /* 358 */ + /* 1 */ V(3, 7, 1), + + /* 0010 1111 ... */ + /* 0 */ V(7, 3, 1), /* 360 */ + /* 1 */ V(4, 6, 1), + + /* 0011 0110 ... */ + /* 0 */ V(0, 7, 1), /* 362 */ + /* 1 */ V(7, 0, 1), + + /* 0011 1110 ... */ + /* 0 */ V(0, 6, 1), /* 364 */ + /* 1 */ V(6, 0, 1), + + /* 0000 0000 0000 ... */ + /* 0 */ V(15, 15, 1), /* 366 */ + /* 1 */ V(14, 15, 1), + + /* 0000 0000 0001 ... */ + /* 0 */ V(15, 14, 1), /* 368 */ + /* 1 */ V(13, 15, 1), + + /* 0000 0000 0011 ... */ + /* 0 */ V(15, 13, 1), /* 370 */ + /* 1 */ V(12, 15, 1), + + /* 0000 0000 0100 ... */ + /* 0 */ V(15, 12, 1), /* 372 */ + /* 1 */ V(13, 14, 1), + + /* 0000 0000 0101 ... */ + /* 0 */ V(14, 13, 1), /* 374 */ + /* 1 */ V(11, 15, 1), + + /* 0000 0000 0111 ... */ + /* 0 */ V(12, 14, 1), /* 376 */ + /* 1 */ V(14, 12, 1), + + /* 0000 0001 1111 ... */ + /* 0 */ V(10, 14, 1), /* 378 */ + /* 1 */ V(0, 15, 1) }; static union huffpair const hufftab16[] PROGMEM = { - /* 0000 */ PTR(16, 4), - /* 0001 */ PTR(32, 4), - /* 0010 */ PTR(48, 4), - /* 0011 */ PTR(64, 2), - /* 0100 */ V(1, 1, 4), - /* 0101 */ V(0, 1, 4), - /* 0110 */ V(1, 0, 3), - /* 0111 */ V(1, 0, 3), - /* 1000 */ V(0, 0, 1), - /* 1001 */ V(0, 0, 1), - /* 1010 */ V(0, 0, 1), - /* 1011 */ V(0, 0, 1), - /* 1100 */ V(0, 0, 1), - /* 1101 */ V(0, 0, 1), - /* 1110 */ V(0, 0, 1), - /* 1111 */ V(0, 0, 1), - - /* 0000 ... */ - /* 0000 */ PTR(68, 3), /* 16 */ - /* 0001 */ PTR(76, 3), - /* 0010 */ PTR(84, 2), - /* 0011 */ V(15, 15, 4), - /* 0100 */ PTR(88, 2), - /* 0101 */ PTR(92, 1), - /* 0110 */ PTR(94, 4), - /* 0111 */ V(15, 2, 4), - /* 1000 */ PTR(110, 1), - /* 1001 */ V(1, 15, 4), - /* 1010 */ V(15, 1, 4), - /* 1011 */ PTR(112, 4), - /* 1100 */ PTR(128, 4), - /* 1101 */ PTR(144, 4), - /* 1110 */ PTR(160, 4), - /* 1111 */ PTR(176, 4), - - /* 0001 ... */ - /* 0000 */ PTR(192, 4), /* 32 */ - /* 0001 */ PTR(208, 3), - /* 0010 */ PTR(216, 3), - /* 0011 */ PTR(224, 3), - /* 0100 */ PTR(232, 3), - /* 0101 */ PTR(240, 3), - /* 0110 */ PTR(248, 3), - /* 0111 */ PTR(256, 3), - /* 1000 */ PTR(264, 2), - /* 1001 */ PTR(268, 2), - /* 1010 */ PTR(272, 1), - /* 1011 */ PTR(274, 2), - /* 1100 */ PTR(278, 2), - /* 1101 */ PTR(282, 1), - /* 1110 */ V(5, 1, 4), - /* 1111 */ PTR(284, 1), - - /* 0010 ... */ - /* 0000 */ PTR(286, 1), /* 48 */ - /* 0001 */ PTR(288, 1), - /* 0010 */ PTR(290, 1), - /* 0011 */ V(1, 4, 4), - /* 0100 */ V(4, 1, 4), - /* 0101 */ PTR(292, 1), - /* 0110 */ V(2, 3, 4), - /* 0111 */ V(3, 2, 4), - /* 1000 */ V(1, 3, 3), - /* 1001 */ V(1, 3, 3), - /* 1010 */ V(3, 1, 3), - /* 1011 */ V(3, 1, 3), - /* 1100 */ V(0, 3, 4), - /* 1101 */ V(3, 0, 4), - /* 1110 */ V(2, 2, 3), - /* 1111 */ V(2, 2, 3), - - /* 0011 ... */ - /* 00 */ V(1, 2, 2), /* 64 */ - /* 01 */ V(2, 1, 2), - /* 10 */ V(0, 2, 2), - /* 11 */ V(2, 0, 2), - - /* 0000 0000 ... */ - /* 000 */ V(14, 15, 3), /* 68 */ - /* 001 */ V(15, 14, 3), - /* 010 */ V(13, 15, 3), - /* 011 */ V(15, 13, 3), - /* 100 */ V(12, 15, 3), - /* 101 */ V(15, 12, 3), - /* 110 */ V(11, 15, 3), - /* 111 */ V(15, 11, 3), - - /* 0000 0001 ... */ - /* 000 */ V(10, 15, 2), /* 76 */ - /* 001 */ V(10, 15, 2), - /* 010 */ V(15, 10, 3), - /* 011 */ V(9, 15, 3), - /* 100 */ V(15, 9, 3), - /* 101 */ V(15, 8, 3), - /* 110 */ V(8, 15, 2), - /* 111 */ V(8, 15, 2), - - /* 0000 0010 ... */ - /* 00 */ V(7, 15, 2), /* 84 */ - /* 01 */ V(15, 7, 2), - /* 10 */ V(6, 15, 2), - /* 11 */ V(15, 6, 2), - - /* 0000 0100 ... */ - /* 00 */ V(5, 15, 2), /* 88 */ - /* 01 */ V(15, 5, 2), - /* 10 */ V(4, 15, 1), - /* 11 */ V(4, 15, 1), - - /* 0000 0101 ... */ - /* 0 */ V(15, 4, 1), /* 92 */ - /* 1 */ V(15, 3, 1), - - /* 0000 0110 ... */ - /* 0000 */ V(15, 0, 1), /* 94 */ - /* 0001 */ V(15, 0, 1), - /* 0010 */ V(15, 0, 1), - /* 0011 */ V(15, 0, 1), - /* 0100 */ V(15, 0, 1), - /* 0101 */ V(15, 0, 1), - /* 0110 */ V(15, 0, 1), - /* 0111 */ V(15, 0, 1), - /* 1000 */ V(3, 15, 2), - /* 1001 */ V(3, 15, 2), - /* 1010 */ V(3, 15, 2), - /* 1011 */ V(3, 15, 2), - /* 1100 */ PTR(294, 4), - /* 1101 */ PTR(310, 3), - /* 1110 */ PTR(318, 3), - /* 1111 */ PTR(326, 3), - - /* 0000 1000 ... */ - /* 0 */ V(2, 15, 1), /* 110 */ - /* 1 */ V(0, 15, 1), - - /* 0000 1011 ... */ - /* 0000 */ PTR(334, 2), /* 112 */ - /* 0001 */ PTR(338, 2), - /* 0010 */ PTR(342, 2), - /* 0011 */ PTR(346, 1), - /* 0100 */ PTR(348, 2), - /* 0101 */ PTR(352, 2), - /* 0110 */ PTR(356, 1), - /* 0111 */ PTR(358, 2), - /* 1000 */ PTR(362, 2), - /* 1001 */ PTR(366, 2), - /* 1010 */ PTR(370, 2), - /* 1011 */ V(14, 3, 4), - /* 1100 */ PTR(374, 1), - /* 1101 */ PTR(376, 1), - /* 1110 */ PTR(378, 1), - /* 1111 */ PTR(380, 1), - - /* 0000 1100 ... */ - /* 0000 */ PTR(382, 1), /* 128 */ - /* 0001 */ PTR(384, 1), - /* 0010 */ PTR(386, 1), - /* 0011 */ V(0, 13, 4), - /* 0100 */ PTR(388, 1), - /* 0101 */ PTR(390, 1), - /* 0110 */ PTR(392, 1), - /* 0111 */ V(3, 12, 4), - /* 1000 */ PTR(394, 1), - /* 1001 */ V(1, 12, 4), - /* 1010 */ V(12, 0, 4), - /* 1011 */ PTR(396, 1), - /* 1100 */ V(14, 2, 3), - /* 1101 */ V(14, 2, 3), - /* 1110 */ V(2, 14, 4), - /* 1111 */ V(1, 14, 4), - - /* 0000 1101 ... */ - /* 0000 */ V(13, 3, 4), /* 144 */ - /* 0001 */ V(2, 13, 4), - /* 0010 */ V(13, 2, 4), - /* 0011 */ V(13, 1, 4), - /* 0100 */ V(3, 11, 4), - /* 0101 */ PTR(398, 1), - /* 0110 */ V(1, 13, 3), - /* 0111 */ V(1, 13, 3), - /* 1000 */ V(12, 4, 4), - /* 1001 */ V(6, 11, 4), - /* 1010 */ V(12, 3, 4), - /* 1011 */ V(10, 7, 4), - /* 1100 */ V(2, 12, 3), - /* 1101 */ V(2, 12, 3), - /* 1110 */ V(12, 2, 4), - /* 1111 */ V(11, 5, 4), - - /* 0000 1110 ... */ - /* 0000 */ V(12, 1, 4), /* 160 */ - /* 0001 */ V(0, 12, 4), - /* 0010 */ V(4, 11, 4), - /* 0011 */ V(11, 4, 4), - /* 0100 */ V(6, 10, 4), - /* 0101 */ V(10, 6, 4), - /* 0110 */ V(11, 3, 3), - /* 0111 */ V(11, 3, 3), - /* 1000 */ V(5, 10, 4), - /* 1001 */ V(10, 5, 4), - /* 1010 */ V(2, 11, 3), - /* 1011 */ V(2, 11, 3), - /* 1100 */ V(11, 2, 3), - /* 1101 */ V(11, 2, 3), - /* 1110 */ V(1, 11, 3), - /* 1111 */ V(1, 11, 3), - - /* 0000 1111 ... */ - /* 0000 */ V(11, 1, 3), /* 176 */ - /* 0001 */ V(11, 1, 3), - /* 0010 */ V(0, 11, 4), - /* 0011 */ V(11, 0, 4), - /* 0100 */ V(6, 9, 4), - /* 0101 */ V(9, 6, 4), - /* 0110 */ V(4, 10, 4), - /* 0111 */ V(10, 4, 4), - /* 1000 */ V(7, 8, 4), - /* 1001 */ V(8, 7, 4), - /* 1010 */ V(10, 3, 3), - /* 1011 */ V(10, 3, 3), - /* 1100 */ V(3, 10, 4), - /* 1101 */ V(5, 9, 4), - /* 1110 */ V(2, 10, 3), - /* 1111 */ V(2, 10, 3), - - /* 0001 0000 ... */ - /* 0000 */ V(9, 5, 4), /* 192 */ - /* 0001 */ V(6, 8, 4), - /* 0010 */ V(10, 1, 3), - /* 0011 */ V(10, 1, 3), - /* 0100 */ V(8, 6, 4), - /* 0101 */ V(7, 7, 4), - /* 0110 */ V(9, 4, 3), - /* 0111 */ V(9, 4, 3), - /* 1000 */ V(4, 9, 4), - /* 1001 */ V(5, 7, 4), - /* 1010 */ V(6, 7, 3), - /* 1011 */ V(6, 7, 3), - /* 1100 */ V(10, 2, 2), - /* 1101 */ V(10, 2, 2), - /* 1110 */ V(10, 2, 2), - /* 1111 */ V(10, 2, 2), - - /* 0001 0001 ... */ - /* 000 */ V(1, 10, 2), /* 208 */ - /* 001 */ V(1, 10, 2), - /* 010 */ V(0, 10, 3), - /* 011 */ V(10, 0, 3), - /* 100 */ V(3, 9, 3), - /* 101 */ V(9, 3, 3), - /* 110 */ V(5, 8, 3), - /* 111 */ V(8, 5, 3), - - /* 0001 0010 ... */ - /* 000 */ V(2, 9, 2), /* 216 */ - /* 001 */ V(2, 9, 2), - /* 010 */ V(9, 2, 2), - /* 011 */ V(9, 2, 2), - /* 100 */ V(7, 6, 3), - /* 101 */ V(0, 9, 3), - /* 110 */ V(1, 9, 2), - /* 111 */ V(1, 9, 2), - - /* 0001 0011 ... */ - /* 000 */ V(9, 1, 2), /* 224 */ - /* 001 */ V(9, 1, 2), - /* 010 */ V(9, 0, 3), - /* 011 */ V(4, 8, 3), - /* 100 */ V(8, 4, 3), - /* 101 */ V(7, 5, 3), - /* 110 */ V(3, 8, 3), - /* 111 */ V(8, 3, 3), - - /* 0001 0100 ... */ - /* 000 */ V(6, 6, 3), /* 232 */ - /* 001 */ V(2, 8, 3), - /* 010 */ V(8, 2, 2), - /* 011 */ V(8, 2, 2), - /* 100 */ V(4, 7, 3), - /* 101 */ V(7, 4, 3), - /* 110 */ V(1, 8, 2), - /* 111 */ V(1, 8, 2), - - /* 0001 0101 ... */ - /* 000 */ V(8, 1, 2), /* 240 */ - /* 001 */ V(8, 1, 2), - /* 010 */ V(8, 0, 2), - /* 011 */ V(8, 0, 2), - /* 100 */ V(0, 8, 3), - /* 101 */ V(5, 6, 3), - /* 110 */ V(3, 7, 2), - /* 111 */ V(3, 7, 2), - - /* 0001 0110 ... */ - /* 000 */ V(7, 3, 2), /* 248 */ - /* 001 */ V(7, 3, 2), - /* 010 */ V(6, 5, 3), - /* 011 */ V(4, 6, 3), - /* 100 */ V(2, 7, 2), - /* 101 */ V(2, 7, 2), - /* 110 */ V(7, 2, 2), - /* 111 */ V(7, 2, 2), - - /* 0001 0111 ... */ - /* 000 */ V(6, 4, 3), /* 256 */ - /* 001 */ V(5, 5, 3), - /* 010 */ V(0, 7, 2), - /* 011 */ V(0, 7, 2), - /* 100 */ V(1, 7, 1), - /* 101 */ V(1, 7, 1), - /* 110 */ V(1, 7, 1), - /* 111 */ V(1, 7, 1), - - /* 0001 1000 ... */ - /* 00 */ V(7, 1, 1), /* 264 */ - /* 01 */ V(7, 1, 1), - /* 10 */ V(7, 0, 2), - /* 11 */ V(3, 6, 2), - - /* 0001 1001 ... */ - /* 00 */ V(6, 3, 2), /* 268 */ - /* 01 */ V(4, 5, 2), - /* 10 */ V(5, 4, 2), - /* 11 */ V(2, 6, 2), - - /* 0001 1010 ... */ - /* 0 */ V(6, 2, 1), /* 272 */ - /* 1 */ V(1, 6, 1), - - /* 0001 1011 ... */ - /* 00 */ V(6, 1, 1), /* 274 */ - /* 01 */ V(6, 1, 1), - /* 10 */ V(0, 6, 2), - /* 11 */ V(6, 0, 2), - - /* 0001 1100 ... */ - /* 00 */ V(5, 3, 1), /* 278 */ - /* 01 */ V(5, 3, 1), - /* 10 */ V(3, 5, 2), - /* 11 */ V(4, 4, 2), - - /* 0001 1101 ... */ - /* 0 */ V(2, 5, 1), /* 282 */ - /* 1 */ V(5, 2, 1), - - /* 0001 1111 ... */ - /* 0 */ V(1, 5, 1), /* 284 */ - /* 1 */ V(0, 5, 1), - - /* 0010 0000 ... */ - /* 0 */ V(3, 4, 1), /* 286 */ - /* 1 */ V(4, 3, 1), - - /* 0010 0001 ... */ - /* 0 */ V(5, 0, 1), /* 288 */ - /* 1 */ V(2, 4, 1), - - /* 0010 0010 ... */ - /* 0 */ V(4, 2, 1), /* 290 */ - /* 1 */ V(3, 3, 1), - - /* 0010 0101 ... */ - /* 0 */ V(0, 4, 1), /* 292 */ - /* 1 */ V(4, 0, 1), - - /* 0000 0110 1100 ... */ - /* 0000 */ V(12, 14, 4), /* 294 */ - /* 0001 */ PTR(400, 1), - /* 0010 */ V(13, 14, 3), - /* 0011 */ V(13, 14, 3), - /* 0100 */ V(14, 9, 3), - /* 0101 */ V(14, 9, 3), - /* 0110 */ V(14, 10, 4), - /* 0111 */ V(13, 9, 4), - /* 1000 */ V(14, 14, 2), - /* 1001 */ V(14, 14, 2), - /* 1010 */ V(14, 14, 2), - /* 1011 */ V(14, 14, 2), - /* 1100 */ V(14, 13, 3), - /* 1101 */ V(14, 13, 3), - /* 1110 */ V(14, 11, 3), - /* 1111 */ V(14, 11, 3), - - /* 0000 0110 1101 ... */ - /* 000 */ V(11, 14, 2), /* 310 */ - /* 001 */ V(11, 14, 2), - /* 010 */ V(12, 13, 2), - /* 011 */ V(12, 13, 2), - /* 100 */ V(13, 12, 3), - /* 101 */ V(13, 11, 3), - /* 110 */ V(10, 14, 2), - /* 111 */ V(10, 14, 2), - - /* 0000 0110 1110 ... */ - /* 000 */ V(12, 12, 2), /* 318 */ - /* 001 */ V(12, 12, 2), - /* 010 */ V(10, 13, 3), - /* 011 */ V(13, 10, 3), - /* 100 */ V(7, 14, 3), - /* 101 */ V(10, 12, 3), - /* 110 */ V(12, 10, 2), - /* 111 */ V(12, 10, 2), - - /* 0000 0110 1111 ... */ - /* 000 */ V(12, 9, 3), /* 326 */ - /* 001 */ V(7, 13, 3), - /* 010 */ V(5, 14, 2), - /* 011 */ V(5, 14, 2), - /* 100 */ V(11, 13, 1), - /* 101 */ V(11, 13, 1), - /* 110 */ V(11, 13, 1), - /* 111 */ V(11, 13, 1), - - /* 0000 1011 0000 ... */ - /* 00 */ V(9, 14, 1), /* 334 */ - /* 01 */ V(9, 14, 1), - /* 10 */ V(11, 12, 2), - /* 11 */ V(12, 11, 2), - - /* 0000 1011 0001 ... */ - /* 00 */ V(8, 14, 2), /* 338 */ - /* 01 */ V(14, 8, 2), - /* 10 */ V(9, 13, 2), - /* 11 */ V(14, 7, 2), - - /* 0000 1011 0010 ... */ - /* 00 */ V(11, 11, 2), /* 342 */ - /* 01 */ V(8, 13, 2), - /* 10 */ V(13, 8, 2), - /* 11 */ V(6, 14, 2), - - /* 0000 1011 0011 ... */ - /* 0 */ V(14, 6, 1), /* 346 */ - /* 1 */ V(9, 12, 1), - - /* 0000 1011 0100 ... */ - /* 00 */ V(10, 11, 2), /* 348 */ - /* 01 */ V(11, 10, 2), - /* 10 */ V(14, 5, 2), - /* 11 */ V(13, 7, 2), - - /* 0000 1011 0101 ... */ - /* 00 */ V(4, 14, 1), /* 352 */ - /* 01 */ V(4, 14, 1), - /* 10 */ V(14, 4, 2), - /* 11 */ V(8, 12, 2), - - /* 0000 1011 0110 ... */ - /* 0 */ V(12, 8, 1), /* 356 */ - /* 1 */ V(3, 14, 1), - - /* 0000 1011 0111 ... */ - /* 00 */ V(6, 13, 1), /* 358 */ - /* 01 */ V(6, 13, 1), - /* 10 */ V(13, 6, 2), - /* 11 */ V(9, 11, 2), - - /* 0000 1011 1000 ... */ - /* 00 */ V(11, 9, 2), /* 362 */ - /* 01 */ V(10, 10, 2), - /* 10 */ V(14, 1, 1), - /* 11 */ V(14, 1, 1), - - /* 0000 1011 1001 ... */ - /* 00 */ V(13, 4, 1), /* 366 */ - /* 01 */ V(13, 4, 1), - /* 10 */ V(11, 8, 2), - /* 11 */ V(10, 9, 2), - - /* 0000 1011 1010 ... */ - /* 00 */ V(7, 11, 1), /* 370 */ - /* 01 */ V(7, 11, 1), - /* 10 */ V(11, 7, 2), - /* 11 */ V(13, 0, 2), - - /* 0000 1011 1100 ... */ - /* 0 */ V(0, 14, 1), /* 374 */ - /* 1 */ V(14, 0, 1), - - /* 0000 1011 1101 ... */ - /* 0 */ V(5, 13, 1), /* 376 */ - /* 1 */ V(13, 5, 1), - - /* 0000 1011 1110 ... */ - /* 0 */ V(7, 12, 1), /* 378 */ - /* 1 */ V(12, 7, 1), - - /* 0000 1011 1111 ... */ - /* 0 */ V(4, 13, 1), /* 380 */ - /* 1 */ V(8, 11, 1), - - /* 0000 1100 0000 ... */ - /* 0 */ V(9, 10, 1), /* 382 */ - /* 1 */ V(6, 12, 1), - - /* 0000 1100 0001 ... */ - /* 0 */ V(12, 6, 1), /* 384 */ - /* 1 */ V(3, 13, 1), - - /* 0000 1100 0010 ... */ - /* 0 */ V(5, 12, 1), /* 386 */ - /* 1 */ V(12, 5, 1), - - /* 0000 1100 0100 ... */ - /* 0 */ V(8, 10, 1), /* 388 */ - /* 1 */ V(10, 8, 1), - - /* 0000 1100 0101 ... */ - /* 0 */ V(9, 9, 1), /* 390 */ - /* 1 */ V(4, 12, 1), - - /* 0000 1100 0110 ... */ - /* 0 */ V(11, 6, 1), /* 392 */ - /* 1 */ V(7, 10, 1), - - /* 0000 1100 1000 ... */ - /* 0 */ V(5, 11, 1), /* 394 */ - /* 1 */ V(8, 9, 1), - - /* 0000 1100 1011 ... */ - /* 0 */ V(9, 8, 1), /* 396 */ - /* 1 */ V(7, 9, 1), - - /* 0000 1101 0101 ... */ - /* 0 */ V(9, 7, 1), /* 398 */ - /* 1 */ V(8, 8, 1), - - /* 0000 0110 1100 0001 ... */ - /* 0 */ V(14, 12, 1), /* 400 */ - /* 1 */ V(13, 13, 1) + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ PTR(48, 4), + /* 0011 */ PTR(64, 2), + /* 0100 */ V(1, 1, 4), + /* 0101 */ V(0, 1, 4), + /* 0110 */ V(1, 0, 3), + /* 0111 */ V(1, 0, 3), + /* 1000 */ V(0, 0, 1), + /* 1001 */ V(0, 0, 1), + /* 1010 */ V(0, 0, 1), + /* 1011 */ V(0, 0, 1), + /* 1100 */ V(0, 0, 1), + /* 1101 */ V(0, 0, 1), + /* 1110 */ V(0, 0, 1), + /* 1111 */ V(0, 0, 1), + + /* 0000 ... */ + /* 0000 */ PTR(68, 3), /* 16 */ + /* 0001 */ PTR(76, 3), + /* 0010 */ PTR(84, 2), + /* 0011 */ V(15, 15, 4), + /* 0100 */ PTR(88, 2), + /* 0101 */ PTR(92, 1), + /* 0110 */ PTR(94, 4), + /* 0111 */ V(15, 2, 4), + /* 1000 */ PTR(110, 1), + /* 1001 */ V(1, 15, 4), + /* 1010 */ V(15, 1, 4), + /* 1011 */ PTR(112, 4), + /* 1100 */ PTR(128, 4), + /* 1101 */ PTR(144, 4), + /* 1110 */ PTR(160, 4), + /* 1111 */ PTR(176, 4), + + /* 0001 ... */ + /* 0000 */ PTR(192, 4), /* 32 */ + /* 0001 */ PTR(208, 3), + /* 0010 */ PTR(216, 3), + /* 0011 */ PTR(224, 3), + /* 0100 */ PTR(232, 3), + /* 0101 */ PTR(240, 3), + /* 0110 */ PTR(248, 3), + /* 0111 */ PTR(256, 3), + /* 1000 */ PTR(264, 2), + /* 1001 */ PTR(268, 2), + /* 1010 */ PTR(272, 1), + /* 1011 */ PTR(274, 2), + /* 1100 */ PTR(278, 2), + /* 1101 */ PTR(282, 1), + /* 1110 */ V(5, 1, 4), + /* 1111 */ PTR(284, 1), + + /* 0010 ... */ + /* 0000 */ PTR(286, 1), /* 48 */ + /* 0001 */ PTR(288, 1), + /* 0010 */ PTR(290, 1), + /* 0011 */ V(1, 4, 4), + /* 0100 */ V(4, 1, 4), + /* 0101 */ PTR(292, 1), + /* 0110 */ V(2, 3, 4), + /* 0111 */ V(3, 2, 4), + /* 1000 */ V(1, 3, 3), + /* 1001 */ V(1, 3, 3), + /* 1010 */ V(3, 1, 3), + /* 1011 */ V(3, 1, 3), + /* 1100 */ V(0, 3, 4), + /* 1101 */ V(3, 0, 4), + /* 1110 */ V(2, 2, 3), + /* 1111 */ V(2, 2, 3), + + /* 0011 ... */ + /* 00 */ V(1, 2, 2), /* 64 */ + /* 01 */ V(2, 1, 2), + /* 10 */ V(0, 2, 2), + /* 11 */ V(2, 0, 2), + + /* 0000 0000 ... */ + /* 000 */ V(14, 15, 3), /* 68 */ + /* 001 */ V(15, 14, 3), + /* 010 */ V(13, 15, 3), + /* 011 */ V(15, 13, 3), + /* 100 */ V(12, 15, 3), + /* 101 */ V(15, 12, 3), + /* 110 */ V(11, 15, 3), + /* 111 */ V(15, 11, 3), + + /* 0000 0001 ... */ + /* 000 */ V(10, 15, 2), /* 76 */ + /* 001 */ V(10, 15, 2), + /* 010 */ V(15, 10, 3), + /* 011 */ V(9, 15, 3), + /* 100 */ V(15, 9, 3), + /* 101 */ V(15, 8, 3), + /* 110 */ V(8, 15, 2), + /* 111 */ V(8, 15, 2), + + /* 0000 0010 ... */ + /* 00 */ V(7, 15, 2), /* 84 */ + /* 01 */ V(15, 7, 2), + /* 10 */ V(6, 15, 2), + /* 11 */ V(15, 6, 2), + + /* 0000 0100 ... */ + /* 00 */ V(5, 15, 2), /* 88 */ + /* 01 */ V(15, 5, 2), + /* 10 */ V(4, 15, 1), + /* 11 */ V(4, 15, 1), + + /* 0000 0101 ... */ + /* 0 */ V(15, 4, 1), /* 92 */ + /* 1 */ V(15, 3, 1), + + /* 0000 0110 ... */ + /* 0000 */ V(15, 0, 1), /* 94 */ + /* 0001 */ V(15, 0, 1), + /* 0010 */ V(15, 0, 1), + /* 0011 */ V(15, 0, 1), + /* 0100 */ V(15, 0, 1), + /* 0101 */ V(15, 0, 1), + /* 0110 */ V(15, 0, 1), + /* 0111 */ V(15, 0, 1), + /* 1000 */ V(3, 15, 2), + /* 1001 */ V(3, 15, 2), + /* 1010 */ V(3, 15, 2), + /* 1011 */ V(3, 15, 2), + /* 1100 */ PTR(294, 4), + /* 1101 */ PTR(310, 3), + /* 1110 */ PTR(318, 3), + /* 1111 */ PTR(326, 3), + + /* 0000 1000 ... */ + /* 0 */ V(2, 15, 1), /* 110 */ + /* 1 */ V(0, 15, 1), + + /* 0000 1011 ... */ + /* 0000 */ PTR(334, 2), /* 112 */ + /* 0001 */ PTR(338, 2), + /* 0010 */ PTR(342, 2), + /* 0011 */ PTR(346, 1), + /* 0100 */ PTR(348, 2), + /* 0101 */ PTR(352, 2), + /* 0110 */ PTR(356, 1), + /* 0111 */ PTR(358, 2), + /* 1000 */ PTR(362, 2), + /* 1001 */ PTR(366, 2), + /* 1010 */ PTR(370, 2), + /* 1011 */ V(14, 3, 4), + /* 1100 */ PTR(374, 1), + /* 1101 */ PTR(376, 1), + /* 1110 */ PTR(378, 1), + /* 1111 */ PTR(380, 1), + + /* 0000 1100 ... */ + /* 0000 */ PTR(382, 1), /* 128 */ + /* 0001 */ PTR(384, 1), + /* 0010 */ PTR(386, 1), + /* 0011 */ V(0, 13, 4), + /* 0100 */ PTR(388, 1), + /* 0101 */ PTR(390, 1), + /* 0110 */ PTR(392, 1), + /* 0111 */ V(3, 12, 4), + /* 1000 */ PTR(394, 1), + /* 1001 */ V(1, 12, 4), + /* 1010 */ V(12, 0, 4), + /* 1011 */ PTR(396, 1), + /* 1100 */ V(14, 2, 3), + /* 1101 */ V(14, 2, 3), + /* 1110 */ V(2, 14, 4), + /* 1111 */ V(1, 14, 4), + + /* 0000 1101 ... */ + /* 0000 */ V(13, 3, 4), /* 144 */ + /* 0001 */ V(2, 13, 4), + /* 0010 */ V(13, 2, 4), + /* 0011 */ V(13, 1, 4), + /* 0100 */ V(3, 11, 4), + /* 0101 */ PTR(398, 1), + /* 0110 */ V(1, 13, 3), + /* 0111 */ V(1, 13, 3), + /* 1000 */ V(12, 4, 4), + /* 1001 */ V(6, 11, 4), + /* 1010 */ V(12, 3, 4), + /* 1011 */ V(10, 7, 4), + /* 1100 */ V(2, 12, 3), + /* 1101 */ V(2, 12, 3), + /* 1110 */ V(12, 2, 4), + /* 1111 */ V(11, 5, 4), + + /* 0000 1110 ... */ + /* 0000 */ V(12, 1, 4), /* 160 */ + /* 0001 */ V(0, 12, 4), + /* 0010 */ V(4, 11, 4), + /* 0011 */ V(11, 4, 4), + /* 0100 */ V(6, 10, 4), + /* 0101 */ V(10, 6, 4), + /* 0110 */ V(11, 3, 3), + /* 0111 */ V(11, 3, 3), + /* 1000 */ V(5, 10, 4), + /* 1001 */ V(10, 5, 4), + /* 1010 */ V(2, 11, 3), + /* 1011 */ V(2, 11, 3), + /* 1100 */ V(11, 2, 3), + /* 1101 */ V(11, 2, 3), + /* 1110 */ V(1, 11, 3), + /* 1111 */ V(1, 11, 3), + + /* 0000 1111 ... */ + /* 0000 */ V(11, 1, 3), /* 176 */ + /* 0001 */ V(11, 1, 3), + /* 0010 */ V(0, 11, 4), + /* 0011 */ V(11, 0, 4), + /* 0100 */ V(6, 9, 4), + /* 0101 */ V(9, 6, 4), + /* 0110 */ V(4, 10, 4), + /* 0111 */ V(10, 4, 4), + /* 1000 */ V(7, 8, 4), + /* 1001 */ V(8, 7, 4), + /* 1010 */ V(10, 3, 3), + /* 1011 */ V(10, 3, 3), + /* 1100 */ V(3, 10, 4), + /* 1101 */ V(5, 9, 4), + /* 1110 */ V(2, 10, 3), + /* 1111 */ V(2, 10, 3), + + /* 0001 0000 ... */ + /* 0000 */ V(9, 5, 4), /* 192 */ + /* 0001 */ V(6, 8, 4), + /* 0010 */ V(10, 1, 3), + /* 0011 */ V(10, 1, 3), + /* 0100 */ V(8, 6, 4), + /* 0101 */ V(7, 7, 4), + /* 0110 */ V(9, 4, 3), + /* 0111 */ V(9, 4, 3), + /* 1000 */ V(4, 9, 4), + /* 1001 */ V(5, 7, 4), + /* 1010 */ V(6, 7, 3), + /* 1011 */ V(6, 7, 3), + /* 1100 */ V(10, 2, 2), + /* 1101 */ V(10, 2, 2), + /* 1110 */ V(10, 2, 2), + /* 1111 */ V(10, 2, 2), + + /* 0001 0001 ... */ + /* 000 */ V(1, 10, 2), /* 208 */ + /* 001 */ V(1, 10, 2), + /* 010 */ V(0, 10, 3), + /* 011 */ V(10, 0, 3), + /* 100 */ V(3, 9, 3), + /* 101 */ V(9, 3, 3), + /* 110 */ V(5, 8, 3), + /* 111 */ V(8, 5, 3), + + /* 0001 0010 ... */ + /* 000 */ V(2, 9, 2), /* 216 */ + /* 001 */ V(2, 9, 2), + /* 010 */ V(9, 2, 2), + /* 011 */ V(9, 2, 2), + /* 100 */ V(7, 6, 3), + /* 101 */ V(0, 9, 3), + /* 110 */ V(1, 9, 2), + /* 111 */ V(1, 9, 2), + + /* 0001 0011 ... */ + /* 000 */ V(9, 1, 2), /* 224 */ + /* 001 */ V(9, 1, 2), + /* 010 */ V(9, 0, 3), + /* 011 */ V(4, 8, 3), + /* 100 */ V(8, 4, 3), + /* 101 */ V(7, 5, 3), + /* 110 */ V(3, 8, 3), + /* 111 */ V(8, 3, 3), + + /* 0001 0100 ... */ + /* 000 */ V(6, 6, 3), /* 232 */ + /* 001 */ V(2, 8, 3), + /* 010 */ V(8, 2, 2), + /* 011 */ V(8, 2, 2), + /* 100 */ V(4, 7, 3), + /* 101 */ V(7, 4, 3), + /* 110 */ V(1, 8, 2), + /* 111 */ V(1, 8, 2), + + /* 0001 0101 ... */ + /* 000 */ V(8, 1, 2), /* 240 */ + /* 001 */ V(8, 1, 2), + /* 010 */ V(8, 0, 2), + /* 011 */ V(8, 0, 2), + /* 100 */ V(0, 8, 3), + /* 101 */ V(5, 6, 3), + /* 110 */ V(3, 7, 2), + /* 111 */ V(3, 7, 2), + + /* 0001 0110 ... */ + /* 000 */ V(7, 3, 2), /* 248 */ + /* 001 */ V(7, 3, 2), + /* 010 */ V(6, 5, 3), + /* 011 */ V(4, 6, 3), + /* 100 */ V(2, 7, 2), + /* 101 */ V(2, 7, 2), + /* 110 */ V(7, 2, 2), + /* 111 */ V(7, 2, 2), + + /* 0001 0111 ... */ + /* 000 */ V(6, 4, 3), /* 256 */ + /* 001 */ V(5, 5, 3), + /* 010 */ V(0, 7, 2), + /* 011 */ V(0, 7, 2), + /* 100 */ V(1, 7, 1), + /* 101 */ V(1, 7, 1), + /* 110 */ V(1, 7, 1), + /* 111 */ V(1, 7, 1), + + /* 0001 1000 ... */ + /* 00 */ V(7, 1, 1), /* 264 */ + /* 01 */ V(7, 1, 1), + /* 10 */ V(7, 0, 2), + /* 11 */ V(3, 6, 2), + + /* 0001 1001 ... */ + /* 00 */ V(6, 3, 2), /* 268 */ + /* 01 */ V(4, 5, 2), + /* 10 */ V(5, 4, 2), + /* 11 */ V(2, 6, 2), + + /* 0001 1010 ... */ + /* 0 */ V(6, 2, 1), /* 272 */ + /* 1 */ V(1, 6, 1), + + /* 0001 1011 ... */ + /* 00 */ V(6, 1, 1), /* 274 */ + /* 01 */ V(6, 1, 1), + /* 10 */ V(0, 6, 2), + /* 11 */ V(6, 0, 2), + + /* 0001 1100 ... */ + /* 00 */ V(5, 3, 1), /* 278 */ + /* 01 */ V(5, 3, 1), + /* 10 */ V(3, 5, 2), + /* 11 */ V(4, 4, 2), + + /* 0001 1101 ... */ + /* 0 */ V(2, 5, 1), /* 282 */ + /* 1 */ V(5, 2, 1), + + /* 0001 1111 ... */ + /* 0 */ V(1, 5, 1), /* 284 */ + /* 1 */ V(0, 5, 1), + + /* 0010 0000 ... */ + /* 0 */ V(3, 4, 1), /* 286 */ + /* 1 */ V(4, 3, 1), + + /* 0010 0001 ... */ + /* 0 */ V(5, 0, 1), /* 288 */ + /* 1 */ V(2, 4, 1), + + /* 0010 0010 ... */ + /* 0 */ V(4, 2, 1), /* 290 */ + /* 1 */ V(3, 3, 1), + + /* 0010 0101 ... */ + /* 0 */ V(0, 4, 1), /* 292 */ + /* 1 */ V(4, 0, 1), + + /* 0000 0110 1100 ... */ + /* 0000 */ V(12, 14, 4), /* 294 */ + /* 0001 */ PTR(400, 1), + /* 0010 */ V(13, 14, 3), + /* 0011 */ V(13, 14, 3), + /* 0100 */ V(14, 9, 3), + /* 0101 */ V(14, 9, 3), + /* 0110 */ V(14, 10, 4), + /* 0111 */ V(13, 9, 4), + /* 1000 */ V(14, 14, 2), + /* 1001 */ V(14, 14, 2), + /* 1010 */ V(14, 14, 2), + /* 1011 */ V(14, 14, 2), + /* 1100 */ V(14, 13, 3), + /* 1101 */ V(14, 13, 3), + /* 1110 */ V(14, 11, 3), + /* 1111 */ V(14, 11, 3), + + /* 0000 0110 1101 ... */ + /* 000 */ V(11, 14, 2), /* 310 */ + /* 001 */ V(11, 14, 2), + /* 010 */ V(12, 13, 2), + /* 011 */ V(12, 13, 2), + /* 100 */ V(13, 12, 3), + /* 101 */ V(13, 11, 3), + /* 110 */ V(10, 14, 2), + /* 111 */ V(10, 14, 2), + + /* 0000 0110 1110 ... */ + /* 000 */ V(12, 12, 2), /* 318 */ + /* 001 */ V(12, 12, 2), + /* 010 */ V(10, 13, 3), + /* 011 */ V(13, 10, 3), + /* 100 */ V(7, 14, 3), + /* 101 */ V(10, 12, 3), + /* 110 */ V(12, 10, 2), + /* 111 */ V(12, 10, 2), + + /* 0000 0110 1111 ... */ + /* 000 */ V(12, 9, 3), /* 326 */ + /* 001 */ V(7, 13, 3), + /* 010 */ V(5, 14, 2), + /* 011 */ V(5, 14, 2), + /* 100 */ V(11, 13, 1), + /* 101 */ V(11, 13, 1), + /* 110 */ V(11, 13, 1), + /* 111 */ V(11, 13, 1), + + /* 0000 1011 0000 ... */ + /* 00 */ V(9, 14, 1), /* 334 */ + /* 01 */ V(9, 14, 1), + /* 10 */ V(11, 12, 2), + /* 11 */ V(12, 11, 2), + + /* 0000 1011 0001 ... */ + /* 00 */ V(8, 14, 2), /* 338 */ + /* 01 */ V(14, 8, 2), + /* 10 */ V(9, 13, 2), + /* 11 */ V(14, 7, 2), + + /* 0000 1011 0010 ... */ + /* 00 */ V(11, 11, 2), /* 342 */ + /* 01 */ V(8, 13, 2), + /* 10 */ V(13, 8, 2), + /* 11 */ V(6, 14, 2), + + /* 0000 1011 0011 ... */ + /* 0 */ V(14, 6, 1), /* 346 */ + /* 1 */ V(9, 12, 1), + + /* 0000 1011 0100 ... */ + /* 00 */ V(10, 11, 2), /* 348 */ + /* 01 */ V(11, 10, 2), + /* 10 */ V(14, 5, 2), + /* 11 */ V(13, 7, 2), + + /* 0000 1011 0101 ... */ + /* 00 */ V(4, 14, 1), /* 352 */ + /* 01 */ V(4, 14, 1), + /* 10 */ V(14, 4, 2), + /* 11 */ V(8, 12, 2), + + /* 0000 1011 0110 ... */ + /* 0 */ V(12, 8, 1), /* 356 */ + /* 1 */ V(3, 14, 1), + + /* 0000 1011 0111 ... */ + /* 00 */ V(6, 13, 1), /* 358 */ + /* 01 */ V(6, 13, 1), + /* 10 */ V(13, 6, 2), + /* 11 */ V(9, 11, 2), + + /* 0000 1011 1000 ... */ + /* 00 */ V(11, 9, 2), /* 362 */ + /* 01 */ V(10, 10, 2), + /* 10 */ V(14, 1, 1), + /* 11 */ V(14, 1, 1), + + /* 0000 1011 1001 ... */ + /* 00 */ V(13, 4, 1), /* 366 */ + /* 01 */ V(13, 4, 1), + /* 10 */ V(11, 8, 2), + /* 11 */ V(10, 9, 2), + + /* 0000 1011 1010 ... */ + /* 00 */ V(7, 11, 1), /* 370 */ + /* 01 */ V(7, 11, 1), + /* 10 */ V(11, 7, 2), + /* 11 */ V(13, 0, 2), + + /* 0000 1011 1100 ... */ + /* 0 */ V(0, 14, 1), /* 374 */ + /* 1 */ V(14, 0, 1), + + /* 0000 1011 1101 ... */ + /* 0 */ V(5, 13, 1), /* 376 */ + /* 1 */ V(13, 5, 1), + + /* 0000 1011 1110 ... */ + /* 0 */ V(7, 12, 1), /* 378 */ + /* 1 */ V(12, 7, 1), + + /* 0000 1011 1111 ... */ + /* 0 */ V(4, 13, 1), /* 380 */ + /* 1 */ V(8, 11, 1), + + /* 0000 1100 0000 ... */ + /* 0 */ V(9, 10, 1), /* 382 */ + /* 1 */ V(6, 12, 1), + + /* 0000 1100 0001 ... */ + /* 0 */ V(12, 6, 1), /* 384 */ + /* 1 */ V(3, 13, 1), + + /* 0000 1100 0010 ... */ + /* 0 */ V(5, 12, 1), /* 386 */ + /* 1 */ V(12, 5, 1), + + /* 0000 1100 0100 ... */ + /* 0 */ V(8, 10, 1), /* 388 */ + /* 1 */ V(10, 8, 1), + + /* 0000 1100 0101 ... */ + /* 0 */ V(9, 9, 1), /* 390 */ + /* 1 */ V(4, 12, 1), + + /* 0000 1100 0110 ... */ + /* 0 */ V(11, 6, 1), /* 392 */ + /* 1 */ V(7, 10, 1), + + /* 0000 1100 1000 ... */ + /* 0 */ V(5, 11, 1), /* 394 */ + /* 1 */ V(8, 9, 1), + + /* 0000 1100 1011 ... */ + /* 0 */ V(9, 8, 1), /* 396 */ + /* 1 */ V(7, 9, 1), + + /* 0000 1101 0101 ... */ + /* 0 */ V(9, 7, 1), /* 398 */ + /* 1 */ V(8, 8, 1), + + /* 0000 0110 1100 0001 ... */ + /* 0 */ V(14, 12, 1), /* 400 */ + /* 1 */ V(13, 13, 1) }; static union huffpair const hufftab24[] PROGMEM = { - /* 0000 */ PTR(16, 4), - /* 0001 */ PTR(32, 4), - /* 0010 */ PTR(48, 4), - /* 0011 */ V(15, 15, 4), - /* 0100 */ PTR(64, 4), - /* 0101 */ PTR(80, 4), - /* 0110 */ PTR(96, 4), - /* 0111 */ PTR(112, 4), - /* 1000 */ PTR(128, 4), - /* 1001 */ PTR(144, 4), - /* 1010 */ PTR(160, 3), - /* 1011 */ PTR(168, 2), - /* 1100 */ V(1, 1, 4), - /* 1101 */ V(0, 1, 4), - /* 1110 */ V(1, 0, 4), - /* 1111 */ V(0, 0, 4), - - /* 0000 ... */ - /* 0000 */ V(14, 15, 4), /* 16 */ - /* 0001 */ V(15, 14, 4), - /* 0010 */ V(13, 15, 4), - /* 0011 */ V(15, 13, 4), - /* 0100 */ V(12, 15, 4), - /* 0101 */ V(15, 12, 4), - /* 0110 */ V(11, 15, 4), - /* 0111 */ V(15, 11, 4), - /* 1000 */ V(15, 10, 3), - /* 1001 */ V(15, 10, 3), - /* 1010 */ V(10, 15, 4), - /* 1011 */ V(9, 15, 4), - /* 1100 */ V(15, 9, 3), - /* 1101 */ V(15, 9, 3), - /* 1110 */ V(15, 8, 3), - /* 1111 */ V(15, 8, 3), - - /* 0001 ... */ - /* 0000 */ V(8, 15, 4), /* 32 */ - /* 0001 */ V(7, 15, 4), - /* 0010 */ V(15, 7, 3), - /* 0011 */ V(15, 7, 3), - /* 0100 */ V(6, 15, 3), - /* 0101 */ V(6, 15, 3), - /* 0110 */ V(15, 6, 3), - /* 0111 */ V(15, 6, 3), - /* 1000 */ V(5, 15, 3), - /* 1001 */ V(5, 15, 3), - /* 1010 */ V(15, 5, 3), - /* 1011 */ V(15, 5, 3), - /* 1100 */ V(4, 15, 3), - /* 1101 */ V(4, 15, 3), - /* 1110 */ V(15, 4, 3), - /* 1111 */ V(15, 4, 3), - - /* 0010 ... */ - /* 0000 */ V(3, 15, 3), /* 48 */ - /* 0001 */ V(3, 15, 3), - /* 0010 */ V(15, 3, 3), - /* 0011 */ V(15, 3, 3), - /* 0100 */ V(2, 15, 3), - /* 0101 */ V(2, 15, 3), - /* 0110 */ V(15, 2, 3), - /* 0111 */ V(15, 2, 3), - /* 1000 */ V(15, 1, 3), - /* 1001 */ V(15, 1, 3), - /* 1010 */ V(1, 15, 4), - /* 1011 */ V(15, 0, 4), - /* 1100 */ PTR(172, 3), - /* 1101 */ PTR(180, 3), - /* 1110 */ PTR(188, 3), - /* 1111 */ PTR(196, 3), - - /* 0100 ... */ - /* 0000 */ PTR(204, 4), /* 64 */ - /* 0001 */ PTR(220, 3), - /* 0010 */ PTR(228, 3), - /* 0011 */ PTR(236, 3), - /* 0100 */ PTR(244, 2), - /* 0101 */ PTR(248, 2), - /* 0110 */ PTR(252, 2), - /* 0111 */ PTR(256, 2), - /* 1000 */ PTR(260, 2), - /* 1001 */ PTR(264, 2), - /* 1010 */ PTR(268, 2), - /* 1011 */ PTR(272, 2), - /* 1100 */ PTR(276, 2), - /* 1101 */ PTR(280, 3), - /* 1110 */ PTR(288, 2), - /* 1111 */ PTR(292, 2), - - /* 0101 ... */ - /* 0000 */ PTR(296, 2), /* 80 */ - /* 0001 */ PTR(300, 3), - /* 0010 */ PTR(308, 2), - /* 0011 */ PTR(312, 3), - /* 0100 */ PTR(320, 1), - /* 0101 */ PTR(322, 2), - /* 0110 */ PTR(326, 2), - /* 0111 */ PTR(330, 1), - /* 1000 */ PTR(332, 2), - /* 1001 */ PTR(336, 1), - /* 1010 */ PTR(338, 1), - /* 1011 */ PTR(340, 1), - /* 1100 */ PTR(342, 1), - /* 1101 */ PTR(344, 1), - /* 1110 */ PTR(346, 1), - /* 1111 */ PTR(348, 1), - - /* 0110 ... */ - /* 0000 */ PTR(350, 1), /* 96 */ - /* 0001 */ PTR(352, 1), - /* 0010 */ PTR(354, 1), - /* 0011 */ PTR(356, 1), - /* 0100 */ PTR(358, 1), - /* 0101 */ PTR(360, 1), - /* 0110 */ PTR(362, 1), - /* 0111 */ PTR(364, 1), - /* 1000 */ PTR(366, 1), - /* 1001 */ PTR(368, 1), - /* 1010 */ PTR(370, 2), - /* 1011 */ PTR(374, 1), - /* 1100 */ PTR(376, 2), - /* 1101 */ V(7, 3, 4), - /* 1110 */ PTR(380, 1), - /* 1111 */ V(7, 2, 4), - - /* 0111 ... */ - /* 0000 */ V(4, 6, 4), /* 112 */ - /* 0001 */ V(6, 4, 4), - /* 0010 */ V(5, 5, 4), - /* 0011 */ V(7, 1, 4), - /* 0100 */ V(3, 6, 4), - /* 0101 */ V(6, 3, 4), - /* 0110 */ V(4, 5, 4), - /* 0111 */ V(5, 4, 4), - /* 1000 */ V(2, 6, 4), - /* 1001 */ V(6, 2, 4), - /* 1010 */ V(1, 6, 4), - /* 1011 */ V(6, 1, 4), - /* 1100 */ PTR(382, 1), - /* 1101 */ V(3, 5, 4), - /* 1110 */ V(5, 3, 4), - /* 1111 */ V(4, 4, 4), - - /* 1000 ... */ - /* 0000 */ V(2, 5, 4), /* 128 */ - /* 0001 */ V(5, 2, 4), - /* 0010 */ V(1, 5, 4), - /* 0011 */ PTR(384, 1), - /* 0100 */ V(5, 1, 3), - /* 0101 */ V(5, 1, 3), - /* 0110 */ V(3, 4, 4), - /* 0111 */ V(4, 3, 4), - /* 1000 */ V(2, 4, 3), - /* 1001 */ V(2, 4, 3), - /* 1010 */ V(4, 2, 3), - /* 1011 */ V(4, 2, 3), - /* 1100 */ V(3, 3, 3), - /* 1101 */ V(3, 3, 3), - /* 1110 */ V(1, 4, 3), - /* 1111 */ V(1, 4, 3), - - /* 1001 ... */ - /* 0000 */ V(4, 1, 3), /* 144 */ - /* 0001 */ V(4, 1, 3), - /* 0010 */ V(0, 4, 4), - /* 0011 */ V(4, 0, 4), - /* 0100 */ V(2, 3, 3), - /* 0101 */ V(2, 3, 3), - /* 0110 */ V(3, 2, 3), - /* 0111 */ V(3, 2, 3), - /* 1000 */ V(1, 3, 2), - /* 1001 */ V(1, 3, 2), - /* 1010 */ V(1, 3, 2), - /* 1011 */ V(1, 3, 2), - /* 1100 */ V(3, 1, 2), - /* 1101 */ V(3, 1, 2), - /* 1110 */ V(3, 1, 2), - /* 1111 */ V(3, 1, 2), - - /* 1010 ... */ - /* 000 */ V(0, 3, 3), /* 160 */ - /* 001 */ V(3, 0, 3), - /* 010 */ V(2, 2, 2), - /* 011 */ V(2, 2, 2), - /* 100 */ V(1, 2, 1), - /* 101 */ V(1, 2, 1), - /* 110 */ V(1, 2, 1), - /* 111 */ V(1, 2, 1), - - /* 1011 ... */ - /* 00 */ V(2, 1, 1), /* 168 */ - /* 01 */ V(2, 1, 1), - /* 10 */ V(0, 2, 2), - /* 11 */ V(2, 0, 2), - - /* 0010 1100 ... */ - /* 000 */ V(0, 15, 1), /* 172 */ - /* 001 */ V(0, 15, 1), - /* 010 */ V(0, 15, 1), - /* 011 */ V(0, 15, 1), - /* 100 */ V(14, 14, 3), - /* 101 */ V(13, 14, 3), - /* 110 */ V(14, 13, 3), - /* 111 */ V(12, 14, 3), - - /* 0010 1101 ... */ - /* 000 */ V(14, 12, 3), /* 180 */ - /* 001 */ V(13, 13, 3), - /* 010 */ V(11, 14, 3), - /* 011 */ V(14, 11, 3), - /* 100 */ V(12, 13, 3), - /* 101 */ V(13, 12, 3), - /* 110 */ V(10, 14, 3), - /* 111 */ V(14, 10, 3), - - /* 0010 1110 ... */ - /* 000 */ V(11, 13, 3), /* 188 */ - /* 001 */ V(13, 11, 3), - /* 010 */ V(12, 12, 3), - /* 011 */ V(9, 14, 3), - /* 100 */ V(14, 9, 3), - /* 101 */ V(10, 13, 3), - /* 110 */ V(13, 10, 3), - /* 111 */ V(11, 12, 3), - - /* 0010 1111 ... */ - /* 000 */ V(12, 11, 3), /* 196 */ - /* 001 */ V(8, 14, 3), - /* 010 */ V(14, 8, 3), - /* 011 */ V(9, 13, 3), - /* 100 */ V(13, 9, 3), - /* 101 */ V(7, 14, 3), - /* 110 */ V(14, 7, 3), - /* 111 */ V(10, 12, 3), - - /* 0100 0000 ... */ - /* 0000 */ V(12, 10, 3), /* 204 */ - /* 0001 */ V(12, 10, 3), - /* 0010 */ V(11, 11, 3), - /* 0011 */ V(11, 11, 3), - /* 0100 */ V(8, 13, 3), - /* 0101 */ V(8, 13, 3), - /* 0110 */ V(13, 8, 3), - /* 0111 */ V(13, 8, 3), - /* 1000 */ V(0, 14, 4), - /* 1001 */ V(14, 0, 4), - /* 1010 */ V(0, 13, 3), - /* 1011 */ V(0, 13, 3), - /* 1100 */ V(14, 6, 2), - /* 1101 */ V(14, 6, 2), - /* 1110 */ V(14, 6, 2), - /* 1111 */ V(14, 6, 2), - - /* 0100 0001 ... */ - /* 000 */ V(6, 14, 3), /* 220 */ - /* 001 */ V(9, 12, 3), - /* 010 */ V(12, 9, 2), - /* 011 */ V(12, 9, 2), - /* 100 */ V(5, 14, 2), - /* 101 */ V(5, 14, 2), - /* 110 */ V(11, 10, 2), - /* 111 */ V(11, 10, 2), - - /* 0100 0010 ... */ - /* 000 */ V(14, 5, 2), /* 228 */ - /* 001 */ V(14, 5, 2), - /* 010 */ V(10, 11, 3), - /* 011 */ V(7, 13, 3), - /* 100 */ V(13, 7, 2), - /* 101 */ V(13, 7, 2), - /* 110 */ V(14, 4, 2), - /* 111 */ V(14, 4, 2), - - /* 0100 0011 ... */ - /* 000 */ V(8, 12, 2), /* 236 */ - /* 001 */ V(8, 12, 2), - /* 010 */ V(12, 8, 2), - /* 011 */ V(12, 8, 2), - /* 100 */ V(4, 14, 3), - /* 101 */ V(2, 14, 3), - /* 110 */ V(3, 14, 2), - /* 111 */ V(3, 14, 2), - - /* 0100 0100 ... */ - /* 00 */ V(6, 13, 2), /* 244 */ - /* 01 */ V(13, 6, 2), - /* 10 */ V(14, 3, 2), - /* 11 */ V(9, 11, 2), - - /* 0100 0101 ... */ - /* 00 */ V(11, 9, 2), /* 248 */ - /* 01 */ V(10, 10, 2), - /* 10 */ V(14, 2, 2), - /* 11 */ V(1, 14, 2), - - /* 0100 0110 ... */ - /* 00 */ V(14, 1, 2), /* 252 */ - /* 01 */ V(5, 13, 2), - /* 10 */ V(13, 5, 2), - /* 11 */ V(7, 12, 2), - - /* 0100 0111 ... */ - /* 00 */ V(12, 7, 2), /* 256 */ - /* 01 */ V(4, 13, 2), - /* 10 */ V(8, 11, 2), - /* 11 */ V(11, 8, 2), - - /* 0100 1000 ... */ - /* 00 */ V(13, 4, 2), /* 260 */ - /* 01 */ V(9, 10, 2), - /* 10 */ V(10, 9, 2), - /* 11 */ V(6, 12, 2), - - /* 0100 1001 ... */ - /* 00 */ V(12, 6, 2), /* 264 */ - /* 01 */ V(3, 13, 2), - /* 10 */ V(13, 3, 2), - /* 11 */ V(2, 13, 2), - - /* 0100 1010 ... */ - /* 00 */ V(13, 2, 2), /* 268 */ - /* 01 */ V(1, 13, 2), - /* 10 */ V(7, 11, 2), - /* 11 */ V(11, 7, 2), - - /* 0100 1011 ... */ - /* 00 */ V(13, 1, 2), /* 272 */ - /* 01 */ V(5, 12, 2), - /* 10 */ V(12, 5, 2), - /* 11 */ V(8, 10, 2), - - /* 0100 1100 ... */ - /* 00 */ V(10, 8, 2), /* 276 */ - /* 01 */ V(9, 9, 2), - /* 10 */ V(4, 12, 2), - /* 11 */ V(12, 4, 2), - - /* 0100 1101 ... */ - /* 000 */ V(6, 11, 2), /* 280 */ - /* 001 */ V(6, 11, 2), - /* 010 */ V(11, 6, 2), - /* 011 */ V(11, 6, 2), - /* 100 */ V(13, 0, 3), - /* 101 */ V(0, 12, 3), - /* 110 */ V(3, 12, 2), - /* 111 */ V(3, 12, 2), - - /* 0100 1110 ... */ - /* 00 */ V(12, 3, 2), /* 288 */ - /* 01 */ V(7, 10, 2), - /* 10 */ V(10, 7, 2), - /* 11 */ V(2, 12, 2), - - /* 0100 1111 ... */ - /* 00 */ V(12, 2, 2), /* 292 */ - /* 01 */ V(5, 11, 2), - /* 10 */ V(11, 5, 2), - /* 11 */ V(1, 12, 2), - - /* 0101 0000 ... */ - /* 00 */ V(8, 9, 2), /* 296 */ - /* 01 */ V(9, 8, 2), - /* 10 */ V(12, 1, 2), - /* 11 */ V(4, 11, 2), - - /* 0101 0001 ... */ - /* 000 */ V(12, 0, 3), /* 300 */ - /* 001 */ V(0, 11, 3), - /* 010 */ V(3, 11, 2), - /* 011 */ V(3, 11, 2), - /* 100 */ V(11, 0, 3), - /* 101 */ V(0, 10, 3), - /* 110 */ V(1, 10, 2), - /* 111 */ V(1, 10, 2), - - /* 0101 0010 ... */ - /* 00 */ V(11, 4, 1), /* 308 */ - /* 01 */ V(11, 4, 1), - /* 10 */ V(6, 10, 2), - /* 11 */ V(10, 6, 2), - - /* 0101 0011 ... */ - /* 000 */ V(7, 9, 2), /* 312 */ - /* 001 */ V(7, 9, 2), - /* 010 */ V(9, 7, 2), - /* 011 */ V(9, 7, 2), - /* 100 */ V(10, 0, 3), - /* 101 */ V(0, 9, 3), - /* 110 */ V(9, 0, 2), - /* 111 */ V(9, 0, 2), - - /* 0101 0100 ... */ - /* 0 */ V(11, 3, 1), /* 320 */ - /* 1 */ V(8, 8, 1), - - /* 0101 0101 ... */ - /* 00 */ V(2, 11, 2), /* 322 */ - /* 01 */ V(5, 10, 2), - /* 10 */ V(11, 2, 1), - /* 11 */ V(11, 2, 1), - - /* 0101 0110 ... */ - /* 00 */ V(10, 5, 2), /* 326 */ - /* 01 */ V(1, 11, 2), - /* 10 */ V(11, 1, 2), - /* 11 */ V(6, 9, 2), - - /* 0101 0111 ... */ - /* 0 */ V(9, 6, 1), /* 330 */ - /* 1 */ V(10, 4, 1), - - /* 0101 1000 ... */ - /* 00 */ V(4, 10, 2), /* 332 */ - /* 01 */ V(7, 8, 2), - /* 10 */ V(8, 7, 1), - /* 11 */ V(8, 7, 1), - - /* 0101 1001 ... */ - /* 0 */ V(3, 10, 1), /* 336 */ - /* 1 */ V(10, 3, 1), - - /* 0101 1010 ... */ - /* 0 */ V(5, 9, 1), /* 338 */ - /* 1 */ V(9, 5, 1), - - /* 0101 1011 ... */ - /* 0 */ V(2, 10, 1), /* 340 */ - /* 1 */ V(10, 2, 1), - - /* 0101 1100 ... */ - /* 0 */ V(10, 1, 1), /* 342 */ - /* 1 */ V(6, 8, 1), - - /* 0101 1101 ... */ - /* 0 */ V(8, 6, 1), /* 344 */ - /* 1 */ V(7, 7, 1), - - /* 0101 1110 ... */ - /* 0 */ V(4, 9, 1), /* 346 */ - /* 1 */ V(9, 4, 1), - - /* 0101 1111 ... */ - /* 0 */ V(3, 9, 1), /* 348 */ - /* 1 */ V(9, 3, 1), - - /* 0110 0000 ... */ - /* 0 */ V(5, 8, 1), /* 350 */ - /* 1 */ V(8, 5, 1), - - /* 0110 0001 ... */ - /* 0 */ V(2, 9, 1), /* 352 */ - /* 1 */ V(6, 7, 1), - - /* 0110 0010 ... */ - /* 0 */ V(7, 6, 1), /* 354 */ - /* 1 */ V(9, 2, 1), - - /* 0110 0011 ... */ - /* 0 */ V(1, 9, 1), /* 356 */ - /* 1 */ V(9, 1, 1), - - /* 0110 0100 ... */ - /* 0 */ V(4, 8, 1), /* 358 */ - /* 1 */ V(8, 4, 1), - - /* 0110 0101 ... */ - /* 0 */ V(5, 7, 1), /* 360 */ - /* 1 */ V(7, 5, 1), - - /* 0110 0110 ... */ - /* 0 */ V(3, 8, 1), /* 362 */ - /* 1 */ V(8, 3, 1), - - /* 0110 0111 ... */ - /* 0 */ V(6, 6, 1), /* 364 */ - /* 1 */ V(2, 8, 1), - - /* 0110 1000 ... */ - /* 0 */ V(8, 2, 1), /* 366 */ - /* 1 */ V(1, 8, 1), - - /* 0110 1001 ... */ - /* 0 */ V(4, 7, 1), /* 368 */ - /* 1 */ V(7, 4, 1), - - /* 0110 1010 ... */ - /* 00 */ V(8, 1, 1), /* 370 */ - /* 01 */ V(8, 1, 1), - /* 10 */ V(0, 8, 2), - /* 11 */ V(8, 0, 2), - - /* 0110 1011 ... */ - /* 0 */ V(5, 6, 1), /* 374 */ - /* 1 */ V(6, 5, 1), - - /* 0110 1100 ... */ - /* 00 */ V(1, 7, 1), /* 376 */ - /* 01 */ V(1, 7, 1), - /* 10 */ V(0, 7, 2), - /* 11 */ V(7, 0, 2), - - /* 0110 1110 ... */ - /* 0 */ V(3, 7, 1), /* 380 */ - /* 1 */ V(2, 7, 1), - - /* 0111 1100 ... */ - /* 0 */ V(0, 6, 1), /* 382 */ - /* 1 */ V(6, 0, 1), - - /* 1000 0011 ... */ - /* 0 */ V(0, 5, 1), /* 384 */ - /* 1 */ V(5, 0, 1) + /* 0000 */ PTR(16, 4), + /* 0001 */ PTR(32, 4), + /* 0010 */ PTR(48, 4), + /* 0011 */ V(15, 15, 4), + /* 0100 */ PTR(64, 4), + /* 0101 */ PTR(80, 4), + /* 0110 */ PTR(96, 4), + /* 0111 */ PTR(112, 4), + /* 1000 */ PTR(128, 4), + /* 1001 */ PTR(144, 4), + /* 1010 */ PTR(160, 3), + /* 1011 */ PTR(168, 2), + /* 1100 */ V(1, 1, 4), + /* 1101 */ V(0, 1, 4), + /* 1110 */ V(1, 0, 4), + /* 1111 */ V(0, 0, 4), + + /* 0000 ... */ + /* 0000 */ V(14, 15, 4), /* 16 */ + /* 0001 */ V(15, 14, 4), + /* 0010 */ V(13, 15, 4), + /* 0011 */ V(15, 13, 4), + /* 0100 */ V(12, 15, 4), + /* 0101 */ V(15, 12, 4), + /* 0110 */ V(11, 15, 4), + /* 0111 */ V(15, 11, 4), + /* 1000 */ V(15, 10, 3), + /* 1001 */ V(15, 10, 3), + /* 1010 */ V(10, 15, 4), + /* 1011 */ V(9, 15, 4), + /* 1100 */ V(15, 9, 3), + /* 1101 */ V(15, 9, 3), + /* 1110 */ V(15, 8, 3), + /* 1111 */ V(15, 8, 3), + + /* 0001 ... */ + /* 0000 */ V(8, 15, 4), /* 32 */ + /* 0001 */ V(7, 15, 4), + /* 0010 */ V(15, 7, 3), + /* 0011 */ V(15, 7, 3), + /* 0100 */ V(6, 15, 3), + /* 0101 */ V(6, 15, 3), + /* 0110 */ V(15, 6, 3), + /* 0111 */ V(15, 6, 3), + /* 1000 */ V(5, 15, 3), + /* 1001 */ V(5, 15, 3), + /* 1010 */ V(15, 5, 3), + /* 1011 */ V(15, 5, 3), + /* 1100 */ V(4, 15, 3), + /* 1101 */ V(4, 15, 3), + /* 1110 */ V(15, 4, 3), + /* 1111 */ V(15, 4, 3), + + /* 0010 ... */ + /* 0000 */ V(3, 15, 3), /* 48 */ + /* 0001 */ V(3, 15, 3), + /* 0010 */ V(15, 3, 3), + /* 0011 */ V(15, 3, 3), + /* 0100 */ V(2, 15, 3), + /* 0101 */ V(2, 15, 3), + /* 0110 */ V(15, 2, 3), + /* 0111 */ V(15, 2, 3), + /* 1000 */ V(15, 1, 3), + /* 1001 */ V(15, 1, 3), + /* 1010 */ V(1, 15, 4), + /* 1011 */ V(15, 0, 4), + /* 1100 */ PTR(172, 3), + /* 1101 */ PTR(180, 3), + /* 1110 */ PTR(188, 3), + /* 1111 */ PTR(196, 3), + + /* 0100 ... */ + /* 0000 */ PTR(204, 4), /* 64 */ + /* 0001 */ PTR(220, 3), + /* 0010 */ PTR(228, 3), + /* 0011 */ PTR(236, 3), + /* 0100 */ PTR(244, 2), + /* 0101 */ PTR(248, 2), + /* 0110 */ PTR(252, 2), + /* 0111 */ PTR(256, 2), + /* 1000 */ PTR(260, 2), + /* 1001 */ PTR(264, 2), + /* 1010 */ PTR(268, 2), + /* 1011 */ PTR(272, 2), + /* 1100 */ PTR(276, 2), + /* 1101 */ PTR(280, 3), + /* 1110 */ PTR(288, 2), + /* 1111 */ PTR(292, 2), + + /* 0101 ... */ + /* 0000 */ PTR(296, 2), /* 80 */ + /* 0001 */ PTR(300, 3), + /* 0010 */ PTR(308, 2), + /* 0011 */ PTR(312, 3), + /* 0100 */ PTR(320, 1), + /* 0101 */ PTR(322, 2), + /* 0110 */ PTR(326, 2), + /* 0111 */ PTR(330, 1), + /* 1000 */ PTR(332, 2), + /* 1001 */ PTR(336, 1), + /* 1010 */ PTR(338, 1), + /* 1011 */ PTR(340, 1), + /* 1100 */ PTR(342, 1), + /* 1101 */ PTR(344, 1), + /* 1110 */ PTR(346, 1), + /* 1111 */ PTR(348, 1), + + /* 0110 ... */ + /* 0000 */ PTR(350, 1), /* 96 */ + /* 0001 */ PTR(352, 1), + /* 0010 */ PTR(354, 1), + /* 0011 */ PTR(356, 1), + /* 0100 */ PTR(358, 1), + /* 0101 */ PTR(360, 1), + /* 0110 */ PTR(362, 1), + /* 0111 */ PTR(364, 1), + /* 1000 */ PTR(366, 1), + /* 1001 */ PTR(368, 1), + /* 1010 */ PTR(370, 2), + /* 1011 */ PTR(374, 1), + /* 1100 */ PTR(376, 2), + /* 1101 */ V(7, 3, 4), + /* 1110 */ PTR(380, 1), + /* 1111 */ V(7, 2, 4), + + /* 0111 ... */ + /* 0000 */ V(4, 6, 4), /* 112 */ + /* 0001 */ V(6, 4, 4), + /* 0010 */ V(5, 5, 4), + /* 0011 */ V(7, 1, 4), + /* 0100 */ V(3, 6, 4), + /* 0101 */ V(6, 3, 4), + /* 0110 */ V(4, 5, 4), + /* 0111 */ V(5, 4, 4), + /* 1000 */ V(2, 6, 4), + /* 1001 */ V(6, 2, 4), + /* 1010 */ V(1, 6, 4), + /* 1011 */ V(6, 1, 4), + /* 1100 */ PTR(382, 1), + /* 1101 */ V(3, 5, 4), + /* 1110 */ V(5, 3, 4), + /* 1111 */ V(4, 4, 4), + + /* 1000 ... */ + /* 0000 */ V(2, 5, 4), /* 128 */ + /* 0001 */ V(5, 2, 4), + /* 0010 */ V(1, 5, 4), + /* 0011 */ PTR(384, 1), + /* 0100 */ V(5, 1, 3), + /* 0101 */ V(5, 1, 3), + /* 0110 */ V(3, 4, 4), + /* 0111 */ V(4, 3, 4), + /* 1000 */ V(2, 4, 3), + /* 1001 */ V(2, 4, 3), + /* 1010 */ V(4, 2, 3), + /* 1011 */ V(4, 2, 3), + /* 1100 */ V(3, 3, 3), + /* 1101 */ V(3, 3, 3), + /* 1110 */ V(1, 4, 3), + /* 1111 */ V(1, 4, 3), + + /* 1001 ... */ + /* 0000 */ V(4, 1, 3), /* 144 */ + /* 0001 */ V(4, 1, 3), + /* 0010 */ V(0, 4, 4), + /* 0011 */ V(4, 0, 4), + /* 0100 */ V(2, 3, 3), + /* 0101 */ V(2, 3, 3), + /* 0110 */ V(3, 2, 3), + /* 0111 */ V(3, 2, 3), + /* 1000 */ V(1, 3, 2), + /* 1001 */ V(1, 3, 2), + /* 1010 */ V(1, 3, 2), + /* 1011 */ V(1, 3, 2), + /* 1100 */ V(3, 1, 2), + /* 1101 */ V(3, 1, 2), + /* 1110 */ V(3, 1, 2), + /* 1111 */ V(3, 1, 2), + + /* 1010 ... */ + /* 000 */ V(0, 3, 3), /* 160 */ + /* 001 */ V(3, 0, 3), + /* 010 */ V(2, 2, 2), + /* 011 */ V(2, 2, 2), + /* 100 */ V(1, 2, 1), + /* 101 */ V(1, 2, 1), + /* 110 */ V(1, 2, 1), + /* 111 */ V(1, 2, 1), + + /* 1011 ... */ + /* 00 */ V(2, 1, 1), /* 168 */ + /* 01 */ V(2, 1, 1), + /* 10 */ V(0, 2, 2), + /* 11 */ V(2, 0, 2), + + /* 0010 1100 ... */ + /* 000 */ V(0, 15, 1), /* 172 */ + /* 001 */ V(0, 15, 1), + /* 010 */ V(0, 15, 1), + /* 011 */ V(0, 15, 1), + /* 100 */ V(14, 14, 3), + /* 101 */ V(13, 14, 3), + /* 110 */ V(14, 13, 3), + /* 111 */ V(12, 14, 3), + + /* 0010 1101 ... */ + /* 000 */ V(14, 12, 3), /* 180 */ + /* 001 */ V(13, 13, 3), + /* 010 */ V(11, 14, 3), + /* 011 */ V(14, 11, 3), + /* 100 */ V(12, 13, 3), + /* 101 */ V(13, 12, 3), + /* 110 */ V(10, 14, 3), + /* 111 */ V(14, 10, 3), + + /* 0010 1110 ... */ + /* 000 */ V(11, 13, 3), /* 188 */ + /* 001 */ V(13, 11, 3), + /* 010 */ V(12, 12, 3), + /* 011 */ V(9, 14, 3), + /* 100 */ V(14, 9, 3), + /* 101 */ V(10, 13, 3), + /* 110 */ V(13, 10, 3), + /* 111 */ V(11, 12, 3), + + /* 0010 1111 ... */ + /* 000 */ V(12, 11, 3), /* 196 */ + /* 001 */ V(8, 14, 3), + /* 010 */ V(14, 8, 3), + /* 011 */ V(9, 13, 3), + /* 100 */ V(13, 9, 3), + /* 101 */ V(7, 14, 3), + /* 110 */ V(14, 7, 3), + /* 111 */ V(10, 12, 3), + + /* 0100 0000 ... */ + /* 0000 */ V(12, 10, 3), /* 204 */ + /* 0001 */ V(12, 10, 3), + /* 0010 */ V(11, 11, 3), + /* 0011 */ V(11, 11, 3), + /* 0100 */ V(8, 13, 3), + /* 0101 */ V(8, 13, 3), + /* 0110 */ V(13, 8, 3), + /* 0111 */ V(13, 8, 3), + /* 1000 */ V(0, 14, 4), + /* 1001 */ V(14, 0, 4), + /* 1010 */ V(0, 13, 3), + /* 1011 */ V(0, 13, 3), + /* 1100 */ V(14, 6, 2), + /* 1101 */ V(14, 6, 2), + /* 1110 */ V(14, 6, 2), + /* 1111 */ V(14, 6, 2), + + /* 0100 0001 ... */ + /* 000 */ V(6, 14, 3), /* 220 */ + /* 001 */ V(9, 12, 3), + /* 010 */ V(12, 9, 2), + /* 011 */ V(12, 9, 2), + /* 100 */ V(5, 14, 2), + /* 101 */ V(5, 14, 2), + /* 110 */ V(11, 10, 2), + /* 111 */ V(11, 10, 2), + + /* 0100 0010 ... */ + /* 000 */ V(14, 5, 2), /* 228 */ + /* 001 */ V(14, 5, 2), + /* 010 */ V(10, 11, 3), + /* 011 */ V(7, 13, 3), + /* 100 */ V(13, 7, 2), + /* 101 */ V(13, 7, 2), + /* 110 */ V(14, 4, 2), + /* 111 */ V(14, 4, 2), + + /* 0100 0011 ... */ + /* 000 */ V(8, 12, 2), /* 236 */ + /* 001 */ V(8, 12, 2), + /* 010 */ V(12, 8, 2), + /* 011 */ V(12, 8, 2), + /* 100 */ V(4, 14, 3), + /* 101 */ V(2, 14, 3), + /* 110 */ V(3, 14, 2), + /* 111 */ V(3, 14, 2), + + /* 0100 0100 ... */ + /* 00 */ V(6, 13, 2), /* 244 */ + /* 01 */ V(13, 6, 2), + /* 10 */ V(14, 3, 2), + /* 11 */ V(9, 11, 2), + + /* 0100 0101 ... */ + /* 00 */ V(11, 9, 2), /* 248 */ + /* 01 */ V(10, 10, 2), + /* 10 */ V(14, 2, 2), + /* 11 */ V(1, 14, 2), + + /* 0100 0110 ... */ + /* 00 */ V(14, 1, 2), /* 252 */ + /* 01 */ V(5, 13, 2), + /* 10 */ V(13, 5, 2), + /* 11 */ V(7, 12, 2), + + /* 0100 0111 ... */ + /* 00 */ V(12, 7, 2), /* 256 */ + /* 01 */ V(4, 13, 2), + /* 10 */ V(8, 11, 2), + /* 11 */ V(11, 8, 2), + + /* 0100 1000 ... */ + /* 00 */ V(13, 4, 2), /* 260 */ + /* 01 */ V(9, 10, 2), + /* 10 */ V(10, 9, 2), + /* 11 */ V(6, 12, 2), + + /* 0100 1001 ... */ + /* 00 */ V(12, 6, 2), /* 264 */ + /* 01 */ V(3, 13, 2), + /* 10 */ V(13, 3, 2), + /* 11 */ V(2, 13, 2), + + /* 0100 1010 ... */ + /* 00 */ V(13, 2, 2), /* 268 */ + /* 01 */ V(1, 13, 2), + /* 10 */ V(7, 11, 2), + /* 11 */ V(11, 7, 2), + + /* 0100 1011 ... */ + /* 00 */ V(13, 1, 2), /* 272 */ + /* 01 */ V(5, 12, 2), + /* 10 */ V(12, 5, 2), + /* 11 */ V(8, 10, 2), + + /* 0100 1100 ... */ + /* 00 */ V(10, 8, 2), /* 276 */ + /* 01 */ V(9, 9, 2), + /* 10 */ V(4, 12, 2), + /* 11 */ V(12, 4, 2), + + /* 0100 1101 ... */ + /* 000 */ V(6, 11, 2), /* 280 */ + /* 001 */ V(6, 11, 2), + /* 010 */ V(11, 6, 2), + /* 011 */ V(11, 6, 2), + /* 100 */ V(13, 0, 3), + /* 101 */ V(0, 12, 3), + /* 110 */ V(3, 12, 2), + /* 111 */ V(3, 12, 2), + + /* 0100 1110 ... */ + /* 00 */ V(12, 3, 2), /* 288 */ + /* 01 */ V(7, 10, 2), + /* 10 */ V(10, 7, 2), + /* 11 */ V(2, 12, 2), + + /* 0100 1111 ... */ + /* 00 */ V(12, 2, 2), /* 292 */ + /* 01 */ V(5, 11, 2), + /* 10 */ V(11, 5, 2), + /* 11 */ V(1, 12, 2), + + /* 0101 0000 ... */ + /* 00 */ V(8, 9, 2), /* 296 */ + /* 01 */ V(9, 8, 2), + /* 10 */ V(12, 1, 2), + /* 11 */ V(4, 11, 2), + + /* 0101 0001 ... */ + /* 000 */ V(12, 0, 3), /* 300 */ + /* 001 */ V(0, 11, 3), + /* 010 */ V(3, 11, 2), + /* 011 */ V(3, 11, 2), + /* 100 */ V(11, 0, 3), + /* 101 */ V(0, 10, 3), + /* 110 */ V(1, 10, 2), + /* 111 */ V(1, 10, 2), + + /* 0101 0010 ... */ + /* 00 */ V(11, 4, 1), /* 308 */ + /* 01 */ V(11, 4, 1), + /* 10 */ V(6, 10, 2), + /* 11 */ V(10, 6, 2), + + /* 0101 0011 ... */ + /* 000 */ V(7, 9, 2), /* 312 */ + /* 001 */ V(7, 9, 2), + /* 010 */ V(9, 7, 2), + /* 011 */ V(9, 7, 2), + /* 100 */ V(10, 0, 3), + /* 101 */ V(0, 9, 3), + /* 110 */ V(9, 0, 2), + /* 111 */ V(9, 0, 2), + + /* 0101 0100 ... */ + /* 0 */ V(11, 3, 1), /* 320 */ + /* 1 */ V(8, 8, 1), + + /* 0101 0101 ... */ + /* 00 */ V(2, 11, 2), /* 322 */ + /* 01 */ V(5, 10, 2), + /* 10 */ V(11, 2, 1), + /* 11 */ V(11, 2, 1), + + /* 0101 0110 ... */ + /* 00 */ V(10, 5, 2), /* 326 */ + /* 01 */ V(1, 11, 2), + /* 10 */ V(11, 1, 2), + /* 11 */ V(6, 9, 2), + + /* 0101 0111 ... */ + /* 0 */ V(9, 6, 1), /* 330 */ + /* 1 */ V(10, 4, 1), + + /* 0101 1000 ... */ + /* 00 */ V(4, 10, 2), /* 332 */ + /* 01 */ V(7, 8, 2), + /* 10 */ V(8, 7, 1), + /* 11 */ V(8, 7, 1), + + /* 0101 1001 ... */ + /* 0 */ V(3, 10, 1), /* 336 */ + /* 1 */ V(10, 3, 1), + + /* 0101 1010 ... */ + /* 0 */ V(5, 9, 1), /* 338 */ + /* 1 */ V(9, 5, 1), + + /* 0101 1011 ... */ + /* 0 */ V(2, 10, 1), /* 340 */ + /* 1 */ V(10, 2, 1), + + /* 0101 1100 ... */ + /* 0 */ V(10, 1, 1), /* 342 */ + /* 1 */ V(6, 8, 1), + + /* 0101 1101 ... */ + /* 0 */ V(8, 6, 1), /* 344 */ + /* 1 */ V(7, 7, 1), + + /* 0101 1110 ... */ + /* 0 */ V(4, 9, 1), /* 346 */ + /* 1 */ V(9, 4, 1), + + /* 0101 1111 ... */ + /* 0 */ V(3, 9, 1), /* 348 */ + /* 1 */ V(9, 3, 1), + + /* 0110 0000 ... */ + /* 0 */ V(5, 8, 1), /* 350 */ + /* 1 */ V(8, 5, 1), + + /* 0110 0001 ... */ + /* 0 */ V(2, 9, 1), /* 352 */ + /* 1 */ V(6, 7, 1), + + /* 0110 0010 ... */ + /* 0 */ V(7, 6, 1), /* 354 */ + /* 1 */ V(9, 2, 1), + + /* 0110 0011 ... */ + /* 0 */ V(1, 9, 1), /* 356 */ + /* 1 */ V(9, 1, 1), + + /* 0110 0100 ... */ + /* 0 */ V(4, 8, 1), /* 358 */ + /* 1 */ V(8, 4, 1), + + /* 0110 0101 ... */ + /* 0 */ V(5, 7, 1), /* 360 */ + /* 1 */ V(7, 5, 1), + + /* 0110 0110 ... */ + /* 0 */ V(3, 8, 1), /* 362 */ + /* 1 */ V(8, 3, 1), + + /* 0110 0111 ... */ + /* 0 */ V(6, 6, 1), /* 364 */ + /* 1 */ V(2, 8, 1), + + /* 0110 1000 ... */ + /* 0 */ V(8, 2, 1), /* 366 */ + /* 1 */ V(1, 8, 1), + + /* 0110 1001 ... */ + /* 0 */ V(4, 7, 1), /* 368 */ + /* 1 */ V(7, 4, 1), + + /* 0110 1010 ... */ + /* 00 */ V(8, 1, 1), /* 370 */ + /* 01 */ V(8, 1, 1), + /* 10 */ V(0, 8, 2), + /* 11 */ V(8, 0, 2), + + /* 0110 1011 ... */ + /* 0 */ V(5, 6, 1), /* 374 */ + /* 1 */ V(6, 5, 1), + + /* 0110 1100 ... */ + /* 00 */ V(1, 7, 1), /* 376 */ + /* 01 */ V(1, 7, 1), + /* 10 */ V(0, 7, 2), + /* 11 */ V(7, 0, 2), + + /* 0110 1110 ... */ + /* 0 */ V(3, 7, 1), /* 380 */ + /* 1 */ V(2, 7, 1), + + /* 0111 1100 ... */ + /* 0 */ V(0, 6, 1), /* 382 */ + /* 1 */ V(6, 0, 1), + + /* 1000 0011 ... */ + /* 0 */ V(0, 5, 1), /* 384 */ + /* 1 */ V(5, 0, 1) }; # undef V @@ -3075,36 +3075,36 @@ union huffpair const hufftab24[] PROGMEM = { union huffquad const *const mad_huff_quad_table[2] PROGMEM = { hufftabA, hufftabB }; struct hufftable const mad_huff_pair_table[32] PROGMEM = { - /* 0 */ { hufftab0, 0, 0 }, - /* 1 */ { hufftab1, 0, 3 }, - /* 2 */ { hufftab2, 0, 3 }, - /* 3 */ { hufftab3, 0, 3 }, - /* 4 */ { 0 /* not used */ }, - /* 5 */ { hufftab5, 0, 3 }, - /* 6 */ { hufftab6, 0, 4 }, - /* 7 */ { hufftab7, 0, 4 }, - /* 8 */ { hufftab8, 0, 4 }, - /* 9 */ { hufftab9, 0, 4 }, - /* 10 */ { hufftab10, 0, 4 }, - /* 11 */ { hufftab11, 0, 4 }, - /* 12 */ { hufftab12, 0, 4 }, - /* 13 */ { hufftab13, 0, 4 }, - /* 14 */ { 0 /* not used */ }, - /* 15 */ { hufftab15, 0, 4 }, - /* 16 */ { hufftab16, 1, 4 }, - /* 17 */ { hufftab16, 2, 4 }, - /* 18 */ { hufftab16, 3, 4 }, - /* 19 */ { hufftab16, 4, 4 }, - /* 20 */ { hufftab16, 6, 4 }, - /* 21 */ { hufftab16, 8, 4 }, - /* 22 */ { hufftab16, 10, 4 }, - /* 23 */ { hufftab16, 13, 4 }, - /* 24 */ { hufftab24, 4, 4 }, - /* 25 */ { hufftab24, 5, 4 }, - /* 26 */ { hufftab24, 6, 4 }, - /* 27 */ { hufftab24, 7, 4 }, - /* 28 */ { hufftab24, 8, 4 }, - /* 29 */ { hufftab24, 9, 4 }, - /* 30 */ { hufftab24, 11, 4 }, - /* 31 */ { hufftab24, 13, 4 } + /* 0 */ { hufftab0, 0, 0 }, + /* 1 */ { hufftab1, 0, 3 }, + /* 2 */ { hufftab2, 0, 3 }, + /* 3 */ { hufftab3, 0, 3 }, + /* 4 */ { 0 /* not used */ }, + /* 5 */ { hufftab5, 0, 3 }, + /* 6 */ { hufftab6, 0, 4 }, + /* 7 */ { hufftab7, 0, 4 }, + /* 8 */ { hufftab8, 0, 4 }, + /* 9 */ { hufftab9, 0, 4 }, + /* 10 */ { hufftab10, 0, 4 }, + /* 11 */ { hufftab11, 0, 4 }, + /* 12 */ { hufftab12, 0, 4 }, + /* 13 */ { hufftab13, 0, 4 }, + /* 14 */ { 0 /* not used */ }, + /* 15 */ { hufftab15, 0, 4 }, + /* 16 */ { hufftab16, 1, 4 }, + /* 17 */ { hufftab16, 2, 4 }, + /* 18 */ { hufftab16, 3, 4 }, + /* 19 */ { hufftab16, 4, 4 }, + /* 20 */ { hufftab16, 6, 4 }, + /* 21 */ { hufftab16, 8, 4 }, + /* 22 */ { hufftab16, 10, 4 }, + /* 23 */ { hufftab16, 13, 4 }, + /* 24 */ { hufftab24, 4, 4 }, + /* 25 */ { hufftab24, 5, 4 }, + /* 26 */ { hufftab24, 6, 4 }, + /* 27 */ { hufftab24, 7, 4 }, + /* 28 */ { hufftab24, 8, 4 }, + /* 29 */ { hufftab24, 9, 4 }, + /* 30 */ { hufftab24, 11, 4 }, + /* 31 */ { hufftab24, 13, 4 } }; diff --git a/src/libmad/huffman.h b/src/libmad/huffman.h index 5d3862e6..725ff91b 100644 --- a/src/libmad/huffman.h +++ b/src/libmad/huffman.h @@ -1,23 +1,23 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: huffman.h,v 1.11 2004/01/23 09:41:32 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: huffman.h,v 1.11 2004/01/23 09:41:32 rob Exp $ +*/ # ifndef LIBMAD_HUFFMAN_H # define LIBMAD_HUFFMAN_H @@ -26,41 +26,41 @@ // for easy direct access w/o any helper functions when placed in PROGMEM union huffquad { - struct { - unsigned int final; - unsigned int bits; - unsigned int offset; - } ptr; - struct { - unsigned int final; - unsigned int hlen; - unsigned int v; - unsigned int w; - unsigned int x; - unsigned int y; - } value; - unsigned int final ; + struct { + unsigned int final; + unsigned int bits; + unsigned int offset; + } ptr; + struct { + unsigned int final; + unsigned int hlen; + unsigned int v; + unsigned int w; + unsigned int x; + unsigned int y; + } value; + unsigned int final ; }; union huffpair { - struct { - unsigned int final; - unsigned int bits; - unsigned int offset; - } ptr; - struct { + struct { + unsigned int final; + unsigned int bits; + unsigned int offset; + } ptr; + struct { + unsigned int final; + unsigned int hlen; + unsigned int x; + unsigned int y; + } value; unsigned int final; - unsigned int hlen; - unsigned int x; - unsigned int y; - } value; - unsigned int final; }; struct hufftable { - union huffpair const *table; - unsigned int linbits; - unsigned int startbits; + union huffpair const *table; + unsigned int linbits; + unsigned int startbits; }; extern union huffquad const *const mad_huff_quad_table[2]; diff --git a/src/libmad/imdct_s.dat.h b/src/libmad/imdct_s.dat.h index 476710ea..4e18ec7b 100644 --- a/src/libmad/imdct_s.dat.h +++ b/src/libmad/imdct_s.dat.h @@ -1,62 +1,68 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: imdct_s.dat,v 1.8 2004/01/23 09:41:32 rob Exp $ - */ - - /* 0 */ { MAD_F(0x09bd7ca0) /* 0.608761429 */, - -MAD_F(0x0ec835e8) /* -0.923879533 */, - -MAD_F(0x0216a2a2) /* -0.130526192 */, - MAD_F(0x0fdcf549) /* 0.991444861 */, - -MAD_F(0x061f78aa) /* -0.382683432 */, - -MAD_F(0x0cb19346) /* -0.793353340 */ }, - - /* 6 */ { -MAD_F(0x0cb19346) /* -0.793353340 */, - MAD_F(0x061f78aa) /* 0.382683432 */, - MAD_F(0x0fdcf549) /* 0.991444861 */, - MAD_F(0x0216a2a2) /* 0.130526192 */, - -MAD_F(0x0ec835e8) /* -0.923879533 */, - -MAD_F(0x09bd7ca0) /* -0.608761429 */ }, - - /* 1 */ { MAD_F(0x061f78aa) /* 0.382683432 */, - -MAD_F(0x0ec835e8) /* -0.923879533 */, - MAD_F(0x0ec835e8) /* 0.923879533 */, - -MAD_F(0x061f78aa) /* -0.382683432 */, - -MAD_F(0x061f78aa) /* -0.382683432 */, - MAD_F(0x0ec835e8) /* 0.923879533 */ }, - - /* 7 */ { -MAD_F(0x0ec835e8) /* -0.923879533 */, - -MAD_F(0x061f78aa) /* -0.382683432 */, - MAD_F(0x061f78aa) /* 0.382683432 */, - MAD_F(0x0ec835e8) /* 0.923879533 */, - MAD_F(0x0ec835e8) /* 0.923879533 */, - MAD_F(0x061f78aa) /* 0.382683432 */ }, - - /* 2 */ { MAD_F(0x0216a2a2) /* 0.130526192 */, - -MAD_F(0x061f78aa) /* -0.382683432 */, - MAD_F(0x09bd7ca0) /* 0.608761429 */, - -MAD_F(0x0cb19346) /* -0.793353340 */, - MAD_F(0x0ec835e8) /* 0.923879533 */, - -MAD_F(0x0fdcf549) /* -0.991444861 */ }, - - /* 8 */ { -MAD_F(0x0fdcf549) /* -0.991444861 */, - -MAD_F(0x0ec835e8) /* -0.923879533 */, - -MAD_F(0x0cb19346) /* -0.793353340 */, - -MAD_F(0x09bd7ca0) /* -0.608761429 */, - -MAD_F(0x061f78aa) /* -0.382683432 */, - -MAD_F(0x0216a2a2) /* -0.130526192 */ } + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: imdct_s.dat,v 1.8 2004/01/23 09:41:32 rob Exp $ +*/ + +/* 0 */ { MAD_F(0x09bd7ca0) /* 0.608761429 */, + -MAD_F(0x0ec835e8) /* -0.923879533 */, + -MAD_F(0x0216a2a2) /* -0.130526192 */, + MAD_F(0x0fdcf549) /* 0.991444861 */, + -MAD_F(0x061f78aa) /* -0.382683432 */, + -MAD_F(0x0cb19346) /* -0.793353340 */ +}, + +/* 6 */ { -MAD_F(0x0cb19346) /* -0.793353340 */, + MAD_F(0x061f78aa) /* 0.382683432 */, + MAD_F(0x0fdcf549) /* 0.991444861 */, + MAD_F(0x0216a2a2) /* 0.130526192 */, + -MAD_F(0x0ec835e8) /* -0.923879533 */, + -MAD_F(0x09bd7ca0) /* -0.608761429 */ + }, + +/* 1 */ { MAD_F(0x061f78aa) /* 0.382683432 */, + -MAD_F(0x0ec835e8) /* -0.923879533 */, + MAD_F(0x0ec835e8) /* 0.923879533 */, + -MAD_F(0x061f78aa) /* -0.382683432 */, + -MAD_F(0x061f78aa) /* -0.382683432 */, + MAD_F(0x0ec835e8) /* 0.923879533 */ +}, + +/* 7 */ { -MAD_F(0x0ec835e8) /* -0.923879533 */, + -MAD_F(0x061f78aa) /* -0.382683432 */, + MAD_F(0x061f78aa) /* 0.382683432 */, + MAD_F(0x0ec835e8) /* 0.923879533 */, + MAD_F(0x0ec835e8) /* 0.923879533 */, + MAD_F(0x061f78aa) /* 0.382683432 */ + }, + +/* 2 */ { MAD_F(0x0216a2a2) /* 0.130526192 */, + -MAD_F(0x061f78aa) /* -0.382683432 */, + MAD_F(0x09bd7ca0) /* 0.608761429 */, + -MAD_F(0x0cb19346) /* -0.793353340 */, + MAD_F(0x0ec835e8) /* 0.923879533 */, + -MAD_F(0x0fdcf549) /* -0.991444861 */ +}, + +/* 8 */ { -MAD_F(0x0fdcf549) /* -0.991444861 */, + -MAD_F(0x0ec835e8) /* -0.923879533 */, + -MAD_F(0x0cb19346) /* -0.793353340 */, + -MAD_F(0x09bd7ca0) /* -0.608761429 */, + -MAD_F(0x061f78aa) /* -0.382683432 */, + -MAD_F(0x0216a2a2) /* -0.130526192 */ + } diff --git a/src/libmad/layer3.c b/src/libmad/layer3.c index 66ed7c2e..8376e9f5 100644 --- a/src/libmad/layer3.c +++ b/src/libmad/layer3.c @@ -1,25 +1,26 @@ /* - libmad - MPEG audio decoder library - Copyright (C) 2000-2004 Underbit Technologies, Inc. + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - $Id: layer3.c,v 1.43 2004/01/23 09:41:32 rob Exp $ + $Id: layer3.c,v 1.43 2004/01/23 09:41:32 rob Exp $ */ #pragma GCC optimize ("O3") +#pragma GCC diagnostic ignored "-Wstrict-aliasing" #include # include "config.h" @@ -50,237 +51,237 @@ /* --- Layer III ----------------------------------------------------------- */ enum { - count1table_select = 0x01, - scalefac_scale = 0x02, - preflag = 0x04, - mixed_block_flag = 0x08 + count1table_select = 0x01, + scalefac_scale = 0x02, + preflag = 0x04, + mixed_block_flag = 0x08 }; enum { - I_STEREO = 0x1, - MS_STEREO = 0x2 + I_STEREO = 0x1, + MS_STEREO = 0x2 }; struct sideinfo { - unsigned int main_data_begin; - unsigned int private_bits; - - unsigned char scfsi[2]; - - struct granule { - struct channel { - /* from side info */ - unsigned short part2_3_length; - unsigned short big_values; - unsigned short global_gain; - unsigned short scalefac_compress; - - unsigned char flags; - unsigned char block_type; - unsigned char table_select[3]; - unsigned char subblock_gain[3]; - unsigned char region0_count; - unsigned char region1_count; - - /* from main_data */ - unsigned char scalefac[39]; /* scalefac_l and/or scalefac_s */ - } ch[2]; - } gr[2]; + unsigned int main_data_begin; + unsigned int private_bits; + + unsigned char scfsi[2]; + + struct granule { + struct channel { + /* from side info */ + unsigned short part2_3_length; + unsigned short big_values; + unsigned short global_gain; + unsigned short scalefac_compress; + + unsigned char flags; + unsigned char block_type; + unsigned char table_select[3]; + unsigned char subblock_gain[3]; + unsigned char region0_count; + unsigned char region1_count; + + /* from main_data */ + unsigned char scalefac[39]; /* scalefac_l and/or scalefac_s */ + } ch[2]; + } gr[2]; }; /* - scalefactor bit lengths - derived from section 2.4.2.7 of ISO/IEC 11172-3 + scalefactor bit lengths + derived from section 2.4.2.7 of ISO/IEC 11172-3 */ static struct { - unsigned int slen1; - unsigned int slen2; + unsigned int slen1; + unsigned int slen2; } const sflen_table[16] PROGMEM = { - { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, - { 3, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 }, - { 2, 1 }, { 2, 2 }, { 2, 3 }, { 3, 1 }, - { 3, 2 }, { 3, 3 }, { 4, 2 }, { 4, 3 } + { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, + { 3, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 }, + { 2, 1 }, { 2, 2 }, { 2, 3 }, { 3, 1 }, + { 3, 2 }, { 3, 3 }, { 4, 2 }, { 4, 3 } }; /* - number of LSF scalefactor band values - derived from section 2.4.3.2 of ISO/IEC 13818-3 + number of LSF scalefactor band values + derived from section 2.4.3.2 of ISO/IEC 13818-3 */ static unsigned int const nsfb_table[6][3][4] PROGMEM = { - { { 6, 5, 5, 5 }, - { 9, 9, 9, 9 }, - { 6, 9, 9, 9 } - }, - - { { 6, 5, 7, 3 }, - { 9, 9, 12, 6 }, - { 6, 9, 12, 6 } - }, - - { { 11, 10, 0, 0 }, - { 18, 18, 0, 0 }, - { 15, 18, 0, 0 } - }, - - { { 7, 7, 7, 0 }, - { 12, 12, 12, 0 }, - { 6, 15, 12, 0 } - }, - - { { 6, 6, 6, 3 }, - { 12, 9, 9, 6 }, - { 6, 12, 9, 6 } - }, - - { { 8, 8, 5, 0 }, - { 15, 12, 9, 0 }, - { 6, 18, 9, 0 } - } + { { 6, 5, 5, 5 }, + { 9, 9, 9, 9 }, + { 6, 9, 9, 9 } + }, + + { { 6, 5, 7, 3 }, + { 9, 9, 12, 6 }, + { 6, 9, 12, 6 } + }, + + { { 11, 10, 0, 0 }, + { 18, 18, 0, 0 }, + { 15, 18, 0, 0 } + }, + + { { 7, 7, 7, 0 }, + { 12, 12, 12, 0 }, + { 6, 15, 12, 0 } + }, + + { { 6, 6, 6, 3 }, + { 12, 9, 9, 6 }, + { 6, 12, 9, 6 } + }, + + { { 8, 8, 5, 0 }, + { 15, 12, 9, 0 }, + { 6, 18, 9, 0 } + } }; /* - MPEG-1 scalefactor band widths - derived from Table B.8 of ISO/IEC 11172-3 + MPEG-1 scalefactor band widths + derived from Table B.8 of ISO/IEC 11172-3 */ static unsigned int const sfb_48000_long[] PROGMEM = { - 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10, - 12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192 + 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10, + 12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192 }; static unsigned int const sfb_44100_long[] PROGMEM = { - 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10, - 12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158 + 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10, + 12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158 }; static unsigned int const sfb_32000_long[] PROGMEM = { - 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12, - 16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26 + 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12, + 16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26 }; static unsigned int const sfb_48000_short[] PROGMEM = { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, - 6, 6, 6, 6, 6, 10, 10, 10, 12, 12, 12, 14, 14, - 14, 16, 16, 16, 20, 20, 20, 26, 26, 26, 66, 66, 66 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, + 6, 6, 6, 6, 6, 10, 10, 10, 12, 12, 12, 14, 14, + 14, 16, 16, 16, 20, 20, 20, 26, 26, 26, 66, 66, 66 }; static unsigned int const sfb_44100_short[] PROGMEM = { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, - 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, - 14, 18, 18, 18, 22, 22, 22, 30, 30, 30, 56, 56, 56 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, + 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, + 14, 18, 18, 18, 22, 22, 22, 30, 30, 30, 56, 56, 56 }; static unsigned int const sfb_32000_short[] PROGMEM = { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, - 6, 6, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 20, - 20, 26, 26, 26, 34, 34, 34, 42, 42, 42, 12, 12, 12 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, + 6, 6, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 20, + 20, 26, 26, 26, 34, 34, 34, 42, 42, 42, 12, 12, 12 }; static unsigned int const sfb_48000_mixed[] PROGMEM = { - /* long */ 4, 4, 4, 4, 4, 4, 6, 6, - /* short */ 4, 4, 4, 6, 6, 6, 6, 6, 6, 10, - 10, 10, 12, 12, 12, 14, 14, 14, 16, 16, - 16, 20, 20, 20, 26, 26, 26, 66, 66, 66 + /* long */ 4, 4, 4, 4, 4, 4, 6, 6, + /* short */ 4, 4, 4, 6, 6, 6, 6, 6, 6, 10, + 10, 10, 12, 12, 12, 14, 14, 14, 16, 16, + 16, 20, 20, 20, 26, 26, 26, 66, 66, 66 }; static unsigned int const sfb_44100_mixed[] PROGMEM = { - /* long */ 4, 4, 4, 4, 4, 4, 6, 6, - /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 10, - 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, - 18, 22, 22, 22, 30, 30, 30, 56, 56, 56 + /* long */ 4, 4, 4, 4, 4, 4, 6, 6, + /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 10, + 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, + 18, 22, 22, 22, 30, 30, 30, 56, 56, 56 }; static unsigned int const sfb_32000_mixed[] PROGMEM = { - /* long */ 4, 4, 4, 4, 4, 4, 6, 6, - /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 12, - 12, 12, 16, 16, 16, 20, 20, 20, 26, 26, - 26, 34, 34, 34, 42, 42, 42, 12, 12, 12 + /* long */ 4, 4, 4, 4, 4, 4, 6, 6, + /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 12, + 12, 12, 16, 16, 16, 20, 20, 20, 26, 26, + 26, 34, 34, 34, 42, 42, 42, 12, 12, 12 }; /* - MPEG-2 scalefactor band widths - derived from Table B.2 of ISO/IEC 13818-3 + MPEG-2 scalefactor band widths + derived from Table B.2 of ISO/IEC 13818-3 */ static unsigned int const sfb_24000_long[] PROGMEM = { - 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, - 18, 22, 26, 32, 38, 46, 54, 62, 70, 76, 36 + 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 18, 22, 26, 32, 38, 46, 54, 62, 70, 76, 36 }; static unsigned int const sfb_22050_long[] PROGMEM = { - 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, - 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54 + 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54 }; # define sfb_16000_long sfb_22050_long static unsigned int const sfb_24000_short[] PROGMEM = { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, - 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, - 18, 24, 24, 24, 32, 32, 32, 44, 44, 44, 12, 12, 12 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, + 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, + 18, 24, 24, 24, 32, 32, 32, 44, 44, 44, 12, 12, 12 }; static unsigned int const sfb_22050_short[] PROGMEM = { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, - 6, 6, 8, 8, 8, 10, 10, 10, 14, 14, 14, 18, 18, - 18, 26, 26, 26, 32, 32, 32, 42, 42, 42, 18, 18, 18 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, + 6, 6, 8, 8, 8, 10, 10, 10, 14, 14, 14, 18, 18, + 18, 26, 26, 26, 32, 32, 32, 42, 42, 42, 18, 18, 18 }; static unsigned int const sfb_16000_short[] PROGMEM = { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, - 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, - 18, 24, 24, 24, 30, 30, 30, 40, 40, 40, 18, 18, 18 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, + 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, + 18, 24, 24, 24, 30, 30, 30, 40, 40, 40, 18, 18, 18 }; static unsigned int const sfb_24000_mixed[] PROGMEM = { - /* long */ 6, 6, 6, 6, 6, 6, - /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, - 12, 12, 14, 14, 14, 18, 18, 18, 24, 24, - 24, 32, 32, 32, 44, 44, 44, 12, 12, 12 + /* long */ 6, 6, 6, 6, 6, 6, + /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, + 12, 12, 14, 14, 14, 18, 18, 18, 24, 24, + 24, 32, 32, 32, 44, 44, 44, 12, 12, 12 }; static unsigned int const sfb_22050_mixed[] PROGMEM = { - /* long */ 6, 6, 6, 6, 6, 6, - /* short */ 6, 6, 6, 6, 6, 6, 8, 8, 8, 10, - 10, 10, 14, 14, 14, 18, 18, 18, 26, 26, - 26, 32, 32, 32, 42, 42, 42, 18, 18, 18 + /* long */ 6, 6, 6, 6, 6, 6, + /* short */ 6, 6, 6, 6, 6, 6, 8, 8, 8, 10, + 10, 10, 14, 14, 14, 18, 18, 18, 26, 26, + 26, 32, 32, 32, 42, 42, 42, 18, 18, 18 }; static unsigned int const sfb_16000_mixed[] PROGMEM = { - /* long */ 6, 6, 6, 6, 6, 6, - /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, - 12, 12, 14, 14, 14, 18, 18, 18, 24, 24, - 24, 30, 30, 30, 40, 40, 40, 18, 18, 18 + /* long */ 6, 6, 6, 6, 6, 6, + /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, + 12, 12, 14, 14, 14, 18, 18, 18, 24, 24, + 24, 30, 30, 30, 40, 40, 40, 18, 18, 18 }; /* - MPEG 2.5 scalefactor band widths - derived from public sources + MPEG 2.5 scalefactor band widths + derived from public sources */ # define sfb_12000_long sfb_16000_long # define sfb_11025_long sfb_12000_long static unsigned int const sfb_8000_long[] PROGMEM = { - 12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32, - 40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2 + 12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32, + 40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2 }; # define sfb_12000_short sfb_16000_short @@ -288,72 +289,70 @@ unsigned int const sfb_8000_long[] PROGMEM = { static unsigned int const sfb_8000_short[] PROGMEM = { - 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 16, - 16, 16, 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36, - 36, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 16, + 16, 16, 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36, + 36, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26 }; # define sfb_12000_mixed sfb_16000_mixed # define sfb_11025_mixed sfb_12000_mixed -/* the 8000 Hz short block scalefactor bands do not break after - the first 36 frequency lines, so this is probably wrong */ +/* the 8000 Hz short block scalefactor bands do not break after + the first 36 frequency lines, so this is probably wrong */ static unsigned int const sfb_8000_mixed[] PROGMEM = { - /* long */ 12, 12, 12, - /* short */ 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16, - 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36, 36, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26 + /* long */ 12, 12, 12, + /* short */ 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16, + 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36, 36, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26 }; static struct { - unsigned int const *l; - unsigned int const *s; - unsigned int const *m; + unsigned int const *l; + unsigned int const *s; + unsigned int const *m; } const sfbwidth_table[9] PROGMEM = { - { sfb_48000_long, sfb_48000_short, sfb_48000_mixed }, - { sfb_44100_long, sfb_44100_short, sfb_44100_mixed }, - { sfb_32000_long, sfb_32000_short, sfb_32000_mixed }, - { sfb_24000_long, sfb_24000_short, sfb_24000_mixed }, - { sfb_22050_long, sfb_22050_short, sfb_22050_mixed }, - { sfb_16000_long, sfb_16000_short, sfb_16000_mixed }, - { sfb_12000_long, sfb_12000_short, sfb_12000_mixed }, - { sfb_11025_long, sfb_11025_short, sfb_11025_mixed }, - { sfb_8000_long, sfb_8000_short, sfb_8000_mixed } + { sfb_48000_long, sfb_48000_short, sfb_48000_mixed }, + { sfb_44100_long, sfb_44100_short, sfb_44100_mixed }, + { sfb_32000_long, sfb_32000_short, sfb_32000_mixed }, + { sfb_24000_long, sfb_24000_short, sfb_24000_mixed }, + { sfb_22050_long, sfb_22050_short, sfb_22050_mixed }, + { sfb_16000_long, sfb_16000_short, sfb_16000_mixed }, + { sfb_12000_long, sfb_12000_short, sfb_12000_mixed }, + { sfb_11025_long, sfb_11025_short, sfb_11025_mixed }, + { sfb_8000_long, sfb_8000_short, sfb_8000_mixed } }; /* - scalefactor band preemphasis (used only when preflag is set) - derived from Table B.6 of ISO/IEC 11172-3 + scalefactor band preemphasis (used only when preflag is set) + derived from Table B.6 of ISO/IEC 11172-3 */ static unsigned int const pretab[22] PROGMEM = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 }; /* - table for requantization + table for requantization - rq_table[x].mantissa * 2^(rq_table[x].exponent) = x^(4/3) + rq_table[x].mantissa * 2^(rq_table[x].exponent) = x^(4/3) */ static struct fixedfloat { - unsigned long mantissa : 27; - unsigned short exponent : 5; + unsigned long mantissa : 27; + unsigned short exponent : 5; } const rq_table[8207] PROGMEM = { # include "rq_table.dat.h" }; /* - fractional powers of two - used for requantization and joint stereo decoding + fractional powers of two + used for requantization and joint stereo decoding - root_table[3 + x] = 2^(x/4) + root_table[3 + x] = 2^(x/4) */ -static inline mad_fixed_t root_table(int i) -{ - static mad_fixed_t const root_table_val[7] PROGMEM = { +static mad_fixed_t const root_table_val[7] PROGMEM = { MAD_F(0x09837f05) /* 2^(-3/4) == 0.59460355750136 */, MAD_F(0x0b504f33) /* 2^(-2/4) == 0.70710678118655 */, MAD_F(0x0d744fcd) /* 2^(-1/4) == 0.84089641525371 */, @@ -361,48 +360,47 @@ static inline mad_fixed_t root_table(int i) MAD_F(0x1306fe0a) /* 2^(+1/4) == 1.18920711500272 */, MAD_F(0x16a09e66) /* 2^(+2/4) == 1.41421356237310 */, MAD_F(0x1ae89f99) /* 2^(+3/4) == 1.68179283050743 */ - }; - volatile uint32_t a = *(uint32_t*)&root_table_val[i]; - return *(mad_fixed_t*)&a; +}; +static inline mad_fixed_t root_table(int i) { + volatile mad_fixed_t a = root_table_val[i]; + return a; } /* - coefficients for aliasing reduction - derived from Table B.9 of ISO/IEC 11172-3 + coefficients for aliasing reduction + derived from Table B.9 of ISO/IEC 11172-3 c[] = { -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037 } - cs[i] = 1 / sqrt(1 + c[i]^2) - ca[i] = c[i] / sqrt(1 + c[i]^2) + cs[i] = 1 / sqrt(1 + c[i]^2) + ca[i] = c[i] / sqrt(1 + c[i]^2) */ -static inline mad_fixed_t cs(int i) -{ - static mad_fixed_t const cs_val[8] PROGMEM = { +static mad_fixed_t const cs_val[8] PROGMEM = { +MAD_F(0x0db84a81) /* +0.857492926 */, +MAD_F(0x0e1b9d7f) /* +0.881741997 */, - +MAD_F(0x0f31adcf) /* +0.949628649 */, +MAD_F(0x0fbba815) /* +0.983314592 */, - +MAD_F(0x0feda417) /* +0.995517816 */, +MAD_F(0x0ffc8fc8) /* +0.999160558 */, - +MAD_F(0x0fff964c) /* +0.999899195 */, +MAD_F(0x0ffff8d3) /* +0.999993155 */ - }; - volatile uint32_t a = *(uint32_t*)&cs_val[i]; - return *(mad_fixed_t*)&a; + +MAD_F(0x0f31adcf) /* +0.949628649 */, +MAD_F(0x0fbba815) /* +0.983314592 */, + +MAD_F(0x0feda417) /* +0.995517816 */, +MAD_F(0x0ffc8fc8) /* +0.999160558 */, + +MAD_F(0x0fff964c) /* +0.999899195 */, +MAD_F(0x0ffff8d3) /* +0.999993155 */ + }; +static inline mad_fixed_t cs(int i) { + volatile mad_fixed_t a = cs_val[i]; + return a; } -static inline mad_fixed_t ca(int i) -{ - static mad_fixed_t const ca_val[8] PROGMEM = { +static mad_fixed_t const ca_val[8] PROGMEM = { -MAD_F(0x083b5fe7) /* -0.514495755 */, -MAD_F(0x078c36d2) /* -0.471731969 */, - -MAD_F(0x05039814) /* -0.313377454 */, -MAD_F(0x02e91dd1) /* -0.181913200 */, - -MAD_F(0x0183603a) /* -0.094574193 */, -MAD_F(0x00a7cb87) /* -0.040965583 */, - -MAD_F(0x003a2847) /* -0.014198569 */, -MAD_F(0x000f27b4) /* -0.003699975 */ - }; - volatile uint32_t a = *(uint32_t*)&ca_val[i]; - return *(mad_fixed_t*)&a; + -MAD_F(0x05039814) /* -0.313377454 */, -MAD_F(0x02e91dd1) /* -0.181913200 */, + -MAD_F(0x0183603a) /* -0.094574193 */, -MAD_F(0x00a7cb87) /* -0.040965583 */, + -MAD_F(0x003a2847) /* -0.014198569 */, -MAD_F(0x000f27b4) /* -0.003699975 */ + }; +static inline mad_fixed_t ca(int i) { + volatile mad_fixed_t a = ca_val[i]; + return a; } /* - IMDCT coefficients for short blocks - derived from section 2.4.3.4.10.2 of ISO/IEC 11172-3 + IMDCT coefficients for short blocks + derived from section 2.4.3.4.10.2 of ISO/IEC 11172-3 - imdct_s[i/even][k] = cos((PI / 24) * (2 * (i / 2) + 7) * (2 * k + 1)) - imdct_s[i /odd][k] = cos((PI / 24) * (2 * (6 + (i-1)/2) + 7) * (2 * k + 1)) + imdct_s[i/even][k] = cos((PI / 24) * (2 * (i / 2) + 7) * (2 * k + 1)) + imdct_s[i /odd][k] = cos((PI / 24) * (2 * (6 + (i-1)/2) + 7) * (2 * k + 1)) */ static mad_fixed_t const imdct_s[6][6] PROGMEM = { @@ -411,14 +409,12 @@ mad_fixed_t const imdct_s[6][6] PROGMEM = { # if !defined(ASO_IMDCT) /* - windowing coefficients for long blocks - derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3 + windowing coefficients for long blocks + derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3 - window_l[i] = sin((PI / 36) * (i + 1/2)) + window_l[i] = sin((PI / 36) * (i + 1/2)) */ -static inline mad_fixed_t window_l(int i) -{ - static mad_fixed_t const window_l_val[36] PROGMEM = { +static mad_fixed_t const window_l_val[36] PROGMEM = { MAD_F(0x00b2aa3e) /* 0.043619387 */, MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x03768962) /* 0.216439614 */, MAD_F(0x04cfb0e2) /* 0.300705800 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x07635284) /* 0.461748613 */, @@ -439,42 +435,40 @@ static inline mad_fixed_t window_l(int i) MAD_F(0x07635284) /* 0.461748613 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x04cfb0e2) /* 0.300705800 */, MAD_F(0x03768962) /* 0.216439614 */, MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x00b2aa3e) /* 0.043619387 */, - }; - volatile uint32_t a = *(uint32_t*)&window_l_val[i]; - return *(mad_fixed_t*)&a; +}; +static inline mad_fixed_t window_l(int i) { + volatile mad_fixed_t a = window_l_val[i]; + return *(mad_fixed_t*)&a; } # endif /* ASO_IMDCT */ /* - windowing coefficients for short blocks - derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3 + windowing coefficients for short blocks + derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3 - window_s[i] = sin((PI / 12) * (i + 1/2)) + window_s[i] = sin((PI / 12) * (i + 1/2)) */ -static inline mad_fixed_t window_s(int i) -{ - static mad_fixed_t const window_s_val[12] PROGMEM = { +static mad_fixed_t const window_s_val[12] PROGMEM = { MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x0216a2a2) /* 0.130526192 */, - }; - volatile uint32_t a = *(uint32_t*)&window_s_val[i]; - return *(mad_fixed_t*)&a; +}; +static inline mad_fixed_t window_s(int i) { + volatile mad_fixed_t a = window_s_val[i]; + return a; } /* - coefficients for intensity stereo processing - derived from section 2.4.3.4.9.3 of ISO/IEC 11172-3 + coefficients for intensity stereo processing + derived from section 2.4.3.4.9.3 of ISO/IEC 11172-3 - is_ratio[i] = tan(i * (PI / 12)) - is_table[i] = is_ratio[i] / (1 + is_ratio[i]) + is_ratio[i] = tan(i * (PI / 12)) + is_table[i] = is_ratio[i] / (1 + is_ratio[i]) */ -static inline mad_fixed_t is_table(int i) -{ - static mad_fixed_t const is_table_val[7] PROGMEM = { +static mad_fixed_t const is_table_val[7] PROGMEM = { MAD_F(0x00000000) /* 0.000000000 */, MAD_F(0x0361962f) /* 0.211324865 */, MAD_F(0x05db3d74) /* 0.366025404 */, @@ -482,343 +476,351 @@ static inline mad_fixed_t is_table(int i) MAD_F(0x0a24c28c) /* 0.633974596 */, MAD_F(0x0c9e69d1) /* 0.788675135 */, MAD_F(0x10000000) /* 1.000000000 */ - }; - volatile uint32_t a = *(uint32_t*)&is_table_val[i]; - return *(mad_fixed_t*)&a; +}; +static inline mad_fixed_t is_table(int i) { + volatile mad_fixed_t a = is_table_val[i]; + return a; } /* - coefficients for LSF intensity stereo processing - derived from section 2.4.3.2 of ISO/IEC 13818-3 + coefficients for LSF intensity stereo processing + derived from section 2.4.3.2 of ISO/IEC 13818-3 - is_lsf_table[0][i] = (1 / sqrt(sqrt(2)))^(i + 1) - is_lsf_table[1][i] = (1 / sqrt(2)) ^(i + 1) + is_lsf_table[0][i] = (1 / sqrt(sqrt(2)))^(i + 1) + is_lsf_table[1][i] = (1 / sqrt(2)) ^(i + 1) */ static mad_fixed_t const is_lsf_table[2][15] PROGMEM = { - { - MAD_F(0x0d744fcd) /* 0.840896415 */, - MAD_F(0x0b504f33) /* 0.707106781 */, - MAD_F(0x09837f05) /* 0.594603558 */, - MAD_F(0x08000000) /* 0.500000000 */, - MAD_F(0x06ba27e6) /* 0.420448208 */, - MAD_F(0x05a8279a) /* 0.353553391 */, - MAD_F(0x04c1bf83) /* 0.297301779 */, - MAD_F(0x04000000) /* 0.250000000 */, - MAD_F(0x035d13f3) /* 0.210224104 */, - MAD_F(0x02d413cd) /* 0.176776695 */, - MAD_F(0x0260dfc1) /* 0.148650889 */, - MAD_F(0x02000000) /* 0.125000000 */, - MAD_F(0x01ae89fa) /* 0.105112052 */, - MAD_F(0x016a09e6) /* 0.088388348 */, - MAD_F(0x01306fe1) /* 0.074325445 */ - }, { - MAD_F(0x0b504f33) /* 0.707106781 */, - MAD_F(0x08000000) /* 0.500000000 */, - MAD_F(0x05a8279a) /* 0.353553391 */, - MAD_F(0x04000000) /* 0.250000000 */, - MAD_F(0x02d413cd) /* 0.176776695 */, - MAD_F(0x02000000) /* 0.125000000 */, - MAD_F(0x016a09e6) /* 0.088388348 */, - MAD_F(0x01000000) /* 0.062500000 */, - MAD_F(0x00b504f3) /* 0.044194174 */, - MAD_F(0x00800000) /* 0.031250000 */, - MAD_F(0x005a827a) /* 0.022097087 */, - MAD_F(0x00400000) /* 0.015625000 */, - MAD_F(0x002d413d) /* 0.011048543 */, - MAD_F(0x00200000) /* 0.007812500 */, - MAD_F(0x0016a09e) /* 0.005524272 */ - } + { + MAD_F(0x0d744fcd) /* 0.840896415 */, + MAD_F(0x0b504f33) /* 0.707106781 */, + MAD_F(0x09837f05) /* 0.594603558 */, + MAD_F(0x08000000) /* 0.500000000 */, + MAD_F(0x06ba27e6) /* 0.420448208 */, + MAD_F(0x05a8279a) /* 0.353553391 */, + MAD_F(0x04c1bf83) /* 0.297301779 */, + MAD_F(0x04000000) /* 0.250000000 */, + MAD_F(0x035d13f3) /* 0.210224104 */, + MAD_F(0x02d413cd) /* 0.176776695 */, + MAD_F(0x0260dfc1) /* 0.148650889 */, + MAD_F(0x02000000) /* 0.125000000 */, + MAD_F(0x01ae89fa) /* 0.105112052 */, + MAD_F(0x016a09e6) /* 0.088388348 */, + MAD_F(0x01306fe1) /* 0.074325445 */ + }, { + MAD_F(0x0b504f33) /* 0.707106781 */, + MAD_F(0x08000000) /* 0.500000000 */, + MAD_F(0x05a8279a) /* 0.353553391 */, + MAD_F(0x04000000) /* 0.250000000 */, + MAD_F(0x02d413cd) /* 0.176776695 */, + MAD_F(0x02000000) /* 0.125000000 */, + MAD_F(0x016a09e6) /* 0.088388348 */, + MAD_F(0x01000000) /* 0.062500000 */, + MAD_F(0x00b504f3) /* 0.044194174 */, + MAD_F(0x00800000) /* 0.031250000 */, + MAD_F(0x005a827a) /* 0.022097087 */, + MAD_F(0x00400000) /* 0.015625000 */, + MAD_F(0x002d413d) /* 0.011048543 */, + MAD_F(0x00200000) /* 0.007812500 */, + MAD_F(0x0016a09e) /* 0.005524272 */ + } }; /* - NAME: III_sideinfo() - DESCRIPTION: decode frame side information from a bitstream + NAME: III_sideinfo() + DESCRIPTION: decode frame side information from a bitstream */ static enum mad_error III_sideinfo(struct mad_bitptr *ptr, unsigned int nch, int lsf, struct sideinfo *si, unsigned int *data_bitlen, - unsigned int *priv_bitlen) -{ - unsigned int ngr, gr, ch, i; - enum mad_error result = MAD_ERROR_NONE; - stack(__FUNCTION__, __FILE__, __LINE__); + unsigned int *priv_bitlen) { + unsigned int ngr, gr, ch, i; + enum mad_error result = MAD_ERROR_NONE; + stackenter(__FUNCTION__, __FILE__, __LINE__); - *data_bitlen = 0; - *priv_bitlen = lsf ? ((nch == 1) ? 1 : 2) : ((nch == 1) ? 5 : 3); + *data_bitlen = 0; + *priv_bitlen = lsf ? ((nch == 1) ? 1 : 2) : ((nch == 1) ? 5 : 3); - si->main_data_begin = mad_bit_read(ptr, lsf ? 8 : 9); - si->private_bits = mad_bit_read(ptr, *priv_bitlen); + si->main_data_begin = mad_bit_read(ptr, lsf ? 8 : 9); + si->private_bits = mad_bit_read(ptr, *priv_bitlen); - ngr = 1; - if (!lsf) { - ngr = 2; + ngr = 1; + if (!lsf) { + ngr = 2; - for (ch = 0; ch < nch; ++ch) - si->scfsi[ch] = mad_bit_read(ptr, 4); - } + for (ch = 0; ch < nch; ++ch) { + si->scfsi[ch] = mad_bit_read(ptr, 4); + } + } - for (gr = 0; gr < ngr; ++gr) { - struct granule *granule = &si->gr[gr]; + for (gr = 0; gr < ngr; ++gr) { + struct granule *granule = &si->gr[gr]; - for (ch = 0; ch < nch; ++ch) { - struct channel *channel = &granule->ch[ch]; + for (ch = 0; ch < nch; ++ch) { + struct channel *channel = &granule->ch[ch]; - channel->part2_3_length = mad_bit_read(ptr, 12); - channel->big_values = mad_bit_read(ptr, 9); - channel->global_gain = mad_bit_read(ptr, 8); - channel->scalefac_compress = mad_bit_read(ptr, lsf ? 9 : 4); + channel->part2_3_length = mad_bit_read(ptr, 12); + channel->big_values = mad_bit_read(ptr, 9); + channel->global_gain = mad_bit_read(ptr, 8); + channel->scalefac_compress = mad_bit_read(ptr, lsf ? 9 : 4); - *data_bitlen += channel->part2_3_length; + *data_bitlen += channel->part2_3_length; - if (channel->big_values > 288 && result == 0) - result = MAD_ERROR_BADBIGVALUES; + if (channel->big_values > 288 && result == 0) { + result = MAD_ERROR_BADBIGVALUES; + } - channel->flags = 0; + channel->flags = 0; - /* window_switching_flag */ - if (mad_bit_read(ptr, 1)) { - channel->block_type = mad_bit_read(ptr, 2); + /* window_switching_flag */ + if (mad_bit_read(ptr, 1)) { + channel->block_type = mad_bit_read(ptr, 2); - if (channel->block_type == 0 && result == 0) - result = MAD_ERROR_BADBLOCKTYPE; + if (channel->block_type == 0 && result == 0) { + result = MAD_ERROR_BADBLOCKTYPE; + } - if (!lsf && channel->block_type == 2 && si->scfsi[ch] && result == 0) - result = MAD_ERROR_BADSCFSI; + if (!lsf && channel->block_type == 2 && si->scfsi[ch] && result == 0) { + result = MAD_ERROR_BADSCFSI; + } - channel->region0_count = 7; - channel->region1_count = 36; + channel->region0_count = 7; + channel->region1_count = 36; - if (mad_bit_read(ptr, 1)) - channel->flags |= mixed_block_flag; - else if (channel->block_type == 2) - channel->region0_count = 8; + if (mad_bit_read(ptr, 1)) { + channel->flags |= mixed_block_flag; + } else if (channel->block_type == 2) { + channel->region0_count = 8; + } - for (i = 0; i < 2; ++i) - channel->table_select[i] = mad_bit_read(ptr, 5); + for (i = 0; i < 2; ++i) { + channel->table_select[i] = mad_bit_read(ptr, 5); + } # if defined(DEBUG) - channel->table_select[2] = 4; /* not used */ + channel->table_select[2] = 4; /* not used */ # endif - for (i = 0; i < 3; ++i) - channel->subblock_gain[i] = mad_bit_read(ptr, 3); - } - else { - channel->block_type = 0; + for (i = 0; i < 3; ++i) { + channel->subblock_gain[i] = mad_bit_read(ptr, 3); + } + } else { + channel->block_type = 0; - for (i = 0; i < 3; ++i) - channel->table_select[i] = mad_bit_read(ptr, 5); + for (i = 0; i < 3; ++i) { + channel->table_select[i] = mad_bit_read(ptr, 5); + } - channel->region0_count = mad_bit_read(ptr, 4); - channel->region1_count = mad_bit_read(ptr, 3); - } + channel->region0_count = mad_bit_read(ptr, 4); + channel->region1_count = mad_bit_read(ptr, 3); + } - /* [preflag,] scalefac_scale, count1table_select */ - channel->flags |= mad_bit_read(ptr, lsf ? 2 : 3); + /* [preflag,] scalefac_scale, count1table_select */ + channel->flags |= mad_bit_read(ptr, lsf ? 2 : 3); + } } - } - return result; + return result; } /* - NAME: III_scalefactors_lsf() - DESCRIPTION: decode channel scalefactors for LSF from a bitstream + NAME: III_scalefactors_lsf() + DESCRIPTION: decode channel scalefactors for LSF from a bitstream */ static unsigned int III_scalefactors_lsf(struct mad_bitptr *ptr, struct channel *channel, - struct channel *gr1ch, int mode_extension) -{ - struct mad_bitptr start; - unsigned int scalefac_compress, index, slen[4], part, n, i; - unsigned int const *nsfb; - stack(__FUNCTION__, __FILE__, __LINE__); - - start = *ptr; - - scalefac_compress = channel->scalefac_compress; - index = (channel->block_type == 2) ? - ((channel->flags & mixed_block_flag) ? 2 : 1) : 0; - - if (!((mode_extension & I_STEREO) && gr1ch)) { - if (scalefac_compress < 400) { - slen[0] = (scalefac_compress >> 4) / 5; - slen[1] = (scalefac_compress >> 4) % 5; - slen[2] = (scalefac_compress % 16) >> 2; - slen[3] = scalefac_compress % 4; - - nsfb = nsfb_table[0][index]; - } - else if (scalefac_compress < 500) { - scalefac_compress -= 400; - - slen[0] = (scalefac_compress >> 2) / 5; - slen[1] = (scalefac_compress >> 2) % 5; - slen[2] = scalefac_compress % 4; - slen[3] = 0; - - nsfb = nsfb_table[1][index]; - } - else { - scalefac_compress -= 500; + struct channel *gr1ch, int mode_extension) { + struct mad_bitptr start; + unsigned int scalefac_compress, index, slen[4], part, n, i; + unsigned int const *nsfb; + stackenter(__FUNCTION__, __FILE__, __LINE__); + + start = *ptr; + + scalefac_compress = channel->scalefac_compress; + index = (channel->block_type == 2) ? + ((channel->flags & mixed_block_flag) ? 2 : 1) : 0; + + if (!((mode_extension & I_STEREO) && gr1ch)) { + if (scalefac_compress < 400) { + slen[0] = (scalefac_compress >> 4) / 5; + slen[1] = (scalefac_compress >> 4) % 5; + slen[2] = (scalefac_compress % 16) >> 2; + slen[3] = scalefac_compress % 4; + + nsfb = nsfb_table[0][index]; + } else if (scalefac_compress < 500) { + scalefac_compress -= 400; + + slen[0] = (scalefac_compress >> 2) / 5; + slen[1] = (scalefac_compress >> 2) % 5; + slen[2] = scalefac_compress % 4; + slen[3] = 0; + + nsfb = nsfb_table[1][index]; + } else { + scalefac_compress -= 500; + + slen[0] = scalefac_compress / 3; + slen[1] = scalefac_compress % 3; + slen[2] = 0; + slen[3] = 0; + + channel->flags |= preflag; + + nsfb = nsfb_table[2][index]; + } - slen[0] = scalefac_compress / 3; - slen[1] = scalefac_compress % 3; - slen[2] = 0; - slen[3] = 0; + n = 0; + for (part = 0; part < 4; ++part) { + for (i = 0; i < nsfb[part]; ++i) { + channel->scalefac[n++] = mad_bit_read(ptr, slen[part]); + } + } - channel->flags |= preflag; + while (n < 39) { + channel->scalefac[n++] = 0; + } + } else { /* (mode_extension & I_STEREO) && gr1ch (i.e. ch == 1) */ + scalefac_compress >>= 1; + + if (scalefac_compress < 180) { + slen[0] = scalefac_compress / 36; + slen[1] = (scalefac_compress % 36) / 6; + slen[2] = (scalefac_compress % 36) % 6; + slen[3] = 0; + + nsfb = nsfb_table[3][index]; + } else if (scalefac_compress < 244) { + scalefac_compress -= 180; + + slen[0] = (scalefac_compress % 64) >> 4; + slen[1] = (scalefac_compress % 16) >> 2; + slen[2] = scalefac_compress % 4; + slen[3] = 0; + + nsfb = nsfb_table[4][index]; + } else { + scalefac_compress -= 244; + + slen[0] = scalefac_compress / 3; + slen[1] = scalefac_compress % 3; + slen[2] = 0; + slen[3] = 0; + + nsfb = nsfb_table[5][index]; + } - nsfb = nsfb_table[2][index]; - } + n = 0; + for (part = 0; part < 4; ++part) { + unsigned int max, is_pos; - n = 0; - for (part = 0; part < 4; ++part) { - for (i = 0; i < nsfb[part]; ++i) - channel->scalefac[n++] = mad_bit_read(ptr, slen[part]); - } + max = (1 << slen[part]) - 1; - while (n < 39) - channel->scalefac[n++] = 0; - } - else { /* (mode_extension & I_STEREO) && gr1ch (i.e. ch == 1) */ - scalefac_compress >>= 1; + for (i = 0; i < nsfb[part]; ++i) { + is_pos = mad_bit_read(ptr, slen[part]); - if (scalefac_compress < 180) { - slen[0] = scalefac_compress / 36; - slen[1] = (scalefac_compress % 36) / 6; - slen[2] = (scalefac_compress % 36) % 6; - slen[3] = 0; + channel->scalefac[n] = is_pos; + gr1ch->scalefac[n++] = (is_pos == max); + } + } - nsfb = nsfb_table[3][index]; + while (n < 39) { + channel->scalefac[n] = 0; + gr1ch->scalefac[n++] = 0; /* apparently not illegal */ + } } - else if (scalefac_compress < 244) { - scalefac_compress -= 180; - - slen[0] = (scalefac_compress % 64) >> 4; - slen[1] = (scalefac_compress % 16) >> 2; - slen[2] = scalefac_compress % 4; - slen[3] = 0; - nsfb = nsfb_table[4][index]; - } - else { - scalefac_compress -= 244; + return mad_bit_length(&start, ptr); +} - slen[0] = scalefac_compress / 3; - slen[1] = scalefac_compress % 3; - slen[2] = 0; - slen[3] = 0; +/* + NAME: III_scalefactors() + DESCRIPTION: decode channel scalefactors of one granule from a bitstream +*/ +static +unsigned int III_scalefactors(struct mad_bitptr *ptr, struct channel *channel, + struct channel const *gr0ch, unsigned int scfsi) { + struct mad_bitptr start; + unsigned int slen1, slen2, sfbi; + stackenter(__FUNCTION__, __FILE__, __LINE__); - nsfb = nsfb_table[5][index]; - } + start = *ptr; - n = 0; - for (part = 0; part < 4; ++part) { - unsigned int max, is_pos; + slen1 = sflen_table[channel->scalefac_compress].slen1; + slen2 = sflen_table[channel->scalefac_compress].slen2; - max = (1 << slen[part]) - 1; + if (channel->block_type == 2) { + unsigned int nsfb; - for (i = 0; i < nsfb[part]; ++i) { - is_pos = mad_bit_read(ptr, slen[part]); + sfbi = 0; - channel->scalefac[n] = is_pos; - gr1ch->scalefac[n++] = (is_pos == max); - } - } + nsfb = (channel->flags & mixed_block_flag) ? 8 + 3 * 3 : 6 * 3; + while (nsfb--) { + channel->scalefac[sfbi++] = mad_bit_read(ptr, slen1); + } - while (n < 39) { - channel->scalefac[n] = 0; - gr1ch->scalefac[n++] = 0; /* apparently not illegal */ - } - } + nsfb = 6 * 3; + while (nsfb--) { + channel->scalefac[sfbi++] = mad_bit_read(ptr, slen2); + } - return mad_bit_length(&start, ptr); -} + nsfb = 1 * 3; + while (nsfb--) { + channel->scalefac[sfbi++] = 0; + } + } else { /* channel->block_type != 2 */ + if (scfsi & 0x8) { + for (sfbi = 0; sfbi < 6; ++sfbi) { + channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; + } + } else { + for (sfbi = 0; sfbi < 6; ++sfbi) { + channel->scalefac[sfbi] = mad_bit_read(ptr, slen1); + } + } -/* - NAME: III_scalefactors() - DESCRIPTION: decode channel scalefactors of one granule from a bitstream -*/ -static -unsigned int III_scalefactors(struct mad_bitptr *ptr, struct channel *channel, - struct channel const *gr0ch, unsigned int scfsi) -{ - struct mad_bitptr start; - unsigned int slen1, slen2, sfbi; - stack(__FUNCTION__, __FILE__, __LINE__); - - start = *ptr; - - slen1 = sflen_table[channel->scalefac_compress].slen1; - slen2 = sflen_table[channel->scalefac_compress].slen2; - - if (channel->block_type == 2) { - unsigned int nsfb; - - sfbi = 0; - - nsfb = (channel->flags & mixed_block_flag) ? 8 + 3 * 3 : 6 * 3; - while (nsfb--) - channel->scalefac[sfbi++] = mad_bit_read(ptr, slen1); - - nsfb = 6 * 3; - while (nsfb--) - channel->scalefac[sfbi++] = mad_bit_read(ptr, slen2); - - nsfb = 1 * 3; - while (nsfb--) - channel->scalefac[sfbi++] = 0; - } - else { /* channel->block_type != 2 */ - if (scfsi & 0x8) { - for (sfbi = 0; sfbi < 6; ++sfbi) - channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; - } - else { - for (sfbi = 0; sfbi < 6; ++sfbi) - channel->scalefac[sfbi] = mad_bit_read(ptr, slen1); - } + if (scfsi & 0x4) { + for (sfbi = 6; sfbi < 11; ++sfbi) { + channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; + } + } else { + for (sfbi = 6; sfbi < 11; ++sfbi) { + channel->scalefac[sfbi] = mad_bit_read(ptr, slen1); + } + } - if (scfsi & 0x4) { - for (sfbi = 6; sfbi < 11; ++sfbi) - channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; - } - else { - for (sfbi = 6; sfbi < 11; ++sfbi) - channel->scalefac[sfbi] = mad_bit_read(ptr, slen1); - } + if (scfsi & 0x2) { + for (sfbi = 11; sfbi < 16; ++sfbi) { + channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; + } + } else { + for (sfbi = 11; sfbi < 16; ++sfbi) { + channel->scalefac[sfbi] = mad_bit_read(ptr, slen2); + } + } - if (scfsi & 0x2) { - for (sfbi = 11; sfbi < 16; ++sfbi) - channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; - } - else { - for (sfbi = 11; sfbi < 16; ++sfbi) - channel->scalefac[sfbi] = mad_bit_read(ptr, slen2); - } + if (scfsi & 0x1) { + for (sfbi = 16; sfbi < 21; ++sfbi) { + channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; + } + } else { + for (sfbi = 16; sfbi < 21; ++sfbi) { + channel->scalefac[sfbi] = mad_bit_read(ptr, slen2); + } + } - if (scfsi & 0x1) { - for (sfbi = 16; sfbi < 21; ++sfbi) - channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; - } - else { - for (sfbi = 16; sfbi < 21; ++sfbi) - channel->scalefac[sfbi] = mad_bit_read(ptr, slen2); + channel->scalefac[21] = 0; } - channel->scalefac[21] = 0; - } - - return mad_bit_length(&start, ptr); + return mad_bit_length(&start, ptr); } /* - The Layer III formula for requantization and scaling is defined by - section 2.4.3.4.7.1 of ISO/IEC 11172-3, as follows: + The Layer III formula for requantization and scaling is defined by + section 2.4.3.4.7.1 of ISO/IEC 11172-3, as follows: long blocks: xr[i] = sign(is[i]) * abs(is[i])^(4/3) @@ -834,130 +836,124 @@ unsigned int III_scalefactors(struct mad_bitptr *ptr, struct channel *channel, where: scalefac_multiplier = (scalefac_scale + 1) / 2 - The routines III_exponents() and III_requantize() facilitate this - calculation. + The routines III_exponents() and III_requantize() facilitate this + calculation. */ /* - NAME: III_exponents() - DESCRIPTION: calculate scalefactor exponents + NAME: III_exponents() + DESCRIPTION: calculate scalefactor exponents */ static void III_exponents(struct channel const *channel, - unsigned int const *sfbwidth, signed int exponents[39]) -{ - signed int gain; - unsigned int scalefac_multiplier, sfbi; - stack(__FUNCTION__, __FILE__, __LINE__); + unsigned int const *sfbwidth, signed int exponents[39]) { + signed int gain; + unsigned int scalefac_multiplier, sfbi; + stackenter(__FUNCTION__, __FILE__, __LINE__); - gain = (signed int) channel->global_gain - 210; - scalefac_multiplier = (channel->flags & scalefac_scale) ? 2 : 1; + gain = (signed int) channel->global_gain - 210; + scalefac_multiplier = (channel->flags & scalefac_scale) ? 2 : 1; - if (channel->block_type == 2) { - unsigned int l; - signed int gain0, gain1, gain2; + if (channel->block_type == 2) { + unsigned int l; + signed int gain0, gain1, gain2; - sfbi = l = 0; + sfbi = l = 0; - if (channel->flags & mixed_block_flag) { - unsigned int premask; + if (channel->flags & mixed_block_flag) { + unsigned int premask; - premask = (channel->flags & preflag) ? ~0 : 0; + premask = (channel->flags & preflag) ? ~0 : 0; - /* long block subbands 0-1 */ + /* long block subbands 0-1 */ - while (l < 36) { - exponents[sfbi] = gain - - (signed int) ((channel->scalefac[sfbi] + (pretab[sfbi] & premask)) << - scalefac_multiplier); + while (l < 36) { + exponents[sfbi] = gain - + (signed int)((channel->scalefac[sfbi] + (pretab[sfbi] & premask)) << + scalefac_multiplier); - l += sfbwidth[sfbi++]; - } - } + l += sfbwidth[sfbi++]; + } + } - /* this is probably wrong for 8000 Hz short/mixed blocks */ + /* this is probably wrong for 8000 Hz short/mixed blocks */ - gain0 = gain - 8 * (signed int) channel->subblock_gain[0]; - gain1 = gain - 8 * (signed int) channel->subblock_gain[1]; - gain2 = gain - 8 * (signed int) channel->subblock_gain[2]; + gain0 = gain - 8 * (signed int) channel->subblock_gain[0]; + gain1 = gain - 8 * (signed int) channel->subblock_gain[1]; + gain2 = gain - 8 * (signed int) channel->subblock_gain[2]; - while (l < 576) { - exponents[sfbi + 0] = gain0 - - (signed int) (channel->scalefac[sfbi + 0] << scalefac_multiplier); - exponents[sfbi + 1] = gain1 - - (signed int) (channel->scalefac[sfbi + 1] << scalefac_multiplier); - exponents[sfbi + 2] = gain2 - - (signed int) (channel->scalefac[sfbi + 2] << scalefac_multiplier); + while (l < 576) { + exponents[sfbi + 0] = gain0 - + (signed int)(channel->scalefac[sfbi + 0] << scalefac_multiplier); + exponents[sfbi + 1] = gain1 - + (signed int)(channel->scalefac[sfbi + 1] << scalefac_multiplier); + exponents[sfbi + 2] = gain2 - + (signed int)(channel->scalefac[sfbi + 2] << scalefac_multiplier); - l += 3 * sfbwidth[sfbi]; - sfbi += 3; - } - } - else { /* channel->block_type != 2 */ - if (channel->flags & preflag) { - for (sfbi = 0; sfbi < 22; ++sfbi) { - exponents[sfbi] = gain - - (signed int) ((channel->scalefac[sfbi] + pretab[sfbi]) << - scalefac_multiplier); - } - } - else { - for (sfbi = 0; sfbi < 22; ++sfbi) { - exponents[sfbi] = gain - - (signed int) (channel->scalefac[sfbi] << scalefac_multiplier); - } + l += 3 * sfbwidth[sfbi]; + sfbi += 3; + } + } else { /* channel->block_type != 2 */ + if (channel->flags & preflag) { + for (sfbi = 0; sfbi < 22; ++sfbi) { + exponents[sfbi] = gain - + (signed int)((channel->scalefac[sfbi] + pretab[sfbi]) << + scalefac_multiplier); + } + } else { + for (sfbi = 0; sfbi < 22; ++sfbi) { + exponents[sfbi] = gain - + (signed int)(channel->scalefac[sfbi] << scalefac_multiplier); + } + } } - } } /* - NAME: III_requantize() - DESCRIPTION: requantize one (positive) value + NAME: III_requantize() + DESCRIPTION: requantize one (positive) value */ static -mad_fixed_t III_requantize(unsigned int value, signed int exp) -{ - mad_fixed_t requantized; - signed int frac; - struct fixedfloat power; +mad_fixed_t III_requantize(unsigned int value, signed int exp) { + mad_fixed_t requantized; + signed int frac; + struct fixedfloat power; - stack(__FUNCTION__, __FILE__, __LINE__); - frac = exp % 4; /* assumes sign(frac) == sign(exp) */ - exp /= 4; + stackenter(__FUNCTION__, __FILE__, __LINE__); + frac = exp % 4; /* assumes sign(frac) == sign(exp) */ + exp /= 4; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-aliasing" - *(uint32_t*)&power = *(uint32_t*)&rq_table[value]; //memcpy_P(&power, &rq_table[value], sizeof(power)); // Avoid byte access to PROGMEM + *(uint32_t*)&power = *(uint32_t*)&rq_table[value]; //memcpy_P(&power, &rq_table[value], sizeof(power)); // Avoid byte access to PROGMEM #pragma GCC diagnostic pop #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wuninitialized" - requantized = power.mantissa; - exp += power.exponent; + requantized = power.mantissa; + exp += power.exponent; #pragma GCC diagnostic pop - if (exp < 0) { - if (-exp >= (int)(sizeof(mad_fixed_t) * CHAR_BIT)) { - /* underflow */ - requantized = 0; - } - else { - requantized += 1L << (-exp - 1); - requantized >>= -exp; - } - } - else { - if (exp >= 5) { - /* overflow */ + if (exp < 0) { + if (-exp >= (int)(sizeof(mad_fixed_t) * CHAR_BIT)) { + /* underflow */ + requantized = 0; + } else { + requantized += 1L << (-exp - 1); + requantized >>= -exp; + } + } else { + if (exp >= 5) { + /* overflow */ # if 0 && defined(DEBUG) - fprintf(stderr, "requantize overflow (%f * 2^%d)\n", - mad_f_todouble(requantized), exp); + fprintf(stderr, "requantize overflow (%f * 2^%d)\n", + mad_f_todouble(requantized), exp); # endif - requantized = MAD_F_MAX; + requantized = MAD_F_MAX; + } else { + requantized <<= exp; + } } - else - requantized <<= exp; - } - return frac ? mad_f_mul(requantized, root_table(3 + frac)) : requantized; + return frac ? mad_f_mul(requantized, root_table(3 + frac)) : requantized; } /* we must take care that sz >= bits and sz < sizeof(long) lest bits == 0 */ @@ -967,668 +963,677 @@ mad_fixed_t III_requantize(unsigned int value, signed int exp) ((cache) & (1 << ((sz) - 1))) /* - NAME: III_huffdecode() - DESCRIPTION: decode Huffman code words of one channel of one granule + NAME: III_huffdecode() + DESCRIPTION: decode Huffman code words of one channel of one granule */ static enum mad_error III_huffdecode(struct mad_bitptr *ptr, mad_fixed_t xr[576], struct channel *channel, unsigned int const *sfbwidth, - unsigned int part2_length) -{ - signed int exponents[39], exp; - signed int const *expptr; - struct mad_bitptr peek; - signed int bits_left, cachesz; - register mad_fixed_t *xrptr; - mad_fixed_t const *sfbound; - register unsigned long bitcache; - - stack(__FUNCTION__, __FILE__, __LINE__); - bits_left = (signed) channel->part2_3_length - (signed) part2_length; - if (bits_left < 0) - return MAD_ERROR_BADPART3LEN; - - III_exponents(channel, sfbwidth, exponents); - - peek = *ptr; - mad_bit_skip(ptr, bits_left); - - /* align bit reads to byte boundaries */ - cachesz = mad_bit_bitsleft(&peek); - cachesz += ((32 - 1 - 24) + (24 - cachesz)) & ~7; - - bitcache = mad_bit_read(&peek, cachesz); - bits_left -= cachesz; - - xrptr = &xr[0]; - - /* big_values */ - { - unsigned int region, rcount; - struct hufftable const *entry; - union huffpair const *table; - unsigned int linbits, startbits, big_values, reqhits; - mad_fixed_t reqcache[16]; - - sfbound = xrptr + *sfbwidth++; - rcount = channel->region0_count + 1; - - entry = &mad_huff_pair_table[channel->table_select[region = 0]]; - table = entry->table; - linbits = entry->linbits; - startbits = entry->startbits; - - if (table == 0) - return MAD_ERROR_BADHUFFTABLE; - - expptr = &exponents[0]; - exp = *expptr++; - reqhits = 0; - - big_values = channel->big_values; - - while (big_values-- && cachesz + bits_left > 0) { - union huffpair const *pair; - unsigned int clumpsz, value; - register mad_fixed_t requantized; - - if (xrptr == sfbound) { - sfbound += *sfbwidth++; - - /* change table if region boundary */ - - if (--rcount == 0) { - if (region == 0) - rcount = channel->region1_count + 1; - else - rcount = 0; /* all remaining */ - - entry = &mad_huff_pair_table[channel->table_select[++region]]; - table = entry->table; - linbits = entry->linbits; - startbits = entry->startbits; - - if (table == 0) - return MAD_ERROR_BADHUFFTABLE; - } + unsigned int part2_length) { + signed int exponents[39], exp; + signed int const *expptr; + struct mad_bitptr peek; + signed int bits_left, cachesz; + register mad_fixed_t *xrptr; + mad_fixed_t const *sfbound; + register unsigned long bitcache; + + stackenter(__FUNCTION__, __FILE__, __LINE__); + bits_left = (signed) channel->part2_3_length - (signed) part2_length; + if (bits_left < 0) { + return MAD_ERROR_BADPART3LEN; + } + + III_exponents(channel, sfbwidth, exponents); + + peek = *ptr; + mad_bit_skip(ptr, bits_left); + + /* align bit reads to byte boundaries */ + cachesz = mad_bit_bitsleft(&peek); + cachesz += ((32 - 1 - 24) + (24 - cachesz)) & ~7; + + bitcache = mad_bit_read(&peek, cachesz); + bits_left -= cachesz; + + xrptr = &xr[0]; - if (exp != *expptr) { - exp = *expptr; - reqhits = 0; + /* big_values */ + { + unsigned int region, rcount; + struct hufftable const *entry; + union huffpair const *table; + unsigned int linbits, startbits, big_values, reqhits; + mad_fixed_t reqcache[16]; + + sfbound = xrptr + *sfbwidth++; + rcount = channel->region0_count + 1; + + entry = &mad_huff_pair_table[channel->table_select[region = 0]]; + table = entry->table; + linbits = entry->linbits; + startbits = entry->startbits; + + if (table == 0) { + return MAD_ERROR_BADHUFFTABLE; } - ++expptr; - } + expptr = &exponents[0]; + exp = *expptr++; + reqhits = 0; - if (cachesz < 21) { - unsigned int bits; + big_values = channel->big_values; - bits = ((32 - 1 - 21) + (21 - cachesz)) & ~7; - bitcache = (bitcache << bits) | mad_bit_read(&peek, bits); - cachesz += bits; - bits_left -= bits; - } + while (big_values-- && cachesz + bits_left > 0) { + union huffpair const *pair; + unsigned int clumpsz, value; + register mad_fixed_t requantized; - /* hcod (0..19) */ + if (xrptr == sfbound) { + sfbound += *sfbwidth++; - clumpsz = startbits; - pair = &table[MASK(bitcache, cachesz, clumpsz)]; + /* change table if region boundary */ - while (!pair->final) { - cachesz -= clumpsz; + if (--rcount == 0) { + if (region == 0) { + rcount = channel->region1_count + 1; + } else { + rcount = 0; /* all remaining */ + } - clumpsz = pair->ptr.bits; - pair = &table[pair->ptr.offset + MASK(bitcache, cachesz, clumpsz)]; - } + entry = &mad_huff_pair_table[channel->table_select[++region]]; + table = entry->table; + linbits = entry->linbits; + startbits = entry->startbits; - cachesz -= pair->value.hlen; + if (table == 0) { + return MAD_ERROR_BADHUFFTABLE; + } + } - if (linbits) { - /* x (0..14) */ + if (exp != *expptr) { + exp = *expptr; + reqhits = 0; + } - value = pair->value.x; + ++expptr; + } - switch (value) { - case 0: - xrptr[0] = 0; - break; + if (cachesz < 21) { + unsigned int bits; - case 15: - if (cachesz < (int)(linbits + 2)) { - bitcache = (bitcache << 16) | mad_bit_read(&peek, 16); - cachesz += 16; - bits_left -= 16; + bits = ((32 - 1 - 21) + (21 - cachesz)) & ~7; + bitcache = (bitcache << bits) | mad_bit_read(&peek, bits); + cachesz += bits; + bits_left -= bits; } - value += MASK(bitcache, cachesz, linbits); - cachesz -= linbits; + /* hcod (0..19) */ - requantized = III_requantize(value, exp); - goto x_final; + clumpsz = startbits; + pair = &table[MASK(bitcache, cachesz, clumpsz)]; - default: - if (reqhits & (1 << value)) - requantized = reqcache[value]; - else { - reqhits |= (1 << value); - requantized = reqcache[value] = III_requantize(value, exp); + while (!pair->final) { + cachesz -= clumpsz; + + clumpsz = pair->ptr.bits; + pair = &table[pair->ptr.offset + MASK(bitcache, cachesz, clumpsz)]; } -x_final: - xrptr[0] = MASK1BIT(bitcache, cachesz--) ? - -requantized : requantized; - } + cachesz -= pair->value.hlen; - /* y (0..14) */ + if (linbits) { + /* x (0..14) */ - value = pair->value.y; + value = pair->value.x; - switch (value) { - case 0: - xrptr[1] = 0; - break; + switch (value) { + case 0: + xrptr[0] = 0; + break; - case 15: - if (cachesz < (int)(linbits + 1)) { - bitcache = (bitcache << 16) | mad_bit_read(&peek, 16); - cachesz += 16; - bits_left -= 16; - } + case 15: + if (cachesz < (int)(linbits + 2)) { + bitcache = (bitcache << 16) | mad_bit_read(&peek, 16); + cachesz += 16; + bits_left -= 16; + } - value += MASK(bitcache, cachesz, linbits); - cachesz -= linbits; + value += MASK(bitcache, cachesz, linbits); + cachesz -= linbits; - requantized = III_requantize(value, exp); - goto y_final; + requantized = III_requantize(value, exp); + goto x_final; - default: - if (reqhits & (1 << value)) - requantized = reqcache[value]; - else { - reqhits |= (1 << value); - requantized = reqcache[value] = III_requantize(value, exp); - } + default: + if (reqhits & (1 << value)) { + requantized = reqcache[value]; + } else { + reqhits |= (1 << value); + requantized = reqcache[value] = III_requantize(value, exp); + } -y_final: - xrptr[1] = MASK1BIT(bitcache, cachesz--) ? - -requantized : requantized; - } - } - else { - /* x (0..1) */ - - value = pair->value.x; - - if (value == 0) - xrptr[0] = 0; - else { - if (reqhits & (1 << value)) - requantized = reqcache[value]; - else { - reqhits |= (1 << value); - requantized = reqcache[value] = III_requantize(value, exp); - } - - xrptr[0] = MASK1BIT(bitcache, cachesz--) ? - -requantized : requantized; - } +x_final: + xrptr[0] = MASK1BIT(bitcache, cachesz--) ? + -requantized : requantized; + } - /* y (0..1) */ + /* y (0..14) */ - value = pair->value.y; + value = pair->value.y; - if (value == 0) - xrptr[1] = 0; - else { - if (reqhits & (1 << value)) - requantized = reqcache[value]; - else { - reqhits |= (1 << value); - requantized = reqcache[value] = III_requantize(value, exp); - } + switch (value) { + case 0: + xrptr[1] = 0; + break; - xrptr[1] = MASK1BIT(bitcache, cachesz--) ? - -requantized : requantized; - } - } + case 15: + if (cachesz < (int)(linbits + 1)) { + bitcache = (bitcache << 16) | mad_bit_read(&peek, 16); + cachesz += 16; + bits_left -= 16; + } + + value += MASK(bitcache, cachesz, linbits); + cachesz -= linbits; + + requantized = III_requantize(value, exp); + goto y_final; + + default: + if (reqhits & (1 << value)) { + requantized = reqcache[value]; + } else { + reqhits |= (1 << value); + requantized = reqcache[value] = III_requantize(value, exp); + } - xrptr += 2; +y_final: + xrptr[1] = MASK1BIT(bitcache, cachesz--) ? + -requantized : requantized; + } + } else { + /* x (0..1) */ + + value = pair->value.x; + + if (value == 0) { + xrptr[0] = 0; + } else { + if (reqhits & (1 << value)) { + requantized = reqcache[value]; + } else { + reqhits |= (1 << value); + requantized = reqcache[value] = III_requantize(value, exp); + } + + xrptr[0] = MASK1BIT(bitcache, cachesz--) ? + -requantized : requantized; + } + + /* y (0..1) */ + + value = pair->value.y; + + if (value == 0) { + xrptr[1] = 0; + } else { + if (reqhits & (1 << value)) { + requantized = reqcache[value]; + } else { + reqhits |= (1 << value); + requantized = reqcache[value] = III_requantize(value, exp); + } + + xrptr[1] = MASK1BIT(bitcache, cachesz--) ? + -requantized : requantized; + } + } + + xrptr += 2; + } } - } - if (cachesz + bits_left < 0) - return MAD_ERROR_BADHUFFDATA; /* big_values overrun */ + if (cachesz + bits_left < 0) { + return MAD_ERROR_BADHUFFDATA; /* big_values overrun */ + } - /* count1 */ - { - union huffquad const *table; - register mad_fixed_t requantized; + /* count1 */ + { + union huffquad const *table; + register mad_fixed_t requantized; - table = mad_huff_quad_table[channel->flags & count1table_select]; + table = mad_huff_quad_table[channel->flags & count1table_select]; - requantized = III_requantize(1, exp); + requantized = III_requantize(1, exp); - while (cachesz + bits_left > 0 && xrptr <= &xr[572]) { - union huffquad const *quad; + while (cachesz + bits_left > 0 && xrptr <= &xr[572]) { + union huffquad const *quad; - /* hcod (1..6) */ + /* hcod (1..6) */ - if (cachesz < 10) { - bitcache = (bitcache << 16) | mad_bit_read(&peek, 16); - cachesz += 16; - bits_left -= 16; - } + if (cachesz < 10) { + bitcache = (bitcache << 16) | mad_bit_read(&peek, 16); + cachesz += 16; + bits_left -= 16; + } - quad = &table[MASK(bitcache, cachesz, 4)]; + quad = &table[MASK(bitcache, cachesz, 4)]; - /* quad tables guaranteed to have at most one extra lookup */ - if (!quad->final) { - cachesz -= 4; + /* quad tables guaranteed to have at most one extra lookup */ + if (!quad->final) { + cachesz -= 4; - quad = &table[quad->ptr.offset + - MASK(bitcache, cachesz, quad->ptr.bits)]; - } + quad = &table[quad->ptr.offset + + MASK(bitcache, cachesz, quad->ptr.bits)]; + } - cachesz -= quad->value.hlen; + cachesz -= quad->value.hlen; - if (xrptr == sfbound) { - sfbound += *sfbwidth++; + if (xrptr == sfbound) { + sfbound += *sfbwidth++; - if (exp != *expptr) { - exp = *expptr; - requantized = III_requantize(1, exp); - } + if (exp != *expptr) { + exp = *expptr; + requantized = III_requantize(1, exp); + } - ++expptr; - } + ++expptr; + } - /* v (0..1) */ + /* v (0..1) */ - xrptr[0] = quad->value.v ? - (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; + xrptr[0] = quad->value.v ? + (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; - /* w (0..1) */ + /* w (0..1) */ - xrptr[1] = quad->value.w ? - (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; + xrptr[1] = quad->value.w ? + (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; - xrptr += 2; + xrptr += 2; - if (xrptr == sfbound) { - sfbound += *sfbwidth++; + if (xrptr == sfbound) { + sfbound += *sfbwidth++; - if (exp != *expptr) { - exp = *expptr; - requantized = III_requantize(1, exp); - } + if (exp != *expptr) { + exp = *expptr; + requantized = III_requantize(1, exp); + } - ++expptr; - } + ++expptr; + } - /* x (0..1) */ + /* x (0..1) */ - xrptr[0] = quad->value.x ? - (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; + xrptr[0] = quad->value.x ? + (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; - /* y (0..1) */ + /* y (0..1) */ - xrptr[1] = quad->value.y ? - (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; + xrptr[1] = quad->value.y ? + (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; - xrptr += 2; - } + xrptr += 2; + } - if (cachesz + bits_left < 0) { + if (cachesz + bits_left < 0) { # if 0 && defined(DEBUG) - fprintf(stderr, "huffman count1 overrun (%d bits)\n", - -(cachesz + bits_left)); + fprintf(stderr, "huffman count1 overrun (%d bits)\n", + -(cachesz + bits_left)); # endif - /* technically the bitstream is misformatted, but apparently - some encoders are just a bit sloppy with stuffing bits */ + /* technically the bitstream is misformatted, but apparently + some encoders are just a bit sloppy with stuffing bits */ - xrptr -= 4; + xrptr -= 4; + } } - } - assert(-bits_left <= MAD_BUFFER_GUARD * CHAR_BIT); + assert(-bits_left <= MAD_BUFFER_GUARD * CHAR_BIT); # if 0 && defined(DEBUG) - if (bits_left < 0) - fprintf(stderr, "read %d bits too many\n", -bits_left); - else if (cachesz + bits_left > 0) - fprintf(stderr, "%d stuffing bits\n", cachesz + bits_left); + if (bits_left < 0) { + fprintf(stderr, "read %d bits too many\n", -bits_left); + } else if (cachesz + bits_left > 0) { + fprintf(stderr, "%d stuffing bits\n", cachesz + bits_left); + } # endif - /* rzero */ - while (xrptr < &xr[576]) { - xrptr[0] = 0; - xrptr[1] = 0; + /* rzero */ + while (xrptr < &xr[576]) { + xrptr[0] = 0; + xrptr[1] = 0; - xrptr += 2; - } + xrptr += 2; + } - return MAD_ERROR_NONE; + return MAD_ERROR_NONE; } # undef MASK # undef MASK1BIT /* - NAME: III_reorder() - DESCRIPTION: reorder frequency lines of a short block into subband order + NAME: III_reorder() + DESCRIPTION: reorder frequency lines of a short block into subband order */ static enum mad_error III_reorder(mad_fixed_t xr[576], struct channel const *channel, - unsigned int const sfbwidth[39], mad_fixed_t tmp[576]) -{ - unsigned int sb, l, f, w, sbw[3], sw[3]; -// mad_fixed_t *tmp; // [32][3][6] - // See if we can allocate this buffer on the stack and save heap -// char onstack = 0; -// if (stackfree() > (int)(100 + sizeof(mad_fixed_t)*32*3*6)) { -// onstack = 1; -// tmp = alloca(sizeof(mad_fixed_t)*32*3*6); -// } else { -// tmp = (mad_fixed_t*)malloc(sizeof(mad_fixed_t)*32*3*6); -// if (!tmp) return MAD_ERROR_NOMEM; -// } - - stack(__FUNCTION__, __FILE__, __LINE__); - - /* this is probably wrong for 8000 Hz mixed blocks */ - - sb = 0; - if (channel->flags & mixed_block_flag) { - sb = 2; - - l = 0; - while (l < 36) - l += *sfbwidth++; - } - - for (w = 0; w < 3; ++w) { - sbw[w] = sb; - sw[w] = 0; - } - - f = *sfbwidth++; - w = 0; - - for (l = 18 * sb; l < 576; ++l) { - if (f-- == 0) { - f = *sfbwidth++ - 1; - w = (w + 1) % 3; + unsigned int const sfbwidth[39], mad_fixed_t tmp[576]) { + unsigned int sb, l, f, w, sbw[3], sw[3]; + // mad_fixed_t *tmp; // [32][3][6] + // See if we can allocate this buffer on the stack and save heap + // char onstack = 0; + // if (stackfree() > (int)(100 + sizeof(mad_fixed_t)*32*3*6)) { + // onstack = 1; + // tmp = alloca(sizeof(mad_fixed_t)*32*3*6); + // } else { + // tmp = (mad_fixed_t*)malloc(sizeof(mad_fixed_t)*32*3*6); + // if (!tmp) return MAD_ERROR_NOMEM; + // } + + stackenter(__FUNCTION__, __FILE__, __LINE__); + + /* this is probably wrong for 8000 Hz mixed blocks */ + + sb = 0; + if (channel->flags & mixed_block_flag) { + sb = 2; + + l = 0; + while (l < 36) { + l += *sfbwidth++; + } } - tmp[ (sbw[w]*3*6) + (w*6) + (sw[w]++) ] = xr[l]; + for (w = 0; w < 3; ++w) { + sbw[w] = sb; + sw[w] = 0; + } + + f = *sfbwidth++; + w = 0; + + for (l = 18 * sb; l < 576; ++l) { + if (f-- == 0) { + f = *sfbwidth++ - 1; + w = (w + 1) % 3; + } + + tmp[(sbw[w] * 3 * 6) + (w * 6) + (sw[w]++) ] = xr[l]; - if (sw[w] == 6) { - sw[w] = 0; - ++sbw[w]; + if (sw[w] == 6) { + sw[w] = 0; + ++sbw[w]; + } } - } - memcpy(&xr[18 * sb], &tmp[sb * 3 * 6], (576 - 18 * sb) * sizeof(mad_fixed_t)); + memcpy(&xr[18 * sb], &tmp[sb * 3 * 6], (576 - 18 * sb) * sizeof(mad_fixed_t)); -// if (!onstack) free(tmp); -// // If it's on the stack, it'll go away on the return - return MAD_ERROR_NONE; + // if (!onstack) free(tmp); + // // If it's on the stack, it'll go away on the return + return MAD_ERROR_NONE; } /* - NAME: III_stereo() - DESCRIPTION: perform joint stereo processing on a granule + NAME: III_stereo() + DESCRIPTION: perform joint stereo processing on a granule */ static enum mad_error III_stereo(mad_fixed_t xr[2][576], struct granule const *granule, struct mad_header *header, - unsigned int const *sfbwidth) -{ - short modes[39]; - unsigned int sfbi, l, n, i; - stack(__FUNCTION__, __FILE__, __LINE__); + unsigned int const *sfbwidth) { + short modes[39]; + unsigned int sfbi, l, n, i; + stackenter(__FUNCTION__, __FILE__, __LINE__); + + if (granule->ch[0].block_type != + granule->ch[1].block_type || + (granule->ch[0].flags & mixed_block_flag) != + (granule->ch[1].flags & mixed_block_flag)) { + return MAD_ERROR_BADSTEREO; + } - if (granule->ch[0].block_type != - granule->ch[1].block_type || - (granule->ch[0].flags & mixed_block_flag) != - (granule->ch[1].flags & mixed_block_flag)) - return MAD_ERROR_BADSTEREO; + for (i = 0; i < 39; ++i) { + modes[i] = header->mode_extension; + } - for (i = 0; i < 39; ++i) - modes[i] = header->mode_extension; + /* intensity stereo */ - /* intensity stereo */ + if (header->mode_extension & I_STEREO) { + struct channel const *right_ch = &granule->ch[1]; + mad_fixed_t const *right_xr = xr[1]; + unsigned int is_pos; - if (header->mode_extension & I_STEREO) { - struct channel const *right_ch = &granule->ch[1]; - mad_fixed_t const *right_xr = xr[1]; - unsigned int is_pos; + header->flags |= MAD_FLAG_I_STEREO; - header->flags |= MAD_FLAG_I_STEREO; + /* first determine which scalefactor bands are to be processed */ - /* first determine which scalefactor bands are to be processed */ + if (right_ch->block_type == 2) { + unsigned int lower, start, max, bound[3], w; - if (right_ch->block_type == 2) { - unsigned int lower, start, max, bound[3], w; + lower = start = max = bound[0] = bound[1] = bound[2] = 0; - lower = start = max = bound[0] = bound[1] = bound[2] = 0; + sfbi = l = 0; - sfbi = l = 0; + if (right_ch->flags & mixed_block_flag) { + while (l < 36) { + n = sfbwidth[sfbi++]; - if (right_ch->flags & mixed_block_flag) { - while (l < 36) { - n = sfbwidth[sfbi++]; + for (i = 0; i < n; ++i) { + if (right_xr[i]) { + lower = sfbi; + break; + } + } - for (i = 0; i < n; ++i) { - if (right_xr[i]) { - lower = sfbi; - break; + right_xr += n; + l += n; + } + + start = sfbi; } - } - right_xr += n; - l += n; - } + w = 0; + while (l < 576) { + n = sfbwidth[sfbi++]; - start = sfbi; - } + for (i = 0; i < n; ++i) { + if (right_xr[i]) { + max = bound[w] = sfbi; + break; + } + } - w = 0; - while (l < 576) { - n = sfbwidth[sfbi++]; + right_xr += n; + l += n; + w = (w + 1) % 3; + } - for (i = 0; i < n; ++i) { - if (right_xr[i]) { - max = bound[w] = sfbi; - break; - } - } + if (max) { + lower = start; + } - right_xr += n; - l += n; - w = (w + 1) % 3; - } + /* long blocks */ - if (max) - lower = start; + for (i = 0; i < lower; ++i) { + modes[i] = header->mode_extension & ~I_STEREO; + } - /* long blocks */ + /* short blocks */ - for (i = 0; i < lower; ++i) - modes[i] = header->mode_extension & ~I_STEREO; + w = 0; + for (i = start; i < max; ++i) { + if (i < bound[w]) { + modes[i] = header->mode_extension & ~I_STEREO; + } - /* short blocks */ + w = (w + 1) % 3; + } + } else { /* right_ch->block_type != 2 */ + unsigned int bound; - w = 0; - for (i = start; i < max; ++i) { - if (i < bound[w]) - modes[i] = header->mode_extension & ~I_STEREO; + bound = 0; + for (sfbi = l = 0; l < 576; l += n) { + n = sfbwidth[sfbi++]; - w = (w + 1) % 3; - } - } - else { /* right_ch->block_type != 2 */ - unsigned int bound; - - bound = 0; - for (sfbi = l = 0; l < 576; l += n) { - n = sfbwidth[sfbi++]; - - for (i = 0; i < n; ++i) { - if (right_xr[i]) { - bound = sfbi; - break; - } - } + for (i = 0; i < n; ++i) { + if (right_xr[i]) { + bound = sfbi; + break; + } + } - right_xr += n; - } + right_xr += n; + } - for (i = 0; i < bound; ++i) - modes[i] = header->mode_extension & ~I_STEREO; - } + for (i = 0; i < bound; ++i) { + modes[i] = header->mode_extension & ~I_STEREO; + } + } - /* now do the actual processing */ + /* now do the actual processing */ - if (header->flags & MAD_FLAG_LSF_EXT) { - unsigned char const *illegal_pos = granule[1].ch[1].scalefac; - mad_fixed_t const *lsf_scale; + if (header->flags & MAD_FLAG_LSF_EXT) { + unsigned char const *illegal_pos = granule[1].ch[1].scalefac; + mad_fixed_t const *lsf_scale; - /* intensity_scale */ - lsf_scale = is_lsf_table[right_ch->scalefac_compress & 0x1]; + /* intensity_scale */ + lsf_scale = is_lsf_table[right_ch->scalefac_compress & 0x1]; - for (sfbi = l = 0; l < 576; ++sfbi, l += n) { - n = sfbwidth[sfbi]; + for (sfbi = l = 0; l < 576; ++sfbi, l += n) { + n = sfbwidth[sfbi]; - if (!(modes[sfbi] & I_STEREO)) - continue; + if (!(modes[sfbi] & I_STEREO)) { + continue; + } - if (illegal_pos[sfbi]) { - modes[sfbi] &= ~I_STEREO; - continue; - } + if (illegal_pos[sfbi]) { + modes[sfbi] &= ~I_STEREO; + continue; + } - is_pos = right_ch->scalefac[sfbi]; + is_pos = right_ch->scalefac[sfbi]; - for (i = 0; i < n; ++i) { - register mad_fixed_t left; + for (i = 0; i < n; ++i) { + register mad_fixed_t left; - left = xr[0][l + i]; + left = xr[0][l + i]; - if (is_pos == 0) - xr[1][l + i] = left; - else { - register mad_fixed_t opposite; + if (is_pos == 0) { + xr[1][l + i] = left; + } else { + register mad_fixed_t opposite; - opposite = mad_f_mul(left, lsf_scale[(is_pos - 1) / 2]); + opposite = mad_f_mul(left, lsf_scale[(is_pos - 1) / 2]); - if (is_pos & 1) { - xr[0][l + i] = opposite; - xr[1][l + i] = left; + if (is_pos & 1) { + xr[0][l + i] = opposite; + xr[1][l + i] = left; + } else { + xr[1][l + i] = opposite; + } + } + } } - else - xr[1][l + i] = opposite; - } - } - } - } - else { /* !(header->flags & MAD_FLAG_LSF_EXT) */ - for (sfbi = l = 0; l < 576; ++sfbi, l += n) { - n = sfbwidth[sfbi]; + } else { /* !(header->flags & MAD_FLAG_LSF_EXT) */ + for (sfbi = l = 0; l < 576; ++sfbi, l += n) { + n = sfbwidth[sfbi]; - if (!(modes[sfbi] & I_STEREO)) - continue; + if (!(modes[sfbi] & I_STEREO)) { + continue; + } - is_pos = right_ch->scalefac[sfbi]; + is_pos = right_ch->scalefac[sfbi]; - if (is_pos >= 7) { /* illegal intensity position */ - modes[sfbi] &= ~I_STEREO; - continue; - } + if (is_pos >= 7) { /* illegal intensity position */ + modes[sfbi] &= ~I_STEREO; + continue; + } - for (i = 0; i < n; ++i) { - register mad_fixed_t left; + for (i = 0; i < n; ++i) { + register mad_fixed_t left; - left = xr[0][l + i]; + left = xr[0][l + i]; - xr[0][l + i] = mad_f_mul(left, is_table( is_pos)); - xr[1][l + i] = mad_f_mul(left, is_table(6 - is_pos)); + xr[0][l + i] = mad_f_mul(left, is_table(is_pos)); + xr[1][l + i] = mad_f_mul(left, is_table(6 - is_pos)); + } + } } - } } - } - /* middle/side stereo */ + /* middle/side stereo */ - if (header->mode_extension & MS_STEREO) { - register mad_fixed_t invsqrt2; + if (header->mode_extension & MS_STEREO) { + register mad_fixed_t invsqrt2; - header->flags |= MAD_FLAG_MS_STEREO; + header->flags |= MAD_FLAG_MS_STEREO; - invsqrt2 = root_table(3 + -2); + invsqrt2 = root_table(3 + -2); - for (sfbi = l = 0; l < 576; ++sfbi, l += n) { - n = sfbwidth[sfbi]; + for (sfbi = l = 0; l < 576; ++sfbi, l += n) { + n = sfbwidth[sfbi]; - if (modes[sfbi] != MS_STEREO) - continue; + if (modes[sfbi] != MS_STEREO) { + continue; + } - for (i = 0; i < n; ++i) { - register mad_fixed_t m, s; + for (i = 0; i < n; ++i) { + register mad_fixed_t m, s; - m = xr[0][l + i]; - s = xr[1][l + i]; + m = xr[0][l + i]; + s = xr[1][l + i]; - xr[0][l + i] = mad_f_mul(m + s, invsqrt2); /* l = (m + s) / sqrt(2) */ - xr[1][l + i] = mad_f_mul(m - s, invsqrt2); /* r = (m - s) / sqrt(2) */ - } + xr[0][l + i] = mad_f_mul(m + s, invsqrt2); /* l = (m + s) / sqrt(2) */ + xr[1][l + i] = mad_f_mul(m - s, invsqrt2); /* r = (m - s) / sqrt(2) */ + } + } } - } - return MAD_ERROR_NONE; + return MAD_ERROR_NONE; } /* - NAME: III_aliasreduce() - DESCRIPTION: perform frequency line alias reduction + NAME: III_aliasreduce() + DESCRIPTION: perform frequency line alias reduction */ static -void III_aliasreduce(mad_fixed_t xr[576], int lines) -{ - mad_fixed_t const *bound; - int i; - stack(__FUNCTION__, __FILE__, __LINE__); - - bound = &xr[lines]; - for (xr += 18; xr < bound; xr += 18) { - for (i = 0; i < 8; ++i) { - register mad_fixed_t a, b; - register mad_fixed64hi_t hi; - register mad_fixed64lo_t lo; - - a = xr[-1 - i]; - b = xr[ i]; +void III_aliasreduce(mad_fixed_t xr[576], int lines) { + mad_fixed_t const *bound; + int i; + stackenter(__FUNCTION__, __FILE__, __LINE__); + + bound = &xr[lines]; + for (xr += 18; xr < bound; xr += 18) { + for (i = 0; i < 8; ++i) { + register mad_fixed_t a, b; + register mad_fixed64hi_t hi; + register mad_fixed64lo_t lo; + + a = xr[-1 - i]; + b = xr[ i]; # if defined(ASO_ZEROCHECK) - if (a | b) { + if (a | b) { # endif - MAD_F_ML0(hi, lo, a, cs(i)); - MAD_F_MLA(hi, lo, -b, ca(i)); + MAD_F_ML0(hi, lo, a, cs(i)); + MAD_F_MLA(hi, lo, -b, ca(i)); - xr[-1 - i] = MAD_F_MLZ(hi, lo); + xr[-1 - i] = MAD_F_MLZ(hi, lo); - MAD_F_ML0(hi, lo, b, cs(i)); - MAD_F_MLA(hi, lo, a, ca(i)); + MAD_F_ML0(hi, lo, b, cs(i)); + MAD_F_MLA(hi, lo, a, ca(i)); - xr[ i] = MAD_F_MLZ(hi, lo); + xr[ i] = MAD_F_MLZ(hi, lo); # if defined(ASO_ZEROCHECK) - } + } # endif + } } - } } # if defined(ASO_IMDCT) @@ -1636,1134 +1641,1141 @@ void III_imdct_l(mad_fixed_t const [18], mad_fixed_t [36], unsigned int); # else # if 1 static -void fastsdct(mad_fixed_t const x[9], mad_fixed_t y[18]) -{ - mad_fixed_t a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12; - mad_fixed_t a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25; - mad_fixed_t m0, m1, m2, m3, m4, m5, m6, m7; - - enum { - c0 = MAD_F(0x1f838b8d), /* 2 * cos( 1 * PI / 18) */ - c1 = MAD_F(0x1bb67ae8), /* 2 * cos( 3 * PI / 18) */ - c2 = MAD_F(0x18836fa3), /* 2 * cos( 4 * PI / 18) */ - c3 = MAD_F(0x1491b752), /* 2 * cos( 5 * PI / 18) */ - c4 = MAD_F(0x0af1d43a), /* 2 * cos( 7 * PI / 18) */ - c5 = MAD_F(0x058e86a0), /* 2 * cos( 8 * PI / 18) */ - c6 = -MAD_F(0x1e11f642) /* 2 * cos(16 * PI / 18) */ - }; - - a0 = x[3] + x[5]; - a1 = x[3] - x[5]; - a2 = x[6] + x[2]; - a3 = x[6] - x[2]; - a4 = x[1] + x[7]; - a5 = x[1] - x[7]; - a6 = x[8] + x[0]; - a7 = x[8] - x[0]; - - a8 = a0 + a2; - a9 = a0 - a2; - a10 = a0 - a6; - a11 = a2 - a6; - a12 = a8 + a6; - a13 = a1 - a3; - a14 = a13 + a7; - a15 = a3 + a7; - a16 = a1 - a7; - a17 = a1 + a3; - - m0 = mad_f_mul(a17, -c3); - m1 = mad_f_mul(a16, -c0); - m2 = mad_f_mul(a15, -c4); - m3 = mad_f_mul(a14, -c1); - m4 = mad_f_mul(a5, -c1); - m5 = mad_f_mul(a11, -c6); - m6 = mad_f_mul(a10, -c5); - m7 = mad_f_mul(a9, -c2); - - a18 = x[4] + a4; - a19 = 2 * x[4] - a4; - a20 = a19 + m5; - a21 = a19 - m5; - a22 = a19 + m6; - a23 = m4 + m2; - a24 = m4 - m2; - a25 = m4 + m1; - - /* output to every other slot for convenience */ - - y[ 0] = a18 + a12; - y[ 2] = m0 - a25; - y[ 4] = m7 - a20; - y[ 6] = m3; - y[ 8] = a21 - m6; - y[10] = a24 - m1; - y[12] = a12 - 2 * a18; - y[14] = a23 + m0; - y[16] = a22 + m7; +void fastsdct(mad_fixed_t const x[9], mad_fixed_t y[18]) { + mad_fixed_t a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12; + mad_fixed_t a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25; + mad_fixed_t m0, m1, m2, m3, m4, m5, m6, m7; + + enum { + c0 = MAD_F(0x1f838b8d), /* 2 * cos( 1 * PI / 18) */ + c1 = MAD_F(0x1bb67ae8), /* 2 * cos( 3 * PI / 18) */ + c2 = MAD_F(0x18836fa3), /* 2 * cos( 4 * PI / 18) */ + c3 = MAD_F(0x1491b752), /* 2 * cos( 5 * PI / 18) */ + c4 = MAD_F(0x0af1d43a), /* 2 * cos( 7 * PI / 18) */ + c5 = MAD_F(0x058e86a0), /* 2 * cos( 8 * PI / 18) */ + c6 = -MAD_F(0x1e11f642) /* 2 * cos(16 * PI / 18) */ + }; + + a0 = x[3] + x[5]; + a1 = x[3] - x[5]; + a2 = x[6] + x[2]; + a3 = x[6] - x[2]; + a4 = x[1] + x[7]; + a5 = x[1] - x[7]; + a6 = x[8] + x[0]; + a7 = x[8] - x[0]; + + a8 = a0 + a2; + a9 = a0 - a2; + a10 = a0 - a6; + a11 = a2 - a6; + a12 = a8 + a6; + a13 = a1 - a3; + a14 = a13 + a7; + a15 = a3 + a7; + a16 = a1 - a7; + a17 = a1 + a3; + + m0 = mad_f_mul(a17, -c3); + m1 = mad_f_mul(a16, -c0); + m2 = mad_f_mul(a15, -c4); + m3 = mad_f_mul(a14, -c1); + m4 = mad_f_mul(a5, -c1); + m5 = mad_f_mul(a11, -c6); + m6 = mad_f_mul(a10, -c5); + m7 = mad_f_mul(a9, -c2); + + a18 = x[4] + a4; + a19 = 2 * x[4] - a4; + a20 = a19 + m5; + a21 = a19 - m5; + a22 = a19 + m6; + a23 = m4 + m2; + a24 = m4 - m2; + a25 = m4 + m1; + + /* output to every other slot for convenience */ + + y[ 0] = a18 + a12; + y[ 2] = m0 - a25; + y[ 4] = m7 - a20; + y[ 6] = m3; + y[ 8] = a21 - m6; + y[10] = a24 - m1; + y[12] = a12 - 2 * a18; + y[14] = a23 + m0; + y[16] = a22 + m7; } static inline -void sdctII(mad_fixed_t const x[18], mad_fixed_t X[18]) -{ - mad_fixed_t tmp[9]; - int i; - stack(__FUNCTION__, __FILE__, __LINE__); - - /* scale[i] = 2 * cos(PI * (2 * i + 1) / (2 * 18)) */ - static mad_fixed_t const scale[9] PROGMEM = { - MAD_F(0x1fe0d3b4), MAD_F(0x1ee8dd47), MAD_F(0x1d007930), - MAD_F(0x1a367e59), MAD_F(0x16a09e66), MAD_F(0x125abcf8), - MAD_F(0x0d8616bc), MAD_F(0x08483ee1), MAD_F(0x02c9fad7) - }; - - /* divide the 18-point SDCT-II into two 9-point SDCT-IIs */ - - /* even input butterfly */ - - for (i = 0; i < 9; i += 3) { - tmp[i + 0] = x[i + 0] + x[18 - (i + 0) - 1]; - tmp[i + 1] = x[i + 1] + x[18 - (i + 1) - 1]; - tmp[i + 2] = x[i + 2] + x[18 - (i + 2) - 1]; - } - - fastsdct(tmp, &X[0]); - - /* odd input butterfly and scaling */ - - for (i = 0; i < 9; i += 3) { - mad_fixed_t s; - s = *(volatile mad_fixed_t*)(volatile uint32_t*)&scale[i + 0]; tmp[i + 0] = mad_f_mul(x[i + 0] - x[18 - (i + 0) - 1], s); //scale[i + 0]); - s = *(volatile mad_fixed_t*)(volatile uint32_t*)&scale[i + 1]; tmp[i + 1] = mad_f_mul(x[i + 1] - x[18 - (i + 1) - 1], s); //scale[i + 1]); - s = *(volatile mad_fixed_t*)(volatile uint32_t*)&scale[i + 2]; tmp[i + 2] = mad_f_mul(x[i + 2] - x[18 - (i + 2) - 1], s); //scale[i + 2]); - } - - fastsdct(tmp, &X[1]); - - /* output accumulation */ - - for (i = 3; i < 18; i += 8) { - X[i + 0] -= X[(i + 0) - 2]; - X[i + 2] -= X[(i + 2) - 2]; - X[i + 4] -= X[(i + 4) - 2]; - X[i + 6] -= X[(i + 6) - 2]; - } +void sdctII(mad_fixed_t const x[18], mad_fixed_t X[18]) { + mad_fixed_t tmp[9]; + int i; + stackenter(__FUNCTION__, __FILE__, __LINE__); + + /* scale[i] = 2 * cos(PI * (2 * i + 1) / (2 * 18)) */ + static mad_fixed_t const scale[9] PROGMEM = { + MAD_F(0x1fe0d3b4), MAD_F(0x1ee8dd47), MAD_F(0x1d007930), + MAD_F(0x1a367e59), MAD_F(0x16a09e66), MAD_F(0x125abcf8), + MAD_F(0x0d8616bc), MAD_F(0x08483ee1), MAD_F(0x02c9fad7) + }; + + /* divide the 18-point SDCT-II into two 9-point SDCT-IIs */ + + /* even input butterfly */ + + for (i = 0; i < 9; i += 3) { + tmp[i + 0] = x[i + 0] + x[18 - (i + 0) - 1]; + tmp[i + 1] = x[i + 1] + x[18 - (i + 1) - 1]; + tmp[i + 2] = x[i + 2] + x[18 - (i + 2) - 1]; + } + + fastsdct(tmp, &X[0]); + + /* odd input butterfly and scaling */ + + for (i = 0; i < 9; i += 3) { + mad_fixed_t s; + s = *(volatile mad_fixed_t*)(volatile uint32_t*)&scale[i + 0]; tmp[i + 0] = mad_f_mul(x[i + 0] - x[18 - (i + 0) - 1], s); //scale[i + 0]); + s = *(volatile mad_fixed_t*)(volatile uint32_t*)&scale[i + 1]; tmp[i + 1] = mad_f_mul(x[i + 1] - x[18 - (i + 1) - 1], s); //scale[i + 1]); + s = *(volatile mad_fixed_t*)(volatile uint32_t*)&scale[i + 2]; tmp[i + 2] = mad_f_mul(x[i + 2] - x[18 - (i + 2) - 1], s); //scale[i + 2]); + } + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overflow" + fastsdct(tmp, &X[1]); +#pragma GCC diagnostic pop + + /* output accumulation */ + + for (i = 3; i < 18; i += 8) { + X[i + 0] -= X[(i + 0) - 2]; + X[i + 2] -= X[(i + 2) - 2]; + X[i + 4] -= X[(i + 4) - 2]; + X[i + 6] -= X[(i + 6) - 2]; + } } static inline -void dctIV(mad_fixed_t const y[18], mad_fixed_t X[18]) -{ - mad_fixed_t tmp[18]; - int i; - stack(__FUNCTION__, __FILE__, __LINE__); - - /* scale[i] = 2 * cos(PI * (2 * i + 1) / (4 * 18)) */ - static mad_fixed_t const scale[18] PROGMEM = { - MAD_F(0x1ff833fa), MAD_F(0x1fb9ea93), MAD_F(0x1f3dd120), - MAD_F(0x1e84d969), MAD_F(0x1d906bcf), MAD_F(0x1c62648b), - MAD_F(0x1afd100f), MAD_F(0x1963268b), MAD_F(0x1797c6a4), - MAD_F(0x159e6f5b), MAD_F(0x137af940), MAD_F(0x11318ef3), - MAD_F(0x0ec6a507), MAD_F(0x0c3ef153), MAD_F(0x099f61c5), - MAD_F(0x06ed12c5), MAD_F(0x042d4544), MAD_F(0x0165547c) - }; - - /* scaling */ - - for (i = 0; i < 18; i += 3) { - mad_fixed_t s; - s = *(volatile mad_fixed_t*)(volatile uint32_t*)&scale[i + 0]; tmp[i + 0] = mad_f_mul(y[i + 0], s); //scale[i + 0]); - s = *(volatile mad_fixed_t*)(volatile uint32_t*)&scale[i + 1]; tmp[i + 1] = mad_f_mul(y[i + 1], s); //scale[i + 1]); - s = *(volatile mad_fixed_t*)(volatile uint32_t*)&scale[i + 2]; tmp[i + 2] = mad_f_mul(y[i + 2], s); //scale[i + 2]); - } - - /* SDCT-II */ - - sdctII(tmp, X); - - /* scale reduction and output accumulation */ - - X[0] /= 2; - for (i = 1; i < 17; i += 4) { - X[i + 0] = X[i + 0] / 2 - X[(i + 0) - 1]; - X[i + 1] = X[i + 1] / 2 - X[(i + 1) - 1]; - X[i + 2] = X[i + 2] / 2 - X[(i + 2) - 1]; - X[i + 3] = X[i + 3] / 2 - X[(i + 3) - 1]; - } - X[17] = X[17] / 2 - X[16]; +void dctIV(mad_fixed_t const y[18], mad_fixed_t X[18]) { + mad_fixed_t tmp[18]; + int i; + stackenter(__FUNCTION__, __FILE__, __LINE__); + + /* scale[i] = 2 * cos(PI * (2 * i + 1) / (4 * 18)) */ + static mad_fixed_t const scale[18] PROGMEM = { + MAD_F(0x1ff833fa), MAD_F(0x1fb9ea93), MAD_F(0x1f3dd120), + MAD_F(0x1e84d969), MAD_F(0x1d906bcf), MAD_F(0x1c62648b), + MAD_F(0x1afd100f), MAD_F(0x1963268b), MAD_F(0x1797c6a4), + MAD_F(0x159e6f5b), MAD_F(0x137af940), MAD_F(0x11318ef3), + MAD_F(0x0ec6a507), MAD_F(0x0c3ef153), MAD_F(0x099f61c5), + MAD_F(0x06ed12c5), MAD_F(0x042d4544), MAD_F(0x0165547c) + }; + + /* scaling */ + + for (i = 0; i < 18; i += 3) { + mad_fixed_t s; + s = *(volatile mad_fixed_t*)(volatile uint32_t*)&scale[i + 0]; tmp[i + 0] = mad_f_mul(y[i + 0], s); //scale[i + 0]); + s = *(volatile mad_fixed_t*)(volatile uint32_t*)&scale[i + 1]; tmp[i + 1] = mad_f_mul(y[i + 1], s); //scale[i + 1]); + s = *(volatile mad_fixed_t*)(volatile uint32_t*)&scale[i + 2]; tmp[i + 2] = mad_f_mul(y[i + 2], s); //scale[i + 2]); + } + + /* SDCT-II */ + + sdctII(tmp, X); + + /* scale reduction and output accumulation */ + + X[0] /= 2; + for (i = 1; i < 17; i += 4) { + X[i + 0] = X[i + 0] / 2 - X[(i + 0) - 1]; + X[i + 1] = X[i + 1] / 2 - X[(i + 1) - 1]; + X[i + 2] = X[i + 2] / 2 - X[(i + 2) - 1]; + X[i + 3] = X[i + 3] / 2 - X[(i + 3) - 1]; + } + X[17] = X[17] / 2 - X[16]; } /* - NAME: imdct36 - DESCRIPTION: perform X[18]->x[36] IMDCT using Szu-Wei Lee's fast algorithm + NAME: imdct36 + DESCRIPTION: perform X[18]->x[36] IMDCT using Szu-Wei Lee's fast algorithm */ static inline -void imdct36(mad_fixed_t const x[18], mad_fixed_t y[36]) -{ - mad_fixed_t tmp[18]; - int i; - stack(__FUNCTION__, __FILE__, __LINE__); - - /* DCT-IV */ - - dctIV(x, tmp); - - /* convert 18-point DCT-IV to 36-point IMDCT */ - - for (i = 0; i < 9; i += 3) { - y[i + 0] = tmp[9 + (i + 0)]; - y[i + 1] = tmp[9 + (i + 1)]; - y[i + 2] = tmp[9 + (i + 2)]; - } - for (i = 9; i < 27; i += 3) { - y[i + 0] = -tmp[36 - (9 + (i + 0)) - 1]; - y[i + 1] = -tmp[36 - (9 + (i + 1)) - 1]; - y[i + 2] = -tmp[36 - (9 + (i + 2)) - 1]; - } - for (i = 27; i < 36; i += 3) { - y[i + 0] = -tmp[(i + 0) - 27]; - y[i + 1] = -tmp[(i + 1) - 27]; - y[i + 2] = -tmp[(i + 2) - 27]; - } +void imdct36(mad_fixed_t const x[18], mad_fixed_t y[36]) { + mad_fixed_t tmp[18]; + int i; + stackenter(__FUNCTION__, __FILE__, __LINE__); + + /* DCT-IV */ + + dctIV(x, tmp); + + /* convert 18-point DCT-IV to 36-point IMDCT */ + + for (i = 0; i < 9; i += 3) { + y[i + 0] = tmp[9 + (i + 0)]; + y[i + 1] = tmp[9 + (i + 1)]; + y[i + 2] = tmp[9 + (i + 2)]; + } + for (i = 9; i < 27; i += 3) { + y[i + 0] = -tmp[36 - (9 + (i + 0)) - 1]; + y[i + 1] = -tmp[36 - (9 + (i + 1)) - 1]; + y[i + 2] = -tmp[36 - (9 + (i + 2)) - 1]; + } + for (i = 27; i < 36; i += 3) { + y[i + 0] = -tmp[(i + 0) - 27]; + y[i + 1] = -tmp[(i + 1) - 27]; + y[i + 2] = -tmp[(i + 2) - 27]; + } } # else /* - NAME: imdct36 - DESCRIPTION: perform X[18]->x[36] IMDCT + NAME: imdct36 + DESCRIPTION: perform X[18]->x[36] IMDCT */ static inline -void imdct36(mad_fixed_t const X[18], mad_fixed_t x[36]) -{ - mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7; - mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15; - register mad_fixed64hi_t hi; - register mad_fixed64lo_t lo; - - MAD_F_ML0(hi, lo, X[4], MAD_F(0x0ec835e8)); - MAD_F_MLA(hi, lo, X[13], MAD_F(0x061f78aa)); - - t6 = MAD_F_MLZ(hi, lo); - - MAD_F_MLA(hi, lo, (t14 = X[1] - X[10]), -MAD_F(0x061f78aa)); - MAD_F_MLA(hi, lo, (t15 = X[7] + X[16]), -MAD_F(0x0ec835e8)); - - t0 = MAD_F_MLZ(hi, lo); - - MAD_F_MLA(hi, lo, (t8 = X[0] - X[11] - X[12]), MAD_F(0x0216a2a2)); - MAD_F_MLA(hi, lo, (t9 = X[2] - X[9] - X[14]), MAD_F(0x09bd7ca0)); - MAD_F_MLA(hi, lo, (t10 = X[3] - X[8] - X[15]), -MAD_F(0x0cb19346)); - MAD_F_MLA(hi, lo, (t11 = X[5] - X[6] - X[17]), -MAD_F(0x0fdcf549)); - - x[7] = MAD_F_MLZ(hi, lo); - x[10] = -x[7]; - - MAD_F_ML0(hi, lo, t8, -MAD_F(0x0cb19346)); - MAD_F_MLA(hi, lo, t9, MAD_F(0x0fdcf549)); - MAD_F_MLA(hi, lo, t10, MAD_F(0x0216a2a2)); - MAD_F_MLA(hi, lo, t11, -MAD_F(0x09bd7ca0)); - - x[19] = x[34] = MAD_F_MLZ(hi, lo) - t0; - - t12 = X[0] - X[3] + X[8] - X[11] - X[12] + X[15]; - t13 = X[2] + X[5] - X[6] - X[9] - X[14] - X[17]; - - MAD_F_ML0(hi, lo, t12, -MAD_F(0x0ec835e8)); - MAD_F_MLA(hi, lo, t13, MAD_F(0x061f78aa)); - - x[22] = x[31] = MAD_F_MLZ(hi, lo) + t0; - - MAD_F_ML0(hi, lo, X[1], -MAD_F(0x09bd7ca0)); - MAD_F_MLA(hi, lo, X[7], MAD_F(0x0216a2a2)); - MAD_F_MLA(hi, lo, X[10], -MAD_F(0x0fdcf549)); - MAD_F_MLA(hi, lo, X[16], MAD_F(0x0cb19346)); - - t1 = MAD_F_MLZ(hi, lo) + t6; - - MAD_F_ML0(hi, lo, X[0], MAD_F(0x03768962)); - MAD_F_MLA(hi, lo, X[2], MAD_F(0x0e313245)); - MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0ffc19fd)); - MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0acf37ad)); - MAD_F_MLA(hi, lo, X[6], MAD_F(0x04cfb0e2)); - MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0898c779)); - MAD_F_MLA(hi, lo, X[9], MAD_F(0x0d7e8807)); - MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f426cb5)); - MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0bcbe352)); - MAD_F_MLA(hi, lo, X[14], MAD_F(0x00b2aa3e)); - MAD_F_MLA(hi, lo, X[15], -MAD_F(0x07635284)); - MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0f9ee890)); - - x[6] = MAD_F_MLZ(hi, lo) + t1; - x[11] = -x[6]; - - MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f426cb5)); - MAD_F_MLA(hi, lo, X[2], -MAD_F(0x00b2aa3e)); - MAD_F_MLA(hi, lo, X[3], MAD_F(0x0898c779)); - MAD_F_MLA(hi, lo, X[5], MAD_F(0x0f9ee890)); - MAD_F_MLA(hi, lo, X[6], MAD_F(0x0acf37ad)); - MAD_F_MLA(hi, lo, X[8], -MAD_F(0x07635284)); - MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0e313245)); - MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0bcbe352)); - MAD_F_MLA(hi, lo, X[12], -MAD_F(0x03768962)); - MAD_F_MLA(hi, lo, X[14], MAD_F(0x0d7e8807)); - MAD_F_MLA(hi, lo, X[15], MAD_F(0x0ffc19fd)); - MAD_F_MLA(hi, lo, X[17], MAD_F(0x04cfb0e2)); - - x[23] = x[30] = MAD_F_MLZ(hi, lo) + t1; - - MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0bcbe352)); - MAD_F_MLA(hi, lo, X[2], MAD_F(0x0d7e8807)); - MAD_F_MLA(hi, lo, X[3], -MAD_F(0x07635284)); - MAD_F_MLA(hi, lo, X[5], MAD_F(0x04cfb0e2)); - MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f9ee890)); - MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0ffc19fd)); - MAD_F_MLA(hi, lo, X[9], -MAD_F(0x00b2aa3e)); - MAD_F_MLA(hi, lo, X[11], MAD_F(0x03768962)); - MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0f426cb5)); - MAD_F_MLA(hi, lo, X[14], MAD_F(0x0e313245)); - MAD_F_MLA(hi, lo, X[15], MAD_F(0x0898c779)); - MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0acf37ad)); - - x[18] = x[35] = MAD_F_MLZ(hi, lo) - t1; - - MAD_F_ML0(hi, lo, X[4], MAD_F(0x061f78aa)); - MAD_F_MLA(hi, lo, X[13], -MAD_F(0x0ec835e8)); - - t7 = MAD_F_MLZ(hi, lo); - - MAD_F_MLA(hi, lo, X[1], -MAD_F(0x0cb19346)); - MAD_F_MLA(hi, lo, X[7], MAD_F(0x0fdcf549)); - MAD_F_MLA(hi, lo, X[10], MAD_F(0x0216a2a2)); - MAD_F_MLA(hi, lo, X[16], -MAD_F(0x09bd7ca0)); - - t2 = MAD_F_MLZ(hi, lo); - - MAD_F_MLA(hi, lo, X[0], MAD_F(0x04cfb0e2)); - MAD_F_MLA(hi, lo, X[2], MAD_F(0x0ffc19fd)); - MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0d7e8807)); - MAD_F_MLA(hi, lo, X[5], MAD_F(0x03768962)); - MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0bcbe352)); - MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0e313245)); - MAD_F_MLA(hi, lo, X[9], MAD_F(0x07635284)); - MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0acf37ad)); - MAD_F_MLA(hi, lo, X[12], MAD_F(0x0f9ee890)); - MAD_F_MLA(hi, lo, X[14], MAD_F(0x0898c779)); - MAD_F_MLA(hi, lo, X[15], MAD_F(0x00b2aa3e)); - MAD_F_MLA(hi, lo, X[17], MAD_F(0x0f426cb5)); - - x[5] = MAD_F_MLZ(hi, lo); - x[12] = -x[5]; - - MAD_F_ML0(hi, lo, X[0], MAD_F(0x0acf37ad)); - MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0898c779)); - MAD_F_MLA(hi, lo, X[3], MAD_F(0x0e313245)); - MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0f426cb5)); - MAD_F_MLA(hi, lo, X[6], -MAD_F(0x03768962)); - MAD_F_MLA(hi, lo, X[8], MAD_F(0x00b2aa3e)); - MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0ffc19fd)); - MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f9ee890)); - MAD_F_MLA(hi, lo, X[12], -MAD_F(0x04cfb0e2)); - MAD_F_MLA(hi, lo, X[14], MAD_F(0x07635284)); - MAD_F_MLA(hi, lo, X[15], MAD_F(0x0d7e8807)); - MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0bcbe352)); - - x[0] = MAD_F_MLZ(hi, lo) + t2; - x[17] = -x[0]; - - MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f9ee890)); - MAD_F_MLA(hi, lo, X[2], -MAD_F(0x07635284)); - MAD_F_MLA(hi, lo, X[3], -MAD_F(0x00b2aa3e)); - MAD_F_MLA(hi, lo, X[5], MAD_F(0x0bcbe352)); - MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f426cb5)); - MAD_F_MLA(hi, lo, X[8], MAD_F(0x0d7e8807)); - MAD_F_MLA(hi, lo, X[9], MAD_F(0x0898c779)); - MAD_F_MLA(hi, lo, X[11], -MAD_F(0x04cfb0e2)); - MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0acf37ad)); - MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0ffc19fd)); - MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0e313245)); - MAD_F_MLA(hi, lo, X[17], -MAD_F(0x03768962)); - - x[24] = x[29] = MAD_F_MLZ(hi, lo) + t2; - - MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0216a2a2)); - MAD_F_MLA(hi, lo, X[7], -MAD_F(0x09bd7ca0)); - MAD_F_MLA(hi, lo, X[10], MAD_F(0x0cb19346)); - MAD_F_MLA(hi, lo, X[16], MAD_F(0x0fdcf549)); - - t3 = MAD_F_MLZ(hi, lo) + t7; - - MAD_F_ML0(hi, lo, X[0], MAD_F(0x00b2aa3e)); - MAD_F_MLA(hi, lo, X[2], MAD_F(0x03768962)); - MAD_F_MLA(hi, lo, X[3], -MAD_F(0x04cfb0e2)); - MAD_F_MLA(hi, lo, X[5], -MAD_F(0x07635284)); - MAD_F_MLA(hi, lo, X[6], MAD_F(0x0898c779)); - MAD_F_MLA(hi, lo, X[8], MAD_F(0x0acf37ad)); - MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0bcbe352)); - MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0d7e8807)); - MAD_F_MLA(hi, lo, X[12], MAD_F(0x0e313245)); - MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f426cb5)); - MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0f9ee890)); - MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0ffc19fd)); - - x[8] = MAD_F_MLZ(hi, lo) + t3; - x[9] = -x[8]; - - MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0e313245)); - MAD_F_MLA(hi, lo, X[2], MAD_F(0x0bcbe352)); - MAD_F_MLA(hi, lo, X[3], MAD_F(0x0f9ee890)); - MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0898c779)); - MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0ffc19fd)); - MAD_F_MLA(hi, lo, X[8], MAD_F(0x04cfb0e2)); - MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f426cb5)); - MAD_F_MLA(hi, lo, X[11], -MAD_F(0x00b2aa3e)); - MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0d7e8807)); - MAD_F_MLA(hi, lo, X[14], -MAD_F(0x03768962)); - MAD_F_MLA(hi, lo, X[15], MAD_F(0x0acf37ad)); - MAD_F_MLA(hi, lo, X[17], MAD_F(0x07635284)); - - x[21] = x[32] = MAD_F_MLZ(hi, lo) + t3; - - MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0d7e8807)); - MAD_F_MLA(hi, lo, X[2], MAD_F(0x0f426cb5)); - MAD_F_MLA(hi, lo, X[3], MAD_F(0x0acf37ad)); - MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0ffc19fd)); - MAD_F_MLA(hi, lo, X[6], -MAD_F(0x07635284)); - MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f9ee890)); - MAD_F_MLA(hi, lo, X[9], MAD_F(0x03768962)); - MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0e313245)); - MAD_F_MLA(hi, lo, X[12], MAD_F(0x00b2aa3e)); - MAD_F_MLA(hi, lo, X[14], MAD_F(0x0bcbe352)); - MAD_F_MLA(hi, lo, X[15], -MAD_F(0x04cfb0e2)); - MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0898c779)); - - x[20] = x[33] = MAD_F_MLZ(hi, lo) - t3; - - MAD_F_ML0(hi, lo, t14, -MAD_F(0x0ec835e8)); - MAD_F_MLA(hi, lo, t15, MAD_F(0x061f78aa)); - - t4 = MAD_F_MLZ(hi, lo) - t7; - - MAD_F_ML0(hi, lo, t12, MAD_F(0x061f78aa)); - MAD_F_MLA(hi, lo, t13, MAD_F(0x0ec835e8)); - - x[4] = MAD_F_MLZ(hi, lo) + t4; - x[13] = -x[4]; - - MAD_F_ML0(hi, lo, t8, MAD_F(0x09bd7ca0)); - MAD_F_MLA(hi, lo, t9, -MAD_F(0x0216a2a2)); - MAD_F_MLA(hi, lo, t10, MAD_F(0x0fdcf549)); - MAD_F_MLA(hi, lo, t11, -MAD_F(0x0cb19346)); - - x[1] = MAD_F_MLZ(hi, lo) + t4; - x[16] = -x[1]; - - MAD_F_ML0(hi, lo, t8, -MAD_F(0x0fdcf549)); - MAD_F_MLA(hi, lo, t9, -MAD_F(0x0cb19346)); - MAD_F_MLA(hi, lo, t10, -MAD_F(0x09bd7ca0)); - MAD_F_MLA(hi, lo, t11, -MAD_F(0x0216a2a2)); - - x[25] = x[28] = MAD_F_MLZ(hi, lo) + t4; - - MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0fdcf549)); - MAD_F_MLA(hi, lo, X[7], -MAD_F(0x0cb19346)); - MAD_F_MLA(hi, lo, X[10], -MAD_F(0x09bd7ca0)); - MAD_F_MLA(hi, lo, X[16], -MAD_F(0x0216a2a2)); - - t5 = MAD_F_MLZ(hi, lo) - t6; - - MAD_F_ML0(hi, lo, X[0], MAD_F(0x0898c779)); - MAD_F_MLA(hi, lo, X[2], MAD_F(0x04cfb0e2)); - MAD_F_MLA(hi, lo, X[3], MAD_F(0x0bcbe352)); - MAD_F_MLA(hi, lo, X[5], MAD_F(0x00b2aa3e)); - MAD_F_MLA(hi, lo, X[6], MAD_F(0x0e313245)); - MAD_F_MLA(hi, lo, X[8], -MAD_F(0x03768962)); - MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f9ee890)); - MAD_F_MLA(hi, lo, X[11], -MAD_F(0x07635284)); - MAD_F_MLA(hi, lo, X[12], MAD_F(0x0ffc19fd)); - MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0acf37ad)); - MAD_F_MLA(hi, lo, X[15], MAD_F(0x0f426cb5)); - MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0d7e8807)); - - x[2] = MAD_F_MLZ(hi, lo) + t5; - x[15] = -x[2]; - - MAD_F_ML0(hi, lo, X[0], MAD_F(0x07635284)); - MAD_F_MLA(hi, lo, X[2], MAD_F(0x0acf37ad)); - MAD_F_MLA(hi, lo, X[3], MAD_F(0x03768962)); - MAD_F_MLA(hi, lo, X[5], MAD_F(0x0d7e8807)); - MAD_F_MLA(hi, lo, X[6], -MAD_F(0x00b2aa3e)); - MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f426cb5)); - MAD_F_MLA(hi, lo, X[9], -MAD_F(0x04cfb0e2)); - MAD_F_MLA(hi, lo, X[11], MAD_F(0x0ffc19fd)); - MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0898c779)); - MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f9ee890)); - MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0bcbe352)); - MAD_F_MLA(hi, lo, X[17], MAD_F(0x0e313245)); - - x[3] = MAD_F_MLZ(hi, lo) + t5; - x[14] = -x[3]; - - MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0ffc19fd)); - MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0f9ee890)); - MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0f426cb5)); - MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0e313245)); - MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0d7e8807)); - MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0bcbe352)); - MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0acf37ad)); - MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0898c779)); - MAD_F_MLA(hi, lo, X[12], -MAD_F(0x07635284)); - MAD_F_MLA(hi, lo, X[14], -MAD_F(0x04cfb0e2)); - MAD_F_MLA(hi, lo, X[15], -MAD_F(0x03768962)); - MAD_F_MLA(hi, lo, X[17], -MAD_F(0x00b2aa3e)); - - x[26] = x[27] = MAD_F_MLZ(hi, lo) + t5; +void imdct36(mad_fixed_t const X[18], mad_fixed_t x[36]) { + mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7; + mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15; + register mad_fixed64hi_t hi; + register mad_fixed64lo_t lo; + + MAD_F_ML0(hi, lo, X[4], MAD_F(0x0ec835e8)); + MAD_F_MLA(hi, lo, X[13], MAD_F(0x061f78aa)); + + t6 = MAD_F_MLZ(hi, lo); + + MAD_F_MLA(hi, lo, (t14 = X[1] - X[10]), -MAD_F(0x061f78aa)); + MAD_F_MLA(hi, lo, (t15 = X[7] + X[16]), -MAD_F(0x0ec835e8)); + + t0 = MAD_F_MLZ(hi, lo); + + MAD_F_MLA(hi, lo, (t8 = X[0] - X[11] - X[12]), MAD_F(0x0216a2a2)); + MAD_F_MLA(hi, lo, (t9 = X[2] - X[9] - X[14]), MAD_F(0x09bd7ca0)); + MAD_F_MLA(hi, lo, (t10 = X[3] - X[8] - X[15]), -MAD_F(0x0cb19346)); + MAD_F_MLA(hi, lo, (t11 = X[5] - X[6] - X[17]), -MAD_F(0x0fdcf549)); + + x[7] = MAD_F_MLZ(hi, lo); + x[10] = -x[7]; + + MAD_F_ML0(hi, lo, t8, -MAD_F(0x0cb19346)); + MAD_F_MLA(hi, lo, t9, MAD_F(0x0fdcf549)); + MAD_F_MLA(hi, lo, t10, MAD_F(0x0216a2a2)); + MAD_F_MLA(hi, lo, t11, -MAD_F(0x09bd7ca0)); + + x[19] = x[34] = MAD_F_MLZ(hi, lo) - t0; + + t12 = X[0] - X[3] + X[8] - X[11] - X[12] + X[15]; + t13 = X[2] + X[5] - X[6] - X[9] - X[14] - X[17]; + + MAD_F_ML0(hi, lo, t12, -MAD_F(0x0ec835e8)); + MAD_F_MLA(hi, lo, t13, MAD_F(0x061f78aa)); + + x[22] = x[31] = MAD_F_MLZ(hi, lo) + t0; + + MAD_F_ML0(hi, lo, X[1], -MAD_F(0x09bd7ca0)); + MAD_F_MLA(hi, lo, X[7], MAD_F(0x0216a2a2)); + MAD_F_MLA(hi, lo, X[10], -MAD_F(0x0fdcf549)); + MAD_F_MLA(hi, lo, X[16], MAD_F(0x0cb19346)); + + t1 = MAD_F_MLZ(hi, lo) + t6; + + MAD_F_ML0(hi, lo, X[0], MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[2], MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[6], MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[9], MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[14], MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[15], -MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0f9ee890)); + + x[6] = MAD_F_MLZ(hi, lo) + t1; + x[11] = -x[6]; + + MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[2], -MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[3], MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[5], MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[6], MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[8], -MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[12], -MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[14], MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[15], MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[17], MAD_F(0x04cfb0e2)); + + x[23] = x[30] = MAD_F_MLZ(hi, lo) + t1; + + MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[2], MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[3], -MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[5], MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[9], -MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[11], MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[14], MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[15], MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0acf37ad)); + + x[18] = x[35] = MAD_F_MLZ(hi, lo) - t1; + + MAD_F_ML0(hi, lo, X[4], MAD_F(0x061f78aa)); + MAD_F_MLA(hi, lo, X[13], -MAD_F(0x0ec835e8)); + + t7 = MAD_F_MLZ(hi, lo); + + MAD_F_MLA(hi, lo, X[1], -MAD_F(0x0cb19346)); + MAD_F_MLA(hi, lo, X[7], MAD_F(0x0fdcf549)); + MAD_F_MLA(hi, lo, X[10], MAD_F(0x0216a2a2)); + MAD_F_MLA(hi, lo, X[16], -MAD_F(0x09bd7ca0)); + + t2 = MAD_F_MLZ(hi, lo); + + MAD_F_MLA(hi, lo, X[0], MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[2], MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[5], MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[9], MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[12], MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[14], MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[15], MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[17], MAD_F(0x0f426cb5)); + + x[5] = MAD_F_MLZ(hi, lo); + x[12] = -x[5]; + + MAD_F_ML0(hi, lo, X[0], MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[3], MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[6], -MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[8], MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[12], -MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[14], MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[15], MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0bcbe352)); + + x[0] = MAD_F_MLZ(hi, lo) + t2; + x[17] = -x[0]; + + MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[2], -MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[3], -MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[5], MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[8], MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[9], MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[11], -MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[17], -MAD_F(0x03768962)); + + x[24] = x[29] = MAD_F_MLZ(hi, lo) + t2; + + MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0216a2a2)); + MAD_F_MLA(hi, lo, X[7], -MAD_F(0x09bd7ca0)); + MAD_F_MLA(hi, lo, X[10], MAD_F(0x0cb19346)); + MAD_F_MLA(hi, lo, X[16], MAD_F(0x0fdcf549)); + + t3 = MAD_F_MLZ(hi, lo) + t7; + + MAD_F_ML0(hi, lo, X[0], MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[2], MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[3], -MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[5], -MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[6], MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[8], MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[12], MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0ffc19fd)); + + x[8] = MAD_F_MLZ(hi, lo) + t3; + x[9] = -x[8]; + + MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[2], MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[3], MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[8], MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[11], -MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[14], -MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[15], MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[17], MAD_F(0x07635284)); + + x[21] = x[32] = MAD_F_MLZ(hi, lo) + t3; + + MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[2], MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[3], MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[6], -MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[9], MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[12], MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[14], MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[15], -MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0898c779)); + + x[20] = x[33] = MAD_F_MLZ(hi, lo) - t3; + + MAD_F_ML0(hi, lo, t14, -MAD_F(0x0ec835e8)); + MAD_F_MLA(hi, lo, t15, MAD_F(0x061f78aa)); + + t4 = MAD_F_MLZ(hi, lo) - t7; + + MAD_F_ML0(hi, lo, t12, MAD_F(0x061f78aa)); + MAD_F_MLA(hi, lo, t13, MAD_F(0x0ec835e8)); + + x[4] = MAD_F_MLZ(hi, lo) + t4; + x[13] = -x[4]; + + MAD_F_ML0(hi, lo, t8, MAD_F(0x09bd7ca0)); + MAD_F_MLA(hi, lo, t9, -MAD_F(0x0216a2a2)); + MAD_F_MLA(hi, lo, t10, MAD_F(0x0fdcf549)); + MAD_F_MLA(hi, lo, t11, -MAD_F(0x0cb19346)); + + x[1] = MAD_F_MLZ(hi, lo) + t4; + x[16] = -x[1]; + + MAD_F_ML0(hi, lo, t8, -MAD_F(0x0fdcf549)); + MAD_F_MLA(hi, lo, t9, -MAD_F(0x0cb19346)); + MAD_F_MLA(hi, lo, t10, -MAD_F(0x09bd7ca0)); + MAD_F_MLA(hi, lo, t11, -MAD_F(0x0216a2a2)); + + x[25] = x[28] = MAD_F_MLZ(hi, lo) + t4; + + MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0fdcf549)); + MAD_F_MLA(hi, lo, X[7], -MAD_F(0x0cb19346)); + MAD_F_MLA(hi, lo, X[10], -MAD_F(0x09bd7ca0)); + MAD_F_MLA(hi, lo, X[16], -MAD_F(0x0216a2a2)); + + t5 = MAD_F_MLZ(hi, lo) - t6; + + MAD_F_ML0(hi, lo, X[0], MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[2], MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[3], MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[5], MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[6], MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[8], -MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[11], -MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[12], MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[15], MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0d7e8807)); + + x[2] = MAD_F_MLZ(hi, lo) + t5; + x[15] = -x[2]; + + MAD_F_ML0(hi, lo, X[0], MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[2], MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[3], MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[5], MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[6], -MAD_F(0x00b2aa3e)); + MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[9], -MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[11], MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[17], MAD_F(0x0e313245)); + + x[3] = MAD_F_MLZ(hi, lo) + t5; + x[14] = -x[3]; + + MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0ffc19fd)); + MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0f9ee890)); + MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0f426cb5)); + MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0e313245)); + MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0d7e8807)); + MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0bcbe352)); + MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0acf37ad)); + MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0898c779)); + MAD_F_MLA(hi, lo, X[12], -MAD_F(0x07635284)); + MAD_F_MLA(hi, lo, X[14], -MAD_F(0x04cfb0e2)); + MAD_F_MLA(hi, lo, X[15], -MAD_F(0x03768962)); + MAD_F_MLA(hi, lo, X[17], -MAD_F(0x00b2aa3e)); + + x[26] = x[27] = MAD_F_MLZ(hi, lo) + t5; } # endif /* - NAME: III_imdct_l() - DESCRIPTION: perform IMDCT and windowing for long blocks + NAME: III_imdct_l() + DESCRIPTION: perform IMDCT and windowing for long blocks */ static void III_imdct_l(mad_fixed_t const X[18], mad_fixed_t z[36], - unsigned int block_type) -{ - unsigned int i; - stack(__FUNCTION__, __FILE__, __LINE__); + unsigned int block_type) { + unsigned int i; + stackenter(__FUNCTION__, __FILE__, __LINE__); - /* IMDCT */ + /* IMDCT */ - imdct36(X, z); + imdct36(X, z); - /* windowing */ + /* windowing */ - switch (block_type) { + switch (block_type) { case 0: /* normal window */ # if defined(ASO_INTERLEAVE1) - { + { register mad_fixed_t tmp1, tmp2; tmp1 = window_l[0]; tmp2 = window_l[1]; for (i = 0; i < 34; i += 2) { - z[i + 0] = mad_f_mul(z[i + 0], tmp1); - tmp1 = window_l[i + 2]; - z[i + 1] = mad_f_mul(z[i + 1], tmp2); - tmp2 = window_l[i + 3]; + z[i + 0] = mad_f_mul(z[i + 0], tmp1); + tmp1 = window_l[i + 2]; + z[i + 1] = mad_f_mul(z[i + 1], tmp2); + tmp2 = window_l[i + 3]; } z[34] = mad_f_mul(z[34], tmp1); z[35] = mad_f_mul(z[35], tmp2); - } + } # elif defined(ASO_INTERLEAVE2) - { + { register mad_fixed_t tmp1, tmp2; tmp1 = z[0]; tmp2 = window_l[0]; for (i = 0; i < 35; ++i) { - z[i] = mad_f_mul(tmp1, tmp2); - tmp1 = z[i + 1]; - tmp2 = window_l[i + 1]; + z[i] = mad_f_mul(tmp1, tmp2); + tmp1 = z[i + 1]; + tmp2 = window_l[i + 1]; } z[35] = mad_f_mul(tmp1, tmp2); - } + } # elif 1 - for (i = 0; i < 36; i += 4) { + for (i = 0; i < 36; i += 4) { z[i + 0] = mad_f_mul(z[i + 0], window_l(i + 0)); z[i + 1] = mad_f_mul(z[i + 1], window_l(i + 1)); z[i + 2] = mad_f_mul(z[i + 2], window_l(i + 2)); z[i + 3] = mad_f_mul(z[i + 3], window_l(i + 3)); - } + } # else - for (i = 0; i < 36; ++i) z[i] = mad_f_mul(z[i], window_l[i]); + for (i = 0; i < 36; ++i) { + z[i] = mad_f_mul(z[i], window_l[i]); + } # endif - break; + break; case 1: /* start block */ - for (i = 0; i < 18; i += 3) { - z[i + 0] = mad_f_mul(z[i + 0], window_l(i + 0)); - z[i + 1] = mad_f_mul(z[i + 1], window_l(i + 1)); - z[i + 2] = mad_f_mul(z[i + 2], window_l(i + 2)); - } - /* (i = 18; i < 24; ++i) z[i] unchanged */ - for (i = 24; i < 30; ++i) z[i] = mad_f_mul(z[i], window_s(i - 18)); - for (i = 30; i < 36; ++i) z[i] = 0; - break; + for (i = 0; i < 18; i += 3) { + z[i + 0] = mad_f_mul(z[i + 0], window_l(i + 0)); + z[i + 1] = mad_f_mul(z[i + 1], window_l(i + 1)); + z[i + 2] = mad_f_mul(z[i + 2], window_l(i + 2)); + } + /* (i = 18; i < 24; ++i) z[i] unchanged */ + for (i = 24; i < 30; ++i) { + z[i] = mad_f_mul(z[i], window_s(i - 18)); + } + for (i = 30; i < 36; ++i) { + z[i] = 0; + } + break; case 3: /* stop block */ - for (i = 0; i < 6; ++i) z[i] = 0; - for (i = 6; i < 12; ++i) z[i] = mad_f_mul(z[i], window_s(i - 6)); - /* (i = 12; i < 18; ++i) z[i] unchanged */ - for (i = 18; i < 36; i += 3) { - z[i + 0] = mad_f_mul(z[i + 0], window_l(i + 0)); - z[i + 1] = mad_f_mul(z[i + 1], window_l(i + 1)); - z[i + 2] = mad_f_mul(z[i + 2], window_l(i + 2)); - } - break; - } + for (i = 0; i < 6; ++i) { + z[i] = 0; + } + for (i = 6; i < 12; ++i) { + z[i] = mad_f_mul(z[i], window_s(i - 6)); + } + /* (i = 12; i < 18; ++i) z[i] unchanged */ + for (i = 18; i < 36; i += 3) { + z[i + 0] = mad_f_mul(z[i + 0], window_l(i + 0)); + z[i + 1] = mad_f_mul(z[i + 1], window_l(i + 1)); + z[i + 2] = mad_f_mul(z[i + 2], window_l(i + 2)); + } + break; + } } # endif /* ASO_IMDCT */ /* - NAME: III_imdct_s() - DESCRIPTION: perform IMDCT and windowing for short blocks + NAME: III_imdct_s() + DESCRIPTION: perform IMDCT and windowing for short blocks */ static -void III_imdct_s(mad_fixed_t const X[18], mad_fixed_t z[36]) -{ - mad_fixed_t y[36], *yptr; - int wptr; //mad_fixed_t const *wptr; - int w, i; - register mad_fixed64hi_t hi; - register mad_fixed64lo_t lo; - // MAD_F_MLA may produce non-32b aligned reads, so copy from progmem to stack and work from there... - mad_fixed_t imdct_s_lcl[6][6]; - memcpy_P(imdct_s_lcl, imdct_s, sizeof(imdct_s)); - stack(__FUNCTION__, __FILE__, __LINE__); - - /* IMDCT */ - - yptr = &y[0]; - - for (w = 0; w < 3; ++w) { - register mad_fixed_t (*s)[6]; - - s = imdct_s_lcl; - - for (i = 0; i < 3; ++i) { - MAD_F_ML0(hi, lo, X[0], (*s)[0]); - MAD_F_MLA(hi, lo, X[1], (*s)[1]); - MAD_F_MLA(hi, lo, X[2], (*s)[2]); - MAD_F_MLA(hi, lo, X[3], (*s)[3]); - MAD_F_MLA(hi, lo, X[4], (*s)[4]); - MAD_F_MLA(hi, lo, X[5], (*s)[5]); - - yptr[i + 0] = MAD_F_MLZ(hi, lo); - yptr[5 - i] = -yptr[i + 0]; - - ++s; - - MAD_F_ML0(hi, lo, X[0], (*s)[0]); - MAD_F_MLA(hi, lo, X[1], (*s)[1]); - MAD_F_MLA(hi, lo, X[2], (*s)[2]); - MAD_F_MLA(hi, lo, X[3], (*s)[3]); - MAD_F_MLA(hi, lo, X[4], (*s)[4]); - MAD_F_MLA(hi, lo, X[5], (*s)[5]); - - yptr[ i + 6] = MAD_F_MLZ(hi, lo); - yptr[11 - i] = yptr[i + 6]; - - ++s; - } +void III_imdct_s(mad_fixed_t const X[18], mad_fixed_t z[36]) { + mad_fixed_t y[36], *yptr; + int wptr; //mad_fixed_t const *wptr; + int w, i; + register mad_fixed64hi_t hi; + register mad_fixed64lo_t lo; + // MAD_F_MLA may produce non-32b aligned reads, so copy from progmem to stack and work from there... + mad_fixed_t imdct_s_lcl[6][6]; + memcpy_P(imdct_s_lcl, imdct_s, sizeof(imdct_s)); + stackenter(__FUNCTION__, __FILE__, __LINE__); + + /* IMDCT */ + + yptr = &y[0]; + + for (w = 0; w < 3; ++w) { + register mad_fixed_t (*s)[6]; + + s = imdct_s_lcl; + + for (i = 0; i < 3; ++i) { + MAD_F_ML0(hi, lo, X[0], (*s)[0]); + MAD_F_MLA(hi, lo, X[1], (*s)[1]); + MAD_F_MLA(hi, lo, X[2], (*s)[2]); + MAD_F_MLA(hi, lo, X[3], (*s)[3]); + MAD_F_MLA(hi, lo, X[4], (*s)[4]); + MAD_F_MLA(hi, lo, X[5], (*s)[5]); + + yptr[i + 0] = MAD_F_MLZ(hi, lo); + yptr[5 - i] = -yptr[i + 0]; + + ++s; + + MAD_F_ML0(hi, lo, X[0], (*s)[0]); + MAD_F_MLA(hi, lo, X[1], (*s)[1]); + MAD_F_MLA(hi, lo, X[2], (*s)[2]); + MAD_F_MLA(hi, lo, X[3], (*s)[3]); + MAD_F_MLA(hi, lo, X[4], (*s)[4]); + MAD_F_MLA(hi, lo, X[5], (*s)[5]); + + yptr[ i + 6] = MAD_F_MLZ(hi, lo); + yptr[11 - i] = yptr[i + 6]; + + ++s; + } - yptr += 12; - X += 6; - } + yptr += 12; + X += 6; + } - /* windowing, overlapping and concatenation */ + /* windowing, overlapping and concatenation */ - yptr = &y[0]; - wptr = 0; //wptr = &window_s[0]; + yptr = &y[0]; + wptr = 0; //wptr = &window_s[0]; - for (i = 0; i < 6; ++i) { - z[i + 0] = 0; - z[i + 6] = mad_f_mul(yptr[ 0 + 0], window_s(wptr + 0)); + for (i = 0; i < 6; ++i) { + z[i + 0] = 0; + z[i + 6] = mad_f_mul(yptr[ 0 + 0], window_s(wptr + 0)); - MAD_F_ML0(hi, lo, yptr[ 0 + 6], window_s(wptr + 6)); - MAD_F_MLA(hi, lo, yptr[12 + 0], window_s(wptr + 0)); + MAD_F_ML0(hi, lo, yptr[ 0 + 6], window_s(wptr + 6)); + MAD_F_MLA(hi, lo, yptr[12 + 0], window_s(wptr + 0)); - z[i + 12] = MAD_F_MLZ(hi, lo); + z[i + 12] = MAD_F_MLZ(hi, lo); - MAD_F_ML0(hi, lo, yptr[12 + 6], window_s(wptr + 6)); - MAD_F_MLA(hi, lo, yptr[24 + 0], window_s(wptr + 0)); + MAD_F_ML0(hi, lo, yptr[12 + 6], window_s(wptr + 6)); + MAD_F_MLA(hi, lo, yptr[24 + 0], window_s(wptr + 0)); - z[i + 18] = MAD_F_MLZ(hi, lo); + z[i + 18] = MAD_F_MLZ(hi, lo); - z[i + 24] = mad_f_mul(yptr[24 + 6], window_s(wptr + 6)); - z[i + 30] = 0; + z[i + 24] = mad_f_mul(yptr[24 + 6], window_s(wptr + 6)); + z[i + 30] = 0; - ++yptr; - ++wptr; - } + ++yptr; + ++wptr; + } } /* - NAME: III_overlap() - DESCRIPTION: perform overlap-add of windowed IMDCT outputs + NAME: III_overlap() + DESCRIPTION: perform overlap-add of windowed IMDCT outputs */ static void III_overlap(mad_fixed_t const output[36], mad_fixed_t overlap[18], - mad_fixed_t sample[18][32], unsigned int sb) -{ - unsigned int i; - stack(__FUNCTION__, __FILE__, __LINE__); + mad_fixed_t sample[18][32], unsigned int sb) { + unsigned int i; + stackenter(__FUNCTION__, __FILE__, __LINE__); # if defined(ASO_INTERLEAVE2) - { - register mad_fixed_t tmp1, tmp2; + { + register mad_fixed_t tmp1, tmp2; - tmp1 = overlap[0]; - tmp2 = overlap[1]; + tmp1 = overlap[0]; + tmp2 = overlap[1]; - for (i = 0; i < 16; i += 2) { - sample[i + 0][sb] = output[i + 0 + 0] + tmp1; - overlap[i + 0] = output[i + 0 + 18]; - tmp1 = overlap[i + 2]; + for (i = 0; i < 16; i += 2) { + sample[i + 0][sb] = output[i + 0 + 0] + tmp1; + overlap[i + 0] = output[i + 0 + 18]; + tmp1 = overlap[i + 2]; - sample[i + 1][sb] = output[i + 1 + 0] + tmp2; - overlap[i + 1] = output[i + 1 + 18]; - tmp2 = overlap[i + 3]; - } + sample[i + 1][sb] = output[i + 1 + 0] + tmp2; + overlap[i + 1] = output[i + 1 + 18]; + tmp2 = overlap[i + 3]; + } - sample[16][sb] = output[16 + 0] + tmp1; - overlap[16] = output[16 + 18]; - sample[17][sb] = output[17 + 0] + tmp2; - overlap[17] = output[17 + 18]; - } + sample[16][sb] = output[16 + 0] + tmp1; + overlap[16] = output[16 + 18]; + sample[17][sb] = output[17 + 0] + tmp2; + overlap[17] = output[17 + 18]; + } # elif 0 - for (i = 0; i < 18; i += 2) { - sample[i + 0][sb] = output[i + 0 + 0] + overlap[i + 0]; - overlap[i + 0] = output[i + 0 + 18]; + for (i = 0; i < 18; i += 2) { + sample[i + 0][sb] = output[i + 0 + 0] + overlap[i + 0]; + overlap[i + 0] = output[i + 0 + 18]; - sample[i + 1][sb] = output[i + 1 + 0] + overlap[i + 1]; - overlap[i + 1] = output[i + 1 + 18]; - } + sample[i + 1][sb] = output[i + 1 + 0] + overlap[i + 1]; + overlap[i + 1] = output[i + 1 + 18]; + } # else - for (i = 0; i < 18; ++i) { - sample[i][sb] = output[i + 0] + overlap[i]; - overlap[i] = output[i + 18]; - } + for (i = 0; i < 18; ++i) { + sample[i][sb] = output[i + 0] + overlap[i]; + overlap[i] = output[i + 18]; + } # endif } /* - NAME: III_overlap_z() - DESCRIPTION: perform "overlap-add" of zero IMDCT outputs + NAME: III_overlap_z() + DESCRIPTION: perform "overlap-add" of zero IMDCT outputs */ static inline void III_overlap_z(mad_fixed_t overlap[18], - mad_fixed_t sample[18][32], unsigned int sb) -{ - unsigned int i; + mad_fixed_t sample[18][32], unsigned int sb) { + unsigned int i; # if defined(ASO_INTERLEAVE2) - { - register mad_fixed_t tmp1, tmp2; + { + register mad_fixed_t tmp1, tmp2; - tmp1 = overlap[0]; - tmp2 = overlap[1]; + tmp1 = overlap[0]; + tmp2 = overlap[1]; - for (i = 0; i < 16; i += 2) { - sample[i + 0][sb] = tmp1; - overlap[i + 0] = 0; - tmp1 = overlap[i + 2]; + for (i = 0; i < 16; i += 2) { + sample[i + 0][sb] = tmp1; + overlap[i + 0] = 0; + tmp1 = overlap[i + 2]; - sample[i + 1][sb] = tmp2; - overlap[i + 1] = 0; - tmp2 = overlap[i + 3]; - } + sample[i + 1][sb] = tmp2; + overlap[i + 1] = 0; + tmp2 = overlap[i + 3]; + } - sample[16][sb] = tmp1; - overlap[16] = 0; - sample[17][sb] = tmp2; - overlap[17] = 0; - } + sample[16][sb] = tmp1; + overlap[16] = 0; + sample[17][sb] = tmp2; + overlap[17] = 0; + } # else - for (i = 0; i < 18; ++i) { - sample[i][sb] = overlap[i]; - overlap[i] = 0; - } + for (i = 0; i < 18; ++i) { + sample[i][sb] = overlap[i]; + overlap[i] = 0; + } # endif } /* - NAME: III_freqinver() - DESCRIPTION: perform subband frequency inversion for odd sample lines + NAME: III_freqinver() + DESCRIPTION: perform subband frequency inversion for odd sample lines */ static -void III_freqinver(mad_fixed_t sample[18][32], unsigned int sb) -{ - unsigned int i; - stack(__FUNCTION__, __FILE__, __LINE__); +void III_freqinver(mad_fixed_t sample[18][32], unsigned int sb) { + unsigned int i; + stackenter(__FUNCTION__, __FILE__, __LINE__); # if 1 || defined(ASO_INTERLEAVE1) || defined(ASO_INTERLEAVE2) - { - register mad_fixed_t tmp1, tmp2; + { + register mad_fixed_t tmp1, tmp2; - tmp1 = sample[1][sb]; - tmp2 = sample[3][sb]; + tmp1 = sample[1][sb]; + tmp2 = sample[3][sb]; - for (i = 1; i < 13; i += 4) { - sample[i + 0][sb] = -tmp1; - tmp1 = sample[i + 4][sb]; - sample[i + 2][sb] = -tmp2; - tmp2 = sample[i + 6][sb]; - } + for (i = 1; i < 13; i += 4) { + sample[i + 0][sb] = -tmp1; + tmp1 = sample[i + 4][sb]; + sample[i + 2][sb] = -tmp2; + tmp2 = sample[i + 6][sb]; + } - sample[13][sb] = -tmp1; - tmp1 = sample[17][sb]; - sample[15][sb] = -tmp2; - sample[17][sb] = -tmp1; - } + sample[13][sb] = -tmp1; + tmp1 = sample[17][sb]; + sample[15][sb] = -tmp2; + sample[17][sb] = -tmp1; + } # else - for (i = 1; i < 18; i += 2) - sample[i][sb] = -sample[i][sb]; + for (i = 1; i < 18; i += 2) { + sample[i][sb] = -sample[i][sb]; + } # endif } /* - NAME: III_decode() - DESCRIPTION: decode frame main_data + NAME: III_decode() + DESCRIPTION: decode frame main_data */ static enum mad_error III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, - struct sideinfo *si, unsigned int nch) -{ - struct mad_header *header = &frame->header; - mad_fixed_t *xr[2]; // Moved from stack to dynheap -// mad_fixed_t *xr_raw; // [2][576] - unsigned int sfreqi, ngr, gr; -// xr_raw = (mad_fixed_t*)malloc(sizeof(mad_fixed_t) * 2 * 576); -// if (!xr_raw) -// return MAD_ERROR_NOMEM; - xr[0] = frame->xr_raw; //xr_raw; - xr[1] = frame->xr_raw + 576; //xr_raw + 576; - - stack(__FUNCTION__, __FILE__, __LINE__); - { - unsigned int sfreq; - - sfreq = header->samplerate; - if (header->flags & MAD_FLAG_MPEG_2_5_EXT) - sfreq *= 2; - - /* 48000 => 0, 44100 => 1, 32000 => 2, - 24000 => 3, 22050 => 4, 16000 => 5 */ - sfreqi = ((sfreq >> 7) & 0x000f) + - ((sfreq >> 15) & 0x0001) - 8; - - if (header->flags & MAD_FLAG_MPEG_2_5_EXT) - sfreqi += 3; - } - - /* scalefactors, Huffman decoding, requantization */ - - ngr = (header->flags & MAD_FLAG_LSF_EXT) ? 1 : 2; - - for (gr = 0; gr < ngr; ++gr) { - struct granule *granule = &si->gr[gr]; - unsigned int const *sfbwidth[2]; - unsigned int ch; - enum mad_error error; - - for (ch = 0; ch < nch; ++ch) { - struct channel *channel = &granule->ch[ch]; - unsigned int part2_length; - - sfbwidth[ch] = sfbwidth_table[sfreqi].l; - if (channel->block_type == 2) { - sfbwidth[ch] = (channel->flags & mixed_block_flag) ? - sfbwidth_table[sfreqi].m : sfbwidth_table[sfreqi].s; - } - - if (header->flags & MAD_FLAG_LSF_EXT) { - part2_length = III_scalefactors_lsf(ptr, channel, - ch == 0 ? 0 : &si->gr[1].ch[1], - header->mode_extension); - } - else { - part2_length = III_scalefactors(ptr, channel, &si->gr[0].ch[ch], - gr == 0 ? 0 : si->scfsi[ch]); - } - - error = III_huffdecode(ptr, xr[ch], channel, sfbwidth[ch], part2_length); - if (error) { -// free(xr_raw); - return error; - } - } + struct sideinfo *si, unsigned int nch) { + struct mad_header *header = &frame->header; + mad_fixed_t *xr[2]; // Moved from stack to dynheap + // mad_fixed_t *xr_raw; // [2][576] + unsigned int sfreqi, ngr, gr; + // xr_raw = (mad_fixed_t*)malloc(sizeof(mad_fixed_t) * 2 * 576); + // if (!xr_raw) + // return MAD_ERROR_NOMEM; + xr[0] = frame->xr_raw; //xr_raw; + xr[1] = frame->xr_raw + 576; //xr_raw + 576; + + stackenter(__FUNCTION__, __FILE__, __LINE__); + { + unsigned int sfreq; + + sfreq = header->samplerate; + if (header->flags & MAD_FLAG_MPEG_2_5_EXT) { + sfreq *= 2; + } - /* joint stereo processing */ + /* 48000 => 0, 44100 => 1, 32000 => 2, + 24000 => 3, 22050 => 4, 16000 => 5 */ + sfreqi = ((sfreq >> 7) & 0x000f) + + ((sfreq >> 15) & 0x0001) - 8; - if (header->mode == MAD_MODE_JOINT_STEREO && header->mode_extension) { - // (void*) below just to get rid of warning about passing in a * and not a [2][576] - error = III_stereo((void*)frame->xr_raw, granule, header, sfbwidth[0]); - if (error) { -// free(xr_raw); - return error; - } + if (header->flags & MAD_FLAG_MPEG_2_5_EXT) { + sfreqi += 3; + } } - /* reordering, alias reduction, IMDCT, overlap-add, frequency inversion */ + /* scalefactors, Huffman decoding, requantization */ - for (ch = 0; ch < nch; ++ch) { - struct channel const *channel = &granule->ch[ch]; - mad_fixed_t (*sample)[32] = &frame->sbsample[ch][18 * gr]; - unsigned int sb, l, i, sblimit; - mad_fixed_t output[36]; + ngr = (header->flags & MAD_FLAG_LSF_EXT) ? 1 : 2; - if (channel->block_type == 2) { - error = III_reorder(xr[ch], channel, sfbwidth[ch], frame->tmp); - if (error) { -// free(xr_raw); - return error; - } + for (gr = 0; gr < ngr; ++gr) { + struct granule *granule = &si->gr[gr]; + unsigned int const *sfbwidth[2]; + unsigned int ch; + enum mad_error error; -# if !defined(OPT_STRICT) - /* - According to ISO/IEC 11172-3, "Alias reduction is not applied for - granules with block_type == 2 (short block)." However, other - sources suggest alias reduction should indeed be performed on the - lower two subbands of mixed blocks. Most other implementations do - this, so by default we will too. - */ - if (channel->flags & mixed_block_flag) - III_aliasreduce(xr[ch], 36); -# endif - } - else - III_aliasreduce(xr[ch], 576); + for (ch = 0; ch < nch; ++ch) { + struct channel *channel = &granule->ch[ch]; + unsigned int part2_length; - l = 0; + sfbwidth[ch] = sfbwidth_table[sfreqi].l; + if (channel->block_type == 2) { + sfbwidth[ch] = (channel->flags & mixed_block_flag) ? + sfbwidth_table[sfreqi].m : sfbwidth_table[sfreqi].s; + } - /* subbands 0-1 */ + if (header->flags & MAD_FLAG_LSF_EXT) { + part2_length = III_scalefactors_lsf(ptr, channel, + ch == 0 ? 0 : &si->gr[1].ch[1], + header->mode_extension); + } else { + part2_length = III_scalefactors(ptr, channel, &si->gr[0].ch[ch], + gr == 0 ? 0 : si->scfsi[ch]); + } - if (channel->block_type != 2 || (channel->flags & mixed_block_flag)) { - unsigned int block_type; + error = III_huffdecode(ptr, xr[ch], channel, sfbwidth[ch], part2_length); + if (error) { + // free(xr_raw); + return error; + } + } - block_type = channel->block_type; - if (channel->flags & mixed_block_flag) - block_type = 0; + /* joint stereo processing */ - /* long blocks */ - for (sb = 0; sb < 2; ++sb, l += 18) { - III_imdct_l(&xr[ch][l], output, block_type); - III_overlap(output, frame->overlap[ch][sb], sample, sb); - } - } - else { - /* short blocks */ - for (sb = 0; sb < 2; ++sb, l += 18) { - III_imdct_s(&xr[ch][l], output); - III_overlap(output, frame->overlap[ch][sb], sample, sb); + if (header->mode == MAD_MODE_JOINT_STEREO && header->mode_extension) { + // (void*) below just to get rid of warning about passing in a * and not a [2][576] + error = III_stereo((void*)frame->xr_raw, granule, header, sfbwidth[0]); + if (error) { + // free(xr_raw); + return error; + } } - } - III_freqinver(sample, 1); + /* reordering, alias reduction, IMDCT, overlap-add, frequency inversion */ + + for (ch = 0; ch < nch; ++ch) { + struct channel const *channel = &granule->ch[ch]; + mad_fixed_t (*sample)[32] = &frame->sbsample[ch][18 * gr]; + unsigned int sb, l, i, sblimit; + mad_fixed_t output[36]; - /* (nonzero) subbands 2-31 */ + if (channel->block_type == 2) { + error = III_reorder(xr[ch], channel, sfbwidth[ch], frame->tmp); + if (error) { + // free(xr_raw); + return error; + } - i = 576; - while (i > 36 && xr[ch][i - 1] == 0) - --i; +# if !defined(OPT_STRICT) + /* + According to ISO/IEC 11172-3, "Alias reduction is not applied for + granules with block_type == 2 (short block)." However, other + sources suggest alias reduction should indeed be performed on the + lower two subbands of mixed blocks. Most other implementations do + this, so by default we will too. + */ + if (channel->flags & mixed_block_flag) { + III_aliasreduce(xr[ch], 36); + } +# endif + } else { + III_aliasreduce(xr[ch], 576); + } - sblimit = 32 - (576 - i) / 18; + l = 0; + + /* subbands 0-1 */ + + if (channel->block_type != 2 || (channel->flags & mixed_block_flag)) { + unsigned int block_type; + + block_type = channel->block_type; + if (channel->flags & mixed_block_flag) { + block_type = 0; + } + + /* long blocks */ + for (sb = 0; sb < 2; ++sb, l += 18) { + III_imdct_l(&xr[ch][l], output, block_type); + III_overlap(output, frame->overlap[ch][sb], sample, sb); + } + } else { + /* short blocks */ + for (sb = 0; sb < 2; ++sb, l += 18) { + III_imdct_s(&xr[ch][l], output); + III_overlap(output, frame->overlap[ch][sb], sample, sb); + } + } - if (channel->block_type != 2) { - /* long blocks */ - for (sb = 2; sb < sblimit; ++sb, l += 18) { - III_imdct_l(&xr[ch][l], output, channel->block_type); - III_overlap(output, frame->overlap[ch][sb], sample, sb); + III_freqinver(sample, 1); - if (sb & 1) - III_freqinver(sample, sb); - } - } - else { - /* short blocks */ - for (sb = 2; sb < sblimit; ++sb, l += 18) { - III_imdct_s(&xr[ch][l], output); - III_overlap(output, frame->overlap[ch][sb], sample, sb); - - if (sb & 1) - III_freqinver(sample, sb); - } - } + /* (nonzero) subbands 2-31 */ + + i = 576; + while (i > 36 && xr[ch][i - 1] == 0) { + --i; + } - /* remaining (zero) subbands */ + sblimit = 32 - (576 - i) / 18; + + if (channel->block_type != 2) { + /* long blocks */ + for (sb = 2; sb < sblimit; ++sb, l += 18) { + III_imdct_l(&xr[ch][l], output, channel->block_type); + III_overlap(output, frame->overlap[ch][sb], sample, sb); + + if (sb & 1) { + III_freqinver(sample, sb); + } + } + } else { + /* short blocks */ + for (sb = 2; sb < sblimit; ++sb, l += 18) { + III_imdct_s(&xr[ch][l], output); + III_overlap(output, frame->overlap[ch][sb], sample, sb); + + if (sb & 1) { + III_freqinver(sample, sb); + } + } + } - for (sb = sblimit; sb < 32; ++sb) { - III_overlap_z(frame->overlap[ch][sb], sample, sb); + /* remaining (zero) subbands */ - if (sb & 1) - III_freqinver(sample, sb); - } + for (sb = sblimit; sb < 32; ++sb) { + III_overlap_z(frame->overlap[ch][sb], sample, sb); + + if (sb & 1) { + III_freqinver(sample, sb); + } + } + } } - } -// free(xr_raw); - return MAD_ERROR_NONE; + // free(xr_raw); + return MAD_ERROR_NONE; } /* - NAME: layer->III() - DESCRIPTION: decode a single Layer III frame + NAME: layer->III() + DESCRIPTION: decode a single Layer III frame */ -int mad_layer_III(struct mad_stream *stream, struct mad_frame *frame) -{ - struct mad_header *header = &frame->header; - unsigned int nch, priv_bitlen, next_md_begin = 0; - unsigned int si_len, data_bitlen, md_len; - unsigned int frame_space, frame_used, frame_free; - struct mad_bitptr ptr; - struct sideinfo si; - enum mad_error error; - int result = 0; - stack(__FUNCTION__, __FILE__, __LINE__); - - nch = MAD_NCHANNELS(header); - si_len = (header->flags & MAD_FLAG_LSF_EXT) ? - (nch == 1 ? 9 : 17) : (nch == 1 ? 17 : 32); - - /* check frame sanity */ - - if (stream->next_frame - mad_bit_nextbyte(&stream->ptr) < - (signed int) si_len) { - stream->error = MAD_ERROR_BADFRAMELEN; - stream->md_len = 0; - return -1; - } - - /* check CRC word */ - - if (header->flags & MAD_FLAG_PROTECTION) { - header->crc_check = - mad_bit_crc(stream->ptr, si_len * CHAR_BIT, header->crc_check); - - if (header->crc_check != header->crc_target && - !(frame->options & MAD_OPTION_IGNORECRC)) { - stream->error = MAD_ERROR_BADCRC; - result = -1; - } - } +int mad_layer_III(struct mad_stream *stream, struct mad_frame *frame) { + struct mad_header *header = &frame->header; + unsigned int nch, priv_bitlen, next_md_begin = 0; + unsigned int si_len, data_bitlen, md_len; + unsigned int frame_space, frame_used, frame_free; + struct mad_bitptr ptr; + struct sideinfo si; + enum mad_error error; + int result = 0; + stackenter(__FUNCTION__, __FILE__, __LINE__); - /* decode frame side information */ + nch = MAD_NCHANNELS(header); + si_len = (header->flags & MAD_FLAG_LSF_EXT) ? + (nch == 1 ? 9 : 17) : (nch == 1 ? 17 : 32); - error = III_sideinfo(&stream->ptr, nch, header->flags & MAD_FLAG_LSF_EXT, - &si, &data_bitlen, &priv_bitlen); - if (error && result == 0) { - stream->error = error; - result = -1; - } + /* check frame sanity */ - header->flags |= priv_bitlen; - header->private_bits |= si.private_bits; + if (stream->next_frame - mad_bit_nextbyte(&stream->ptr) < + (signed int) si_len) { + stream->error = MAD_ERROR_BADFRAMELEN; + stream->md_len = 0; + return -1; + } - /* find main_data of next frame */ + /* check CRC word */ - { - struct mad_bitptr peek; - unsigned long header; + if (header->flags & MAD_FLAG_PROTECTION) { + header->crc_check = + mad_bit_crc(stream->ptr, si_len * CHAR_BIT, header->crc_check); - mad_bit_init(&peek, stream->next_frame); + if (header->crc_check != header->crc_target && + !(frame->options & MAD_OPTION_IGNORECRC)) { + stream->error = MAD_ERROR_BADCRC; + result = -1; + } + } - header = mad_bit_read(&peek, 32); - if ((header & 0xffe60000L) /* syncword | layer */ == 0xffe20000L) { - if (!(header & 0x00010000L)) /* protection_bit */ - mad_bit_skip(&peek, 16); /* crc_check */ + /* decode frame side information */ - next_md_begin = - mad_bit_read(&peek, (header & 0x00080000L) /* ID */ ? 9 : 8); + error = III_sideinfo(&stream->ptr, nch, header->flags & MAD_FLAG_LSF_EXT, + &si, &data_bitlen, &priv_bitlen); + if (error && result == 0) { + stream->error = error; + result = -1; } - mad_bit_finish(&peek); - } - - /* find main_data of this frame */ + header->flags |= priv_bitlen; + header->private_bits |= si.private_bits; - frame_space = stream->next_frame - mad_bit_nextbyte(&stream->ptr); + /* find main_data of next frame */ - if (next_md_begin > si.main_data_begin + frame_space) - next_md_begin = 0; + { + struct mad_bitptr peek; + unsigned long header; - md_len = si.main_data_begin + frame_space - next_md_begin; + mad_bit_init(&peek, stream->next_frame); - frame_used = 0; + header = mad_bit_read(&peek, 32); + if ((header & 0xffe60000L) /* syncword | layer */ == 0xffe20000L) { + if (!(header & 0x00010000L)) { /* protection_bit */ + mad_bit_skip(&peek, 16); /* crc_check */ + } - if (si.main_data_begin == 0) { - ptr = stream->ptr; - stream->md_len = 0; + next_md_begin = + mad_bit_read(&peek, (header & 0x00080000L) /* ID */ ? 9 : 8); + } - frame_used = md_len; - } - else { - if (si.main_data_begin > stream->md_len) { - if (result == 0) { - stream->error = MAD_ERROR_BADDATAPTR; - result = -1; - } + mad_bit_finish(&peek); } - else { - mad_bit_init(&ptr, - stream->main_data + stream->md_len - si.main_data_begin); - if (md_len > si.main_data_begin) { - assert(stream->md_len + md_len - - si.main_data_begin <= MAD_BUFFER_MDLEN); + /* find main_data of this frame */ - memcpy(stream->main_data + stream->md_len, - mad_bit_nextbyte(&stream->ptr), - frame_used = md_len - si.main_data_begin); - stream->md_len += frame_used; - } + frame_space = stream->next_frame - mad_bit_nextbyte(&stream->ptr); + + if (next_md_begin > si.main_data_begin + frame_space) { + next_md_begin = 0; } - } - frame_free = frame_space - frame_used; + md_len = si.main_data_begin + frame_space - next_md_begin; - /* decode main_data */ + frame_used = 0; - if (result == 0) { - error = III_decode(&ptr, frame, &si, nch); - if (error) { - stream->error = error; - result = -1; + if (si.main_data_begin == 0) { + ptr = stream->ptr; + stream->md_len = 0; + + frame_used = md_len; + } else { + if (si.main_data_begin > stream->md_len) { + if (result == 0) { + stream->error = MAD_ERROR_BADDATAPTR; + result = -1; + } + } else { + mad_bit_init(&ptr, + stream->main_data + stream->md_len - si.main_data_begin); + + if (md_len > si.main_data_begin) { + assert(stream->md_len + md_len - + si.main_data_begin <= MAD_BUFFER_MDLEN); + + memcpy(stream->main_data + stream->md_len, + mad_bit_nextbyte(&stream->ptr), + frame_used = md_len - si.main_data_begin); + stream->md_len += frame_used; + } + } } - /* designate ancillary bits */ + frame_free = frame_space - frame_used; + + /* decode main_data */ - stream->anc_ptr = ptr; - stream->anc_bitlen = md_len * CHAR_BIT - data_bitlen; - } + if (result == 0) { + error = III_decode(&ptr, frame, &si, nch); + if (error) { + stream->error = error; + result = -1; + } + + /* designate ancillary bits */ + + stream->anc_ptr = ptr; + stream->anc_bitlen = md_len * CHAR_BIT - data_bitlen; + } # if 0 && defined(DEBUG) - fprintf(stderr, - "main_data_begin:%u, md_len:%u, frame_free:%u, " - "data_bitlen:%u, anc_bitlen: %u\n", - si.main_data_begin, md_len, frame_free, - data_bitlen, stream->anc_bitlen); + fprintf(stderr, + "main_data_begin:%u, md_len:%u, frame_free:%u, " + "data_bitlen:%u, anc_bitlen: %u\n", + si.main_data_begin, md_len, frame_free, + data_bitlen, stream->anc_bitlen); # endif - /* preload main_data buffer with up to 511 bytes for next frame(s) */ - - if (frame_free >= next_md_begin) { - memcpy(stream->main_data, - stream->next_frame - next_md_begin, next_md_begin); - stream->md_len = next_md_begin; - } - else { - if (md_len < si.main_data_begin) { - unsigned int extra; - - extra = si.main_data_begin - md_len; - if (extra + frame_free > next_md_begin) - extra = next_md_begin - frame_free; - - if (extra < stream->md_len) { - memmove(stream->main_data, - stream->main_data + stream->md_len - extra, extra); - stream->md_len = extra; - } - } - else - stream->md_len = 0; + /* preload main_data buffer with up to 511 bytes for next frame(s) */ - memcpy(stream->main_data + stream->md_len, - stream->next_frame - frame_free, frame_free); - stream->md_len += frame_free; - } + if (frame_free >= next_md_begin) { + memcpy(stream->main_data, + stream->next_frame - next_md_begin, next_md_begin); + stream->md_len = next_md_begin; + } else { + if (md_len < si.main_data_begin) { + unsigned int extra; + + extra = si.main_data_begin - md_len; + if (extra + frame_free > next_md_begin) { + extra = next_md_begin - frame_free; + } + + if (extra < stream->md_len) { + memmove(stream->main_data, + stream->main_data + stream->md_len - extra, extra); + stream->md_len = extra; + } + } else { + stream->md_len = 0; + } + + memcpy(stream->main_data + stream->md_len, + stream->next_frame - frame_free, frame_free); + stream->md_len += frame_free; + } - return result; + return result; } diff --git a/src/libmad/layer3.h b/src/libmad/layer3.h index 2504d461..70ba11ce 100644 --- a/src/libmad/layer3.h +++ b/src/libmad/layer3.h @@ -1,23 +1,23 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: layer3.h,v 1.10 2004/01/23 09:41:32 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: layer3.h,v 1.10 2004/01/23 09:41:32 rob Exp $ +*/ # ifndef LIBMAD_LAYER3_H # define LIBMAD_LAYER3_H diff --git a/src/libmad/mad.h b/src/libmad/mad.h index 0ed3a16a..0c415a07 100644 --- a/src/libmad/mad.h +++ b/src/libmad/mad.h @@ -1,24 +1,24 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * If you would like to negotiate alternate licensing terms, you may do - * so by contacting: Underbit Technologies, Inc. - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + If you would like to negotiate alternate licensing terms, you may do + so by contacting: Underbit Technologies, Inc. +*/ # ifdef __cplusplus extern "C" { @@ -89,27 +89,27 @@ typedef mad_fixed_t mad_sample_t; # endif /* - * Fixed-point format: 0xABBBBBBB - * A == whole part (sign + 3 bits) - * B == fractional part (28 bits) - * - * Values are signed two's complement, so the effective range is: - * 0x80000000 to 0x7fffffff - * -8.0 to +7.9999999962747097015380859375 - * - * The smallest representable value is: - * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9) - * - * 28 bits of fractional accuracy represent about - * 8.6 digits of decimal accuracy. - * - * Fixed-point numbers can be added or subtracted as normal - * integers, but multiplication requires shifting the 64-bit result - * from 56 fractional bits back to 28 (and rounding.) - * - * Changing the definition of MAD_F_FRACBITS is only partially - * supported, and must be done with care. - */ + Fixed-point format: 0xABBBBBBB + A == whole part (sign + 3 bits) + B == fractional part (28 bits) + + Values are signed two's complement, so the effective range is: + 0x80000000 to 0x7fffffff + -8.0 to +7.9999999962747097015380859375 + + The smallest representable value is: + 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9) + + 28 bits of fractional accuracy represent about + 8.6 digits of decimal accuracy. + + Fixed-point numbers can be added or subtracted as normal + integers, but multiplication requires shifting the 64-bit result + from 56 fractional bits back to 28 (and rounding.) + + Changing the definition of MAD_F_FRACBITS is only partially + supported, and must be done with care. +*/ # define MAD_F_FRACBITS 28 @@ -141,7 +141,7 @@ typedef mad_fixed_t mad_sample_t; # define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS) # define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1)) - /* (x should be positive) */ +/* (x should be positive) */ # define mad_f_fromint(x) ((x) << MAD_F_FRACBITS) @@ -162,9 +162,9 @@ typedef mad_fixed_t mad_sample_t; # elif defined(FPM_64BIT) /* - * This version should be the most accurate if 64-bit types are supported by - * the compiler, although it may not be the most efficient. - */ + This version should be the most accurate if 64-bit types are supported by + the compiler, although it may not be the most efficient. +*/ # if defined(OPT_ACCURACY) # define mad_f_mul(x, y) \ ((mad_fixed_t) \ @@ -185,19 +185,18 @@ typedef mad_fixed_t mad_sample_t; # pragma warning(push) # pragma warning(disable: 4035) /* no return value */ static __forceinline -mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) -{ - enum { - fracbits = MAD_F_FRACBITS - }; - - __asm { - mov eax, x - imul y - shrd eax, edx, fracbits - } - - /* implicit return of eax */ +mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) { + enum { + fracbits = MAD_F_FRACBITS + }; + + __asm { + mov eax, x + imul y + shrd eax, edx, fracbits + } + + /* implicit return of eax */ } # pragma warning(pop) @@ -205,9 +204,9 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # define mad_f_scale64 # else /* - * This Intel version is fast and accurate; the disposition of the least - * significant bit depends on OPT_ACCURACY via mad_f_scale64(). - */ + This Intel version is fast and accurate; the disposition of the least + significant bit depends on OPT_ACCURACY via mad_f_scale64(). +*/ # define MAD_F_MLX(hi, lo, x, y) \ asm ("imull %3" \ : "=a" (lo), "=d" (hi) \ @@ -216,8 +215,8 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # if defined(OPT_ACCURACY) /* - * This gives best accuracy but is not very fast. - */ + This gives best accuracy but is not very fast. +*/ # define MAD_F_MLA(hi, lo, x, y) \ ({ mad_fixed64hi_t __hi; \ mad_fixed64lo_t __lo; \ @@ -232,8 +231,8 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # if defined(OPT_ACCURACY) /* - * Surprisingly, this is faster than SHRD followed by ADC. - */ + Surprisingly, this is faster than SHRD followed by ADC. +*/ # define mad_f_scale64(hi, lo) \ ({ mad_fixed64hi_t __hi_; \ mad_fixed64lo_t __lo_; \ @@ -252,8 +251,8 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) }) # elif defined(OPT_INTEL) /* - * Alternate Intel scaling that may or may not perform better. - */ + Alternate Intel scaling that may or may not perform better. +*/ # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result; \ asm ("shrl %3,%1\n\t" \ @@ -283,15 +282,15 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # elif defined(FPM_ARM) -/* - * This ARM V4 version is as accurate as FPM_64BIT but much faster. The - * least significant bit is properly rounded at no CPU cycle cost! - */ +/* + This ARM V4 version is as accurate as FPM_64BIT but much faster. The + least significant bit is properly rounded at no CPU cycle cost! +*/ # if 1 /* - * This is faster than the default implementation via MAD_F_MLX() and - * mad_f_scale64(). - */ + This is faster than the default implementation via MAD_F_MLX() and + mad_f_scale64(). +*/ # define mad_f_mul(x, y) \ ({ mad_fixed64hi_t __hi; \ mad_fixed64lo_t __lo; \ @@ -342,9 +341,9 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # elif defined(FPM_MIPS) /* - * This MIPS version is fast and accurate; the disposition of the least - * significant bit depends on OPT_ACCURACY via mad_f_scale64(). - */ + This MIPS version is fast and accurate; the disposition of the least + significant bit depends on OPT_ACCURACY via mad_f_scale64(). +*/ # define MAD_F_MLX(hi, lo, x, y) \ asm ("mult %2,%3" \ : "=l" (lo), "=h" (hi) \ @@ -357,9 +356,9 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) : "%r" (x), "r" (y)) # elif defined(HAVE_MADD16_ASM) /* - * This loses significant accuracy due to the 16-bit integer limit in the - * multiply/accumulate instruction. - */ + This loses significant accuracy due to the 16-bit integer limit in the + multiply/accumulate instruction. +*/ # define MAD_F_ML0(hi, lo, x, y) \ asm ("mult %2,%3" \ : "=l" (lo), "=h" (hi) \ @@ -382,9 +381,9 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # elif defined(FPM_SPARC) /* - * This SPARC V8 version is fast and accurate; the disposition of the least - * significant bit depends on OPT_ACCURACY via mad_f_scale64(). - */ + This SPARC V8 version is fast and accurate; the disposition of the least + significant bit depends on OPT_ACCURACY via mad_f_scale64(). +*/ # define MAD_F_MLX(hi, lo, x, y) \ asm ("smul %2, %3, %0\n\t" \ "rd %%y, %1" \ @@ -396,9 +395,9 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # elif defined(FPM_PPC) /* - * This PowerPC version is fast and accurate; the disposition of the least - * significant bit depends on OPT_ACCURACY via mad_f_scale64(). - */ + This PowerPC version is fast and accurate; the disposition of the least + significant bit depends on OPT_ACCURACY via mad_f_scale64(). +*/ # define MAD_F_MLX(hi, lo, x, y) \ do { \ asm ("mullw %0,%1,%2" \ @@ -412,8 +411,8 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # if defined(OPT_ACCURACY) /* - * This gives best accuracy but is not very fast. - */ + This gives best accuracy but is not very fast. +*/ # define MAD_F_MLA(hi, lo, x, y) \ ({ mad_fixed64hi_t __hi; \ mad_fixed64lo_t __lo; \ @@ -429,8 +428,8 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # if defined(OPT_ACCURACY) /* - * This is slower than the truncating version below it. - */ + This is slower than the truncating version below it. +*/ # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result, __round; \ asm ("rotrwi %0,%1,%2" \ @@ -467,14 +466,14 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # elif defined(FPM_DEFAULT) /* - * This version is the most portable but it loses significant accuracy. - * Furthermore, accuracy is biased against the second argument, so care - * should be taken when ordering operands. - * - * The scale factors are constant as this is not used with SSO. - * - * Pre-rounding is required to stay within the limits of compliance. - */ + This version is the most portable but it loses significant accuracy. + Furthermore, accuracy is biased against the second argument, so care + should be taken when ordering operands. + + The scale factors are constant as this is not used with SSO. + + Pre-rounding is required to stay within the limits of compliance. +*/ # if defined(OPT_SPEED) # define mad_f_mul(x, y) (((x) >> 12) * ((y) >> 16)) # else @@ -546,9 +545,9 @@ mad_fixed_t mad_f_div(mad_fixed_t, mad_fixed_t); # define LIBMAD_BIT_H struct mad_bitptr { - unsigned char const *byte; - unsigned short cache; - unsigned short left; + unsigned char const *byte; + unsigned short cache; + unsigned short left; }; void mad_bit_init(struct mad_bitptr *, unsigned char const *); @@ -556,7 +555,7 @@ void mad_bit_init(struct mad_bitptr *, unsigned char const *); # define mad_bit_finish(bitptr) /* nothing */ unsigned int mad_bit_length(struct mad_bitptr const *, - struct mad_bitptr const *); + struct mad_bitptr const *); # define mad_bit_bitsleft(bitptr) ((bitptr)->left) unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *); @@ -575,8 +574,8 @@ unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short); # define LIBMAD_TIMER_H typedef struct { - signed long seconds; /* whole seconds */ - unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */ + signed long seconds; /* whole seconds */ + unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */ } mad_timer_t; extern mad_timer_t const mad_timer_zero; @@ -584,51 +583,51 @@ extern mad_timer_t const mad_timer_zero; # define MAD_TIMER_RESOLUTION 352800000UL enum mad_units { - MAD_UNITS_HOURS = -2, - MAD_UNITS_MINUTES = -1, - MAD_UNITS_SECONDS = 0, + MAD_UNITS_HOURS = -2, + MAD_UNITS_MINUTES = -1, + MAD_UNITS_SECONDS = 0, - /* metric units */ + /* metric units */ - MAD_UNITS_DECISECONDS = 10, - MAD_UNITS_CENTISECONDS = 100, - MAD_UNITS_MILLISECONDS = 1000, + MAD_UNITS_DECISECONDS = 10, + MAD_UNITS_CENTISECONDS = 100, + MAD_UNITS_MILLISECONDS = 1000, - /* audio sample units */ + /* audio sample units */ - MAD_UNITS_8000_HZ = 8000, - MAD_UNITS_11025_HZ = 11025, - MAD_UNITS_12000_HZ = 12000, + MAD_UNITS_8000_HZ = 8000, + MAD_UNITS_11025_HZ = 11025, + MAD_UNITS_12000_HZ = 12000, - MAD_UNITS_16000_HZ = 16000, - MAD_UNITS_22050_HZ = 22050, - MAD_UNITS_24000_HZ = 24000, + MAD_UNITS_16000_HZ = 16000, + MAD_UNITS_22050_HZ = 22050, + MAD_UNITS_24000_HZ = 24000, - MAD_UNITS_32000_HZ = 32000, - MAD_UNITS_44100_HZ = 44100, - MAD_UNITS_48000_HZ = 48000, + MAD_UNITS_32000_HZ = 32000, + MAD_UNITS_44100_HZ = 44100, + MAD_UNITS_48000_HZ = 48000, - /* video frame/field units */ + /* video frame/field units */ - MAD_UNITS_24_FPS = 24, - MAD_UNITS_25_FPS = 25, - MAD_UNITS_30_FPS = 30, - MAD_UNITS_48_FPS = 48, - MAD_UNITS_50_FPS = 50, - MAD_UNITS_60_FPS = 60, + MAD_UNITS_24_FPS = 24, + MAD_UNITS_25_FPS = 25, + MAD_UNITS_30_FPS = 30, + MAD_UNITS_48_FPS = 48, + MAD_UNITS_50_FPS = 50, + MAD_UNITS_60_FPS = 60, - /* CD audio frames */ + /* CD audio frames */ - MAD_UNITS_75_FPS = 75, + MAD_UNITS_75_FPS = 75, - /* video drop-frame units */ + /* video drop-frame units */ - MAD_UNITS_23_976_FPS = -24, - MAD_UNITS_24_975_FPS = -25, - MAD_UNITS_29_97_FPS = -30, - MAD_UNITS_47_952_FPS = -48, - MAD_UNITS_49_95_FPS = -50, - MAD_UNITS_59_94_FPS = -60 + MAD_UNITS_23_976_FPS = -24, + MAD_UNITS_24_975_FPS = -25, + MAD_UNITS_29_97_FPS = -30, + MAD_UNITS_47_952_FPS = -48, + MAD_UNITS_49_95_FPS = -50, + MAD_UNITS_59_94_FPS = -60 }; # define mad_timer_reset(timer) ((void) (*(timer) = mad_timer_zero)) @@ -647,7 +646,7 @@ void mad_timer_multiply(mad_timer_t *, signed long); signed long mad_timer_count(mad_timer_t, enum mad_units); unsigned long mad_timer_fraction(mad_timer_t, unsigned long); void mad_timer_string(mad_timer_t, char *, char const *, - enum mad_units, enum mad_units, unsigned long); + enum mad_units, enum mad_units, unsigned long); # endif @@ -661,66 +660,66 @@ void mad_timer_string(mad_timer_t, char *, char const *, # define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD) enum mad_error { - MAD_ERROR_NONE = 0x0000, /* no error */ - - MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */ - MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */ - - MAD_ERROR_NOMEM = 0x0031, /* not enough memory */ - - MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */ - MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */ - MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */ - MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */ - MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */ - - MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */ - MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */ - MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */ - MAD_ERROR_BADMODE = 0x0222, /* bad bitrate/mode combination */ - MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */ - MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */ - MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */ - MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */ - MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */ - MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */ - MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */ - MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */ - MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */ + MAD_ERROR_NONE = 0x0000, /* no error */ + + MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */ + MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */ + + MAD_ERROR_NOMEM = 0x0031, /* not enough memory */ + + MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */ + MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */ + MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */ + MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */ + MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */ + + MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */ + MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */ + MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */ + MAD_ERROR_BADMODE = 0x0222, /* bad bitrate/mode combination */ + MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */ + MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */ + MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */ + MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */ + MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */ + MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */ + MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */ + MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */ + MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */ }; # define MAD_RECOVERABLE(error) ((error) & 0xff00) struct mad_stream { - unsigned char const *buffer; /* input bitstream buffer */ - unsigned char const *bufend; /* end of buffer */ - unsigned long skiplen; /* bytes to skip before next frame */ + unsigned char const *buffer; /* input bitstream buffer */ + unsigned char const *bufend; /* end of buffer */ + unsigned long skiplen; /* bytes to skip before next frame */ - int sync; /* stream sync found */ - unsigned long freerate; /* free bitrate (fixed) */ + int sync; /* stream sync found */ + unsigned long freerate; /* free bitrate (fixed) */ - unsigned char const *this_frame; /* start of current frame */ - unsigned char const *next_frame; /* start of next frame */ - struct mad_bitptr ptr; /* current processing bit pointer */ + unsigned char const *this_frame; /* start of current frame */ + unsigned char const *next_frame; /* start of next frame */ + struct mad_bitptr ptr; /* current processing bit pointer */ - struct mad_bitptr anc_ptr; /* ancillary bits pointer */ - unsigned int anc_bitlen; /* number of ancillary bits */ + struct mad_bitptr anc_ptr; /* ancillary bits pointer */ + unsigned int anc_bitlen; /* number of ancillary bits */ - unsigned char main_data[MAD_BUFFER_MDLEN]; - /* Layer III main_data() */ - unsigned int md_len; /* bytes in main_data */ + unsigned char main_data[MAD_BUFFER_MDLEN]; + /* Layer III main_data() */ + unsigned int md_len; /* bytes in main_data */ - int options; /* decoding options (see below) */ - enum mad_error error; /* error code (see above) */ + int options; /* decoding options (see below) */ + enum mad_error error; /* error code (see above) */ }; enum { - MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */ - MAD_OPTION_HALFSAMPLERATE = 0x0002 /* generate PCM at 1/2 sample rate */ + MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */ + MAD_OPTION_HALFSAMPLERATE = 0x0002 /* generate PCM at 1/2 sample rate */ # if 0 /* not yet implemented */ - MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */ - MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */ - MAD_OPTION_SINGLECHANNEL = 0x0030 /* combine channels */ + MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */ + MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */ + MAD_OPTION_SINGLECHANNEL = 0x0030 /* combine channels */ # endif }; @@ -731,7 +730,7 @@ void mad_stream_finish(struct mad_stream *); ((void) ((stream)->options = (opts))) void mad_stream_buffer(struct mad_stream *, - unsigned char const *, unsigned long); + unsigned char const *, unsigned long); void mad_stream_skip(struct mad_stream *, unsigned long); int mad_stream_sync(struct mad_stream *); @@ -747,53 +746,53 @@ char const *mad_stream_errorstr(struct mad_stream const *); enum mad_layer { - MAD_LAYER_I = 1, /* Layer I */ - MAD_LAYER_II = 2, /* Layer II */ - MAD_LAYER_III = 3 /* Layer III */ + MAD_LAYER_I = 1, /* Layer I */ + MAD_LAYER_II = 2, /* Layer II */ + MAD_LAYER_III = 3 /* Layer III */ }; enum mad_mode { - MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */ - MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */ - MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */ - MAD_MODE_STEREO = 3 /* normal LR stereo */ + MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */ + MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */ + MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */ + MAD_MODE_STEREO = 3 /* normal LR stereo */ }; enum mad_emphasis { - MAD_EMPHASIS_NONE = 0, /* no emphasis */ - MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */ - MAD_EMPHASIS_CCITT_J_17 = 3, /* CCITT J.17 emphasis */ - MAD_EMPHASIS_RESERVED = 2 /* unknown emphasis */ + MAD_EMPHASIS_NONE = 0, /* no emphasis */ + MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */ + MAD_EMPHASIS_CCITT_J_17 = 3, /* CCITT J.17 emphasis */ + MAD_EMPHASIS_RESERVED = 2 /* unknown emphasis */ }; struct mad_header { - enum mad_layer layer; /* audio layer (1, 2, or 3) */ - enum mad_mode mode; /* channel mode (see above) */ - int mode_extension; /* additional mode info */ - enum mad_emphasis emphasis; /* de-emphasis to use (see above) */ + enum mad_layer layer; /* audio layer (1, 2, or 3) */ + enum mad_mode mode; /* channel mode (see above) */ + int mode_extension; /* additional mode info */ + enum mad_emphasis emphasis; /* de-emphasis to use (see above) */ - unsigned long bitrate; /* stream bitrate (bps) */ - unsigned int samplerate; /* sampling frequency (Hz) */ + unsigned long bitrate; /* stream bitrate (bps) */ + unsigned int samplerate; /* sampling frequency (Hz) */ - unsigned short crc_check; /* frame CRC accumulator */ - unsigned short crc_target; /* final target CRC checksum */ + unsigned short crc_check; /* frame CRC accumulator */ + unsigned short crc_target; /* final target CRC checksum */ - int flags; /* flags (see below) */ - int private_bits; /* private bits (see below) */ + int flags; /* flags (see below) */ + int private_bits; /* private bits (see below) */ - mad_timer_t duration; /* audio playing time of frame */ + mad_timer_t duration; /* audio playing time of frame */ }; struct mad_frame { - struct mad_header header; /* MPEG audio header */ + struct mad_header header; /* MPEG audio header */ - int options; /* decoding options (from stream) */ + int options; /* decoding options (from stream) */ - mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */ - mad_fixed_t overlap[2][32][18]; /* Layer III block overlap data */ + mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */ + mad_fixed_t overlap[2][32][18]; /* Layer III block overlap data */ - mad_fixed_t xr_raw[576*2]; - mad_fixed_t tmp[576]; + mad_fixed_t xr_raw[576 * 2]; + mad_fixed_t tmp[576]; }; # define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1) @@ -803,26 +802,26 @@ struct mad_frame { ((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36)) enum { - MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */ - MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */ + MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */ + MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */ - MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */ - MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */ - MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */ - MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */ + MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */ + MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */ + MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */ + MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */ - MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */ - MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */ - MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */ + MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */ + MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */ + MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */ - MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */ - MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */ - MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */ + MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */ + MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */ + MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */ }; enum { - MAD_PRIVATE_HEADER = 0x0100, /* header private bit */ - MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */ + MAD_PRIVATE_HEADER = 0x0100, /* header private bit */ + MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */ }; void mad_header_init(struct mad_header *); @@ -847,36 +846,36 @@ void mad_frame_mute(struct mad_frame *); struct mad_pcm { - unsigned int samplerate; /* sampling frequency (Hz) */ - unsigned short channels; /* number of channels */ - unsigned short length; /* number of samples per channel */ - int16_t samples[2][32];//1152]; /* PCM output samples [ch][sample] */ + unsigned int samplerate; /* sampling frequency (Hz) */ + unsigned short channels; /* number of channels */ + unsigned short length; /* number of samples per channel */ + int16_t samples[2][32];//1152]; /* PCM output samples [ch][sample] */ }; struct mad_synth { - mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */ - /* [ch][eo][peo][s][v] */ + mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */ + /* [ch][eo][peo][s][v] */ - unsigned int phase; /* current processing phase */ + unsigned int phase; /* current processing phase */ - struct mad_pcm pcm; /* PCM output */ + struct mad_pcm pcm; /* PCM output */ }; /* single channel PCM selector */ enum { - MAD_PCM_CHANNEL_SINGLE = 0 + MAD_PCM_CHANNEL_SINGLE = 0 }; /* dual channel PCM selector */ enum { - MAD_PCM_CHANNEL_DUAL_1 = 0, - MAD_PCM_CHANNEL_DUAL_2 = 1 + MAD_PCM_CHANNEL_DUAL_1 = 0, + MAD_PCM_CHANNEL_DUAL_2 = 1 }; /* stereo PCM selector */ enum { - MAD_PCM_CHANNEL_STEREO_LEFT = 0, - MAD_PCM_CHANNEL_STEREO_RIGHT = 1 + MAD_PCM_CHANNEL_STEREO_LEFT = 0, + MAD_PCM_CHANNEL_STEREO_RIGHT = 1 }; void mad_synth_init(struct mad_synth *); @@ -885,16 +884,16 @@ void mad_synth_init(struct mad_synth *); enum mad_flow { - MAD_FLOW_CONTINUE = 0x0000, /* continue normally */ - MAD_FLOW_STOP = 0x0010, /* stop decoding normally */ - MAD_FLOW_BREAK = 0x0011, /* stop decoding and signal an error */ - MAD_FLOW_IGNORE = 0x0020 /* ignore the current frame */ + MAD_FLOW_CONTINUE = 0x0000, /* continue normally */ + MAD_FLOW_STOP = 0x0010, /* stop decoding normally */ + MAD_FLOW_BREAK = 0x0011, /* stop decoding and signal an error */ + MAD_FLOW_IGNORE = 0x0020 /* ignore the current frame */ }; void mad_synth_mute(struct mad_synth *); -enum mad_flow mad_synth_frame(struct mad_synth *, struct mad_frame const *, enum mad_flow (*output_func)(void *s, struct mad_header const *, struct mad_pcm *), void *cbdata ); +enum mad_flow mad_synth_frame(struct mad_synth *, struct mad_frame const *, enum mad_flow(*output_func)(void *s, struct mad_header const *, struct mad_pcm *), void *cbdata); enum mad_flow mad_synth_frame_onens(struct mad_synth *synth, struct mad_frame const *frame, unsigned int ns); # endif @@ -906,53 +905,53 @@ enum mad_flow mad_synth_frame_onens(struct mad_synth *synth, struct mad_frame co enum mad_decoder_mode { - MAD_DECODER_MODE_SYNC = 0, - MAD_DECODER_MODE_ASYNC + MAD_DECODER_MODE_SYNC = 0, + MAD_DECODER_MODE_ASYNC }; struct mad_decoder { - enum mad_decoder_mode mode; - - int options; - - struct { - long pid; - int in; - int out; - } async; - - struct { - struct mad_stream stream; - struct mad_frame frame; - struct mad_synth synth; - } *sync; - - void *cb_data; - - enum mad_flow (*input_func)(void *, struct mad_stream *); - enum mad_flow (*header_func)(void *, struct mad_header const *); - enum mad_flow (*filter_func)(void *, - struct mad_stream const *, struct mad_frame *); - enum mad_flow (*output_func)(void *, - struct mad_header const *, struct mad_pcm *); - enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); - enum mad_flow (*message_func)(void *, void *, unsigned int *); + enum mad_decoder_mode mode; + + int options; + + struct { + long pid; + int in; + int out; + } async; + + struct { + struct mad_stream stream; + struct mad_frame frame; + struct mad_synth synth; + } *sync; + + void *cb_data; + + enum mad_flow(*input_func)(void *, struct mad_stream *); + enum mad_flow(*header_func)(void *, struct mad_header const *); + enum mad_flow(*filter_func)(void *, + struct mad_stream const *, struct mad_frame *); + enum mad_flow(*output_func)(void *, + struct mad_header const *, struct mad_pcm *); + enum mad_flow(*error_func)(void *, struct mad_stream *, struct mad_frame *); + enum mad_flow(*message_func)(void *, void *, unsigned int *); }; void mad_decoder_init(struct mad_decoder *, void *, - enum mad_flow (*)(void *, struct mad_stream *), - enum mad_flow (*)(void *, struct mad_header const *), - enum mad_flow (*)(void *, - struct mad_stream const *, - struct mad_frame *), - enum mad_flow (*)(void *, - struct mad_header const *, - struct mad_pcm *), - enum mad_flow (*)(void *, - struct mad_stream *, - struct mad_frame *), - enum mad_flow (*)(void *, void *, unsigned int *)); + enum mad_flow(*)(void *, struct mad_stream *), + enum mad_flow(*)(void *, struct mad_header const *), + enum mad_flow(*)(void *, + struct mad_stream const *, + struct mad_frame *), + enum mad_flow(*)(void *, + struct mad_header const *, + struct mad_pcm *), + enum mad_flow(*)(void *, + struct mad_stream *, + struct mad_frame *), + enum mad_flow(*)(void *, void *, unsigned int *)); int mad_decoder_finish(struct mad_decoder *); # define mad_decoder_options(decoder, opts) \ diff --git a/src/libmad/qc_table.dat.h b/src/libmad/qc_table.dat.h index 35a22234..6fb36ec0 100644 --- a/src/libmad/qc_table.dat.h +++ b/src/libmad/qc_table.dat.h @@ -1,77 +1,95 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: qc_table.dat,v 1.7 2004/01/23 09:41:32 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: qc_table.dat,v 1.7 2004/01/23 09:41:32 rob Exp $ +*/ /* - * These are the Layer II classes of quantization. - * The table is derived from Table B.4 of ISO/IEC 11172-3. - */ + These are the Layer II classes of quantization. + The table is derived from Table B.4 of ISO/IEC 11172-3. +*/ - { 3, 2, 5, +{ + 3, 2, 5, MAD_F(0x15555555) /* 1.33333333333 => 1.33333333209, e 0.00000000124 */, - MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, - { 5, 3, 7, + MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ +}, { + 5, 3, 7, MAD_F(0x1999999a) /* 1.60000000000 => 1.60000000149, e -0.00000000149 */, - MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, - { 7, 0, 3, + MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ +}, { + 7, 0, 3, MAD_F(0x12492492) /* 1.14285714286 => 1.14285714179, e 0.00000000107 */, - MAD_F(0x04000000) /* 0.25000000000 => 0.25000000000, e 0.00000000000 */ }, - { 9, 4, 10, + MAD_F(0x04000000) /* 0.25000000000 => 0.25000000000, e 0.00000000000 */ +}, { + 9, 4, 10, MAD_F(0x1c71c71c) /* 1.77777777777 => 1.77777777612, e 0.00000000165 */, - MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, - { 15, 0, 4, + MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ +}, { + 15, 0, 4, MAD_F(0x11111111) /* 1.06666666666 => 1.06666666642, e 0.00000000024 */, - MAD_F(0x02000000) /* 0.12500000000 => 0.12500000000, e 0.00000000000 */ }, - { 31, 0, 5, + MAD_F(0x02000000) /* 0.12500000000 => 0.12500000000, e 0.00000000000 */ +}, { + 31, 0, 5, MAD_F(0x10842108) /* 1.03225806452 => 1.03225806355, e 0.00000000097 */, - MAD_F(0x01000000) /* 0.06250000000 => 0.06250000000, e 0.00000000000 */ }, - { 63, 0, 6, + MAD_F(0x01000000) /* 0.06250000000 => 0.06250000000, e 0.00000000000 */ +}, { + 63, 0, 6, MAD_F(0x10410410) /* 1.01587301587 => 1.01587301493, e 0.00000000094 */, - MAD_F(0x00800000) /* 0.03125000000 => 0.03125000000, e 0.00000000000 */ }, - { 127, 0, 7, + MAD_F(0x00800000) /* 0.03125000000 => 0.03125000000, e 0.00000000000 */ +}, { + 127, 0, 7, MAD_F(0x10204081) /* 1.00787401575 => 1.00787401572, e 0.00000000003 */, - MAD_F(0x00400000) /* 0.01562500000 => 0.01562500000, e 0.00000000000 */ }, - { 255, 0, 8, + MAD_F(0x00400000) /* 0.01562500000 => 0.01562500000, e 0.00000000000 */ +}, { + 255, 0, 8, MAD_F(0x10101010) /* 1.00392156863 => 1.00392156839, e 0.00000000024 */, - MAD_F(0x00200000) /* 0.00781250000 => 0.00781250000, e 0.00000000000 */ }, - { 511, 0, 9, + MAD_F(0x00200000) /* 0.00781250000 => 0.00781250000, e 0.00000000000 */ +}, { + 511, 0, 9, MAD_F(0x10080402) /* 1.00195694716 => 1.00195694715, e 0.00000000001 */, - MAD_F(0x00100000) /* 0.00390625000 => 0.00390625000, e 0.00000000000 */ }, - { 1023, 0, 10, + MAD_F(0x00100000) /* 0.00390625000 => 0.00390625000, e 0.00000000000 */ +}, { + 1023, 0, 10, MAD_F(0x10040100) /* 1.00097751711 => 1.00097751617, e 0.00000000094 */, - MAD_F(0x00080000) /* 0.00195312500 => 0.00195312500, e 0.00000000000 */ }, - { 2047, 0, 11, + MAD_F(0x00080000) /* 0.00195312500 => 0.00195312500, e 0.00000000000 */ +}, { + 2047, 0, 11, MAD_F(0x10020040) /* 1.00048851979 => 1.00048851967, e 0.00000000012 */, - MAD_F(0x00040000) /* 0.00097656250 => 0.00097656250, e 0.00000000000 */ }, - { 4095, 0, 12, + MAD_F(0x00040000) /* 0.00097656250 => 0.00097656250, e 0.00000000000 */ +}, { + 4095, 0, 12, MAD_F(0x10010010) /* 1.00024420024 => 1.00024420023, e 0.00000000001 */, - MAD_F(0x00020000) /* 0.00048828125 => 0.00048828125, e 0.00000000000 */ }, - { 8191, 0, 13, + MAD_F(0x00020000) /* 0.00048828125 => 0.00048828125, e 0.00000000000 */ +}, { + 8191, 0, 13, MAD_F(0x10008004) /* 1.00012208522 => 1.00012208521, e 0.00000000001 */, - MAD_F(0x00010000) /* 0.00024414063 => 0.00024414062, e 0.00000000000 */ }, - { 16383, 0, 14, + MAD_F(0x00010000) /* 0.00024414063 => 0.00024414062, e 0.00000000000 */ +}, { + 16383, 0, 14, MAD_F(0x10004001) /* 1.00006103888 => 1.00006103888, e -0.00000000000 */, - MAD_F(0x00008000) /* 0.00012207031 => 0.00012207031, e -0.00000000000 */ }, - { 32767, 0, 15, + MAD_F(0x00008000) /* 0.00012207031 => 0.00012207031, e -0.00000000000 */ +}, { + 32767, 0, 15, MAD_F(0x10002000) /* 1.00003051851 => 1.00003051758, e 0.00000000093 */, - MAD_F(0x00004000) /* 0.00006103516 => 0.00006103516, e 0.00000000000 */ }, - { 65535, 0, 16, + MAD_F(0x00004000) /* 0.00006103516 => 0.00006103516, e 0.00000000000 */ +}, { + 65535, 0, 16, MAD_F(0x10001000) /* 1.00001525902 => 1.00001525879, e 0.00000000023 */, - MAD_F(0x00002000) /* 0.00003051758 => 0.00003051758, e 0.00000000000 */ } + MAD_F(0x00002000) /* 0.00003051758 => 0.00003051758, e 0.00000000000 */ +} diff --git a/src/libmad/rq_table.dat.h b/src/libmad/rq_table.dat.h index 059c4f31..34b26303 100644 --- a/src/libmad/rq_table.dat.h +++ b/src/libmad/rq_table.dat.h @@ -1,8747 +1,8747 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: rq_table.dat,v 1.7 2004/01/23 09:41:32 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: rq_table.dat,v 1.7 2004/01/23 09:41:32 rob Exp $ +*/ /* - * This is the lookup table used to compute x^(4/3) for Layer III - * requantization. To maintain the best possible accuracy, the value is - * stored as a normalized mantissa with exponent. The requantization - * algorithm recombines these parts with appropriate scaling. - */ - - /* 0 */ { MAD_F(0x00000000) /* 0.000000000 */, 0 }, - /* 1 */ { MAD_F(0x04000000) /* 0.250000000 */, 2 }, - /* 2 */ { MAD_F(0x050a28be) /* 0.314980262 */, 3 }, - /* 3 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 4 }, - /* 4 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 4 }, - /* 5 */ { MAD_F(0x04466275) /* 0.267183742 */, 5 }, - /* 6 */ { MAD_F(0x05738c72) /* 0.340710111 */, 5 }, - /* 7 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 5 }, - /* 8 */ { MAD_F(0x04000000) /* 0.250000000 */, 6 }, - /* 9 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 6 }, - /* 10 */ { MAD_F(0x0562d694) /* 0.336630420 */, 6 }, - /* 11 */ { MAD_F(0x061dae96) /* 0.382246578 */, 6 }, - /* 12 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 6 }, - /* 13 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 6 }, - /* 14 */ { MAD_F(0x0437be65) /* 0.263609310 */, 7 }, - /* 15 */ { MAD_F(0x049fc824) /* 0.289009227 */, 7 }, - - /* 16 */ { MAD_F(0x050a28be) /* 0.314980262 */, 7 }, - /* 17 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 7 }, - /* 18 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 7 }, - /* 19 */ { MAD_F(0x06566361) /* 0.396090870 */, 7 }, - /* 20 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 7 }, - /* 21 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 7 }, - /* 22 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 7 }, - /* 23 */ { MAD_F(0x04168b05) /* 0.255503674 */, 8 }, - /* 24 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 8 }, - /* 25 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 8 }, - /* 26 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 8 }, - /* 27 */ { MAD_F(0x05100000) /* 0.316406250 */, 8 }, - /* 28 */ { MAD_F(0x05506451) /* 0.332126919 */, 8 }, - /* 29 */ { MAD_F(0x05918e15) /* 0.348035890 */, 8 }, - /* 30 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 8 }, - /* 31 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 8 }, - - /* 32 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 8 }, - /* 33 */ { MAD_F(0x069d9400) /* 0.413471222 */, 8 }, - /* 34 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 8 }, - /* 35 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 8 }, - /* 36 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 8 }, - /* 37 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 8 }, - /* 38 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 8 }, - /* 39 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 9 }, - /* 40 */ { MAD_F(0x04466275) /* 0.267183742 */, 9 }, - /* 41 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 9 }, - /* 42 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 9 }, - /* 43 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 9 }, - /* 44 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 9 }, - /* 45 */ { MAD_F(0x05007b49) /* 0.312617576 */, 9 }, - /* 46 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 9 }, - /* 47 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 9 }, - - /* 48 */ { MAD_F(0x05738c72) /* 0.340710111 */, 9 }, - /* 49 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 9 }, - /* 50 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 9 }, - /* 51 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 9 }, - /* 52 */ { MAD_F(0x0610b982) /* 0.379083164 */, 9 }, - /* 53 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 9 }, - /* 54 */ { MAD_F(0x0660db91) /* 0.398646895 */, 9 }, - /* 55 */ { MAD_F(0x06894c90) /* 0.408520284 */, 9 }, - /* 56 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 9 }, - /* 57 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 9 }, - /* 58 */ { MAD_F(0x07041636) /* 0.438497744 */, 9 }, - /* 59 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 9 }, - /* 60 */ { MAD_F(0x075722ef) /* 0.458773552 */, 9 }, - /* 61 */ { MAD_F(0x078102b8) /* 0.468996735 */, 9 }, - /* 62 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 9 }, - /* 63 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 9 }, - - /* 64 */ { MAD_F(0x04000000) /* 0.250000000 */, 10 }, - /* 65 */ { MAD_F(0x04156381) /* 0.255221850 */, 10 }, - /* 66 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 10 }, - /* 67 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 10 }, - /* 68 */ { MAD_F(0x045635cf) /* 0.271047409 */, 10 }, - /* 69 */ { MAD_F(0x046c083e) /* 0.276375048 */, 10 }, - /* 70 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 10 }, - /* 71 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 10 }, - /* 72 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 10 }, - /* 73 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 10 }, - /* 74 */ { MAD_F(0x04dab524) /* 0.303395408 */, 10 }, - /* 75 */ { MAD_F(0x04f12624) /* 0.308874267 */, 10 }, - /* 76 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 10 }, - /* 77 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 10 }, - /* 78 */ { MAD_F(0x053511cb) /* 0.325456423 */, 10 }, - /* 79 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 10 }, - - /* 80 */ { MAD_F(0x0562d694) /* 0.336630420 */, 10 }, - /* 81 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 10 }, - /* 82 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 10 }, - /* 83 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 10 }, - /* 84 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 10 }, - /* 85 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 10 }, - /* 86 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 10 }, - /* 87 */ { MAD_F(0x0606012b) /* 0.376465960 */, 10 }, - /* 88 */ { MAD_F(0x061dae96) /* 0.382246578 */, 10 }, - /* 89 */ { MAD_F(0x06357302) /* 0.388049134 */, 10 }, - /* 90 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 10 }, - /* 91 */ { MAD_F(0x0665402d) /* 0.399719406 */, 10 }, - /* 92 */ { MAD_F(0x067d4896) /* 0.405586801 */, 10 }, - /* 93 */ { MAD_F(0x06956753) /* 0.411475493 */, 10 }, - /* 94 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 10 }, - /* 95 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 10 }, - - /* 96 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 10 }, - /* 97 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 10 }, - /* 98 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 10 }, - /* 99 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 10 }, - /* 100 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 10 }, - /* 101 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 10 }, - /* 102 */ { MAD_F(0x07724f64) /* 0.465407744 */, 10 }, - /* 103 */ { MAD_F(0x078b4514) /* 0.471501425 */, 10 }, - /* 104 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 10 }, - /* 105 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 10 }, - /* 106 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 10 }, - /* 107 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 10 }, - /* 108 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 11 }, - /* 109 */ { MAD_F(0x04115aca) /* 0.254236974 */, 11 }, - /* 110 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 11 }, - /* 111 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 11 }, - - /* 112 */ { MAD_F(0x0437be65) /* 0.263609310 */, 11 }, - /* 113 */ { MAD_F(0x04449dee) /* 0.266752177 */, 11 }, - /* 114 */ { MAD_F(0x04518733) /* 0.269904329 */, 11 }, - /* 115 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 11 }, - /* 116 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 11 }, - /* 117 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 11 }, - /* 118 */ { MAD_F(0x04858c83) /* 0.282604707 */, 11 }, - /* 119 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 11 }, - /* 120 */ { MAD_F(0x049fc824) /* 0.289009227 */, 11 }, - /* 121 */ { MAD_F(0x04acf402) /* 0.292224893 */, 11 }, - /* 122 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 11 }, - /* 123 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 11 }, - /* 124 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 11 }, - /* 125 */ { MAD_F(0x04e20000) /* 0.305175781 */, 11 }, - /* 126 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 11 }, - /* 127 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 11 }, - - /* 128 */ { MAD_F(0x050a28be) /* 0.314980262 */, 11 }, - /* 129 */ { MAD_F(0x05179da4) /* 0.318265572 */, 11 }, - /* 130 */ { MAD_F(0x05251b73) /* 0.321559381 */, 11 }, - /* 131 */ { MAD_F(0x0532a220) /* 0.324861647 */, 11 }, - /* 132 */ { MAD_F(0x054031a0) /* 0.328172327 */, 11 }, - /* 133 */ { MAD_F(0x054dc9e7) /* 0.331491377 */, 11 }, - /* 134 */ { MAD_F(0x055b6ae9) /* 0.334818756 */, 11 }, - /* 135 */ { MAD_F(0x0569149c) /* 0.338154423 */, 11 }, - /* 136 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 11 }, - /* 137 */ { MAD_F(0x058481e9) /* 0.344850455 */, 11 }, - /* 138 */ { MAD_F(0x0592456d) /* 0.348210741 */, 11 }, - /* 139 */ { MAD_F(0x05a01176) /* 0.351579152 */, 11 }, - /* 140 */ { MAD_F(0x05ade5fa) /* 0.354955651 */, 11 }, - /* 141 */ { MAD_F(0x05bbc2ef) /* 0.358340200 */, 11 }, - /* 142 */ { MAD_F(0x05c9a84a) /* 0.361732758 */, 11 }, - /* 143 */ { MAD_F(0x05d79601) /* 0.365133291 */, 11 }, - - /* 144 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 11 }, - /* 145 */ { MAD_F(0x05f38a5d) /* 0.371958126 */, 11 }, - /* 146 */ { MAD_F(0x060190ee) /* 0.375382356 */, 11 }, - /* 147 */ { MAD_F(0x060f9fb3) /* 0.378814413 */, 11 }, - /* 148 */ { MAD_F(0x061db6a5) /* 0.382254261 */, 11 }, - /* 149 */ { MAD_F(0x062bd5b8) /* 0.385701865 */, 11 }, - /* 150 */ { MAD_F(0x0639fce4) /* 0.389157191 */, 11 }, - /* 151 */ { MAD_F(0x06482c1f) /* 0.392620204 */, 11 }, - /* 152 */ { MAD_F(0x06566361) /* 0.396090870 */, 11 }, - /* 153 */ { MAD_F(0x0664a2a0) /* 0.399569155 */, 11 }, - /* 154 */ { MAD_F(0x0672e9d4) /* 0.403055027 */, 11 }, - /* 155 */ { MAD_F(0x068138f3) /* 0.406548452 */, 11 }, - /* 156 */ { MAD_F(0x068f8ff5) /* 0.410049398 */, 11 }, - /* 157 */ { MAD_F(0x069deed1) /* 0.413557833 */, 11 }, - /* 158 */ { MAD_F(0x06ac557f) /* 0.417073724 */, 11 }, - /* 159 */ { MAD_F(0x06bac3f6) /* 0.420597041 */, 11 }, - - /* 160 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 11 }, - /* 161 */ { MAD_F(0x06d7b81f) /* 0.427665827 */, 11 }, - /* 162 */ { MAD_F(0x06e63dc0) /* 0.431211234 */, 11 }, - /* 163 */ { MAD_F(0x06f4cb09) /* 0.434763944 */, 11 }, - /* 164 */ { MAD_F(0x07035ff3) /* 0.438323927 */, 11 }, - /* 165 */ { MAD_F(0x0711fc75) /* 0.441891153 */, 11 }, - /* 166 */ { MAD_F(0x0720a087) /* 0.445465593 */, 11 }, - /* 167 */ { MAD_F(0x072f4c22) /* 0.449047217 */, 11 }, - /* 168 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 11 }, - /* 169 */ { MAD_F(0x074cb9d3) /* 0.456231906 */, 11 }, - /* 170 */ { MAD_F(0x075b7bdb) /* 0.459834914 */, 11 }, - /* 171 */ { MAD_F(0x076a454c) /* 0.463444993 */, 11 }, - /* 172 */ { MAD_F(0x07791620) /* 0.467062117 */, 11 }, - /* 173 */ { MAD_F(0x0787ee50) /* 0.470686258 */, 11 }, - /* 174 */ { MAD_F(0x0796cdd4) /* 0.474317388 */, 11 }, - /* 175 */ { MAD_F(0x07a5b4a5) /* 0.477955481 */, 11 }, - - /* 176 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 11 }, - /* 177 */ { MAD_F(0x07c39812) /* 0.485252449 */, 11 }, - /* 178 */ { MAD_F(0x07d294a0) /* 0.488911273 */, 11 }, - /* 179 */ { MAD_F(0x07e1985f) /* 0.492576954 */, 11 }, - /* 180 */ { MAD_F(0x07f0a348) /* 0.496249468 */, 11 }, - /* 181 */ { MAD_F(0x07ffb554) /* 0.499928790 */, 11 }, - /* 182 */ { MAD_F(0x0407673f) /* 0.251807447 */, 12 }, - /* 183 */ { MAD_F(0x040ef75e) /* 0.253653877 */, 12 }, - /* 184 */ { MAD_F(0x04168b05) /* 0.255503674 */, 12 }, - /* 185 */ { MAD_F(0x041e2230) /* 0.257356825 */, 12 }, - /* 186 */ { MAD_F(0x0425bcdd) /* 0.259213318 */, 12 }, - /* 187 */ { MAD_F(0x042d5b07) /* 0.261073141 */, 12 }, - /* 188 */ { MAD_F(0x0434fcad) /* 0.262936282 */, 12 }, - /* 189 */ { MAD_F(0x043ca1c9) /* 0.264802730 */, 12 }, - /* 190 */ { MAD_F(0x04444a5a) /* 0.266672472 */, 12 }, - /* 191 */ { MAD_F(0x044bf65d) /* 0.268545497 */, 12 }, - - /* 192 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 12 }, - /* 193 */ { MAD_F(0x045b58a9) /* 0.272301352 */, 12 }, - /* 194 */ { MAD_F(0x04630eed) /* 0.274184158 */, 12 }, - /* 195 */ { MAD_F(0x046ac896) /* 0.276070203 */, 12 }, - /* 196 */ { MAD_F(0x047285a2) /* 0.277959474 */, 12 }, - /* 197 */ { MAD_F(0x047a460c) /* 0.279851960 */, 12 }, - /* 198 */ { MAD_F(0x048209d3) /* 0.281747652 */, 12 }, - /* 199 */ { MAD_F(0x0489d0f4) /* 0.283646538 */, 12 }, - /* 200 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 12 }, - /* 201 */ { MAD_F(0x04996935) /* 0.287453849 */, 12 }, - /* 202 */ { MAD_F(0x04a13a50) /* 0.289362253 */, 12 }, - /* 203 */ { MAD_F(0x04a90eba) /* 0.291273810 */, 12 }, - /* 204 */ { MAD_F(0x04b0e66e) /* 0.293188507 */, 12 }, - /* 205 */ { MAD_F(0x04b8c16c) /* 0.295106336 */, 12 }, - /* 206 */ { MAD_F(0x04c09faf) /* 0.297027285 */, 12 }, - /* 207 */ { MAD_F(0x04c88135) /* 0.298951346 */, 12 }, - - /* 208 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 12 }, - /* 209 */ { MAD_F(0x04d84dff) /* 0.302808759 */, 12 }, - /* 210 */ { MAD_F(0x04e0393e) /* 0.304742092 */, 12 }, - /* 211 */ { MAD_F(0x04e827b6) /* 0.306678497 */, 12 }, - /* 212 */ { MAD_F(0x04f01963) /* 0.308617963 */, 12 }, - /* 213 */ { MAD_F(0x04f80e44) /* 0.310560480 */, 12 }, - /* 214 */ { MAD_F(0x05000655) /* 0.312506041 */, 12 }, - /* 215 */ { MAD_F(0x05080195) /* 0.314454634 */, 12 }, - /* 216 */ { MAD_F(0x05100000) /* 0.316406250 */, 12 }, - /* 217 */ { MAD_F(0x05180194) /* 0.318360880 */, 12 }, - /* 218 */ { MAD_F(0x0520064f) /* 0.320318516 */, 12 }, - /* 219 */ { MAD_F(0x05280e2d) /* 0.322279147 */, 12 }, - /* 220 */ { MAD_F(0x0530192e) /* 0.324242764 */, 12 }, - /* 221 */ { MAD_F(0x0538274e) /* 0.326209359 */, 12 }, - /* 222 */ { MAD_F(0x0540388a) /* 0.328178922 */, 12 }, - /* 223 */ { MAD_F(0x05484ce2) /* 0.330151445 */, 12 }, - - /* 224 */ { MAD_F(0x05506451) /* 0.332126919 */, 12 }, - /* 225 */ { MAD_F(0x05587ed5) /* 0.334105334 */, 12 }, - /* 226 */ { MAD_F(0x05609c6e) /* 0.336086683 */, 12 }, - /* 227 */ { MAD_F(0x0568bd17) /* 0.338070956 */, 12 }, - /* 228 */ { MAD_F(0x0570e0cf) /* 0.340058145 */, 12 }, - /* 229 */ { MAD_F(0x05790793) /* 0.342048241 */, 12 }, - /* 230 */ { MAD_F(0x05813162) /* 0.344041237 */, 12 }, - /* 231 */ { MAD_F(0x05895e39) /* 0.346037122 */, 12 }, - /* 232 */ { MAD_F(0x05918e15) /* 0.348035890 */, 12 }, - /* 233 */ { MAD_F(0x0599c0f4) /* 0.350037532 */, 12 }, - /* 234 */ { MAD_F(0x05a1f6d5) /* 0.352042040 */, 12 }, - /* 235 */ { MAD_F(0x05aa2fb5) /* 0.354049405 */, 12 }, - /* 236 */ { MAD_F(0x05b26b92) /* 0.356059619 */, 12 }, - /* 237 */ { MAD_F(0x05baaa69) /* 0.358072674 */, 12 }, - /* 238 */ { MAD_F(0x05c2ec39) /* 0.360088563 */, 12 }, - /* 239 */ { MAD_F(0x05cb3100) /* 0.362107278 */, 12 }, - - /* 240 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 12 }, - /* 241 */ { MAD_F(0x05dbc368) /* 0.366153151 */, 12 }, - /* 242 */ { MAD_F(0x05e41105) /* 0.368180294 */, 12 }, - /* 243 */ { MAD_F(0x05ec6190) /* 0.370210231 */, 12 }, - /* 244 */ { MAD_F(0x05f4b507) /* 0.372242955 */, 12 }, - /* 245 */ { MAD_F(0x05fd0b68) /* 0.374278458 */, 12 }, - /* 246 */ { MAD_F(0x060564b1) /* 0.376316732 */, 12 }, - /* 247 */ { MAD_F(0x060dc0e0) /* 0.378357769 */, 12 }, - /* 248 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 12 }, - /* 249 */ { MAD_F(0x061e81e8) /* 0.382448106 */, 12 }, - /* 250 */ { MAD_F(0x0626e6bc) /* 0.384497391 */, 12 }, - /* 251 */ { MAD_F(0x062f4e6f) /* 0.386549409 */, 12 }, - /* 252 */ { MAD_F(0x0637b8fd) /* 0.388604155 */, 12 }, - /* 253 */ { MAD_F(0x06402666) /* 0.390661620 */, 12 }, - /* 254 */ { MAD_F(0x064896a7) /* 0.392721798 */, 12 }, - /* 255 */ { MAD_F(0x065109be) /* 0.394784681 */, 12 }, - - /* 256 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 12 }, - /* 257 */ { MAD_F(0x0661f867) /* 0.398918536 */, 12 }, - /* 258 */ { MAD_F(0x066a73f5) /* 0.400989493 */, 12 }, - /* 259 */ { MAD_F(0x0672f252) /* 0.403063128 */, 12 }, - /* 260 */ { MAD_F(0x067b737c) /* 0.405139433 */, 12 }, - /* 261 */ { MAD_F(0x0683f771) /* 0.407218402 */, 12 }, - /* 262 */ { MAD_F(0x068c7e2f) /* 0.409300027 */, 12 }, - /* 263 */ { MAD_F(0x069507b5) /* 0.411384303 */, 12 }, - /* 264 */ { MAD_F(0x069d9400) /* 0.413471222 */, 12 }, - /* 265 */ { MAD_F(0x06a6230f) /* 0.415560778 */, 12 }, - /* 266 */ { MAD_F(0x06aeb4e0) /* 0.417652964 */, 12 }, - /* 267 */ { MAD_F(0x06b74971) /* 0.419747773 */, 12 }, - /* 268 */ { MAD_F(0x06bfe0c0) /* 0.421845199 */, 12 }, - /* 269 */ { MAD_F(0x06c87acc) /* 0.423945235 */, 12 }, - /* 270 */ { MAD_F(0x06d11794) /* 0.426047876 */, 12 }, - /* 271 */ { MAD_F(0x06d9b714) /* 0.428153114 */, 12 }, - - /* 272 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 12 }, - /* 273 */ { MAD_F(0x06eafe3a) /* 0.432371356 */, 12 }, - /* 274 */ { MAD_F(0x06f3a5dc) /* 0.434484348 */, 12 }, - /* 275 */ { MAD_F(0x06fc5030) /* 0.436599912 */, 12 }, - /* 276 */ { MAD_F(0x0704fd35) /* 0.438718042 */, 12 }, - /* 277 */ { MAD_F(0x070dacea) /* 0.440838732 */, 12 }, - /* 278 */ { MAD_F(0x07165f4b) /* 0.442961975 */, 12 }, - /* 279 */ { MAD_F(0x071f1459) /* 0.445087765 */, 12 }, - /* 280 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 12 }, - /* 281 */ { MAD_F(0x07308671) /* 0.449346964 */, 12 }, - /* 282 */ { MAD_F(0x07394378) /* 0.451480360 */, 12 }, - /* 283 */ { MAD_F(0x07420325) /* 0.453616280 */, 12 }, - /* 284 */ { MAD_F(0x074ac575) /* 0.455754717 */, 12 }, - /* 285 */ { MAD_F(0x07538a67) /* 0.457895665 */, 12 }, - /* 286 */ { MAD_F(0x075c51fa) /* 0.460039119 */, 12 }, - /* 287 */ { MAD_F(0x07651c2c) /* 0.462185072 */, 12 }, - - /* 288 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 12 }, - /* 289 */ { MAD_F(0x0776b867) /* 0.466484455 */, 12 }, - /* 290 */ { MAD_F(0x077f8a6d) /* 0.468637872 */, 12 }, - /* 291 */ { MAD_F(0x07885f0b) /* 0.470793767 */, 12 }, - /* 292 */ { MAD_F(0x07913641) /* 0.472952132 */, 12 }, - /* 293 */ { MAD_F(0x079a100c) /* 0.475112962 */, 12 }, - /* 294 */ { MAD_F(0x07a2ec6c) /* 0.477276252 */, 12 }, - /* 295 */ { MAD_F(0x07abcb5f) /* 0.479441997 */, 12 }, - /* 296 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 12 }, - /* 297 */ { MAD_F(0x07bd90f6) /* 0.483780825 */, 12 }, - /* 298 */ { MAD_F(0x07c67798) /* 0.485953899 */, 12 }, - /* 299 */ { MAD_F(0x07cf60c7) /* 0.488129404 */, 12 }, - /* 300 */ { MAD_F(0x07d84c81) /* 0.490307336 */, 12 }, - /* 301 */ { MAD_F(0x07e13ac5) /* 0.492487690 */, 12 }, - /* 302 */ { MAD_F(0x07ea2b92) /* 0.494670459 */, 12 }, - /* 303 */ { MAD_F(0x07f31ee6) /* 0.496855639 */, 12 }, - - /* 304 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 12 }, - /* 305 */ { MAD_F(0x0402868e) /* 0.250616605 */, 13 }, - /* 306 */ { MAD_F(0x040703ff) /* 0.251712795 */, 13 }, - /* 307 */ { MAD_F(0x040b82b0) /* 0.252810180 */, 13 }, - /* 308 */ { MAD_F(0x041002a1) /* 0.253908756 */, 13 }, - /* 309 */ { MAD_F(0x041483d1) /* 0.255008523 */, 13 }, - /* 310 */ { MAD_F(0x04190640) /* 0.256109476 */, 13 }, - /* 311 */ { MAD_F(0x041d89ed) /* 0.257211614 */, 13 }, - /* 312 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 13 }, - /* 313 */ { MAD_F(0x042694fe) /* 0.259419433 */, 13 }, - /* 314 */ { MAD_F(0x042b1c60) /* 0.260525110 */, 13 }, - /* 315 */ { MAD_F(0x042fa4fe) /* 0.261631960 */, 13 }, - /* 316 */ { MAD_F(0x04342ed7) /* 0.262739982 */, 13 }, - /* 317 */ { MAD_F(0x0438b9e9) /* 0.263849174 */, 13 }, - /* 318 */ { MAD_F(0x043d4635) /* 0.264959533 */, 13 }, - /* 319 */ { MAD_F(0x0441d3b9) /* 0.266071056 */, 13 }, - - /* 320 */ { MAD_F(0x04466275) /* 0.267183742 */, 13 }, - /* 321 */ { MAD_F(0x044af269) /* 0.268297587 */, 13 }, - /* 322 */ { MAD_F(0x044f8393) /* 0.269412589 */, 13 }, - /* 323 */ { MAD_F(0x045415f3) /* 0.270528746 */, 13 }, - /* 324 */ { MAD_F(0x0458a989) /* 0.271646056 */, 13 }, - /* 325 */ { MAD_F(0x045d3e53) /* 0.272764515 */, 13 }, - /* 326 */ { MAD_F(0x0461d451) /* 0.273884123 */, 13 }, - /* 327 */ { MAD_F(0x04666b83) /* 0.275004875 */, 13 }, - /* 328 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 13 }, - /* 329 */ { MAD_F(0x046f9d7e) /* 0.277249808 */, 13 }, - /* 330 */ { MAD_F(0x04743847) /* 0.278373983 */, 13 }, - /* 331 */ { MAD_F(0x0478d440) /* 0.279499294 */, 13 }, - /* 332 */ { MAD_F(0x047d716a) /* 0.280625739 */, 13 }, - /* 333 */ { MAD_F(0x04820fc3) /* 0.281753315 */, 13 }, - /* 334 */ { MAD_F(0x0486af4c) /* 0.282882021 */, 13 }, - /* 335 */ { MAD_F(0x048b5003) /* 0.284011853 */, 13 }, - - /* 336 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 13 }, - /* 337 */ { MAD_F(0x049494fb) /* 0.286274891 */, 13 }, - /* 338 */ { MAD_F(0x0499393a) /* 0.287408091 */, 13 }, - /* 339 */ { MAD_F(0x049ddea5) /* 0.288542409 */, 13 }, - /* 340 */ { MAD_F(0x04a2853c) /* 0.289677844 */, 13 }, - /* 341 */ { MAD_F(0x04a72cfe) /* 0.290814392 */, 13 }, - /* 342 */ { MAD_F(0x04abd5ea) /* 0.291952051 */, 13 }, - /* 343 */ { MAD_F(0x04b08000) /* 0.293090820 */, 13 }, - /* 344 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 13 }, - /* 345 */ { MAD_F(0x04b9d7a7) /* 0.295371678 */, 13 }, - /* 346 */ { MAD_F(0x04be8537) /* 0.296513762 */, 13 }, - /* 347 */ { MAD_F(0x04c333ee) /* 0.297656947 */, 13 }, - /* 348 */ { MAD_F(0x04c7e3cc) /* 0.298801231 */, 13 }, - /* 349 */ { MAD_F(0x04cc94d1) /* 0.299946611 */, 13 }, - /* 350 */ { MAD_F(0x04d146fb) /* 0.301093085 */, 13 }, - /* 351 */ { MAD_F(0x04d5fa4b) /* 0.302240653 */, 13 }, - - /* 352 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 13 }, - /* 353 */ { MAD_F(0x04df6458) /* 0.304539056 */, 13 }, - /* 354 */ { MAD_F(0x04e41b14) /* 0.305689888 */, 13 }, - /* 355 */ { MAD_F(0x04e8d2f3) /* 0.306841804 */, 13 }, - /* 356 */ { MAD_F(0x04ed8bf5) /* 0.307994802 */, 13 }, - /* 357 */ { MAD_F(0x04f24618) /* 0.309148880 */, 13 }, - /* 358 */ { MAD_F(0x04f7015d) /* 0.310304037 */, 13 }, - /* 359 */ { MAD_F(0x04fbbdc3) /* 0.311460269 */, 13 }, - /* 360 */ { MAD_F(0x05007b49) /* 0.312617576 */, 13 }, - /* 361 */ { MAD_F(0x050539ef) /* 0.313775954 */, 13 }, - /* 362 */ { MAD_F(0x0509f9b4) /* 0.314935403 */, 13 }, - /* 363 */ { MAD_F(0x050eba98) /* 0.316095920 */, 13 }, - /* 364 */ { MAD_F(0x05137c9a) /* 0.317257503 */, 13 }, - /* 365 */ { MAD_F(0x05183fba) /* 0.318420150 */, 13 }, - /* 366 */ { MAD_F(0x051d03f7) /* 0.319583859 */, 13 }, - /* 367 */ { MAD_F(0x0521c950) /* 0.320748629 */, 13 }, - - /* 368 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 13 }, - /* 369 */ { MAD_F(0x052b5757) /* 0.323081342 */, 13 }, - /* 370 */ { MAD_F(0x05302003) /* 0.324249281 */, 13 }, - /* 371 */ { MAD_F(0x0534e9ca) /* 0.325418273 */, 13 }, - /* 372 */ { MAD_F(0x0539b4ab) /* 0.326588316 */, 13 }, - /* 373 */ { MAD_F(0x053e80a6) /* 0.327759407 */, 13 }, - /* 374 */ { MAD_F(0x05434db9) /* 0.328931546 */, 13 }, - /* 375 */ { MAD_F(0x05481be5) /* 0.330104730 */, 13 }, - /* 376 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 13 }, - /* 377 */ { MAD_F(0x0551bb85) /* 0.332454225 */, 13 }, - /* 378 */ { MAD_F(0x05568cf8) /* 0.333630533 */, 13 }, - /* 379 */ { MAD_F(0x055b5f81) /* 0.334807879 */, 13 }, - /* 380 */ { MAD_F(0x05603321) /* 0.335986261 */, 13 }, - /* 381 */ { MAD_F(0x056507d6) /* 0.337165677 */, 13 }, - /* 382 */ { MAD_F(0x0569dda0) /* 0.338346125 */, 13 }, - /* 383 */ { MAD_F(0x056eb47f) /* 0.339527604 */, 13 }, - - /* 384 */ { MAD_F(0x05738c72) /* 0.340710111 */, 13 }, - /* 385 */ { MAD_F(0x05786578) /* 0.341893646 */, 13 }, - /* 386 */ { MAD_F(0x057d3f92) /* 0.343078205 */, 13 }, - /* 387 */ { MAD_F(0x05821abf) /* 0.344263788 */, 13 }, - /* 388 */ { MAD_F(0x0586f6fd) /* 0.345450393 */, 13 }, - /* 389 */ { MAD_F(0x058bd44e) /* 0.346638017 */, 13 }, - /* 390 */ { MAD_F(0x0590b2b0) /* 0.347826659 */, 13 }, - /* 391 */ { MAD_F(0x05959222) /* 0.349016318 */, 13 }, - /* 392 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 13 }, - /* 393 */ { MAD_F(0x059f5438) /* 0.351398678 */, 13 }, - /* 394 */ { MAD_F(0x05a436da) /* 0.352591376 */, 13 }, - /* 395 */ { MAD_F(0x05a91a8c) /* 0.353785083 */, 13 }, - /* 396 */ { MAD_F(0x05adff4c) /* 0.354979798 */, 13 }, - /* 397 */ { MAD_F(0x05b2e51a) /* 0.356175519 */, 13 }, - /* 398 */ { MAD_F(0x05b7cbf5) /* 0.357372244 */, 13 }, - /* 399 */ { MAD_F(0x05bcb3de) /* 0.358569972 */, 13 }, - - /* 400 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 13 }, - /* 401 */ { MAD_F(0x05c686d5) /* 0.360968429 */, 13 }, - /* 402 */ { MAD_F(0x05cb71e2) /* 0.362169156 */, 13 }, - /* 403 */ { MAD_F(0x05d05dfb) /* 0.363370878 */, 13 }, - /* 404 */ { MAD_F(0x05d54b1f) /* 0.364573594 */, 13 }, - /* 405 */ { MAD_F(0x05da394d) /* 0.365777304 */, 13 }, - /* 406 */ { MAD_F(0x05df2885) /* 0.366982004 */, 13 }, - /* 407 */ { MAD_F(0x05e418c7) /* 0.368187694 */, 13 }, - /* 408 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 13 }, - /* 409 */ { MAD_F(0x05edfc66) /* 0.370602036 */, 13 }, - /* 410 */ { MAD_F(0x05f2efc2) /* 0.371810684 */, 13 }, - /* 411 */ { MAD_F(0x05f7e426) /* 0.373020316 */, 13 }, - /* 412 */ { MAD_F(0x05fcd992) /* 0.374230929 */, 13 }, - /* 413 */ { MAD_F(0x0601d004) /* 0.375442522 */, 13 }, - /* 414 */ { MAD_F(0x0606c77d) /* 0.376655093 */, 13 }, - /* 415 */ { MAD_F(0x060bbffd) /* 0.377868641 */, 13 }, - - /* 416 */ { MAD_F(0x0610b982) /* 0.379083164 */, 13 }, - /* 417 */ { MAD_F(0x0615b40c) /* 0.380298661 */, 13 }, - /* 418 */ { MAD_F(0x061aaf9c) /* 0.381515130 */, 13 }, - /* 419 */ { MAD_F(0x061fac2f) /* 0.382732569 */, 13 }, - /* 420 */ { MAD_F(0x0624a9c7) /* 0.383950977 */, 13 }, - /* 421 */ { MAD_F(0x0629a863) /* 0.385170352 */, 13 }, - /* 422 */ { MAD_F(0x062ea802) /* 0.386390694 */, 13 }, - /* 423 */ { MAD_F(0x0633a8a3) /* 0.387611999 */, 13 }, - /* 424 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 13 }, - /* 425 */ { MAD_F(0x063dacee) /* 0.390057497 */, 13 }, - /* 426 */ { MAD_F(0x0642b096) /* 0.391281687 */, 13 }, - /* 427 */ { MAD_F(0x0647b53f) /* 0.392506834 */, 13 }, - /* 428 */ { MAD_F(0x064cbae9) /* 0.393732939 */, 13 }, - /* 429 */ { MAD_F(0x0651c193) /* 0.394959999 */, 13 }, - /* 430 */ { MAD_F(0x0656c93d) /* 0.396188012 */, 13 }, - /* 431 */ { MAD_F(0x065bd1e7) /* 0.397416978 */, 13 }, - - /* 432 */ { MAD_F(0x0660db91) /* 0.398646895 */, 13 }, - /* 433 */ { MAD_F(0x0665e639) /* 0.399877761 */, 13 }, - /* 434 */ { MAD_F(0x066af1df) /* 0.401109575 */, 13 }, - /* 435 */ { MAD_F(0x066ffe84) /* 0.402342335 */, 13 }, - /* 436 */ { MAD_F(0x06750c26) /* 0.403576041 */, 13 }, - /* 437 */ { MAD_F(0x067a1ac6) /* 0.404810690 */, 13 }, - /* 438 */ { MAD_F(0x067f2a62) /* 0.406046281 */, 13 }, - /* 439 */ { MAD_F(0x06843afb) /* 0.407282813 */, 13 }, - /* 440 */ { MAD_F(0x06894c90) /* 0.408520284 */, 13 }, - /* 441 */ { MAD_F(0x068e5f21) /* 0.409758693 */, 13 }, - /* 442 */ { MAD_F(0x069372ae) /* 0.410998038 */, 13 }, - /* 443 */ { MAD_F(0x06988735) /* 0.412238319 */, 13 }, - /* 444 */ { MAD_F(0x069d9cb7) /* 0.413479532 */, 13 }, - /* 445 */ { MAD_F(0x06a2b333) /* 0.414721679 */, 13 }, - /* 446 */ { MAD_F(0x06a7caa9) /* 0.415964756 */, 13 }, - /* 447 */ { MAD_F(0x06ace318) /* 0.417208762 */, 13 }, - - /* 448 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 13 }, - /* 449 */ { MAD_F(0x06b716e2) /* 0.419699557 */, 13 }, - /* 450 */ { MAD_F(0x06bc323b) /* 0.420946343 */, 13 }, - /* 451 */ { MAD_F(0x06c14e8d) /* 0.422194054 */, 13 }, - /* 452 */ { MAD_F(0x06c66bd6) /* 0.423442686 */, 13 }, - /* 453 */ { MAD_F(0x06cb8a17) /* 0.424692240 */, 13 }, - /* 454 */ { MAD_F(0x06d0a94e) /* 0.425942714 */, 13 }, - /* 455 */ { MAD_F(0x06d5c97c) /* 0.427194106 */, 13 }, - /* 456 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 13 }, - /* 457 */ { MAD_F(0x06e00cbb) /* 0.429699640 */, 13 }, - /* 458 */ { MAD_F(0x06e52fca) /* 0.430953779 */, 13 }, - /* 459 */ { MAD_F(0x06ea53cf) /* 0.432208832 */, 13 }, - /* 460 */ { MAD_F(0x06ef78c8) /* 0.433464796 */, 13 }, - /* 461 */ { MAD_F(0x06f49eb6) /* 0.434721671 */, 13 }, - /* 462 */ { MAD_F(0x06f9c597) /* 0.435979455 */, 13 }, - /* 463 */ { MAD_F(0x06feed6d) /* 0.437238146 */, 13 }, - - /* 464 */ { MAD_F(0x07041636) /* 0.438497744 */, 13 }, - /* 465 */ { MAD_F(0x07093ff2) /* 0.439758248 */, 13 }, - /* 466 */ { MAD_F(0x070e6aa0) /* 0.441019655 */, 13 }, - /* 467 */ { MAD_F(0x07139641) /* 0.442281965 */, 13 }, - /* 468 */ { MAD_F(0x0718c2d3) /* 0.443545176 */, 13 }, - /* 469 */ { MAD_F(0x071df058) /* 0.444809288 */, 13 }, - /* 470 */ { MAD_F(0x07231ecd) /* 0.446074298 */, 13 }, - /* 471 */ { MAD_F(0x07284e34) /* 0.447340205 */, 13 }, - /* 472 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 13 }, - /* 473 */ { MAD_F(0x0732afd2) /* 0.449874708 */, 13 }, - /* 474 */ { MAD_F(0x0737e209) /* 0.451143300 */, 13 }, - /* 475 */ { MAD_F(0x073d1530) /* 0.452412785 */, 13 }, - /* 476 */ { MAD_F(0x07424946) /* 0.453683161 */, 13 }, - /* 477 */ { MAD_F(0x07477e4b) /* 0.454954427 */, 13 }, - /* 478 */ { MAD_F(0x074cb43e) /* 0.456226581 */, 13 }, - /* 479 */ { MAD_F(0x0751eb20) /* 0.457499623 */, 13 }, - - /* 480 */ { MAD_F(0x075722ef) /* 0.458773552 */, 13 }, - /* 481 */ { MAD_F(0x075c5bac) /* 0.460048365 */, 13 }, - /* 482 */ { MAD_F(0x07619557) /* 0.461324062 */, 13 }, - /* 483 */ { MAD_F(0x0766cfee) /* 0.462600642 */, 13 }, - /* 484 */ { MAD_F(0x076c0b72) /* 0.463878102 */, 13 }, - /* 485 */ { MAD_F(0x077147e2) /* 0.465156443 */, 13 }, - /* 486 */ { MAD_F(0x0776853e) /* 0.466435663 */, 13 }, - /* 487 */ { MAD_F(0x077bc385) /* 0.467715761 */, 13 }, - /* 488 */ { MAD_F(0x078102b8) /* 0.468996735 */, 13 }, - /* 489 */ { MAD_F(0x078642d6) /* 0.470278584 */, 13 }, - /* 490 */ { MAD_F(0x078b83de) /* 0.471561307 */, 13 }, - /* 491 */ { MAD_F(0x0790c5d1) /* 0.472844904 */, 13 }, - /* 492 */ { MAD_F(0x079608ae) /* 0.474129372 */, 13 }, - /* 493 */ { MAD_F(0x079b4c74) /* 0.475414710 */, 13 }, - /* 494 */ { MAD_F(0x07a09124) /* 0.476700918 */, 13 }, - /* 495 */ { MAD_F(0x07a5d6bd) /* 0.477987994 */, 13 }, - - /* 496 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 13 }, - /* 497 */ { MAD_F(0x07b064a8) /* 0.480564746 */, 13 }, - /* 498 */ { MAD_F(0x07b5acfb) /* 0.481854420 */, 13 }, - /* 499 */ { MAD_F(0x07baf635) /* 0.483144957 */, 13 }, - /* 500 */ { MAD_F(0x07c04056) /* 0.484436356 */, 13 }, - /* 501 */ { MAD_F(0x07c58b5f) /* 0.485728617 */, 13 }, - /* 502 */ { MAD_F(0x07cad74e) /* 0.487021738 */, 13 }, - /* 503 */ { MAD_F(0x07d02424) /* 0.488315717 */, 13 }, - /* 504 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 13 }, - /* 505 */ { MAD_F(0x07dac083) /* 0.490906249 */, 13 }, - /* 506 */ { MAD_F(0x07e0100a) /* 0.492202799 */, 13 }, - /* 507 */ { MAD_F(0x07e56078) /* 0.493500203 */, 13 }, - /* 508 */ { MAD_F(0x07eab1ca) /* 0.494798460 */, 13 }, - /* 509 */ { MAD_F(0x07f00401) /* 0.496097570 */, 13 }, - /* 510 */ { MAD_F(0x07f5571d) /* 0.497397530 */, 13 }, - /* 511 */ { MAD_F(0x07faab1c) /* 0.498698341 */, 13 }, - - /* 512 */ { MAD_F(0x04000000) /* 0.250000000 */, 14 }, - /* 513 */ { MAD_F(0x0402aae3) /* 0.250651254 */, 14 }, - /* 514 */ { MAD_F(0x04055638) /* 0.251302930 */, 14 }, - /* 515 */ { MAD_F(0x040801ff) /* 0.251955030 */, 14 }, - /* 516 */ { MAD_F(0x040aae37) /* 0.252607552 */, 14 }, - /* 517 */ { MAD_F(0x040d5ae0) /* 0.253260495 */, 14 }, - /* 518 */ { MAD_F(0x041007fa) /* 0.253913860 */, 14 }, - /* 519 */ { MAD_F(0x0412b586) /* 0.254567645 */, 14 }, - /* 520 */ { MAD_F(0x04156381) /* 0.255221850 */, 14 }, - /* 521 */ { MAD_F(0x041811ee) /* 0.255876475 */, 14 }, - /* 522 */ { MAD_F(0x041ac0cb) /* 0.256531518 */, 14 }, - /* 523 */ { MAD_F(0x041d7018) /* 0.257186980 */, 14 }, - /* 524 */ { MAD_F(0x04201fd5) /* 0.257842860 */, 14 }, - /* 525 */ { MAD_F(0x0422d003) /* 0.258499157 */, 14 }, - /* 526 */ { MAD_F(0x042580a0) /* 0.259155872 */, 14 }, - /* 527 */ { MAD_F(0x042831ad) /* 0.259813002 */, 14 }, - - /* 528 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 14 }, - /* 529 */ { MAD_F(0x042d9516) /* 0.261128510 */, 14 }, - /* 530 */ { MAD_F(0x04304772) /* 0.261786886 */, 14 }, - /* 531 */ { MAD_F(0x0432fa3d) /* 0.262445676 */, 14 }, - /* 532 */ { MAD_F(0x0435ad76) /* 0.263104880 */, 14 }, - /* 533 */ { MAD_F(0x0438611f) /* 0.263764497 */, 14 }, - /* 534 */ { MAD_F(0x043b1536) /* 0.264424527 */, 14 }, - /* 535 */ { MAD_F(0x043dc9bc) /* 0.265084969 */, 14 }, - /* 536 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 14 }, - /* 537 */ { MAD_F(0x04433414) /* 0.266407088 */, 14 }, - /* 538 */ { MAD_F(0x0445e9e5) /* 0.267068763 */, 14 }, - /* 539 */ { MAD_F(0x0448a024) /* 0.267730848 */, 14 }, - /* 540 */ { MAD_F(0x044b56d1) /* 0.268393343 */, 14 }, - /* 541 */ { MAD_F(0x044e0dec) /* 0.269056248 */, 14 }, - /* 542 */ { MAD_F(0x0450c575) /* 0.269719560 */, 14 }, - /* 543 */ { MAD_F(0x04537d6b) /* 0.270383281 */, 14 }, - - /* 544 */ { MAD_F(0x045635cf) /* 0.271047409 */, 14 }, - /* 545 */ { MAD_F(0x0458ee9f) /* 0.271711944 */, 14 }, - /* 546 */ { MAD_F(0x045ba7dd) /* 0.272376886 */, 14 }, - /* 547 */ { MAD_F(0x045e6188) /* 0.273042234 */, 14 }, - /* 548 */ { MAD_F(0x04611ba0) /* 0.273707988 */, 14 }, - /* 549 */ { MAD_F(0x0463d625) /* 0.274374147 */, 14 }, - /* 550 */ { MAD_F(0x04669116) /* 0.275040710 */, 14 }, - /* 551 */ { MAD_F(0x04694c74) /* 0.275707677 */, 14 }, - /* 552 */ { MAD_F(0x046c083e) /* 0.276375048 */, 14 }, - /* 553 */ { MAD_F(0x046ec474) /* 0.277042822 */, 14 }, - /* 554 */ { MAD_F(0x04718116) /* 0.277710999 */, 14 }, - /* 555 */ { MAD_F(0x04743e25) /* 0.278379578 */, 14 }, - /* 556 */ { MAD_F(0x0476fb9f) /* 0.279048558 */, 14 }, - /* 557 */ { MAD_F(0x0479b984) /* 0.279717940 */, 14 }, - /* 558 */ { MAD_F(0x047c77d6) /* 0.280387722 */, 14 }, - /* 559 */ { MAD_F(0x047f3693) /* 0.281057905 */, 14 }, - - /* 560 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 14 }, - /* 561 */ { MAD_F(0x0484b54e) /* 0.282399469 */, 14 }, - /* 562 */ { MAD_F(0x0487754c) /* 0.283070849 */, 14 }, - /* 563 */ { MAD_F(0x048a35b6) /* 0.283742628 */, 14 }, - /* 564 */ { MAD_F(0x048cf68a) /* 0.284414805 */, 14 }, - /* 565 */ { MAD_F(0x048fb7c8) /* 0.285087379 */, 14 }, - /* 566 */ { MAD_F(0x04927972) /* 0.285760350 */, 14 }, - /* 567 */ { MAD_F(0x04953b85) /* 0.286433717 */, 14 }, - /* 568 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 14 }, - /* 569 */ { MAD_F(0x049ac0eb) /* 0.287781640 */, 14 }, - /* 570 */ { MAD_F(0x049d843e) /* 0.288456194 */, 14 }, - /* 571 */ { MAD_F(0x04a047fa) /* 0.289131142 */, 14 }, - /* 572 */ { MAD_F(0x04a30c20) /* 0.289806485 */, 14 }, - /* 573 */ { MAD_F(0x04a5d0af) /* 0.290482221 */, 14 }, - /* 574 */ { MAD_F(0x04a895a8) /* 0.291158351 */, 14 }, - /* 575 */ { MAD_F(0x04ab5b0b) /* 0.291834873 */, 14 }, - - /* 576 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 14 }, - /* 577 */ { MAD_F(0x04b0e70c) /* 0.293189094 */, 14 }, - /* 578 */ { MAD_F(0x04b3adaa) /* 0.293866792 */, 14 }, - /* 579 */ { MAD_F(0x04b674b1) /* 0.294544881 */, 14 }, - /* 580 */ { MAD_F(0x04b93c21) /* 0.295223360 */, 14 }, - /* 581 */ { MAD_F(0x04bc03fa) /* 0.295902229 */, 14 }, - /* 582 */ { MAD_F(0x04becc3b) /* 0.296581488 */, 14 }, - /* 583 */ { MAD_F(0x04c194e4) /* 0.297261136 */, 14 }, - /* 584 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 14 }, - /* 585 */ { MAD_F(0x04c72771) /* 0.298621598 */, 14 }, - /* 586 */ { MAD_F(0x04c9f153) /* 0.299302411 */, 14 }, - /* 587 */ { MAD_F(0x04ccbb9d) /* 0.299983611 */, 14 }, - /* 588 */ { MAD_F(0x04cf864f) /* 0.300665198 */, 14 }, - /* 589 */ { MAD_F(0x04d25169) /* 0.301347172 */, 14 }, - /* 590 */ { MAD_F(0x04d51ceb) /* 0.302029532 */, 14 }, - /* 591 */ { MAD_F(0x04d7e8d4) /* 0.302712277 */, 14 }, - - /* 592 */ { MAD_F(0x04dab524) /* 0.303395408 */, 14 }, - /* 593 */ { MAD_F(0x04dd81dc) /* 0.304078923 */, 14 }, - /* 594 */ { MAD_F(0x04e04efb) /* 0.304762823 */, 14 }, - /* 595 */ { MAD_F(0x04e31c81) /* 0.305447106 */, 14 }, - /* 596 */ { MAD_F(0x04e5ea6e) /* 0.306131773 */, 14 }, - /* 597 */ { MAD_F(0x04e8b8c2) /* 0.306816823 */, 14 }, - /* 598 */ { MAD_F(0x04eb877c) /* 0.307502256 */, 14 }, - /* 599 */ { MAD_F(0x04ee569d) /* 0.308188071 */, 14 }, - /* 600 */ { MAD_F(0x04f12624) /* 0.308874267 */, 14 }, - /* 601 */ { MAD_F(0x04f3f612) /* 0.309560845 */, 14 }, - /* 602 */ { MAD_F(0x04f6c666) /* 0.310247804 */, 14 }, - /* 603 */ { MAD_F(0x04f99721) /* 0.310935143 */, 14 }, - /* 604 */ { MAD_F(0x04fc6841) /* 0.311622862 */, 14 }, - /* 605 */ { MAD_F(0x04ff39c7) /* 0.312310961 */, 14 }, - /* 606 */ { MAD_F(0x05020bb3) /* 0.312999439 */, 14 }, - /* 607 */ { MAD_F(0x0504de05) /* 0.313688296 */, 14 }, - - /* 608 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 14 }, - /* 609 */ { MAD_F(0x050a83d8) /* 0.315067145 */, 14 }, - /* 610 */ { MAD_F(0x050d575b) /* 0.315757136 */, 14 }, - /* 611 */ { MAD_F(0x05102b42) /* 0.316447504 */, 14 }, - /* 612 */ { MAD_F(0x0512ff8e) /* 0.317138249 */, 14 }, - /* 613 */ { MAD_F(0x0515d440) /* 0.317829370 */, 14 }, - /* 614 */ { MAD_F(0x0518a956) /* 0.318520867 */, 14 }, - /* 615 */ { MAD_F(0x051b7ed1) /* 0.319212739 */, 14 }, - /* 616 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 14 }, - /* 617 */ { MAD_F(0x05212af5) /* 0.320597609 */, 14 }, - /* 618 */ { MAD_F(0x0524019e) /* 0.321290606 */, 14 }, - /* 619 */ { MAD_F(0x0526d8ab) /* 0.321983976 */, 14 }, - /* 620 */ { MAD_F(0x0529b01d) /* 0.322677720 */, 14 }, - /* 621 */ { MAD_F(0x052c87f2) /* 0.323371837 */, 14 }, - /* 622 */ { MAD_F(0x052f602c) /* 0.324066327 */, 14 }, - /* 623 */ { MAD_F(0x053238ca) /* 0.324761189 */, 14 }, - - /* 624 */ { MAD_F(0x053511cb) /* 0.325456423 */, 14 }, - /* 625 */ { MAD_F(0x0537eb30) /* 0.326152028 */, 14 }, - /* 626 */ { MAD_F(0x053ac4f9) /* 0.326848005 */, 14 }, - /* 627 */ { MAD_F(0x053d9f25) /* 0.327544352 */, 14 }, - /* 628 */ { MAD_F(0x054079b5) /* 0.328241070 */, 14 }, - /* 629 */ { MAD_F(0x054354a8) /* 0.328938157 */, 14 }, - /* 630 */ { MAD_F(0x05462ffe) /* 0.329635614 */, 14 }, - /* 631 */ { MAD_F(0x05490bb7) /* 0.330333440 */, 14 }, - /* 632 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 14 }, - /* 633 */ { MAD_F(0x054ec453) /* 0.331730198 */, 14 }, - /* 634 */ { MAD_F(0x0551a134) /* 0.332429129 */, 14 }, - /* 635 */ { MAD_F(0x05547e79) /* 0.333128427 */, 14 }, - /* 636 */ { MAD_F(0x05575c20) /* 0.333828093 */, 14 }, - /* 637 */ { MAD_F(0x055a3a2a) /* 0.334528126 */, 14 }, - /* 638 */ { MAD_F(0x055d1896) /* 0.335228525 */, 14 }, - /* 639 */ { MAD_F(0x055ff764) /* 0.335929290 */, 14 }, - - /* 640 */ { MAD_F(0x0562d694) /* 0.336630420 */, 14 }, - /* 641 */ { MAD_F(0x0565b627) /* 0.337331916 */, 14 }, - /* 642 */ { MAD_F(0x0568961b) /* 0.338033777 */, 14 }, - /* 643 */ { MAD_F(0x056b7671) /* 0.338736002 */, 14 }, - /* 644 */ { MAD_F(0x056e5729) /* 0.339438592 */, 14 }, - /* 645 */ { MAD_F(0x05713843) /* 0.340141545 */, 14 }, - /* 646 */ { MAD_F(0x057419be) /* 0.340844862 */, 14 }, - /* 647 */ { MAD_F(0x0576fb9a) /* 0.341548541 */, 14 }, - /* 648 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 14 }, - /* 649 */ { MAD_F(0x057cc077) /* 0.342956988 */, 14 }, - /* 650 */ { MAD_F(0x057fa378) /* 0.343661754 */, 14 }, - /* 651 */ { MAD_F(0x058286d9) /* 0.344366882 */, 14 }, - /* 652 */ { MAD_F(0x05856a9b) /* 0.345072371 */, 14 }, - /* 653 */ { MAD_F(0x05884ebe) /* 0.345778221 */, 14 }, - /* 654 */ { MAD_F(0x058b3342) /* 0.346484431 */, 14 }, - /* 655 */ { MAD_F(0x058e1827) /* 0.347191002 */, 14 }, - - /* 656 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 14 }, - /* 657 */ { MAD_F(0x0593e311) /* 0.348605221 */, 14 }, - /* 658 */ { MAD_F(0x0596c917) /* 0.349312869 */, 14 }, - /* 659 */ { MAD_F(0x0599af7d) /* 0.350020876 */, 14 }, - /* 660 */ { MAD_F(0x059c9643) /* 0.350729240 */, 14 }, - /* 661 */ { MAD_F(0x059f7d6a) /* 0.351437963 */, 14 }, - /* 662 */ { MAD_F(0x05a264f0) /* 0.352147044 */, 14 }, - /* 663 */ { MAD_F(0x05a54cd6) /* 0.352856481 */, 14 }, - /* 664 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 14 }, - /* 665 */ { MAD_F(0x05ab1dc2) /* 0.354276426 */, 14 }, - /* 666 */ { MAD_F(0x05ae06c7) /* 0.354986932 */, 14 }, - /* 667 */ { MAD_F(0x05b0f02b) /* 0.355697795 */, 14 }, - /* 668 */ { MAD_F(0x05b3d9f0) /* 0.356409012 */, 14 }, - /* 669 */ { MAD_F(0x05b6c413) /* 0.357120585 */, 14 }, - /* 670 */ { MAD_F(0x05b9ae95) /* 0.357832512 */, 14 }, - /* 671 */ { MAD_F(0x05bc9977) /* 0.358544794 */, 14 }, - - /* 672 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 14 }, - /* 673 */ { MAD_F(0x05c27057) /* 0.359970419 */, 14 }, - /* 674 */ { MAD_F(0x05c55c56) /* 0.360683761 */, 14 }, - /* 675 */ { MAD_F(0x05c848b3) /* 0.361397456 */, 14 }, - /* 676 */ { MAD_F(0x05cb356e) /* 0.362111504 */, 14 }, - /* 677 */ { MAD_F(0x05ce2289) /* 0.362825904 */, 14 }, - /* 678 */ { MAD_F(0x05d11001) /* 0.363540655 */, 14 }, - /* 679 */ { MAD_F(0x05d3fdd8) /* 0.364255759 */, 14 }, - /* 680 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 14 }, - /* 681 */ { MAD_F(0x05d9daa1) /* 0.365687018 */, 14 }, - /* 682 */ { MAD_F(0x05dcc993) /* 0.366403174 */, 14 }, - /* 683 */ { MAD_F(0x05dfb8e2) /* 0.367119680 */, 14 }, - /* 684 */ { MAD_F(0x05e2a890) /* 0.367836535 */, 14 }, - /* 685 */ { MAD_F(0x05e5989b) /* 0.368553740 */, 14 }, - /* 686 */ { MAD_F(0x05e88904) /* 0.369271294 */, 14 }, - /* 687 */ { MAD_F(0x05eb79cb) /* 0.369989197 */, 14 }, - - /* 688 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 14 }, - /* 689 */ { MAD_F(0x05f15c70) /* 0.371426047 */, 14 }, - /* 690 */ { MAD_F(0x05f44e4f) /* 0.372144994 */, 14 }, - /* 691 */ { MAD_F(0x05f7408b) /* 0.372864289 */, 14 }, - /* 692 */ { MAD_F(0x05fa3324) /* 0.373583930 */, 14 }, - /* 693 */ { MAD_F(0x05fd261b) /* 0.374303918 */, 14 }, - /* 694 */ { MAD_F(0x0600196e) /* 0.375024253 */, 14 }, - /* 695 */ { MAD_F(0x06030d1e) /* 0.375744934 */, 14 }, - /* 696 */ { MAD_F(0x0606012b) /* 0.376465960 */, 14 }, - /* 697 */ { MAD_F(0x0608f595) /* 0.377187332 */, 14 }, - /* 698 */ { MAD_F(0x060bea5c) /* 0.377909049 */, 14 }, - /* 699 */ { MAD_F(0x060edf7f) /* 0.378631110 */, 14 }, - /* 700 */ { MAD_F(0x0611d4fe) /* 0.379353516 */, 14 }, - /* 701 */ { MAD_F(0x0614cada) /* 0.380076266 */, 14 }, - /* 702 */ { MAD_F(0x0617c112) /* 0.380799360 */, 14 }, - /* 703 */ { MAD_F(0x061ab7a6) /* 0.381522798 */, 14 }, - - /* 704 */ { MAD_F(0x061dae96) /* 0.382246578 */, 14 }, - /* 705 */ { MAD_F(0x0620a5e3) /* 0.382970701 */, 14 }, - /* 706 */ { MAD_F(0x06239d8b) /* 0.383695167 */, 14 }, - /* 707 */ { MAD_F(0x0626958f) /* 0.384419975 */, 14 }, - /* 708 */ { MAD_F(0x06298def) /* 0.385145124 */, 14 }, - /* 709 */ { MAD_F(0x062c86aa) /* 0.385870615 */, 14 }, - /* 710 */ { MAD_F(0x062f7fc1) /* 0.386596448 */, 14 }, - /* 711 */ { MAD_F(0x06327934) /* 0.387322621 */, 14 }, - /* 712 */ { MAD_F(0x06357302) /* 0.388049134 */, 14 }, - /* 713 */ { MAD_F(0x06386d2b) /* 0.388775988 */, 14 }, - /* 714 */ { MAD_F(0x063b67b0) /* 0.389503182 */, 14 }, - /* 715 */ { MAD_F(0x063e6290) /* 0.390230715 */, 14 }, - /* 716 */ { MAD_F(0x06415dcb) /* 0.390958588 */, 14 }, - /* 717 */ { MAD_F(0x06445960) /* 0.391686799 */, 14 }, - /* 718 */ { MAD_F(0x06475551) /* 0.392415349 */, 14 }, - /* 719 */ { MAD_F(0x064a519c) /* 0.393144238 */, 14 }, - - /* 720 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 14 }, - /* 721 */ { MAD_F(0x06504b44) /* 0.394603028 */, 14 }, - /* 722 */ { MAD_F(0x0653489f) /* 0.395332930 */, 14 }, - /* 723 */ { MAD_F(0x06564655) /* 0.396063168 */, 14 }, - /* 724 */ { MAD_F(0x06594465) /* 0.396793743 */, 14 }, - /* 725 */ { MAD_F(0x065c42d0) /* 0.397524655 */, 14 }, - /* 726 */ { MAD_F(0x065f4195) /* 0.398255903 */, 14 }, - /* 727 */ { MAD_F(0x066240b4) /* 0.398987487 */, 14 }, - /* 728 */ { MAD_F(0x0665402d) /* 0.399719406 */, 14 }, - /* 729 */ { MAD_F(0x06684000) /* 0.400451660 */, 14 }, - /* 730 */ { MAD_F(0x066b402d) /* 0.401184249 */, 14 }, - /* 731 */ { MAD_F(0x066e40b3) /* 0.401917173 */, 14 }, - /* 732 */ { MAD_F(0x06714194) /* 0.402650431 */, 14 }, - /* 733 */ { MAD_F(0x067442ce) /* 0.403384024 */, 14 }, - /* 734 */ { MAD_F(0x06774462) /* 0.404117949 */, 14 }, - /* 735 */ { MAD_F(0x067a464f) /* 0.404852209 */, 14 }, - - /* 736 */ { MAD_F(0x067d4896) /* 0.405586801 */, 14 }, - /* 737 */ { MAD_F(0x06804b36) /* 0.406321726 */, 14 }, - /* 738 */ { MAD_F(0x06834e2f) /* 0.407056983 */, 14 }, - /* 739 */ { MAD_F(0x06865181) /* 0.407792573 */, 14 }, - /* 740 */ { MAD_F(0x0689552c) /* 0.408528495 */, 14 }, - /* 741 */ { MAD_F(0x068c5931) /* 0.409264748 */, 14 }, - /* 742 */ { MAD_F(0x068f5d8e) /* 0.410001332 */, 14 }, - /* 743 */ { MAD_F(0x06926245) /* 0.410738247 */, 14 }, - /* 744 */ { MAD_F(0x06956753) /* 0.411475493 */, 14 }, - /* 745 */ { MAD_F(0x06986cbb) /* 0.412213070 */, 14 }, - /* 746 */ { MAD_F(0x069b727b) /* 0.412950976 */, 14 }, - /* 747 */ { MAD_F(0x069e7894) /* 0.413689213 */, 14 }, - /* 748 */ { MAD_F(0x06a17f05) /* 0.414427779 */, 14 }, - /* 749 */ { MAD_F(0x06a485cf) /* 0.415166674 */, 14 }, - /* 750 */ { MAD_F(0x06a78cf1) /* 0.415905897 */, 14 }, - /* 751 */ { MAD_F(0x06aa946b) /* 0.416645450 */, 14 }, - - /* 752 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 14 }, - /* 753 */ { MAD_F(0x06b0a468) /* 0.418125540 */, 14 }, - /* 754 */ { MAD_F(0x06b3acea) /* 0.418866076 */, 14 }, - /* 755 */ { MAD_F(0x06b6b5c4) /* 0.419606940 */, 14 }, - /* 756 */ { MAD_F(0x06b9bef6) /* 0.420348132 */, 14 }, - /* 757 */ { MAD_F(0x06bcc880) /* 0.421089650 */, 14 }, - /* 758 */ { MAD_F(0x06bfd261) /* 0.421831494 */, 14 }, - /* 759 */ { MAD_F(0x06c2dc9a) /* 0.422573665 */, 14 }, - /* 760 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 14 }, - /* 761 */ { MAD_F(0x06c8f213) /* 0.424058985 */, 14 }, - /* 762 */ { MAD_F(0x06cbfd52) /* 0.424802133 */, 14 }, - /* 763 */ { MAD_F(0x06cf08e9) /* 0.425545607 */, 14 }, - /* 764 */ { MAD_F(0x06d214d7) /* 0.426289405 */, 14 }, - /* 765 */ { MAD_F(0x06d5211c) /* 0.427033528 */, 14 }, - /* 766 */ { MAD_F(0x06d82db8) /* 0.427777975 */, 14 }, - /* 767 */ { MAD_F(0x06db3aaa) /* 0.428522746 */, 14 }, - - /* 768 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 14 }, - /* 769 */ { MAD_F(0x06e15595) /* 0.430013259 */, 14 }, - /* 770 */ { MAD_F(0x06e4638d) /* 0.430759001 */, 14 }, - /* 771 */ { MAD_F(0x06e771db) /* 0.431505065 */, 14 }, - /* 772 */ { MAD_F(0x06ea807f) /* 0.432251452 */, 14 }, - /* 773 */ { MAD_F(0x06ed8f7b) /* 0.432998162 */, 14 }, - /* 774 */ { MAD_F(0x06f09ecc) /* 0.433745193 */, 14 }, - /* 775 */ { MAD_F(0x06f3ae75) /* 0.434492546 */, 14 }, - /* 776 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 14 }, - /* 777 */ { MAD_F(0x06f9cec8) /* 0.435988217 */, 14 }, - /* 778 */ { MAD_F(0x06fcdf72) /* 0.436736534 */, 14 }, - /* 779 */ { MAD_F(0x06fff073) /* 0.437485172 */, 14 }, - /* 780 */ { MAD_F(0x070301ca) /* 0.438234130 */, 14 }, - /* 781 */ { MAD_F(0x07061377) /* 0.438983408 */, 14 }, - /* 782 */ { MAD_F(0x0709257a) /* 0.439733006 */, 14 }, - /* 783 */ { MAD_F(0x070c37d2) /* 0.440482924 */, 14 }, - - /* 784 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 14 }, - /* 785 */ { MAD_F(0x07125d84) /* 0.441983717 */, 14 }, - /* 786 */ { MAD_F(0x071570de) /* 0.442734592 */, 14 }, - /* 787 */ { MAD_F(0x0718848d) /* 0.443485785 */, 14 }, - /* 788 */ { MAD_F(0x071b9891) /* 0.444237296 */, 14 }, - /* 789 */ { MAD_F(0x071eaceb) /* 0.444989126 */, 14 }, - /* 790 */ { MAD_F(0x0721c19a) /* 0.445741273 */, 14 }, - /* 791 */ { MAD_F(0x0724d69e) /* 0.446493738 */, 14 }, - /* 792 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 14 }, - /* 793 */ { MAD_F(0x072b01a6) /* 0.447999618 */, 14 }, - /* 794 */ { MAD_F(0x072e17a9) /* 0.448753033 */, 14 }, - /* 795 */ { MAD_F(0x07312e01) /* 0.449506765 */, 14 }, - /* 796 */ { MAD_F(0x073444ae) /* 0.450260813 */, 14 }, - /* 797 */ { MAD_F(0x07375bb0) /* 0.451015176 */, 14 }, - /* 798 */ { MAD_F(0x073a7307) /* 0.451769856 */, 14 }, - /* 799 */ { MAD_F(0x073d8ab2) /* 0.452524850 */, 14 }, - - /* 800 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 14 }, - /* 801 */ { MAD_F(0x0743bb06) /* 0.454035784 */, 14 }, - /* 802 */ { MAD_F(0x0746d3af) /* 0.454791723 */, 14 }, - /* 803 */ { MAD_F(0x0749ecac) /* 0.455547976 */, 14 }, - /* 804 */ { MAD_F(0x074d05fe) /* 0.456304543 */, 14 }, - /* 805 */ { MAD_F(0x07501fa3) /* 0.457061423 */, 14 }, - /* 806 */ { MAD_F(0x0753399d) /* 0.457818618 */, 14 }, - /* 807 */ { MAD_F(0x075653eb) /* 0.458576125 */, 14 }, - /* 808 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 14 }, - /* 809 */ { MAD_F(0x075c8983) /* 0.460092079 */, 14 }, - /* 810 */ { MAD_F(0x075fa4cc) /* 0.460850524 */, 14 }, - /* 811 */ { MAD_F(0x0762c06a) /* 0.461609282 */, 14 }, - /* 812 */ { MAD_F(0x0765dc5b) /* 0.462368352 */, 14 }, - /* 813 */ { MAD_F(0x0768f8a0) /* 0.463127733 */, 14 }, - /* 814 */ { MAD_F(0x076c1538) /* 0.463887426 */, 14 }, - /* 815 */ { MAD_F(0x076f3224) /* 0.464647430 */, 14 }, - - /* 816 */ { MAD_F(0x07724f64) /* 0.465407744 */, 14 }, - /* 817 */ { MAD_F(0x07756cf7) /* 0.466168370 */, 14 }, - /* 818 */ { MAD_F(0x07788add) /* 0.466929306 */, 14 }, - /* 819 */ { MAD_F(0x077ba916) /* 0.467690552 */, 14 }, - /* 820 */ { MAD_F(0x077ec7a3) /* 0.468452108 */, 14 }, - /* 821 */ { MAD_F(0x0781e683) /* 0.469213973 */, 14 }, - /* 822 */ { MAD_F(0x078505b5) /* 0.469976148 */, 14 }, - /* 823 */ { MAD_F(0x0788253b) /* 0.470738632 */, 14 }, - /* 824 */ { MAD_F(0x078b4514) /* 0.471501425 */, 14 }, - /* 825 */ { MAD_F(0x078e653f) /* 0.472264527 */, 14 }, - /* 826 */ { MAD_F(0x079185be) /* 0.473027937 */, 14 }, - /* 827 */ { MAD_F(0x0794a68f) /* 0.473791655 */, 14 }, - /* 828 */ { MAD_F(0x0797c7b2) /* 0.474555681 */, 14 }, - /* 829 */ { MAD_F(0x079ae929) /* 0.475320014 */, 14 }, - /* 830 */ { MAD_F(0x079e0af1) /* 0.476084655 */, 14 }, - /* 831 */ { MAD_F(0x07a12d0c) /* 0.476849603 */, 14 }, - - /* 832 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 14 }, - /* 833 */ { MAD_F(0x07a7723a) /* 0.478380420 */, 14 }, - /* 834 */ { MAD_F(0x07aa954c) /* 0.479146288 */, 14 }, - /* 835 */ { MAD_F(0x07adb8b0) /* 0.479912463 */, 14 }, - /* 836 */ { MAD_F(0x07b0dc67) /* 0.480678943 */, 14 }, - /* 837 */ { MAD_F(0x07b4006f) /* 0.481445729 */, 14 }, - /* 838 */ { MAD_F(0x07b724ca) /* 0.482212820 */, 14 }, - /* 839 */ { MAD_F(0x07ba4976) /* 0.482980216 */, 14 }, - /* 840 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 14 }, - /* 841 */ { MAD_F(0x07c093c5) /* 0.484515924 */, 14 }, - /* 842 */ { MAD_F(0x07c3b967) /* 0.485284235 */, 14 }, - /* 843 */ { MAD_F(0x07c6df5a) /* 0.486052849 */, 14 }, - /* 844 */ { MAD_F(0x07ca059f) /* 0.486821768 */, 14 }, - /* 845 */ { MAD_F(0x07cd2c36) /* 0.487590991 */, 14 }, - /* 846 */ { MAD_F(0x07d0531e) /* 0.488360517 */, 14 }, - /* 847 */ { MAD_F(0x07d37a57) /* 0.489130346 */, 14 }, - - /* 848 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 14 }, - /* 849 */ { MAD_F(0x07d9c9be) /* 0.490670914 */, 14 }, - /* 850 */ { MAD_F(0x07dcf1ec) /* 0.491441651 */, 14 }, - /* 851 */ { MAD_F(0x07e01a6a) /* 0.492212691 */, 14 }, - /* 852 */ { MAD_F(0x07e3433a) /* 0.492984033 */, 14 }, - /* 853 */ { MAD_F(0x07e66c5a) /* 0.493755677 */, 14 }, - /* 854 */ { MAD_F(0x07e995cc) /* 0.494527623 */, 14 }, - /* 855 */ { MAD_F(0x07ecbf8e) /* 0.495299870 */, 14 }, - /* 856 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 14 }, - /* 857 */ { MAD_F(0x07f31405) /* 0.496845266 */, 14 }, - /* 858 */ { MAD_F(0x07f63eba) /* 0.497618416 */, 14 }, - /* 859 */ { MAD_F(0x07f969c0) /* 0.498391866 */, 14 }, - /* 860 */ { MAD_F(0x07fc9516) /* 0.499165616 */, 14 }, - /* 861 */ { MAD_F(0x07ffc0bc) /* 0.499939666 */, 14 }, - /* 862 */ { MAD_F(0x04017659) /* 0.250357008 */, 15 }, - /* 863 */ { MAD_F(0x04030c7d) /* 0.250744333 */, 15 }, - - /* 864 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 15 }, - /* 865 */ { MAD_F(0x0406393d) /* 0.251519431 */, 15 }, - /* 866 */ { MAD_F(0x0407cfd9) /* 0.251907204 */, 15 }, - /* 867 */ { MAD_F(0x0409669d) /* 0.252295127 */, 15 }, - /* 868 */ { MAD_F(0x040afd89) /* 0.252683198 */, 15 }, - /* 869 */ { MAD_F(0x040c949e) /* 0.253071419 */, 15 }, - /* 870 */ { MAD_F(0x040e2bda) /* 0.253459789 */, 15 }, - /* 871 */ { MAD_F(0x040fc33e) /* 0.253848307 */, 15 }, - /* 872 */ { MAD_F(0x04115aca) /* 0.254236974 */, 15 }, - /* 873 */ { MAD_F(0x0412f27e) /* 0.254625790 */, 15 }, - /* 874 */ { MAD_F(0x04148a5a) /* 0.255014755 */, 15 }, - /* 875 */ { MAD_F(0x0416225d) /* 0.255403867 */, 15 }, - /* 876 */ { MAD_F(0x0417ba89) /* 0.255793128 */, 15 }, - /* 877 */ { MAD_F(0x041952dc) /* 0.256182537 */, 15 }, - /* 878 */ { MAD_F(0x041aeb57) /* 0.256572095 */, 15 }, - /* 879 */ { MAD_F(0x041c83fa) /* 0.256961800 */, 15 }, - - /* 880 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 15 }, - /* 881 */ { MAD_F(0x041fb5b6) /* 0.257741653 */, 15 }, - /* 882 */ { MAD_F(0x04214ed0) /* 0.258131801 */, 15 }, - /* 883 */ { MAD_F(0x0422e811) /* 0.258522097 */, 15 }, - /* 884 */ { MAD_F(0x04248179) /* 0.258912540 */, 15 }, - /* 885 */ { MAD_F(0x04261b0a) /* 0.259303130 */, 15 }, - /* 886 */ { MAD_F(0x0427b4c2) /* 0.259693868 */, 15 }, - /* 887 */ { MAD_F(0x04294ea1) /* 0.260084752 */, 15 }, - /* 888 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 15 }, - /* 889 */ { MAD_F(0x042c82d6) /* 0.260866961 */, 15 }, - /* 890 */ { MAD_F(0x042e1d2b) /* 0.261258286 */, 15 }, - /* 891 */ { MAD_F(0x042fb7a8) /* 0.261649758 */, 15 }, - /* 892 */ { MAD_F(0x0431524c) /* 0.262041376 */, 15 }, - /* 893 */ { MAD_F(0x0432ed17) /* 0.262433140 */, 15 }, - /* 894 */ { MAD_F(0x0434880a) /* 0.262825051 */, 15 }, - /* 895 */ { MAD_F(0x04362324) /* 0.263217107 */, 15 }, - - /* 896 */ { MAD_F(0x0437be65) /* 0.263609310 */, 15 }, - /* 897 */ { MAD_F(0x043959cd) /* 0.264001659 */, 15 }, - /* 898 */ { MAD_F(0x043af55d) /* 0.264394153 */, 15 }, - /* 899 */ { MAD_F(0x043c9113) /* 0.264786794 */, 15 }, - /* 900 */ { MAD_F(0x043e2cf1) /* 0.265179580 */, 15 }, - /* 901 */ { MAD_F(0x043fc8f6) /* 0.265572511 */, 15 }, - /* 902 */ { MAD_F(0x04416522) /* 0.265965588 */, 15 }, - /* 903 */ { MAD_F(0x04430174) /* 0.266358810 */, 15 }, - /* 904 */ { MAD_F(0x04449dee) /* 0.266752177 */, 15 }, - /* 905 */ { MAD_F(0x04463a8f) /* 0.267145689 */, 15 }, - /* 906 */ { MAD_F(0x0447d756) /* 0.267539347 */, 15 }, - /* 907 */ { MAD_F(0x04497445) /* 0.267933149 */, 15 }, - /* 908 */ { MAD_F(0x044b115a) /* 0.268327096 */, 15 }, - /* 909 */ { MAD_F(0x044cae96) /* 0.268721187 */, 15 }, - /* 910 */ { MAD_F(0x044e4bf9) /* 0.269115423 */, 15 }, - /* 911 */ { MAD_F(0x044fe983) /* 0.269509804 */, 15 }, - - /* 912 */ { MAD_F(0x04518733) /* 0.269904329 */, 15 }, - /* 913 */ { MAD_F(0x0453250a) /* 0.270298998 */, 15 }, - /* 914 */ { MAD_F(0x0454c308) /* 0.270693811 */, 15 }, - /* 915 */ { MAD_F(0x0456612d) /* 0.271088768 */, 15 }, - /* 916 */ { MAD_F(0x0457ff78) /* 0.271483869 */, 15 }, - /* 917 */ { MAD_F(0x04599dea) /* 0.271879114 */, 15 }, - /* 918 */ { MAD_F(0x045b3c82) /* 0.272274503 */, 15 }, - /* 919 */ { MAD_F(0x045cdb41) /* 0.272670035 */, 15 }, - /* 920 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 15 }, - /* 921 */ { MAD_F(0x04601932) /* 0.273461530 */, 15 }, - /* 922 */ { MAD_F(0x0461b864) /* 0.273857492 */, 15 }, - /* 923 */ { MAD_F(0x046357bd) /* 0.274253597 */, 15 }, - /* 924 */ { MAD_F(0x0464f73c) /* 0.274649846 */, 15 }, - /* 925 */ { MAD_F(0x046696e2) /* 0.275046238 */, 15 }, - /* 926 */ { MAD_F(0x046836ae) /* 0.275442772 */, 15 }, - /* 927 */ { MAD_F(0x0469d6a0) /* 0.275839449 */, 15 }, - - /* 928 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 15 }, - /* 929 */ { MAD_F(0x046d16f7) /* 0.276633232 */, 15 }, - /* 930 */ { MAD_F(0x046eb75c) /* 0.277030337 */, 15 }, - /* 931 */ { MAD_F(0x047057e8) /* 0.277427584 */, 15 }, - /* 932 */ { MAD_F(0x0471f899) /* 0.277824973 */, 15 }, - /* 933 */ { MAD_F(0x04739971) /* 0.278222505 */, 15 }, - /* 934 */ { MAD_F(0x04753a6f) /* 0.278620179 */, 15 }, - /* 935 */ { MAD_F(0x0476db92) /* 0.279017995 */, 15 }, - /* 936 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 15 }, - /* 937 */ { MAD_F(0x047a1e4c) /* 0.279814051 */, 15 }, - /* 938 */ { MAD_F(0x047bbfe2) /* 0.280212292 */, 15 }, - /* 939 */ { MAD_F(0x047d619e) /* 0.280610675 */, 15 }, - /* 940 */ { MAD_F(0x047f0380) /* 0.281009199 */, 15 }, - /* 941 */ { MAD_F(0x0480a588) /* 0.281407864 */, 15 }, - /* 942 */ { MAD_F(0x048247b6) /* 0.281806670 */, 15 }, - /* 943 */ { MAD_F(0x0483ea0a) /* 0.282205618 */, 15 }, - - /* 944 */ { MAD_F(0x04858c83) /* 0.282604707 */, 15 }, - /* 945 */ { MAD_F(0x04872f22) /* 0.283003936 */, 15 }, - /* 946 */ { MAD_F(0x0488d1e8) /* 0.283403307 */, 15 }, - /* 947 */ { MAD_F(0x048a74d3) /* 0.283802818 */, 15 }, - /* 948 */ { MAD_F(0x048c17e3) /* 0.284202470 */, 15 }, - /* 949 */ { MAD_F(0x048dbb1a) /* 0.284602263 */, 15 }, - /* 950 */ { MAD_F(0x048f5e76) /* 0.285002195 */, 15 }, - /* 951 */ { MAD_F(0x049101f8) /* 0.285402269 */, 15 }, - /* 952 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 15 }, - /* 953 */ { MAD_F(0x0494496c) /* 0.286202836 */, 15 }, - /* 954 */ { MAD_F(0x0495ed5f) /* 0.286603329 */, 15 }, - /* 955 */ { MAD_F(0x04979177) /* 0.287003963 */, 15 }, - /* 956 */ { MAD_F(0x049935b5) /* 0.287404737 */, 15 }, - /* 957 */ { MAD_F(0x049ada19) /* 0.287805650 */, 15 }, - /* 958 */ { MAD_F(0x049c7ea1) /* 0.288206703 */, 15 }, - /* 959 */ { MAD_F(0x049e2350) /* 0.288607895 */, 15 }, - - /* 960 */ { MAD_F(0x049fc824) /* 0.289009227 */, 15 }, - /* 961 */ { MAD_F(0x04a16d1d) /* 0.289410699 */, 15 }, - /* 962 */ { MAD_F(0x04a3123b) /* 0.289812309 */, 15 }, - /* 963 */ { MAD_F(0x04a4b77f) /* 0.290214059 */, 15 }, - /* 964 */ { MAD_F(0x04a65ce8) /* 0.290615948 */, 15 }, - /* 965 */ { MAD_F(0x04a80277) /* 0.291017976 */, 15 }, - /* 966 */ { MAD_F(0x04a9a82b) /* 0.291420143 */, 15 }, - /* 967 */ { MAD_F(0x04ab4e04) /* 0.291822449 */, 15 }, - /* 968 */ { MAD_F(0x04acf402) /* 0.292224893 */, 15 }, - /* 969 */ { MAD_F(0x04ae9a26) /* 0.292627476 */, 15 }, - /* 970 */ { MAD_F(0x04b0406e) /* 0.293030197 */, 15 }, - /* 971 */ { MAD_F(0x04b1e6dc) /* 0.293433057 */, 15 }, - /* 972 */ { MAD_F(0x04b38d6f) /* 0.293836055 */, 15 }, - /* 973 */ { MAD_F(0x04b53427) /* 0.294239192 */, 15 }, - /* 974 */ { MAD_F(0x04b6db05) /* 0.294642466 */, 15 }, - /* 975 */ { MAD_F(0x04b88207) /* 0.295045879 */, 15 }, - - /* 976 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 15 }, - /* 977 */ { MAD_F(0x04bbd07a) /* 0.295853118 */, 15 }, - /* 978 */ { MAD_F(0x04bd77ec) /* 0.296256944 */, 15 }, - /* 979 */ { MAD_F(0x04bf1f82) /* 0.296660907 */, 15 }, - /* 980 */ { MAD_F(0x04c0c73d) /* 0.297065009 */, 15 }, - /* 981 */ { MAD_F(0x04c26f1d) /* 0.297469248 */, 15 }, - /* 982 */ { MAD_F(0x04c41722) /* 0.297873624 */, 15 }, - /* 983 */ { MAD_F(0x04c5bf4c) /* 0.298278137 */, 15 }, - /* 984 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 15 }, - /* 985 */ { MAD_F(0x04c9100d) /* 0.299087576 */, 15 }, - /* 986 */ { MAD_F(0x04cab8a6) /* 0.299492500 */, 15 }, - /* 987 */ { MAD_F(0x04cc6163) /* 0.299897562 */, 15 }, - /* 988 */ { MAD_F(0x04ce0a44) /* 0.300302761 */, 15 }, - /* 989 */ { MAD_F(0x04cfb34b) /* 0.300708096 */, 15 }, - /* 990 */ { MAD_F(0x04d15c76) /* 0.301113568 */, 15 }, - /* 991 */ { MAD_F(0x04d305c5) /* 0.301519176 */, 15 }, - - /* 992 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 15 }, - /* 993 */ { MAD_F(0x04d658d2) /* 0.302330802 */, 15 }, - /* 994 */ { MAD_F(0x04d80290) /* 0.302736820 */, 15 }, - /* 995 */ { MAD_F(0x04d9ac72) /* 0.303142973 */, 15 }, - /* 996 */ { MAD_F(0x04db5679) /* 0.303549263 */, 15 }, - /* 997 */ { MAD_F(0x04dd00a4) /* 0.303955689 */, 15 }, - /* 998 */ { MAD_F(0x04deaaf3) /* 0.304362251 */, 15 }, - /* 999 */ { MAD_F(0x04e05567) /* 0.304768948 */, 15 }, - /* 1000 */ { MAD_F(0x04e20000) /* 0.305175781 */, 15 }, - /* 1001 */ { MAD_F(0x04e3aabd) /* 0.305582750 */, 15 }, - /* 1002 */ { MAD_F(0x04e5559e) /* 0.305989854 */, 15 }, - /* 1003 */ { MAD_F(0x04e700a3) /* 0.306397094 */, 15 }, - /* 1004 */ { MAD_F(0x04e8abcd) /* 0.306804470 */, 15 }, - /* 1005 */ { MAD_F(0x04ea571c) /* 0.307211980 */, 15 }, - /* 1006 */ { MAD_F(0x04ec028e) /* 0.307619626 */, 15 }, - /* 1007 */ { MAD_F(0x04edae25) /* 0.308027406 */, 15 }, - - /* 1008 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 15 }, - /* 1009 */ { MAD_F(0x04f105bf) /* 0.308843373 */, 15 }, - /* 1010 */ { MAD_F(0x04f2b1c3) /* 0.309251558 */, 15 }, - /* 1011 */ { MAD_F(0x04f45dea) /* 0.309659879 */, 15 }, - /* 1012 */ { MAD_F(0x04f60a36) /* 0.310068333 */, 15 }, - /* 1013 */ { MAD_F(0x04f7b6a6) /* 0.310476923 */, 15 }, - /* 1014 */ { MAD_F(0x04f9633a) /* 0.310885647 */, 15 }, - /* 1015 */ { MAD_F(0x04fb0ff2) /* 0.311294505 */, 15 }, - /* 1016 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 15 }, - /* 1017 */ { MAD_F(0x04fe69ce) /* 0.312112625 */, 15 }, - /* 1018 */ { MAD_F(0x050016f3) /* 0.312521885 */, 15 }, - /* 1019 */ { MAD_F(0x0501c43b) /* 0.312931280 */, 15 }, - /* 1020 */ { MAD_F(0x050371a7) /* 0.313340809 */, 15 }, - /* 1021 */ { MAD_F(0x05051f37) /* 0.313750472 */, 15 }, - /* 1022 */ { MAD_F(0x0506cceb) /* 0.314160269 */, 15 }, - /* 1023 */ { MAD_F(0x05087ac2) /* 0.314570199 */, 15 }, - - /* 1024 */ { MAD_F(0x050a28be) /* 0.314980262 */, 15 }, - /* 1025 */ { MAD_F(0x050bd6de) /* 0.315390460 */, 15 }, - /* 1026 */ { MAD_F(0x050d8521) /* 0.315800790 */, 15 }, - /* 1027 */ { MAD_F(0x050f3388) /* 0.316211255 */, 15 }, - /* 1028 */ { MAD_F(0x0510e213) /* 0.316621852 */, 15 }, - /* 1029 */ { MAD_F(0x051290c2) /* 0.317032582 */, 15 }, - /* 1030 */ { MAD_F(0x05143f94) /* 0.317443446 */, 15 }, - /* 1031 */ { MAD_F(0x0515ee8a) /* 0.317854442 */, 15 }, - /* 1032 */ { MAD_F(0x05179da4) /* 0.318265572 */, 15 }, - /* 1033 */ { MAD_F(0x05194ce1) /* 0.318676834 */, 15 }, - /* 1034 */ { MAD_F(0x051afc42) /* 0.319088229 */, 15 }, - /* 1035 */ { MAD_F(0x051cabc7) /* 0.319499756 */, 15 }, - /* 1036 */ { MAD_F(0x051e5b6f) /* 0.319911417 */, 15 }, - /* 1037 */ { MAD_F(0x05200b3a) /* 0.320323209 */, 15 }, - /* 1038 */ { MAD_F(0x0521bb2a) /* 0.320735134 */, 15 }, - /* 1039 */ { MAD_F(0x05236b3d) /* 0.321147192 */, 15 }, - - /* 1040 */ { MAD_F(0x05251b73) /* 0.321559381 */, 15 }, - /* 1041 */ { MAD_F(0x0526cbcd) /* 0.321971703 */, 15 }, - /* 1042 */ { MAD_F(0x05287c4a) /* 0.322384156 */, 15 }, - /* 1043 */ { MAD_F(0x052a2cea) /* 0.322796742 */, 15 }, - /* 1044 */ { MAD_F(0x052bddae) /* 0.323209460 */, 15 }, - /* 1045 */ { MAD_F(0x052d8e96) /* 0.323622309 */, 15 }, - /* 1046 */ { MAD_F(0x052f3fa1) /* 0.324035290 */, 15 }, - /* 1047 */ { MAD_F(0x0530f0cf) /* 0.324448403 */, 15 }, - /* 1048 */ { MAD_F(0x0532a220) /* 0.324861647 */, 15 }, - /* 1049 */ { MAD_F(0x05345395) /* 0.325275023 */, 15 }, - /* 1050 */ { MAD_F(0x0536052d) /* 0.325688530 */, 15 }, - /* 1051 */ { MAD_F(0x0537b6e8) /* 0.326102168 */, 15 }, - /* 1052 */ { MAD_F(0x053968c6) /* 0.326515938 */, 15 }, - /* 1053 */ { MAD_F(0x053b1ac8) /* 0.326929839 */, 15 }, - /* 1054 */ { MAD_F(0x053ccced) /* 0.327343870 */, 15 }, - /* 1055 */ { MAD_F(0x053e7f35) /* 0.327758033 */, 15 }, - - /* 1056 */ { MAD_F(0x054031a0) /* 0.328172327 */, 15 }, - /* 1057 */ { MAD_F(0x0541e42e) /* 0.328586751 */, 15 }, - /* 1058 */ { MAD_F(0x054396df) /* 0.329001306 */, 15 }, - /* 1059 */ { MAD_F(0x054549b4) /* 0.329415992 */, 15 }, - /* 1060 */ { MAD_F(0x0546fcab) /* 0.329830808 */, 15 }, - /* 1061 */ { MAD_F(0x0548afc6) /* 0.330245755 */, 15 }, - /* 1062 */ { MAD_F(0x054a6303) /* 0.330660832 */, 15 }, - /* 1063 */ { MAD_F(0x054c1663) /* 0.331076039 */, 15 }, - /* 1064 */ { MAD_F(0x054dc9e7) /* 0.331491377 */, 15 }, - /* 1065 */ { MAD_F(0x054f7d8d) /* 0.331906845 */, 15 }, - /* 1066 */ { MAD_F(0x05513156) /* 0.332322443 */, 15 }, - /* 1067 */ { MAD_F(0x0552e542) /* 0.332738170 */, 15 }, - /* 1068 */ { MAD_F(0x05549951) /* 0.333154028 */, 15 }, - /* 1069 */ { MAD_F(0x05564d83) /* 0.333570016 */, 15 }, - /* 1070 */ { MAD_F(0x055801d8) /* 0.333986133 */, 15 }, - /* 1071 */ { MAD_F(0x0559b64f) /* 0.334402380 */, 15 }, - - /* 1072 */ { MAD_F(0x055b6ae9) /* 0.334818756 */, 15 }, - /* 1073 */ { MAD_F(0x055d1fa6) /* 0.335235262 */, 15 }, - /* 1074 */ { MAD_F(0x055ed486) /* 0.335651898 */, 15 }, - /* 1075 */ { MAD_F(0x05608988) /* 0.336068662 */, 15 }, - /* 1076 */ { MAD_F(0x05623ead) /* 0.336485556 */, 15 }, - /* 1077 */ { MAD_F(0x0563f3f5) /* 0.336902579 */, 15 }, - /* 1078 */ { MAD_F(0x0565a960) /* 0.337319732 */, 15 }, - /* 1079 */ { MAD_F(0x05675eed) /* 0.337737013 */, 15 }, - /* 1080 */ { MAD_F(0x0569149c) /* 0.338154423 */, 15 }, - /* 1081 */ { MAD_F(0x056aca6f) /* 0.338571962 */, 15 }, - /* 1082 */ { MAD_F(0x056c8064) /* 0.338989630 */, 15 }, - /* 1083 */ { MAD_F(0x056e367b) /* 0.339407426 */, 15 }, - /* 1084 */ { MAD_F(0x056fecb5) /* 0.339825351 */, 15 }, - /* 1085 */ { MAD_F(0x0571a311) /* 0.340243405 */, 15 }, - /* 1086 */ { MAD_F(0x05735990) /* 0.340661587 */, 15 }, - /* 1087 */ { MAD_F(0x05751032) /* 0.341079898 */, 15 }, - - /* 1088 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 15 }, - /* 1089 */ { MAD_F(0x05787ddc) /* 0.341916903 */, 15 }, - /* 1090 */ { MAD_F(0x057a34e4) /* 0.342335598 */, 15 }, - /* 1091 */ { MAD_F(0x057bec0f) /* 0.342754421 */, 15 }, - /* 1092 */ { MAD_F(0x057da35d) /* 0.343173373 */, 15 }, - /* 1093 */ { MAD_F(0x057f5acc) /* 0.343592452 */, 15 }, - /* 1094 */ { MAD_F(0x0581125e) /* 0.344011659 */, 15 }, - /* 1095 */ { MAD_F(0x0582ca12) /* 0.344430993 */, 15 }, - /* 1096 */ { MAD_F(0x058481e9) /* 0.344850455 */, 15 }, - /* 1097 */ { MAD_F(0x058639e2) /* 0.345270045 */, 15 }, - /* 1098 */ { MAD_F(0x0587f1fd) /* 0.345689763 */, 15 }, - /* 1099 */ { MAD_F(0x0589aa3a) /* 0.346109608 */, 15 }, - /* 1100 */ { MAD_F(0x058b629a) /* 0.346529580 */, 15 }, - /* 1101 */ { MAD_F(0x058d1b1b) /* 0.346949679 */, 15 }, - /* 1102 */ { MAD_F(0x058ed3bf) /* 0.347369906 */, 15 }, - /* 1103 */ { MAD_F(0x05908c85) /* 0.347790260 */, 15 }, - - /* 1104 */ { MAD_F(0x0592456d) /* 0.348210741 */, 15 }, - /* 1105 */ { MAD_F(0x0593fe77) /* 0.348631348 */, 15 }, - /* 1106 */ { MAD_F(0x0595b7a3) /* 0.349052083 */, 15 }, - /* 1107 */ { MAD_F(0x059770f1) /* 0.349472945 */, 15 }, - /* 1108 */ { MAD_F(0x05992a61) /* 0.349893933 */, 15 }, - /* 1109 */ { MAD_F(0x059ae3f3) /* 0.350315048 */, 15 }, - /* 1110 */ { MAD_F(0x059c9da8) /* 0.350736290 */, 15 }, - /* 1111 */ { MAD_F(0x059e577e) /* 0.351157658 */, 15 }, - /* 1112 */ { MAD_F(0x05a01176) /* 0.351579152 */, 15 }, - /* 1113 */ { MAD_F(0x05a1cb90) /* 0.352000773 */, 15 }, - /* 1114 */ { MAD_F(0x05a385cc) /* 0.352422520 */, 15 }, - /* 1115 */ { MAD_F(0x05a5402a) /* 0.352844394 */, 15 }, - /* 1116 */ { MAD_F(0x05a6faa9) /* 0.353266393 */, 15 }, - /* 1117 */ { MAD_F(0x05a8b54b) /* 0.353688519 */, 15 }, - /* 1118 */ { MAD_F(0x05aa700e) /* 0.354110771 */, 15 }, - /* 1119 */ { MAD_F(0x05ac2af3) /* 0.354533148 */, 15 }, - - /* 1120 */ { MAD_F(0x05ade5fa) /* 0.354955651 */, 15 }, - /* 1121 */ { MAD_F(0x05afa123) /* 0.355378281 */, 15 }, - /* 1122 */ { MAD_F(0x05b15c6d) /* 0.355801035 */, 15 }, - /* 1123 */ { MAD_F(0x05b317d9) /* 0.356223916 */, 15 }, - /* 1124 */ { MAD_F(0x05b4d367) /* 0.356646922 */, 15 }, - /* 1125 */ { MAD_F(0x05b68f16) /* 0.357070053 */, 15 }, - /* 1126 */ { MAD_F(0x05b84ae7) /* 0.357493310 */, 15 }, - /* 1127 */ { MAD_F(0x05ba06da) /* 0.357916692 */, 15 }, - /* 1128 */ { MAD_F(0x05bbc2ef) /* 0.358340200 */, 15 }, - /* 1129 */ { MAD_F(0x05bd7f25) /* 0.358763832 */, 15 }, - /* 1130 */ { MAD_F(0x05bf3b7c) /* 0.359187590 */, 15 }, - /* 1131 */ { MAD_F(0x05c0f7f5) /* 0.359611472 */, 15 }, - /* 1132 */ { MAD_F(0x05c2b490) /* 0.360035480 */, 15 }, - /* 1133 */ { MAD_F(0x05c4714c) /* 0.360459613 */, 15 }, - /* 1134 */ { MAD_F(0x05c62e2a) /* 0.360883870 */, 15 }, - /* 1135 */ { MAD_F(0x05c7eb29) /* 0.361308252 */, 15 }, - - /* 1136 */ { MAD_F(0x05c9a84a) /* 0.361732758 */, 15 }, - /* 1137 */ { MAD_F(0x05cb658c) /* 0.362157390 */, 15 }, - /* 1138 */ { MAD_F(0x05cd22ef) /* 0.362582145 */, 15 }, - /* 1139 */ { MAD_F(0x05cee074) /* 0.363007026 */, 15 }, - /* 1140 */ { MAD_F(0x05d09e1b) /* 0.363432030 */, 15 }, - /* 1141 */ { MAD_F(0x05d25be2) /* 0.363857159 */, 15 }, - /* 1142 */ { MAD_F(0x05d419cb) /* 0.364282412 */, 15 }, - /* 1143 */ { MAD_F(0x05d5d7d5) /* 0.364707789 */, 15 }, - /* 1144 */ { MAD_F(0x05d79601) /* 0.365133291 */, 15 }, - /* 1145 */ { MAD_F(0x05d9544e) /* 0.365558916 */, 15 }, - /* 1146 */ { MAD_F(0x05db12bc) /* 0.365984665 */, 15 }, - /* 1147 */ { MAD_F(0x05dcd14c) /* 0.366410538 */, 15 }, - /* 1148 */ { MAD_F(0x05de8ffc) /* 0.366836535 */, 15 }, - /* 1149 */ { MAD_F(0x05e04ece) /* 0.367262655 */, 15 }, - /* 1150 */ { MAD_F(0x05e20dc1) /* 0.367688900 */, 15 }, - /* 1151 */ { MAD_F(0x05e3ccd5) /* 0.368115267 */, 15 }, - - /* 1152 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 15 }, - /* 1153 */ { MAD_F(0x05e74b61) /* 0.368968373 */, 15 }, - /* 1154 */ { MAD_F(0x05e90ad9) /* 0.369395111 */, 15 }, - /* 1155 */ { MAD_F(0x05eaca72) /* 0.369821973 */, 15 }, - /* 1156 */ { MAD_F(0x05ec8a2b) /* 0.370248957 */, 15 }, - /* 1157 */ { MAD_F(0x05ee4a06) /* 0.370676065 */, 15 }, - /* 1158 */ { MAD_F(0x05f00a02) /* 0.371103295 */, 15 }, - /* 1159 */ { MAD_F(0x05f1ca1f) /* 0.371530649 */, 15 }, - /* 1160 */ { MAD_F(0x05f38a5d) /* 0.371958126 */, 15 }, - /* 1161 */ { MAD_F(0x05f54abc) /* 0.372385725 */, 15 }, - /* 1162 */ { MAD_F(0x05f70b3c) /* 0.372813448 */, 15 }, - /* 1163 */ { MAD_F(0x05f8cbdc) /* 0.373241292 */, 15 }, - /* 1164 */ { MAD_F(0x05fa8c9e) /* 0.373669260 */, 15 }, - /* 1165 */ { MAD_F(0x05fc4d81) /* 0.374097350 */, 15 }, - /* 1166 */ { MAD_F(0x05fe0e84) /* 0.374525563 */, 15 }, - /* 1167 */ { MAD_F(0x05ffcfa8) /* 0.374953898 */, 15 }, - - /* 1168 */ { MAD_F(0x060190ee) /* 0.375382356 */, 15 }, - /* 1169 */ { MAD_F(0x06035254) /* 0.375810936 */, 15 }, - /* 1170 */ { MAD_F(0x060513da) /* 0.376239638 */, 15 }, - /* 1171 */ { MAD_F(0x0606d582) /* 0.376668462 */, 15 }, - /* 1172 */ { MAD_F(0x0608974a) /* 0.377097408 */, 15 }, - /* 1173 */ { MAD_F(0x060a5934) /* 0.377526476 */, 15 }, - /* 1174 */ { MAD_F(0x060c1b3d) /* 0.377955667 */, 15 }, - /* 1175 */ { MAD_F(0x060ddd68) /* 0.378384979 */, 15 }, - /* 1176 */ { MAD_F(0x060f9fb3) /* 0.378814413 */, 15 }, - /* 1177 */ { MAD_F(0x0611621f) /* 0.379243968 */, 15 }, - /* 1178 */ { MAD_F(0x061324ac) /* 0.379673646 */, 15 }, - /* 1179 */ { MAD_F(0x0614e759) /* 0.380103444 */, 15 }, - /* 1180 */ { MAD_F(0x0616aa27) /* 0.380533365 */, 15 }, - /* 1181 */ { MAD_F(0x06186d16) /* 0.380963407 */, 15 }, - /* 1182 */ { MAD_F(0x061a3025) /* 0.381393570 */, 15 }, - /* 1183 */ { MAD_F(0x061bf354) /* 0.381823855 */, 15 }, - - /* 1184 */ { MAD_F(0x061db6a5) /* 0.382254261 */, 15 }, - /* 1185 */ { MAD_F(0x061f7a15) /* 0.382684788 */, 15 }, - /* 1186 */ { MAD_F(0x06213da7) /* 0.383115436 */, 15 }, - /* 1187 */ { MAD_F(0x06230158) /* 0.383546205 */, 15 }, - /* 1188 */ { MAD_F(0x0624c52a) /* 0.383977096 */, 15 }, - /* 1189 */ { MAD_F(0x0626891d) /* 0.384408107 */, 15 }, - /* 1190 */ { MAD_F(0x06284d30) /* 0.384839239 */, 15 }, - /* 1191 */ { MAD_F(0x062a1164) /* 0.385270492 */, 15 }, - /* 1192 */ { MAD_F(0x062bd5b8) /* 0.385701865 */, 15 }, - /* 1193 */ { MAD_F(0x062d9a2c) /* 0.386133359 */, 15 }, - /* 1194 */ { MAD_F(0x062f5ec1) /* 0.386564974 */, 15 }, - /* 1195 */ { MAD_F(0x06312376) /* 0.386996709 */, 15 }, - /* 1196 */ { MAD_F(0x0632e84b) /* 0.387428565 */, 15 }, - /* 1197 */ { MAD_F(0x0634ad41) /* 0.387860541 */, 15 }, - /* 1198 */ { MAD_F(0x06367257) /* 0.388292637 */, 15 }, - /* 1199 */ { MAD_F(0x0638378d) /* 0.388724854 */, 15 }, - - /* 1200 */ { MAD_F(0x0639fce4) /* 0.389157191 */, 15 }, - /* 1201 */ { MAD_F(0x063bc25b) /* 0.389589648 */, 15 }, - /* 1202 */ { MAD_F(0x063d87f2) /* 0.390022225 */, 15 }, - /* 1203 */ { MAD_F(0x063f4da9) /* 0.390454922 */, 15 }, - /* 1204 */ { MAD_F(0x06411380) /* 0.390887739 */, 15 }, - /* 1205 */ { MAD_F(0x0642d978) /* 0.391320675 */, 15 }, - /* 1206 */ { MAD_F(0x06449f8f) /* 0.391753732 */, 15 }, - /* 1207 */ { MAD_F(0x064665c7) /* 0.392186908 */, 15 }, - /* 1208 */ { MAD_F(0x06482c1f) /* 0.392620204 */, 15 }, - /* 1209 */ { MAD_F(0x0649f297) /* 0.393053619 */, 15 }, - /* 1210 */ { MAD_F(0x064bb92f) /* 0.393487154 */, 15 }, - /* 1211 */ { MAD_F(0x064d7fe8) /* 0.393920808 */, 15 }, - /* 1212 */ { MAD_F(0x064f46c0) /* 0.394354582 */, 15 }, - /* 1213 */ { MAD_F(0x06510db8) /* 0.394788475 */, 15 }, - /* 1214 */ { MAD_F(0x0652d4d0) /* 0.395222488 */, 15 }, - /* 1215 */ { MAD_F(0x06549c09) /* 0.395656619 */, 15 }, - - /* 1216 */ { MAD_F(0x06566361) /* 0.396090870 */, 15 }, - /* 1217 */ { MAD_F(0x06582ad9) /* 0.396525239 */, 15 }, - /* 1218 */ { MAD_F(0x0659f271) /* 0.396959728 */, 15 }, - /* 1219 */ { MAD_F(0x065bba29) /* 0.397394336 */, 15 }, - /* 1220 */ { MAD_F(0x065d8201) /* 0.397829062 */, 15 }, - /* 1221 */ { MAD_F(0x065f49f9) /* 0.398263907 */, 15 }, - /* 1222 */ { MAD_F(0x06611211) /* 0.398698871 */, 15 }, - /* 1223 */ { MAD_F(0x0662da49) /* 0.399133954 */, 15 }, - /* 1224 */ { MAD_F(0x0664a2a0) /* 0.399569155 */, 15 }, - /* 1225 */ { MAD_F(0x06666b17) /* 0.400004475 */, 15 }, - /* 1226 */ { MAD_F(0x066833ae) /* 0.400439913 */, 15 }, - /* 1227 */ { MAD_F(0x0669fc65) /* 0.400875470 */, 15 }, - /* 1228 */ { MAD_F(0x066bc53c) /* 0.401311145 */, 15 }, - /* 1229 */ { MAD_F(0x066d8e32) /* 0.401746938 */, 15 }, - /* 1230 */ { MAD_F(0x066f5748) /* 0.402182850 */, 15 }, - /* 1231 */ { MAD_F(0x0671207e) /* 0.402618879 */, 15 }, - - /* 1232 */ { MAD_F(0x0672e9d4) /* 0.403055027 */, 15 }, - /* 1233 */ { MAD_F(0x0674b349) /* 0.403491293 */, 15 }, - /* 1234 */ { MAD_F(0x06767cde) /* 0.403927676 */, 15 }, - /* 1235 */ { MAD_F(0x06784692) /* 0.404364178 */, 15 }, - /* 1236 */ { MAD_F(0x067a1066) /* 0.404800797 */, 15 }, - /* 1237 */ { MAD_F(0x067bda5a) /* 0.405237535 */, 15 }, - /* 1238 */ { MAD_F(0x067da46d) /* 0.405674390 */, 15 }, - /* 1239 */ { MAD_F(0x067f6ea0) /* 0.406111362 */, 15 }, - /* 1240 */ { MAD_F(0x068138f3) /* 0.406548452 */, 15 }, - /* 1241 */ { MAD_F(0x06830365) /* 0.406985660 */, 15 }, - /* 1242 */ { MAD_F(0x0684cdf6) /* 0.407422985 */, 15 }, - /* 1243 */ { MAD_F(0x068698a8) /* 0.407860427 */, 15 }, - /* 1244 */ { MAD_F(0x06886378) /* 0.408297987 */, 15 }, - /* 1245 */ { MAD_F(0x068a2e68) /* 0.408735664 */, 15 }, - /* 1246 */ { MAD_F(0x068bf978) /* 0.409173458 */, 15 }, - /* 1247 */ { MAD_F(0x068dc4a7) /* 0.409611370 */, 15 }, - - /* 1248 */ { MAD_F(0x068f8ff5) /* 0.410049398 */, 15 }, - /* 1249 */ { MAD_F(0x06915b63) /* 0.410487544 */, 15 }, - /* 1250 */ { MAD_F(0x069326f0) /* 0.410925806 */, 15 }, - /* 1251 */ { MAD_F(0x0694f29c) /* 0.411364185 */, 15 }, - /* 1252 */ { MAD_F(0x0696be68) /* 0.411802681 */, 15 }, - /* 1253 */ { MAD_F(0x06988a54) /* 0.412241294 */, 15 }, - /* 1254 */ { MAD_F(0x069a565e) /* 0.412680024 */, 15 }, - /* 1255 */ { MAD_F(0x069c2288) /* 0.413118870 */, 15 }, - /* 1256 */ { MAD_F(0x069deed1) /* 0.413557833 */, 15 }, - /* 1257 */ { MAD_F(0x069fbb3a) /* 0.413996912 */, 15 }, - /* 1258 */ { MAD_F(0x06a187c1) /* 0.414436108 */, 15 }, - /* 1259 */ { MAD_F(0x06a35468) /* 0.414875420 */, 15 }, - /* 1260 */ { MAD_F(0x06a5212f) /* 0.415314849 */, 15 }, - /* 1261 */ { MAD_F(0x06a6ee14) /* 0.415754393 */, 15 }, - /* 1262 */ { MAD_F(0x06a8bb18) /* 0.416194054 */, 15 }, - /* 1263 */ { MAD_F(0x06aa883c) /* 0.416633831 */, 15 }, - - /* 1264 */ { MAD_F(0x06ac557f) /* 0.417073724 */, 15 }, - /* 1265 */ { MAD_F(0x06ae22e1) /* 0.417513734 */, 15 }, - /* 1266 */ { MAD_F(0x06aff062) /* 0.417953859 */, 15 }, - /* 1267 */ { MAD_F(0x06b1be03) /* 0.418394100 */, 15 }, - /* 1268 */ { MAD_F(0x06b38bc2) /* 0.418834457 */, 15 }, - /* 1269 */ { MAD_F(0x06b559a1) /* 0.419274929 */, 15 }, - /* 1270 */ { MAD_F(0x06b7279e) /* 0.419715518 */, 15 }, - /* 1271 */ { MAD_F(0x06b8f5bb) /* 0.420156222 */, 15 }, - /* 1272 */ { MAD_F(0x06bac3f6) /* 0.420597041 */, 15 }, - /* 1273 */ { MAD_F(0x06bc9251) /* 0.421037977 */, 15 }, - /* 1274 */ { MAD_F(0x06be60cb) /* 0.421479027 */, 15 }, - /* 1275 */ { MAD_F(0x06c02f63) /* 0.421920193 */, 15 }, - /* 1276 */ { MAD_F(0x06c1fe1b) /* 0.422361475 */, 15 }, - /* 1277 */ { MAD_F(0x06c3ccf1) /* 0.422802871 */, 15 }, - /* 1278 */ { MAD_F(0x06c59be7) /* 0.423244383 */, 15 }, - /* 1279 */ { MAD_F(0x06c76afb) /* 0.423686010 */, 15 }, - - /* 1280 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 15 }, - /* 1281 */ { MAD_F(0x06cb0981) /* 0.424569610 */, 15 }, - /* 1282 */ { MAD_F(0x06ccd8f2) /* 0.425011582 */, 15 }, - /* 1283 */ { MAD_F(0x06cea881) /* 0.425453669 */, 15 }, - /* 1284 */ { MAD_F(0x06d07830) /* 0.425895871 */, 15 }, - /* 1285 */ { MAD_F(0x06d247fe) /* 0.426338188 */, 15 }, - /* 1286 */ { MAD_F(0x06d417ea) /* 0.426780620 */, 15 }, - /* 1287 */ { MAD_F(0x06d5e7f5) /* 0.427223166 */, 15 }, - /* 1288 */ { MAD_F(0x06d7b81f) /* 0.427665827 */, 15 }, - /* 1289 */ { MAD_F(0x06d98868) /* 0.428108603 */, 15 }, - /* 1290 */ { MAD_F(0x06db58cf) /* 0.428551493 */, 15 }, - /* 1291 */ { MAD_F(0x06dd2955) /* 0.428994497 */, 15 }, - /* 1292 */ { MAD_F(0x06def9fa) /* 0.429437616 */, 15 }, - /* 1293 */ { MAD_F(0x06e0cabe) /* 0.429880849 */, 15 }, - /* 1294 */ { MAD_F(0x06e29ba0) /* 0.430324197 */, 15 }, - /* 1295 */ { MAD_F(0x06e46ca1) /* 0.430767659 */, 15 }, - - /* 1296 */ { MAD_F(0x06e63dc0) /* 0.431211234 */, 15 }, - /* 1297 */ { MAD_F(0x06e80efe) /* 0.431654924 */, 15 }, - /* 1298 */ { MAD_F(0x06e9e05b) /* 0.432098728 */, 15 }, - /* 1299 */ { MAD_F(0x06ebb1d6) /* 0.432542647 */, 15 }, - /* 1300 */ { MAD_F(0x06ed8370) /* 0.432986678 */, 15 }, - /* 1301 */ { MAD_F(0x06ef5529) /* 0.433430824 */, 15 }, - /* 1302 */ { MAD_F(0x06f12700) /* 0.433875084 */, 15 }, - /* 1303 */ { MAD_F(0x06f2f8f5) /* 0.434319457 */, 15 }, - /* 1304 */ { MAD_F(0x06f4cb09) /* 0.434763944 */, 15 }, - /* 1305 */ { MAD_F(0x06f69d3c) /* 0.435208545 */, 15 }, - /* 1306 */ { MAD_F(0x06f86f8d) /* 0.435653259 */, 15 }, - /* 1307 */ { MAD_F(0x06fa41fd) /* 0.436098087 */, 15 }, - /* 1308 */ { MAD_F(0x06fc148b) /* 0.436543029 */, 15 }, - /* 1309 */ { MAD_F(0x06fde737) /* 0.436988083 */, 15 }, - /* 1310 */ { MAD_F(0x06ffba02) /* 0.437433251 */, 15 }, - /* 1311 */ { MAD_F(0x07018ceb) /* 0.437878533 */, 15 }, - - /* 1312 */ { MAD_F(0x07035ff3) /* 0.438323927 */, 15 }, - /* 1313 */ { MAD_F(0x07053319) /* 0.438769435 */, 15 }, - /* 1314 */ { MAD_F(0x0707065d) /* 0.439215056 */, 15 }, - /* 1315 */ { MAD_F(0x0708d9c0) /* 0.439660790 */, 15 }, - /* 1316 */ { MAD_F(0x070aad41) /* 0.440106636 */, 15 }, - /* 1317 */ { MAD_F(0x070c80e1) /* 0.440552596 */, 15 }, - /* 1318 */ { MAD_F(0x070e549f) /* 0.440998669 */, 15 }, - /* 1319 */ { MAD_F(0x0710287b) /* 0.441444855 */, 15 }, - /* 1320 */ { MAD_F(0x0711fc75) /* 0.441891153 */, 15 }, - /* 1321 */ { MAD_F(0x0713d08d) /* 0.442337564 */, 15 }, - /* 1322 */ { MAD_F(0x0715a4c4) /* 0.442784088 */, 15 }, - /* 1323 */ { MAD_F(0x07177919) /* 0.443230724 */, 15 }, - /* 1324 */ { MAD_F(0x07194d8c) /* 0.443677473 */, 15 }, - /* 1325 */ { MAD_F(0x071b221e) /* 0.444124334 */, 15 }, - /* 1326 */ { MAD_F(0x071cf6ce) /* 0.444571308 */, 15 }, - /* 1327 */ { MAD_F(0x071ecb9b) /* 0.445018394 */, 15 }, - - /* 1328 */ { MAD_F(0x0720a087) /* 0.445465593 */, 15 }, - /* 1329 */ { MAD_F(0x07227591) /* 0.445912903 */, 15 }, - /* 1330 */ { MAD_F(0x07244ab9) /* 0.446360326 */, 15 }, - /* 1331 */ { MAD_F(0x07262000) /* 0.446807861 */, 15 }, - /* 1332 */ { MAD_F(0x0727f564) /* 0.447255509 */, 15 }, - /* 1333 */ { MAD_F(0x0729cae7) /* 0.447703268 */, 15 }, - /* 1334 */ { MAD_F(0x072ba087) /* 0.448151139 */, 15 }, - /* 1335 */ { MAD_F(0x072d7646) /* 0.448599122 */, 15 }, - /* 1336 */ { MAD_F(0x072f4c22) /* 0.449047217 */, 15 }, - /* 1337 */ { MAD_F(0x0731221d) /* 0.449495424 */, 15 }, - /* 1338 */ { MAD_F(0x0732f835) /* 0.449943742 */, 15 }, - /* 1339 */ { MAD_F(0x0734ce6c) /* 0.450392173 */, 15 }, - /* 1340 */ { MAD_F(0x0736a4c1) /* 0.450840715 */, 15 }, - /* 1341 */ { MAD_F(0x07387b33) /* 0.451289368 */, 15 }, - /* 1342 */ { MAD_F(0x073a51c4) /* 0.451738133 */, 15 }, - /* 1343 */ { MAD_F(0x073c2872) /* 0.452187010 */, 15 }, - - /* 1344 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 15 }, - /* 1345 */ { MAD_F(0x073fd628) /* 0.453085097 */, 15 }, - /* 1346 */ { MAD_F(0x0741ad30) /* 0.453534308 */, 15 }, - /* 1347 */ { MAD_F(0x07438456) /* 0.453983630 */, 15 }, - /* 1348 */ { MAD_F(0x07455b9a) /* 0.454433063 */, 15 }, - /* 1349 */ { MAD_F(0x074732fc) /* 0.454882607 */, 15 }, - /* 1350 */ { MAD_F(0x07490a7b) /* 0.455332262 */, 15 }, - /* 1351 */ { MAD_F(0x074ae218) /* 0.455782029 */, 15 }, - /* 1352 */ { MAD_F(0x074cb9d3) /* 0.456231906 */, 15 }, - /* 1353 */ { MAD_F(0x074e91ac) /* 0.456681894 */, 15 }, - /* 1354 */ { MAD_F(0x075069a3) /* 0.457131993 */, 15 }, - /* 1355 */ { MAD_F(0x075241b7) /* 0.457582203 */, 15 }, - /* 1356 */ { MAD_F(0x075419e9) /* 0.458032524 */, 15 }, - /* 1357 */ { MAD_F(0x0755f239) /* 0.458482956 */, 15 }, - /* 1358 */ { MAD_F(0x0757caa7) /* 0.458933498 */, 15 }, - /* 1359 */ { MAD_F(0x0759a332) /* 0.459384151 */, 15 }, - - /* 1360 */ { MAD_F(0x075b7bdb) /* 0.459834914 */, 15 }, - /* 1361 */ { MAD_F(0x075d54a1) /* 0.460285788 */, 15 }, - /* 1362 */ { MAD_F(0x075f2d85) /* 0.460736772 */, 15 }, - /* 1363 */ { MAD_F(0x07610687) /* 0.461187867 */, 15 }, - /* 1364 */ { MAD_F(0x0762dfa6) /* 0.461639071 */, 15 }, - /* 1365 */ { MAD_F(0x0764b8e3) /* 0.462090387 */, 15 }, - /* 1366 */ { MAD_F(0x0766923e) /* 0.462541812 */, 15 }, - /* 1367 */ { MAD_F(0x07686bb6) /* 0.462993348 */, 15 }, - /* 1368 */ { MAD_F(0x076a454c) /* 0.463444993 */, 15 }, - /* 1369 */ { MAD_F(0x076c1eff) /* 0.463896749 */, 15 }, - /* 1370 */ { MAD_F(0x076df8d0) /* 0.464348615 */, 15 }, - /* 1371 */ { MAD_F(0x076fd2be) /* 0.464800591 */, 15 }, - /* 1372 */ { MAD_F(0x0771acca) /* 0.465252676 */, 15 }, - /* 1373 */ { MAD_F(0x077386f3) /* 0.465704872 */, 15 }, - /* 1374 */ { MAD_F(0x0775613a) /* 0.466157177 */, 15 }, - /* 1375 */ { MAD_F(0x07773b9e) /* 0.466609592 */, 15 }, - - /* 1376 */ { MAD_F(0x07791620) /* 0.467062117 */, 15 }, - /* 1377 */ { MAD_F(0x077af0bf) /* 0.467514751 */, 15 }, - /* 1378 */ { MAD_F(0x077ccb7c) /* 0.467967495 */, 15 }, - /* 1379 */ { MAD_F(0x077ea656) /* 0.468420349 */, 15 }, - /* 1380 */ { MAD_F(0x0780814d) /* 0.468873312 */, 15 }, - /* 1381 */ { MAD_F(0x07825c62) /* 0.469326384 */, 15 }, - /* 1382 */ { MAD_F(0x07843794) /* 0.469779566 */, 15 }, - /* 1383 */ { MAD_F(0x078612e3) /* 0.470232857 */, 15 }, - /* 1384 */ { MAD_F(0x0787ee50) /* 0.470686258 */, 15 }, - /* 1385 */ { MAD_F(0x0789c9da) /* 0.471139767 */, 15 }, - /* 1386 */ { MAD_F(0x078ba581) /* 0.471593386 */, 15 }, - /* 1387 */ { MAD_F(0x078d8146) /* 0.472047114 */, 15 }, - /* 1388 */ { MAD_F(0x078f5d28) /* 0.472500951 */, 15 }, - /* 1389 */ { MAD_F(0x07913927) /* 0.472954896 */, 15 }, - /* 1390 */ { MAD_F(0x07931543) /* 0.473408951 */, 15 }, - /* 1391 */ { MAD_F(0x0794f17d) /* 0.473863115 */, 15 }, - - /* 1392 */ { MAD_F(0x0796cdd4) /* 0.474317388 */, 15 }, - /* 1393 */ { MAD_F(0x0798aa48) /* 0.474771769 */, 15 }, - /* 1394 */ { MAD_F(0x079a86d9) /* 0.475226259 */, 15 }, - /* 1395 */ { MAD_F(0x079c6388) /* 0.475680858 */, 15 }, - /* 1396 */ { MAD_F(0x079e4053) /* 0.476135565 */, 15 }, - /* 1397 */ { MAD_F(0x07a01d3c) /* 0.476590381 */, 15 }, - /* 1398 */ { MAD_F(0x07a1fa42) /* 0.477045306 */, 15 }, - /* 1399 */ { MAD_F(0x07a3d765) /* 0.477500339 */, 15 }, - /* 1400 */ { MAD_F(0x07a5b4a5) /* 0.477955481 */, 15 }, - /* 1401 */ { MAD_F(0x07a79202) /* 0.478410731 */, 15 }, - /* 1402 */ { MAD_F(0x07a96f7d) /* 0.478866089 */, 15 }, - /* 1403 */ { MAD_F(0x07ab4d14) /* 0.479321555 */, 15 }, - /* 1404 */ { MAD_F(0x07ad2ac8) /* 0.479777130 */, 15 }, - /* 1405 */ { MAD_F(0x07af089a) /* 0.480232813 */, 15 }, - /* 1406 */ { MAD_F(0x07b0e688) /* 0.480688604 */, 15 }, - /* 1407 */ { MAD_F(0x07b2c494) /* 0.481144503 */, 15 }, - - /* 1408 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 15 }, - /* 1409 */ { MAD_F(0x07b68102) /* 0.482056625 */, 15 }, - /* 1410 */ { MAD_F(0x07b85f64) /* 0.482512848 */, 15 }, - /* 1411 */ { MAD_F(0x07ba3de4) /* 0.482969179 */, 15 }, - /* 1412 */ { MAD_F(0x07bc1c80) /* 0.483425618 */, 15 }, - /* 1413 */ { MAD_F(0x07bdfb39) /* 0.483882164 */, 15 }, - /* 1414 */ { MAD_F(0x07bfda0f) /* 0.484338818 */, 15 }, - /* 1415 */ { MAD_F(0x07c1b902) /* 0.484795580 */, 15 }, - /* 1416 */ { MAD_F(0x07c39812) /* 0.485252449 */, 15 }, - /* 1417 */ { MAD_F(0x07c5773f) /* 0.485709426 */, 15 }, - /* 1418 */ { MAD_F(0x07c75689) /* 0.486166511 */, 15 }, - /* 1419 */ { MAD_F(0x07c935ef) /* 0.486623703 */, 15 }, - /* 1420 */ { MAD_F(0x07cb1573) /* 0.487081002 */, 15 }, - /* 1421 */ { MAD_F(0x07ccf513) /* 0.487538409 */, 15 }, - /* 1422 */ { MAD_F(0x07ced4d0) /* 0.487995923 */, 15 }, - /* 1423 */ { MAD_F(0x07d0b4aa) /* 0.488453544 */, 15 }, - - /* 1424 */ { MAD_F(0x07d294a0) /* 0.488911273 */, 15 }, - /* 1425 */ { MAD_F(0x07d474b3) /* 0.489369108 */, 15 }, - /* 1426 */ { MAD_F(0x07d654e4) /* 0.489827051 */, 15 }, - /* 1427 */ { MAD_F(0x07d83530) /* 0.490285101 */, 15 }, - /* 1428 */ { MAD_F(0x07da159a) /* 0.490743258 */, 15 }, - /* 1429 */ { MAD_F(0x07dbf620) /* 0.491201522 */, 15 }, - /* 1430 */ { MAD_F(0x07ddd6c3) /* 0.491659892 */, 15 }, - /* 1431 */ { MAD_F(0x07dfb783) /* 0.492118370 */, 15 }, - /* 1432 */ { MAD_F(0x07e1985f) /* 0.492576954 */, 15 }, - /* 1433 */ { MAD_F(0x07e37958) /* 0.493035645 */, 15 }, - /* 1434 */ { MAD_F(0x07e55a6e) /* 0.493494443 */, 15 }, - /* 1435 */ { MAD_F(0x07e73ba0) /* 0.493953348 */, 15 }, - /* 1436 */ { MAD_F(0x07e91cef) /* 0.494412359 */, 15 }, - /* 1437 */ { MAD_F(0x07eafe5a) /* 0.494871476 */, 15 }, - /* 1438 */ { MAD_F(0x07ecdfe2) /* 0.495330701 */, 15 }, - /* 1439 */ { MAD_F(0x07eec187) /* 0.495790031 */, 15 }, - - /* 1440 */ { MAD_F(0x07f0a348) /* 0.496249468 */, 15 }, - /* 1441 */ { MAD_F(0x07f28526) /* 0.496709012 */, 15 }, - /* 1442 */ { MAD_F(0x07f46720) /* 0.497168662 */, 15 }, - /* 1443 */ { MAD_F(0x07f64937) /* 0.497628418 */, 15 }, - /* 1444 */ { MAD_F(0x07f82b6a) /* 0.498088280 */, 15 }, - /* 1445 */ { MAD_F(0x07fa0dba) /* 0.498548248 */, 15 }, - /* 1446 */ { MAD_F(0x07fbf026) /* 0.499008323 */, 15 }, - /* 1447 */ { MAD_F(0x07fdd2af) /* 0.499468503 */, 15 }, - /* 1448 */ { MAD_F(0x07ffb554) /* 0.499928790 */, 15 }, - /* 1449 */ { MAD_F(0x0400cc0b) /* 0.250194591 */, 16 }, - /* 1450 */ { MAD_F(0x0401bd7a) /* 0.250424840 */, 16 }, - /* 1451 */ { MAD_F(0x0402aef7) /* 0.250655143 */, 16 }, - /* 1452 */ { MAD_F(0x0403a083) /* 0.250885498 */, 16 }, - /* 1453 */ { MAD_F(0x0404921c) /* 0.251115906 */, 16 }, - /* 1454 */ { MAD_F(0x040583c4) /* 0.251346367 */, 16 }, - /* 1455 */ { MAD_F(0x0406757a) /* 0.251576880 */, 16 }, - - /* 1456 */ { MAD_F(0x0407673f) /* 0.251807447 */, 16 }, - /* 1457 */ { MAD_F(0x04085911) /* 0.252038066 */, 16 }, - /* 1458 */ { MAD_F(0x04094af1) /* 0.252268738 */, 16 }, - /* 1459 */ { MAD_F(0x040a3ce0) /* 0.252499463 */, 16 }, - /* 1460 */ { MAD_F(0x040b2edd) /* 0.252730240 */, 16 }, - /* 1461 */ { MAD_F(0x040c20e8) /* 0.252961071 */, 16 }, - /* 1462 */ { MAD_F(0x040d1301) /* 0.253191953 */, 16 }, - /* 1463 */ { MAD_F(0x040e0529) /* 0.253422889 */, 16 }, - /* 1464 */ { MAD_F(0x040ef75e) /* 0.253653877 */, 16 }, - /* 1465 */ { MAD_F(0x040fe9a1) /* 0.253884918 */, 16 }, - /* 1466 */ { MAD_F(0x0410dbf3) /* 0.254116011 */, 16 }, - /* 1467 */ { MAD_F(0x0411ce53) /* 0.254347157 */, 16 }, - /* 1468 */ { MAD_F(0x0412c0c1) /* 0.254578356 */, 16 }, - /* 1469 */ { MAD_F(0x0413b33d) /* 0.254809606 */, 16 }, - /* 1470 */ { MAD_F(0x0414a5c7) /* 0.255040910 */, 16 }, - /* 1471 */ { MAD_F(0x0415985f) /* 0.255272266 */, 16 }, - - /* 1472 */ { MAD_F(0x04168b05) /* 0.255503674 */, 16 }, - /* 1473 */ { MAD_F(0x04177db9) /* 0.255735135 */, 16 }, - /* 1474 */ { MAD_F(0x0418707c) /* 0.255966648 */, 16 }, - /* 1475 */ { MAD_F(0x0419634c) /* 0.256198213 */, 16 }, - /* 1476 */ { MAD_F(0x041a562a) /* 0.256429831 */, 16 }, - /* 1477 */ { MAD_F(0x041b4917) /* 0.256661501 */, 16 }, - /* 1478 */ { MAD_F(0x041c3c11) /* 0.256893223 */, 16 }, - /* 1479 */ { MAD_F(0x041d2f1a) /* 0.257124998 */, 16 }, - /* 1480 */ { MAD_F(0x041e2230) /* 0.257356825 */, 16 }, - /* 1481 */ { MAD_F(0x041f1555) /* 0.257588704 */, 16 }, - /* 1482 */ { MAD_F(0x04200888) /* 0.257820635 */, 16 }, - /* 1483 */ { MAD_F(0x0420fbc8) /* 0.258052619 */, 16 }, - /* 1484 */ { MAD_F(0x0421ef17) /* 0.258284654 */, 16 }, - /* 1485 */ { MAD_F(0x0422e273) /* 0.258516742 */, 16 }, - /* 1486 */ { MAD_F(0x0423d5de) /* 0.258748882 */, 16 }, - /* 1487 */ { MAD_F(0x0424c956) /* 0.258981074 */, 16 }, - - /* 1488 */ { MAD_F(0x0425bcdd) /* 0.259213318 */, 16 }, - /* 1489 */ { MAD_F(0x0426b071) /* 0.259445614 */, 16 }, - /* 1490 */ { MAD_F(0x0427a414) /* 0.259677962 */, 16 }, - /* 1491 */ { MAD_F(0x042897c4) /* 0.259910362 */, 16 }, - /* 1492 */ { MAD_F(0x04298b83) /* 0.260142814 */, 16 }, - /* 1493 */ { MAD_F(0x042a7f4f) /* 0.260375318 */, 16 }, - /* 1494 */ { MAD_F(0x042b7329) /* 0.260607874 */, 16 }, - /* 1495 */ { MAD_F(0x042c6711) /* 0.260840481 */, 16 }, - /* 1496 */ { MAD_F(0x042d5b07) /* 0.261073141 */, 16 }, - /* 1497 */ { MAD_F(0x042e4f0b) /* 0.261305852 */, 16 }, - /* 1498 */ { MAD_F(0x042f431d) /* 0.261538616 */, 16 }, - /* 1499 */ { MAD_F(0x0430373d) /* 0.261771431 */, 16 }, - /* 1500 */ { MAD_F(0x04312b6b) /* 0.262004297 */, 16 }, - /* 1501 */ { MAD_F(0x04321fa6) /* 0.262237216 */, 16 }, - /* 1502 */ { MAD_F(0x043313f0) /* 0.262470186 */, 16 }, - /* 1503 */ { MAD_F(0x04340847) /* 0.262703208 */, 16 }, - - /* 1504 */ { MAD_F(0x0434fcad) /* 0.262936282 */, 16 }, - /* 1505 */ { MAD_F(0x0435f120) /* 0.263169407 */, 16 }, - /* 1506 */ { MAD_F(0x0436e5a1) /* 0.263402584 */, 16 }, - /* 1507 */ { MAD_F(0x0437da2f) /* 0.263635813 */, 16 }, - /* 1508 */ { MAD_F(0x0438cecc) /* 0.263869093 */, 16 }, - /* 1509 */ { MAD_F(0x0439c377) /* 0.264102425 */, 16 }, - /* 1510 */ { MAD_F(0x043ab82f) /* 0.264335808 */, 16 }, - /* 1511 */ { MAD_F(0x043bacf5) /* 0.264569243 */, 16 }, - /* 1512 */ { MAD_F(0x043ca1c9) /* 0.264802730 */, 16 }, - /* 1513 */ { MAD_F(0x043d96ab) /* 0.265036267 */, 16 }, - /* 1514 */ { MAD_F(0x043e8b9b) /* 0.265269857 */, 16 }, - /* 1515 */ { MAD_F(0x043f8098) /* 0.265503498 */, 16 }, - /* 1516 */ { MAD_F(0x044075a3) /* 0.265737190 */, 16 }, - /* 1517 */ { MAD_F(0x04416abc) /* 0.265970933 */, 16 }, - /* 1518 */ { MAD_F(0x04425fe3) /* 0.266204728 */, 16 }, - /* 1519 */ { MAD_F(0x04435518) /* 0.266438574 */, 16 }, - - /* 1520 */ { MAD_F(0x04444a5a) /* 0.266672472 */, 16 }, - /* 1521 */ { MAD_F(0x04453fab) /* 0.266906421 */, 16 }, - /* 1522 */ { MAD_F(0x04463508) /* 0.267140421 */, 16 }, - /* 1523 */ { MAD_F(0x04472a74) /* 0.267374472 */, 16 }, - /* 1524 */ { MAD_F(0x04481fee) /* 0.267608575 */, 16 }, - /* 1525 */ { MAD_F(0x04491575) /* 0.267842729 */, 16 }, - /* 1526 */ { MAD_F(0x044a0b0a) /* 0.268076934 */, 16 }, - /* 1527 */ { MAD_F(0x044b00ac) /* 0.268311190 */, 16 }, - /* 1528 */ { MAD_F(0x044bf65d) /* 0.268545497 */, 16 }, - /* 1529 */ { MAD_F(0x044cec1b) /* 0.268779856 */, 16 }, - /* 1530 */ { MAD_F(0x044de1e7) /* 0.269014265 */, 16 }, - /* 1531 */ { MAD_F(0x044ed7c0) /* 0.269248726 */, 16 }, - /* 1532 */ { MAD_F(0x044fcda8) /* 0.269483238 */, 16 }, - /* 1533 */ { MAD_F(0x0450c39c) /* 0.269717800 */, 16 }, - /* 1534 */ { MAD_F(0x0451b99f) /* 0.269952414 */, 16 }, - /* 1535 */ { MAD_F(0x0452afaf) /* 0.270187079 */, 16 }, - - /* 1536 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 16 }, - /* 1537 */ { MAD_F(0x04549bf9) /* 0.270656561 */, 16 }, - /* 1538 */ { MAD_F(0x04559232) /* 0.270891379 */, 16 }, - /* 1539 */ { MAD_F(0x04568879) /* 0.271126247 */, 16 }, - /* 1540 */ { MAD_F(0x04577ece) /* 0.271361166 */, 16 }, - /* 1541 */ { MAD_F(0x04587530) /* 0.271596136 */, 16 }, - /* 1542 */ { MAD_F(0x04596ba0) /* 0.271831157 */, 16 }, - /* 1543 */ { MAD_F(0x045a621e) /* 0.272066229 */, 16 }, - /* 1544 */ { MAD_F(0x045b58a9) /* 0.272301352 */, 16 }, - /* 1545 */ { MAD_F(0x045c4f42) /* 0.272536525 */, 16 }, - /* 1546 */ { MAD_F(0x045d45e9) /* 0.272771749 */, 16 }, - /* 1547 */ { MAD_F(0x045e3c9d) /* 0.273007024 */, 16 }, - /* 1548 */ { MAD_F(0x045f335e) /* 0.273242350 */, 16 }, - /* 1549 */ { MAD_F(0x04602a2e) /* 0.273477726 */, 16 }, - /* 1550 */ { MAD_F(0x0461210b) /* 0.273713153 */, 16 }, - /* 1551 */ { MAD_F(0x046217f5) /* 0.273948630 */, 16 }, - - /* 1552 */ { MAD_F(0x04630eed) /* 0.274184158 */, 16 }, - /* 1553 */ { MAD_F(0x046405f3) /* 0.274419737 */, 16 }, - /* 1554 */ { MAD_F(0x0464fd06) /* 0.274655366 */, 16 }, - /* 1555 */ { MAD_F(0x0465f427) /* 0.274891046 */, 16 }, - /* 1556 */ { MAD_F(0x0466eb55) /* 0.275126776 */, 16 }, - /* 1557 */ { MAD_F(0x0467e291) /* 0.275362557 */, 16 }, - /* 1558 */ { MAD_F(0x0468d9db) /* 0.275598389 */, 16 }, - /* 1559 */ { MAD_F(0x0469d132) /* 0.275834270 */, 16 }, - /* 1560 */ { MAD_F(0x046ac896) /* 0.276070203 */, 16 }, - /* 1561 */ { MAD_F(0x046bc009) /* 0.276306185 */, 16 }, - /* 1562 */ { MAD_F(0x046cb788) /* 0.276542218 */, 16 }, - /* 1563 */ { MAD_F(0x046daf15) /* 0.276778302 */, 16 }, - /* 1564 */ { MAD_F(0x046ea6b0) /* 0.277014435 */, 16 }, - /* 1565 */ { MAD_F(0x046f9e58) /* 0.277250619 */, 16 }, - /* 1566 */ { MAD_F(0x0470960e) /* 0.277486854 */, 16 }, - /* 1567 */ { MAD_F(0x04718dd1) /* 0.277723139 */, 16 }, - - /* 1568 */ { MAD_F(0x047285a2) /* 0.277959474 */, 16 }, - /* 1569 */ { MAD_F(0x04737d80) /* 0.278195859 */, 16 }, - /* 1570 */ { MAD_F(0x0474756c) /* 0.278432294 */, 16 }, - /* 1571 */ { MAD_F(0x04756d65) /* 0.278668780 */, 16 }, - /* 1572 */ { MAD_F(0x0476656b) /* 0.278905316 */, 16 }, - /* 1573 */ { MAD_F(0x04775d7f) /* 0.279141902 */, 16 }, - /* 1574 */ { MAD_F(0x047855a1) /* 0.279378538 */, 16 }, - /* 1575 */ { MAD_F(0x04794dd0) /* 0.279615224 */, 16 }, - /* 1576 */ { MAD_F(0x047a460c) /* 0.279851960 */, 16 }, - /* 1577 */ { MAD_F(0x047b3e56) /* 0.280088747 */, 16 }, - /* 1578 */ { MAD_F(0x047c36ae) /* 0.280325583 */, 16 }, - /* 1579 */ { MAD_F(0x047d2f12) /* 0.280562470 */, 16 }, - /* 1580 */ { MAD_F(0x047e2784) /* 0.280799406 */, 16 }, - /* 1581 */ { MAD_F(0x047f2004) /* 0.281036393 */, 16 }, - /* 1582 */ { MAD_F(0x04801891) /* 0.281273429 */, 16 }, - /* 1583 */ { MAD_F(0x0481112b) /* 0.281510516 */, 16 }, - - /* 1584 */ { MAD_F(0x048209d3) /* 0.281747652 */, 16 }, - /* 1585 */ { MAD_F(0x04830288) /* 0.281984838 */, 16 }, - /* 1586 */ { MAD_F(0x0483fb4b) /* 0.282222075 */, 16 }, - /* 1587 */ { MAD_F(0x0484f41b) /* 0.282459361 */, 16 }, - /* 1588 */ { MAD_F(0x0485ecf8) /* 0.282696697 */, 16 }, - /* 1589 */ { MAD_F(0x0486e5e3) /* 0.282934082 */, 16 }, - /* 1590 */ { MAD_F(0x0487dedb) /* 0.283171518 */, 16 }, - /* 1591 */ { MAD_F(0x0488d7e1) /* 0.283409003 */, 16 }, - /* 1592 */ { MAD_F(0x0489d0f4) /* 0.283646538 */, 16 }, - /* 1593 */ { MAD_F(0x048aca14) /* 0.283884123 */, 16 }, - /* 1594 */ { MAD_F(0x048bc341) /* 0.284121757 */, 16 }, - /* 1595 */ { MAD_F(0x048cbc7c) /* 0.284359441 */, 16 }, - /* 1596 */ { MAD_F(0x048db5c4) /* 0.284597175 */, 16 }, - /* 1597 */ { MAD_F(0x048eaf1a) /* 0.284834959 */, 16 }, - /* 1598 */ { MAD_F(0x048fa87d) /* 0.285072792 */, 16 }, - /* 1599 */ { MAD_F(0x0490a1ed) /* 0.285310675 */, 16 }, - - /* 1600 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 16 }, - /* 1601 */ { MAD_F(0x049294f5) /* 0.285786589 */, 16 }, - /* 1602 */ { MAD_F(0x04938e8d) /* 0.286024621 */, 16 }, - /* 1603 */ { MAD_F(0x04948833) /* 0.286262702 */, 16 }, - /* 1604 */ { MAD_F(0x049581e5) /* 0.286500832 */, 16 }, - /* 1605 */ { MAD_F(0x04967ba5) /* 0.286739012 */, 16 }, - /* 1606 */ { MAD_F(0x04977573) /* 0.286977242 */, 16 }, - /* 1607 */ { MAD_F(0x04986f4d) /* 0.287215521 */, 16 }, - /* 1608 */ { MAD_F(0x04996935) /* 0.287453849 */, 16 }, - /* 1609 */ { MAD_F(0x049a632a) /* 0.287692227 */, 16 }, - /* 1610 */ { MAD_F(0x049b5d2c) /* 0.287930654 */, 16 }, - /* 1611 */ { MAD_F(0x049c573c) /* 0.288169131 */, 16 }, - /* 1612 */ { MAD_F(0x049d5159) /* 0.288407657 */, 16 }, - /* 1613 */ { MAD_F(0x049e4b83) /* 0.288646232 */, 16 }, - /* 1614 */ { MAD_F(0x049f45ba) /* 0.288884857 */, 16 }, - /* 1615 */ { MAD_F(0x04a03ffe) /* 0.289123530 */, 16 }, - - /* 1616 */ { MAD_F(0x04a13a50) /* 0.289362253 */, 16 }, - /* 1617 */ { MAD_F(0x04a234af) /* 0.289601026 */, 16 }, - /* 1618 */ { MAD_F(0x04a32f1b) /* 0.289839847 */, 16 }, - /* 1619 */ { MAD_F(0x04a42995) /* 0.290078718 */, 16 }, - /* 1620 */ { MAD_F(0x04a5241b) /* 0.290317638 */, 16 }, - /* 1621 */ { MAD_F(0x04a61eaf) /* 0.290556607 */, 16 }, - /* 1622 */ { MAD_F(0x04a71950) /* 0.290795626 */, 16 }, - /* 1623 */ { MAD_F(0x04a813fe) /* 0.291034693 */, 16 }, - /* 1624 */ { MAD_F(0x04a90eba) /* 0.291273810 */, 16 }, - /* 1625 */ { MAD_F(0x04aa0982) /* 0.291512975 */, 16 }, - /* 1626 */ { MAD_F(0x04ab0458) /* 0.291752190 */, 16 }, - /* 1627 */ { MAD_F(0x04abff3b) /* 0.291991453 */, 16 }, - /* 1628 */ { MAD_F(0x04acfa2b) /* 0.292230766 */, 16 }, - /* 1629 */ { MAD_F(0x04adf528) /* 0.292470128 */, 16 }, - /* 1630 */ { MAD_F(0x04aef032) /* 0.292709539 */, 16 }, - /* 1631 */ { MAD_F(0x04afeb4a) /* 0.292948998 */, 16 }, - - /* 1632 */ { MAD_F(0x04b0e66e) /* 0.293188507 */, 16 }, - /* 1633 */ { MAD_F(0x04b1e1a0) /* 0.293428065 */, 16 }, - /* 1634 */ { MAD_F(0x04b2dcdf) /* 0.293667671 */, 16 }, - /* 1635 */ { MAD_F(0x04b3d82b) /* 0.293907326 */, 16 }, - /* 1636 */ { MAD_F(0x04b4d384) /* 0.294147031 */, 16 }, - /* 1637 */ { MAD_F(0x04b5ceea) /* 0.294386784 */, 16 }, - /* 1638 */ { MAD_F(0x04b6ca5e) /* 0.294626585 */, 16 }, - /* 1639 */ { MAD_F(0x04b7c5de) /* 0.294866436 */, 16 }, - /* 1640 */ { MAD_F(0x04b8c16c) /* 0.295106336 */, 16 }, - /* 1641 */ { MAD_F(0x04b9bd06) /* 0.295346284 */, 16 }, - /* 1642 */ { MAD_F(0x04bab8ae) /* 0.295586281 */, 16 }, - /* 1643 */ { MAD_F(0x04bbb463) /* 0.295826327 */, 16 }, - /* 1644 */ { MAD_F(0x04bcb024) /* 0.296066421 */, 16 }, - /* 1645 */ { MAD_F(0x04bdabf3) /* 0.296306564 */, 16 }, - /* 1646 */ { MAD_F(0x04bea7cf) /* 0.296546756 */, 16 }, - /* 1647 */ { MAD_F(0x04bfa3b8) /* 0.296786996 */, 16 }, - - /* 1648 */ { MAD_F(0x04c09faf) /* 0.297027285 */, 16 }, - /* 1649 */ { MAD_F(0x04c19bb2) /* 0.297267623 */, 16 }, - /* 1650 */ { MAD_F(0x04c297c2) /* 0.297508009 */, 16 }, - /* 1651 */ { MAD_F(0x04c393df) /* 0.297748444 */, 16 }, - /* 1652 */ { MAD_F(0x04c49009) /* 0.297988927 */, 16 }, - /* 1653 */ { MAD_F(0x04c58c41) /* 0.298229459 */, 16 }, - /* 1654 */ { MAD_F(0x04c68885) /* 0.298470039 */, 16 }, - /* 1655 */ { MAD_F(0x04c784d6) /* 0.298710668 */, 16 }, - /* 1656 */ { MAD_F(0x04c88135) /* 0.298951346 */, 16 }, - /* 1657 */ { MAD_F(0x04c97da0) /* 0.299192071 */, 16 }, - /* 1658 */ { MAD_F(0x04ca7a18) /* 0.299432846 */, 16 }, - /* 1659 */ { MAD_F(0x04cb769e) /* 0.299673668 */, 16 }, - /* 1660 */ { MAD_F(0x04cc7330) /* 0.299914539 */, 16 }, - /* 1661 */ { MAD_F(0x04cd6fcf) /* 0.300155459 */, 16 }, - /* 1662 */ { MAD_F(0x04ce6c7b) /* 0.300396426 */, 16 }, - /* 1663 */ { MAD_F(0x04cf6935) /* 0.300637443 */, 16 }, - - /* 1664 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 16 }, - /* 1665 */ { MAD_F(0x04d162ce) /* 0.301119620 */, 16 }, - /* 1666 */ { MAD_F(0x04d25fae) /* 0.301360781 */, 16 }, - /* 1667 */ { MAD_F(0x04d35c9b) /* 0.301601990 */, 16 }, - /* 1668 */ { MAD_F(0x04d45995) /* 0.301843247 */, 16 }, - /* 1669 */ { MAD_F(0x04d5569c) /* 0.302084553 */, 16 }, - /* 1670 */ { MAD_F(0x04d653b0) /* 0.302325907 */, 16 }, - /* 1671 */ { MAD_F(0x04d750d1) /* 0.302567309 */, 16 }, - /* 1672 */ { MAD_F(0x04d84dff) /* 0.302808759 */, 16 }, - /* 1673 */ { MAD_F(0x04d94b3a) /* 0.303050257 */, 16 }, - /* 1674 */ { MAD_F(0x04da4881) /* 0.303291804 */, 16 }, - /* 1675 */ { MAD_F(0x04db45d6) /* 0.303533399 */, 16 }, - /* 1676 */ { MAD_F(0x04dc4337) /* 0.303775041 */, 16 }, - /* 1677 */ { MAD_F(0x04dd40a6) /* 0.304016732 */, 16 }, - /* 1678 */ { MAD_F(0x04de3e21) /* 0.304258471 */, 16 }, - /* 1679 */ { MAD_F(0x04df3ba9) /* 0.304500257 */, 16 }, - - /* 1680 */ { MAD_F(0x04e0393e) /* 0.304742092 */, 16 }, - /* 1681 */ { MAD_F(0x04e136e0) /* 0.304983975 */, 16 }, - /* 1682 */ { MAD_F(0x04e2348f) /* 0.305225906 */, 16 }, - /* 1683 */ { MAD_F(0x04e3324b) /* 0.305467885 */, 16 }, - /* 1684 */ { MAD_F(0x04e43013) /* 0.305709911 */, 16 }, - /* 1685 */ { MAD_F(0x04e52de9) /* 0.305951986 */, 16 }, - /* 1686 */ { MAD_F(0x04e62bcb) /* 0.306194108 */, 16 }, - /* 1687 */ { MAD_F(0x04e729ba) /* 0.306436279 */, 16 }, - /* 1688 */ { MAD_F(0x04e827b6) /* 0.306678497 */, 16 }, - /* 1689 */ { MAD_F(0x04e925bf) /* 0.306920763 */, 16 }, - /* 1690 */ { MAD_F(0x04ea23d4) /* 0.307163077 */, 16 }, - /* 1691 */ { MAD_F(0x04eb21f7) /* 0.307405438 */, 16 }, - /* 1692 */ { MAD_F(0x04ec2026) /* 0.307647848 */, 16 }, - /* 1693 */ { MAD_F(0x04ed1e62) /* 0.307890305 */, 16 }, - /* 1694 */ { MAD_F(0x04ee1cab) /* 0.308132810 */, 16 }, - /* 1695 */ { MAD_F(0x04ef1b01) /* 0.308375362 */, 16 }, - - /* 1696 */ { MAD_F(0x04f01963) /* 0.308617963 */, 16 }, - /* 1697 */ { MAD_F(0x04f117d3) /* 0.308860611 */, 16 }, - /* 1698 */ { MAD_F(0x04f2164f) /* 0.309103306 */, 16 }, - /* 1699 */ { MAD_F(0x04f314d8) /* 0.309346050 */, 16 }, - /* 1700 */ { MAD_F(0x04f4136d) /* 0.309588841 */, 16 }, - /* 1701 */ { MAD_F(0x04f51210) /* 0.309831679 */, 16 }, - /* 1702 */ { MAD_F(0x04f610bf) /* 0.310074565 */, 16 }, - /* 1703 */ { MAD_F(0x04f70f7b) /* 0.310317499 */, 16 }, - /* 1704 */ { MAD_F(0x04f80e44) /* 0.310560480 */, 16 }, - /* 1705 */ { MAD_F(0x04f90d19) /* 0.310803509 */, 16 }, - /* 1706 */ { MAD_F(0x04fa0bfc) /* 0.311046586 */, 16 }, - /* 1707 */ { MAD_F(0x04fb0aeb) /* 0.311289710 */, 16 }, - /* 1708 */ { MAD_F(0x04fc09e7) /* 0.311532881 */, 16 }, - /* 1709 */ { MAD_F(0x04fd08ef) /* 0.311776100 */, 16 }, - /* 1710 */ { MAD_F(0x04fe0805) /* 0.312019366 */, 16 }, - /* 1711 */ { MAD_F(0x04ff0727) /* 0.312262680 */, 16 }, - - /* 1712 */ { MAD_F(0x05000655) /* 0.312506041 */, 16 }, - /* 1713 */ { MAD_F(0x05010591) /* 0.312749449 */, 16 }, - /* 1714 */ { MAD_F(0x050204d9) /* 0.312992905 */, 16 }, - /* 1715 */ { MAD_F(0x0503042e) /* 0.313236408 */, 16 }, - /* 1716 */ { MAD_F(0x0504038f) /* 0.313479959 */, 16 }, - /* 1717 */ { MAD_F(0x050502fe) /* 0.313723556 */, 16 }, - /* 1718 */ { MAD_F(0x05060279) /* 0.313967202 */, 16 }, - /* 1719 */ { MAD_F(0x05070200) /* 0.314210894 */, 16 }, - /* 1720 */ { MAD_F(0x05080195) /* 0.314454634 */, 16 }, - /* 1721 */ { MAD_F(0x05090136) /* 0.314698420 */, 16 }, - /* 1722 */ { MAD_F(0x050a00e3) /* 0.314942255 */, 16 }, - /* 1723 */ { MAD_F(0x050b009e) /* 0.315186136 */, 16 }, - /* 1724 */ { MAD_F(0x050c0065) /* 0.315430064 */, 16 }, - /* 1725 */ { MAD_F(0x050d0039) /* 0.315674040 */, 16 }, - /* 1726 */ { MAD_F(0x050e0019) /* 0.315918063 */, 16 }, - /* 1727 */ { MAD_F(0x050f0006) /* 0.316162133 */, 16 }, - - /* 1728 */ { MAD_F(0x05100000) /* 0.316406250 */, 16 }, - /* 1729 */ { MAD_F(0x05110006) /* 0.316650414 */, 16 }, - /* 1730 */ { MAD_F(0x05120019) /* 0.316894625 */, 16 }, - /* 1731 */ { MAD_F(0x05130039) /* 0.317138884 */, 16 }, - /* 1732 */ { MAD_F(0x05140065) /* 0.317383189 */, 16 }, - /* 1733 */ { MAD_F(0x0515009e) /* 0.317627541 */, 16 }, - /* 1734 */ { MAD_F(0x051600e3) /* 0.317871941 */, 16 }, - /* 1735 */ { MAD_F(0x05170135) /* 0.318116387 */, 16 }, - /* 1736 */ { MAD_F(0x05180194) /* 0.318360880 */, 16 }, - /* 1737 */ { MAD_F(0x051901ff) /* 0.318605421 */, 16 }, - /* 1738 */ { MAD_F(0x051a0277) /* 0.318850008 */, 16 }, - /* 1739 */ { MAD_F(0x051b02fc) /* 0.319094642 */, 16 }, - /* 1740 */ { MAD_F(0x051c038d) /* 0.319339323 */, 16 }, - /* 1741 */ { MAD_F(0x051d042a) /* 0.319584051 */, 16 }, - /* 1742 */ { MAD_F(0x051e04d4) /* 0.319828826 */, 16 }, - /* 1743 */ { MAD_F(0x051f058b) /* 0.320073647 */, 16 }, - - /* 1744 */ { MAD_F(0x0520064f) /* 0.320318516 */, 16 }, - /* 1745 */ { MAD_F(0x0521071f) /* 0.320563431 */, 16 }, - /* 1746 */ { MAD_F(0x052207fb) /* 0.320808393 */, 16 }, - /* 1747 */ { MAD_F(0x052308e4) /* 0.321053402 */, 16 }, - /* 1748 */ { MAD_F(0x052409da) /* 0.321298457 */, 16 }, - /* 1749 */ { MAD_F(0x05250adc) /* 0.321543560 */, 16 }, - /* 1750 */ { MAD_F(0x05260bea) /* 0.321788709 */, 16 }, - /* 1751 */ { MAD_F(0x05270d06) /* 0.322033904 */, 16 }, - /* 1752 */ { MAD_F(0x05280e2d) /* 0.322279147 */, 16 }, - /* 1753 */ { MAD_F(0x05290f62) /* 0.322524436 */, 16 }, - /* 1754 */ { MAD_F(0x052a10a3) /* 0.322769771 */, 16 }, - /* 1755 */ { MAD_F(0x052b11f0) /* 0.323015154 */, 16 }, - /* 1756 */ { MAD_F(0x052c134a) /* 0.323260583 */, 16 }, - /* 1757 */ { MAD_F(0x052d14b0) /* 0.323506058 */, 16 }, - /* 1758 */ { MAD_F(0x052e1623) /* 0.323751580 */, 16 }, - /* 1759 */ { MAD_F(0x052f17a2) /* 0.323997149 */, 16 }, - - /* 1760 */ { MAD_F(0x0530192e) /* 0.324242764 */, 16 }, - /* 1761 */ { MAD_F(0x05311ac6) /* 0.324488426 */, 16 }, - /* 1762 */ { MAD_F(0x05321c6b) /* 0.324734134 */, 16 }, - /* 1763 */ { MAD_F(0x05331e1c) /* 0.324979889 */, 16 }, - /* 1764 */ { MAD_F(0x05341fda) /* 0.325225690 */, 16 }, - /* 1765 */ { MAD_F(0x053521a4) /* 0.325471538 */, 16 }, - /* 1766 */ { MAD_F(0x0536237b) /* 0.325717432 */, 16 }, - /* 1767 */ { MAD_F(0x0537255e) /* 0.325963372 */, 16 }, - /* 1768 */ { MAD_F(0x0538274e) /* 0.326209359 */, 16 }, - /* 1769 */ { MAD_F(0x0539294a) /* 0.326455392 */, 16 }, - /* 1770 */ { MAD_F(0x053a2b52) /* 0.326701472 */, 16 }, - /* 1771 */ { MAD_F(0x053b2d67) /* 0.326947598 */, 16 }, - /* 1772 */ { MAD_F(0x053c2f89) /* 0.327193770 */, 16 }, - /* 1773 */ { MAD_F(0x053d31b6) /* 0.327439989 */, 16 }, - /* 1774 */ { MAD_F(0x053e33f1) /* 0.327686254 */, 16 }, - /* 1775 */ { MAD_F(0x053f3637) /* 0.327932565 */, 16 }, - - /* 1776 */ { MAD_F(0x0540388a) /* 0.328178922 */, 16 }, - /* 1777 */ { MAD_F(0x05413aea) /* 0.328425326 */, 16 }, - /* 1778 */ { MAD_F(0x05423d56) /* 0.328671776 */, 16 }, - /* 1779 */ { MAD_F(0x05433fce) /* 0.328918272 */, 16 }, - /* 1780 */ { MAD_F(0x05444253) /* 0.329164814 */, 16 }, - /* 1781 */ { MAD_F(0x054544e4) /* 0.329411403 */, 16 }, - /* 1782 */ { MAD_F(0x05464781) /* 0.329658038 */, 16 }, - /* 1783 */ { MAD_F(0x05474a2b) /* 0.329904718 */, 16 }, - /* 1784 */ { MAD_F(0x05484ce2) /* 0.330151445 */, 16 }, - /* 1785 */ { MAD_F(0x05494fa4) /* 0.330398218 */, 16 }, - /* 1786 */ { MAD_F(0x054a5273) /* 0.330645037 */, 16 }, - /* 1787 */ { MAD_F(0x054b554e) /* 0.330891903 */, 16 }, - /* 1788 */ { MAD_F(0x054c5836) /* 0.331138814 */, 16 }, - /* 1789 */ { MAD_F(0x054d5b2a) /* 0.331385771 */, 16 }, - /* 1790 */ { MAD_F(0x054e5e2b) /* 0.331632774 */, 16 }, - /* 1791 */ { MAD_F(0x054f6138) /* 0.331879824 */, 16 }, - - /* 1792 */ { MAD_F(0x05506451) /* 0.332126919 */, 16 }, - /* 1793 */ { MAD_F(0x05516776) /* 0.332374060 */, 16 }, - /* 1794 */ { MAD_F(0x05526aa8) /* 0.332621247 */, 16 }, - /* 1795 */ { MAD_F(0x05536de6) /* 0.332868480 */, 16 }, - /* 1796 */ { MAD_F(0x05547131) /* 0.333115759 */, 16 }, - /* 1797 */ { MAD_F(0x05557487) /* 0.333363084 */, 16 }, - /* 1798 */ { MAD_F(0x055677ea) /* 0.333610455 */, 16 }, - /* 1799 */ { MAD_F(0x05577b5a) /* 0.333857872 */, 16 }, - /* 1800 */ { MAD_F(0x05587ed5) /* 0.334105334 */, 16 }, - /* 1801 */ { MAD_F(0x0559825e) /* 0.334352843 */, 16 }, - /* 1802 */ { MAD_F(0x055a85f2) /* 0.334600397 */, 16 }, - /* 1803 */ { MAD_F(0x055b8992) /* 0.334847997 */, 16 }, - /* 1804 */ { MAD_F(0x055c8d3f) /* 0.335095642 */, 16 }, - /* 1805 */ { MAD_F(0x055d90f9) /* 0.335343334 */, 16 }, - /* 1806 */ { MAD_F(0x055e94be) /* 0.335591071 */, 16 }, - /* 1807 */ { MAD_F(0x055f9890) /* 0.335838854 */, 16 }, - - /* 1808 */ { MAD_F(0x05609c6e) /* 0.336086683 */, 16 }, - /* 1809 */ { MAD_F(0x0561a058) /* 0.336334557 */, 16 }, - /* 1810 */ { MAD_F(0x0562a44f) /* 0.336582477 */, 16 }, - /* 1811 */ { MAD_F(0x0563a851) /* 0.336830443 */, 16 }, - /* 1812 */ { MAD_F(0x0564ac60) /* 0.337078454 */, 16 }, - /* 1813 */ { MAD_F(0x0565b07c) /* 0.337326511 */, 16 }, - /* 1814 */ { MAD_F(0x0566b4a3) /* 0.337574614 */, 16 }, - /* 1815 */ { MAD_F(0x0567b8d7) /* 0.337822762 */, 16 }, - /* 1816 */ { MAD_F(0x0568bd17) /* 0.338070956 */, 16 }, - /* 1817 */ { MAD_F(0x0569c163) /* 0.338319195 */, 16 }, - /* 1818 */ { MAD_F(0x056ac5bc) /* 0.338567480 */, 16 }, - /* 1819 */ { MAD_F(0x056bca20) /* 0.338815811 */, 16 }, - /* 1820 */ { MAD_F(0x056cce91) /* 0.339064186 */, 16 }, - /* 1821 */ { MAD_F(0x056dd30e) /* 0.339312608 */, 16 }, - /* 1822 */ { MAD_F(0x056ed798) /* 0.339561075 */, 16 }, - /* 1823 */ { MAD_F(0x056fdc2d) /* 0.339809587 */, 16 }, - - /* 1824 */ { MAD_F(0x0570e0cf) /* 0.340058145 */, 16 }, - /* 1825 */ { MAD_F(0x0571e57d) /* 0.340306748 */, 16 }, - /* 1826 */ { MAD_F(0x0572ea37) /* 0.340555397 */, 16 }, - /* 1827 */ { MAD_F(0x0573eefd) /* 0.340804091 */, 16 }, - /* 1828 */ { MAD_F(0x0574f3d0) /* 0.341052830 */, 16 }, - /* 1829 */ { MAD_F(0x0575f8ae) /* 0.341301615 */, 16 }, - /* 1830 */ { MAD_F(0x0576fd99) /* 0.341550445 */, 16 }, - /* 1831 */ { MAD_F(0x05780290) /* 0.341799321 */, 16 }, - /* 1832 */ { MAD_F(0x05790793) /* 0.342048241 */, 16 }, - /* 1833 */ { MAD_F(0x057a0ca3) /* 0.342297207 */, 16 }, - /* 1834 */ { MAD_F(0x057b11be) /* 0.342546219 */, 16 }, - /* 1835 */ { MAD_F(0x057c16e6) /* 0.342795275 */, 16 }, - /* 1836 */ { MAD_F(0x057d1c1a) /* 0.343044377 */, 16 }, - /* 1837 */ { MAD_F(0x057e2159) /* 0.343293524 */, 16 }, - /* 1838 */ { MAD_F(0x057f26a6) /* 0.343542717 */, 16 }, - /* 1839 */ { MAD_F(0x05802bfe) /* 0.343791954 */, 16 }, - - /* 1840 */ { MAD_F(0x05813162) /* 0.344041237 */, 16 }, - /* 1841 */ { MAD_F(0x058236d2) /* 0.344290564 */, 16 }, - /* 1842 */ { MAD_F(0x05833c4f) /* 0.344539937 */, 16 }, - /* 1843 */ { MAD_F(0x058441d8) /* 0.344789356 */, 16 }, - /* 1844 */ { MAD_F(0x0585476c) /* 0.345038819 */, 16 }, - /* 1845 */ { MAD_F(0x05864d0d) /* 0.345288327 */, 16 }, - /* 1846 */ { MAD_F(0x058752ba) /* 0.345537880 */, 16 }, - /* 1847 */ { MAD_F(0x05885873) /* 0.345787479 */, 16 }, - /* 1848 */ { MAD_F(0x05895e39) /* 0.346037122 */, 16 }, - /* 1849 */ { MAD_F(0x058a640a) /* 0.346286811 */, 16 }, - /* 1850 */ { MAD_F(0x058b69e7) /* 0.346536545 */, 16 }, - /* 1851 */ { MAD_F(0x058c6fd1) /* 0.346786323 */, 16 }, - /* 1852 */ { MAD_F(0x058d75c6) /* 0.347036147 */, 16 }, - /* 1853 */ { MAD_F(0x058e7bc8) /* 0.347286015 */, 16 }, - /* 1854 */ { MAD_F(0x058f81d5) /* 0.347535929 */, 16 }, - /* 1855 */ { MAD_F(0x059087ef) /* 0.347785887 */, 16 }, - - /* 1856 */ { MAD_F(0x05918e15) /* 0.348035890 */, 16 }, - /* 1857 */ { MAD_F(0x05929447) /* 0.348285939 */, 16 }, - /* 1858 */ { MAD_F(0x05939a84) /* 0.348536032 */, 16 }, - /* 1859 */ { MAD_F(0x0594a0ce) /* 0.348786170 */, 16 }, - /* 1860 */ { MAD_F(0x0595a724) /* 0.349036353 */, 16 }, - /* 1861 */ { MAD_F(0x0596ad86) /* 0.349286580 */, 16 }, - /* 1862 */ { MAD_F(0x0597b3f4) /* 0.349536853 */, 16 }, - /* 1863 */ { MAD_F(0x0598ba6e) /* 0.349787170 */, 16 }, - /* 1864 */ { MAD_F(0x0599c0f4) /* 0.350037532 */, 16 }, - /* 1865 */ { MAD_F(0x059ac786) /* 0.350287939 */, 16 }, - /* 1866 */ { MAD_F(0x059bce25) /* 0.350538391 */, 16 }, - /* 1867 */ { MAD_F(0x059cd4cf) /* 0.350788887 */, 16 }, - /* 1868 */ { MAD_F(0x059ddb85) /* 0.351039428 */, 16 }, - /* 1869 */ { MAD_F(0x059ee247) /* 0.351290014 */, 16 }, - /* 1870 */ { MAD_F(0x059fe915) /* 0.351540645 */, 16 }, - /* 1871 */ { MAD_F(0x05a0efef) /* 0.351791320 */, 16 }, - - /* 1872 */ { MAD_F(0x05a1f6d5) /* 0.352042040 */, 16 }, - /* 1873 */ { MAD_F(0x05a2fdc7) /* 0.352292804 */, 16 }, - /* 1874 */ { MAD_F(0x05a404c5) /* 0.352543613 */, 16 }, - /* 1875 */ { MAD_F(0x05a50bcf) /* 0.352794467 */, 16 }, - /* 1876 */ { MAD_F(0x05a612e5) /* 0.353045365 */, 16 }, - /* 1877 */ { MAD_F(0x05a71a07) /* 0.353296308 */, 16 }, - /* 1878 */ { MAD_F(0x05a82135) /* 0.353547296 */, 16 }, - /* 1879 */ { MAD_F(0x05a9286f) /* 0.353798328 */, 16 }, - /* 1880 */ { MAD_F(0x05aa2fb5) /* 0.354049405 */, 16 }, - /* 1881 */ { MAD_F(0x05ab3707) /* 0.354300526 */, 16 }, - /* 1882 */ { MAD_F(0x05ac3e65) /* 0.354551691 */, 16 }, - /* 1883 */ { MAD_F(0x05ad45ce) /* 0.354802901 */, 16 }, - /* 1884 */ { MAD_F(0x05ae4d44) /* 0.355054156 */, 16 }, - /* 1885 */ { MAD_F(0x05af54c6) /* 0.355305455 */, 16 }, - /* 1886 */ { MAD_F(0x05b05c53) /* 0.355556799 */, 16 }, - /* 1887 */ { MAD_F(0x05b163ed) /* 0.355808187 */, 16 }, - - /* 1888 */ { MAD_F(0x05b26b92) /* 0.356059619 */, 16 }, - /* 1889 */ { MAD_F(0x05b37343) /* 0.356311096 */, 16 }, - /* 1890 */ { MAD_F(0x05b47b00) /* 0.356562617 */, 16 }, - /* 1891 */ { MAD_F(0x05b582c9) /* 0.356814182 */, 16 }, - /* 1892 */ { MAD_F(0x05b68a9e) /* 0.357065792 */, 16 }, - /* 1893 */ { MAD_F(0x05b7927f) /* 0.357317446 */, 16 }, - /* 1894 */ { MAD_F(0x05b89a6c) /* 0.357569145 */, 16 }, - /* 1895 */ { MAD_F(0x05b9a265) /* 0.357820887 */, 16 }, - /* 1896 */ { MAD_F(0x05baaa69) /* 0.358072674 */, 16 }, - /* 1897 */ { MAD_F(0x05bbb27a) /* 0.358324506 */, 16 }, - /* 1898 */ { MAD_F(0x05bcba96) /* 0.358576381 */, 16 }, - /* 1899 */ { MAD_F(0x05bdc2be) /* 0.358828301 */, 16 }, - /* 1900 */ { MAD_F(0x05becaf2) /* 0.359080265 */, 16 }, - /* 1901 */ { MAD_F(0x05bfd332) /* 0.359332273 */, 16 }, - /* 1902 */ { MAD_F(0x05c0db7e) /* 0.359584326 */, 16 }, - /* 1903 */ { MAD_F(0x05c1e3d6) /* 0.359836423 */, 16 }, - - /* 1904 */ { MAD_F(0x05c2ec39) /* 0.360088563 */, 16 }, - /* 1905 */ { MAD_F(0x05c3f4a9) /* 0.360340748 */, 16 }, - /* 1906 */ { MAD_F(0x05c4fd24) /* 0.360592977 */, 16 }, - /* 1907 */ { MAD_F(0x05c605ab) /* 0.360845251 */, 16 }, - /* 1908 */ { MAD_F(0x05c70e3e) /* 0.361097568 */, 16 }, - /* 1909 */ { MAD_F(0x05c816dd) /* 0.361349929 */, 16 }, - /* 1910 */ { MAD_F(0x05c91f87) /* 0.361602335 */, 16 }, - /* 1911 */ { MAD_F(0x05ca283e) /* 0.361854784 */, 16 }, - /* 1912 */ { MAD_F(0x05cb3100) /* 0.362107278 */, 16 }, - /* 1913 */ { MAD_F(0x05cc39ce) /* 0.362359815 */, 16 }, - /* 1914 */ { MAD_F(0x05cd42a8) /* 0.362612397 */, 16 }, - /* 1915 */ { MAD_F(0x05ce4b8d) /* 0.362865022 */, 16 }, - /* 1916 */ { MAD_F(0x05cf547f) /* 0.363117692 */, 16 }, - /* 1917 */ { MAD_F(0x05d05d7c) /* 0.363370405 */, 16 }, - /* 1918 */ { MAD_F(0x05d16685) /* 0.363623163 */, 16 }, - /* 1919 */ { MAD_F(0x05d26f9a) /* 0.363875964 */, 16 }, - - /* 1920 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 16 }, - /* 1921 */ { MAD_F(0x05d481e7) /* 0.364381698 */, 16 }, - /* 1922 */ { MAD_F(0x05d58b1f) /* 0.364634632 */, 16 }, - /* 1923 */ { MAD_F(0x05d69463) /* 0.364887608 */, 16 }, - /* 1924 */ { MAD_F(0x05d79db3) /* 0.365140629 */, 16 }, - /* 1925 */ { MAD_F(0x05d8a70f) /* 0.365393694 */, 16 }, - /* 1926 */ { MAD_F(0x05d9b076) /* 0.365646802 */, 16 }, - /* 1927 */ { MAD_F(0x05dab9e9) /* 0.365899955 */, 16 }, - /* 1928 */ { MAD_F(0x05dbc368) /* 0.366153151 */, 16 }, - /* 1929 */ { MAD_F(0x05dcccf2) /* 0.366406390 */, 16 }, - /* 1930 */ { MAD_F(0x05ddd689) /* 0.366659674 */, 16 }, - /* 1931 */ { MAD_F(0x05dee02b) /* 0.366913001 */, 16 }, - /* 1932 */ { MAD_F(0x05dfe9d8) /* 0.367166372 */, 16 }, - /* 1933 */ { MAD_F(0x05e0f392) /* 0.367419787 */, 16 }, - /* 1934 */ { MAD_F(0x05e1fd57) /* 0.367673246 */, 16 }, - /* 1935 */ { MAD_F(0x05e30728) /* 0.367926748 */, 16 }, - - /* 1936 */ { MAD_F(0x05e41105) /* 0.368180294 */, 16 }, - /* 1937 */ { MAD_F(0x05e51aed) /* 0.368433883 */, 16 }, - /* 1938 */ { MAD_F(0x05e624e1) /* 0.368687517 */, 16 }, - /* 1939 */ { MAD_F(0x05e72ee1) /* 0.368941193 */, 16 }, - /* 1940 */ { MAD_F(0x05e838ed) /* 0.369194914 */, 16 }, - /* 1941 */ { MAD_F(0x05e94304) /* 0.369448678 */, 16 }, - /* 1942 */ { MAD_F(0x05ea4d27) /* 0.369702485 */, 16 }, - /* 1943 */ { MAD_F(0x05eb5756) /* 0.369956336 */, 16 }, - /* 1944 */ { MAD_F(0x05ec6190) /* 0.370210231 */, 16 }, - /* 1945 */ { MAD_F(0x05ed6bd6) /* 0.370464169 */, 16 }, - /* 1946 */ { MAD_F(0x05ee7628) /* 0.370718151 */, 16 }, - /* 1947 */ { MAD_F(0x05ef8085) /* 0.370972177 */, 16 }, - /* 1948 */ { MAD_F(0x05f08aee) /* 0.371226245 */, 16 }, - /* 1949 */ { MAD_F(0x05f19563) /* 0.371480358 */, 16 }, - /* 1950 */ { MAD_F(0x05f29fe3) /* 0.371734513 */, 16 }, - /* 1951 */ { MAD_F(0x05f3aa6f) /* 0.371988712 */, 16 }, - - /* 1952 */ { MAD_F(0x05f4b507) /* 0.372242955 */, 16 }, - /* 1953 */ { MAD_F(0x05f5bfab) /* 0.372497241 */, 16 }, - /* 1954 */ { MAD_F(0x05f6ca5a) /* 0.372751570 */, 16 }, - /* 1955 */ { MAD_F(0x05f7d514) /* 0.373005943 */, 16 }, - /* 1956 */ { MAD_F(0x05f8dfdb) /* 0.373260359 */, 16 }, - /* 1957 */ { MAD_F(0x05f9eaad) /* 0.373514819 */, 16 }, - /* 1958 */ { MAD_F(0x05faf58a) /* 0.373769322 */, 16 }, - /* 1959 */ { MAD_F(0x05fc0073) /* 0.374023868 */, 16 }, - /* 1960 */ { MAD_F(0x05fd0b68) /* 0.374278458 */, 16 }, - /* 1961 */ { MAD_F(0x05fe1669) /* 0.374533091 */, 16 }, - /* 1962 */ { MAD_F(0x05ff2175) /* 0.374787767 */, 16 }, - /* 1963 */ { MAD_F(0x06002c8d) /* 0.375042486 */, 16 }, - /* 1964 */ { MAD_F(0x060137b0) /* 0.375297249 */, 16 }, - /* 1965 */ { MAD_F(0x060242df) /* 0.375552055 */, 16 }, - /* 1966 */ { MAD_F(0x06034e19) /* 0.375806904 */, 16 }, - /* 1967 */ { MAD_F(0x0604595f) /* 0.376061796 */, 16 }, - - /* 1968 */ { MAD_F(0x060564b1) /* 0.376316732 */, 16 }, - /* 1969 */ { MAD_F(0x0606700f) /* 0.376571710 */, 16 }, - /* 1970 */ { MAD_F(0x06077b77) /* 0.376826732 */, 16 }, - /* 1971 */ { MAD_F(0x060886ec) /* 0.377081797 */, 16 }, - /* 1972 */ { MAD_F(0x0609926c) /* 0.377336905 */, 16 }, - /* 1973 */ { MAD_F(0x060a9df8) /* 0.377592057 */, 16 }, - /* 1974 */ { MAD_F(0x060ba98f) /* 0.377847251 */, 16 }, - /* 1975 */ { MAD_F(0x060cb532) /* 0.378102489 */, 16 }, - /* 1976 */ { MAD_F(0x060dc0e0) /* 0.378357769 */, 16 }, - /* 1977 */ { MAD_F(0x060ecc9a) /* 0.378613093 */, 16 }, - /* 1978 */ { MAD_F(0x060fd860) /* 0.378868460 */, 16 }, - /* 1979 */ { MAD_F(0x0610e431) /* 0.379123870 */, 16 }, - /* 1980 */ { MAD_F(0x0611f00d) /* 0.379379322 */, 16 }, - /* 1981 */ { MAD_F(0x0612fbf5) /* 0.379634818 */, 16 }, - /* 1982 */ { MAD_F(0x061407e9) /* 0.379890357 */, 16 }, - /* 1983 */ { MAD_F(0x061513e8) /* 0.380145939 */, 16 }, - - /* 1984 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 16 }, - /* 1985 */ { MAD_F(0x06172c09) /* 0.380657231 */, 16 }, - /* 1986 */ { MAD_F(0x0618382b) /* 0.380912942 */, 16 }, - /* 1987 */ { MAD_F(0x06194458) /* 0.381168695 */, 16 }, - /* 1988 */ { MAD_F(0x061a5091) /* 0.381424492 */, 16 }, - /* 1989 */ { MAD_F(0x061b5cd5) /* 0.381680331 */, 16 }, - /* 1990 */ { MAD_F(0x061c6925) /* 0.381936213 */, 16 }, - /* 1991 */ { MAD_F(0x061d7581) /* 0.382192138 */, 16 }, - /* 1992 */ { MAD_F(0x061e81e8) /* 0.382448106 */, 16 }, - /* 1993 */ { MAD_F(0x061f8e5a) /* 0.382704117 */, 16 }, - /* 1994 */ { MAD_F(0x06209ad8) /* 0.382960171 */, 16 }, - /* 1995 */ { MAD_F(0x0621a761) /* 0.383216267 */, 16 }, - /* 1996 */ { MAD_F(0x0622b3f6) /* 0.383472406 */, 16 }, - /* 1997 */ { MAD_F(0x0623c096) /* 0.383728588 */, 16 }, - /* 1998 */ { MAD_F(0x0624cd42) /* 0.383984813 */, 16 }, - /* 1999 */ { MAD_F(0x0625d9f9) /* 0.384241080 */, 16 }, - - /* 2000 */ { MAD_F(0x0626e6bc) /* 0.384497391 */, 16 }, - /* 2001 */ { MAD_F(0x0627f38a) /* 0.384753744 */, 16 }, - /* 2002 */ { MAD_F(0x06290064) /* 0.385010139 */, 16 }, - /* 2003 */ { MAD_F(0x062a0d49) /* 0.385266578 */, 16 }, - /* 2004 */ { MAD_F(0x062b1a3a) /* 0.385523059 */, 16 }, - /* 2005 */ { MAD_F(0x062c2736) /* 0.385779582 */, 16 }, - /* 2006 */ { MAD_F(0x062d343d) /* 0.386036149 */, 16 }, - /* 2007 */ { MAD_F(0x062e4150) /* 0.386292758 */, 16 }, - /* 2008 */ { MAD_F(0x062f4e6f) /* 0.386549409 */, 16 }, - /* 2009 */ { MAD_F(0x06305b99) /* 0.386806104 */, 16 }, - /* 2010 */ { MAD_F(0x063168ce) /* 0.387062840 */, 16 }, - /* 2011 */ { MAD_F(0x0632760f) /* 0.387319620 */, 16 }, - /* 2012 */ { MAD_F(0x0633835b) /* 0.387576442 */, 16 }, - /* 2013 */ { MAD_F(0x063490b2) /* 0.387833306 */, 16 }, - /* 2014 */ { MAD_F(0x06359e15) /* 0.388090213 */, 16 }, - /* 2015 */ { MAD_F(0x0636ab83) /* 0.388347163 */, 16 }, - - /* 2016 */ { MAD_F(0x0637b8fd) /* 0.388604155 */, 16 }, - /* 2017 */ { MAD_F(0x0638c682) /* 0.388861190 */, 16 }, - /* 2018 */ { MAD_F(0x0639d413) /* 0.389118267 */, 16 }, - /* 2019 */ { MAD_F(0x063ae1af) /* 0.389375386 */, 16 }, - /* 2020 */ { MAD_F(0x063bef56) /* 0.389632548 */, 16 }, - /* 2021 */ { MAD_F(0x063cfd09) /* 0.389889752 */, 16 }, - /* 2022 */ { MAD_F(0x063e0ac7) /* 0.390146999 */, 16 }, - /* 2023 */ { MAD_F(0x063f1891) /* 0.390404289 */, 16 }, - /* 2024 */ { MAD_F(0x06402666) /* 0.390661620 */, 16 }, - /* 2025 */ { MAD_F(0x06413446) /* 0.390918994 */, 16 }, - /* 2026 */ { MAD_F(0x06424232) /* 0.391176411 */, 16 }, - /* 2027 */ { MAD_F(0x06435029) /* 0.391433869 */, 16 }, - /* 2028 */ { MAD_F(0x06445e2b) /* 0.391691371 */, 16 }, - /* 2029 */ { MAD_F(0x06456c39) /* 0.391948914 */, 16 }, - /* 2030 */ { MAD_F(0x06467a52) /* 0.392206500 */, 16 }, - /* 2031 */ { MAD_F(0x06478877) /* 0.392464128 */, 16 }, - - /* 2032 */ { MAD_F(0x064896a7) /* 0.392721798 */, 16 }, - /* 2033 */ { MAD_F(0x0649a4e2) /* 0.392979511 */, 16 }, - /* 2034 */ { MAD_F(0x064ab328) /* 0.393237266 */, 16 }, - /* 2035 */ { MAD_F(0x064bc17a) /* 0.393495063 */, 16 }, - /* 2036 */ { MAD_F(0x064ccfd8) /* 0.393752902 */, 16 }, - /* 2037 */ { MAD_F(0x064dde40) /* 0.394010784 */, 16 }, - /* 2038 */ { MAD_F(0x064eecb4) /* 0.394268707 */, 16 }, - /* 2039 */ { MAD_F(0x064ffb33) /* 0.394526673 */, 16 }, - /* 2040 */ { MAD_F(0x065109be) /* 0.394784681 */, 16 }, - /* 2041 */ { MAD_F(0x06521854) /* 0.395042732 */, 16 }, - /* 2042 */ { MAD_F(0x065326f5) /* 0.395300824 */, 16 }, - /* 2043 */ { MAD_F(0x065435a1) /* 0.395558959 */, 16 }, - /* 2044 */ { MAD_F(0x06554459) /* 0.395817135 */, 16 }, - /* 2045 */ { MAD_F(0x0656531c) /* 0.396075354 */, 16 }, - /* 2046 */ { MAD_F(0x065761ea) /* 0.396333615 */, 16 }, - /* 2047 */ { MAD_F(0x065870c4) /* 0.396591918 */, 16 }, - - /* 2048 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 16 }, - /* 2049 */ { MAD_F(0x065a8e99) /* 0.397108650 */, 16 }, - /* 2050 */ { MAD_F(0x065b9d95) /* 0.397367079 */, 16 }, - /* 2051 */ { MAD_F(0x065cac9c) /* 0.397625550 */, 16 }, - /* 2052 */ { MAD_F(0x065dbbae) /* 0.397884063 */, 16 }, - /* 2053 */ { MAD_F(0x065ecacb) /* 0.398142619 */, 16 }, - /* 2054 */ { MAD_F(0x065fd9f4) /* 0.398401216 */, 16 }, - /* 2055 */ { MAD_F(0x0660e928) /* 0.398659855 */, 16 }, - /* 2056 */ { MAD_F(0x0661f867) /* 0.398918536 */, 16 }, - /* 2057 */ { MAD_F(0x066307b1) /* 0.399177259 */, 16 }, - /* 2058 */ { MAD_F(0x06641707) /* 0.399436024 */, 16 }, - /* 2059 */ { MAD_F(0x06652668) /* 0.399694831 */, 16 }, - /* 2060 */ { MAD_F(0x066635d4) /* 0.399953679 */, 16 }, - /* 2061 */ { MAD_F(0x0667454c) /* 0.400212570 */, 16 }, - /* 2062 */ { MAD_F(0x066854ce) /* 0.400471503 */, 16 }, - /* 2063 */ { MAD_F(0x0669645c) /* 0.400730477 */, 16 }, - - /* 2064 */ { MAD_F(0x066a73f5) /* 0.400989493 */, 16 }, - /* 2065 */ { MAD_F(0x066b839a) /* 0.401248551 */, 16 }, - /* 2066 */ { MAD_F(0x066c9349) /* 0.401507651 */, 16 }, - /* 2067 */ { MAD_F(0x066da304) /* 0.401766793 */, 16 }, - /* 2068 */ { MAD_F(0x066eb2ca) /* 0.402025976 */, 16 }, - /* 2069 */ { MAD_F(0x066fc29b) /* 0.402285202 */, 16 }, - /* 2070 */ { MAD_F(0x0670d278) /* 0.402544469 */, 16 }, - /* 2071 */ { MAD_F(0x0671e25f) /* 0.402803777 */, 16 }, - /* 2072 */ { MAD_F(0x0672f252) /* 0.403063128 */, 16 }, - /* 2073 */ { MAD_F(0x06740250) /* 0.403322520 */, 16 }, - /* 2074 */ { MAD_F(0x0675125a) /* 0.403581954 */, 16 }, - /* 2075 */ { MAD_F(0x0676226e) /* 0.403841430 */, 16 }, - /* 2076 */ { MAD_F(0x0677328e) /* 0.404100947 */, 16 }, - /* 2077 */ { MAD_F(0x067842b9) /* 0.404360506 */, 16 }, - /* 2078 */ { MAD_F(0x067952ef) /* 0.404620107 */, 16 }, - /* 2079 */ { MAD_F(0x067a6330) /* 0.404879749 */, 16 }, - - /* 2080 */ { MAD_F(0x067b737c) /* 0.405139433 */, 16 }, - /* 2081 */ { MAD_F(0x067c83d4) /* 0.405399159 */, 16 }, - /* 2082 */ { MAD_F(0x067d9436) /* 0.405658926 */, 16 }, - /* 2083 */ { MAD_F(0x067ea4a4) /* 0.405918735 */, 16 }, - /* 2084 */ { MAD_F(0x067fb51d) /* 0.406178585 */, 16 }, - /* 2085 */ { MAD_F(0x0680c5a2) /* 0.406438477 */, 16 }, - /* 2086 */ { MAD_F(0x0681d631) /* 0.406698410 */, 16 }, - /* 2087 */ { MAD_F(0x0682e6cb) /* 0.406958385 */, 16 }, - /* 2088 */ { MAD_F(0x0683f771) /* 0.407218402 */, 16 }, - /* 2089 */ { MAD_F(0x06850822) /* 0.407478460 */, 16 }, - /* 2090 */ { MAD_F(0x068618de) /* 0.407738559 */, 16 }, - /* 2091 */ { MAD_F(0x068729a5) /* 0.407998700 */, 16 }, - /* 2092 */ { MAD_F(0x06883a77) /* 0.408258883 */, 16 }, - /* 2093 */ { MAD_F(0x06894b55) /* 0.408519107 */, 16 }, - /* 2094 */ { MAD_F(0x068a5c3d) /* 0.408779372 */, 16 }, - /* 2095 */ { MAD_F(0x068b6d31) /* 0.409039679 */, 16 }, - - /* 2096 */ { MAD_F(0x068c7e2f) /* 0.409300027 */, 16 }, - /* 2097 */ { MAD_F(0x068d8f39) /* 0.409560417 */, 16 }, - /* 2098 */ { MAD_F(0x068ea04e) /* 0.409820848 */, 16 }, - /* 2099 */ { MAD_F(0x068fb16e) /* 0.410081321 */, 16 }, - /* 2100 */ { MAD_F(0x0690c299) /* 0.410341834 */, 16 }, - /* 2101 */ { MAD_F(0x0691d3cf) /* 0.410602390 */, 16 }, - /* 2102 */ { MAD_F(0x0692e511) /* 0.410862986 */, 16 }, - /* 2103 */ { MAD_F(0x0693f65d) /* 0.411123624 */, 16 }, - /* 2104 */ { MAD_F(0x069507b5) /* 0.411384303 */, 16 }, - /* 2105 */ { MAD_F(0x06961917) /* 0.411645024 */, 16 }, - /* 2106 */ { MAD_F(0x06972a85) /* 0.411905785 */, 16 }, - /* 2107 */ { MAD_F(0x06983bfe) /* 0.412166588 */, 16 }, - /* 2108 */ { MAD_F(0x06994d82) /* 0.412427433 */, 16 }, - /* 2109 */ { MAD_F(0x069a5f11) /* 0.412688318 */, 16 }, - /* 2110 */ { MAD_F(0x069b70ab) /* 0.412949245 */, 16 }, - /* 2111 */ { MAD_F(0x069c8250) /* 0.413210213 */, 16 }, - - /* 2112 */ { MAD_F(0x069d9400) /* 0.413471222 */, 16 }, - /* 2113 */ { MAD_F(0x069ea5bb) /* 0.413732273 */, 16 }, - /* 2114 */ { MAD_F(0x069fb781) /* 0.413993364 */, 16 }, - /* 2115 */ { MAD_F(0x06a0c953) /* 0.414254497 */, 16 }, - /* 2116 */ { MAD_F(0x06a1db2f) /* 0.414515671 */, 16 }, - /* 2117 */ { MAD_F(0x06a2ed16) /* 0.414776886 */, 16 }, - /* 2118 */ { MAD_F(0x06a3ff09) /* 0.415038142 */, 16 }, - /* 2119 */ { MAD_F(0x06a51106) /* 0.415299440 */, 16 }, - /* 2120 */ { MAD_F(0x06a6230f) /* 0.415560778 */, 16 }, - /* 2121 */ { MAD_F(0x06a73522) /* 0.415822157 */, 16 }, - /* 2122 */ { MAD_F(0x06a84741) /* 0.416083578 */, 16 }, - /* 2123 */ { MAD_F(0x06a9596a) /* 0.416345040 */, 16 }, - /* 2124 */ { MAD_F(0x06aa6b9f) /* 0.416606542 */, 16 }, - /* 2125 */ { MAD_F(0x06ab7ddf) /* 0.416868086 */, 16 }, - /* 2126 */ { MAD_F(0x06ac9029) /* 0.417129671 */, 16 }, - /* 2127 */ { MAD_F(0x06ada27f) /* 0.417391297 */, 16 }, - - /* 2128 */ { MAD_F(0x06aeb4e0) /* 0.417652964 */, 16 }, - /* 2129 */ { MAD_F(0x06afc74b) /* 0.417914672 */, 16 }, - /* 2130 */ { MAD_F(0x06b0d9c2) /* 0.418176420 */, 16 }, - /* 2131 */ { MAD_F(0x06b1ec43) /* 0.418438210 */, 16 }, - /* 2132 */ { MAD_F(0x06b2fed0) /* 0.418700041 */, 16 }, - /* 2133 */ { MAD_F(0x06b41168) /* 0.418961912 */, 16 }, - /* 2134 */ { MAD_F(0x06b5240a) /* 0.419223825 */, 16 }, - /* 2135 */ { MAD_F(0x06b636b8) /* 0.419485778 */, 16 }, - /* 2136 */ { MAD_F(0x06b74971) /* 0.419747773 */, 16 }, - /* 2137 */ { MAD_F(0x06b85c34) /* 0.420009808 */, 16 }, - /* 2138 */ { MAD_F(0x06b96f03) /* 0.420271884 */, 16 }, - /* 2139 */ { MAD_F(0x06ba81dc) /* 0.420534001 */, 16 }, - /* 2140 */ { MAD_F(0x06bb94c1) /* 0.420796159 */, 16 }, - /* 2141 */ { MAD_F(0x06bca7b0) /* 0.421058358 */, 16 }, - /* 2142 */ { MAD_F(0x06bdbaaa) /* 0.421320597 */, 16 }, - /* 2143 */ { MAD_F(0x06becdb0) /* 0.421582878 */, 16 }, - - /* 2144 */ { MAD_F(0x06bfe0c0) /* 0.421845199 */, 16 }, - /* 2145 */ { MAD_F(0x06c0f3db) /* 0.422107561 */, 16 }, - /* 2146 */ { MAD_F(0x06c20702) /* 0.422369964 */, 16 }, - /* 2147 */ { MAD_F(0x06c31a33) /* 0.422632407 */, 16 }, - /* 2148 */ { MAD_F(0x06c42d6f) /* 0.422894891 */, 16 }, - /* 2149 */ { MAD_F(0x06c540b6) /* 0.423157416 */, 16 }, - /* 2150 */ { MAD_F(0x06c65408) /* 0.423419982 */, 16 }, - /* 2151 */ { MAD_F(0x06c76765) /* 0.423682588 */, 16 }, - /* 2152 */ { MAD_F(0x06c87acc) /* 0.423945235 */, 16 }, - /* 2153 */ { MAD_F(0x06c98e3f) /* 0.424207923 */, 16 }, - /* 2154 */ { MAD_F(0x06caa1bd) /* 0.424470652 */, 16 }, - /* 2155 */ { MAD_F(0x06cbb545) /* 0.424733421 */, 16 }, - /* 2156 */ { MAD_F(0x06ccc8d9) /* 0.424996230 */, 16 }, - /* 2157 */ { MAD_F(0x06cddc77) /* 0.425259081 */, 16 }, - /* 2158 */ { MAD_F(0x06cef020) /* 0.425521972 */, 16 }, - /* 2159 */ { MAD_F(0x06d003d4) /* 0.425784903 */, 16 }, - - /* 2160 */ { MAD_F(0x06d11794) /* 0.426047876 */, 16 }, - /* 2161 */ { MAD_F(0x06d22b5e) /* 0.426310889 */, 16 }, - /* 2162 */ { MAD_F(0x06d33f32) /* 0.426573942 */, 16 }, - /* 2163 */ { MAD_F(0x06d45312) /* 0.426837036 */, 16 }, - /* 2164 */ { MAD_F(0x06d566fd) /* 0.427100170 */, 16 }, - /* 2165 */ { MAD_F(0x06d67af2) /* 0.427363345 */, 16 }, - /* 2166 */ { MAD_F(0x06d78ef3) /* 0.427626561 */, 16 }, - /* 2167 */ { MAD_F(0x06d8a2fe) /* 0.427889817 */, 16 }, - /* 2168 */ { MAD_F(0x06d9b714) /* 0.428153114 */, 16 }, - /* 2169 */ { MAD_F(0x06dacb35) /* 0.428416451 */, 16 }, - /* 2170 */ { MAD_F(0x06dbdf61) /* 0.428679828 */, 16 }, - /* 2171 */ { MAD_F(0x06dcf398) /* 0.428943246 */, 16 }, - /* 2172 */ { MAD_F(0x06de07d9) /* 0.429206704 */, 16 }, - /* 2173 */ { MAD_F(0x06df1c26) /* 0.429470203 */, 16 }, - /* 2174 */ { MAD_F(0x06e0307d) /* 0.429733743 */, 16 }, - /* 2175 */ { MAD_F(0x06e144df) /* 0.429997322 */, 16 }, - - /* 2176 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 16 }, - /* 2177 */ { MAD_F(0x06e36dc4) /* 0.430524603 */, 16 }, - /* 2178 */ { MAD_F(0x06e48246) /* 0.430788304 */, 16 }, - /* 2179 */ { MAD_F(0x06e596d4) /* 0.431052045 */, 16 }, - /* 2180 */ { MAD_F(0x06e6ab6c) /* 0.431315826 */, 16 }, - /* 2181 */ { MAD_F(0x06e7c00f) /* 0.431579648 */, 16 }, - /* 2182 */ { MAD_F(0x06e8d4bd) /* 0.431843511 */, 16 }, - /* 2183 */ { MAD_F(0x06e9e976) /* 0.432107413 */, 16 }, - /* 2184 */ { MAD_F(0x06eafe3a) /* 0.432371356 */, 16 }, - /* 2185 */ { MAD_F(0x06ec1308) /* 0.432635339 */, 16 }, - /* 2186 */ { MAD_F(0x06ed27e2) /* 0.432899362 */, 16 }, - /* 2187 */ { MAD_F(0x06ee3cc6) /* 0.433163426 */, 16 }, - /* 2188 */ { MAD_F(0x06ef51b4) /* 0.433427530 */, 16 }, - /* 2189 */ { MAD_F(0x06f066ae) /* 0.433691674 */, 16 }, - /* 2190 */ { MAD_F(0x06f17bb3) /* 0.433955859 */, 16 }, - /* 2191 */ { MAD_F(0x06f290c2) /* 0.434220083 */, 16 }, - - /* 2192 */ { MAD_F(0x06f3a5dc) /* 0.434484348 */, 16 }, - /* 2193 */ { MAD_F(0x06f4bb01) /* 0.434748653 */, 16 }, - /* 2194 */ { MAD_F(0x06f5d030) /* 0.435012998 */, 16 }, - /* 2195 */ { MAD_F(0x06f6e56b) /* 0.435277383 */, 16 }, - /* 2196 */ { MAD_F(0x06f7fab0) /* 0.435541809 */, 16 }, - /* 2197 */ { MAD_F(0x06f91000) /* 0.435806274 */, 16 }, - /* 2198 */ { MAD_F(0x06fa255a) /* 0.436070780 */, 16 }, - /* 2199 */ { MAD_F(0x06fb3ac0) /* 0.436335326 */, 16 }, - /* 2200 */ { MAD_F(0x06fc5030) /* 0.436599912 */, 16 }, - /* 2201 */ { MAD_F(0x06fd65ab) /* 0.436864538 */, 16 }, - /* 2202 */ { MAD_F(0x06fe7b31) /* 0.437129204 */, 16 }, - /* 2203 */ { MAD_F(0x06ff90c2) /* 0.437393910 */, 16 }, - /* 2204 */ { MAD_F(0x0700a65d) /* 0.437658657 */, 16 }, - /* 2205 */ { MAD_F(0x0701bc03) /* 0.437923443 */, 16 }, - /* 2206 */ { MAD_F(0x0702d1b4) /* 0.438188269 */, 16 }, - /* 2207 */ { MAD_F(0x0703e76f) /* 0.438453136 */, 16 }, - - /* 2208 */ { MAD_F(0x0704fd35) /* 0.438718042 */, 16 }, - /* 2209 */ { MAD_F(0x07061306) /* 0.438982988 */, 16 }, - /* 2210 */ { MAD_F(0x070728e2) /* 0.439247975 */, 16 }, - /* 2211 */ { MAD_F(0x07083ec9) /* 0.439513001 */, 16 }, - /* 2212 */ { MAD_F(0x070954ba) /* 0.439778067 */, 16 }, - /* 2213 */ { MAD_F(0x070a6ab6) /* 0.440043173 */, 16 }, - /* 2214 */ { MAD_F(0x070b80bc) /* 0.440308320 */, 16 }, - /* 2215 */ { MAD_F(0x070c96ce) /* 0.440573506 */, 16 }, - /* 2216 */ { MAD_F(0x070dacea) /* 0.440838732 */, 16 }, - /* 2217 */ { MAD_F(0x070ec310) /* 0.441103997 */, 16 }, - /* 2218 */ { MAD_F(0x070fd942) /* 0.441369303 */, 16 }, - /* 2219 */ { MAD_F(0x0710ef7e) /* 0.441634649 */, 16 }, - /* 2220 */ { MAD_F(0x071205c5) /* 0.441900034 */, 16 }, - /* 2221 */ { MAD_F(0x07131c17) /* 0.442165460 */, 16 }, - /* 2222 */ { MAD_F(0x07143273) /* 0.442430925 */, 16 }, - /* 2223 */ { MAD_F(0x071548da) /* 0.442696430 */, 16 }, - - /* 2224 */ { MAD_F(0x07165f4b) /* 0.442961975 */, 16 }, - /* 2225 */ { MAD_F(0x071775c8) /* 0.443227559 */, 16 }, - /* 2226 */ { MAD_F(0x07188c4f) /* 0.443493184 */, 16 }, - /* 2227 */ { MAD_F(0x0719a2e0) /* 0.443758848 */, 16 }, - /* 2228 */ { MAD_F(0x071ab97d) /* 0.444024552 */, 16 }, - /* 2229 */ { MAD_F(0x071bd024) /* 0.444290296 */, 16 }, - /* 2230 */ { MAD_F(0x071ce6d6) /* 0.444556079 */, 16 }, - /* 2231 */ { MAD_F(0x071dfd92) /* 0.444821902 */, 16 }, - /* 2232 */ { MAD_F(0x071f1459) /* 0.445087765 */, 16 }, - /* 2233 */ { MAD_F(0x07202b2b) /* 0.445353668 */, 16 }, - /* 2234 */ { MAD_F(0x07214207) /* 0.445619610 */, 16 }, - /* 2235 */ { MAD_F(0x072258ee) /* 0.445885592 */, 16 }, - /* 2236 */ { MAD_F(0x07236fe0) /* 0.446151614 */, 16 }, - /* 2237 */ { MAD_F(0x072486dc) /* 0.446417675 */, 16 }, - /* 2238 */ { MAD_F(0x07259de3) /* 0.446683776 */, 16 }, - /* 2239 */ { MAD_F(0x0726b4f4) /* 0.446949917 */, 16 }, - - /* 2240 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 16 }, - /* 2241 */ { MAD_F(0x0728e338) /* 0.447482317 */, 16 }, - /* 2242 */ { MAD_F(0x0729fa69) /* 0.447748576 */, 16 }, - /* 2243 */ { MAD_F(0x072b11a5) /* 0.448014875 */, 16 }, - /* 2244 */ { MAD_F(0x072c28ec) /* 0.448281214 */, 16 }, - /* 2245 */ { MAD_F(0x072d403d) /* 0.448547592 */, 16 }, - /* 2246 */ { MAD_F(0x072e5799) /* 0.448814010 */, 16 }, - /* 2247 */ { MAD_F(0x072f6f00) /* 0.449080467 */, 16 }, - /* 2248 */ { MAD_F(0x07308671) /* 0.449346964 */, 16 }, - /* 2249 */ { MAD_F(0x07319ded) /* 0.449613501 */, 16 }, - /* 2250 */ { MAD_F(0x0732b573) /* 0.449880076 */, 16 }, - /* 2251 */ { MAD_F(0x0733cd04) /* 0.450146692 */, 16 }, - /* 2252 */ { MAD_F(0x0734e4a0) /* 0.450413347 */, 16 }, - /* 2253 */ { MAD_F(0x0735fc46) /* 0.450680041 */, 16 }, - /* 2254 */ { MAD_F(0x073713f7) /* 0.450946775 */, 16 }, - /* 2255 */ { MAD_F(0x07382bb2) /* 0.451213548 */, 16 }, - - /* 2256 */ { MAD_F(0x07394378) /* 0.451480360 */, 16 }, - /* 2257 */ { MAD_F(0x073a5b49) /* 0.451747213 */, 16 }, - /* 2258 */ { MAD_F(0x073b7324) /* 0.452014104 */, 16 }, - /* 2259 */ { MAD_F(0x073c8b0a) /* 0.452281035 */, 16 }, - /* 2260 */ { MAD_F(0x073da2fa) /* 0.452548005 */, 16 }, - /* 2261 */ { MAD_F(0x073ebaf5) /* 0.452815015 */, 16 }, - /* 2262 */ { MAD_F(0x073fd2fa) /* 0.453082064 */, 16 }, - /* 2263 */ { MAD_F(0x0740eb0a) /* 0.453349152 */, 16 }, - /* 2264 */ { MAD_F(0x07420325) /* 0.453616280 */, 16 }, - /* 2265 */ { MAD_F(0x07431b4a) /* 0.453883447 */, 16 }, - /* 2266 */ { MAD_F(0x0744337a) /* 0.454150653 */, 16 }, - /* 2267 */ { MAD_F(0x07454bb4) /* 0.454417899 */, 16 }, - /* 2268 */ { MAD_F(0x074663f8) /* 0.454685184 */, 16 }, - /* 2269 */ { MAD_F(0x07477c48) /* 0.454952508 */, 16 }, - /* 2270 */ { MAD_F(0x074894a2) /* 0.455219872 */, 16 }, - /* 2271 */ { MAD_F(0x0749ad06) /* 0.455487275 */, 16 }, - - /* 2272 */ { MAD_F(0x074ac575) /* 0.455754717 */, 16 }, - /* 2273 */ { MAD_F(0x074bddee) /* 0.456022198 */, 16 }, - /* 2274 */ { MAD_F(0x074cf672) /* 0.456289719 */, 16 }, - /* 2275 */ { MAD_F(0x074e0f01) /* 0.456557278 */, 16 }, - /* 2276 */ { MAD_F(0x074f279a) /* 0.456824877 */, 16 }, - /* 2277 */ { MAD_F(0x0750403e) /* 0.457092516 */, 16 }, - /* 2278 */ { MAD_F(0x075158ec) /* 0.457360193 */, 16 }, - /* 2279 */ { MAD_F(0x075271a4) /* 0.457627909 */, 16 }, - /* 2280 */ { MAD_F(0x07538a67) /* 0.457895665 */, 16 }, - /* 2281 */ { MAD_F(0x0754a335) /* 0.458163460 */, 16 }, - /* 2282 */ { MAD_F(0x0755bc0d) /* 0.458431294 */, 16 }, - /* 2283 */ { MAD_F(0x0756d4f0) /* 0.458699167 */, 16 }, - /* 2284 */ { MAD_F(0x0757eddd) /* 0.458967079 */, 16 }, - /* 2285 */ { MAD_F(0x075906d5) /* 0.459235030 */, 16 }, - /* 2286 */ { MAD_F(0x075a1fd7) /* 0.459503021 */, 16 }, - /* 2287 */ { MAD_F(0x075b38e3) /* 0.459771050 */, 16 }, - - /* 2288 */ { MAD_F(0x075c51fa) /* 0.460039119 */, 16 }, - /* 2289 */ { MAD_F(0x075d6b1c) /* 0.460307226 */, 16 }, - /* 2290 */ { MAD_F(0x075e8448) /* 0.460575373 */, 16 }, - /* 2291 */ { MAD_F(0x075f9d7f) /* 0.460843559 */, 16 }, - /* 2292 */ { MAD_F(0x0760b6c0) /* 0.461111783 */, 16 }, - /* 2293 */ { MAD_F(0x0761d00b) /* 0.461380047 */, 16 }, - /* 2294 */ { MAD_F(0x0762e961) /* 0.461648350 */, 16 }, - /* 2295 */ { MAD_F(0x076402c1) /* 0.461916691 */, 16 }, - /* 2296 */ { MAD_F(0x07651c2c) /* 0.462185072 */, 16 }, - /* 2297 */ { MAD_F(0x076635a2) /* 0.462453492 */, 16 }, - /* 2298 */ { MAD_F(0x07674f22) /* 0.462721950 */, 16 }, - /* 2299 */ { MAD_F(0x076868ac) /* 0.462990448 */, 16 }, - /* 2300 */ { MAD_F(0x07698240) /* 0.463258984 */, 16 }, - /* 2301 */ { MAD_F(0x076a9be0) /* 0.463527560 */, 16 }, - /* 2302 */ { MAD_F(0x076bb589) /* 0.463796174 */, 16 }, - /* 2303 */ { MAD_F(0x076ccf3d) /* 0.464064827 */, 16 }, - - /* 2304 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 16 }, - /* 2305 */ { MAD_F(0x076f02c5) /* 0.464602250 */, 16 }, - /* 2306 */ { MAD_F(0x07701c98) /* 0.464871020 */, 16 }, - /* 2307 */ { MAD_F(0x07713676) /* 0.465139829 */, 16 }, - /* 2308 */ { MAD_F(0x0772505e) /* 0.465408676 */, 16 }, - /* 2309 */ { MAD_F(0x07736a51) /* 0.465677563 */, 16 }, - /* 2310 */ { MAD_F(0x0774844e) /* 0.465946488 */, 16 }, - /* 2311 */ { MAD_F(0x07759e55) /* 0.466215452 */, 16 }, - /* 2312 */ { MAD_F(0x0776b867) /* 0.466484455 */, 16 }, - /* 2313 */ { MAD_F(0x0777d283) /* 0.466753496 */, 16 }, - /* 2314 */ { MAD_F(0x0778ecaa) /* 0.467022577 */, 16 }, - /* 2315 */ { MAD_F(0x077a06db) /* 0.467291696 */, 16 }, - /* 2316 */ { MAD_F(0x077b2117) /* 0.467560854 */, 16 }, - /* 2317 */ { MAD_F(0x077c3b5d) /* 0.467830050 */, 16 }, - /* 2318 */ { MAD_F(0x077d55ad) /* 0.468099285 */, 16 }, - /* 2319 */ { MAD_F(0x077e7008) /* 0.468368560 */, 16 }, - - /* 2320 */ { MAD_F(0x077f8a6d) /* 0.468637872 */, 16 }, - /* 2321 */ { MAD_F(0x0780a4dc) /* 0.468907224 */, 16 }, - /* 2322 */ { MAD_F(0x0781bf56) /* 0.469176614 */, 16 }, - /* 2323 */ { MAD_F(0x0782d9da) /* 0.469446043 */, 16 }, - /* 2324 */ { MAD_F(0x0783f469) /* 0.469715510 */, 16 }, - /* 2325 */ { MAD_F(0x07850f02) /* 0.469985016 */, 16 }, - /* 2326 */ { MAD_F(0x078629a5) /* 0.470254561 */, 16 }, - /* 2327 */ { MAD_F(0x07874453) /* 0.470524145 */, 16 }, - /* 2328 */ { MAD_F(0x07885f0b) /* 0.470793767 */, 16 }, - /* 2329 */ { MAD_F(0x078979ce) /* 0.471063427 */, 16 }, - /* 2330 */ { MAD_F(0x078a949a) /* 0.471333126 */, 16 }, - /* 2331 */ { MAD_F(0x078baf72) /* 0.471602864 */, 16 }, - /* 2332 */ { MAD_F(0x078cca53) /* 0.471872641 */, 16 }, - /* 2333 */ { MAD_F(0x078de53f) /* 0.472142456 */, 16 }, - /* 2334 */ { MAD_F(0x078f0035) /* 0.472412309 */, 16 }, - /* 2335 */ { MAD_F(0x07901b36) /* 0.472682201 */, 16 }, - - /* 2336 */ { MAD_F(0x07913641) /* 0.472952132 */, 16 }, - /* 2337 */ { MAD_F(0x07925156) /* 0.473222101 */, 16 }, - /* 2338 */ { MAD_F(0x07936c76) /* 0.473492108 */, 16 }, - /* 2339 */ { MAD_F(0x079487a0) /* 0.473762155 */, 16 }, - /* 2340 */ { MAD_F(0x0795a2d4) /* 0.474032239 */, 16 }, - /* 2341 */ { MAD_F(0x0796be13) /* 0.474302362 */, 16 }, - /* 2342 */ { MAD_F(0x0797d95c) /* 0.474572524 */, 16 }, - /* 2343 */ { MAD_F(0x0798f4af) /* 0.474842724 */, 16 }, - /* 2344 */ { MAD_F(0x079a100c) /* 0.475112962 */, 16 }, - /* 2345 */ { MAD_F(0x079b2b74) /* 0.475383239 */, 16 }, - /* 2346 */ { MAD_F(0x079c46e7) /* 0.475653554 */, 16 }, - /* 2347 */ { MAD_F(0x079d6263) /* 0.475923908 */, 16 }, - /* 2348 */ { MAD_F(0x079e7dea) /* 0.476194300 */, 16 }, - /* 2349 */ { MAD_F(0x079f997b) /* 0.476464731 */, 16 }, - /* 2350 */ { MAD_F(0x07a0b516) /* 0.476735200 */, 16 }, - /* 2351 */ { MAD_F(0x07a1d0bc) /* 0.477005707 */, 16 }, - - /* 2352 */ { MAD_F(0x07a2ec6c) /* 0.477276252 */, 16 }, - /* 2353 */ { MAD_F(0x07a40827) /* 0.477546836 */, 16 }, - /* 2354 */ { MAD_F(0x07a523eb) /* 0.477817459 */, 16 }, - /* 2355 */ { MAD_F(0x07a63fba) /* 0.478088119 */, 16 }, - /* 2356 */ { MAD_F(0x07a75b93) /* 0.478358818 */, 16 }, - /* 2357 */ { MAD_F(0x07a87777) /* 0.478629555 */, 16 }, - /* 2358 */ { MAD_F(0x07a99364) /* 0.478900331 */, 16 }, - /* 2359 */ { MAD_F(0x07aaaf5c) /* 0.479171145 */, 16 }, - /* 2360 */ { MAD_F(0x07abcb5f) /* 0.479441997 */, 16 }, - /* 2361 */ { MAD_F(0x07ace76b) /* 0.479712887 */, 16 }, - /* 2362 */ { MAD_F(0x07ae0382) /* 0.479983816 */, 16 }, - /* 2363 */ { MAD_F(0x07af1fa3) /* 0.480254782 */, 16 }, - /* 2364 */ { MAD_F(0x07b03bcf) /* 0.480525787 */, 16 }, - /* 2365 */ { MAD_F(0x07b15804) /* 0.480796831 */, 16 }, - /* 2366 */ { MAD_F(0x07b27444) /* 0.481067912 */, 16 }, - /* 2367 */ { MAD_F(0x07b3908e) /* 0.481339032 */, 16 }, - - /* 2368 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 16 }, - /* 2369 */ { MAD_F(0x07b5c941) /* 0.481881385 */, 16 }, - /* 2370 */ { MAD_F(0x07b6e5aa) /* 0.482152620 */, 16 }, - /* 2371 */ { MAD_F(0x07b8021d) /* 0.482423892 */, 16 }, - /* 2372 */ { MAD_F(0x07b91e9b) /* 0.482695202 */, 16 }, - /* 2373 */ { MAD_F(0x07ba3b22) /* 0.482966551 */, 16 }, - /* 2374 */ { MAD_F(0x07bb57b4) /* 0.483237938 */, 16 }, - /* 2375 */ { MAD_F(0x07bc7450) /* 0.483509362 */, 16 }, - /* 2376 */ { MAD_F(0x07bd90f6) /* 0.483780825 */, 16 }, - /* 2377 */ { MAD_F(0x07beada7) /* 0.484052326 */, 16 }, - /* 2378 */ { MAD_F(0x07bfca61) /* 0.484323865 */, 16 }, - /* 2379 */ { MAD_F(0x07c0e726) /* 0.484595443 */, 16 }, - /* 2380 */ { MAD_F(0x07c203f5) /* 0.484867058 */, 16 }, - /* 2381 */ { MAD_F(0x07c320cf) /* 0.485138711 */, 16 }, - /* 2382 */ { MAD_F(0x07c43db2) /* 0.485410402 */, 16 }, - /* 2383 */ { MAD_F(0x07c55aa0) /* 0.485682131 */, 16 }, - - /* 2384 */ { MAD_F(0x07c67798) /* 0.485953899 */, 16 }, - /* 2385 */ { MAD_F(0x07c7949a) /* 0.486225704 */, 16 }, - /* 2386 */ { MAD_F(0x07c8b1a7) /* 0.486497547 */, 16 }, - /* 2387 */ { MAD_F(0x07c9cebd) /* 0.486769429 */, 16 }, - /* 2388 */ { MAD_F(0x07caebde) /* 0.487041348 */, 16 }, - /* 2389 */ { MAD_F(0x07cc0909) /* 0.487313305 */, 16 }, - /* 2390 */ { MAD_F(0x07cd263e) /* 0.487585300 */, 16 }, - /* 2391 */ { MAD_F(0x07ce437d) /* 0.487857333 */, 16 }, - /* 2392 */ { MAD_F(0x07cf60c7) /* 0.488129404 */, 16 }, - /* 2393 */ { MAD_F(0x07d07e1b) /* 0.488401513 */, 16 }, - /* 2394 */ { MAD_F(0x07d19b79) /* 0.488673660 */, 16 }, - /* 2395 */ { MAD_F(0x07d2b8e1) /* 0.488945845 */, 16 }, - /* 2396 */ { MAD_F(0x07d3d653) /* 0.489218067 */, 16 }, - /* 2397 */ { MAD_F(0x07d4f3cf) /* 0.489490328 */, 16 }, - /* 2398 */ { MAD_F(0x07d61156) /* 0.489762626 */, 16 }, - /* 2399 */ { MAD_F(0x07d72ee6) /* 0.490034962 */, 16 }, - - /* 2400 */ { MAD_F(0x07d84c81) /* 0.490307336 */, 16 }, - /* 2401 */ { MAD_F(0x07d96a26) /* 0.490579748 */, 16 }, - /* 2402 */ { MAD_F(0x07da87d5) /* 0.490852198 */, 16 }, - /* 2403 */ { MAD_F(0x07dba58f) /* 0.491124686 */, 16 }, - /* 2404 */ { MAD_F(0x07dcc352) /* 0.491397211 */, 16 }, - /* 2405 */ { MAD_F(0x07dde120) /* 0.491669774 */, 16 }, - /* 2406 */ { MAD_F(0x07defef7) /* 0.491942375 */, 16 }, - /* 2407 */ { MAD_F(0x07e01cd9) /* 0.492215014 */, 16 }, - /* 2408 */ { MAD_F(0x07e13ac5) /* 0.492487690 */, 16 }, - /* 2409 */ { MAD_F(0x07e258bc) /* 0.492760404 */, 16 }, - /* 2410 */ { MAD_F(0x07e376bc) /* 0.493033156 */, 16 }, - /* 2411 */ { MAD_F(0x07e494c6) /* 0.493305946 */, 16 }, - /* 2412 */ { MAD_F(0x07e5b2db) /* 0.493578773 */, 16 }, - /* 2413 */ { MAD_F(0x07e6d0f9) /* 0.493851638 */, 16 }, - /* 2414 */ { MAD_F(0x07e7ef22) /* 0.494124541 */, 16 }, - /* 2415 */ { MAD_F(0x07e90d55) /* 0.494397481 */, 16 }, - - /* 2416 */ { MAD_F(0x07ea2b92) /* 0.494670459 */, 16 }, - /* 2417 */ { MAD_F(0x07eb49d9) /* 0.494943475 */, 16 }, - /* 2418 */ { MAD_F(0x07ec682a) /* 0.495216529 */, 16 }, - /* 2419 */ { MAD_F(0x07ed8686) /* 0.495489620 */, 16 }, - /* 2420 */ { MAD_F(0x07eea4eb) /* 0.495762748 */, 16 }, - /* 2421 */ { MAD_F(0x07efc35b) /* 0.496035915 */, 16 }, - /* 2422 */ { MAD_F(0x07f0e1d4) /* 0.496309119 */, 16 }, - /* 2423 */ { MAD_F(0x07f20058) /* 0.496582360 */, 16 }, - /* 2424 */ { MAD_F(0x07f31ee6) /* 0.496855639 */, 16 }, - /* 2425 */ { MAD_F(0x07f43d7e) /* 0.497128956 */, 16 }, - /* 2426 */ { MAD_F(0x07f55c20) /* 0.497402310 */, 16 }, - /* 2427 */ { MAD_F(0x07f67acc) /* 0.497675702 */, 16 }, - /* 2428 */ { MAD_F(0x07f79982) /* 0.497949132 */, 16 }, - /* 2429 */ { MAD_F(0x07f8b842) /* 0.498222598 */, 16 }, - /* 2430 */ { MAD_F(0x07f9d70c) /* 0.498496103 */, 16 }, - /* 2431 */ { MAD_F(0x07faf5e1) /* 0.498769645 */, 16 }, - - /* 2432 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 16 }, - /* 2433 */ { MAD_F(0x07fd33a8) /* 0.499316841 */, 16 }, - /* 2434 */ { MAD_F(0x07fe529a) /* 0.499590496 */, 16 }, - /* 2435 */ { MAD_F(0x07ff7197) /* 0.499864188 */, 16 }, - /* 2436 */ { MAD_F(0x0400484f) /* 0.250068959 */, 17 }, - /* 2437 */ { MAD_F(0x0400d7d7) /* 0.250205842 */, 17 }, - /* 2438 */ { MAD_F(0x04016764) /* 0.250342744 */, 17 }, - /* 2439 */ { MAD_F(0x0401f6f7) /* 0.250479665 */, 17 }, - /* 2440 */ { MAD_F(0x0402868e) /* 0.250616605 */, 17 }, - /* 2441 */ { MAD_F(0x0403162b) /* 0.250753563 */, 17 }, - /* 2442 */ { MAD_F(0x0403a5cc) /* 0.250890540 */, 17 }, - /* 2443 */ { MAD_F(0x04043573) /* 0.251027536 */, 17 }, - /* 2444 */ { MAD_F(0x0404c51e) /* 0.251164550 */, 17 }, - /* 2445 */ { MAD_F(0x040554cf) /* 0.251301583 */, 17 }, - /* 2446 */ { MAD_F(0x0405e484) /* 0.251438635 */, 17 }, - /* 2447 */ { MAD_F(0x0406743f) /* 0.251575706 */, 17 }, - - /* 2448 */ { MAD_F(0x040703ff) /* 0.251712795 */, 17 }, - /* 2449 */ { MAD_F(0x040793c3) /* 0.251849903 */, 17 }, - /* 2450 */ { MAD_F(0x0408238d) /* 0.251987029 */, 17 }, - /* 2451 */ { MAD_F(0x0408b35b) /* 0.252124174 */, 17 }, - /* 2452 */ { MAD_F(0x0409432f) /* 0.252261338 */, 17 }, - /* 2453 */ { MAD_F(0x0409d308) /* 0.252398520 */, 17 }, - /* 2454 */ { MAD_F(0x040a62e5) /* 0.252535721 */, 17 }, - /* 2455 */ { MAD_F(0x040af2c8) /* 0.252672941 */, 17 }, - /* 2456 */ { MAD_F(0x040b82b0) /* 0.252810180 */, 17 }, - /* 2457 */ { MAD_F(0x040c129c) /* 0.252947436 */, 17 }, - /* 2458 */ { MAD_F(0x040ca28e) /* 0.253084712 */, 17 }, - /* 2459 */ { MAD_F(0x040d3284) /* 0.253222006 */, 17 }, - /* 2460 */ { MAD_F(0x040dc280) /* 0.253359319 */, 17 }, - /* 2461 */ { MAD_F(0x040e5281) /* 0.253496651 */, 17 }, - /* 2462 */ { MAD_F(0x040ee286) /* 0.253634001 */, 17 }, - /* 2463 */ { MAD_F(0x040f7291) /* 0.253771369 */, 17 }, - - /* 2464 */ { MAD_F(0x041002a1) /* 0.253908756 */, 17 }, - /* 2465 */ { MAD_F(0x041092b5) /* 0.254046162 */, 17 }, - /* 2466 */ { MAD_F(0x041122cf) /* 0.254183587 */, 17 }, - /* 2467 */ { MAD_F(0x0411b2ed) /* 0.254321030 */, 17 }, - /* 2468 */ { MAD_F(0x04124311) /* 0.254458491 */, 17 }, - /* 2469 */ { MAD_F(0x0412d339) /* 0.254595971 */, 17 }, - /* 2470 */ { MAD_F(0x04136367) /* 0.254733470 */, 17 }, - /* 2471 */ { MAD_F(0x0413f399) /* 0.254870987 */, 17 }, - /* 2472 */ { MAD_F(0x041483d1) /* 0.255008523 */, 17 }, - /* 2473 */ { MAD_F(0x0415140d) /* 0.255146077 */, 17 }, - /* 2474 */ { MAD_F(0x0415a44f) /* 0.255283650 */, 17 }, - /* 2475 */ { MAD_F(0x04163495) /* 0.255421241 */, 17 }, - /* 2476 */ { MAD_F(0x0416c4e1) /* 0.255558851 */, 17 }, - /* 2477 */ { MAD_F(0x04175531) /* 0.255696480 */, 17 }, - /* 2478 */ { MAD_F(0x0417e586) /* 0.255834127 */, 17 }, - /* 2479 */ { MAD_F(0x041875e1) /* 0.255971792 */, 17 }, - - /* 2480 */ { MAD_F(0x04190640) /* 0.256109476 */, 17 }, - /* 2481 */ { MAD_F(0x041996a4) /* 0.256247179 */, 17 }, - /* 2482 */ { MAD_F(0x041a270d) /* 0.256384900 */, 17 }, - /* 2483 */ { MAD_F(0x041ab77b) /* 0.256522639 */, 17 }, - /* 2484 */ { MAD_F(0x041b47ef) /* 0.256660397 */, 17 }, - /* 2485 */ { MAD_F(0x041bd867) /* 0.256798174 */, 17 }, - /* 2486 */ { MAD_F(0x041c68e4) /* 0.256935969 */, 17 }, - /* 2487 */ { MAD_F(0x041cf966) /* 0.257073782 */, 17 }, - /* 2488 */ { MAD_F(0x041d89ed) /* 0.257211614 */, 17 }, - /* 2489 */ { MAD_F(0x041e1a79) /* 0.257349465 */, 17 }, - /* 2490 */ { MAD_F(0x041eab0a) /* 0.257487334 */, 17 }, - /* 2491 */ { MAD_F(0x041f3b9f) /* 0.257625221 */, 17 }, - /* 2492 */ { MAD_F(0x041fcc3a) /* 0.257763127 */, 17 }, - /* 2493 */ { MAD_F(0x04205cda) /* 0.257901051 */, 17 }, - /* 2494 */ { MAD_F(0x0420ed7f) /* 0.258038994 */, 17 }, - /* 2495 */ { MAD_F(0x04217e28) /* 0.258176955 */, 17 }, - - /* 2496 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 17 }, - /* 2497 */ { MAD_F(0x04229f8a) /* 0.258452932 */, 17 }, - /* 2498 */ { MAD_F(0x04233043) /* 0.258590948 */, 17 }, - /* 2499 */ { MAD_F(0x0423c100) /* 0.258728983 */, 17 }, - /* 2500 */ { MAD_F(0x042451c3) /* 0.258867036 */, 17 }, - /* 2501 */ { MAD_F(0x0424e28a) /* 0.259005108 */, 17 }, - /* 2502 */ { MAD_F(0x04257356) /* 0.259143198 */, 17 }, - /* 2503 */ { MAD_F(0x04260428) /* 0.259281307 */, 17 }, - /* 2504 */ { MAD_F(0x042694fe) /* 0.259419433 */, 17 }, - /* 2505 */ { MAD_F(0x042725d9) /* 0.259557579 */, 17 }, - /* 2506 */ { MAD_F(0x0427b6b9) /* 0.259695742 */, 17 }, - /* 2507 */ { MAD_F(0x0428479e) /* 0.259833924 */, 17 }, - /* 2508 */ { MAD_F(0x0428d888) /* 0.259972124 */, 17 }, - /* 2509 */ { MAD_F(0x04296976) /* 0.260110343 */, 17 }, - /* 2510 */ { MAD_F(0x0429fa6a) /* 0.260248580 */, 17 }, - /* 2511 */ { MAD_F(0x042a8b63) /* 0.260386836 */, 17 }, - - /* 2512 */ { MAD_F(0x042b1c60) /* 0.260525110 */, 17 }, - /* 2513 */ { MAD_F(0x042bad63) /* 0.260663402 */, 17 }, - /* 2514 */ { MAD_F(0x042c3e6a) /* 0.260801712 */, 17 }, - /* 2515 */ { MAD_F(0x042ccf77) /* 0.260940041 */, 17 }, - /* 2516 */ { MAD_F(0x042d6088) /* 0.261078388 */, 17 }, - /* 2517 */ { MAD_F(0x042df19e) /* 0.261216754 */, 17 }, - /* 2518 */ { MAD_F(0x042e82b9) /* 0.261355137 */, 17 }, - /* 2519 */ { MAD_F(0x042f13d9) /* 0.261493540 */, 17 }, - /* 2520 */ { MAD_F(0x042fa4fe) /* 0.261631960 */, 17 }, - /* 2521 */ { MAD_F(0x04303628) /* 0.261770399 */, 17 }, - /* 2522 */ { MAD_F(0x0430c757) /* 0.261908856 */, 17 }, - /* 2523 */ { MAD_F(0x0431588b) /* 0.262047331 */, 17 }, - /* 2524 */ { MAD_F(0x0431e9c3) /* 0.262185825 */, 17 }, - /* 2525 */ { MAD_F(0x04327b01) /* 0.262324337 */, 17 }, - /* 2526 */ { MAD_F(0x04330c43) /* 0.262462867 */, 17 }, - /* 2527 */ { MAD_F(0x04339d8a) /* 0.262601416 */, 17 }, - - /* 2528 */ { MAD_F(0x04342ed7) /* 0.262739982 */, 17 }, - /* 2529 */ { MAD_F(0x0434c028) /* 0.262878568 */, 17 }, - /* 2530 */ { MAD_F(0x0435517e) /* 0.263017171 */, 17 }, - /* 2531 */ { MAD_F(0x0435e2d9) /* 0.263155792 */, 17 }, - /* 2532 */ { MAD_F(0x04367439) /* 0.263294432 */, 17 }, - /* 2533 */ { MAD_F(0x0437059e) /* 0.263433090 */, 17 }, - /* 2534 */ { MAD_F(0x04379707) /* 0.263571767 */, 17 }, - /* 2535 */ { MAD_F(0x04382876) /* 0.263710461 */, 17 }, - /* 2536 */ { MAD_F(0x0438b9e9) /* 0.263849174 */, 17 }, - /* 2537 */ { MAD_F(0x04394b61) /* 0.263987905 */, 17 }, - /* 2538 */ { MAD_F(0x0439dcdf) /* 0.264126655 */, 17 }, - /* 2539 */ { MAD_F(0x043a6e61) /* 0.264265422 */, 17 }, - /* 2540 */ { MAD_F(0x043affe8) /* 0.264404208 */, 17 }, - /* 2541 */ { MAD_F(0x043b9174) /* 0.264543012 */, 17 }, - /* 2542 */ { MAD_F(0x043c2305) /* 0.264681834 */, 17 }, - /* 2543 */ { MAD_F(0x043cb49a) /* 0.264820674 */, 17 }, - - /* 2544 */ { MAD_F(0x043d4635) /* 0.264959533 */, 17 }, - /* 2545 */ { MAD_F(0x043dd7d4) /* 0.265098410 */, 17 }, - /* 2546 */ { MAD_F(0x043e6979) /* 0.265237305 */, 17 }, - /* 2547 */ { MAD_F(0x043efb22) /* 0.265376218 */, 17 }, - /* 2548 */ { MAD_F(0x043f8cd0) /* 0.265515149 */, 17 }, - /* 2549 */ { MAD_F(0x04401e83) /* 0.265654099 */, 17 }, - /* 2550 */ { MAD_F(0x0440b03b) /* 0.265793066 */, 17 }, - /* 2551 */ { MAD_F(0x044141f7) /* 0.265932052 */, 17 }, - /* 2552 */ { MAD_F(0x0441d3b9) /* 0.266071056 */, 17 }, - /* 2553 */ { MAD_F(0x04426580) /* 0.266210078 */, 17 }, - /* 2554 */ { MAD_F(0x0442f74b) /* 0.266349119 */, 17 }, - /* 2555 */ { MAD_F(0x0443891b) /* 0.266488177 */, 17 }, - /* 2556 */ { MAD_F(0x04441af0) /* 0.266627254 */, 17 }, - /* 2557 */ { MAD_F(0x0444acca) /* 0.266766349 */, 17 }, - /* 2558 */ { MAD_F(0x04453ea9) /* 0.266905462 */, 17 }, - /* 2559 */ { MAD_F(0x0445d08d) /* 0.267044593 */, 17 }, - - /* 2560 */ { MAD_F(0x04466275) /* 0.267183742 */, 17 }, - /* 2561 */ { MAD_F(0x0446f463) /* 0.267322909 */, 17 }, - /* 2562 */ { MAD_F(0x04478655) /* 0.267462094 */, 17 }, - /* 2563 */ { MAD_F(0x0448184c) /* 0.267601298 */, 17 }, - /* 2564 */ { MAD_F(0x0448aa48) /* 0.267740519 */, 17 }, - /* 2565 */ { MAD_F(0x04493c49) /* 0.267879759 */, 17 }, - /* 2566 */ { MAD_F(0x0449ce4f) /* 0.268019017 */, 17 }, - /* 2567 */ { MAD_F(0x044a6059) /* 0.268158293 */, 17 }, - /* 2568 */ { MAD_F(0x044af269) /* 0.268297587 */, 17 }, - /* 2569 */ { MAD_F(0x044b847d) /* 0.268436899 */, 17 }, - /* 2570 */ { MAD_F(0x044c1696) /* 0.268576229 */, 17 }, - /* 2571 */ { MAD_F(0x044ca8b4) /* 0.268715577 */, 17 }, - /* 2572 */ { MAD_F(0x044d3ad7) /* 0.268854943 */, 17 }, - /* 2573 */ { MAD_F(0x044dccff) /* 0.268994328 */, 17 }, - /* 2574 */ { MAD_F(0x044e5f2b) /* 0.269133730 */, 17 }, - /* 2575 */ { MAD_F(0x044ef15d) /* 0.269273150 */, 17 }, - - /* 2576 */ { MAD_F(0x044f8393) /* 0.269412589 */, 17 }, - /* 2577 */ { MAD_F(0x045015ce) /* 0.269552045 */, 17 }, - /* 2578 */ { MAD_F(0x0450a80e) /* 0.269691520 */, 17 }, - /* 2579 */ { MAD_F(0x04513a53) /* 0.269831013 */, 17 }, - /* 2580 */ { MAD_F(0x0451cc9c) /* 0.269970523 */, 17 }, - /* 2581 */ { MAD_F(0x04525eeb) /* 0.270110052 */, 17 }, - /* 2582 */ { MAD_F(0x0452f13e) /* 0.270249599 */, 17 }, - /* 2583 */ { MAD_F(0x04538396) /* 0.270389163 */, 17 }, - /* 2584 */ { MAD_F(0x045415f3) /* 0.270528746 */, 17 }, - /* 2585 */ { MAD_F(0x0454a855) /* 0.270668347 */, 17 }, - /* 2586 */ { MAD_F(0x04553abb) /* 0.270807965 */, 17 }, - /* 2587 */ { MAD_F(0x0455cd27) /* 0.270947602 */, 17 }, - /* 2588 */ { MAD_F(0x04565f97) /* 0.271087257 */, 17 }, - /* 2589 */ { MAD_F(0x0456f20c) /* 0.271226930 */, 17 }, - /* 2590 */ { MAD_F(0x04578486) /* 0.271366620 */, 17 }, - /* 2591 */ { MAD_F(0x04581705) /* 0.271506329 */, 17 }, - - /* 2592 */ { MAD_F(0x0458a989) /* 0.271646056 */, 17 }, - /* 2593 */ { MAD_F(0x04593c11) /* 0.271785800 */, 17 }, - /* 2594 */ { MAD_F(0x0459ce9e) /* 0.271925563 */, 17 }, - /* 2595 */ { MAD_F(0x045a6130) /* 0.272065343 */, 17 }, - /* 2596 */ { MAD_F(0x045af3c7) /* 0.272205142 */, 17 }, - /* 2597 */ { MAD_F(0x045b8663) /* 0.272344958 */, 17 }, - /* 2598 */ { MAD_F(0x045c1903) /* 0.272484793 */, 17 }, - /* 2599 */ { MAD_F(0x045caba9) /* 0.272624645 */, 17 }, - /* 2600 */ { MAD_F(0x045d3e53) /* 0.272764515 */, 17 }, - /* 2601 */ { MAD_F(0x045dd102) /* 0.272904403 */, 17 }, - /* 2602 */ { MAD_F(0x045e63b6) /* 0.273044310 */, 17 }, - /* 2603 */ { MAD_F(0x045ef66e) /* 0.273184234 */, 17 }, - /* 2604 */ { MAD_F(0x045f892b) /* 0.273324176 */, 17 }, - /* 2605 */ { MAD_F(0x04601bee) /* 0.273464136 */, 17 }, - /* 2606 */ { MAD_F(0x0460aeb5) /* 0.273604113 */, 17 }, - /* 2607 */ { MAD_F(0x04614180) /* 0.273744109 */, 17 }, - - /* 2608 */ { MAD_F(0x0461d451) /* 0.273884123 */, 17 }, - /* 2609 */ { MAD_F(0x04626727) /* 0.274024154 */, 17 }, - /* 2610 */ { MAD_F(0x0462fa01) /* 0.274164204 */, 17 }, - /* 2611 */ { MAD_F(0x04638ce0) /* 0.274304271 */, 17 }, - /* 2612 */ { MAD_F(0x04641fc4) /* 0.274444356 */, 17 }, - /* 2613 */ { MAD_F(0x0464b2ac) /* 0.274584459 */, 17 }, - /* 2614 */ { MAD_F(0x0465459a) /* 0.274724580 */, 17 }, - /* 2615 */ { MAD_F(0x0465d88c) /* 0.274864719 */, 17 }, - /* 2616 */ { MAD_F(0x04666b83) /* 0.275004875 */, 17 }, - /* 2617 */ { MAD_F(0x0466fe7f) /* 0.275145050 */, 17 }, - /* 2618 */ { MAD_F(0x0467917f) /* 0.275285242 */, 17 }, - /* 2619 */ { MAD_F(0x04682485) /* 0.275425452 */, 17 }, - /* 2620 */ { MAD_F(0x0468b78f) /* 0.275565681 */, 17 }, - /* 2621 */ { MAD_F(0x04694a9e) /* 0.275705926 */, 17 }, - /* 2622 */ { MAD_F(0x0469ddb2) /* 0.275846190 */, 17 }, - /* 2623 */ { MAD_F(0x046a70ca) /* 0.275986472 */, 17 }, - - /* 2624 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 17 }, - /* 2625 */ { MAD_F(0x046b970a) /* 0.276267088 */, 17 }, - /* 2626 */ { MAD_F(0x046c2a31) /* 0.276407423 */, 17 }, - /* 2627 */ { MAD_F(0x046cbd5c) /* 0.276547776 */, 17 }, - /* 2628 */ { MAD_F(0x046d508d) /* 0.276688147 */, 17 }, - /* 2629 */ { MAD_F(0x046de3c2) /* 0.276828535 */, 17 }, - /* 2630 */ { MAD_F(0x046e76fc) /* 0.276968942 */, 17 }, - /* 2631 */ { MAD_F(0x046f0a3b) /* 0.277109366 */, 17 }, - /* 2632 */ { MAD_F(0x046f9d7e) /* 0.277249808 */, 17 }, - /* 2633 */ { MAD_F(0x047030c7) /* 0.277390267 */, 17 }, - /* 2634 */ { MAD_F(0x0470c414) /* 0.277530745 */, 17 }, - /* 2635 */ { MAD_F(0x04715766) /* 0.277671240 */, 17 }, - /* 2636 */ { MAD_F(0x0471eabc) /* 0.277811753 */, 17 }, - /* 2637 */ { MAD_F(0x04727e18) /* 0.277952284 */, 17 }, - /* 2638 */ { MAD_F(0x04731178) /* 0.278092832 */, 17 }, - /* 2639 */ { MAD_F(0x0473a4dd) /* 0.278233399 */, 17 }, - - /* 2640 */ { MAD_F(0x04743847) /* 0.278373983 */, 17 }, - /* 2641 */ { MAD_F(0x0474cbb5) /* 0.278514584 */, 17 }, - /* 2642 */ { MAD_F(0x04755f29) /* 0.278655204 */, 17 }, - /* 2643 */ { MAD_F(0x0475f2a1) /* 0.278795841 */, 17 }, - /* 2644 */ { MAD_F(0x0476861d) /* 0.278936496 */, 17 }, - /* 2645 */ { MAD_F(0x0477199f) /* 0.279077169 */, 17 }, - /* 2646 */ { MAD_F(0x0477ad25) /* 0.279217860 */, 17 }, - /* 2647 */ { MAD_F(0x047840b0) /* 0.279358568 */, 17 }, - /* 2648 */ { MAD_F(0x0478d440) /* 0.279499294 */, 17 }, - /* 2649 */ { MAD_F(0x047967d5) /* 0.279640037 */, 17 }, - /* 2650 */ { MAD_F(0x0479fb6e) /* 0.279780799 */, 17 }, - /* 2651 */ { MAD_F(0x047a8f0c) /* 0.279921578 */, 17 }, - /* 2652 */ { MAD_F(0x047b22af) /* 0.280062375 */, 17 }, - /* 2653 */ { MAD_F(0x047bb657) /* 0.280203189 */, 17 }, - /* 2654 */ { MAD_F(0x047c4a03) /* 0.280344021 */, 17 }, - /* 2655 */ { MAD_F(0x047cddb4) /* 0.280484871 */, 17 }, - - /* 2656 */ { MAD_F(0x047d716a) /* 0.280625739 */, 17 }, - /* 2657 */ { MAD_F(0x047e0524) /* 0.280766624 */, 17 }, - /* 2658 */ { MAD_F(0x047e98e4) /* 0.280907527 */, 17 }, - /* 2659 */ { MAD_F(0x047f2ca8) /* 0.281048447 */, 17 }, - /* 2660 */ { MAD_F(0x047fc071) /* 0.281189385 */, 17 }, - /* 2661 */ { MAD_F(0x0480543e) /* 0.281330341 */, 17 }, - /* 2662 */ { MAD_F(0x0480e811) /* 0.281471315 */, 17 }, - /* 2663 */ { MAD_F(0x04817be8) /* 0.281612306 */, 17 }, - /* 2664 */ { MAD_F(0x04820fc3) /* 0.281753315 */, 17 }, - /* 2665 */ { MAD_F(0x0482a3a4) /* 0.281894341 */, 17 }, - /* 2666 */ { MAD_F(0x04833789) /* 0.282035386 */, 17 }, - /* 2667 */ { MAD_F(0x0483cb73) /* 0.282176447 */, 17 }, - /* 2668 */ { MAD_F(0x04845f62) /* 0.282317527 */, 17 }, - /* 2669 */ { MAD_F(0x0484f355) /* 0.282458624 */, 17 }, - /* 2670 */ { MAD_F(0x0485874d) /* 0.282599738 */, 17 }, - /* 2671 */ { MAD_F(0x04861b4a) /* 0.282740871 */, 17 }, - - /* 2672 */ { MAD_F(0x0486af4c) /* 0.282882021 */, 17 }, - /* 2673 */ { MAD_F(0x04874352) /* 0.283023188 */, 17 }, - /* 2674 */ { MAD_F(0x0487d75d) /* 0.283164373 */, 17 }, - /* 2675 */ { MAD_F(0x04886b6d) /* 0.283305576 */, 17 }, - /* 2676 */ { MAD_F(0x0488ff82) /* 0.283446796 */, 17 }, - /* 2677 */ { MAD_F(0x0489939b) /* 0.283588034 */, 17 }, - /* 2678 */ { MAD_F(0x048a27b9) /* 0.283729290 */, 17 }, - /* 2679 */ { MAD_F(0x048abbdc) /* 0.283870563 */, 17 }, - /* 2680 */ { MAD_F(0x048b5003) /* 0.284011853 */, 17 }, - /* 2681 */ { MAD_F(0x048be42f) /* 0.284153161 */, 17 }, - /* 2682 */ { MAD_F(0x048c7860) /* 0.284294487 */, 17 }, - /* 2683 */ { MAD_F(0x048d0c96) /* 0.284435831 */, 17 }, - /* 2684 */ { MAD_F(0x048da0d0) /* 0.284577192 */, 17 }, - /* 2685 */ { MAD_F(0x048e350f) /* 0.284718570 */, 17 }, - /* 2686 */ { MAD_F(0x048ec953) /* 0.284859966 */, 17 }, - /* 2687 */ { MAD_F(0x048f5d9b) /* 0.285001380 */, 17 }, - - /* 2688 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 17 }, - /* 2689 */ { MAD_F(0x0490863a) /* 0.285284259 */, 17 }, - /* 2690 */ { MAD_F(0x04911a91) /* 0.285425726 */, 17 }, - /* 2691 */ { MAD_F(0x0491aeec) /* 0.285567209 */, 17 }, - /* 2692 */ { MAD_F(0x0492434c) /* 0.285708711 */, 17 }, - /* 2693 */ { MAD_F(0x0492d7b0) /* 0.285850229 */, 17 }, - /* 2694 */ { MAD_F(0x04936c1a) /* 0.285991766 */, 17 }, - /* 2695 */ { MAD_F(0x04940088) /* 0.286133319 */, 17 }, - /* 2696 */ { MAD_F(0x049494fb) /* 0.286274891 */, 17 }, - /* 2697 */ { MAD_F(0x04952972) /* 0.286416480 */, 17 }, - /* 2698 */ { MAD_F(0x0495bdee) /* 0.286558086 */, 17 }, - /* 2699 */ { MAD_F(0x0496526f) /* 0.286699710 */, 17 }, - /* 2700 */ { MAD_F(0x0496e6f5) /* 0.286841351 */, 17 }, - /* 2701 */ { MAD_F(0x04977b7f) /* 0.286983010 */, 17 }, - /* 2702 */ { MAD_F(0x0498100e) /* 0.287124686 */, 17 }, - /* 2703 */ { MAD_F(0x0498a4a1) /* 0.287266380 */, 17 }, - - /* 2704 */ { MAD_F(0x0499393a) /* 0.287408091 */, 17 }, - /* 2705 */ { MAD_F(0x0499cdd7) /* 0.287549820 */, 17 }, - /* 2706 */ { MAD_F(0x049a6278) /* 0.287691566 */, 17 }, - /* 2707 */ { MAD_F(0x049af71f) /* 0.287833330 */, 17 }, - /* 2708 */ { MAD_F(0x049b8bca) /* 0.287975111 */, 17 }, - /* 2709 */ { MAD_F(0x049c207a) /* 0.288116909 */, 17 }, - /* 2710 */ { MAD_F(0x049cb52e) /* 0.288258725 */, 17 }, - /* 2711 */ { MAD_F(0x049d49e7) /* 0.288400559 */, 17 }, - /* 2712 */ { MAD_F(0x049ddea5) /* 0.288542409 */, 17 }, - /* 2713 */ { MAD_F(0x049e7367) /* 0.288684278 */, 17 }, - /* 2714 */ { MAD_F(0x049f082f) /* 0.288826163 */, 17 }, - /* 2715 */ { MAD_F(0x049f9cfa) /* 0.288968067 */, 17 }, - /* 2716 */ { MAD_F(0x04a031cb) /* 0.289109987 */, 17 }, - /* 2717 */ { MAD_F(0x04a0c6a0) /* 0.289251925 */, 17 }, - /* 2718 */ { MAD_F(0x04a15b7a) /* 0.289393881 */, 17 }, - /* 2719 */ { MAD_F(0x04a1f059) /* 0.289535854 */, 17 }, - - /* 2720 */ { MAD_F(0x04a2853c) /* 0.289677844 */, 17 }, - /* 2721 */ { MAD_F(0x04a31a24) /* 0.289819851 */, 17 }, - /* 2722 */ { MAD_F(0x04a3af10) /* 0.289961876 */, 17 }, - /* 2723 */ { MAD_F(0x04a44401) /* 0.290103919 */, 17 }, - /* 2724 */ { MAD_F(0x04a4d8f7) /* 0.290245979 */, 17 }, - /* 2725 */ { MAD_F(0x04a56df2) /* 0.290388056 */, 17 }, - /* 2726 */ { MAD_F(0x04a602f1) /* 0.290530150 */, 17 }, - /* 2727 */ { MAD_F(0x04a697f5) /* 0.290672262 */, 17 }, - /* 2728 */ { MAD_F(0x04a72cfe) /* 0.290814392 */, 17 }, - /* 2729 */ { MAD_F(0x04a7c20b) /* 0.290956538 */, 17 }, - /* 2730 */ { MAD_F(0x04a8571d) /* 0.291098703 */, 17 }, - /* 2731 */ { MAD_F(0x04a8ec33) /* 0.291240884 */, 17 }, - /* 2732 */ { MAD_F(0x04a9814e) /* 0.291383083 */, 17 }, - /* 2733 */ { MAD_F(0x04aa166e) /* 0.291525299 */, 17 }, - /* 2734 */ { MAD_F(0x04aaab93) /* 0.291667532 */, 17 }, - /* 2735 */ { MAD_F(0x04ab40bc) /* 0.291809783 */, 17 }, - - /* 2736 */ { MAD_F(0x04abd5ea) /* 0.291952051 */, 17 }, - /* 2737 */ { MAD_F(0x04ac6b1c) /* 0.292094337 */, 17 }, - /* 2738 */ { MAD_F(0x04ad0053) /* 0.292236640 */, 17 }, - /* 2739 */ { MAD_F(0x04ad958f) /* 0.292378960 */, 17 }, - /* 2740 */ { MAD_F(0x04ae2ad0) /* 0.292521297 */, 17 }, - /* 2741 */ { MAD_F(0x04aec015) /* 0.292663652 */, 17 }, - /* 2742 */ { MAD_F(0x04af555e) /* 0.292806024 */, 17 }, - /* 2743 */ { MAD_F(0x04afeaad) /* 0.292948414 */, 17 }, - /* 2744 */ { MAD_F(0x04b08000) /* 0.293090820 */, 17 }, - /* 2745 */ { MAD_F(0x04b11557) /* 0.293233244 */, 17 }, - /* 2746 */ { MAD_F(0x04b1aab4) /* 0.293375686 */, 17 }, - /* 2747 */ { MAD_F(0x04b24015) /* 0.293518144 */, 17 }, - /* 2748 */ { MAD_F(0x04b2d57a) /* 0.293660620 */, 17 }, - /* 2749 */ { MAD_F(0x04b36ae4) /* 0.293803113 */, 17 }, - /* 2750 */ { MAD_F(0x04b40053) /* 0.293945624 */, 17 }, - /* 2751 */ { MAD_F(0x04b495c7) /* 0.294088151 */, 17 }, - - /* 2752 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 17 }, - /* 2753 */ { MAD_F(0x04b5c0bc) /* 0.294373259 */, 17 }, - /* 2754 */ { MAD_F(0x04b6563d) /* 0.294515838 */, 17 }, - /* 2755 */ { MAD_F(0x04b6ebc3) /* 0.294658435 */, 17 }, - /* 2756 */ { MAD_F(0x04b7814e) /* 0.294801049 */, 17 }, - /* 2757 */ { MAD_F(0x04b816dd) /* 0.294943680 */, 17 }, - /* 2758 */ { MAD_F(0x04b8ac71) /* 0.295086329 */, 17 }, - /* 2759 */ { MAD_F(0x04b9420a) /* 0.295228995 */, 17 }, - /* 2760 */ { MAD_F(0x04b9d7a7) /* 0.295371678 */, 17 }, - /* 2761 */ { MAD_F(0x04ba6d49) /* 0.295514378 */, 17 }, - /* 2762 */ { MAD_F(0x04bb02ef) /* 0.295657095 */, 17 }, - /* 2763 */ { MAD_F(0x04bb989a) /* 0.295799830 */, 17 }, - /* 2764 */ { MAD_F(0x04bc2e4a) /* 0.295942582 */, 17 }, - /* 2765 */ { MAD_F(0x04bcc3fe) /* 0.296085351 */, 17 }, - /* 2766 */ { MAD_F(0x04bd59b7) /* 0.296228138 */, 17 }, - /* 2767 */ { MAD_F(0x04bdef74) /* 0.296370941 */, 17 }, - - /* 2768 */ { MAD_F(0x04be8537) /* 0.296513762 */, 17 }, - /* 2769 */ { MAD_F(0x04bf1afd) /* 0.296656600 */, 17 }, - /* 2770 */ { MAD_F(0x04bfb0c9) /* 0.296799455 */, 17 }, - /* 2771 */ { MAD_F(0x04c04699) /* 0.296942327 */, 17 }, - /* 2772 */ { MAD_F(0x04c0dc6d) /* 0.297085217 */, 17 }, - /* 2773 */ { MAD_F(0x04c17247) /* 0.297228124 */, 17 }, - /* 2774 */ { MAD_F(0x04c20824) /* 0.297371048 */, 17 }, - /* 2775 */ { MAD_F(0x04c29e07) /* 0.297513989 */, 17 }, - /* 2776 */ { MAD_F(0x04c333ee) /* 0.297656947 */, 17 }, - /* 2777 */ { MAD_F(0x04c3c9da) /* 0.297799922 */, 17 }, - /* 2778 */ { MAD_F(0x04c45fca) /* 0.297942915 */, 17 }, - /* 2779 */ { MAD_F(0x04c4f5bf) /* 0.298085925 */, 17 }, - /* 2780 */ { MAD_F(0x04c58bb8) /* 0.298228951 */, 17 }, - /* 2781 */ { MAD_F(0x04c621b6) /* 0.298371996 */, 17 }, - /* 2782 */ { MAD_F(0x04c6b7b9) /* 0.298515057 */, 17 }, - /* 2783 */ { MAD_F(0x04c74dc0) /* 0.298658135 */, 17 }, - - /* 2784 */ { MAD_F(0x04c7e3cc) /* 0.298801231 */, 17 }, - /* 2785 */ { MAD_F(0x04c879dd) /* 0.298944343 */, 17 }, - /* 2786 */ { MAD_F(0x04c90ff2) /* 0.299087473 */, 17 }, - /* 2787 */ { MAD_F(0x04c9a60c) /* 0.299230620 */, 17 }, - /* 2788 */ { MAD_F(0x04ca3c2a) /* 0.299373784 */, 17 }, - /* 2789 */ { MAD_F(0x04cad24d) /* 0.299516965 */, 17 }, - /* 2790 */ { MAD_F(0x04cb6874) /* 0.299660163 */, 17 }, - /* 2791 */ { MAD_F(0x04cbfea0) /* 0.299803378 */, 17 }, - /* 2792 */ { MAD_F(0x04cc94d1) /* 0.299946611 */, 17 }, - /* 2793 */ { MAD_F(0x04cd2b06) /* 0.300089860 */, 17 }, - /* 2794 */ { MAD_F(0x04cdc140) /* 0.300233127 */, 17 }, - /* 2795 */ { MAD_F(0x04ce577f) /* 0.300376411 */, 17 }, - /* 2796 */ { MAD_F(0x04ceedc2) /* 0.300519711 */, 17 }, - /* 2797 */ { MAD_F(0x04cf8409) /* 0.300663029 */, 17 }, - /* 2798 */ { MAD_F(0x04d01a55) /* 0.300806364 */, 17 }, - /* 2799 */ { MAD_F(0x04d0b0a6) /* 0.300949716 */, 17 }, - - /* 2800 */ { MAD_F(0x04d146fb) /* 0.301093085 */, 17 }, - /* 2801 */ { MAD_F(0x04d1dd55) /* 0.301236472 */, 17 }, - /* 2802 */ { MAD_F(0x04d273b4) /* 0.301379875 */, 17 }, - /* 2803 */ { MAD_F(0x04d30a17) /* 0.301523295 */, 17 }, - /* 2804 */ { MAD_F(0x04d3a07f) /* 0.301666733 */, 17 }, - /* 2805 */ { MAD_F(0x04d436eb) /* 0.301810187 */, 17 }, - /* 2806 */ { MAD_F(0x04d4cd5c) /* 0.301953659 */, 17 }, - /* 2807 */ { MAD_F(0x04d563d1) /* 0.302097147 */, 17 }, - /* 2808 */ { MAD_F(0x04d5fa4b) /* 0.302240653 */, 17 }, - /* 2809 */ { MAD_F(0x04d690ca) /* 0.302384175 */, 17 }, - /* 2810 */ { MAD_F(0x04d7274d) /* 0.302527715 */, 17 }, - /* 2811 */ { MAD_F(0x04d7bdd5) /* 0.302671271 */, 17 }, - /* 2812 */ { MAD_F(0x04d85461) /* 0.302814845 */, 17 }, - /* 2813 */ { MAD_F(0x04d8eaf2) /* 0.302958436 */, 17 }, - /* 2814 */ { MAD_F(0x04d98187) /* 0.303102044 */, 17 }, - /* 2815 */ { MAD_F(0x04da1821) /* 0.303245668 */, 17 }, - - /* 2816 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 17 }, - /* 2817 */ { MAD_F(0x04db4563) /* 0.303532969 */, 17 }, - /* 2818 */ { MAD_F(0x04dbdc0a) /* 0.303676645 */, 17 }, - /* 2819 */ { MAD_F(0x04dc72b7) /* 0.303820337 */, 17 }, - /* 2820 */ { MAD_F(0x04dd0967) /* 0.303964047 */, 17 }, - /* 2821 */ { MAD_F(0x04dda01d) /* 0.304107774 */, 17 }, - /* 2822 */ { MAD_F(0x04de36d7) /* 0.304251517 */, 17 }, - /* 2823 */ { MAD_F(0x04decd95) /* 0.304395278 */, 17 }, - /* 2824 */ { MAD_F(0x04df6458) /* 0.304539056 */, 17 }, - /* 2825 */ { MAD_F(0x04dffb20) /* 0.304682850 */, 17 }, - /* 2826 */ { MAD_F(0x04e091ec) /* 0.304826662 */, 17 }, - /* 2827 */ { MAD_F(0x04e128bc) /* 0.304970491 */, 17 }, - /* 2828 */ { MAD_F(0x04e1bf92) /* 0.305114336 */, 17 }, - /* 2829 */ { MAD_F(0x04e2566b) /* 0.305258199 */, 17 }, - /* 2830 */ { MAD_F(0x04e2ed4a) /* 0.305402078 */, 17 }, - /* 2831 */ { MAD_F(0x04e3842d) /* 0.305545974 */, 17 }, - - /* 2832 */ { MAD_F(0x04e41b14) /* 0.305689888 */, 17 }, - /* 2833 */ { MAD_F(0x04e4b200) /* 0.305833818 */, 17 }, - /* 2834 */ { MAD_F(0x04e548f1) /* 0.305977765 */, 17 }, - /* 2835 */ { MAD_F(0x04e5dfe6) /* 0.306121729 */, 17 }, - /* 2836 */ { MAD_F(0x04e676df) /* 0.306265710 */, 17 }, - /* 2837 */ { MAD_F(0x04e70dde) /* 0.306409708 */, 17 }, - /* 2838 */ { MAD_F(0x04e7a4e0) /* 0.306553723 */, 17 }, - /* 2839 */ { MAD_F(0x04e83be7) /* 0.306697755 */, 17 }, - /* 2840 */ { MAD_F(0x04e8d2f3) /* 0.306841804 */, 17 }, - /* 2841 */ { MAD_F(0x04e96a04) /* 0.306985869 */, 17 }, - /* 2842 */ { MAD_F(0x04ea0118) /* 0.307129952 */, 17 }, - /* 2843 */ { MAD_F(0x04ea9832) /* 0.307274051 */, 17 }, - /* 2844 */ { MAD_F(0x04eb2f50) /* 0.307418168 */, 17 }, - /* 2845 */ { MAD_F(0x04ebc672) /* 0.307562301 */, 17 }, - /* 2846 */ { MAD_F(0x04ec5d99) /* 0.307706451 */, 17 }, - /* 2847 */ { MAD_F(0x04ecf4c5) /* 0.307850618 */, 17 }, - - /* 2848 */ { MAD_F(0x04ed8bf5) /* 0.307994802 */, 17 }, - /* 2849 */ { MAD_F(0x04ee2329) /* 0.308139003 */, 17 }, - /* 2850 */ { MAD_F(0x04eeba63) /* 0.308283220 */, 17 }, - /* 2851 */ { MAD_F(0x04ef51a0) /* 0.308427455 */, 17 }, - /* 2852 */ { MAD_F(0x04efe8e2) /* 0.308571706 */, 17 }, - /* 2853 */ { MAD_F(0x04f08029) /* 0.308715974 */, 17 }, - /* 2854 */ { MAD_F(0x04f11774) /* 0.308860260 */, 17 }, - /* 2855 */ { MAD_F(0x04f1aec4) /* 0.309004561 */, 17 }, - /* 2856 */ { MAD_F(0x04f24618) /* 0.309148880 */, 17 }, - /* 2857 */ { MAD_F(0x04f2dd71) /* 0.309293216 */, 17 }, - /* 2858 */ { MAD_F(0x04f374cf) /* 0.309437568 */, 17 }, - /* 2859 */ { MAD_F(0x04f40c30) /* 0.309581938 */, 17 }, - /* 2860 */ { MAD_F(0x04f4a397) /* 0.309726324 */, 17 }, - /* 2861 */ { MAD_F(0x04f53b02) /* 0.309870727 */, 17 }, - /* 2862 */ { MAD_F(0x04f5d271) /* 0.310015147 */, 17 }, - /* 2863 */ { MAD_F(0x04f669e5) /* 0.310159583 */, 17 }, - - /* 2864 */ { MAD_F(0x04f7015d) /* 0.310304037 */, 17 }, - /* 2865 */ { MAD_F(0x04f798da) /* 0.310448507 */, 17 }, - /* 2866 */ { MAD_F(0x04f8305c) /* 0.310592994 */, 17 }, - /* 2867 */ { MAD_F(0x04f8c7e2) /* 0.310737498 */, 17 }, - /* 2868 */ { MAD_F(0x04f95f6c) /* 0.310882018 */, 17 }, - /* 2869 */ { MAD_F(0x04f9f6fb) /* 0.311026556 */, 17 }, - /* 2870 */ { MAD_F(0x04fa8e8f) /* 0.311171110 */, 17 }, - /* 2871 */ { MAD_F(0x04fb2627) /* 0.311315681 */, 17 }, - /* 2872 */ { MAD_F(0x04fbbdc3) /* 0.311460269 */, 17 }, - /* 2873 */ { MAD_F(0x04fc5564) /* 0.311604874 */, 17 }, - /* 2874 */ { MAD_F(0x04fced0a) /* 0.311749495 */, 17 }, - /* 2875 */ { MAD_F(0x04fd84b4) /* 0.311894133 */, 17 }, - /* 2876 */ { MAD_F(0x04fe1c62) /* 0.312038788 */, 17 }, - /* 2877 */ { MAD_F(0x04feb415) /* 0.312183460 */, 17 }, - /* 2878 */ { MAD_F(0x04ff4bcd) /* 0.312328148 */, 17 }, - /* 2879 */ { MAD_F(0x04ffe389) /* 0.312472854 */, 17 }, - - /* 2880 */ { MAD_F(0x05007b49) /* 0.312617576 */, 17 }, - /* 2881 */ { MAD_F(0x0501130e) /* 0.312762314 */, 17 }, - /* 2882 */ { MAD_F(0x0501aad8) /* 0.312907070 */, 17 }, - /* 2883 */ { MAD_F(0x050242a6) /* 0.313051842 */, 17 }, - /* 2884 */ { MAD_F(0x0502da78) /* 0.313196631 */, 17 }, - /* 2885 */ { MAD_F(0x0503724f) /* 0.313341437 */, 17 }, - /* 2886 */ { MAD_F(0x05040a2b) /* 0.313486259 */, 17 }, - /* 2887 */ { MAD_F(0x0504a20b) /* 0.313631098 */, 17 }, - /* 2888 */ { MAD_F(0x050539ef) /* 0.313775954 */, 17 }, - /* 2889 */ { MAD_F(0x0505d1d8) /* 0.313920827 */, 17 }, - /* 2890 */ { MAD_F(0x050669c5) /* 0.314065716 */, 17 }, - /* 2891 */ { MAD_F(0x050701b7) /* 0.314210622 */, 17 }, - /* 2892 */ { MAD_F(0x050799ae) /* 0.314355545 */, 17 }, - /* 2893 */ { MAD_F(0x050831a9) /* 0.314500484 */, 17 }, - /* 2894 */ { MAD_F(0x0508c9a8) /* 0.314645440 */, 17 }, - /* 2895 */ { MAD_F(0x050961ac) /* 0.314790413 */, 17 }, - - /* 2896 */ { MAD_F(0x0509f9b4) /* 0.314935403 */, 17 }, - /* 2897 */ { MAD_F(0x050a91c1) /* 0.315080409 */, 17 }, - /* 2898 */ { MAD_F(0x050b29d2) /* 0.315225432 */, 17 }, - /* 2899 */ { MAD_F(0x050bc1e8) /* 0.315370472 */, 17 }, - /* 2900 */ { MAD_F(0x050c5a02) /* 0.315515528 */, 17 }, - /* 2901 */ { MAD_F(0x050cf221) /* 0.315660601 */, 17 }, - /* 2902 */ { MAD_F(0x050d8a44) /* 0.315805690 */, 17 }, - /* 2903 */ { MAD_F(0x050e226c) /* 0.315950797 */, 17 }, - /* 2904 */ { MAD_F(0x050eba98) /* 0.316095920 */, 17 }, - /* 2905 */ { MAD_F(0x050f52c9) /* 0.316241059 */, 17 }, - /* 2906 */ { MAD_F(0x050feafe) /* 0.316386216 */, 17 }, - /* 2907 */ { MAD_F(0x05108337) /* 0.316531388 */, 17 }, - /* 2908 */ { MAD_F(0x05111b75) /* 0.316676578 */, 17 }, - /* 2909 */ { MAD_F(0x0511b3b8) /* 0.316821784 */, 17 }, - /* 2910 */ { MAD_F(0x05124bff) /* 0.316967007 */, 17 }, - /* 2911 */ { MAD_F(0x0512e44a) /* 0.317112247 */, 17 }, - - /* 2912 */ { MAD_F(0x05137c9a) /* 0.317257503 */, 17 }, - /* 2913 */ { MAD_F(0x051414ee) /* 0.317402775 */, 17 }, - /* 2914 */ { MAD_F(0x0514ad47) /* 0.317548065 */, 17 }, - /* 2915 */ { MAD_F(0x051545a5) /* 0.317693371 */, 17 }, - /* 2916 */ { MAD_F(0x0515de06) /* 0.317838693 */, 17 }, - /* 2917 */ { MAD_F(0x0516766d) /* 0.317984033 */, 17 }, - /* 2918 */ { MAD_F(0x05170ed7) /* 0.318129388 */, 17 }, - /* 2919 */ { MAD_F(0x0517a746) /* 0.318274761 */, 17 }, - /* 2920 */ { MAD_F(0x05183fba) /* 0.318420150 */, 17 }, - /* 2921 */ { MAD_F(0x0518d832) /* 0.318565555 */, 17 }, - /* 2922 */ { MAD_F(0x051970ae) /* 0.318710978 */, 17 }, - /* 2923 */ { MAD_F(0x051a092f) /* 0.318856416 */, 17 }, - /* 2924 */ { MAD_F(0x051aa1b5) /* 0.319001872 */, 17 }, - /* 2925 */ { MAD_F(0x051b3a3f) /* 0.319147344 */, 17 }, - /* 2926 */ { MAD_F(0x051bd2cd) /* 0.319292832 */, 17 }, - /* 2927 */ { MAD_F(0x051c6b60) /* 0.319438338 */, 17 }, - - /* 2928 */ { MAD_F(0x051d03f7) /* 0.319583859 */, 17 }, - /* 2929 */ { MAD_F(0x051d9c92) /* 0.319729398 */, 17 }, - /* 2930 */ { MAD_F(0x051e3532) /* 0.319874952 */, 17 }, - /* 2931 */ { MAD_F(0x051ecdd7) /* 0.320020524 */, 17 }, - /* 2932 */ { MAD_F(0x051f6680) /* 0.320166112 */, 17 }, - /* 2933 */ { MAD_F(0x051fff2d) /* 0.320311716 */, 17 }, - /* 2934 */ { MAD_F(0x052097df) /* 0.320457337 */, 17 }, - /* 2935 */ { MAD_F(0x05213095) /* 0.320602975 */, 17 }, - /* 2936 */ { MAD_F(0x0521c950) /* 0.320748629 */, 17 }, - /* 2937 */ { MAD_F(0x0522620f) /* 0.320894300 */, 17 }, - /* 2938 */ { MAD_F(0x0522fad3) /* 0.321039987 */, 17 }, - /* 2939 */ { MAD_F(0x0523939b) /* 0.321185691 */, 17 }, - /* 2940 */ { MAD_F(0x05242c68) /* 0.321331411 */, 17 }, - /* 2941 */ { MAD_F(0x0524c538) /* 0.321477148 */, 17 }, - /* 2942 */ { MAD_F(0x05255e0e) /* 0.321622901 */, 17 }, - /* 2943 */ { MAD_F(0x0525f6e8) /* 0.321768671 */, 17 }, - - /* 2944 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 17 }, - /* 2945 */ { MAD_F(0x052728a9) /* 0.322060260 */, 17 }, - /* 2946 */ { MAD_F(0x0527c190) /* 0.322206079 */, 17 }, - /* 2947 */ { MAD_F(0x05285a7b) /* 0.322351915 */, 17 }, - /* 2948 */ { MAD_F(0x0528f36b) /* 0.322497768 */, 17 }, - /* 2949 */ { MAD_F(0x05298c5f) /* 0.322643636 */, 17 }, - /* 2950 */ { MAD_F(0x052a2558) /* 0.322789522 */, 17 }, - /* 2951 */ { MAD_F(0x052abe55) /* 0.322935424 */, 17 }, - /* 2952 */ { MAD_F(0x052b5757) /* 0.323081342 */, 17 }, - /* 2953 */ { MAD_F(0x052bf05d) /* 0.323227277 */, 17 }, - /* 2954 */ { MAD_F(0x052c8968) /* 0.323373228 */, 17 }, - /* 2955 */ { MAD_F(0x052d2277) /* 0.323519196 */, 17 }, - /* 2956 */ { MAD_F(0x052dbb8a) /* 0.323665180 */, 17 }, - /* 2957 */ { MAD_F(0x052e54a2) /* 0.323811180 */, 17 }, - /* 2958 */ { MAD_F(0x052eedbe) /* 0.323957197 */, 17 }, - /* 2959 */ { MAD_F(0x052f86de) /* 0.324103231 */, 17 }, - - /* 2960 */ { MAD_F(0x05302003) /* 0.324249281 */, 17 }, - /* 2961 */ { MAD_F(0x0530b92d) /* 0.324395347 */, 17 }, - /* 2962 */ { MAD_F(0x0531525b) /* 0.324541430 */, 17 }, - /* 2963 */ { MAD_F(0x0531eb8d) /* 0.324687530 */, 17 }, - /* 2964 */ { MAD_F(0x053284c4) /* 0.324833646 */, 17 }, - /* 2965 */ { MAD_F(0x05331dff) /* 0.324979778 */, 17 }, - /* 2966 */ { MAD_F(0x0533b73e) /* 0.325125926 */, 17 }, - /* 2967 */ { MAD_F(0x05345082) /* 0.325272091 */, 17 }, - /* 2968 */ { MAD_F(0x0534e9ca) /* 0.325418273 */, 17 }, - /* 2969 */ { MAD_F(0x05358317) /* 0.325564471 */, 17 }, - /* 2970 */ { MAD_F(0x05361c68) /* 0.325710685 */, 17 }, - /* 2971 */ { MAD_F(0x0536b5be) /* 0.325856916 */, 17 }, - /* 2972 */ { MAD_F(0x05374f17) /* 0.326003163 */, 17 }, - /* 2973 */ { MAD_F(0x0537e876) /* 0.326149427 */, 17 }, - /* 2974 */ { MAD_F(0x053881d9) /* 0.326295707 */, 17 }, - /* 2975 */ { MAD_F(0x05391b40) /* 0.326442003 */, 17 }, - - /* 2976 */ { MAD_F(0x0539b4ab) /* 0.326588316 */, 17 }, - /* 2977 */ { MAD_F(0x053a4e1b) /* 0.326734645 */, 17 }, - /* 2978 */ { MAD_F(0x053ae78f) /* 0.326880990 */, 17 }, - /* 2979 */ { MAD_F(0x053b8108) /* 0.327027352 */, 17 }, - /* 2980 */ { MAD_F(0x053c1a85) /* 0.327173730 */, 17 }, - /* 2981 */ { MAD_F(0x053cb407) /* 0.327320125 */, 17 }, - /* 2982 */ { MAD_F(0x053d4d8d) /* 0.327466536 */, 17 }, - /* 2983 */ { MAD_F(0x053de717) /* 0.327612963 */, 17 }, - /* 2984 */ { MAD_F(0x053e80a6) /* 0.327759407 */, 17 }, - /* 2985 */ { MAD_F(0x053f1a39) /* 0.327905867 */, 17 }, - /* 2986 */ { MAD_F(0x053fb3d0) /* 0.328052344 */, 17 }, - /* 2987 */ { MAD_F(0x05404d6c) /* 0.328198837 */, 17 }, - /* 2988 */ { MAD_F(0x0540e70c) /* 0.328345346 */, 17 }, - /* 2989 */ { MAD_F(0x054180b1) /* 0.328491871 */, 17 }, - /* 2990 */ { MAD_F(0x05421a5a) /* 0.328638413 */, 17 }, - /* 2991 */ { MAD_F(0x0542b407) /* 0.328784971 */, 17 }, - - /* 2992 */ { MAD_F(0x05434db9) /* 0.328931546 */, 17 }, - /* 2993 */ { MAD_F(0x0543e76f) /* 0.329078137 */, 17 }, - /* 2994 */ { MAD_F(0x0544812a) /* 0.329224744 */, 17 }, - /* 2995 */ { MAD_F(0x05451ae9) /* 0.329371367 */, 17 }, - /* 2996 */ { MAD_F(0x0545b4ac) /* 0.329518007 */, 17 }, - /* 2997 */ { MAD_F(0x05464e74) /* 0.329664663 */, 17 }, - /* 2998 */ { MAD_F(0x0546e840) /* 0.329811336 */, 17 }, - /* 2999 */ { MAD_F(0x05478211) /* 0.329958024 */, 17 }, - /* 3000 */ { MAD_F(0x05481be5) /* 0.330104730 */, 17 }, - /* 3001 */ { MAD_F(0x0548b5bf) /* 0.330251451 */, 17 }, - /* 3002 */ { MAD_F(0x05494f9c) /* 0.330398189 */, 17 }, - /* 3003 */ { MAD_F(0x0549e97e) /* 0.330544943 */, 17 }, - /* 3004 */ { MAD_F(0x054a8364) /* 0.330691713 */, 17 }, - /* 3005 */ { MAD_F(0x054b1d4f) /* 0.330838499 */, 17 }, - /* 3006 */ { MAD_F(0x054bb73e) /* 0.330985302 */, 17 }, - /* 3007 */ { MAD_F(0x054c5132) /* 0.331132121 */, 17 }, - - /* 3008 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 17 }, - /* 3009 */ { MAD_F(0x054d8526) /* 0.331425808 */, 17 }, - /* 3010 */ { MAD_F(0x054e1f26) /* 0.331572676 */, 17 }, - /* 3011 */ { MAD_F(0x054eb92b) /* 0.331719560 */, 17 }, - /* 3012 */ { MAD_F(0x054f5334) /* 0.331866461 */, 17 }, - /* 3013 */ { MAD_F(0x054fed42) /* 0.332013377 */, 17 }, - /* 3014 */ { MAD_F(0x05508754) /* 0.332160310 */, 17 }, - /* 3015 */ { MAD_F(0x0551216b) /* 0.332307260 */, 17 }, - /* 3016 */ { MAD_F(0x0551bb85) /* 0.332454225 */, 17 }, - /* 3017 */ { MAD_F(0x055255a4) /* 0.332601207 */, 17 }, - /* 3018 */ { MAD_F(0x0552efc8) /* 0.332748205 */, 17 }, - /* 3019 */ { MAD_F(0x055389f0) /* 0.332895219 */, 17 }, - /* 3020 */ { MAD_F(0x0554241c) /* 0.333042249 */, 17 }, - /* 3021 */ { MAD_F(0x0554be4c) /* 0.333189296 */, 17 }, - /* 3022 */ { MAD_F(0x05555881) /* 0.333336359 */, 17 }, - /* 3023 */ { MAD_F(0x0555f2ba) /* 0.333483438 */, 17 }, - - /* 3024 */ { MAD_F(0x05568cf8) /* 0.333630533 */, 17 }, - /* 3025 */ { MAD_F(0x0557273a) /* 0.333777645 */, 17 }, - /* 3026 */ { MAD_F(0x0557c180) /* 0.333924772 */, 17 }, - /* 3027 */ { MAD_F(0x05585bcb) /* 0.334071916 */, 17 }, - /* 3028 */ { MAD_F(0x0558f61a) /* 0.334219076 */, 17 }, - /* 3029 */ { MAD_F(0x0559906d) /* 0.334366253 */, 17 }, - /* 3030 */ { MAD_F(0x055a2ac5) /* 0.334513445 */, 17 }, - /* 3031 */ { MAD_F(0x055ac521) /* 0.334660654 */, 17 }, - /* 3032 */ { MAD_F(0x055b5f81) /* 0.334807879 */, 17 }, - /* 3033 */ { MAD_F(0x055bf9e6) /* 0.334955120 */, 17 }, - /* 3034 */ { MAD_F(0x055c944f) /* 0.335102377 */, 17 }, - /* 3035 */ { MAD_F(0x055d2ebd) /* 0.335249651 */, 17 }, - /* 3036 */ { MAD_F(0x055dc92e) /* 0.335396941 */, 17 }, - /* 3037 */ { MAD_F(0x055e63a5) /* 0.335544246 */, 17 }, - /* 3038 */ { MAD_F(0x055efe1f) /* 0.335691568 */, 17 }, - /* 3039 */ { MAD_F(0x055f989e) /* 0.335838906 */, 17 }, - - /* 3040 */ { MAD_F(0x05603321) /* 0.335986261 */, 17 }, - /* 3041 */ { MAD_F(0x0560cda8) /* 0.336133631 */, 17 }, - /* 3042 */ { MAD_F(0x05616834) /* 0.336281018 */, 17 }, - /* 3043 */ { MAD_F(0x056202c4) /* 0.336428421 */, 17 }, - /* 3044 */ { MAD_F(0x05629d59) /* 0.336575840 */, 17 }, - /* 3045 */ { MAD_F(0x056337f2) /* 0.336723275 */, 17 }, - /* 3046 */ { MAD_F(0x0563d28f) /* 0.336870726 */, 17 }, - /* 3047 */ { MAD_F(0x05646d30) /* 0.337018193 */, 17 }, - /* 3048 */ { MAD_F(0x056507d6) /* 0.337165677 */, 17 }, - /* 3049 */ { MAD_F(0x0565a280) /* 0.337313176 */, 17 }, - /* 3050 */ { MAD_F(0x05663d2f) /* 0.337460692 */, 17 }, - /* 3051 */ { MAD_F(0x0566d7e1) /* 0.337608224 */, 17 }, - /* 3052 */ { MAD_F(0x05677298) /* 0.337755772 */, 17 }, - /* 3053 */ { MAD_F(0x05680d54) /* 0.337903336 */, 17 }, - /* 3054 */ { MAD_F(0x0568a814) /* 0.338050916 */, 17 }, - /* 3055 */ { MAD_F(0x056942d8) /* 0.338198513 */, 17 }, - - /* 3056 */ { MAD_F(0x0569dda0) /* 0.338346125 */, 17 }, - /* 3057 */ { MAD_F(0x056a786d) /* 0.338493753 */, 17 }, - /* 3058 */ { MAD_F(0x056b133e) /* 0.338641398 */, 17 }, - /* 3059 */ { MAD_F(0x056bae13) /* 0.338789059 */, 17 }, - /* 3060 */ { MAD_F(0x056c48ed) /* 0.338936736 */, 17 }, - /* 3061 */ { MAD_F(0x056ce3cb) /* 0.339084429 */, 17 }, - /* 3062 */ { MAD_F(0x056d7ead) /* 0.339232138 */, 17 }, - /* 3063 */ { MAD_F(0x056e1994) /* 0.339379863 */, 17 }, - /* 3064 */ { MAD_F(0x056eb47f) /* 0.339527604 */, 17 }, - /* 3065 */ { MAD_F(0x056f4f6e) /* 0.339675361 */, 17 }, - /* 3066 */ { MAD_F(0x056fea62) /* 0.339823134 */, 17 }, - /* 3067 */ { MAD_F(0x0570855a) /* 0.339970924 */, 17 }, - /* 3068 */ { MAD_F(0x05712056) /* 0.340118729 */, 17 }, - /* 3069 */ { MAD_F(0x0571bb56) /* 0.340266550 */, 17 }, - /* 3070 */ { MAD_F(0x0572565b) /* 0.340414388 */, 17 }, - /* 3071 */ { MAD_F(0x0572f164) /* 0.340562242 */, 17 }, - - /* 3072 */ { MAD_F(0x05738c72) /* 0.340710111 */, 17 }, - /* 3073 */ { MAD_F(0x05742784) /* 0.340857997 */, 17 }, - /* 3074 */ { MAD_F(0x0574c29a) /* 0.341005899 */, 17 }, - /* 3075 */ { MAD_F(0x05755db4) /* 0.341153816 */, 17 }, - /* 3076 */ { MAD_F(0x0575f8d3) /* 0.341301750 */, 17 }, - /* 3077 */ { MAD_F(0x057693f6) /* 0.341449700 */, 17 }, - /* 3078 */ { MAD_F(0x05772f1d) /* 0.341597666 */, 17 }, - /* 3079 */ { MAD_F(0x0577ca49) /* 0.341745648 */, 17 }, - /* 3080 */ { MAD_F(0x05786578) /* 0.341893646 */, 17 }, - /* 3081 */ { MAD_F(0x057900ad) /* 0.342041659 */, 17 }, - /* 3082 */ { MAD_F(0x05799be5) /* 0.342189689 */, 17 }, - /* 3083 */ { MAD_F(0x057a3722) /* 0.342337735 */, 17 }, - /* 3084 */ { MAD_F(0x057ad263) /* 0.342485797 */, 17 }, - /* 3085 */ { MAD_F(0x057b6da8) /* 0.342633875 */, 17 }, - /* 3086 */ { MAD_F(0x057c08f2) /* 0.342781969 */, 17 }, - /* 3087 */ { MAD_F(0x057ca440) /* 0.342930079 */, 17 }, - - /* 3088 */ { MAD_F(0x057d3f92) /* 0.343078205 */, 17 }, - /* 3089 */ { MAD_F(0x057ddae9) /* 0.343226347 */, 17 }, - /* 3090 */ { MAD_F(0x057e7644) /* 0.343374505 */, 17 }, - /* 3091 */ { MAD_F(0x057f11a3) /* 0.343522679 */, 17 }, - /* 3092 */ { MAD_F(0x057fad06) /* 0.343670869 */, 17 }, - /* 3093 */ { MAD_F(0x0580486e) /* 0.343819075 */, 17 }, - /* 3094 */ { MAD_F(0x0580e3da) /* 0.343967296 */, 17 }, - /* 3095 */ { MAD_F(0x05817f4a) /* 0.344115534 */, 17 }, - /* 3096 */ { MAD_F(0x05821abf) /* 0.344263788 */, 17 }, - /* 3097 */ { MAD_F(0x0582b638) /* 0.344412058 */, 17 }, - /* 3098 */ { MAD_F(0x058351b5) /* 0.344560343 */, 17 }, - /* 3099 */ { MAD_F(0x0583ed36) /* 0.344708645 */, 17 }, - /* 3100 */ { MAD_F(0x058488bc) /* 0.344856963 */, 17 }, - /* 3101 */ { MAD_F(0x05852446) /* 0.345005296 */, 17 }, - /* 3102 */ { MAD_F(0x0585bfd4) /* 0.345153646 */, 17 }, - /* 3103 */ { MAD_F(0x05865b67) /* 0.345302011 */, 17 }, - - /* 3104 */ { MAD_F(0x0586f6fd) /* 0.345450393 */, 17 }, - /* 3105 */ { MAD_F(0x05879298) /* 0.345598790 */, 17 }, - /* 3106 */ { MAD_F(0x05882e38) /* 0.345747203 */, 17 }, - /* 3107 */ { MAD_F(0x0588c9dc) /* 0.345895632 */, 17 }, - /* 3108 */ { MAD_F(0x05896583) /* 0.346044077 */, 17 }, - /* 3109 */ { MAD_F(0x058a0130) /* 0.346192538 */, 17 }, - /* 3110 */ { MAD_F(0x058a9ce0) /* 0.346341015 */, 17 }, - /* 3111 */ { MAD_F(0x058b3895) /* 0.346489508 */, 17 }, - /* 3112 */ { MAD_F(0x058bd44e) /* 0.346638017 */, 17 }, - /* 3113 */ { MAD_F(0x058c700b) /* 0.346786542 */, 17 }, - /* 3114 */ { MAD_F(0x058d0bcd) /* 0.346935082 */, 17 }, - /* 3115 */ { MAD_F(0x058da793) /* 0.347083639 */, 17 }, - /* 3116 */ { MAD_F(0x058e435d) /* 0.347232211 */, 17 }, - /* 3117 */ { MAD_F(0x058edf2b) /* 0.347380799 */, 17 }, - /* 3118 */ { MAD_F(0x058f7afe) /* 0.347529403 */, 17 }, - /* 3119 */ { MAD_F(0x059016d5) /* 0.347678023 */, 17 }, - - /* 3120 */ { MAD_F(0x0590b2b0) /* 0.347826659 */, 17 }, - /* 3121 */ { MAD_F(0x05914e8f) /* 0.347975311 */, 17 }, - /* 3122 */ { MAD_F(0x0591ea73) /* 0.348123979 */, 17 }, - /* 3123 */ { MAD_F(0x0592865b) /* 0.348272662 */, 17 }, - /* 3124 */ { MAD_F(0x05932247) /* 0.348421362 */, 17 }, - /* 3125 */ { MAD_F(0x0593be37) /* 0.348570077 */, 17 }, - /* 3126 */ { MAD_F(0x05945a2c) /* 0.348718808 */, 17 }, - /* 3127 */ { MAD_F(0x0594f625) /* 0.348867555 */, 17 }, - /* 3128 */ { MAD_F(0x05959222) /* 0.349016318 */, 17 }, - /* 3129 */ { MAD_F(0x05962e24) /* 0.349165097 */, 17 }, - /* 3130 */ { MAD_F(0x0596ca2a) /* 0.349313892 */, 17 }, - /* 3131 */ { MAD_F(0x05976634) /* 0.349462702 */, 17 }, - /* 3132 */ { MAD_F(0x05980242) /* 0.349611528 */, 17 }, - /* 3133 */ { MAD_F(0x05989e54) /* 0.349760370 */, 17 }, - /* 3134 */ { MAD_F(0x05993a6b) /* 0.349909228 */, 17 }, - /* 3135 */ { MAD_F(0x0599d686) /* 0.350058102 */, 17 }, - - /* 3136 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 17 }, - /* 3137 */ { MAD_F(0x059b0ec9) /* 0.350355897 */, 17 }, - /* 3138 */ { MAD_F(0x059baaf1) /* 0.350504818 */, 17 }, - /* 3139 */ { MAD_F(0x059c471d) /* 0.350653756 */, 17 }, - /* 3140 */ { MAD_F(0x059ce34d) /* 0.350802708 */, 17 }, - /* 3141 */ { MAD_F(0x059d7f81) /* 0.350951677 */, 17 }, - /* 3142 */ { MAD_F(0x059e1bba) /* 0.351100662 */, 17 }, - /* 3143 */ { MAD_F(0x059eb7f7) /* 0.351249662 */, 17 }, - /* 3144 */ { MAD_F(0x059f5438) /* 0.351398678 */, 17 }, - /* 3145 */ { MAD_F(0x059ff07e) /* 0.351547710 */, 17 }, - /* 3146 */ { MAD_F(0x05a08cc7) /* 0.351696758 */, 17 }, - /* 3147 */ { MAD_F(0x05a12915) /* 0.351845821 */, 17 }, - /* 3148 */ { MAD_F(0x05a1c567) /* 0.351994901 */, 17 }, - /* 3149 */ { MAD_F(0x05a261be) /* 0.352143996 */, 17 }, - /* 3150 */ { MAD_F(0x05a2fe18) /* 0.352293107 */, 17 }, - /* 3151 */ { MAD_F(0x05a39a77) /* 0.352442233 */, 17 }, - - /* 3152 */ { MAD_F(0x05a436da) /* 0.352591376 */, 17 }, - /* 3153 */ { MAD_F(0x05a4d342) /* 0.352740534 */, 17 }, - /* 3154 */ { MAD_F(0x05a56fad) /* 0.352889708 */, 17 }, - /* 3155 */ { MAD_F(0x05a60c1d) /* 0.353038898 */, 17 }, - /* 3156 */ { MAD_F(0x05a6a891) /* 0.353188103 */, 17 }, - /* 3157 */ { MAD_F(0x05a7450a) /* 0.353337325 */, 17 }, - /* 3158 */ { MAD_F(0x05a7e186) /* 0.353486562 */, 17 }, - /* 3159 */ { MAD_F(0x05a87e07) /* 0.353635814 */, 17 }, - /* 3160 */ { MAD_F(0x05a91a8c) /* 0.353785083 */, 17 }, - /* 3161 */ { MAD_F(0x05a9b715) /* 0.353934367 */, 17 }, - /* 3162 */ { MAD_F(0x05aa53a2) /* 0.354083667 */, 17 }, - /* 3163 */ { MAD_F(0x05aaf034) /* 0.354232983 */, 17 }, - /* 3164 */ { MAD_F(0x05ab8cca) /* 0.354382314 */, 17 }, - /* 3165 */ { MAD_F(0x05ac2964) /* 0.354531662 */, 17 }, - /* 3166 */ { MAD_F(0x05acc602) /* 0.354681025 */, 17 }, - /* 3167 */ { MAD_F(0x05ad62a5) /* 0.354830403 */, 17 }, - - /* 3168 */ { MAD_F(0x05adff4c) /* 0.354979798 */, 17 }, - /* 3169 */ { MAD_F(0x05ae9bf7) /* 0.355129208 */, 17 }, - /* 3170 */ { MAD_F(0x05af38a6) /* 0.355278634 */, 17 }, - /* 3171 */ { MAD_F(0x05afd559) /* 0.355428075 */, 17 }, - /* 3172 */ { MAD_F(0x05b07211) /* 0.355577533 */, 17 }, - /* 3173 */ { MAD_F(0x05b10ecd) /* 0.355727006 */, 17 }, - /* 3174 */ { MAD_F(0x05b1ab8d) /* 0.355876494 */, 17 }, - /* 3175 */ { MAD_F(0x05b24851) /* 0.356025999 */, 17 }, - /* 3176 */ { MAD_F(0x05b2e51a) /* 0.356175519 */, 17 }, - /* 3177 */ { MAD_F(0x05b381e6) /* 0.356325054 */, 17 }, - /* 3178 */ { MAD_F(0x05b41eb7) /* 0.356474606 */, 17 }, - /* 3179 */ { MAD_F(0x05b4bb8c) /* 0.356624173 */, 17 }, - /* 3180 */ { MAD_F(0x05b55866) /* 0.356773756 */, 17 }, - /* 3181 */ { MAD_F(0x05b5f543) /* 0.356923354 */, 17 }, - /* 3182 */ { MAD_F(0x05b69225) /* 0.357072969 */, 17 }, - /* 3183 */ { MAD_F(0x05b72f0b) /* 0.357222598 */, 17 }, - - /* 3184 */ { MAD_F(0x05b7cbf5) /* 0.357372244 */, 17 }, - /* 3185 */ { MAD_F(0x05b868e3) /* 0.357521905 */, 17 }, - /* 3186 */ { MAD_F(0x05b905d6) /* 0.357671582 */, 17 }, - /* 3187 */ { MAD_F(0x05b9a2cd) /* 0.357821275 */, 17 }, - /* 3188 */ { MAD_F(0x05ba3fc8) /* 0.357970983 */, 17 }, - /* 3189 */ { MAD_F(0x05badcc7) /* 0.358120707 */, 17 }, - /* 3190 */ { MAD_F(0x05bb79ca) /* 0.358270446 */, 17 }, - /* 3191 */ { MAD_F(0x05bc16d2) /* 0.358420201 */, 17 }, - /* 3192 */ { MAD_F(0x05bcb3de) /* 0.358569972 */, 17 }, - /* 3193 */ { MAD_F(0x05bd50ee) /* 0.358719758 */, 17 }, - /* 3194 */ { MAD_F(0x05bdee02) /* 0.358869560 */, 17 }, - /* 3195 */ { MAD_F(0x05be8b1a) /* 0.359019378 */, 17 }, - /* 3196 */ { MAD_F(0x05bf2837) /* 0.359169211 */, 17 }, - /* 3197 */ { MAD_F(0x05bfc558) /* 0.359319060 */, 17 }, - /* 3198 */ { MAD_F(0x05c0627d) /* 0.359468925 */, 17 }, - /* 3199 */ { MAD_F(0x05c0ffa6) /* 0.359618805 */, 17 }, - - /* 3200 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 17 }, - /* 3201 */ { MAD_F(0x05c23a05) /* 0.359918612 */, 17 }, - /* 3202 */ { MAD_F(0x05c2d73a) /* 0.360068540 */, 17 }, - /* 3203 */ { MAD_F(0x05c37474) /* 0.360218482 */, 17 }, - /* 3204 */ { MAD_F(0x05c411b2) /* 0.360368440 */, 17 }, - /* 3205 */ { MAD_F(0x05c4aef5) /* 0.360518414 */, 17 }, - /* 3206 */ { MAD_F(0x05c54c3b) /* 0.360668404 */, 17 }, - /* 3207 */ { MAD_F(0x05c5e986) /* 0.360818409 */, 17 }, - /* 3208 */ { MAD_F(0x05c686d5) /* 0.360968429 */, 17 }, - /* 3209 */ { MAD_F(0x05c72428) /* 0.361118466 */, 17 }, - /* 3210 */ { MAD_F(0x05c7c17f) /* 0.361268517 */, 17 }, - /* 3211 */ { MAD_F(0x05c85eda) /* 0.361418585 */, 17 }, - /* 3212 */ { MAD_F(0x05c8fc3a) /* 0.361568668 */, 17 }, - /* 3213 */ { MAD_F(0x05c9999e) /* 0.361718766 */, 17 }, - /* 3214 */ { MAD_F(0x05ca3706) /* 0.361868881 */, 17 }, - /* 3215 */ { MAD_F(0x05cad472) /* 0.362019010 */, 17 }, - - /* 3216 */ { MAD_F(0x05cb71e2) /* 0.362169156 */, 17 }, - /* 3217 */ { MAD_F(0x05cc0f57) /* 0.362319316 */, 17 }, - /* 3218 */ { MAD_F(0x05ccaccf) /* 0.362469493 */, 17 }, - /* 3219 */ { MAD_F(0x05cd4a4c) /* 0.362619685 */, 17 }, - /* 3220 */ { MAD_F(0x05cde7cd) /* 0.362769892 */, 17 }, - /* 3221 */ { MAD_F(0x05ce8552) /* 0.362920115 */, 17 }, - /* 3222 */ { MAD_F(0x05cf22dc) /* 0.363070354 */, 17 }, - /* 3223 */ { MAD_F(0x05cfc069) /* 0.363220608 */, 17 }, - /* 3224 */ { MAD_F(0x05d05dfb) /* 0.363370878 */, 17 }, - /* 3225 */ { MAD_F(0x05d0fb91) /* 0.363521163 */, 17 }, - /* 3226 */ { MAD_F(0x05d1992b) /* 0.363671464 */, 17 }, - /* 3227 */ { MAD_F(0x05d236c9) /* 0.363821780 */, 17 }, - /* 3228 */ { MAD_F(0x05d2d46c) /* 0.363972112 */, 17 }, - /* 3229 */ { MAD_F(0x05d37212) /* 0.364122459 */, 17 }, - /* 3230 */ { MAD_F(0x05d40fbd) /* 0.364272822 */, 17 }, - /* 3231 */ { MAD_F(0x05d4ad6c) /* 0.364423200 */, 17 }, - - /* 3232 */ { MAD_F(0x05d54b1f) /* 0.364573594 */, 17 }, - /* 3233 */ { MAD_F(0x05d5e8d6) /* 0.364724004 */, 17 }, - /* 3234 */ { MAD_F(0x05d68691) /* 0.364874429 */, 17 }, - /* 3235 */ { MAD_F(0x05d72451) /* 0.365024869 */, 17 }, - /* 3236 */ { MAD_F(0x05d7c215) /* 0.365175325 */, 17 }, - /* 3237 */ { MAD_F(0x05d85fdc) /* 0.365325796 */, 17 }, - /* 3238 */ { MAD_F(0x05d8fda8) /* 0.365476283 */, 17 }, - /* 3239 */ { MAD_F(0x05d99b79) /* 0.365626786 */, 17 }, - /* 3240 */ { MAD_F(0x05da394d) /* 0.365777304 */, 17 }, - /* 3241 */ { MAD_F(0x05dad726) /* 0.365927837 */, 17 }, - /* 3242 */ { MAD_F(0x05db7502) /* 0.366078386 */, 17 }, - /* 3243 */ { MAD_F(0x05dc12e3) /* 0.366228950 */, 17 }, - /* 3244 */ { MAD_F(0x05dcb0c8) /* 0.366379530 */, 17 }, - /* 3245 */ { MAD_F(0x05dd4eb1) /* 0.366530125 */, 17 }, - /* 3246 */ { MAD_F(0x05ddec9e) /* 0.366680736 */, 17 }, - /* 3247 */ { MAD_F(0x05de8a90) /* 0.366831362 */, 17 }, - - /* 3248 */ { MAD_F(0x05df2885) /* 0.366982004 */, 17 }, - /* 3249 */ { MAD_F(0x05dfc67f) /* 0.367132661 */, 17 }, - /* 3250 */ { MAD_F(0x05e0647d) /* 0.367283334 */, 17 }, - /* 3251 */ { MAD_F(0x05e1027f) /* 0.367434022 */, 17 }, - /* 3252 */ { MAD_F(0x05e1a085) /* 0.367584725 */, 17 }, - /* 3253 */ { MAD_F(0x05e23e8f) /* 0.367735444 */, 17 }, - /* 3254 */ { MAD_F(0x05e2dc9e) /* 0.367886179 */, 17 }, - /* 3255 */ { MAD_F(0x05e37ab0) /* 0.368036929 */, 17 }, - /* 3256 */ { MAD_F(0x05e418c7) /* 0.368187694 */, 17 }, - /* 3257 */ { MAD_F(0x05e4b6e2) /* 0.368338475 */, 17 }, - /* 3258 */ { MAD_F(0x05e55501) /* 0.368489271 */, 17 }, - /* 3259 */ { MAD_F(0x05e5f324) /* 0.368640082 */, 17 }, - /* 3260 */ { MAD_F(0x05e6914c) /* 0.368790909 */, 17 }, - /* 3261 */ { MAD_F(0x05e72f77) /* 0.368941752 */, 17 }, - /* 3262 */ { MAD_F(0x05e7cda7) /* 0.369092610 */, 17 }, - /* 3263 */ { MAD_F(0x05e86bda) /* 0.369243483 */, 17 }, - - /* 3264 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 17 }, - /* 3265 */ { MAD_F(0x05e9a84e) /* 0.369545276 */, 17 }, - /* 3266 */ { MAD_F(0x05ea468e) /* 0.369696195 */, 17 }, - /* 3267 */ { MAD_F(0x05eae4d3) /* 0.369847130 */, 17 }, - /* 3268 */ { MAD_F(0x05eb831b) /* 0.369998080 */, 17 }, - /* 3269 */ { MAD_F(0x05ec2168) /* 0.370149046 */, 17 }, - /* 3270 */ { MAD_F(0x05ecbfb8) /* 0.370300027 */, 17 }, - /* 3271 */ { MAD_F(0x05ed5e0d) /* 0.370451024 */, 17 }, - /* 3272 */ { MAD_F(0x05edfc66) /* 0.370602036 */, 17 }, - /* 3273 */ { MAD_F(0x05ee9ac3) /* 0.370753063 */, 17 }, - /* 3274 */ { MAD_F(0x05ef3924) /* 0.370904105 */, 17 }, - /* 3275 */ { MAD_F(0x05efd78a) /* 0.371055163 */, 17 }, - /* 3276 */ { MAD_F(0x05f075f3) /* 0.371206237 */, 17 }, - /* 3277 */ { MAD_F(0x05f11461) /* 0.371357326 */, 17 }, - /* 3278 */ { MAD_F(0x05f1b2d3) /* 0.371508430 */, 17 }, - /* 3279 */ { MAD_F(0x05f25148) /* 0.371659549 */, 17 }, - - /* 3280 */ { MAD_F(0x05f2efc2) /* 0.371810684 */, 17 }, - /* 3281 */ { MAD_F(0x05f38e40) /* 0.371961834 */, 17 }, - /* 3282 */ { MAD_F(0x05f42cc3) /* 0.372113000 */, 17 }, - /* 3283 */ { MAD_F(0x05f4cb49) /* 0.372264181 */, 17 }, - /* 3284 */ { MAD_F(0x05f569d3) /* 0.372415377 */, 17 }, - /* 3285 */ { MAD_F(0x05f60862) /* 0.372566589 */, 17 }, - /* 3286 */ { MAD_F(0x05f6a6f5) /* 0.372717816 */, 17 }, - /* 3287 */ { MAD_F(0x05f7458b) /* 0.372869058 */, 17 }, - /* 3288 */ { MAD_F(0x05f7e426) /* 0.373020316 */, 17 }, - /* 3289 */ { MAD_F(0x05f882c5) /* 0.373171589 */, 17 }, - /* 3290 */ { MAD_F(0x05f92169) /* 0.373322877 */, 17 }, - /* 3291 */ { MAD_F(0x05f9c010) /* 0.373474181 */, 17 }, - /* 3292 */ { MAD_F(0x05fa5ebb) /* 0.373625500 */, 17 }, - /* 3293 */ { MAD_F(0x05fafd6b) /* 0.373776834 */, 17 }, - /* 3294 */ { MAD_F(0x05fb9c1e) /* 0.373928184 */, 17 }, - /* 3295 */ { MAD_F(0x05fc3ad6) /* 0.374079549 */, 17 }, - - /* 3296 */ { MAD_F(0x05fcd992) /* 0.374230929 */, 17 }, - /* 3297 */ { MAD_F(0x05fd7852) /* 0.374382325 */, 17 }, - /* 3298 */ { MAD_F(0x05fe1716) /* 0.374533735 */, 17 }, - /* 3299 */ { MAD_F(0x05feb5de) /* 0.374685162 */, 17 }, - /* 3300 */ { MAD_F(0x05ff54aa) /* 0.374836603 */, 17 }, - /* 3301 */ { MAD_F(0x05fff37b) /* 0.374988060 */, 17 }, - /* 3302 */ { MAD_F(0x0600924f) /* 0.375139532 */, 17 }, - /* 3303 */ { MAD_F(0x06013128) /* 0.375291019 */, 17 }, - /* 3304 */ { MAD_F(0x0601d004) /* 0.375442522 */, 17 }, - /* 3305 */ { MAD_F(0x06026ee5) /* 0.375594040 */, 17 }, - /* 3306 */ { MAD_F(0x06030dca) /* 0.375745573 */, 17 }, - /* 3307 */ { MAD_F(0x0603acb3) /* 0.375897122 */, 17 }, - /* 3308 */ { MAD_F(0x06044ba0) /* 0.376048685 */, 17 }, - /* 3309 */ { MAD_F(0x0604ea91) /* 0.376200265 */, 17 }, - /* 3310 */ { MAD_F(0x06058987) /* 0.376351859 */, 17 }, - /* 3311 */ { MAD_F(0x06062880) /* 0.376503468 */, 17 }, - - /* 3312 */ { MAD_F(0x0606c77d) /* 0.376655093 */, 17 }, - /* 3313 */ { MAD_F(0x0607667f) /* 0.376806733 */, 17 }, - /* 3314 */ { MAD_F(0x06080585) /* 0.376958389 */, 17 }, - /* 3315 */ { MAD_F(0x0608a48f) /* 0.377110059 */, 17 }, - /* 3316 */ { MAD_F(0x0609439c) /* 0.377261745 */, 17 }, - /* 3317 */ { MAD_F(0x0609e2ae) /* 0.377413446 */, 17 }, - /* 3318 */ { MAD_F(0x060a81c4) /* 0.377565163 */, 17 }, - /* 3319 */ { MAD_F(0x060b20df) /* 0.377716894 */, 17 }, - /* 3320 */ { MAD_F(0x060bbffd) /* 0.377868641 */, 17 }, - /* 3321 */ { MAD_F(0x060c5f1f) /* 0.378020403 */, 17 }, - /* 3322 */ { MAD_F(0x060cfe46) /* 0.378172181 */, 17 }, - /* 3323 */ { MAD_F(0x060d9d70) /* 0.378323973 */, 17 }, - /* 3324 */ { MAD_F(0x060e3c9f) /* 0.378475781 */, 17 }, - /* 3325 */ { MAD_F(0x060edbd1) /* 0.378627604 */, 17 }, - /* 3326 */ { MAD_F(0x060f7b08) /* 0.378779442 */, 17 }, - /* 3327 */ { MAD_F(0x06101a43) /* 0.378931296 */, 17 }, - - /* 3328 */ { MAD_F(0x0610b982) /* 0.379083164 */, 17 }, - /* 3329 */ { MAD_F(0x061158c5) /* 0.379235048 */, 17 }, - /* 3330 */ { MAD_F(0x0611f80c) /* 0.379386947 */, 17 }, - /* 3331 */ { MAD_F(0x06129757) /* 0.379538862 */, 17 }, - /* 3332 */ { MAD_F(0x061336a6) /* 0.379690791 */, 17 }, - /* 3333 */ { MAD_F(0x0613d5fa) /* 0.379842736 */, 17 }, - /* 3334 */ { MAD_F(0x06147551) /* 0.379994696 */, 17 }, - /* 3335 */ { MAD_F(0x061514ad) /* 0.380146671 */, 17 }, - /* 3336 */ { MAD_F(0x0615b40c) /* 0.380298661 */, 17 }, - /* 3337 */ { MAD_F(0x06165370) /* 0.380450666 */, 17 }, - /* 3338 */ { MAD_F(0x0616f2d8) /* 0.380602687 */, 17 }, - /* 3339 */ { MAD_F(0x06179243) /* 0.380754723 */, 17 }, - /* 3340 */ { MAD_F(0x061831b3) /* 0.380906774 */, 17 }, - /* 3341 */ { MAD_F(0x0618d127) /* 0.381058840 */, 17 }, - /* 3342 */ { MAD_F(0x0619709f) /* 0.381210921 */, 17 }, - /* 3343 */ { MAD_F(0x061a101b) /* 0.381363018 */, 17 }, - - /* 3344 */ { MAD_F(0x061aaf9c) /* 0.381515130 */, 17 }, - /* 3345 */ { MAD_F(0x061b4f20) /* 0.381667257 */, 17 }, - /* 3346 */ { MAD_F(0x061beea8) /* 0.381819399 */, 17 }, - /* 3347 */ { MAD_F(0x061c8e34) /* 0.381971556 */, 17 }, - /* 3348 */ { MAD_F(0x061d2dc5) /* 0.382123728 */, 17 }, - /* 3349 */ { MAD_F(0x061dcd59) /* 0.382275916 */, 17 }, - /* 3350 */ { MAD_F(0x061e6cf2) /* 0.382428118 */, 17 }, - /* 3351 */ { MAD_F(0x061f0c8f) /* 0.382580336 */, 17 }, - /* 3352 */ { MAD_F(0x061fac2f) /* 0.382732569 */, 17 }, - /* 3353 */ { MAD_F(0x06204bd4) /* 0.382884817 */, 17 }, - /* 3354 */ { MAD_F(0x0620eb7d) /* 0.383037080 */, 17 }, - /* 3355 */ { MAD_F(0x06218b2a) /* 0.383189358 */, 17 }, - /* 3356 */ { MAD_F(0x06222adb) /* 0.383341652 */, 17 }, - /* 3357 */ { MAD_F(0x0622ca90) /* 0.383493960 */, 17 }, - /* 3358 */ { MAD_F(0x06236a49) /* 0.383646284 */, 17 }, - /* 3359 */ { MAD_F(0x06240a06) /* 0.383798623 */, 17 }, - - /* 3360 */ { MAD_F(0x0624a9c7) /* 0.383950977 */, 17 }, - /* 3361 */ { MAD_F(0x0625498d) /* 0.384103346 */, 17 }, - /* 3362 */ { MAD_F(0x0625e956) /* 0.384255730 */, 17 }, - /* 3363 */ { MAD_F(0x06268923) /* 0.384408129 */, 17 }, - /* 3364 */ { MAD_F(0x062728f5) /* 0.384560544 */, 17 }, - /* 3365 */ { MAD_F(0x0627c8ca) /* 0.384712973 */, 17 }, - /* 3366 */ { MAD_F(0x062868a4) /* 0.384865418 */, 17 }, - /* 3367 */ { MAD_F(0x06290881) /* 0.385017878 */, 17 }, - /* 3368 */ { MAD_F(0x0629a863) /* 0.385170352 */, 17 }, - /* 3369 */ { MAD_F(0x062a4849) /* 0.385322842 */, 17 }, - /* 3370 */ { MAD_F(0x062ae832) /* 0.385475347 */, 17 }, - /* 3371 */ { MAD_F(0x062b8820) /* 0.385627867 */, 17 }, - /* 3372 */ { MAD_F(0x062c2812) /* 0.385780402 */, 17 }, - /* 3373 */ { MAD_F(0x062cc808) /* 0.385932953 */, 17 }, - /* 3374 */ { MAD_F(0x062d6802) /* 0.386085518 */, 17 }, - /* 3375 */ { MAD_F(0x062e0800) /* 0.386238098 */, 17 }, - - /* 3376 */ { MAD_F(0x062ea802) /* 0.386390694 */, 17 }, - /* 3377 */ { MAD_F(0x062f4808) /* 0.386543304 */, 17 }, - /* 3378 */ { MAD_F(0x062fe812) /* 0.386695930 */, 17 }, - /* 3379 */ { MAD_F(0x06308820) /* 0.386848570 */, 17 }, - /* 3380 */ { MAD_F(0x06312832) /* 0.387001226 */, 17 }, - /* 3381 */ { MAD_F(0x0631c849) /* 0.387153897 */, 17 }, - /* 3382 */ { MAD_F(0x06326863) /* 0.387306582 */, 17 }, - /* 3383 */ { MAD_F(0x06330881) /* 0.387459283 */, 17 }, - /* 3384 */ { MAD_F(0x0633a8a3) /* 0.387611999 */, 17 }, - /* 3385 */ { MAD_F(0x063448ca) /* 0.387764730 */, 17 }, - /* 3386 */ { MAD_F(0x0634e8f4) /* 0.387917476 */, 17 }, - /* 3387 */ { MAD_F(0x06358923) /* 0.388070237 */, 17 }, - /* 3388 */ { MAD_F(0x06362955) /* 0.388223013 */, 17 }, - /* 3389 */ { MAD_F(0x0636c98c) /* 0.388375804 */, 17 }, - /* 3390 */ { MAD_F(0x063769c6) /* 0.388528610 */, 17 }, - /* 3391 */ { MAD_F(0x06380a05) /* 0.388681431 */, 17 }, - - /* 3392 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 17 }, - /* 3393 */ { MAD_F(0x06394a8e) /* 0.388987119 */, 17 }, - /* 3394 */ { MAD_F(0x0639ead9) /* 0.389139985 */, 17 }, - /* 3395 */ { MAD_F(0x063a8b28) /* 0.389292866 */, 17 }, - /* 3396 */ { MAD_F(0x063b2b7b) /* 0.389445762 */, 17 }, - /* 3397 */ { MAD_F(0x063bcbd1) /* 0.389598674 */, 17 }, - /* 3398 */ { MAD_F(0x063c6c2c) /* 0.389751600 */, 17 }, - /* 3399 */ { MAD_F(0x063d0c8b) /* 0.389904541 */, 17 }, - /* 3400 */ { MAD_F(0x063dacee) /* 0.390057497 */, 17 }, - /* 3401 */ { MAD_F(0x063e4d55) /* 0.390210468 */, 17 }, - /* 3402 */ { MAD_F(0x063eedc0) /* 0.390363455 */, 17 }, - /* 3403 */ { MAD_F(0x063f8e2f) /* 0.390516456 */, 17 }, - /* 3404 */ { MAD_F(0x06402ea2) /* 0.390669472 */, 17 }, - /* 3405 */ { MAD_F(0x0640cf19) /* 0.390822503 */, 17 }, - /* 3406 */ { MAD_F(0x06416f94) /* 0.390975549 */, 17 }, - /* 3407 */ { MAD_F(0x06421013) /* 0.391128611 */, 17 }, - - /* 3408 */ { MAD_F(0x0642b096) /* 0.391281687 */, 17 }, - /* 3409 */ { MAD_F(0x0643511d) /* 0.391434778 */, 17 }, - /* 3410 */ { MAD_F(0x0643f1a8) /* 0.391587884 */, 17 }, - /* 3411 */ { MAD_F(0x06449237) /* 0.391741005 */, 17 }, - /* 3412 */ { MAD_F(0x064532ca) /* 0.391894141 */, 17 }, - /* 3413 */ { MAD_F(0x0645d361) /* 0.392047292 */, 17 }, - /* 3414 */ { MAD_F(0x064673fc) /* 0.392200458 */, 17 }, - /* 3415 */ { MAD_F(0x0647149c) /* 0.392353638 */, 17 }, - /* 3416 */ { MAD_F(0x0647b53f) /* 0.392506834 */, 17 }, - /* 3417 */ { MAD_F(0x064855e6) /* 0.392660045 */, 17 }, - /* 3418 */ { MAD_F(0x0648f691) /* 0.392813271 */, 17 }, - /* 3419 */ { MAD_F(0x06499740) /* 0.392966511 */, 17 }, - /* 3420 */ { MAD_F(0x064a37f4) /* 0.393119767 */, 17 }, - /* 3421 */ { MAD_F(0x064ad8ab) /* 0.393273038 */, 17 }, - /* 3422 */ { MAD_F(0x064b7966) /* 0.393426323 */, 17 }, - /* 3423 */ { MAD_F(0x064c1a25) /* 0.393579623 */, 17 }, - - /* 3424 */ { MAD_F(0x064cbae9) /* 0.393732939 */, 17 }, - /* 3425 */ { MAD_F(0x064d5bb0) /* 0.393886269 */, 17 }, - /* 3426 */ { MAD_F(0x064dfc7b) /* 0.394039614 */, 17 }, - /* 3427 */ { MAD_F(0x064e9d4b) /* 0.394192974 */, 17 }, - /* 3428 */ { MAD_F(0x064f3e1e) /* 0.394346349 */, 17 }, - /* 3429 */ { MAD_F(0x064fdef5) /* 0.394499739 */, 17 }, - /* 3430 */ { MAD_F(0x06507fd0) /* 0.394653144 */, 17 }, - /* 3431 */ { MAD_F(0x065120b0) /* 0.394806564 */, 17 }, - /* 3432 */ { MAD_F(0x0651c193) /* 0.394959999 */, 17 }, - /* 3433 */ { MAD_F(0x0652627a) /* 0.395113448 */, 17 }, - /* 3434 */ { MAD_F(0x06530366) /* 0.395266913 */, 17 }, - /* 3435 */ { MAD_F(0x0653a455) /* 0.395420392 */, 17 }, - /* 3436 */ { MAD_F(0x06544548) /* 0.395573886 */, 17 }, - /* 3437 */ { MAD_F(0x0654e640) /* 0.395727395 */, 17 }, - /* 3438 */ { MAD_F(0x0655873b) /* 0.395880919 */, 17 }, - /* 3439 */ { MAD_F(0x0656283a) /* 0.396034458 */, 17 }, - - /* 3440 */ { MAD_F(0x0656c93d) /* 0.396188012 */, 17 }, - /* 3441 */ { MAD_F(0x06576a45) /* 0.396341581 */, 17 }, - /* 3442 */ { MAD_F(0x06580b50) /* 0.396495164 */, 17 }, - /* 3443 */ { MAD_F(0x0658ac5f) /* 0.396648763 */, 17 }, - /* 3444 */ { MAD_F(0x06594d73) /* 0.396802376 */, 17 }, - /* 3445 */ { MAD_F(0x0659ee8a) /* 0.396956004 */, 17 }, - /* 3446 */ { MAD_F(0x065a8fa5) /* 0.397109647 */, 17 }, - /* 3447 */ { MAD_F(0x065b30c4) /* 0.397263305 */, 17 }, - /* 3448 */ { MAD_F(0x065bd1e7) /* 0.397416978 */, 17 }, - /* 3449 */ { MAD_F(0x065c730f) /* 0.397570666 */, 17 }, - /* 3450 */ { MAD_F(0x065d143a) /* 0.397724368 */, 17 }, - /* 3451 */ { MAD_F(0x065db569) /* 0.397878085 */, 17 }, - /* 3452 */ { MAD_F(0x065e569c) /* 0.398031818 */, 17 }, - /* 3453 */ { MAD_F(0x065ef7d3) /* 0.398185565 */, 17 }, - /* 3454 */ { MAD_F(0x065f990e) /* 0.398339326 */, 17 }, - /* 3455 */ { MAD_F(0x06603a4e) /* 0.398493103 */, 17 }, - - /* 3456 */ { MAD_F(0x0660db91) /* 0.398646895 */, 17 }, - /* 3457 */ { MAD_F(0x06617cd8) /* 0.398800701 */, 17 }, - /* 3458 */ { MAD_F(0x06621e23) /* 0.398954522 */, 17 }, - /* 3459 */ { MAD_F(0x0662bf72) /* 0.399108358 */, 17 }, - /* 3460 */ { MAD_F(0x066360c5) /* 0.399262209 */, 17 }, - /* 3461 */ { MAD_F(0x0664021c) /* 0.399416075 */, 17 }, - /* 3462 */ { MAD_F(0x0664a377) /* 0.399569955 */, 17 }, - /* 3463 */ { MAD_F(0x066544d6) /* 0.399723851 */, 17 }, - /* 3464 */ { MAD_F(0x0665e639) /* 0.399877761 */, 17 }, - /* 3465 */ { MAD_F(0x066687a0) /* 0.400031686 */, 17 }, - /* 3466 */ { MAD_F(0x0667290b) /* 0.400185625 */, 17 }, - /* 3467 */ { MAD_F(0x0667ca79) /* 0.400339580 */, 17 }, - /* 3468 */ { MAD_F(0x06686bec) /* 0.400493549 */, 17 }, - /* 3469 */ { MAD_F(0x06690d63) /* 0.400647534 */, 17 }, - /* 3470 */ { MAD_F(0x0669aede) /* 0.400801533 */, 17 }, - /* 3471 */ { MAD_F(0x066a505d) /* 0.400955546 */, 17 }, - - /* 3472 */ { MAD_F(0x066af1df) /* 0.401109575 */, 17 }, - /* 3473 */ { MAD_F(0x066b9366) /* 0.401263618 */, 17 }, - /* 3474 */ { MAD_F(0x066c34f1) /* 0.401417676 */, 17 }, - /* 3475 */ { MAD_F(0x066cd67f) /* 0.401571749 */, 17 }, - /* 3476 */ { MAD_F(0x066d7812) /* 0.401725837 */, 17 }, - /* 3477 */ { MAD_F(0x066e19a9) /* 0.401879939 */, 17 }, - /* 3478 */ { MAD_F(0x066ebb43) /* 0.402034056 */, 17 }, - /* 3479 */ { MAD_F(0x066f5ce2) /* 0.402188188 */, 17 }, - /* 3480 */ { MAD_F(0x066ffe84) /* 0.402342335 */, 17 }, - /* 3481 */ { MAD_F(0x0670a02a) /* 0.402496497 */, 17 }, - /* 3482 */ { MAD_F(0x067141d5) /* 0.402650673 */, 17 }, - /* 3483 */ { MAD_F(0x0671e383) /* 0.402804864 */, 17 }, - /* 3484 */ { MAD_F(0x06728535) /* 0.402959070 */, 17 }, - /* 3485 */ { MAD_F(0x067326ec) /* 0.403113291 */, 17 }, - /* 3486 */ { MAD_F(0x0673c8a6) /* 0.403267526 */, 17 }, - /* 3487 */ { MAD_F(0x06746a64) /* 0.403421776 */, 17 }, - - /* 3488 */ { MAD_F(0x06750c26) /* 0.403576041 */, 17 }, - /* 3489 */ { MAD_F(0x0675adec) /* 0.403730320 */, 17 }, - /* 3490 */ { MAD_F(0x06764fb6) /* 0.403884615 */, 17 }, - /* 3491 */ { MAD_F(0x0676f184) /* 0.404038924 */, 17 }, - /* 3492 */ { MAD_F(0x06779356) /* 0.404193247 */, 17 }, - /* 3493 */ { MAD_F(0x0678352c) /* 0.404347586 */, 17 }, - /* 3494 */ { MAD_F(0x0678d706) /* 0.404501939 */, 17 }, - /* 3495 */ { MAD_F(0x067978e4) /* 0.404656307 */, 17 }, - /* 3496 */ { MAD_F(0x067a1ac6) /* 0.404810690 */, 17 }, - /* 3497 */ { MAD_F(0x067abcac) /* 0.404965087 */, 17 }, - /* 3498 */ { MAD_F(0x067b5e95) /* 0.405119499 */, 17 }, - /* 3499 */ { MAD_F(0x067c0083) /* 0.405273926 */, 17 }, - /* 3500 */ { MAD_F(0x067ca275) /* 0.405428368 */, 17 }, - /* 3501 */ { MAD_F(0x067d446a) /* 0.405582824 */, 17 }, - /* 3502 */ { MAD_F(0x067de664) /* 0.405737295 */, 17 }, - /* 3503 */ { MAD_F(0x067e8861) /* 0.405891781 */, 17 }, - - /* 3504 */ { MAD_F(0x067f2a62) /* 0.406046281 */, 17 }, - /* 3505 */ { MAD_F(0x067fcc68) /* 0.406200796 */, 17 }, - /* 3506 */ { MAD_F(0x06806e71) /* 0.406355326 */, 17 }, - /* 3507 */ { MAD_F(0x0681107e) /* 0.406509870 */, 17 }, - /* 3508 */ { MAD_F(0x0681b28f) /* 0.406664429 */, 17 }, - /* 3509 */ { MAD_F(0x068254a4) /* 0.406819003 */, 17 }, - /* 3510 */ { MAD_F(0x0682f6bd) /* 0.406973592 */, 17 }, - /* 3511 */ { MAD_F(0x068398da) /* 0.407128195 */, 17 }, - /* 3512 */ { MAD_F(0x06843afb) /* 0.407282813 */, 17 }, - /* 3513 */ { MAD_F(0x0684dd20) /* 0.407437445 */, 17 }, - /* 3514 */ { MAD_F(0x06857f49) /* 0.407592093 */, 17 }, - /* 3515 */ { MAD_F(0x06862176) /* 0.407746754 */, 17 }, - /* 3516 */ { MAD_F(0x0686c3a6) /* 0.407901431 */, 17 }, - /* 3517 */ { MAD_F(0x068765db) /* 0.408056122 */, 17 }, - /* 3518 */ { MAD_F(0x06880814) /* 0.408210828 */, 17 }, - /* 3519 */ { MAD_F(0x0688aa50) /* 0.408365549 */, 17 }, - - /* 3520 */ { MAD_F(0x06894c90) /* 0.408520284 */, 17 }, - /* 3521 */ { MAD_F(0x0689eed5) /* 0.408675034 */, 17 }, - /* 3522 */ { MAD_F(0x068a911d) /* 0.408829798 */, 17 }, - /* 3523 */ { MAD_F(0x068b3369) /* 0.408984577 */, 17 }, - /* 3524 */ { MAD_F(0x068bd5b9) /* 0.409139371 */, 17 }, - /* 3525 */ { MAD_F(0x068c780e) /* 0.409294180 */, 17 }, - /* 3526 */ { MAD_F(0x068d1a66) /* 0.409449003 */, 17 }, - /* 3527 */ { MAD_F(0x068dbcc1) /* 0.409603840 */, 17 }, - /* 3528 */ { MAD_F(0x068e5f21) /* 0.409758693 */, 17 }, - /* 3529 */ { MAD_F(0x068f0185) /* 0.409913560 */, 17 }, - /* 3530 */ { MAD_F(0x068fa3ed) /* 0.410068441 */, 17 }, - /* 3531 */ { MAD_F(0x06904658) /* 0.410223338 */, 17 }, - /* 3532 */ { MAD_F(0x0690e8c8) /* 0.410378249 */, 17 }, - /* 3533 */ { MAD_F(0x06918b3c) /* 0.410533174 */, 17 }, - /* 3534 */ { MAD_F(0x06922db3) /* 0.410688114 */, 17 }, - /* 3535 */ { MAD_F(0x0692d02e) /* 0.410843069 */, 17 }, - - /* 3536 */ { MAD_F(0x069372ae) /* 0.410998038 */, 17 }, - /* 3537 */ { MAD_F(0x06941531) /* 0.411153022 */, 17 }, - /* 3538 */ { MAD_F(0x0694b7b8) /* 0.411308021 */, 17 }, - /* 3539 */ { MAD_F(0x06955a43) /* 0.411463034 */, 17 }, - /* 3540 */ { MAD_F(0x0695fcd2) /* 0.411618062 */, 17 }, - /* 3541 */ { MAD_F(0x06969f65) /* 0.411773104 */, 17 }, - /* 3542 */ { MAD_F(0x069741fb) /* 0.411928161 */, 17 }, - /* 3543 */ { MAD_F(0x0697e496) /* 0.412083232 */, 17 }, - /* 3544 */ { MAD_F(0x06988735) /* 0.412238319 */, 17 }, - /* 3545 */ { MAD_F(0x069929d7) /* 0.412393419 */, 17 }, - /* 3546 */ { MAD_F(0x0699cc7e) /* 0.412548535 */, 17 }, - /* 3547 */ { MAD_F(0x069a6f28) /* 0.412703664 */, 17 }, - /* 3548 */ { MAD_F(0x069b11d6) /* 0.412858809 */, 17 }, - /* 3549 */ { MAD_F(0x069bb489) /* 0.413013968 */, 17 }, - /* 3550 */ { MAD_F(0x069c573f) /* 0.413169142 */, 17 }, - /* 3551 */ { MAD_F(0x069cf9f9) /* 0.413324330 */, 17 }, - - /* 3552 */ { MAD_F(0x069d9cb7) /* 0.413479532 */, 17 }, - /* 3553 */ { MAD_F(0x069e3f78) /* 0.413634750 */, 17 }, - /* 3554 */ { MAD_F(0x069ee23e) /* 0.413789982 */, 17 }, - /* 3555 */ { MAD_F(0x069f8508) /* 0.413945228 */, 17 }, - /* 3556 */ { MAD_F(0x06a027d5) /* 0.414100489 */, 17 }, - /* 3557 */ { MAD_F(0x06a0caa7) /* 0.414255765 */, 17 }, - /* 3558 */ { MAD_F(0x06a16d7c) /* 0.414411055 */, 17 }, - /* 3559 */ { MAD_F(0x06a21055) /* 0.414566359 */, 17 }, - /* 3560 */ { MAD_F(0x06a2b333) /* 0.414721679 */, 17 }, - /* 3561 */ { MAD_F(0x06a35614) /* 0.414877012 */, 17 }, - /* 3562 */ { MAD_F(0x06a3f8f9) /* 0.415032361 */, 17 }, - /* 3563 */ { MAD_F(0x06a49be2) /* 0.415187723 */, 17 }, - /* 3564 */ { MAD_F(0x06a53ece) /* 0.415343101 */, 17 }, - /* 3565 */ { MAD_F(0x06a5e1bf) /* 0.415498493 */, 17 }, - /* 3566 */ { MAD_F(0x06a684b4) /* 0.415653899 */, 17 }, - /* 3567 */ { MAD_F(0x06a727ac) /* 0.415809320 */, 17 }, - - /* 3568 */ { MAD_F(0x06a7caa9) /* 0.415964756 */, 17 }, - /* 3569 */ { MAD_F(0x06a86da9) /* 0.416120206 */, 17 }, - /* 3570 */ { MAD_F(0x06a910ad) /* 0.416275670 */, 17 }, - /* 3571 */ { MAD_F(0x06a9b3b5) /* 0.416431149 */, 17 }, - /* 3572 */ { MAD_F(0x06aa56c1) /* 0.416586643 */, 17 }, - /* 3573 */ { MAD_F(0x06aaf9d1) /* 0.416742151 */, 17 }, - /* 3574 */ { MAD_F(0x06ab9ce5) /* 0.416897673 */, 17 }, - /* 3575 */ { MAD_F(0x06ac3ffc) /* 0.417053210 */, 17 }, - /* 3576 */ { MAD_F(0x06ace318) /* 0.417208762 */, 17 }, - /* 3577 */ { MAD_F(0x06ad8637) /* 0.417364328 */, 17 }, - /* 3578 */ { MAD_F(0x06ae295b) /* 0.417519909 */, 17 }, - /* 3579 */ { MAD_F(0x06aecc82) /* 0.417675504 */, 17 }, - /* 3580 */ { MAD_F(0x06af6fad) /* 0.417831113 */, 17 }, - /* 3581 */ { MAD_F(0x06b012dc) /* 0.417986737 */, 17 }, - /* 3582 */ { MAD_F(0x06b0b60f) /* 0.418142376 */, 17 }, - /* 3583 */ { MAD_F(0x06b15946) /* 0.418298029 */, 17 }, - - /* 3584 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 17 }, - /* 3585 */ { MAD_F(0x06b29fbf) /* 0.418609378 */, 17 }, - /* 3586 */ { MAD_F(0x06b34302) /* 0.418765075 */, 17 }, - /* 3587 */ { MAD_F(0x06b3e648) /* 0.418920786 */, 17 }, - /* 3588 */ { MAD_F(0x06b48992) /* 0.419076511 */, 17 }, - /* 3589 */ { MAD_F(0x06b52ce0) /* 0.419232251 */, 17 }, - /* 3590 */ { MAD_F(0x06b5d032) /* 0.419388005 */, 17 }, - /* 3591 */ { MAD_F(0x06b67388) /* 0.419543774 */, 17 }, - /* 3592 */ { MAD_F(0x06b716e2) /* 0.419699557 */, 17 }, - /* 3593 */ { MAD_F(0x06b7ba3f) /* 0.419855355 */, 17 }, - /* 3594 */ { MAD_F(0x06b85da1) /* 0.420011167 */, 17 }, - /* 3595 */ { MAD_F(0x06b90106) /* 0.420166994 */, 17 }, - /* 3596 */ { MAD_F(0x06b9a470) /* 0.420322835 */, 17 }, - /* 3597 */ { MAD_F(0x06ba47dd) /* 0.420478690 */, 17 }, - /* 3598 */ { MAD_F(0x06baeb4e) /* 0.420634560 */, 17 }, - /* 3599 */ { MAD_F(0x06bb8ec3) /* 0.420790445 */, 17 }, - - /* 3600 */ { MAD_F(0x06bc323b) /* 0.420946343 */, 17 }, - /* 3601 */ { MAD_F(0x06bcd5b8) /* 0.421102257 */, 17 }, - /* 3602 */ { MAD_F(0x06bd7939) /* 0.421258184 */, 17 }, - /* 3603 */ { MAD_F(0x06be1cbd) /* 0.421414127 */, 17 }, - /* 3604 */ { MAD_F(0x06bec045) /* 0.421570083 */, 17 }, - /* 3605 */ { MAD_F(0x06bf63d1) /* 0.421726054 */, 17 }, - /* 3606 */ { MAD_F(0x06c00761) /* 0.421882040 */, 17 }, - /* 3607 */ { MAD_F(0x06c0aaf5) /* 0.422038039 */, 17 }, - /* 3608 */ { MAD_F(0x06c14e8d) /* 0.422194054 */, 17 }, - /* 3609 */ { MAD_F(0x06c1f229) /* 0.422350082 */, 17 }, - /* 3610 */ { MAD_F(0x06c295c8) /* 0.422506125 */, 17 }, - /* 3611 */ { MAD_F(0x06c3396c) /* 0.422662183 */, 17 }, - /* 3612 */ { MAD_F(0x06c3dd13) /* 0.422818255 */, 17 }, - /* 3613 */ { MAD_F(0x06c480be) /* 0.422974341 */, 17 }, - /* 3614 */ { MAD_F(0x06c5246d) /* 0.423130442 */, 17 }, - /* 3615 */ { MAD_F(0x06c5c820) /* 0.423286557 */, 17 }, - - /* 3616 */ { MAD_F(0x06c66bd6) /* 0.423442686 */, 17 }, - /* 3617 */ { MAD_F(0x06c70f91) /* 0.423598830 */, 17 }, - /* 3618 */ { MAD_F(0x06c7b34f) /* 0.423754988 */, 17 }, - /* 3619 */ { MAD_F(0x06c85712) /* 0.423911161 */, 17 }, - /* 3620 */ { MAD_F(0x06c8fad8) /* 0.424067348 */, 17 }, - /* 3621 */ { MAD_F(0x06c99ea2) /* 0.424223550 */, 17 }, - /* 3622 */ { MAD_F(0x06ca4270) /* 0.424379765 */, 17 }, - /* 3623 */ { MAD_F(0x06cae641) /* 0.424535996 */, 17 }, - /* 3624 */ { MAD_F(0x06cb8a17) /* 0.424692240 */, 17 }, - /* 3625 */ { MAD_F(0x06cc2df0) /* 0.424848499 */, 17 }, - /* 3626 */ { MAD_F(0x06ccd1ce) /* 0.425004772 */, 17 }, - /* 3627 */ { MAD_F(0x06cd75af) /* 0.425161060 */, 17 }, - /* 3628 */ { MAD_F(0x06ce1994) /* 0.425317362 */, 17 }, - /* 3629 */ { MAD_F(0x06cebd7d) /* 0.425473678 */, 17 }, - /* 3630 */ { MAD_F(0x06cf6169) /* 0.425630009 */, 17 }, - /* 3631 */ { MAD_F(0x06d0055a) /* 0.425786354 */, 17 }, - - /* 3632 */ { MAD_F(0x06d0a94e) /* 0.425942714 */, 17 }, - /* 3633 */ { MAD_F(0x06d14d47) /* 0.426099088 */, 17 }, - /* 3634 */ { MAD_F(0x06d1f143) /* 0.426255476 */, 17 }, - /* 3635 */ { MAD_F(0x06d29543) /* 0.426411878 */, 17 }, - /* 3636 */ { MAD_F(0x06d33947) /* 0.426568295 */, 17 }, - /* 3637 */ { MAD_F(0x06d3dd4e) /* 0.426724726 */, 17 }, - /* 3638 */ { MAD_F(0x06d4815a) /* 0.426881172 */, 17 }, - /* 3639 */ { MAD_F(0x06d52569) /* 0.427037632 */, 17 }, - /* 3640 */ { MAD_F(0x06d5c97c) /* 0.427194106 */, 17 }, - /* 3641 */ { MAD_F(0x06d66d93) /* 0.427350594 */, 17 }, - /* 3642 */ { MAD_F(0x06d711ae) /* 0.427507097 */, 17 }, - /* 3643 */ { MAD_F(0x06d7b5cd) /* 0.427663614 */, 17 }, - /* 3644 */ { MAD_F(0x06d859f0) /* 0.427820146 */, 17 }, - /* 3645 */ { MAD_F(0x06d8fe16) /* 0.427976692 */, 17 }, - /* 3646 */ { MAD_F(0x06d9a240) /* 0.428133252 */, 17 }, - /* 3647 */ { MAD_F(0x06da466f) /* 0.428289826 */, 17 }, - - /* 3648 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 17 }, - /* 3649 */ { MAD_F(0x06db8ed6) /* 0.428603018 */, 17 }, - /* 3650 */ { MAD_F(0x06dc3310) /* 0.428759635 */, 17 }, - /* 3651 */ { MAD_F(0x06dcd74d) /* 0.428916267 */, 17 }, - /* 3652 */ { MAD_F(0x06dd7b8f) /* 0.429072913 */, 17 }, - /* 3653 */ { MAD_F(0x06de1fd4) /* 0.429229573 */, 17 }, - /* 3654 */ { MAD_F(0x06dec41d) /* 0.429386248 */, 17 }, - /* 3655 */ { MAD_F(0x06df686a) /* 0.429542937 */, 17 }, - /* 3656 */ { MAD_F(0x06e00cbb) /* 0.429699640 */, 17 }, - /* 3657 */ { MAD_F(0x06e0b10f) /* 0.429856357 */, 17 }, - /* 3658 */ { MAD_F(0x06e15567) /* 0.430013089 */, 17 }, - /* 3659 */ { MAD_F(0x06e1f9c4) /* 0.430169835 */, 17 }, - /* 3660 */ { MAD_F(0x06e29e24) /* 0.430326595 */, 17 }, - /* 3661 */ { MAD_F(0x06e34287) /* 0.430483370 */, 17 }, - /* 3662 */ { MAD_F(0x06e3e6ef) /* 0.430640159 */, 17 }, - /* 3663 */ { MAD_F(0x06e48b5b) /* 0.430796962 */, 17 }, - - /* 3664 */ { MAD_F(0x06e52fca) /* 0.430953779 */, 17 }, - /* 3665 */ { MAD_F(0x06e5d43d) /* 0.431110611 */, 17 }, - /* 3666 */ { MAD_F(0x06e678b4) /* 0.431267457 */, 17 }, - /* 3667 */ { MAD_F(0x06e71d2f) /* 0.431424317 */, 17 }, - /* 3668 */ { MAD_F(0x06e7c1ae) /* 0.431581192 */, 17 }, - /* 3669 */ { MAD_F(0x06e86630) /* 0.431738080 */, 17 }, - /* 3670 */ { MAD_F(0x06e90ab7) /* 0.431894983 */, 17 }, - /* 3671 */ { MAD_F(0x06e9af41) /* 0.432051900 */, 17 }, - /* 3672 */ { MAD_F(0x06ea53cf) /* 0.432208832 */, 17 }, - /* 3673 */ { MAD_F(0x06eaf860) /* 0.432365778 */, 17 }, - /* 3674 */ { MAD_F(0x06eb9cf6) /* 0.432522737 */, 17 }, - /* 3675 */ { MAD_F(0x06ec418f) /* 0.432679712 */, 17 }, - /* 3676 */ { MAD_F(0x06ece62d) /* 0.432836700 */, 17 }, - /* 3677 */ { MAD_F(0x06ed8ace) /* 0.432993703 */, 17 }, - /* 3678 */ { MAD_F(0x06ee2f73) /* 0.433150720 */, 17 }, - /* 3679 */ { MAD_F(0x06eed41b) /* 0.433307751 */, 17 }, - - /* 3680 */ { MAD_F(0x06ef78c8) /* 0.433464796 */, 17 }, - /* 3681 */ { MAD_F(0x06f01d78) /* 0.433621856 */, 17 }, - /* 3682 */ { MAD_F(0x06f0c22c) /* 0.433778929 */, 17 }, - /* 3683 */ { MAD_F(0x06f166e4) /* 0.433936017 */, 17 }, - /* 3684 */ { MAD_F(0x06f20ba0) /* 0.434093120 */, 17 }, - /* 3685 */ { MAD_F(0x06f2b060) /* 0.434250236 */, 17 }, - /* 3686 */ { MAD_F(0x06f35523) /* 0.434407367 */, 17 }, - /* 3687 */ { MAD_F(0x06f3f9eb) /* 0.434564512 */, 17 }, - /* 3688 */ { MAD_F(0x06f49eb6) /* 0.434721671 */, 17 }, - /* 3689 */ { MAD_F(0x06f54385) /* 0.434878844 */, 17 }, - /* 3690 */ { MAD_F(0x06f5e857) /* 0.435036032 */, 17 }, - /* 3691 */ { MAD_F(0x06f68d2e) /* 0.435193233 */, 17 }, - /* 3692 */ { MAD_F(0x06f73208) /* 0.435350449 */, 17 }, - /* 3693 */ { MAD_F(0x06f7d6e6) /* 0.435507679 */, 17 }, - /* 3694 */ { MAD_F(0x06f87bc8) /* 0.435664924 */, 17 }, - /* 3695 */ { MAD_F(0x06f920ae) /* 0.435822182 */, 17 }, - - /* 3696 */ { MAD_F(0x06f9c597) /* 0.435979455 */, 17 }, - /* 3697 */ { MAD_F(0x06fa6a85) /* 0.436136741 */, 17 }, - /* 3698 */ { MAD_F(0x06fb0f76) /* 0.436294042 */, 17 }, - /* 3699 */ { MAD_F(0x06fbb46b) /* 0.436451358 */, 17 }, - /* 3700 */ { MAD_F(0x06fc5964) /* 0.436608687 */, 17 }, - /* 3701 */ { MAD_F(0x06fcfe60) /* 0.436766031 */, 17 }, - /* 3702 */ { MAD_F(0x06fda361) /* 0.436923388 */, 17 }, - /* 3703 */ { MAD_F(0x06fe4865) /* 0.437080760 */, 17 }, - /* 3704 */ { MAD_F(0x06feed6d) /* 0.437238146 */, 17 }, - /* 3705 */ { MAD_F(0x06ff9279) /* 0.437395547 */, 17 }, - /* 3706 */ { MAD_F(0x07003788) /* 0.437552961 */, 17 }, - /* 3707 */ { MAD_F(0x0700dc9c) /* 0.437710389 */, 17 }, - /* 3708 */ { MAD_F(0x070181b3) /* 0.437867832 */, 17 }, - /* 3709 */ { MAD_F(0x070226ce) /* 0.438025289 */, 17 }, - /* 3710 */ { MAD_F(0x0702cbed) /* 0.438182760 */, 17 }, - /* 3711 */ { MAD_F(0x0703710f) /* 0.438340245 */, 17 }, - - /* 3712 */ { MAD_F(0x07041636) /* 0.438497744 */, 17 }, - /* 3713 */ { MAD_F(0x0704bb60) /* 0.438655258 */, 17 }, - /* 3714 */ { MAD_F(0x0705608e) /* 0.438812785 */, 17 }, - /* 3715 */ { MAD_F(0x070605c0) /* 0.438970327 */, 17 }, - /* 3716 */ { MAD_F(0x0706aaf5) /* 0.439127883 */, 17 }, - /* 3717 */ { MAD_F(0x0707502f) /* 0.439285453 */, 17 }, - /* 3718 */ { MAD_F(0x0707f56c) /* 0.439443037 */, 17 }, - /* 3719 */ { MAD_F(0x07089aad) /* 0.439600635 */, 17 }, - /* 3720 */ { MAD_F(0x07093ff2) /* 0.439758248 */, 17 }, - /* 3721 */ { MAD_F(0x0709e53a) /* 0.439915874 */, 17 }, - /* 3722 */ { MAD_F(0x070a8a86) /* 0.440073515 */, 17 }, - /* 3723 */ { MAD_F(0x070b2fd7) /* 0.440231170 */, 17 }, - /* 3724 */ { MAD_F(0x070bd52a) /* 0.440388839 */, 17 }, - /* 3725 */ { MAD_F(0x070c7a82) /* 0.440546522 */, 17 }, - /* 3726 */ { MAD_F(0x070d1fde) /* 0.440704219 */, 17 }, - /* 3727 */ { MAD_F(0x070dc53d) /* 0.440861930 */, 17 }, - - /* 3728 */ { MAD_F(0x070e6aa0) /* 0.441019655 */, 17 }, - /* 3729 */ { MAD_F(0x070f1007) /* 0.441177395 */, 17 }, - /* 3730 */ { MAD_F(0x070fb571) /* 0.441335148 */, 17 }, - /* 3731 */ { MAD_F(0x07105ae0) /* 0.441492916 */, 17 }, - /* 3732 */ { MAD_F(0x07110052) /* 0.441650697 */, 17 }, - /* 3733 */ { MAD_F(0x0711a5c8) /* 0.441808493 */, 17 }, - /* 3734 */ { MAD_F(0x07124b42) /* 0.441966303 */, 17 }, - /* 3735 */ { MAD_F(0x0712f0bf) /* 0.442124127 */, 17 }, - /* 3736 */ { MAD_F(0x07139641) /* 0.442281965 */, 17 }, - /* 3737 */ { MAD_F(0x07143bc6) /* 0.442439817 */, 17 }, - /* 3738 */ { MAD_F(0x0714e14f) /* 0.442597683 */, 17 }, - /* 3739 */ { MAD_F(0x071586db) /* 0.442755564 */, 17 }, - /* 3740 */ { MAD_F(0x07162c6c) /* 0.442913458 */, 17 }, - /* 3741 */ { MAD_F(0x0716d200) /* 0.443071366 */, 17 }, - /* 3742 */ { MAD_F(0x07177798) /* 0.443229289 */, 17 }, - /* 3743 */ { MAD_F(0x07181d34) /* 0.443387226 */, 17 }, - - /* 3744 */ { MAD_F(0x0718c2d3) /* 0.443545176 */, 17 }, - /* 3745 */ { MAD_F(0x07196877) /* 0.443703141 */, 17 }, - /* 3746 */ { MAD_F(0x071a0e1e) /* 0.443861120 */, 17 }, - /* 3747 */ { MAD_F(0x071ab3c9) /* 0.444019113 */, 17 }, - /* 3748 */ { MAD_F(0x071b5977) /* 0.444177119 */, 17 }, - /* 3749 */ { MAD_F(0x071bff2a) /* 0.444335140 */, 17 }, - /* 3750 */ { MAD_F(0x071ca4e0) /* 0.444493175 */, 17 }, - /* 3751 */ { MAD_F(0x071d4a9a) /* 0.444651224 */, 17 }, - /* 3752 */ { MAD_F(0x071df058) /* 0.444809288 */, 17 }, - /* 3753 */ { MAD_F(0x071e9619) /* 0.444967365 */, 17 }, - /* 3754 */ { MAD_F(0x071f3bde) /* 0.445125456 */, 17 }, - /* 3755 */ { MAD_F(0x071fe1a8) /* 0.445283561 */, 17 }, - /* 3756 */ { MAD_F(0x07208774) /* 0.445441680 */, 17 }, - /* 3757 */ { MAD_F(0x07212d45) /* 0.445599814 */, 17 }, - /* 3758 */ { MAD_F(0x0721d319) /* 0.445757961 */, 17 }, - /* 3759 */ { MAD_F(0x072278f1) /* 0.445916122 */, 17 }, - - /* 3760 */ { MAD_F(0x07231ecd) /* 0.446074298 */, 17 }, - /* 3761 */ { MAD_F(0x0723c4ad) /* 0.446232487 */, 17 }, - /* 3762 */ { MAD_F(0x07246a90) /* 0.446390690 */, 17 }, - /* 3763 */ { MAD_F(0x07251077) /* 0.446548908 */, 17 }, - /* 3764 */ { MAD_F(0x0725b662) /* 0.446707139 */, 17 }, - /* 3765 */ { MAD_F(0x07265c51) /* 0.446865385 */, 17 }, - /* 3766 */ { MAD_F(0x07270244) /* 0.447023644 */, 17 }, - /* 3767 */ { MAD_F(0x0727a83a) /* 0.447181918 */, 17 }, - /* 3768 */ { MAD_F(0x07284e34) /* 0.447340205 */, 17 }, - /* 3769 */ { MAD_F(0x0728f431) /* 0.447498507 */, 17 }, - /* 3770 */ { MAD_F(0x07299a33) /* 0.447656822 */, 17 }, - /* 3771 */ { MAD_F(0x072a4038) /* 0.447815152 */, 17 }, - /* 3772 */ { MAD_F(0x072ae641) /* 0.447973495 */, 17 }, - /* 3773 */ { MAD_F(0x072b8c4e) /* 0.448131853 */, 17 }, - /* 3774 */ { MAD_F(0x072c325e) /* 0.448290224 */, 17 }, - /* 3775 */ { MAD_F(0x072cd873) /* 0.448448609 */, 17 }, - - /* 3776 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 17 }, - /* 3777 */ { MAD_F(0x072e24a7) /* 0.448765422 */, 17 }, - /* 3778 */ { MAD_F(0x072ecac6) /* 0.448923850 */, 17 }, - /* 3779 */ { MAD_F(0x072f70e9) /* 0.449082291 */, 17 }, - /* 3780 */ { MAD_F(0x07301710) /* 0.449240746 */, 17 }, - /* 3781 */ { MAD_F(0x0730bd3b) /* 0.449399216 */, 17 }, - /* 3782 */ { MAD_F(0x0731636a) /* 0.449557699 */, 17 }, - /* 3783 */ { MAD_F(0x0732099c) /* 0.449716196 */, 17 }, - /* 3784 */ { MAD_F(0x0732afd2) /* 0.449874708 */, 17 }, - /* 3785 */ { MAD_F(0x0733560c) /* 0.450033233 */, 17 }, - /* 3786 */ { MAD_F(0x0733fc49) /* 0.450191772 */, 17 }, - /* 3787 */ { MAD_F(0x0734a28b) /* 0.450350325 */, 17 }, - /* 3788 */ { MAD_F(0x073548d0) /* 0.450508892 */, 17 }, - /* 3789 */ { MAD_F(0x0735ef18) /* 0.450667473 */, 17 }, - /* 3790 */ { MAD_F(0x07369565) /* 0.450826068 */, 17 }, - /* 3791 */ { MAD_F(0x07373bb5) /* 0.450984677 */, 17 }, - - /* 3792 */ { MAD_F(0x0737e209) /* 0.451143300 */, 17 }, - /* 3793 */ { MAD_F(0x07388861) /* 0.451301937 */, 17 }, - /* 3794 */ { MAD_F(0x07392ebc) /* 0.451460588 */, 17 }, - /* 3795 */ { MAD_F(0x0739d51c) /* 0.451619252 */, 17 }, - /* 3796 */ { MAD_F(0x073a7b7f) /* 0.451777931 */, 17 }, - /* 3797 */ { MAD_F(0x073b21e5) /* 0.451936623 */, 17 }, - /* 3798 */ { MAD_F(0x073bc850) /* 0.452095330 */, 17 }, - /* 3799 */ { MAD_F(0x073c6ebe) /* 0.452254050 */, 17 }, - /* 3800 */ { MAD_F(0x073d1530) /* 0.452412785 */, 17 }, - /* 3801 */ { MAD_F(0x073dbba6) /* 0.452571533 */, 17 }, - /* 3802 */ { MAD_F(0x073e621f) /* 0.452730295 */, 17 }, - /* 3803 */ { MAD_F(0x073f089c) /* 0.452889071 */, 17 }, - /* 3804 */ { MAD_F(0x073faf1d) /* 0.453047861 */, 17 }, - /* 3805 */ { MAD_F(0x074055a2) /* 0.453206665 */, 17 }, - /* 3806 */ { MAD_F(0x0740fc2a) /* 0.453365483 */, 17 }, - /* 3807 */ { MAD_F(0x0741a2b6) /* 0.453524315 */, 17 }, - - /* 3808 */ { MAD_F(0x07424946) /* 0.453683161 */, 17 }, - /* 3809 */ { MAD_F(0x0742efd9) /* 0.453842020 */, 17 }, - /* 3810 */ { MAD_F(0x07439671) /* 0.454000894 */, 17 }, - /* 3811 */ { MAD_F(0x07443d0c) /* 0.454159781 */, 17 }, - /* 3812 */ { MAD_F(0x0744e3aa) /* 0.454318683 */, 17 }, - /* 3813 */ { MAD_F(0x07458a4d) /* 0.454477598 */, 17 }, - /* 3814 */ { MAD_F(0x074630f3) /* 0.454636527 */, 17 }, - /* 3815 */ { MAD_F(0x0746d79d) /* 0.454795470 */, 17 }, - /* 3816 */ { MAD_F(0x07477e4b) /* 0.454954427 */, 17 }, - /* 3817 */ { MAD_F(0x074824fc) /* 0.455113397 */, 17 }, - /* 3818 */ { MAD_F(0x0748cbb1) /* 0.455272382 */, 17 }, - /* 3819 */ { MAD_F(0x0749726a) /* 0.455431381 */, 17 }, - /* 3820 */ { MAD_F(0x074a1927) /* 0.455590393 */, 17 }, - /* 3821 */ { MAD_F(0x074abfe7) /* 0.455749419 */, 17 }, - /* 3822 */ { MAD_F(0x074b66ab) /* 0.455908459 */, 17 }, - /* 3823 */ { MAD_F(0x074c0d73) /* 0.456067513 */, 17 }, - - /* 3824 */ { MAD_F(0x074cb43e) /* 0.456226581 */, 17 }, - /* 3825 */ { MAD_F(0x074d5b0d) /* 0.456385663 */, 17 }, - /* 3826 */ { MAD_F(0x074e01e0) /* 0.456544759 */, 17 }, - /* 3827 */ { MAD_F(0x074ea8b7) /* 0.456703868 */, 17 }, - /* 3828 */ { MAD_F(0x074f4f91) /* 0.456862992 */, 17 }, - /* 3829 */ { MAD_F(0x074ff66f) /* 0.457022129 */, 17 }, - /* 3830 */ { MAD_F(0x07509d51) /* 0.457181280 */, 17 }, - /* 3831 */ { MAD_F(0x07514437) /* 0.457340445 */, 17 }, - /* 3832 */ { MAD_F(0x0751eb20) /* 0.457499623 */, 17 }, - /* 3833 */ { MAD_F(0x0752920d) /* 0.457658816 */, 17 }, - /* 3834 */ { MAD_F(0x075338fd) /* 0.457818022 */, 17 }, - /* 3835 */ { MAD_F(0x0753dff2) /* 0.457977243 */, 17 }, - /* 3836 */ { MAD_F(0x075486ea) /* 0.458136477 */, 17 }, - /* 3837 */ { MAD_F(0x07552de6) /* 0.458295725 */, 17 }, - /* 3838 */ { MAD_F(0x0755d4e5) /* 0.458454987 */, 17 }, - /* 3839 */ { MAD_F(0x07567be8) /* 0.458614262 */, 17 }, - - /* 3840 */ { MAD_F(0x075722ef) /* 0.458773552 */, 17 }, - /* 3841 */ { MAD_F(0x0757c9fa) /* 0.458932855 */, 17 }, - /* 3842 */ { MAD_F(0x07587108) /* 0.459092172 */, 17 }, - /* 3843 */ { MAD_F(0x0759181a) /* 0.459251503 */, 17 }, - /* 3844 */ { MAD_F(0x0759bf30) /* 0.459410848 */, 17 }, - /* 3845 */ { MAD_F(0x075a664a) /* 0.459570206 */, 17 }, - /* 3846 */ { MAD_F(0x075b0d67) /* 0.459729579 */, 17 }, - /* 3847 */ { MAD_F(0x075bb488) /* 0.459888965 */, 17 }, - /* 3848 */ { MAD_F(0x075c5bac) /* 0.460048365 */, 17 }, - /* 3849 */ { MAD_F(0x075d02d5) /* 0.460207779 */, 17 }, - /* 3850 */ { MAD_F(0x075daa01) /* 0.460367206 */, 17 }, - /* 3851 */ { MAD_F(0x075e5130) /* 0.460526648 */, 17 }, - /* 3852 */ { MAD_F(0x075ef864) /* 0.460686103 */, 17 }, - /* 3853 */ { MAD_F(0x075f9f9b) /* 0.460845572 */, 17 }, - /* 3854 */ { MAD_F(0x076046d6) /* 0.461005055 */, 17 }, - /* 3855 */ { MAD_F(0x0760ee14) /* 0.461164552 */, 17 }, - - /* 3856 */ { MAD_F(0x07619557) /* 0.461324062 */, 17 }, - /* 3857 */ { MAD_F(0x07623c9d) /* 0.461483586 */, 17 }, - /* 3858 */ { MAD_F(0x0762e3e6) /* 0.461643124 */, 17 }, - /* 3859 */ { MAD_F(0x07638b34) /* 0.461802676 */, 17 }, - /* 3860 */ { MAD_F(0x07643285) /* 0.461962242 */, 17 }, - /* 3861 */ { MAD_F(0x0764d9d9) /* 0.462121821 */, 17 }, - /* 3862 */ { MAD_F(0x07658132) /* 0.462281414 */, 17 }, - /* 3863 */ { MAD_F(0x0766288e) /* 0.462441021 */, 17 }, - /* 3864 */ { MAD_F(0x0766cfee) /* 0.462600642 */, 17 }, - /* 3865 */ { MAD_F(0x07677751) /* 0.462760276 */, 17 }, - /* 3866 */ { MAD_F(0x07681eb9) /* 0.462919924 */, 17 }, - /* 3867 */ { MAD_F(0x0768c624) /* 0.463079586 */, 17 }, - /* 3868 */ { MAD_F(0x07696d92) /* 0.463239262 */, 17 }, - /* 3869 */ { MAD_F(0x076a1505) /* 0.463398951 */, 17 }, - /* 3870 */ { MAD_F(0x076abc7b) /* 0.463558655 */, 17 }, - /* 3871 */ { MAD_F(0x076b63f4) /* 0.463718372 */, 17 }, - - /* 3872 */ { MAD_F(0x076c0b72) /* 0.463878102 */, 17 }, - /* 3873 */ { MAD_F(0x076cb2f3) /* 0.464037847 */, 17 }, - /* 3874 */ { MAD_F(0x076d5a78) /* 0.464197605 */, 17 }, - /* 3875 */ { MAD_F(0x076e0200) /* 0.464357377 */, 17 }, - /* 3876 */ { MAD_F(0x076ea98c) /* 0.464517163 */, 17 }, - /* 3877 */ { MAD_F(0x076f511c) /* 0.464676962 */, 17 }, - /* 3878 */ { MAD_F(0x076ff8b0) /* 0.464836776 */, 17 }, - /* 3879 */ { MAD_F(0x0770a047) /* 0.464996603 */, 17 }, - /* 3880 */ { MAD_F(0x077147e2) /* 0.465156443 */, 17 }, - /* 3881 */ { MAD_F(0x0771ef80) /* 0.465316298 */, 17 }, - /* 3882 */ { MAD_F(0x07729723) /* 0.465476166 */, 17 }, - /* 3883 */ { MAD_F(0x07733ec9) /* 0.465636048 */, 17 }, - /* 3884 */ { MAD_F(0x0773e672) /* 0.465795943 */, 17 }, - /* 3885 */ { MAD_F(0x07748e20) /* 0.465955853 */, 17 }, - /* 3886 */ { MAD_F(0x077535d1) /* 0.466115776 */, 17 }, - /* 3887 */ { MAD_F(0x0775dd85) /* 0.466275713 */, 17 }, - - /* 3888 */ { MAD_F(0x0776853e) /* 0.466435663 */, 17 }, - /* 3889 */ { MAD_F(0x07772cfa) /* 0.466595627 */, 17 }, - /* 3890 */ { MAD_F(0x0777d4ba) /* 0.466755605 */, 17 }, - /* 3891 */ { MAD_F(0x07787c7d) /* 0.466915597 */, 17 }, - /* 3892 */ { MAD_F(0x07792444) /* 0.467075602 */, 17 }, - /* 3893 */ { MAD_F(0x0779cc0f) /* 0.467235621 */, 17 }, - /* 3894 */ { MAD_F(0x077a73dd) /* 0.467395654 */, 17 }, - /* 3895 */ { MAD_F(0x077b1baf) /* 0.467555701 */, 17 }, - /* 3896 */ { MAD_F(0x077bc385) /* 0.467715761 */, 17 }, - /* 3897 */ { MAD_F(0x077c6b5f) /* 0.467875835 */, 17 }, - /* 3898 */ { MAD_F(0x077d133c) /* 0.468035922 */, 17 }, - /* 3899 */ { MAD_F(0x077dbb1d) /* 0.468196023 */, 17 }, - /* 3900 */ { MAD_F(0x077e6301) /* 0.468356138 */, 17 }, - /* 3901 */ { MAD_F(0x077f0ae9) /* 0.468516267 */, 17 }, - /* 3902 */ { MAD_F(0x077fb2d5) /* 0.468676409 */, 17 }, - /* 3903 */ { MAD_F(0x07805ac5) /* 0.468836565 */, 17 }, - - /* 3904 */ { MAD_F(0x078102b8) /* 0.468996735 */, 17 }, - /* 3905 */ { MAD_F(0x0781aaaf) /* 0.469156918 */, 17 }, - /* 3906 */ { MAD_F(0x078252aa) /* 0.469317115 */, 17 }, - /* 3907 */ { MAD_F(0x0782faa8) /* 0.469477326 */, 17 }, - /* 3908 */ { MAD_F(0x0783a2aa) /* 0.469637550 */, 17 }, - /* 3909 */ { MAD_F(0x07844aaf) /* 0.469797788 */, 17 }, - /* 3910 */ { MAD_F(0x0784f2b8) /* 0.469958040 */, 17 }, - /* 3911 */ { MAD_F(0x07859ac5) /* 0.470118305 */, 17 }, - /* 3912 */ { MAD_F(0x078642d6) /* 0.470278584 */, 17 }, - /* 3913 */ { MAD_F(0x0786eaea) /* 0.470438877 */, 17 }, - /* 3914 */ { MAD_F(0x07879302) /* 0.470599183 */, 17 }, - /* 3915 */ { MAD_F(0x07883b1e) /* 0.470759503 */, 17 }, - /* 3916 */ { MAD_F(0x0788e33d) /* 0.470919836 */, 17 }, - /* 3917 */ { MAD_F(0x07898b60) /* 0.471080184 */, 17 }, - /* 3918 */ { MAD_F(0x078a3386) /* 0.471240545 */, 17 }, - /* 3919 */ { MAD_F(0x078adbb0) /* 0.471400919 */, 17 }, - - /* 3920 */ { MAD_F(0x078b83de) /* 0.471561307 */, 17 }, - /* 3921 */ { MAD_F(0x078c2c10) /* 0.471721709 */, 17 }, - /* 3922 */ { MAD_F(0x078cd445) /* 0.471882125 */, 17 }, - /* 3923 */ { MAD_F(0x078d7c7e) /* 0.472042554 */, 17 }, - /* 3924 */ { MAD_F(0x078e24ba) /* 0.472202996 */, 17 }, - /* 3925 */ { MAD_F(0x078eccfb) /* 0.472363453 */, 17 }, - /* 3926 */ { MAD_F(0x078f753e) /* 0.472523923 */, 17 }, - /* 3927 */ { MAD_F(0x07901d86) /* 0.472684406 */, 17 }, - /* 3928 */ { MAD_F(0x0790c5d1) /* 0.472844904 */, 17 }, - /* 3929 */ { MAD_F(0x07916e20) /* 0.473005414 */, 17 }, - /* 3930 */ { MAD_F(0x07921672) /* 0.473165939 */, 17 }, - /* 3931 */ { MAD_F(0x0792bec8) /* 0.473326477 */, 17 }, - /* 3932 */ { MAD_F(0x07936722) /* 0.473487029 */, 17 }, - /* 3933 */ { MAD_F(0x07940f80) /* 0.473647594 */, 17 }, - /* 3934 */ { MAD_F(0x0794b7e1) /* 0.473808173 */, 17 }, - /* 3935 */ { MAD_F(0x07956045) /* 0.473968765 */, 17 }, - - /* 3936 */ { MAD_F(0x079608ae) /* 0.474129372 */, 17 }, - /* 3937 */ { MAD_F(0x0796b11a) /* 0.474289991 */, 17 }, - /* 3938 */ { MAD_F(0x0797598a) /* 0.474450625 */, 17 }, - /* 3939 */ { MAD_F(0x079801fd) /* 0.474611272 */, 17 }, - /* 3940 */ { MAD_F(0x0798aa74) /* 0.474771932 */, 17 }, - /* 3941 */ { MAD_F(0x079952ee) /* 0.474932606 */, 17 }, - /* 3942 */ { MAD_F(0x0799fb6d) /* 0.475093294 */, 17 }, - /* 3943 */ { MAD_F(0x079aa3ef) /* 0.475253995 */, 17 }, - /* 3944 */ { MAD_F(0x079b4c74) /* 0.475414710 */, 17 }, - /* 3945 */ { MAD_F(0x079bf4fd) /* 0.475575439 */, 17 }, - /* 3946 */ { MAD_F(0x079c9d8a) /* 0.475736181 */, 17 }, - /* 3947 */ { MAD_F(0x079d461b) /* 0.475896936 */, 17 }, - /* 3948 */ { MAD_F(0x079deeaf) /* 0.476057705 */, 17 }, - /* 3949 */ { MAD_F(0x079e9747) /* 0.476218488 */, 17 }, - /* 3950 */ { MAD_F(0x079f3fe2) /* 0.476379285 */, 17 }, - /* 3951 */ { MAD_F(0x079fe881) /* 0.476540095 */, 17 }, - - /* 3952 */ { MAD_F(0x07a09124) /* 0.476700918 */, 17 }, - /* 3953 */ { MAD_F(0x07a139ca) /* 0.476861755 */, 17 }, - /* 3954 */ { MAD_F(0x07a1e274) /* 0.477022606 */, 17 }, - /* 3955 */ { MAD_F(0x07a28b22) /* 0.477183470 */, 17 }, - /* 3956 */ { MAD_F(0x07a333d3) /* 0.477344348 */, 17 }, - /* 3957 */ { MAD_F(0x07a3dc88) /* 0.477505239 */, 17 }, - /* 3958 */ { MAD_F(0x07a48541) /* 0.477666144 */, 17 }, - /* 3959 */ { MAD_F(0x07a52dfd) /* 0.477827062 */, 17 }, - /* 3960 */ { MAD_F(0x07a5d6bd) /* 0.477987994 */, 17 }, - /* 3961 */ { MAD_F(0x07a67f80) /* 0.478148940 */, 17 }, - /* 3962 */ { MAD_F(0x07a72847) /* 0.478309899 */, 17 }, - /* 3963 */ { MAD_F(0x07a7d112) /* 0.478470871 */, 17 }, - /* 3964 */ { MAD_F(0x07a879e1) /* 0.478631857 */, 17 }, - /* 3965 */ { MAD_F(0x07a922b3) /* 0.478792857 */, 17 }, - /* 3966 */ { MAD_F(0x07a9cb88) /* 0.478953870 */, 17 }, - /* 3967 */ { MAD_F(0x07aa7462) /* 0.479114897 */, 17 }, - - /* 3968 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 17 }, - /* 3969 */ { MAD_F(0x07abc61f) /* 0.479436991 */, 17 }, - /* 3970 */ { MAD_F(0x07ac6f03) /* 0.479598058 */, 17 }, - /* 3971 */ { MAD_F(0x07ad17eb) /* 0.479759139 */, 17 }, - /* 3972 */ { MAD_F(0x07adc0d6) /* 0.479920233 */, 17 }, - /* 3973 */ { MAD_F(0x07ae69c6) /* 0.480081341 */, 17 }, - /* 3974 */ { MAD_F(0x07af12b8) /* 0.480242463 */, 17 }, - /* 3975 */ { MAD_F(0x07afbbaf) /* 0.480403598 */, 17 }, - /* 3976 */ { MAD_F(0x07b064a8) /* 0.480564746 */, 17 }, - /* 3977 */ { MAD_F(0x07b10da6) /* 0.480725908 */, 17 }, - /* 3978 */ { MAD_F(0x07b1b6a7) /* 0.480887083 */, 17 }, - /* 3979 */ { MAD_F(0x07b25fac) /* 0.481048272 */, 17 }, - /* 3980 */ { MAD_F(0x07b308b5) /* 0.481209475 */, 17 }, - /* 3981 */ { MAD_F(0x07b3b1c1) /* 0.481370691 */, 17 }, - /* 3982 */ { MAD_F(0x07b45ad0) /* 0.481531920 */, 17 }, - /* 3983 */ { MAD_F(0x07b503e4) /* 0.481693163 */, 17 }, - - /* 3984 */ { MAD_F(0x07b5acfb) /* 0.481854420 */, 17 }, - /* 3985 */ { MAD_F(0x07b65615) /* 0.482015690 */, 17 }, - /* 3986 */ { MAD_F(0x07b6ff33) /* 0.482176973 */, 17 }, - /* 3987 */ { MAD_F(0x07b7a855) /* 0.482338270 */, 17 }, - /* 3988 */ { MAD_F(0x07b8517b) /* 0.482499580 */, 17 }, - /* 3989 */ { MAD_F(0x07b8faa4) /* 0.482660904 */, 17 }, - /* 3990 */ { MAD_F(0x07b9a3d0) /* 0.482822242 */, 17 }, - /* 3991 */ { MAD_F(0x07ba4d01) /* 0.482983592 */, 17 }, - /* 3992 */ { MAD_F(0x07baf635) /* 0.483144957 */, 17 }, - /* 3993 */ { MAD_F(0x07bb9f6c) /* 0.483306335 */, 17 }, - /* 3994 */ { MAD_F(0x07bc48a7) /* 0.483467726 */, 17 }, - /* 3995 */ { MAD_F(0x07bcf1e6) /* 0.483629131 */, 17 }, - /* 3996 */ { MAD_F(0x07bd9b28) /* 0.483790549 */, 17 }, - /* 3997 */ { MAD_F(0x07be446e) /* 0.483951980 */, 17 }, - /* 3998 */ { MAD_F(0x07beedb8) /* 0.484113426 */, 17 }, - /* 3999 */ { MAD_F(0x07bf9705) /* 0.484274884 */, 17 }, - - /* 4000 */ { MAD_F(0x07c04056) /* 0.484436356 */, 17 }, - /* 4001 */ { MAD_F(0x07c0e9aa) /* 0.484597842 */, 17 }, - /* 4002 */ { MAD_F(0x07c19302) /* 0.484759341 */, 17 }, - /* 4003 */ { MAD_F(0x07c23c5e) /* 0.484920853 */, 17 }, - /* 4004 */ { MAD_F(0x07c2e5bd) /* 0.485082379 */, 17 }, - /* 4005 */ { MAD_F(0x07c38f20) /* 0.485243918 */, 17 }, - /* 4006 */ { MAD_F(0x07c43887) /* 0.485405471 */, 17 }, - /* 4007 */ { MAD_F(0x07c4e1f1) /* 0.485567037 */, 17 }, - /* 4008 */ { MAD_F(0x07c58b5f) /* 0.485728617 */, 17 }, - /* 4009 */ { MAD_F(0x07c634d0) /* 0.485890210 */, 17 }, - /* 4010 */ { MAD_F(0x07c6de45) /* 0.486051817 */, 17 }, - /* 4011 */ { MAD_F(0x07c787bd) /* 0.486213436 */, 17 }, - /* 4012 */ { MAD_F(0x07c83139) /* 0.486375070 */, 17 }, - /* 4013 */ { MAD_F(0x07c8dab9) /* 0.486536717 */, 17 }, - /* 4014 */ { MAD_F(0x07c9843c) /* 0.486698377 */, 17 }, - /* 4015 */ { MAD_F(0x07ca2dc3) /* 0.486860051 */, 17 }, - - /* 4016 */ { MAD_F(0x07cad74e) /* 0.487021738 */, 17 }, - /* 4017 */ { MAD_F(0x07cb80dc) /* 0.487183438 */, 17 }, - /* 4018 */ { MAD_F(0x07cc2a6e) /* 0.487345152 */, 17 }, - /* 4019 */ { MAD_F(0x07ccd403) /* 0.487506879 */, 17 }, - /* 4020 */ { MAD_F(0x07cd7d9c) /* 0.487668620 */, 17 }, - /* 4021 */ { MAD_F(0x07ce2739) /* 0.487830374 */, 17 }, - /* 4022 */ { MAD_F(0x07ced0d9) /* 0.487992142 */, 17 }, - /* 4023 */ { MAD_F(0x07cf7a7d) /* 0.488153923 */, 17 }, - /* 4024 */ { MAD_F(0x07d02424) /* 0.488315717 */, 17 }, - /* 4025 */ { MAD_F(0x07d0cdcf) /* 0.488477525 */, 17 }, - /* 4026 */ { MAD_F(0x07d1777e) /* 0.488639346 */, 17 }, - /* 4027 */ { MAD_F(0x07d22130) /* 0.488801181 */, 17 }, - /* 4028 */ { MAD_F(0x07d2cae5) /* 0.488963029 */, 17 }, - /* 4029 */ { MAD_F(0x07d3749f) /* 0.489124890 */, 17 }, - /* 4030 */ { MAD_F(0x07d41e5c) /* 0.489286765 */, 17 }, - /* 4031 */ { MAD_F(0x07d4c81c) /* 0.489448653 */, 17 }, - - /* 4032 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 17 }, - /* 4033 */ { MAD_F(0x07d61ba8) /* 0.489772470 */, 17 }, - /* 4034 */ { MAD_F(0x07d6c573) /* 0.489934398 */, 17 }, - /* 4035 */ { MAD_F(0x07d76f42) /* 0.490096340 */, 17 }, - /* 4036 */ { MAD_F(0x07d81915) /* 0.490258295 */, 17 }, - /* 4037 */ { MAD_F(0x07d8c2eb) /* 0.490420263 */, 17 }, - /* 4038 */ { MAD_F(0x07d96cc4) /* 0.490582245 */, 17 }, - /* 4039 */ { MAD_F(0x07da16a2) /* 0.490744240 */, 17 }, - /* 4040 */ { MAD_F(0x07dac083) /* 0.490906249 */, 17 }, - /* 4041 */ { MAD_F(0x07db6a67) /* 0.491068271 */, 17 }, - /* 4042 */ { MAD_F(0x07dc144f) /* 0.491230306 */, 17 }, - /* 4043 */ { MAD_F(0x07dcbe3b) /* 0.491392355 */, 17 }, - /* 4044 */ { MAD_F(0x07dd682a) /* 0.491554417 */, 17 }, - /* 4045 */ { MAD_F(0x07de121d) /* 0.491716492 */, 17 }, - /* 4046 */ { MAD_F(0x07debc13) /* 0.491878581 */, 17 }, - /* 4047 */ { MAD_F(0x07df660d) /* 0.492040683 */, 17 }, - - /* 4048 */ { MAD_F(0x07e0100a) /* 0.492202799 */, 17 }, - /* 4049 */ { MAD_F(0x07e0ba0c) /* 0.492364928 */, 17 }, - /* 4050 */ { MAD_F(0x07e16410) /* 0.492527070 */, 17 }, - /* 4051 */ { MAD_F(0x07e20e19) /* 0.492689225 */, 17 }, - /* 4052 */ { MAD_F(0x07e2b824) /* 0.492851394 */, 17 }, - /* 4053 */ { MAD_F(0x07e36234) /* 0.493013576 */, 17 }, - /* 4054 */ { MAD_F(0x07e40c47) /* 0.493175772 */, 17 }, - /* 4055 */ { MAD_F(0x07e4b65e) /* 0.493337981 */, 17 }, - /* 4056 */ { MAD_F(0x07e56078) /* 0.493500203 */, 17 }, - /* 4057 */ { MAD_F(0x07e60a95) /* 0.493662438 */, 17 }, - /* 4058 */ { MAD_F(0x07e6b4b7) /* 0.493824687 */, 17 }, - /* 4059 */ { MAD_F(0x07e75edc) /* 0.493986949 */, 17 }, - /* 4060 */ { MAD_F(0x07e80904) /* 0.494149225 */, 17 }, - /* 4061 */ { MAD_F(0x07e8b330) /* 0.494311514 */, 17 }, - /* 4062 */ { MAD_F(0x07e95d60) /* 0.494473816 */, 17 }, - /* 4063 */ { MAD_F(0x07ea0793) /* 0.494636131 */, 17 }, - - /* 4064 */ { MAD_F(0x07eab1ca) /* 0.494798460 */, 17 }, - /* 4065 */ { MAD_F(0x07eb5c04) /* 0.494960802 */, 17 }, - /* 4066 */ { MAD_F(0x07ec0642) /* 0.495123158 */, 17 }, - /* 4067 */ { MAD_F(0x07ecb084) /* 0.495285526 */, 17 }, - /* 4068 */ { MAD_F(0x07ed5ac9) /* 0.495447908 */, 17 }, - /* 4069 */ { MAD_F(0x07ee0512) /* 0.495610304 */, 17 }, - /* 4070 */ { MAD_F(0x07eeaf5e) /* 0.495772712 */, 17 }, - /* 4071 */ { MAD_F(0x07ef59ae) /* 0.495935134 */, 17 }, - /* 4072 */ { MAD_F(0x07f00401) /* 0.496097570 */, 17 }, - /* 4073 */ { MAD_F(0x07f0ae58) /* 0.496260018 */, 17 }, - /* 4074 */ { MAD_F(0x07f158b3) /* 0.496422480 */, 17 }, - /* 4075 */ { MAD_F(0x07f20311) /* 0.496584955 */, 17 }, - /* 4076 */ { MAD_F(0x07f2ad72) /* 0.496747444 */, 17 }, - /* 4077 */ { MAD_F(0x07f357d8) /* 0.496909945 */, 17 }, - /* 4078 */ { MAD_F(0x07f40240) /* 0.497072460 */, 17 }, - /* 4079 */ { MAD_F(0x07f4acad) /* 0.497234989 */, 17 }, - - /* 4080 */ { MAD_F(0x07f5571d) /* 0.497397530 */, 17 }, - /* 4081 */ { MAD_F(0x07f60190) /* 0.497560085 */, 17 }, - /* 4082 */ { MAD_F(0x07f6ac07) /* 0.497722653 */, 17 }, - /* 4083 */ { MAD_F(0x07f75682) /* 0.497885235 */, 17 }, - /* 4084 */ { MAD_F(0x07f80100) /* 0.498047829 */, 17 }, - /* 4085 */ { MAD_F(0x07f8ab82) /* 0.498210437 */, 17 }, - /* 4086 */ { MAD_F(0x07f95607) /* 0.498373058 */, 17 }, - /* 4087 */ { MAD_F(0x07fa0090) /* 0.498535693 */, 17 }, - /* 4088 */ { MAD_F(0x07faab1c) /* 0.498698341 */, 17 }, - /* 4089 */ { MAD_F(0x07fb55ac) /* 0.498861002 */, 17 }, - /* 4090 */ { MAD_F(0x07fc0040) /* 0.499023676 */, 17 }, - /* 4091 */ { MAD_F(0x07fcaad7) /* 0.499186364 */, 17 }, - /* 4092 */ { MAD_F(0x07fd5572) /* 0.499349064 */, 17 }, - /* 4093 */ { MAD_F(0x07fe0010) /* 0.499511778 */, 17 }, - /* 4094 */ { MAD_F(0x07feaab2) /* 0.499674506 */, 17 }, - /* 4095 */ { MAD_F(0x07ff5557) /* 0.499837246 */, 17 }, - - /* 4096 */ { MAD_F(0x04000000) /* 0.250000000 */, 18 }, - /* 4097 */ { MAD_F(0x04005556) /* 0.250081384 */, 18 }, - /* 4098 */ { MAD_F(0x0400aaae) /* 0.250162774 */, 18 }, - /* 4099 */ { MAD_F(0x04010008) /* 0.250244170 */, 18 }, - /* 4100 */ { MAD_F(0x04015563) /* 0.250325574 */, 18 }, - /* 4101 */ { MAD_F(0x0401aac1) /* 0.250406984 */, 18 }, - /* 4102 */ { MAD_F(0x04020020) /* 0.250488400 */, 18 }, - /* 4103 */ { MAD_F(0x04025581) /* 0.250569824 */, 18 }, - /* 4104 */ { MAD_F(0x0402aae3) /* 0.250651254 */, 18 }, - /* 4105 */ { MAD_F(0x04030048) /* 0.250732690 */, 18 }, - /* 4106 */ { MAD_F(0x040355ae) /* 0.250814133 */, 18 }, - /* 4107 */ { MAD_F(0x0403ab16) /* 0.250895583 */, 18 }, - /* 4108 */ { MAD_F(0x04040080) /* 0.250977039 */, 18 }, - /* 4109 */ { MAD_F(0x040455eb) /* 0.251058502 */, 18 }, - /* 4110 */ { MAD_F(0x0404ab59) /* 0.251139971 */, 18 }, - /* 4111 */ { MAD_F(0x040500c8) /* 0.251221448 */, 18 }, - - /* 4112 */ { MAD_F(0x04055638) /* 0.251302930 */, 18 }, - /* 4113 */ { MAD_F(0x0405abab) /* 0.251384420 */, 18 }, - /* 4114 */ { MAD_F(0x0406011f) /* 0.251465916 */, 18 }, - /* 4115 */ { MAD_F(0x04065696) /* 0.251547418 */, 18 }, - /* 4116 */ { MAD_F(0x0406ac0e) /* 0.251628927 */, 18 }, - /* 4117 */ { MAD_F(0x04070187) /* 0.251710443 */, 18 }, - /* 4118 */ { MAD_F(0x04075703) /* 0.251791965 */, 18 }, - /* 4119 */ { MAD_F(0x0407ac80) /* 0.251873494 */, 18 }, - /* 4120 */ { MAD_F(0x040801ff) /* 0.251955030 */, 18 }, - /* 4121 */ { MAD_F(0x04085780) /* 0.252036572 */, 18 }, - /* 4122 */ { MAD_F(0x0408ad02) /* 0.252118121 */, 18 }, - /* 4123 */ { MAD_F(0x04090287) /* 0.252199676 */, 18 }, - /* 4124 */ { MAD_F(0x0409580d) /* 0.252281238 */, 18 }, - /* 4125 */ { MAD_F(0x0409ad95) /* 0.252362807 */, 18 }, - /* 4126 */ { MAD_F(0x040a031e) /* 0.252444382 */, 18 }, - /* 4127 */ { MAD_F(0x040a58aa) /* 0.252525963 */, 18 }, - - /* 4128 */ { MAD_F(0x040aae37) /* 0.252607552 */, 18 }, - /* 4129 */ { MAD_F(0x040b03c6) /* 0.252689147 */, 18 }, - /* 4130 */ { MAD_F(0x040b5957) /* 0.252770748 */, 18 }, - /* 4131 */ { MAD_F(0x040baee9) /* 0.252852356 */, 18 }, - /* 4132 */ { MAD_F(0x040c047e) /* 0.252933971 */, 18 }, - /* 4133 */ { MAD_F(0x040c5a14) /* 0.253015592 */, 18 }, - /* 4134 */ { MAD_F(0x040cafab) /* 0.253097220 */, 18 }, - /* 4135 */ { MAD_F(0x040d0545) /* 0.253178854 */, 18 }, - /* 4136 */ { MAD_F(0x040d5ae0) /* 0.253260495 */, 18 }, - /* 4137 */ { MAD_F(0x040db07d) /* 0.253342143 */, 18 }, - /* 4138 */ { MAD_F(0x040e061c) /* 0.253423797 */, 18 }, - /* 4139 */ { MAD_F(0x040e5bbd) /* 0.253505457 */, 18 }, - /* 4140 */ { MAD_F(0x040eb15f) /* 0.253587125 */, 18 }, - /* 4141 */ { MAD_F(0x040f0703) /* 0.253668799 */, 18 }, - /* 4142 */ { MAD_F(0x040f5ca9) /* 0.253750479 */, 18 }, - /* 4143 */ { MAD_F(0x040fb251) /* 0.253832166 */, 18 }, - - /* 4144 */ { MAD_F(0x041007fa) /* 0.253913860 */, 18 }, - /* 4145 */ { MAD_F(0x04105da6) /* 0.253995560 */, 18 }, - /* 4146 */ { MAD_F(0x0410b353) /* 0.254077266 */, 18 }, - /* 4147 */ { MAD_F(0x04110901) /* 0.254158980 */, 18 }, - /* 4148 */ { MAD_F(0x04115eb2) /* 0.254240700 */, 18 }, - /* 4149 */ { MAD_F(0x0411b464) /* 0.254322426 */, 18 }, - /* 4150 */ { MAD_F(0x04120a18) /* 0.254404159 */, 18 }, - /* 4151 */ { MAD_F(0x04125fce) /* 0.254485899 */, 18 }, - /* 4152 */ { MAD_F(0x0412b586) /* 0.254567645 */, 18 }, - /* 4153 */ { MAD_F(0x04130b3f) /* 0.254649397 */, 18 }, - /* 4154 */ { MAD_F(0x041360fa) /* 0.254731157 */, 18 }, - /* 4155 */ { MAD_F(0x0413b6b7) /* 0.254812922 */, 18 }, - /* 4156 */ { MAD_F(0x04140c75) /* 0.254894695 */, 18 }, - /* 4157 */ { MAD_F(0x04146236) /* 0.254976474 */, 18 }, - /* 4158 */ { MAD_F(0x0414b7f8) /* 0.255058259 */, 18 }, - /* 4159 */ { MAD_F(0x04150dbc) /* 0.255140051 */, 18 }, - - /* 4160 */ { MAD_F(0x04156381) /* 0.255221850 */, 18 }, - /* 4161 */ { MAD_F(0x0415b949) /* 0.255303655 */, 18 }, - /* 4162 */ { MAD_F(0x04160f12) /* 0.255385467 */, 18 }, - /* 4163 */ { MAD_F(0x041664dd) /* 0.255467285 */, 18 }, - /* 4164 */ { MAD_F(0x0416baaa) /* 0.255549110 */, 18 }, - /* 4165 */ { MAD_F(0x04171078) /* 0.255630941 */, 18 }, - /* 4166 */ { MAD_F(0x04176648) /* 0.255712779 */, 18 }, - /* 4167 */ { MAD_F(0x0417bc1a) /* 0.255794624 */, 18 }, - /* 4168 */ { MAD_F(0x041811ee) /* 0.255876475 */, 18 }, - /* 4169 */ { MAD_F(0x041867c3) /* 0.255958332 */, 18 }, - /* 4170 */ { MAD_F(0x0418bd9b) /* 0.256040196 */, 18 }, - /* 4171 */ { MAD_F(0x04191374) /* 0.256122067 */, 18 }, - /* 4172 */ { MAD_F(0x0419694e) /* 0.256203944 */, 18 }, - /* 4173 */ { MAD_F(0x0419bf2b) /* 0.256285828 */, 18 }, - /* 4174 */ { MAD_F(0x041a1509) /* 0.256367718 */, 18 }, - /* 4175 */ { MAD_F(0x041a6ae9) /* 0.256449615 */, 18 }, - - /* 4176 */ { MAD_F(0x041ac0cb) /* 0.256531518 */, 18 }, - /* 4177 */ { MAD_F(0x041b16ae) /* 0.256613428 */, 18 }, - /* 4178 */ { MAD_F(0x041b6c94) /* 0.256695344 */, 18 }, - /* 4179 */ { MAD_F(0x041bc27b) /* 0.256777267 */, 18 }, - /* 4180 */ { MAD_F(0x041c1863) /* 0.256859197 */, 18 }, - /* 4181 */ { MAD_F(0x041c6e4e) /* 0.256941133 */, 18 }, - /* 4182 */ { MAD_F(0x041cc43a) /* 0.257023076 */, 18 }, - /* 4183 */ { MAD_F(0x041d1a28) /* 0.257105025 */, 18 }, - /* 4184 */ { MAD_F(0x041d7018) /* 0.257186980 */, 18 }, - /* 4185 */ { MAD_F(0x041dc60a) /* 0.257268942 */, 18 }, - /* 4186 */ { MAD_F(0x041e1bfd) /* 0.257350911 */, 18 }, - /* 4187 */ { MAD_F(0x041e71f2) /* 0.257432886 */, 18 }, - /* 4188 */ { MAD_F(0x041ec7e9) /* 0.257514868 */, 18 }, - /* 4189 */ { MAD_F(0x041f1de1) /* 0.257596856 */, 18 }, - /* 4190 */ { MAD_F(0x041f73dc) /* 0.257678851 */, 18 }, - /* 4191 */ { MAD_F(0x041fc9d8) /* 0.257760852 */, 18 }, - - /* 4192 */ { MAD_F(0x04201fd5) /* 0.257842860 */, 18 }, - /* 4193 */ { MAD_F(0x042075d5) /* 0.257924875 */, 18 }, - /* 4194 */ { MAD_F(0x0420cbd6) /* 0.258006895 */, 18 }, - /* 4195 */ { MAD_F(0x042121d9) /* 0.258088923 */, 18 }, - /* 4196 */ { MAD_F(0x042177de) /* 0.258170957 */, 18 }, - /* 4197 */ { MAD_F(0x0421cde5) /* 0.258252997 */, 18 }, - /* 4198 */ { MAD_F(0x042223ed) /* 0.258335044 */, 18 }, - /* 4199 */ { MAD_F(0x042279f7) /* 0.258417097 */, 18 }, - /* 4200 */ { MAD_F(0x0422d003) /* 0.258499157 */, 18 }, - /* 4201 */ { MAD_F(0x04232611) /* 0.258581224 */, 18 }, - /* 4202 */ { MAD_F(0x04237c20) /* 0.258663297 */, 18 }, - /* 4203 */ { MAD_F(0x0423d231) /* 0.258745376 */, 18 }, - /* 4204 */ { MAD_F(0x04242844) /* 0.258827462 */, 18 }, - /* 4205 */ { MAD_F(0x04247e58) /* 0.258909555 */, 18 }, - /* 4206 */ { MAD_F(0x0424d46e) /* 0.258991654 */, 18 }, - /* 4207 */ { MAD_F(0x04252a87) /* 0.259073760 */, 18 }, - - /* 4208 */ { MAD_F(0x042580a0) /* 0.259155872 */, 18 }, - /* 4209 */ { MAD_F(0x0425d6bc) /* 0.259237990 */, 18 }, - /* 4210 */ { MAD_F(0x04262cd9) /* 0.259320115 */, 18 }, - /* 4211 */ { MAD_F(0x042682f8) /* 0.259402247 */, 18 }, - /* 4212 */ { MAD_F(0x0426d919) /* 0.259484385 */, 18 }, - /* 4213 */ { MAD_F(0x04272f3b) /* 0.259566529 */, 18 }, - /* 4214 */ { MAD_F(0x04278560) /* 0.259648680 */, 18 }, - /* 4215 */ { MAD_F(0x0427db86) /* 0.259730838 */, 18 }, - /* 4216 */ { MAD_F(0x042831ad) /* 0.259813002 */, 18 }, - /* 4217 */ { MAD_F(0x042887d7) /* 0.259895173 */, 18 }, - /* 4218 */ { MAD_F(0x0428de02) /* 0.259977350 */, 18 }, - /* 4219 */ { MAD_F(0x0429342f) /* 0.260059533 */, 18 }, - /* 4220 */ { MAD_F(0x04298a5e) /* 0.260141723 */, 18 }, - /* 4221 */ { MAD_F(0x0429e08e) /* 0.260223920 */, 18 }, - /* 4222 */ { MAD_F(0x042a36c0) /* 0.260306123 */, 18 }, - /* 4223 */ { MAD_F(0x042a8cf4) /* 0.260388332 */, 18 }, - - /* 4224 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 18 }, - /* 4225 */ { MAD_F(0x042b3962) /* 0.260552771 */, 18 }, - /* 4226 */ { MAD_F(0x042b8f9b) /* 0.260635000 */, 18 }, - /* 4227 */ { MAD_F(0x042be5d6) /* 0.260717235 */, 18 }, - /* 4228 */ { MAD_F(0x042c3c12) /* 0.260799477 */, 18 }, - /* 4229 */ { MAD_F(0x042c9251) /* 0.260881725 */, 18 }, - /* 4230 */ { MAD_F(0x042ce891) /* 0.260963980 */, 18 }, - /* 4231 */ { MAD_F(0x042d3ed3) /* 0.261046242 */, 18 }, - /* 4232 */ { MAD_F(0x042d9516) /* 0.261128510 */, 18 }, - /* 4233 */ { MAD_F(0x042deb5c) /* 0.261210784 */, 18 }, - /* 4234 */ { MAD_F(0x042e41a3) /* 0.261293065 */, 18 }, - /* 4235 */ { MAD_F(0x042e97ec) /* 0.261375352 */, 18 }, - /* 4236 */ { MAD_F(0x042eee36) /* 0.261457646 */, 18 }, - /* 4237 */ { MAD_F(0x042f4482) /* 0.261539946 */, 18 }, - /* 4238 */ { MAD_F(0x042f9ad1) /* 0.261622253 */, 18 }, - /* 4239 */ { MAD_F(0x042ff120) /* 0.261704566 */, 18 }, - - /* 4240 */ { MAD_F(0x04304772) /* 0.261786886 */, 18 }, - /* 4241 */ { MAD_F(0x04309dc5) /* 0.261869212 */, 18 }, - /* 4242 */ { MAD_F(0x0430f41a) /* 0.261951545 */, 18 }, - /* 4243 */ { MAD_F(0x04314a71) /* 0.262033884 */, 18 }, - /* 4244 */ { MAD_F(0x0431a0c9) /* 0.262116229 */, 18 }, - /* 4245 */ { MAD_F(0x0431f723) /* 0.262198581 */, 18 }, - /* 4246 */ { MAD_F(0x04324d7f) /* 0.262280940 */, 18 }, - /* 4247 */ { MAD_F(0x0432a3dd) /* 0.262363305 */, 18 }, - /* 4248 */ { MAD_F(0x0432fa3d) /* 0.262445676 */, 18 }, - /* 4249 */ { MAD_F(0x0433509e) /* 0.262528054 */, 18 }, - /* 4250 */ { MAD_F(0x0433a701) /* 0.262610438 */, 18 }, - /* 4251 */ { MAD_F(0x0433fd65) /* 0.262692829 */, 18 }, - /* 4252 */ { MAD_F(0x043453cc) /* 0.262775227 */, 18 }, - /* 4253 */ { MAD_F(0x0434aa34) /* 0.262857630 */, 18 }, - /* 4254 */ { MAD_F(0x0435009d) /* 0.262940040 */, 18 }, - /* 4255 */ { MAD_F(0x04355709) /* 0.263022457 */, 18 }, - - /* 4256 */ { MAD_F(0x0435ad76) /* 0.263104880 */, 18 }, - /* 4257 */ { MAD_F(0x043603e5) /* 0.263187310 */, 18 }, - /* 4258 */ { MAD_F(0x04365a56) /* 0.263269746 */, 18 }, - /* 4259 */ { MAD_F(0x0436b0c9) /* 0.263352188 */, 18 }, - /* 4260 */ { MAD_F(0x0437073d) /* 0.263434637 */, 18 }, - /* 4261 */ { MAD_F(0x04375db3) /* 0.263517093 */, 18 }, - /* 4262 */ { MAD_F(0x0437b42a) /* 0.263599554 */, 18 }, - /* 4263 */ { MAD_F(0x04380aa4) /* 0.263682023 */, 18 }, - /* 4264 */ { MAD_F(0x0438611f) /* 0.263764497 */, 18 }, - /* 4265 */ { MAD_F(0x0438b79c) /* 0.263846979 */, 18 }, - /* 4266 */ { MAD_F(0x04390e1a) /* 0.263929466 */, 18 }, - /* 4267 */ { MAD_F(0x0439649b) /* 0.264011960 */, 18 }, - /* 4268 */ { MAD_F(0x0439bb1d) /* 0.264094461 */, 18 }, - /* 4269 */ { MAD_F(0x043a11a1) /* 0.264176968 */, 18 }, - /* 4270 */ { MAD_F(0x043a6826) /* 0.264259481 */, 18 }, - /* 4271 */ { MAD_F(0x043abead) /* 0.264342001 */, 18 }, - - /* 4272 */ { MAD_F(0x043b1536) /* 0.264424527 */, 18 }, - /* 4273 */ { MAD_F(0x043b6bc1) /* 0.264507060 */, 18 }, - /* 4274 */ { MAD_F(0x043bc24d) /* 0.264589599 */, 18 }, - /* 4275 */ { MAD_F(0x043c18dc) /* 0.264672145 */, 18 }, - /* 4276 */ { MAD_F(0x043c6f6c) /* 0.264754697 */, 18 }, - /* 4277 */ { MAD_F(0x043cc5fd) /* 0.264837255 */, 18 }, - /* 4278 */ { MAD_F(0x043d1c91) /* 0.264919820 */, 18 }, - /* 4279 */ { MAD_F(0x043d7326) /* 0.265002392 */, 18 }, - /* 4280 */ { MAD_F(0x043dc9bc) /* 0.265084969 */, 18 }, - /* 4281 */ { MAD_F(0x043e2055) /* 0.265167554 */, 18 }, - /* 4282 */ { MAD_F(0x043e76ef) /* 0.265250144 */, 18 }, - /* 4283 */ { MAD_F(0x043ecd8b) /* 0.265332741 */, 18 }, - /* 4284 */ { MAD_F(0x043f2429) /* 0.265415345 */, 18 }, - /* 4285 */ { MAD_F(0x043f7ac8) /* 0.265497955 */, 18 }, - /* 4286 */ { MAD_F(0x043fd169) /* 0.265580571 */, 18 }, - /* 4287 */ { MAD_F(0x0440280c) /* 0.265663194 */, 18 }, - - /* 4288 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 18 }, - /* 4289 */ { MAD_F(0x0440d557) /* 0.265828459 */, 18 }, - /* 4290 */ { MAD_F(0x04412bff) /* 0.265911101 */, 18 }, - /* 4291 */ { MAD_F(0x044182a9) /* 0.265993749 */, 18 }, - /* 4292 */ { MAD_F(0x0441d955) /* 0.266076404 */, 18 }, - /* 4293 */ { MAD_F(0x04423002) /* 0.266159065 */, 18 }, - /* 4294 */ { MAD_F(0x044286b1) /* 0.266241733 */, 18 }, - /* 4295 */ { MAD_F(0x0442dd61) /* 0.266324407 */, 18 }, - /* 4296 */ { MAD_F(0x04433414) /* 0.266407088 */, 18 }, - /* 4297 */ { MAD_F(0x04438ac8) /* 0.266489775 */, 18 }, - /* 4298 */ { MAD_F(0x0443e17e) /* 0.266572468 */, 18 }, - /* 4299 */ { MAD_F(0x04443835) /* 0.266655168 */, 18 }, - /* 4300 */ { MAD_F(0x04448eef) /* 0.266737874 */, 18 }, - /* 4301 */ { MAD_F(0x0444e5aa) /* 0.266820587 */, 18 }, - /* 4302 */ { MAD_F(0x04453c66) /* 0.266903306 */, 18 }, - /* 4303 */ { MAD_F(0x04459325) /* 0.266986031 */, 18 }, - - /* 4304 */ { MAD_F(0x0445e9e5) /* 0.267068763 */, 18 }, - /* 4305 */ { MAD_F(0x044640a7) /* 0.267151501 */, 18 }, - /* 4306 */ { MAD_F(0x0446976a) /* 0.267234246 */, 18 }, - /* 4307 */ { MAD_F(0x0446ee30) /* 0.267316997 */, 18 }, - /* 4308 */ { MAD_F(0x044744f7) /* 0.267399755 */, 18 }, - /* 4309 */ { MAD_F(0x04479bc0) /* 0.267482518 */, 18 }, - /* 4310 */ { MAD_F(0x0447f28a) /* 0.267565289 */, 18 }, - /* 4311 */ { MAD_F(0x04484956) /* 0.267648065 */, 18 }, - /* 4312 */ { MAD_F(0x0448a024) /* 0.267730848 */, 18 }, - /* 4313 */ { MAD_F(0x0448f6f4) /* 0.267813638 */, 18 }, - /* 4314 */ { MAD_F(0x04494dc5) /* 0.267896434 */, 18 }, - /* 4315 */ { MAD_F(0x0449a498) /* 0.267979236 */, 18 }, - /* 4316 */ { MAD_F(0x0449fb6d) /* 0.268062045 */, 18 }, - /* 4317 */ { MAD_F(0x044a5243) /* 0.268144860 */, 18 }, - /* 4318 */ { MAD_F(0x044aa91c) /* 0.268227681 */, 18 }, - /* 4319 */ { MAD_F(0x044afff6) /* 0.268310509 */, 18 }, - - /* 4320 */ { MAD_F(0x044b56d1) /* 0.268393343 */, 18 }, - /* 4321 */ { MAD_F(0x044badaf) /* 0.268476184 */, 18 }, - /* 4322 */ { MAD_F(0x044c048e) /* 0.268559031 */, 18 }, - /* 4323 */ { MAD_F(0x044c5b6f) /* 0.268641885 */, 18 }, - /* 4324 */ { MAD_F(0x044cb251) /* 0.268724744 */, 18 }, - /* 4325 */ { MAD_F(0x044d0935) /* 0.268807611 */, 18 }, - /* 4326 */ { MAD_F(0x044d601b) /* 0.268890483 */, 18 }, - /* 4327 */ { MAD_F(0x044db703) /* 0.268973362 */, 18 }, - /* 4328 */ { MAD_F(0x044e0dec) /* 0.269056248 */, 18 }, - /* 4329 */ { MAD_F(0x044e64d7) /* 0.269139139 */, 18 }, - /* 4330 */ { MAD_F(0x044ebbc4) /* 0.269222037 */, 18 }, - /* 4331 */ { MAD_F(0x044f12b3) /* 0.269304942 */, 18 }, - /* 4332 */ { MAD_F(0x044f69a3) /* 0.269387853 */, 18 }, - /* 4333 */ { MAD_F(0x044fc095) /* 0.269470770 */, 18 }, - /* 4334 */ { MAD_F(0x04501788) /* 0.269553694 */, 18 }, - /* 4335 */ { MAD_F(0x04506e7e) /* 0.269636624 */, 18 }, - - /* 4336 */ { MAD_F(0x0450c575) /* 0.269719560 */, 18 }, - /* 4337 */ { MAD_F(0x04511c6e) /* 0.269802503 */, 18 }, - /* 4338 */ { MAD_F(0x04517368) /* 0.269885452 */, 18 }, - /* 4339 */ { MAD_F(0x0451ca64) /* 0.269968408 */, 18 }, - /* 4340 */ { MAD_F(0x04522162) /* 0.270051370 */, 18 }, - /* 4341 */ { MAD_F(0x04527862) /* 0.270134338 */, 18 }, - /* 4342 */ { MAD_F(0x0452cf63) /* 0.270217312 */, 18 }, - /* 4343 */ { MAD_F(0x04532666) /* 0.270300293 */, 18 }, - /* 4344 */ { MAD_F(0x04537d6b) /* 0.270383281 */, 18 }, - /* 4345 */ { MAD_F(0x0453d472) /* 0.270466275 */, 18 }, - /* 4346 */ { MAD_F(0x04542b7a) /* 0.270549275 */, 18 }, - /* 4347 */ { MAD_F(0x04548284) /* 0.270632281 */, 18 }, - /* 4348 */ { MAD_F(0x0454d98f) /* 0.270715294 */, 18 }, - /* 4349 */ { MAD_F(0x0455309c) /* 0.270798313 */, 18 }, - /* 4350 */ { MAD_F(0x045587ab) /* 0.270881339 */, 18 }, - /* 4351 */ { MAD_F(0x0455debc) /* 0.270964371 */, 18 }, - - /* 4352 */ { MAD_F(0x045635cf) /* 0.271047409 */, 18 }, - /* 4353 */ { MAD_F(0x04568ce3) /* 0.271130454 */, 18 }, - /* 4354 */ { MAD_F(0x0456e3f9) /* 0.271213505 */, 18 }, - /* 4355 */ { MAD_F(0x04573b10) /* 0.271296562 */, 18 }, - /* 4356 */ { MAD_F(0x04579229) /* 0.271379626 */, 18 }, - /* 4357 */ { MAD_F(0x0457e944) /* 0.271462696 */, 18 }, - /* 4358 */ { MAD_F(0x04584061) /* 0.271545772 */, 18 }, - /* 4359 */ { MAD_F(0x0458977f) /* 0.271628855 */, 18 }, - /* 4360 */ { MAD_F(0x0458ee9f) /* 0.271711944 */, 18 }, - /* 4361 */ { MAD_F(0x045945c1) /* 0.271795040 */, 18 }, - /* 4362 */ { MAD_F(0x04599ce5) /* 0.271878142 */, 18 }, - /* 4363 */ { MAD_F(0x0459f40a) /* 0.271961250 */, 18 }, - /* 4364 */ { MAD_F(0x045a4b31) /* 0.272044365 */, 18 }, - /* 4365 */ { MAD_F(0x045aa259) /* 0.272127486 */, 18 }, - /* 4366 */ { MAD_F(0x045af984) /* 0.272210613 */, 18 }, - /* 4367 */ { MAD_F(0x045b50b0) /* 0.272293746 */, 18 }, - - /* 4368 */ { MAD_F(0x045ba7dd) /* 0.272376886 */, 18 }, - /* 4369 */ { MAD_F(0x045bff0d) /* 0.272460033 */, 18 }, - /* 4370 */ { MAD_F(0x045c563e) /* 0.272543185 */, 18 }, - /* 4371 */ { MAD_F(0x045cad71) /* 0.272626344 */, 18 }, - /* 4372 */ { MAD_F(0x045d04a5) /* 0.272709510 */, 18 }, - /* 4373 */ { MAD_F(0x045d5bdc) /* 0.272792681 */, 18 }, - /* 4374 */ { MAD_F(0x045db313) /* 0.272875859 */, 18 }, - /* 4375 */ { MAD_F(0x045e0a4d) /* 0.272959044 */, 18 }, - /* 4376 */ { MAD_F(0x045e6188) /* 0.273042234 */, 18 }, - /* 4377 */ { MAD_F(0x045eb8c5) /* 0.273125431 */, 18 }, - /* 4378 */ { MAD_F(0x045f1004) /* 0.273208635 */, 18 }, - /* 4379 */ { MAD_F(0x045f6745) /* 0.273291844 */, 18 }, - /* 4380 */ { MAD_F(0x045fbe87) /* 0.273375060 */, 18 }, - /* 4381 */ { MAD_F(0x046015cb) /* 0.273458283 */, 18 }, - /* 4382 */ { MAD_F(0x04606d10) /* 0.273541511 */, 18 }, - /* 4383 */ { MAD_F(0x0460c457) /* 0.273624747 */, 18 }, - - /* 4384 */ { MAD_F(0x04611ba0) /* 0.273707988 */, 18 }, - /* 4385 */ { MAD_F(0x046172eb) /* 0.273791236 */, 18 }, - /* 4386 */ { MAD_F(0x0461ca37) /* 0.273874490 */, 18 }, - /* 4387 */ { MAD_F(0x04622185) /* 0.273957750 */, 18 }, - /* 4388 */ { MAD_F(0x046278d5) /* 0.274041017 */, 18 }, - /* 4389 */ { MAD_F(0x0462d026) /* 0.274124290 */, 18 }, - /* 4390 */ { MAD_F(0x0463277a) /* 0.274207569 */, 18 }, - /* 4391 */ { MAD_F(0x04637ece) /* 0.274290855 */, 18 }, - /* 4392 */ { MAD_F(0x0463d625) /* 0.274374147 */, 18 }, - /* 4393 */ { MAD_F(0x04642d7d) /* 0.274457445 */, 18 }, - /* 4394 */ { MAD_F(0x046484d7) /* 0.274540749 */, 18 }, - /* 4395 */ { MAD_F(0x0464dc33) /* 0.274624060 */, 18 }, - /* 4396 */ { MAD_F(0x04653390) /* 0.274707378 */, 18 }, - /* 4397 */ { MAD_F(0x04658aef) /* 0.274790701 */, 18 }, - /* 4398 */ { MAD_F(0x0465e250) /* 0.274874031 */, 18 }, - /* 4399 */ { MAD_F(0x046639b2) /* 0.274957367 */, 18 }, - - /* 4400 */ { MAD_F(0x04669116) /* 0.275040710 */, 18 }, - /* 4401 */ { MAD_F(0x0466e87c) /* 0.275124059 */, 18 }, - /* 4402 */ { MAD_F(0x04673fe3) /* 0.275207414 */, 18 }, - /* 4403 */ { MAD_F(0x0467974d) /* 0.275290775 */, 18 }, - /* 4404 */ { MAD_F(0x0467eeb7) /* 0.275374143 */, 18 }, - /* 4405 */ { MAD_F(0x04684624) /* 0.275457517 */, 18 }, - /* 4406 */ { MAD_F(0x04689d92) /* 0.275540897 */, 18 }, - /* 4407 */ { MAD_F(0x0468f502) /* 0.275624284 */, 18 }, - /* 4408 */ { MAD_F(0x04694c74) /* 0.275707677 */, 18 }, - /* 4409 */ { MAD_F(0x0469a3e7) /* 0.275791076 */, 18 }, - /* 4410 */ { MAD_F(0x0469fb5c) /* 0.275874482 */, 18 }, - /* 4411 */ { MAD_F(0x046a52d3) /* 0.275957894 */, 18 }, - /* 4412 */ { MAD_F(0x046aaa4b) /* 0.276041312 */, 18 }, - /* 4413 */ { MAD_F(0x046b01c5) /* 0.276124737 */, 18 }, - /* 4414 */ { MAD_F(0x046b5941) /* 0.276208167 */, 18 }, - /* 4415 */ { MAD_F(0x046bb0bf) /* 0.276291605 */, 18 }, - - /* 4416 */ { MAD_F(0x046c083e) /* 0.276375048 */, 18 }, - /* 4417 */ { MAD_F(0x046c5fbf) /* 0.276458498 */, 18 }, - /* 4418 */ { MAD_F(0x046cb741) /* 0.276541954 */, 18 }, - /* 4419 */ { MAD_F(0x046d0ec5) /* 0.276625416 */, 18 }, - /* 4420 */ { MAD_F(0x046d664b) /* 0.276708885 */, 18 }, - /* 4421 */ { MAD_F(0x046dbdd3) /* 0.276792360 */, 18 }, - /* 4422 */ { MAD_F(0x046e155c) /* 0.276875841 */, 18 }, - /* 4423 */ { MAD_F(0x046e6ce7) /* 0.276959328 */, 18 }, - /* 4424 */ { MAD_F(0x046ec474) /* 0.277042822 */, 18 }, - /* 4425 */ { MAD_F(0x046f1c02) /* 0.277126322 */, 18 }, - /* 4426 */ { MAD_F(0x046f7392) /* 0.277209829 */, 18 }, - /* 4427 */ { MAD_F(0x046fcb24) /* 0.277293341 */, 18 }, - /* 4428 */ { MAD_F(0x047022b8) /* 0.277376860 */, 18 }, - /* 4429 */ { MAD_F(0x04707a4d) /* 0.277460385 */, 18 }, - /* 4430 */ { MAD_F(0x0470d1e4) /* 0.277543917 */, 18 }, - /* 4431 */ { MAD_F(0x0471297c) /* 0.277627455 */, 18 }, - - /* 4432 */ { MAD_F(0x04718116) /* 0.277710999 */, 18 }, - /* 4433 */ { MAD_F(0x0471d8b2) /* 0.277794549 */, 18 }, - /* 4434 */ { MAD_F(0x04723050) /* 0.277878106 */, 18 }, - /* 4435 */ { MAD_F(0x047287ef) /* 0.277961669 */, 18 }, - /* 4436 */ { MAD_F(0x0472df90) /* 0.278045238 */, 18 }, - /* 4437 */ { MAD_F(0x04733733) /* 0.278128813 */, 18 }, - /* 4438 */ { MAD_F(0x04738ed7) /* 0.278212395 */, 18 }, - /* 4439 */ { MAD_F(0x0473e67d) /* 0.278295983 */, 18 }, - /* 4440 */ { MAD_F(0x04743e25) /* 0.278379578 */, 18 }, - /* 4441 */ { MAD_F(0x047495ce) /* 0.278463178 */, 18 }, - /* 4442 */ { MAD_F(0x0474ed79) /* 0.278546785 */, 18 }, - /* 4443 */ { MAD_F(0x04754526) /* 0.278630398 */, 18 }, - /* 4444 */ { MAD_F(0x04759cd4) /* 0.278714018 */, 18 }, - /* 4445 */ { MAD_F(0x0475f484) /* 0.278797643 */, 18 }, - /* 4446 */ { MAD_F(0x04764c36) /* 0.278881275 */, 18 }, - /* 4447 */ { MAD_F(0x0476a3ea) /* 0.278964914 */, 18 }, - - /* 4448 */ { MAD_F(0x0476fb9f) /* 0.279048558 */, 18 }, - /* 4449 */ { MAD_F(0x04775356) /* 0.279132209 */, 18 }, - /* 4450 */ { MAD_F(0x0477ab0e) /* 0.279215866 */, 18 }, - /* 4451 */ { MAD_F(0x047802c8) /* 0.279299529 */, 18 }, - /* 4452 */ { MAD_F(0x04785a84) /* 0.279383199 */, 18 }, - /* 4453 */ { MAD_F(0x0478b242) /* 0.279466875 */, 18 }, - /* 4454 */ { MAD_F(0x04790a01) /* 0.279550557 */, 18 }, - /* 4455 */ { MAD_F(0x047961c2) /* 0.279634245 */, 18 }, - /* 4456 */ { MAD_F(0x0479b984) /* 0.279717940 */, 18 }, - /* 4457 */ { MAD_F(0x047a1149) /* 0.279801641 */, 18 }, - /* 4458 */ { MAD_F(0x047a690f) /* 0.279885348 */, 18 }, - /* 4459 */ { MAD_F(0x047ac0d6) /* 0.279969061 */, 18 }, - /* 4460 */ { MAD_F(0x047b18a0) /* 0.280052781 */, 18 }, - /* 4461 */ { MAD_F(0x047b706b) /* 0.280136507 */, 18 }, - /* 4462 */ { MAD_F(0x047bc837) /* 0.280220239 */, 18 }, - /* 4463 */ { MAD_F(0x047c2006) /* 0.280303978 */, 18 }, - - /* 4464 */ { MAD_F(0x047c77d6) /* 0.280387722 */, 18 }, - /* 4465 */ { MAD_F(0x047ccfa8) /* 0.280471473 */, 18 }, - /* 4466 */ { MAD_F(0x047d277b) /* 0.280555230 */, 18 }, - /* 4467 */ { MAD_F(0x047d7f50) /* 0.280638994 */, 18 }, - /* 4468 */ { MAD_F(0x047dd727) /* 0.280722764 */, 18 }, - /* 4469 */ { MAD_F(0x047e2eff) /* 0.280806540 */, 18 }, - /* 4470 */ { MAD_F(0x047e86d9) /* 0.280890322 */, 18 }, - /* 4471 */ { MAD_F(0x047edeb5) /* 0.280974110 */, 18 }, - /* 4472 */ { MAD_F(0x047f3693) /* 0.281057905 */, 18 }, - /* 4473 */ { MAD_F(0x047f8e72) /* 0.281141706 */, 18 }, - /* 4474 */ { MAD_F(0x047fe653) /* 0.281225513 */, 18 }, - /* 4475 */ { MAD_F(0x04803e35) /* 0.281309326 */, 18 }, - /* 4476 */ { MAD_F(0x04809619) /* 0.281393146 */, 18 }, - /* 4477 */ { MAD_F(0x0480edff) /* 0.281476972 */, 18 }, - /* 4478 */ { MAD_F(0x048145e7) /* 0.281560804 */, 18 }, - /* 4479 */ { MAD_F(0x04819dd0) /* 0.281644643 */, 18 }, - - /* 4480 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 18 }, - /* 4481 */ { MAD_F(0x04824da7) /* 0.281812338 */, 18 }, - /* 4482 */ { MAD_F(0x0482a595) /* 0.281896195 */, 18 }, - /* 4483 */ { MAD_F(0x0482fd85) /* 0.281980059 */, 18 }, - /* 4484 */ { MAD_F(0x04835577) /* 0.282063928 */, 18 }, - /* 4485 */ { MAD_F(0x0483ad6a) /* 0.282147804 */, 18 }, - /* 4486 */ { MAD_F(0x0484055f) /* 0.282231686 */, 18 }, - /* 4487 */ { MAD_F(0x04845d56) /* 0.282315574 */, 18 }, - /* 4488 */ { MAD_F(0x0484b54e) /* 0.282399469 */, 18 }, - /* 4489 */ { MAD_F(0x04850d48) /* 0.282483370 */, 18 }, - /* 4490 */ { MAD_F(0x04856544) /* 0.282567277 */, 18 }, - /* 4491 */ { MAD_F(0x0485bd41) /* 0.282651190 */, 18 }, - /* 4492 */ { MAD_F(0x04861540) /* 0.282735109 */, 18 }, - /* 4493 */ { MAD_F(0x04866d40) /* 0.282819035 */, 18 }, - /* 4494 */ { MAD_F(0x0486c543) /* 0.282902967 */, 18 }, - /* 4495 */ { MAD_F(0x04871d47) /* 0.282986905 */, 18 }, - - /* 4496 */ { MAD_F(0x0487754c) /* 0.283070849 */, 18 }, - /* 4497 */ { MAD_F(0x0487cd54) /* 0.283154800 */, 18 }, - /* 4498 */ { MAD_F(0x0488255d) /* 0.283238757 */, 18 }, - /* 4499 */ { MAD_F(0x04887d67) /* 0.283322720 */, 18 }, - /* 4500 */ { MAD_F(0x0488d574) /* 0.283406689 */, 18 }, - /* 4501 */ { MAD_F(0x04892d82) /* 0.283490665 */, 18 }, - /* 4502 */ { MAD_F(0x04898591) /* 0.283574646 */, 18 }, - /* 4503 */ { MAD_F(0x0489dda3) /* 0.283658634 */, 18 }, - /* 4504 */ { MAD_F(0x048a35b6) /* 0.283742628 */, 18 }, - /* 4505 */ { MAD_F(0x048a8dca) /* 0.283826629 */, 18 }, - /* 4506 */ { MAD_F(0x048ae5e1) /* 0.283910635 */, 18 }, - /* 4507 */ { MAD_F(0x048b3df9) /* 0.283994648 */, 18 }, - /* 4508 */ { MAD_F(0x048b9612) /* 0.284078667 */, 18 }, - /* 4509 */ { MAD_F(0x048bee2e) /* 0.284162692 */, 18 }, - /* 4510 */ { MAD_F(0x048c464b) /* 0.284246723 */, 18 }, - /* 4511 */ { MAD_F(0x048c9e69) /* 0.284330761 */, 18 }, - - /* 4512 */ { MAD_F(0x048cf68a) /* 0.284414805 */, 18 }, - /* 4513 */ { MAD_F(0x048d4eac) /* 0.284498855 */, 18 }, - /* 4514 */ { MAD_F(0x048da6cf) /* 0.284582911 */, 18 }, - /* 4515 */ { MAD_F(0x048dfef5) /* 0.284666974 */, 18 }, - /* 4516 */ { MAD_F(0x048e571c) /* 0.284751042 */, 18 }, - /* 4517 */ { MAD_F(0x048eaf44) /* 0.284835117 */, 18 }, - /* 4518 */ { MAD_F(0x048f076f) /* 0.284919198 */, 18 }, - /* 4519 */ { MAD_F(0x048f5f9b) /* 0.285003285 */, 18 }, - /* 4520 */ { MAD_F(0x048fb7c8) /* 0.285087379 */, 18 }, - /* 4521 */ { MAD_F(0x04900ff8) /* 0.285171479 */, 18 }, - /* 4522 */ { MAD_F(0x04906829) /* 0.285255584 */, 18 }, - /* 4523 */ { MAD_F(0x0490c05b) /* 0.285339697 */, 18 }, - /* 4524 */ { MAD_F(0x04911890) /* 0.285423815 */, 18 }, - /* 4525 */ { MAD_F(0x049170c6) /* 0.285507939 */, 18 }, - /* 4526 */ { MAD_F(0x0491c8fd) /* 0.285592070 */, 18 }, - /* 4527 */ { MAD_F(0x04922137) /* 0.285676207 */, 18 }, - - /* 4528 */ { MAD_F(0x04927972) /* 0.285760350 */, 18 }, - /* 4529 */ { MAD_F(0x0492d1ae) /* 0.285844499 */, 18 }, - /* 4530 */ { MAD_F(0x049329ed) /* 0.285928655 */, 18 }, - /* 4531 */ { MAD_F(0x0493822c) /* 0.286012816 */, 18 }, - /* 4532 */ { MAD_F(0x0493da6e) /* 0.286096984 */, 18 }, - /* 4533 */ { MAD_F(0x049432b1) /* 0.286181158 */, 18 }, - /* 4534 */ { MAD_F(0x04948af6) /* 0.286265338 */, 18 }, - /* 4535 */ { MAD_F(0x0494e33d) /* 0.286349525 */, 18 }, - /* 4536 */ { MAD_F(0x04953b85) /* 0.286433717 */, 18 }, - /* 4537 */ { MAD_F(0x049593cf) /* 0.286517916 */, 18 }, - /* 4538 */ { MAD_F(0x0495ec1b) /* 0.286602121 */, 18 }, - /* 4539 */ { MAD_F(0x04964468) /* 0.286686332 */, 18 }, - /* 4540 */ { MAD_F(0x04969cb7) /* 0.286770550 */, 18 }, - /* 4541 */ { MAD_F(0x0496f508) /* 0.286854773 */, 18 }, - /* 4542 */ { MAD_F(0x04974d5a) /* 0.286939003 */, 18 }, - /* 4543 */ { MAD_F(0x0497a5ae) /* 0.287023239 */, 18 }, - - /* 4544 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 18 }, - /* 4545 */ { MAD_F(0x0498565a) /* 0.287191729 */, 18 }, - /* 4546 */ { MAD_F(0x0498aeb3) /* 0.287275983 */, 18 }, - /* 4547 */ { MAD_F(0x0499070e) /* 0.287360244 */, 18 }, - /* 4548 */ { MAD_F(0x04995f6a) /* 0.287444511 */, 18 }, - /* 4549 */ { MAD_F(0x0499b7c8) /* 0.287528784 */, 18 }, - /* 4550 */ { MAD_F(0x049a1027) /* 0.287613063 */, 18 }, - /* 4551 */ { MAD_F(0x049a6889) /* 0.287697348 */, 18 }, - /* 4552 */ { MAD_F(0x049ac0eb) /* 0.287781640 */, 18 }, - /* 4553 */ { MAD_F(0x049b1950) /* 0.287865937 */, 18 }, - /* 4554 */ { MAD_F(0x049b71b6) /* 0.287950241 */, 18 }, - /* 4555 */ { MAD_F(0x049bca1e) /* 0.288034551 */, 18 }, - /* 4556 */ { MAD_F(0x049c2287) /* 0.288118867 */, 18 }, - /* 4557 */ { MAD_F(0x049c7af2) /* 0.288203190 */, 18 }, - /* 4558 */ { MAD_F(0x049cd35f) /* 0.288287518 */, 18 }, - /* 4559 */ { MAD_F(0x049d2bce) /* 0.288371853 */, 18 }, - - /* 4560 */ { MAD_F(0x049d843e) /* 0.288456194 */, 18 }, - /* 4561 */ { MAD_F(0x049ddcaf) /* 0.288540541 */, 18 }, - /* 4562 */ { MAD_F(0x049e3523) /* 0.288624894 */, 18 }, - /* 4563 */ { MAD_F(0x049e8d98) /* 0.288709253 */, 18 }, - /* 4564 */ { MAD_F(0x049ee60e) /* 0.288793619 */, 18 }, - /* 4565 */ { MAD_F(0x049f3e87) /* 0.288877990 */, 18 }, - /* 4566 */ { MAD_F(0x049f9701) /* 0.288962368 */, 18 }, - /* 4567 */ { MAD_F(0x049fef7c) /* 0.289046752 */, 18 }, - /* 4568 */ { MAD_F(0x04a047fa) /* 0.289131142 */, 18 }, - /* 4569 */ { MAD_F(0x04a0a079) /* 0.289215538 */, 18 }, - /* 4570 */ { MAD_F(0x04a0f8f9) /* 0.289299941 */, 18 }, - /* 4571 */ { MAD_F(0x04a1517c) /* 0.289384349 */, 18 }, - /* 4572 */ { MAD_F(0x04a1a9ff) /* 0.289468764 */, 18 }, - /* 4573 */ { MAD_F(0x04a20285) /* 0.289553185 */, 18 }, - /* 4574 */ { MAD_F(0x04a25b0c) /* 0.289637612 */, 18 }, - /* 4575 */ { MAD_F(0x04a2b395) /* 0.289722045 */, 18 }, - - /* 4576 */ { MAD_F(0x04a30c20) /* 0.289806485 */, 18 }, - /* 4577 */ { MAD_F(0x04a364ac) /* 0.289890930 */, 18 }, - /* 4578 */ { MAD_F(0x04a3bd3a) /* 0.289975382 */, 18 }, - /* 4579 */ { MAD_F(0x04a415c9) /* 0.290059840 */, 18 }, - /* 4580 */ { MAD_F(0x04a46e5a) /* 0.290144304 */, 18 }, - /* 4581 */ { MAD_F(0x04a4c6ed) /* 0.290228774 */, 18 }, - /* 4582 */ { MAD_F(0x04a51f81) /* 0.290313250 */, 18 }, - /* 4583 */ { MAD_F(0x04a57818) /* 0.290397733 */, 18 }, - /* 4584 */ { MAD_F(0x04a5d0af) /* 0.290482221 */, 18 }, - /* 4585 */ { MAD_F(0x04a62949) /* 0.290566716 */, 18 }, - /* 4586 */ { MAD_F(0x04a681e4) /* 0.290651217 */, 18 }, - /* 4587 */ { MAD_F(0x04a6da80) /* 0.290735724 */, 18 }, - /* 4588 */ { MAD_F(0x04a7331f) /* 0.290820237 */, 18 }, - /* 4589 */ { MAD_F(0x04a78bbf) /* 0.290904756 */, 18 }, - /* 4590 */ { MAD_F(0x04a7e460) /* 0.290989281 */, 18 }, - /* 4591 */ { MAD_F(0x04a83d03) /* 0.291073813 */, 18 }, - - /* 4592 */ { MAD_F(0x04a895a8) /* 0.291158351 */, 18 }, - /* 4593 */ { MAD_F(0x04a8ee4f) /* 0.291242894 */, 18 }, - /* 4594 */ { MAD_F(0x04a946f7) /* 0.291327444 */, 18 }, - /* 4595 */ { MAD_F(0x04a99fa1) /* 0.291412001 */, 18 }, - /* 4596 */ { MAD_F(0x04a9f84c) /* 0.291496563 */, 18 }, - /* 4597 */ { MAD_F(0x04aa50fa) /* 0.291581131 */, 18 }, - /* 4598 */ { MAD_F(0x04aaa9a8) /* 0.291665706 */, 18 }, - /* 4599 */ { MAD_F(0x04ab0259) /* 0.291750286 */, 18 }, - /* 4600 */ { MAD_F(0x04ab5b0b) /* 0.291834873 */, 18 }, - /* 4601 */ { MAD_F(0x04abb3bf) /* 0.291919466 */, 18 }, - /* 4602 */ { MAD_F(0x04ac0c74) /* 0.292004065 */, 18 }, - /* 4603 */ { MAD_F(0x04ac652b) /* 0.292088670 */, 18 }, - /* 4604 */ { MAD_F(0x04acbde4) /* 0.292173281 */, 18 }, - /* 4605 */ { MAD_F(0x04ad169e) /* 0.292257899 */, 18 }, - /* 4606 */ { MAD_F(0x04ad6f5a) /* 0.292342522 */, 18 }, - /* 4607 */ { MAD_F(0x04adc818) /* 0.292427152 */, 18 }, - - /* 4608 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 18 }, - /* 4609 */ { MAD_F(0x04ae7998) /* 0.292596430 */, 18 }, - /* 4610 */ { MAD_F(0x04aed25a) /* 0.292681078 */, 18 }, - /* 4611 */ { MAD_F(0x04af2b1e) /* 0.292765732 */, 18 }, - /* 4612 */ { MAD_F(0x04af83e4) /* 0.292850392 */, 18 }, - /* 4613 */ { MAD_F(0x04afdcac) /* 0.292935058 */, 18 }, - /* 4614 */ { MAD_F(0x04b03575) /* 0.293019731 */, 18 }, - /* 4615 */ { MAD_F(0x04b08e40) /* 0.293104409 */, 18 }, - /* 4616 */ { MAD_F(0x04b0e70c) /* 0.293189094 */, 18 }, - /* 4617 */ { MAD_F(0x04b13fda) /* 0.293273785 */, 18 }, - /* 4618 */ { MAD_F(0x04b198aa) /* 0.293358482 */, 18 }, - /* 4619 */ { MAD_F(0x04b1f17b) /* 0.293443185 */, 18 }, - /* 4620 */ { MAD_F(0x04b24a4e) /* 0.293527894 */, 18 }, - /* 4621 */ { MAD_F(0x04b2a322) /* 0.293612609 */, 18 }, - /* 4622 */ { MAD_F(0x04b2fbf9) /* 0.293697331 */, 18 }, - /* 4623 */ { MAD_F(0x04b354d1) /* 0.293782058 */, 18 }, - - /* 4624 */ { MAD_F(0x04b3adaa) /* 0.293866792 */, 18 }, - /* 4625 */ { MAD_F(0x04b40685) /* 0.293951532 */, 18 }, - /* 4626 */ { MAD_F(0x04b45f62) /* 0.294036278 */, 18 }, - /* 4627 */ { MAD_F(0x04b4b840) /* 0.294121029 */, 18 }, - /* 4628 */ { MAD_F(0x04b51120) /* 0.294205788 */, 18 }, - /* 4629 */ { MAD_F(0x04b56a02) /* 0.294290552 */, 18 }, - /* 4630 */ { MAD_F(0x04b5c2e6) /* 0.294375322 */, 18 }, - /* 4631 */ { MAD_F(0x04b61bcb) /* 0.294460098 */, 18 }, - /* 4632 */ { MAD_F(0x04b674b1) /* 0.294544881 */, 18 }, - /* 4633 */ { MAD_F(0x04b6cd99) /* 0.294629669 */, 18 }, - /* 4634 */ { MAD_F(0x04b72683) /* 0.294714464 */, 18 }, - /* 4635 */ { MAD_F(0x04b77f6f) /* 0.294799265 */, 18 }, - /* 4636 */ { MAD_F(0x04b7d85c) /* 0.294884072 */, 18 }, - /* 4637 */ { MAD_F(0x04b8314b) /* 0.294968885 */, 18 }, - /* 4638 */ { MAD_F(0x04b88a3b) /* 0.295053704 */, 18 }, - /* 4639 */ { MAD_F(0x04b8e32d) /* 0.295138529 */, 18 }, - - /* 4640 */ { MAD_F(0x04b93c21) /* 0.295223360 */, 18 }, - /* 4641 */ { MAD_F(0x04b99516) /* 0.295308197 */, 18 }, - /* 4642 */ { MAD_F(0x04b9ee0d) /* 0.295393041 */, 18 }, - /* 4643 */ { MAD_F(0x04ba4706) /* 0.295477890 */, 18 }, - /* 4644 */ { MAD_F(0x04baa000) /* 0.295562746 */, 18 }, - /* 4645 */ { MAD_F(0x04baf8fc) /* 0.295647608 */, 18 }, - /* 4646 */ { MAD_F(0x04bb51fa) /* 0.295732476 */, 18 }, - /* 4647 */ { MAD_F(0x04bbaaf9) /* 0.295817349 */, 18 }, - /* 4648 */ { MAD_F(0x04bc03fa) /* 0.295902229 */, 18 }, - /* 4649 */ { MAD_F(0x04bc5cfc) /* 0.295987115 */, 18 }, - /* 4650 */ { MAD_F(0x04bcb600) /* 0.296072008 */, 18 }, - /* 4651 */ { MAD_F(0x04bd0f06) /* 0.296156906 */, 18 }, - /* 4652 */ { MAD_F(0x04bd680d) /* 0.296241810 */, 18 }, - /* 4653 */ { MAD_F(0x04bdc116) /* 0.296326721 */, 18 }, - /* 4654 */ { MAD_F(0x04be1a21) /* 0.296411637 */, 18 }, - /* 4655 */ { MAD_F(0x04be732d) /* 0.296496560 */, 18 }, - - /* 4656 */ { MAD_F(0x04becc3b) /* 0.296581488 */, 18 }, - /* 4657 */ { MAD_F(0x04bf254a) /* 0.296666423 */, 18 }, - /* 4658 */ { MAD_F(0x04bf7e5b) /* 0.296751364 */, 18 }, - /* 4659 */ { MAD_F(0x04bfd76e) /* 0.296836311 */, 18 }, - /* 4660 */ { MAD_F(0x04c03083) /* 0.296921264 */, 18 }, - /* 4661 */ { MAD_F(0x04c08999) /* 0.297006223 */, 18 }, - /* 4662 */ { MAD_F(0x04c0e2b0) /* 0.297091188 */, 18 }, - /* 4663 */ { MAD_F(0x04c13bca) /* 0.297176159 */, 18 }, - /* 4664 */ { MAD_F(0x04c194e4) /* 0.297261136 */, 18 }, - /* 4665 */ { MAD_F(0x04c1ee01) /* 0.297346120 */, 18 }, - /* 4666 */ { MAD_F(0x04c2471f) /* 0.297431109 */, 18 }, - /* 4667 */ { MAD_F(0x04c2a03f) /* 0.297516105 */, 18 }, - /* 4668 */ { MAD_F(0x04c2f960) /* 0.297601106 */, 18 }, - /* 4669 */ { MAD_F(0x04c35283) /* 0.297686114 */, 18 }, - /* 4670 */ { MAD_F(0x04c3aba8) /* 0.297771128 */, 18 }, - /* 4671 */ { MAD_F(0x04c404ce) /* 0.297856147 */, 18 }, - - /* 4672 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 18 }, - /* 4673 */ { MAD_F(0x04c4b720) /* 0.298026205 */, 18 }, - /* 4674 */ { MAD_F(0x04c5104b) /* 0.298111243 */, 18 }, - /* 4675 */ { MAD_F(0x04c56978) /* 0.298196287 */, 18 }, - /* 4676 */ { MAD_F(0x04c5c2a7) /* 0.298281337 */, 18 }, - /* 4677 */ { MAD_F(0x04c61bd7) /* 0.298366393 */, 18 }, - /* 4678 */ { MAD_F(0x04c67508) /* 0.298451456 */, 18 }, - /* 4679 */ { MAD_F(0x04c6ce3c) /* 0.298536524 */, 18 }, - /* 4680 */ { MAD_F(0x04c72771) /* 0.298621598 */, 18 }, - /* 4681 */ { MAD_F(0x04c780a7) /* 0.298706679 */, 18 }, - /* 4682 */ { MAD_F(0x04c7d9df) /* 0.298791765 */, 18 }, - /* 4683 */ { MAD_F(0x04c83319) /* 0.298876858 */, 18 }, - /* 4684 */ { MAD_F(0x04c88c55) /* 0.298961956 */, 18 }, - /* 4685 */ { MAD_F(0x04c8e592) /* 0.299047061 */, 18 }, - /* 4686 */ { MAD_F(0x04c93ed1) /* 0.299132172 */, 18 }, - /* 4687 */ { MAD_F(0x04c99811) /* 0.299217288 */, 18 }, - - /* 4688 */ { MAD_F(0x04c9f153) /* 0.299302411 */, 18 }, - /* 4689 */ { MAD_F(0x04ca4a97) /* 0.299387540 */, 18 }, - /* 4690 */ { MAD_F(0x04caa3dc) /* 0.299472675 */, 18 }, - /* 4691 */ { MAD_F(0x04cafd23) /* 0.299557816 */, 18 }, - /* 4692 */ { MAD_F(0x04cb566b) /* 0.299642963 */, 18 }, - /* 4693 */ { MAD_F(0x04cbafb5) /* 0.299728116 */, 18 }, - /* 4694 */ { MAD_F(0x04cc0901) /* 0.299813275 */, 18 }, - /* 4695 */ { MAD_F(0x04cc624e) /* 0.299898440 */, 18 }, - /* 4696 */ { MAD_F(0x04ccbb9d) /* 0.299983611 */, 18 }, - /* 4697 */ { MAD_F(0x04cd14ee) /* 0.300068789 */, 18 }, - /* 4698 */ { MAD_F(0x04cd6e40) /* 0.300153972 */, 18 }, - /* 4699 */ { MAD_F(0x04cdc794) /* 0.300239161 */, 18 }, - /* 4700 */ { MAD_F(0x04ce20e9) /* 0.300324357 */, 18 }, - /* 4701 */ { MAD_F(0x04ce7a40) /* 0.300409558 */, 18 }, - /* 4702 */ { MAD_F(0x04ced399) /* 0.300494765 */, 18 }, - /* 4703 */ { MAD_F(0x04cf2cf3) /* 0.300579979 */, 18 }, - - /* 4704 */ { MAD_F(0x04cf864f) /* 0.300665198 */, 18 }, - /* 4705 */ { MAD_F(0x04cfdfad) /* 0.300750424 */, 18 }, - /* 4706 */ { MAD_F(0x04d0390c) /* 0.300835656 */, 18 }, - /* 4707 */ { MAD_F(0x04d0926d) /* 0.300920893 */, 18 }, - /* 4708 */ { MAD_F(0x04d0ebcf) /* 0.301006137 */, 18 }, - /* 4709 */ { MAD_F(0x04d14533) /* 0.301091387 */, 18 }, - /* 4710 */ { MAD_F(0x04d19e99) /* 0.301176643 */, 18 }, - /* 4711 */ { MAD_F(0x04d1f800) /* 0.301261904 */, 18 }, - /* 4712 */ { MAD_F(0x04d25169) /* 0.301347172 */, 18 }, - /* 4713 */ { MAD_F(0x04d2aad4) /* 0.301432446 */, 18 }, - /* 4714 */ { MAD_F(0x04d30440) /* 0.301517726 */, 18 }, - /* 4715 */ { MAD_F(0x04d35dae) /* 0.301603012 */, 18 }, - /* 4716 */ { MAD_F(0x04d3b71d) /* 0.301688304 */, 18 }, - /* 4717 */ { MAD_F(0x04d4108e) /* 0.301773602 */, 18 }, - /* 4718 */ { MAD_F(0x04d46a01) /* 0.301858906 */, 18 }, - /* 4719 */ { MAD_F(0x04d4c375) /* 0.301944216 */, 18 }, - - /* 4720 */ { MAD_F(0x04d51ceb) /* 0.302029532 */, 18 }, - /* 4721 */ { MAD_F(0x04d57662) /* 0.302114854 */, 18 }, - /* 4722 */ { MAD_F(0x04d5cfdb) /* 0.302200182 */, 18 }, - /* 4723 */ { MAD_F(0x04d62956) /* 0.302285516 */, 18 }, - /* 4724 */ { MAD_F(0x04d682d2) /* 0.302370856 */, 18 }, - /* 4725 */ { MAD_F(0x04d6dc50) /* 0.302456203 */, 18 }, - /* 4726 */ { MAD_F(0x04d735d0) /* 0.302541555 */, 18 }, - /* 4727 */ { MAD_F(0x04d78f51) /* 0.302626913 */, 18 }, - /* 4728 */ { MAD_F(0x04d7e8d4) /* 0.302712277 */, 18 }, - /* 4729 */ { MAD_F(0x04d84258) /* 0.302797648 */, 18 }, - /* 4730 */ { MAD_F(0x04d89bde) /* 0.302883024 */, 18 }, - /* 4731 */ { MAD_F(0x04d8f566) /* 0.302968406 */, 18 }, - /* 4732 */ { MAD_F(0x04d94eef) /* 0.303053794 */, 18 }, - /* 4733 */ { MAD_F(0x04d9a87a) /* 0.303139189 */, 18 }, - /* 4734 */ { MAD_F(0x04da0207) /* 0.303224589 */, 18 }, - /* 4735 */ { MAD_F(0x04da5b95) /* 0.303309995 */, 18 }, - - /* 4736 */ { MAD_F(0x04dab524) /* 0.303395408 */, 18 }, - /* 4737 */ { MAD_F(0x04db0eb6) /* 0.303480826 */, 18 }, - /* 4738 */ { MAD_F(0x04db6849) /* 0.303566251 */, 18 }, - /* 4739 */ { MAD_F(0x04dbc1dd) /* 0.303651681 */, 18 }, - /* 4740 */ { MAD_F(0x04dc1b73) /* 0.303737117 */, 18 }, - /* 4741 */ { MAD_F(0x04dc750b) /* 0.303822560 */, 18 }, - /* 4742 */ { MAD_F(0x04dccea5) /* 0.303908008 */, 18 }, - /* 4743 */ { MAD_F(0x04dd2840) /* 0.303993463 */, 18 }, - /* 4744 */ { MAD_F(0x04dd81dc) /* 0.304078923 */, 18 }, - /* 4745 */ { MAD_F(0x04dddb7a) /* 0.304164390 */, 18 }, - /* 4746 */ { MAD_F(0x04de351a) /* 0.304249862 */, 18 }, - /* 4747 */ { MAD_F(0x04de8ebc) /* 0.304335340 */, 18 }, - /* 4748 */ { MAD_F(0x04dee85f) /* 0.304420825 */, 18 }, - /* 4749 */ { MAD_F(0x04df4203) /* 0.304506315 */, 18 }, - /* 4750 */ { MAD_F(0x04df9baa) /* 0.304591812 */, 18 }, - /* 4751 */ { MAD_F(0x04dff552) /* 0.304677314 */, 18 }, - - /* 4752 */ { MAD_F(0x04e04efb) /* 0.304762823 */, 18 }, - /* 4753 */ { MAD_F(0x04e0a8a6) /* 0.304848337 */, 18 }, - /* 4754 */ { MAD_F(0x04e10253) /* 0.304933858 */, 18 }, - /* 4755 */ { MAD_F(0x04e15c01) /* 0.305019384 */, 18 }, - /* 4756 */ { MAD_F(0x04e1b5b1) /* 0.305104917 */, 18 }, - /* 4757 */ { MAD_F(0x04e20f63) /* 0.305190455 */, 18 }, - /* 4758 */ { MAD_F(0x04e26916) /* 0.305275999 */, 18 }, - /* 4759 */ { MAD_F(0x04e2c2cb) /* 0.305361550 */, 18 }, - /* 4760 */ { MAD_F(0x04e31c81) /* 0.305447106 */, 18 }, - /* 4761 */ { MAD_F(0x04e37639) /* 0.305532669 */, 18 }, - /* 4762 */ { MAD_F(0x04e3cff3) /* 0.305618237 */, 18 }, - /* 4763 */ { MAD_F(0x04e429ae) /* 0.305703811 */, 18 }, - /* 4764 */ { MAD_F(0x04e4836b) /* 0.305789392 */, 18 }, - /* 4765 */ { MAD_F(0x04e4dd29) /* 0.305874978 */, 18 }, - /* 4766 */ { MAD_F(0x04e536e9) /* 0.305960571 */, 18 }, - /* 4767 */ { MAD_F(0x04e590ab) /* 0.306046169 */, 18 }, - - /* 4768 */ { MAD_F(0x04e5ea6e) /* 0.306131773 */, 18 }, - /* 4769 */ { MAD_F(0x04e64433) /* 0.306217383 */, 18 }, - /* 4770 */ { MAD_F(0x04e69df9) /* 0.306303000 */, 18 }, - /* 4771 */ { MAD_F(0x04e6f7c1) /* 0.306388622 */, 18 }, - /* 4772 */ { MAD_F(0x04e7518b) /* 0.306474250 */, 18 }, - /* 4773 */ { MAD_F(0x04e7ab56) /* 0.306559885 */, 18 }, - /* 4774 */ { MAD_F(0x04e80523) /* 0.306645525 */, 18 }, - /* 4775 */ { MAD_F(0x04e85ef2) /* 0.306731171 */, 18 }, - /* 4776 */ { MAD_F(0x04e8b8c2) /* 0.306816823 */, 18 }, - /* 4777 */ { MAD_F(0x04e91293) /* 0.306902481 */, 18 }, - /* 4778 */ { MAD_F(0x04e96c67) /* 0.306988145 */, 18 }, - /* 4779 */ { MAD_F(0x04e9c63b) /* 0.307073816 */, 18 }, - /* 4780 */ { MAD_F(0x04ea2012) /* 0.307159492 */, 18 }, - /* 4781 */ { MAD_F(0x04ea79ea) /* 0.307245174 */, 18 }, - /* 4782 */ { MAD_F(0x04ead3c4) /* 0.307330862 */, 18 }, - /* 4783 */ { MAD_F(0x04eb2d9f) /* 0.307416556 */, 18 }, - - /* 4784 */ { MAD_F(0x04eb877c) /* 0.307502256 */, 18 }, - /* 4785 */ { MAD_F(0x04ebe15b) /* 0.307587962 */, 18 }, - /* 4786 */ { MAD_F(0x04ec3b3b) /* 0.307673674 */, 18 }, - /* 4787 */ { MAD_F(0x04ec951c) /* 0.307759392 */, 18 }, - /* 4788 */ { MAD_F(0x04ecef00) /* 0.307845115 */, 18 }, - /* 4789 */ { MAD_F(0x04ed48e5) /* 0.307930845 */, 18 }, - /* 4790 */ { MAD_F(0x04eda2cb) /* 0.308016581 */, 18 }, - /* 4791 */ { MAD_F(0x04edfcb3) /* 0.308102323 */, 18 }, - /* 4792 */ { MAD_F(0x04ee569d) /* 0.308188071 */, 18 }, - /* 4793 */ { MAD_F(0x04eeb088) /* 0.308273824 */, 18 }, - /* 4794 */ { MAD_F(0x04ef0a75) /* 0.308359584 */, 18 }, - /* 4795 */ { MAD_F(0x04ef6464) /* 0.308445350 */, 18 }, - /* 4796 */ { MAD_F(0x04efbe54) /* 0.308531121 */, 18 }, - /* 4797 */ { MAD_F(0x04f01846) /* 0.308616899 */, 18 }, - /* 4798 */ { MAD_F(0x04f07239) /* 0.308702682 */, 18 }, - /* 4799 */ { MAD_F(0x04f0cc2e) /* 0.308788472 */, 18 }, - - /* 4800 */ { MAD_F(0x04f12624) /* 0.308874267 */, 18 }, - /* 4801 */ { MAD_F(0x04f1801d) /* 0.308960068 */, 18 }, - /* 4802 */ { MAD_F(0x04f1da16) /* 0.309045876 */, 18 }, - /* 4803 */ { MAD_F(0x04f23412) /* 0.309131689 */, 18 }, - /* 4804 */ { MAD_F(0x04f28e0f) /* 0.309217508 */, 18 }, - /* 4805 */ { MAD_F(0x04f2e80d) /* 0.309303334 */, 18 }, - /* 4806 */ { MAD_F(0x04f3420d) /* 0.309389165 */, 18 }, - /* 4807 */ { MAD_F(0x04f39c0f) /* 0.309475002 */, 18 }, - /* 4808 */ { MAD_F(0x04f3f612) /* 0.309560845 */, 18 }, - /* 4809 */ { MAD_F(0x04f45017) /* 0.309646694 */, 18 }, - /* 4810 */ { MAD_F(0x04f4aa1e) /* 0.309732549 */, 18 }, - /* 4811 */ { MAD_F(0x04f50426) /* 0.309818410 */, 18 }, - /* 4812 */ { MAD_F(0x04f55e30) /* 0.309904277 */, 18 }, - /* 4813 */ { MAD_F(0x04f5b83b) /* 0.309990150 */, 18 }, - /* 4814 */ { MAD_F(0x04f61248) /* 0.310076028 */, 18 }, - /* 4815 */ { MAD_F(0x04f66c56) /* 0.310161913 */, 18 }, - - /* 4816 */ { MAD_F(0x04f6c666) /* 0.310247804 */, 18 }, - /* 4817 */ { MAD_F(0x04f72078) /* 0.310333700 */, 18 }, - /* 4818 */ { MAD_F(0x04f77a8b) /* 0.310419603 */, 18 }, - /* 4819 */ { MAD_F(0x04f7d4a0) /* 0.310505511 */, 18 }, - /* 4820 */ { MAD_F(0x04f82eb7) /* 0.310591426 */, 18 }, - /* 4821 */ { MAD_F(0x04f888cf) /* 0.310677346 */, 18 }, - /* 4822 */ { MAD_F(0x04f8e2e9) /* 0.310763272 */, 18 }, - /* 4823 */ { MAD_F(0x04f93d04) /* 0.310849205 */, 18 }, - /* 4824 */ { MAD_F(0x04f99721) /* 0.310935143 */, 18 }, - /* 4825 */ { MAD_F(0x04f9f13f) /* 0.311021087 */, 18 }, - /* 4826 */ { MAD_F(0x04fa4b5f) /* 0.311107037 */, 18 }, - /* 4827 */ { MAD_F(0x04faa581) /* 0.311192993 */, 18 }, - /* 4828 */ { MAD_F(0x04faffa4) /* 0.311278955 */, 18 }, - /* 4829 */ { MAD_F(0x04fb59c9) /* 0.311364923 */, 18 }, - /* 4830 */ { MAD_F(0x04fbb3ef) /* 0.311450897 */, 18 }, - /* 4831 */ { MAD_F(0x04fc0e17) /* 0.311536877 */, 18 }, - - /* 4832 */ { MAD_F(0x04fc6841) /* 0.311622862 */, 18 }, - /* 4833 */ { MAD_F(0x04fcc26c) /* 0.311708854 */, 18 }, - /* 4834 */ { MAD_F(0x04fd1c99) /* 0.311794851 */, 18 }, - /* 4835 */ { MAD_F(0x04fd76c7) /* 0.311880855 */, 18 }, - /* 4836 */ { MAD_F(0x04fdd0f7) /* 0.311966864 */, 18 }, - /* 4837 */ { MAD_F(0x04fe2b29) /* 0.312052880 */, 18 }, - /* 4838 */ { MAD_F(0x04fe855c) /* 0.312138901 */, 18 }, - /* 4839 */ { MAD_F(0x04fedf91) /* 0.312224928 */, 18 }, - /* 4840 */ { MAD_F(0x04ff39c7) /* 0.312310961 */, 18 }, - /* 4841 */ { MAD_F(0x04ff93ff) /* 0.312397000 */, 18 }, - /* 4842 */ { MAD_F(0x04ffee38) /* 0.312483045 */, 18 }, - /* 4843 */ { MAD_F(0x05004874) /* 0.312569096 */, 18 }, - /* 4844 */ { MAD_F(0x0500a2b0) /* 0.312655153 */, 18 }, - /* 4845 */ { MAD_F(0x0500fcef) /* 0.312741216 */, 18 }, - /* 4846 */ { MAD_F(0x0501572e) /* 0.312827284 */, 18 }, - /* 4847 */ { MAD_F(0x0501b170) /* 0.312913359 */, 18 }, - - /* 4848 */ { MAD_F(0x05020bb3) /* 0.312999439 */, 18 }, - /* 4849 */ { MAD_F(0x050265f8) /* 0.313085526 */, 18 }, - /* 4850 */ { MAD_F(0x0502c03e) /* 0.313171618 */, 18 }, - /* 4851 */ { MAD_F(0x05031a86) /* 0.313257716 */, 18 }, - /* 4852 */ { MAD_F(0x050374cf) /* 0.313343820 */, 18 }, - /* 4853 */ { MAD_F(0x0503cf1a) /* 0.313429931 */, 18 }, - /* 4854 */ { MAD_F(0x05042967) /* 0.313516047 */, 18 }, - /* 4855 */ { MAD_F(0x050483b5) /* 0.313602168 */, 18 }, - /* 4856 */ { MAD_F(0x0504de05) /* 0.313688296 */, 18 }, - /* 4857 */ { MAD_F(0x05053856) /* 0.313774430 */, 18 }, - /* 4858 */ { MAD_F(0x050592a9) /* 0.313860570 */, 18 }, - /* 4859 */ { MAD_F(0x0505ecfd) /* 0.313946715 */, 18 }, - /* 4860 */ { MAD_F(0x05064754) /* 0.314032867 */, 18 }, - /* 4861 */ { MAD_F(0x0506a1ab) /* 0.314119024 */, 18 }, - /* 4862 */ { MAD_F(0x0506fc04) /* 0.314205187 */, 18 }, - /* 4863 */ { MAD_F(0x0507565f) /* 0.314291357 */, 18 }, - - /* 4864 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 18 }, - /* 4865 */ { MAD_F(0x05080b1a) /* 0.314463713 */, 18 }, - /* 4866 */ { MAD_F(0x05086579) /* 0.314549900 */, 18 }, - /* 4867 */ { MAD_F(0x0508bfdb) /* 0.314636092 */, 18 }, - /* 4868 */ { MAD_F(0x05091a3d) /* 0.314722291 */, 18 }, - /* 4869 */ { MAD_F(0x050974a2) /* 0.314808496 */, 18 }, - /* 4870 */ { MAD_F(0x0509cf08) /* 0.314894706 */, 18 }, - /* 4871 */ { MAD_F(0x050a296f) /* 0.314980923 */, 18 }, - /* 4872 */ { MAD_F(0x050a83d8) /* 0.315067145 */, 18 }, - /* 4873 */ { MAD_F(0x050ade43) /* 0.315153373 */, 18 }, - /* 4874 */ { MAD_F(0x050b38af) /* 0.315239607 */, 18 }, - /* 4875 */ { MAD_F(0x050b931d) /* 0.315325847 */, 18 }, - /* 4876 */ { MAD_F(0x050bed8d) /* 0.315412093 */, 18 }, - /* 4877 */ { MAD_F(0x050c47fe) /* 0.315498345 */, 18 }, - /* 4878 */ { MAD_F(0x050ca271) /* 0.315584603 */, 18 }, - /* 4879 */ { MAD_F(0x050cfce5) /* 0.315670866 */, 18 }, - - /* 4880 */ { MAD_F(0x050d575b) /* 0.315757136 */, 18 }, - /* 4881 */ { MAD_F(0x050db1d2) /* 0.315843411 */, 18 }, - /* 4882 */ { MAD_F(0x050e0c4b) /* 0.315929693 */, 18 }, - /* 4883 */ { MAD_F(0x050e66c5) /* 0.316015980 */, 18 }, - /* 4884 */ { MAD_F(0x050ec141) /* 0.316102273 */, 18 }, - /* 4885 */ { MAD_F(0x050f1bbf) /* 0.316188572 */, 18 }, - /* 4886 */ { MAD_F(0x050f763e) /* 0.316274877 */, 18 }, - /* 4887 */ { MAD_F(0x050fd0bf) /* 0.316361187 */, 18 }, - /* 4888 */ { MAD_F(0x05102b42) /* 0.316447504 */, 18 }, - /* 4889 */ { MAD_F(0x051085c6) /* 0.316533826 */, 18 }, - /* 4890 */ { MAD_F(0x0510e04b) /* 0.316620155 */, 18 }, - /* 4891 */ { MAD_F(0x05113ad3) /* 0.316706489 */, 18 }, - /* 4892 */ { MAD_F(0x0511955b) /* 0.316792829 */, 18 }, - /* 4893 */ { MAD_F(0x0511efe6) /* 0.316879175 */, 18 }, - /* 4894 */ { MAD_F(0x05124a72) /* 0.316965527 */, 18 }, - /* 4895 */ { MAD_F(0x0512a4ff) /* 0.317051885 */, 18 }, - - /* 4896 */ { MAD_F(0x0512ff8e) /* 0.317138249 */, 18 }, - /* 4897 */ { MAD_F(0x05135a1f) /* 0.317224618 */, 18 }, - /* 4898 */ { MAD_F(0x0513b4b1) /* 0.317310994 */, 18 }, - /* 4899 */ { MAD_F(0x05140f45) /* 0.317397375 */, 18 }, - /* 4900 */ { MAD_F(0x051469da) /* 0.317483762 */, 18 }, - /* 4901 */ { MAD_F(0x0514c471) /* 0.317570155 */, 18 }, - /* 4902 */ { MAD_F(0x05151f0a) /* 0.317656554 */, 18 }, - /* 4903 */ { MAD_F(0x051579a4) /* 0.317742959 */, 18 }, - /* 4904 */ { MAD_F(0x0515d440) /* 0.317829370 */, 18 }, - /* 4905 */ { MAD_F(0x05162edd) /* 0.317915786 */, 18 }, - /* 4906 */ { MAD_F(0x0516897c) /* 0.318002209 */, 18 }, - /* 4907 */ { MAD_F(0x0516e41c) /* 0.318088637 */, 18 }, - /* 4908 */ { MAD_F(0x05173ebe) /* 0.318175071 */, 18 }, - /* 4909 */ { MAD_F(0x05179962) /* 0.318261511 */, 18 }, - /* 4910 */ { MAD_F(0x0517f407) /* 0.318347957 */, 18 }, - /* 4911 */ { MAD_F(0x05184eae) /* 0.318434409 */, 18 }, - - /* 4912 */ { MAD_F(0x0518a956) /* 0.318520867 */, 18 }, - /* 4913 */ { MAD_F(0x05190400) /* 0.318607330 */, 18 }, - /* 4914 */ { MAD_F(0x05195eab) /* 0.318693800 */, 18 }, - /* 4915 */ { MAD_F(0x0519b958) /* 0.318780275 */, 18 }, - /* 4916 */ { MAD_F(0x051a1407) /* 0.318866756 */, 18 }, - /* 4917 */ { MAD_F(0x051a6eb7) /* 0.318953243 */, 18 }, - /* 4918 */ { MAD_F(0x051ac969) /* 0.319039736 */, 18 }, - /* 4919 */ { MAD_F(0x051b241c) /* 0.319126235 */, 18 }, - /* 4920 */ { MAD_F(0x051b7ed1) /* 0.319212739 */, 18 }, - /* 4921 */ { MAD_F(0x051bd987) /* 0.319299250 */, 18 }, - /* 4922 */ { MAD_F(0x051c3440) /* 0.319385766 */, 18 }, - /* 4923 */ { MAD_F(0x051c8ef9) /* 0.319472288 */, 18 }, - /* 4924 */ { MAD_F(0x051ce9b4) /* 0.319558816 */, 18 }, - /* 4925 */ { MAD_F(0x051d4471) /* 0.319645350 */, 18 }, - /* 4926 */ { MAD_F(0x051d9f2f) /* 0.319731890 */, 18 }, - /* 4927 */ { MAD_F(0x051df9ef) /* 0.319818435 */, 18 }, - - /* 4928 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 18 }, - /* 4929 */ { MAD_F(0x051eaf74) /* 0.319991544 */, 18 }, - /* 4930 */ { MAD_F(0x051f0a38) /* 0.320078107 */, 18 }, - /* 4931 */ { MAD_F(0x051f64ff) /* 0.320164676 */, 18 }, - /* 4932 */ { MAD_F(0x051fbfc6) /* 0.320251251 */, 18 }, - /* 4933 */ { MAD_F(0x05201a90) /* 0.320337832 */, 18 }, - /* 4934 */ { MAD_F(0x0520755b) /* 0.320424419 */, 18 }, - /* 4935 */ { MAD_F(0x0520d027) /* 0.320511011 */, 18 }, - /* 4936 */ { MAD_F(0x05212af5) /* 0.320597609 */, 18 }, - /* 4937 */ { MAD_F(0x052185c5) /* 0.320684213 */, 18 }, - /* 4938 */ { MAD_F(0x0521e096) /* 0.320770823 */, 18 }, - /* 4939 */ { MAD_F(0x05223b69) /* 0.320857439 */, 18 }, - /* 4940 */ { MAD_F(0x0522963d) /* 0.320944061 */, 18 }, - /* 4941 */ { MAD_F(0x0522f113) /* 0.321030688 */, 18 }, - /* 4942 */ { MAD_F(0x05234bea) /* 0.321117322 */, 18 }, - /* 4943 */ { MAD_F(0x0523a6c3) /* 0.321203961 */, 18 }, - - /* 4944 */ { MAD_F(0x0524019e) /* 0.321290606 */, 18 }, - /* 4945 */ { MAD_F(0x05245c7a) /* 0.321377257 */, 18 }, - /* 4946 */ { MAD_F(0x0524b758) /* 0.321463913 */, 18 }, - /* 4947 */ { MAD_F(0x05251237) /* 0.321550576 */, 18 }, - /* 4948 */ { MAD_F(0x05256d18) /* 0.321637244 */, 18 }, - /* 4949 */ { MAD_F(0x0525c7fb) /* 0.321723919 */, 18 }, - /* 4950 */ { MAD_F(0x052622df) /* 0.321810599 */, 18 }, - /* 4951 */ { MAD_F(0x05267dc4) /* 0.321897285 */, 18 }, - /* 4952 */ { MAD_F(0x0526d8ab) /* 0.321983976 */, 18 }, - /* 4953 */ { MAD_F(0x05273394) /* 0.322070674 */, 18 }, - /* 4954 */ { MAD_F(0x05278e7e) /* 0.322157377 */, 18 }, - /* 4955 */ { MAD_F(0x0527e96a) /* 0.322244087 */, 18 }, - /* 4956 */ { MAD_F(0x05284457) /* 0.322330802 */, 18 }, - /* 4957 */ { MAD_F(0x05289f46) /* 0.322417523 */, 18 }, - /* 4958 */ { MAD_F(0x0528fa37) /* 0.322504249 */, 18 }, - /* 4959 */ { MAD_F(0x05295529) /* 0.322590982 */, 18 }, - - /* 4960 */ { MAD_F(0x0529b01d) /* 0.322677720 */, 18 }, - /* 4961 */ { MAD_F(0x052a0b12) /* 0.322764465 */, 18 }, - /* 4962 */ { MAD_F(0x052a6609) /* 0.322851215 */, 18 }, - /* 4963 */ { MAD_F(0x052ac101) /* 0.322937971 */, 18 }, - /* 4964 */ { MAD_F(0x052b1bfb) /* 0.323024732 */, 18 }, - /* 4965 */ { MAD_F(0x052b76f7) /* 0.323111500 */, 18 }, - /* 4966 */ { MAD_F(0x052bd1f4) /* 0.323198273 */, 18 }, - /* 4967 */ { MAD_F(0x052c2cf2) /* 0.323285052 */, 18 }, - /* 4968 */ { MAD_F(0x052c87f2) /* 0.323371837 */, 18 }, - /* 4969 */ { MAD_F(0x052ce2f4) /* 0.323458628 */, 18 }, - /* 4970 */ { MAD_F(0x052d3df7) /* 0.323545425 */, 18 }, - /* 4971 */ { MAD_F(0x052d98fc) /* 0.323632227 */, 18 }, - /* 4972 */ { MAD_F(0x052df403) /* 0.323719036 */, 18 }, - /* 4973 */ { MAD_F(0x052e4f0b) /* 0.323805850 */, 18 }, - /* 4974 */ { MAD_F(0x052eaa14) /* 0.323892670 */, 18 }, - /* 4975 */ { MAD_F(0x052f051f) /* 0.323979496 */, 18 }, - - /* 4976 */ { MAD_F(0x052f602c) /* 0.324066327 */, 18 }, - /* 4977 */ { MAD_F(0x052fbb3a) /* 0.324153165 */, 18 }, - /* 4978 */ { MAD_F(0x0530164a) /* 0.324240008 */, 18 }, - /* 4979 */ { MAD_F(0x0530715b) /* 0.324326857 */, 18 }, - /* 4980 */ { MAD_F(0x0530cc6e) /* 0.324413712 */, 18 }, - /* 4981 */ { MAD_F(0x05312783) /* 0.324500572 */, 18 }, - /* 4982 */ { MAD_F(0x05318299) /* 0.324587439 */, 18 }, - /* 4983 */ { MAD_F(0x0531ddb0) /* 0.324674311 */, 18 }, - /* 4984 */ { MAD_F(0x053238ca) /* 0.324761189 */, 18 }, - /* 4985 */ { MAD_F(0x053293e4) /* 0.324848073 */, 18 }, - /* 4986 */ { MAD_F(0x0532ef01) /* 0.324934963 */, 18 }, - /* 4987 */ { MAD_F(0x05334a1e) /* 0.325021858 */, 18 }, - /* 4988 */ { MAD_F(0x0533a53e) /* 0.325108760 */, 18 }, - /* 4989 */ { MAD_F(0x0534005f) /* 0.325195667 */, 18 }, - /* 4990 */ { MAD_F(0x05345b81) /* 0.325282580 */, 18 }, - /* 4991 */ { MAD_F(0x0534b6a5) /* 0.325369498 */, 18 }, - - /* 4992 */ { MAD_F(0x053511cb) /* 0.325456423 */, 18 }, - /* 4993 */ { MAD_F(0x05356cf2) /* 0.325543353 */, 18 }, - /* 4994 */ { MAD_F(0x0535c81b) /* 0.325630290 */, 18 }, - /* 4995 */ { MAD_F(0x05362345) /* 0.325717232 */, 18 }, - /* 4996 */ { MAD_F(0x05367e71) /* 0.325804179 */, 18 }, - /* 4997 */ { MAD_F(0x0536d99f) /* 0.325891133 */, 18 }, - /* 4998 */ { MAD_F(0x053734ce) /* 0.325978092 */, 18 }, - /* 4999 */ { MAD_F(0x05378ffe) /* 0.326065057 */, 18 }, - /* 5000 */ { MAD_F(0x0537eb30) /* 0.326152028 */, 18 }, - /* 5001 */ { MAD_F(0x05384664) /* 0.326239005 */, 18 }, - /* 5002 */ { MAD_F(0x0538a199) /* 0.326325988 */, 18 }, - /* 5003 */ { MAD_F(0x0538fcd0) /* 0.326412976 */, 18 }, - /* 5004 */ { MAD_F(0x05395808) /* 0.326499970 */, 18 }, - /* 5005 */ { MAD_F(0x0539b342) /* 0.326586970 */, 18 }, - /* 5006 */ { MAD_F(0x053a0e7d) /* 0.326673976 */, 18 }, - /* 5007 */ { MAD_F(0x053a69ba) /* 0.326760988 */, 18 }, - - /* 5008 */ { MAD_F(0x053ac4f9) /* 0.326848005 */, 18 }, - /* 5009 */ { MAD_F(0x053b2039) /* 0.326935028 */, 18 }, - /* 5010 */ { MAD_F(0x053b7b7b) /* 0.327022057 */, 18 }, - /* 5011 */ { MAD_F(0x053bd6be) /* 0.327109092 */, 18 }, - /* 5012 */ { MAD_F(0x053c3203) /* 0.327196132 */, 18 }, - /* 5013 */ { MAD_F(0x053c8d49) /* 0.327283178 */, 18 }, - /* 5014 */ { MAD_F(0x053ce891) /* 0.327370231 */, 18 }, - /* 5015 */ { MAD_F(0x053d43da) /* 0.327457288 */, 18 }, - /* 5016 */ { MAD_F(0x053d9f25) /* 0.327544352 */, 18 }, - /* 5017 */ { MAD_F(0x053dfa72) /* 0.327631421 */, 18 }, - /* 5018 */ { MAD_F(0x053e55c0) /* 0.327718497 */, 18 }, - /* 5019 */ { MAD_F(0x053eb10f) /* 0.327805578 */, 18 }, - /* 5020 */ { MAD_F(0x053f0c61) /* 0.327892665 */, 18 }, - /* 5021 */ { MAD_F(0x053f67b3) /* 0.327979757 */, 18 }, - /* 5022 */ { MAD_F(0x053fc308) /* 0.328066855 */, 18 }, - /* 5023 */ { MAD_F(0x05401e5e) /* 0.328153960 */, 18 }, - - /* 5024 */ { MAD_F(0x054079b5) /* 0.328241070 */, 18 }, - /* 5025 */ { MAD_F(0x0540d50e) /* 0.328328185 */, 18 }, - /* 5026 */ { MAD_F(0x05413068) /* 0.328415307 */, 18 }, - /* 5027 */ { MAD_F(0x05418bc4) /* 0.328502434 */, 18 }, - /* 5028 */ { MAD_F(0x0541e722) /* 0.328589567 */, 18 }, - /* 5029 */ { MAD_F(0x05424281) /* 0.328676706 */, 18 }, - /* 5030 */ { MAD_F(0x05429de2) /* 0.328763850 */, 18 }, - /* 5031 */ { MAD_F(0x0542f944) /* 0.328851001 */, 18 }, - /* 5032 */ { MAD_F(0x054354a8) /* 0.328938157 */, 18 }, - /* 5033 */ { MAD_F(0x0543b00d) /* 0.329025319 */, 18 }, - /* 5034 */ { MAD_F(0x05440b74) /* 0.329112486 */, 18 }, - /* 5035 */ { MAD_F(0x054466dd) /* 0.329199660 */, 18 }, - /* 5036 */ { MAD_F(0x0544c247) /* 0.329286839 */, 18 }, - /* 5037 */ { MAD_F(0x05451db2) /* 0.329374024 */, 18 }, - /* 5038 */ { MAD_F(0x0545791f) /* 0.329461215 */, 18 }, - /* 5039 */ { MAD_F(0x0545d48e) /* 0.329548411 */, 18 }, - - /* 5040 */ { MAD_F(0x05462ffe) /* 0.329635614 */, 18 }, - /* 5041 */ { MAD_F(0x05468b70) /* 0.329722822 */, 18 }, - /* 5042 */ { MAD_F(0x0546e6e3) /* 0.329810036 */, 18 }, - /* 5043 */ { MAD_F(0x05474258) /* 0.329897255 */, 18 }, - /* 5044 */ { MAD_F(0x05479dce) /* 0.329984481 */, 18 }, - /* 5045 */ { MAD_F(0x0547f946) /* 0.330071712 */, 18 }, - /* 5046 */ { MAD_F(0x054854c0) /* 0.330158949 */, 18 }, - /* 5047 */ { MAD_F(0x0548b03b) /* 0.330246191 */, 18 }, - /* 5048 */ { MAD_F(0x05490bb7) /* 0.330333440 */, 18 }, - /* 5049 */ { MAD_F(0x05496735) /* 0.330420694 */, 18 }, - /* 5050 */ { MAD_F(0x0549c2b5) /* 0.330507954 */, 18 }, - /* 5051 */ { MAD_F(0x054a1e36) /* 0.330595220 */, 18 }, - /* 5052 */ { MAD_F(0x054a79b9) /* 0.330682491 */, 18 }, - /* 5053 */ { MAD_F(0x054ad53d) /* 0.330769768 */, 18 }, - /* 5054 */ { MAD_F(0x054b30c3) /* 0.330857051 */, 18 }, - /* 5055 */ { MAD_F(0x054b8c4b) /* 0.330944340 */, 18 }, - - /* 5056 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 18 }, - /* 5057 */ { MAD_F(0x054c435e) /* 0.331118935 */, 18 }, - /* 5058 */ { MAD_F(0x054c9eea) /* 0.331206241 */, 18 }, - /* 5059 */ { MAD_F(0x054cfa78) /* 0.331293553 */, 18 }, - /* 5060 */ { MAD_F(0x054d5607) /* 0.331380870 */, 18 }, - /* 5061 */ { MAD_F(0x054db197) /* 0.331468193 */, 18 }, - /* 5062 */ { MAD_F(0x054e0d2a) /* 0.331555522 */, 18 }, - /* 5063 */ { MAD_F(0x054e68bd) /* 0.331642857 */, 18 }, - /* 5064 */ { MAD_F(0x054ec453) /* 0.331730198 */, 18 }, - /* 5065 */ { MAD_F(0x054f1fe9) /* 0.331817544 */, 18 }, - /* 5066 */ { MAD_F(0x054f7b82) /* 0.331904896 */, 18 }, - /* 5067 */ { MAD_F(0x054fd71c) /* 0.331992254 */, 18 }, - /* 5068 */ { MAD_F(0x055032b7) /* 0.332079617 */, 18 }, - /* 5069 */ { MAD_F(0x05508e54) /* 0.332166986 */, 18 }, - /* 5070 */ { MAD_F(0x0550e9f3) /* 0.332254361 */, 18 }, - /* 5071 */ { MAD_F(0x05514593) /* 0.332341742 */, 18 }, - - /* 5072 */ { MAD_F(0x0551a134) /* 0.332429129 */, 18 }, - /* 5073 */ { MAD_F(0x0551fcd8) /* 0.332516521 */, 18 }, - /* 5074 */ { MAD_F(0x0552587c) /* 0.332603919 */, 18 }, - /* 5075 */ { MAD_F(0x0552b423) /* 0.332691323 */, 18 }, - /* 5076 */ { MAD_F(0x05530fca) /* 0.332778732 */, 18 }, - /* 5077 */ { MAD_F(0x05536b74) /* 0.332866147 */, 18 }, - /* 5078 */ { MAD_F(0x0553c71f) /* 0.332953568 */, 18 }, - /* 5079 */ { MAD_F(0x055422cb) /* 0.333040995 */, 18 }, - /* 5080 */ { MAD_F(0x05547e79) /* 0.333128427 */, 18 }, - /* 5081 */ { MAD_F(0x0554da29) /* 0.333215865 */, 18 }, - /* 5082 */ { MAD_F(0x055535da) /* 0.333303309 */, 18 }, - /* 5083 */ { MAD_F(0x0555918c) /* 0.333390759 */, 18 }, - /* 5084 */ { MAD_F(0x0555ed40) /* 0.333478214 */, 18 }, - /* 5085 */ { MAD_F(0x055648f6) /* 0.333565675 */, 18 }, - /* 5086 */ { MAD_F(0x0556a4ad) /* 0.333653142 */, 18 }, - /* 5087 */ { MAD_F(0x05570066) /* 0.333740615 */, 18 }, - - /* 5088 */ { MAD_F(0x05575c20) /* 0.333828093 */, 18 }, - /* 5089 */ { MAD_F(0x0557b7dc) /* 0.333915577 */, 18 }, - /* 5090 */ { MAD_F(0x05581399) /* 0.334003067 */, 18 }, - /* 5091 */ { MAD_F(0x05586f58) /* 0.334090562 */, 18 }, - /* 5092 */ { MAD_F(0x0558cb19) /* 0.334178063 */, 18 }, - /* 5093 */ { MAD_F(0x055926db) /* 0.334265570 */, 18 }, - /* 5094 */ { MAD_F(0x0559829e) /* 0.334353083 */, 18 }, - /* 5095 */ { MAD_F(0x0559de63) /* 0.334440601 */, 18 }, - /* 5096 */ { MAD_F(0x055a3a2a) /* 0.334528126 */, 18 }, - /* 5097 */ { MAD_F(0x055a95f2) /* 0.334615655 */, 18 }, - /* 5098 */ { MAD_F(0x055af1bb) /* 0.334703191 */, 18 }, - /* 5099 */ { MAD_F(0x055b4d87) /* 0.334790732 */, 18 }, - /* 5100 */ { MAD_F(0x055ba953) /* 0.334878279 */, 18 }, - /* 5101 */ { MAD_F(0x055c0522) /* 0.334965832 */, 18 }, - /* 5102 */ { MAD_F(0x055c60f1) /* 0.335053391 */, 18 }, - /* 5103 */ { MAD_F(0x055cbcc3) /* 0.335140955 */, 18 }, - - /* 5104 */ { MAD_F(0x055d1896) /* 0.335228525 */, 18 }, - /* 5105 */ { MAD_F(0x055d746a) /* 0.335316100 */, 18 }, - /* 5106 */ { MAD_F(0x055dd040) /* 0.335403682 */, 18 }, - /* 5107 */ { MAD_F(0x055e2c17) /* 0.335491269 */, 18 }, - /* 5108 */ { MAD_F(0x055e87f0) /* 0.335578861 */, 18 }, - /* 5109 */ { MAD_F(0x055ee3cb) /* 0.335666460 */, 18 }, - /* 5110 */ { MAD_F(0x055f3fa7) /* 0.335754064 */, 18 }, - /* 5111 */ { MAD_F(0x055f9b85) /* 0.335841674 */, 18 }, - /* 5112 */ { MAD_F(0x055ff764) /* 0.335929290 */, 18 }, - /* 5113 */ { MAD_F(0x05605344) /* 0.336016911 */, 18 }, - /* 5114 */ { MAD_F(0x0560af27) /* 0.336104538 */, 18 }, - /* 5115 */ { MAD_F(0x05610b0a) /* 0.336192171 */, 18 }, - /* 5116 */ { MAD_F(0x056166f0) /* 0.336279809 */, 18 }, - /* 5117 */ { MAD_F(0x0561c2d7) /* 0.336367453 */, 18 }, - /* 5118 */ { MAD_F(0x05621ebf) /* 0.336455103 */, 18 }, - /* 5119 */ { MAD_F(0x05627aa9) /* 0.336542759 */, 18 }, - - /* 5120 */ { MAD_F(0x0562d694) /* 0.336630420 */, 18 }, - /* 5121 */ { MAD_F(0x05633281) /* 0.336718087 */, 18 }, - /* 5122 */ { MAD_F(0x05638e70) /* 0.336805760 */, 18 }, - /* 5123 */ { MAD_F(0x0563ea60) /* 0.336893439 */, 18 }, - /* 5124 */ { MAD_F(0x05644651) /* 0.336981123 */, 18 }, - /* 5125 */ { MAD_F(0x0564a244) /* 0.337068813 */, 18 }, - /* 5126 */ { MAD_F(0x0564fe39) /* 0.337156508 */, 18 }, - /* 5127 */ { MAD_F(0x05655a2f) /* 0.337244209 */, 18 }, - /* 5128 */ { MAD_F(0x0565b627) /* 0.337331916 */, 18 }, - /* 5129 */ { MAD_F(0x05661220) /* 0.337419629 */, 18 }, - /* 5130 */ { MAD_F(0x05666e1a) /* 0.337507347 */, 18 }, - /* 5131 */ { MAD_F(0x0566ca17) /* 0.337595071 */, 18 }, - /* 5132 */ { MAD_F(0x05672614) /* 0.337682801 */, 18 }, - /* 5133 */ { MAD_F(0x05678214) /* 0.337770537 */, 18 }, - /* 5134 */ { MAD_F(0x0567de15) /* 0.337858278 */, 18 }, - /* 5135 */ { MAD_F(0x05683a17) /* 0.337946025 */, 18 }, - - /* 5136 */ { MAD_F(0x0568961b) /* 0.338033777 */, 18 }, - /* 5137 */ { MAD_F(0x0568f220) /* 0.338121535 */, 18 }, - /* 5138 */ { MAD_F(0x05694e27) /* 0.338209299 */, 18 }, - /* 5139 */ { MAD_F(0x0569aa30) /* 0.338297069 */, 18 }, - /* 5140 */ { MAD_F(0x056a063a) /* 0.338384844 */, 18 }, - /* 5141 */ { MAD_F(0x056a6245) /* 0.338472625 */, 18 }, - /* 5142 */ { MAD_F(0x056abe52) /* 0.338560412 */, 18 }, - /* 5143 */ { MAD_F(0x056b1a61) /* 0.338648204 */, 18 }, - /* 5144 */ { MAD_F(0x056b7671) /* 0.338736002 */, 18 }, - /* 5145 */ { MAD_F(0x056bd283) /* 0.338823806 */, 18 }, - /* 5146 */ { MAD_F(0x056c2e96) /* 0.338911616 */, 18 }, - /* 5147 */ { MAD_F(0x056c8aab) /* 0.338999431 */, 18 }, - /* 5148 */ { MAD_F(0x056ce6c1) /* 0.339087252 */, 18 }, - /* 5149 */ { MAD_F(0x056d42d9) /* 0.339175078 */, 18 }, - /* 5150 */ { MAD_F(0x056d9ef2) /* 0.339262910 */, 18 }, - /* 5151 */ { MAD_F(0x056dfb0d) /* 0.339350748 */, 18 }, - - /* 5152 */ { MAD_F(0x056e5729) /* 0.339438592 */, 18 }, - /* 5153 */ { MAD_F(0x056eb347) /* 0.339526441 */, 18 }, - /* 5154 */ { MAD_F(0x056f0f66) /* 0.339614296 */, 18 }, - /* 5155 */ { MAD_F(0x056f6b87) /* 0.339702157 */, 18 }, - /* 5156 */ { MAD_F(0x056fc7aa) /* 0.339790023 */, 18 }, - /* 5157 */ { MAD_F(0x057023cd) /* 0.339877895 */, 18 }, - /* 5158 */ { MAD_F(0x05707ff3) /* 0.339965773 */, 18 }, - /* 5159 */ { MAD_F(0x0570dc1a) /* 0.340053656 */, 18 }, - /* 5160 */ { MAD_F(0x05713843) /* 0.340141545 */, 18 }, - /* 5161 */ { MAD_F(0x0571946d) /* 0.340229440 */, 18 }, - /* 5162 */ { MAD_F(0x0571f098) /* 0.340317340 */, 18 }, - /* 5163 */ { MAD_F(0x05724cc5) /* 0.340405246 */, 18 }, - /* 5164 */ { MAD_F(0x0572a8f4) /* 0.340493158 */, 18 }, - /* 5165 */ { MAD_F(0x05730524) /* 0.340581075 */, 18 }, - /* 5166 */ { MAD_F(0x05736156) /* 0.340668999 */, 18 }, - /* 5167 */ { MAD_F(0x0573bd89) /* 0.340756927 */, 18 }, - - /* 5168 */ { MAD_F(0x057419be) /* 0.340844862 */, 18 }, - /* 5169 */ { MAD_F(0x057475f4) /* 0.340932802 */, 18 }, - /* 5170 */ { MAD_F(0x0574d22c) /* 0.341020748 */, 18 }, - /* 5171 */ { MAD_F(0x05752e65) /* 0.341108699 */, 18 }, - /* 5172 */ { MAD_F(0x05758aa0) /* 0.341196656 */, 18 }, - /* 5173 */ { MAD_F(0x0575e6dc) /* 0.341284619 */, 18 }, - /* 5174 */ { MAD_F(0x0576431a) /* 0.341372587 */, 18 }, - /* 5175 */ { MAD_F(0x05769f59) /* 0.341460562 */, 18 }, - /* 5176 */ { MAD_F(0x0576fb9a) /* 0.341548541 */, 18 }, - /* 5177 */ { MAD_F(0x057757dd) /* 0.341636527 */, 18 }, - /* 5178 */ { MAD_F(0x0577b421) /* 0.341724518 */, 18 }, - /* 5179 */ { MAD_F(0x05781066) /* 0.341812515 */, 18 }, - /* 5180 */ { MAD_F(0x05786cad) /* 0.341900517 */, 18 }, - /* 5181 */ { MAD_F(0x0578c8f5) /* 0.341988525 */, 18 }, - /* 5182 */ { MAD_F(0x0579253f) /* 0.342076539 */, 18 }, - /* 5183 */ { MAD_F(0x0579818b) /* 0.342164558 */, 18 }, - - /* 5184 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 18 }, - /* 5185 */ { MAD_F(0x057a3a27) /* 0.342340614 */, 18 }, - /* 5186 */ { MAD_F(0x057a9677) /* 0.342428651 */, 18 }, - /* 5187 */ { MAD_F(0x057af2c8) /* 0.342516693 */, 18 }, - /* 5188 */ { MAD_F(0x057b4f1c) /* 0.342604741 */, 18 }, - /* 5189 */ { MAD_F(0x057bab70) /* 0.342692794 */, 18 }, - /* 5190 */ { MAD_F(0x057c07c6) /* 0.342780853 */, 18 }, - /* 5191 */ { MAD_F(0x057c641e) /* 0.342868918 */, 18 }, - /* 5192 */ { MAD_F(0x057cc077) /* 0.342956988 */, 18 }, - /* 5193 */ { MAD_F(0x057d1cd2) /* 0.343045064 */, 18 }, - /* 5194 */ { MAD_F(0x057d792e) /* 0.343133146 */, 18 }, - /* 5195 */ { MAD_F(0x057dd58c) /* 0.343221233 */, 18 }, - /* 5196 */ { MAD_F(0x057e31eb) /* 0.343309326 */, 18 }, - /* 5197 */ { MAD_F(0x057e8e4c) /* 0.343397425 */, 18 }, - /* 5198 */ { MAD_F(0x057eeaae) /* 0.343485529 */, 18 }, - /* 5199 */ { MAD_F(0x057f4712) /* 0.343573639 */, 18 }, - - /* 5200 */ { MAD_F(0x057fa378) /* 0.343661754 */, 18 }, - /* 5201 */ { MAD_F(0x057fffde) /* 0.343749876 */, 18 }, - /* 5202 */ { MAD_F(0x05805c47) /* 0.343838003 */, 18 }, - /* 5203 */ { MAD_F(0x0580b8b1) /* 0.343926135 */, 18 }, - /* 5204 */ { MAD_F(0x0581151c) /* 0.344014273 */, 18 }, - /* 5205 */ { MAD_F(0x05817189) /* 0.344102417 */, 18 }, - /* 5206 */ { MAD_F(0x0581cdf7) /* 0.344190566 */, 18 }, - /* 5207 */ { MAD_F(0x05822a67) /* 0.344278722 */, 18 }, - /* 5208 */ { MAD_F(0x058286d9) /* 0.344366882 */, 18 }, - /* 5209 */ { MAD_F(0x0582e34c) /* 0.344455049 */, 18 }, - /* 5210 */ { MAD_F(0x05833fc0) /* 0.344543221 */, 18 }, - /* 5211 */ { MAD_F(0x05839c36) /* 0.344631398 */, 18 }, - /* 5212 */ { MAD_F(0x0583f8ae) /* 0.344719582 */, 18 }, - /* 5213 */ { MAD_F(0x05845527) /* 0.344807771 */, 18 }, - /* 5214 */ { MAD_F(0x0584b1a1) /* 0.344895965 */, 18 }, - /* 5215 */ { MAD_F(0x05850e1e) /* 0.344984165 */, 18 }, - - /* 5216 */ { MAD_F(0x05856a9b) /* 0.345072371 */, 18 }, - /* 5217 */ { MAD_F(0x0585c71a) /* 0.345160583 */, 18 }, - /* 5218 */ { MAD_F(0x0586239b) /* 0.345248800 */, 18 }, - /* 5219 */ { MAD_F(0x0586801d) /* 0.345337023 */, 18 }, - /* 5220 */ { MAD_F(0x0586dca1) /* 0.345425251 */, 18 }, - /* 5221 */ { MAD_F(0x05873926) /* 0.345513485 */, 18 }, - /* 5222 */ { MAD_F(0x058795ac) /* 0.345601725 */, 18 }, - /* 5223 */ { MAD_F(0x0587f235) /* 0.345689970 */, 18 }, - /* 5224 */ { MAD_F(0x05884ebe) /* 0.345778221 */, 18 }, - /* 5225 */ { MAD_F(0x0588ab49) /* 0.345866478 */, 18 }, - /* 5226 */ { MAD_F(0x058907d6) /* 0.345954740 */, 18 }, - /* 5227 */ { MAD_F(0x05896464) /* 0.346043008 */, 18 }, - /* 5228 */ { MAD_F(0x0589c0f4) /* 0.346131281 */, 18 }, - /* 5229 */ { MAD_F(0x058a1d85) /* 0.346219560 */, 18 }, - /* 5230 */ { MAD_F(0x058a7a18) /* 0.346307845 */, 18 }, - /* 5231 */ { MAD_F(0x058ad6ac) /* 0.346396135 */, 18 }, - - /* 5232 */ { MAD_F(0x058b3342) /* 0.346484431 */, 18 }, - /* 5233 */ { MAD_F(0x058b8fd9) /* 0.346572733 */, 18 }, - /* 5234 */ { MAD_F(0x058bec72) /* 0.346661040 */, 18 }, - /* 5235 */ { MAD_F(0x058c490c) /* 0.346749353 */, 18 }, - /* 5236 */ { MAD_F(0x058ca5a8) /* 0.346837671 */, 18 }, - /* 5237 */ { MAD_F(0x058d0246) /* 0.346925996 */, 18 }, - /* 5238 */ { MAD_F(0x058d5ee4) /* 0.347014325 */, 18 }, - /* 5239 */ { MAD_F(0x058dbb85) /* 0.347102661 */, 18 }, - /* 5240 */ { MAD_F(0x058e1827) /* 0.347191002 */, 18 }, - /* 5241 */ { MAD_F(0x058e74ca) /* 0.347279348 */, 18 }, - /* 5242 */ { MAD_F(0x058ed16f) /* 0.347367700 */, 18 }, - /* 5243 */ { MAD_F(0x058f2e15) /* 0.347456058 */, 18 }, - /* 5244 */ { MAD_F(0x058f8abd) /* 0.347544422 */, 18 }, - /* 5245 */ { MAD_F(0x058fe766) /* 0.347632791 */, 18 }, - /* 5246 */ { MAD_F(0x05904411) /* 0.347721165 */, 18 }, - /* 5247 */ { MAD_F(0x0590a0be) /* 0.347809546 */, 18 }, - - /* 5248 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 18 }, - /* 5249 */ { MAD_F(0x05915a1b) /* 0.347986323 */, 18 }, - /* 5250 */ { MAD_F(0x0591b6cc) /* 0.348074720 */, 18 }, - /* 5251 */ { MAD_F(0x0592137e) /* 0.348163123 */, 18 }, - /* 5252 */ { MAD_F(0x05927032) /* 0.348251531 */, 18 }, - /* 5253 */ { MAD_F(0x0592cce8) /* 0.348339945 */, 18 }, - /* 5254 */ { MAD_F(0x0593299f) /* 0.348428365 */, 18 }, - /* 5255 */ { MAD_F(0x05938657) /* 0.348516790 */, 18 }, - /* 5256 */ { MAD_F(0x0593e311) /* 0.348605221 */, 18 }, - /* 5257 */ { MAD_F(0x05943fcd) /* 0.348693657 */, 18 }, - /* 5258 */ { MAD_F(0x05949c8a) /* 0.348782099 */, 18 }, - /* 5259 */ { MAD_F(0x0594f948) /* 0.348870547 */, 18 }, - /* 5260 */ { MAD_F(0x05955608) /* 0.348959000 */, 18 }, - /* 5261 */ { MAD_F(0x0595b2ca) /* 0.349047459 */, 18 }, - /* 5262 */ { MAD_F(0x05960f8c) /* 0.349135923 */, 18 }, - /* 5263 */ { MAD_F(0x05966c51) /* 0.349224393 */, 18 }, - - /* 5264 */ { MAD_F(0x0596c917) /* 0.349312869 */, 18 }, - /* 5265 */ { MAD_F(0x059725de) /* 0.349401350 */, 18 }, - /* 5266 */ { MAD_F(0x059782a7) /* 0.349489837 */, 18 }, - /* 5267 */ { MAD_F(0x0597df72) /* 0.349578329 */, 18 }, - /* 5268 */ { MAD_F(0x05983c3e) /* 0.349666827 */, 18 }, - /* 5269 */ { MAD_F(0x0598990c) /* 0.349755331 */, 18 }, - /* 5270 */ { MAD_F(0x0598f5db) /* 0.349843840 */, 18 }, - /* 5271 */ { MAD_F(0x059952ab) /* 0.349932355 */, 18 }, - /* 5272 */ { MAD_F(0x0599af7d) /* 0.350020876 */, 18 }, - /* 5273 */ { MAD_F(0x059a0c51) /* 0.350109402 */, 18 }, - /* 5274 */ { MAD_F(0x059a6926) /* 0.350197933 */, 18 }, - /* 5275 */ { MAD_F(0x059ac5fc) /* 0.350286470 */, 18 }, - /* 5276 */ { MAD_F(0x059b22d4) /* 0.350375013 */, 18 }, - /* 5277 */ { MAD_F(0x059b7fae) /* 0.350463562 */, 18 }, - /* 5278 */ { MAD_F(0x059bdc89) /* 0.350552116 */, 18 }, - /* 5279 */ { MAD_F(0x059c3965) /* 0.350640675 */, 18 }, - - /* 5280 */ { MAD_F(0x059c9643) /* 0.350729240 */, 18 }, - /* 5281 */ { MAD_F(0x059cf323) /* 0.350817811 */, 18 }, - /* 5282 */ { MAD_F(0x059d5004) /* 0.350906388 */, 18 }, - /* 5283 */ { MAD_F(0x059dace6) /* 0.350994970 */, 18 }, - /* 5284 */ { MAD_F(0x059e09cb) /* 0.351083557 */, 18 }, - /* 5285 */ { MAD_F(0x059e66b0) /* 0.351172150 */, 18 }, - /* 5286 */ { MAD_F(0x059ec397) /* 0.351260749 */, 18 }, - /* 5287 */ { MAD_F(0x059f2080) /* 0.351349353 */, 18 }, - /* 5288 */ { MAD_F(0x059f7d6a) /* 0.351437963 */, 18 }, - /* 5289 */ { MAD_F(0x059fda55) /* 0.351526579 */, 18 }, - /* 5290 */ { MAD_F(0x05a03742) /* 0.351615200 */, 18 }, - /* 5291 */ { MAD_F(0x05a09431) /* 0.351703827 */, 18 }, - /* 5292 */ { MAD_F(0x05a0f121) /* 0.351792459 */, 18 }, - /* 5293 */ { MAD_F(0x05a14e12) /* 0.351881097 */, 18 }, - /* 5294 */ { MAD_F(0x05a1ab05) /* 0.351969740 */, 18 }, - /* 5295 */ { MAD_F(0x05a207fa) /* 0.352058389 */, 18 }, - - /* 5296 */ { MAD_F(0x05a264f0) /* 0.352147044 */, 18 }, - /* 5297 */ { MAD_F(0x05a2c1e7) /* 0.352235704 */, 18 }, - /* 5298 */ { MAD_F(0x05a31ee1) /* 0.352324369 */, 18 }, - /* 5299 */ { MAD_F(0x05a37bdb) /* 0.352413041 */, 18 }, - /* 5300 */ { MAD_F(0x05a3d8d7) /* 0.352501718 */, 18 }, - /* 5301 */ { MAD_F(0x05a435d5) /* 0.352590400 */, 18 }, - /* 5302 */ { MAD_F(0x05a492d4) /* 0.352679088 */, 18 }, - /* 5303 */ { MAD_F(0x05a4efd4) /* 0.352767782 */, 18 }, - /* 5304 */ { MAD_F(0x05a54cd6) /* 0.352856481 */, 18 }, - /* 5305 */ { MAD_F(0x05a5a9da) /* 0.352945186 */, 18 }, - /* 5306 */ { MAD_F(0x05a606df) /* 0.353033896 */, 18 }, - /* 5307 */ { MAD_F(0x05a663e5) /* 0.353122612 */, 18 }, - /* 5308 */ { MAD_F(0x05a6c0ed) /* 0.353211333 */, 18 }, - /* 5309 */ { MAD_F(0x05a71df7) /* 0.353300061 */, 18 }, - /* 5310 */ { MAD_F(0x05a77b02) /* 0.353388793 */, 18 }, - /* 5311 */ { MAD_F(0x05a7d80e) /* 0.353477531 */, 18 }, - - /* 5312 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 18 }, - /* 5313 */ { MAD_F(0x05a8922c) /* 0.353655024 */, 18 }, - /* 5314 */ { MAD_F(0x05a8ef3c) /* 0.353743779 */, 18 }, - /* 5315 */ { MAD_F(0x05a94c4f) /* 0.353832540 */, 18 }, - /* 5316 */ { MAD_F(0x05a9a963) /* 0.353921306 */, 18 }, - /* 5317 */ { MAD_F(0x05aa0678) /* 0.354010077 */, 18 }, - /* 5318 */ { MAD_F(0x05aa638f) /* 0.354098855 */, 18 }, - /* 5319 */ { MAD_F(0x05aac0a8) /* 0.354187637 */, 18 }, - /* 5320 */ { MAD_F(0x05ab1dc2) /* 0.354276426 */, 18 }, - /* 5321 */ { MAD_F(0x05ab7add) /* 0.354365220 */, 18 }, - /* 5322 */ { MAD_F(0x05abd7fa) /* 0.354454019 */, 18 }, - /* 5323 */ { MAD_F(0x05ac3518) /* 0.354542824 */, 18 }, - /* 5324 */ { MAD_F(0x05ac9238) /* 0.354631635 */, 18 }, - /* 5325 */ { MAD_F(0x05acef5a) /* 0.354720451 */, 18 }, - /* 5326 */ { MAD_F(0x05ad4c7d) /* 0.354809272 */, 18 }, - /* 5327 */ { MAD_F(0x05ada9a1) /* 0.354898100 */, 18 }, - - /* 5328 */ { MAD_F(0x05ae06c7) /* 0.354986932 */, 18 }, - /* 5329 */ { MAD_F(0x05ae63ee) /* 0.355075771 */, 18 }, - /* 5330 */ { MAD_F(0x05aec117) /* 0.355164615 */, 18 }, - /* 5331 */ { MAD_F(0x05af1e41) /* 0.355253464 */, 18 }, - /* 5332 */ { MAD_F(0x05af7b6d) /* 0.355342319 */, 18 }, - /* 5333 */ { MAD_F(0x05afd89b) /* 0.355431180 */, 18 }, - /* 5334 */ { MAD_F(0x05b035c9) /* 0.355520046 */, 18 }, - /* 5335 */ { MAD_F(0x05b092fa) /* 0.355608917 */, 18 }, - /* 5336 */ { MAD_F(0x05b0f02b) /* 0.355697795 */, 18 }, - /* 5337 */ { MAD_F(0x05b14d5f) /* 0.355786677 */, 18 }, - /* 5338 */ { MAD_F(0x05b1aa94) /* 0.355875566 */, 18 }, - /* 5339 */ { MAD_F(0x05b207ca) /* 0.355964460 */, 18 }, - /* 5340 */ { MAD_F(0x05b26502) /* 0.356053359 */, 18 }, - /* 5341 */ { MAD_F(0x05b2c23b) /* 0.356142264 */, 18 }, - /* 5342 */ { MAD_F(0x05b31f76) /* 0.356231175 */, 18 }, - /* 5343 */ { MAD_F(0x05b37cb2) /* 0.356320091 */, 18 }, - - /* 5344 */ { MAD_F(0x05b3d9f0) /* 0.356409012 */, 18 }, - /* 5345 */ { MAD_F(0x05b4372f) /* 0.356497940 */, 18 }, - /* 5346 */ { MAD_F(0x05b4946f) /* 0.356586872 */, 18 }, - /* 5347 */ { MAD_F(0x05b4f1b2) /* 0.356675811 */, 18 }, - /* 5348 */ { MAD_F(0x05b54ef5) /* 0.356764754 */, 18 }, - /* 5349 */ { MAD_F(0x05b5ac3a) /* 0.356853704 */, 18 }, - /* 5350 */ { MAD_F(0x05b60981) /* 0.356942659 */, 18 }, - /* 5351 */ { MAD_F(0x05b666c9) /* 0.357031619 */, 18 }, - /* 5352 */ { MAD_F(0x05b6c413) /* 0.357120585 */, 18 }, - /* 5353 */ { MAD_F(0x05b7215e) /* 0.357209557 */, 18 }, - /* 5354 */ { MAD_F(0x05b77eab) /* 0.357298534 */, 18 }, - /* 5355 */ { MAD_F(0x05b7dbf9) /* 0.357387516 */, 18 }, - /* 5356 */ { MAD_F(0x05b83948) /* 0.357476504 */, 18 }, - /* 5357 */ { MAD_F(0x05b89699) /* 0.357565498 */, 18 }, - /* 5358 */ { MAD_F(0x05b8f3ec) /* 0.357654497 */, 18 }, - /* 5359 */ { MAD_F(0x05b95140) /* 0.357743502 */, 18 }, - - /* 5360 */ { MAD_F(0x05b9ae95) /* 0.357832512 */, 18 }, - /* 5361 */ { MAD_F(0x05ba0bec) /* 0.357921528 */, 18 }, - /* 5362 */ { MAD_F(0x05ba6945) /* 0.358010550 */, 18 }, - /* 5363 */ { MAD_F(0x05bac69f) /* 0.358099576 */, 18 }, - /* 5364 */ { MAD_F(0x05bb23fa) /* 0.358188609 */, 18 }, - /* 5365 */ { MAD_F(0x05bb8157) /* 0.358277647 */, 18 }, - /* 5366 */ { MAD_F(0x05bbdeb6) /* 0.358366690 */, 18 }, - /* 5367 */ { MAD_F(0x05bc3c16) /* 0.358455739 */, 18 }, - /* 5368 */ { MAD_F(0x05bc9977) /* 0.358544794 */, 18 }, - /* 5369 */ { MAD_F(0x05bcf6da) /* 0.358633854 */, 18 }, - /* 5370 */ { MAD_F(0x05bd543e) /* 0.358722920 */, 18 }, - /* 5371 */ { MAD_F(0x05bdb1a4) /* 0.358811991 */, 18 }, - /* 5372 */ { MAD_F(0x05be0f0b) /* 0.358901067 */, 18 }, - /* 5373 */ { MAD_F(0x05be6c74) /* 0.358990150 */, 18 }, - /* 5374 */ { MAD_F(0x05bec9df) /* 0.359079237 */, 18 }, - /* 5375 */ { MAD_F(0x05bf274a) /* 0.359168331 */, 18 }, - - /* 5376 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 18 }, - /* 5377 */ { MAD_F(0x05bfe226) /* 0.359346534 */, 18 }, - /* 5378 */ { MAD_F(0x05c03f97) /* 0.359435644 */, 18 }, - /* 5379 */ { MAD_F(0x05c09d08) /* 0.359524759 */, 18 }, - /* 5380 */ { MAD_F(0x05c0fa7c) /* 0.359613880 */, 18 }, - /* 5381 */ { MAD_F(0x05c157f0) /* 0.359703006 */, 18 }, - /* 5382 */ { MAD_F(0x05c1b566) /* 0.359792138 */, 18 }, - /* 5383 */ { MAD_F(0x05c212de) /* 0.359881276 */, 18 }, - /* 5384 */ { MAD_F(0x05c27057) /* 0.359970419 */, 18 }, - /* 5385 */ { MAD_F(0x05c2cdd2) /* 0.360059567 */, 18 }, - /* 5386 */ { MAD_F(0x05c32b4e) /* 0.360148721 */, 18 }, - /* 5387 */ { MAD_F(0x05c388cb) /* 0.360237881 */, 18 }, - /* 5388 */ { MAD_F(0x05c3e64b) /* 0.360327046 */, 18 }, - /* 5389 */ { MAD_F(0x05c443cb) /* 0.360416216 */, 18 }, - /* 5390 */ { MAD_F(0x05c4a14d) /* 0.360505392 */, 18 }, - /* 5391 */ { MAD_F(0x05c4fed1) /* 0.360594574 */, 18 }, - - /* 5392 */ { MAD_F(0x05c55c56) /* 0.360683761 */, 18 }, - /* 5393 */ { MAD_F(0x05c5b9dc) /* 0.360772953 */, 18 }, - /* 5394 */ { MAD_F(0x05c61764) /* 0.360862152 */, 18 }, - /* 5395 */ { MAD_F(0x05c674ed) /* 0.360951355 */, 18 }, - /* 5396 */ { MAD_F(0x05c6d278) /* 0.361040564 */, 18 }, - /* 5397 */ { MAD_F(0x05c73005) /* 0.361129779 */, 18 }, - /* 5398 */ { MAD_F(0x05c78d93) /* 0.361218999 */, 18 }, - /* 5399 */ { MAD_F(0x05c7eb22) /* 0.361308225 */, 18 }, - /* 5400 */ { MAD_F(0x05c848b3) /* 0.361397456 */, 18 }, - /* 5401 */ { MAD_F(0x05c8a645) /* 0.361486693 */, 18 }, - /* 5402 */ { MAD_F(0x05c903d9) /* 0.361575935 */, 18 }, - /* 5403 */ { MAD_F(0x05c9616e) /* 0.361665183 */, 18 }, - /* 5404 */ { MAD_F(0x05c9bf05) /* 0.361754436 */, 18 }, - /* 5405 */ { MAD_F(0x05ca1c9d) /* 0.361843695 */, 18 }, - /* 5406 */ { MAD_F(0x05ca7a37) /* 0.361932959 */, 18 }, - /* 5407 */ { MAD_F(0x05cad7d2) /* 0.362022229 */, 18 }, - - /* 5408 */ { MAD_F(0x05cb356e) /* 0.362111504 */, 18 }, - /* 5409 */ { MAD_F(0x05cb930d) /* 0.362200785 */, 18 }, - /* 5410 */ { MAD_F(0x05cbf0ac) /* 0.362290071 */, 18 }, - /* 5411 */ { MAD_F(0x05cc4e4d) /* 0.362379362 */, 18 }, - /* 5412 */ { MAD_F(0x05ccabf0) /* 0.362468660 */, 18 }, - /* 5413 */ { MAD_F(0x05cd0994) /* 0.362557962 */, 18 }, - /* 5414 */ { MAD_F(0x05cd6739) /* 0.362647271 */, 18 }, - /* 5415 */ { MAD_F(0x05cdc4e0) /* 0.362736584 */, 18 }, - /* 5416 */ { MAD_F(0x05ce2289) /* 0.362825904 */, 18 }, - /* 5417 */ { MAD_F(0x05ce8033) /* 0.362915228 */, 18 }, - /* 5418 */ { MAD_F(0x05ceddde) /* 0.363004559 */, 18 }, - /* 5419 */ { MAD_F(0x05cf3b8b) /* 0.363093894 */, 18 }, - /* 5420 */ { MAD_F(0x05cf9939) /* 0.363183236 */, 18 }, - /* 5421 */ { MAD_F(0x05cff6e9) /* 0.363272582 */, 18 }, - /* 5422 */ { MAD_F(0x05d0549a) /* 0.363361935 */, 18 }, - /* 5423 */ { MAD_F(0x05d0b24d) /* 0.363451292 */, 18 }, - - /* 5424 */ { MAD_F(0x05d11001) /* 0.363540655 */, 18 }, - /* 5425 */ { MAD_F(0x05d16db7) /* 0.363630024 */, 18 }, - /* 5426 */ { MAD_F(0x05d1cb6e) /* 0.363719398 */, 18 }, - /* 5427 */ { MAD_F(0x05d22927) /* 0.363808778 */, 18 }, - /* 5428 */ { MAD_F(0x05d286e1) /* 0.363898163 */, 18 }, - /* 5429 */ { MAD_F(0x05d2e49d) /* 0.363987554 */, 18 }, - /* 5430 */ { MAD_F(0x05d3425a) /* 0.364076950 */, 18 }, - /* 5431 */ { MAD_F(0x05d3a018) /* 0.364166352 */, 18 }, - /* 5432 */ { MAD_F(0x05d3fdd8) /* 0.364255759 */, 18 }, - /* 5433 */ { MAD_F(0x05d45b9a) /* 0.364345171 */, 18 }, - /* 5434 */ { MAD_F(0x05d4b95d) /* 0.364434589 */, 18 }, - /* 5435 */ { MAD_F(0x05d51721) /* 0.364524013 */, 18 }, - /* 5436 */ { MAD_F(0x05d574e7) /* 0.364613442 */, 18 }, - /* 5437 */ { MAD_F(0x05d5d2af) /* 0.364702877 */, 18 }, - /* 5438 */ { MAD_F(0x05d63078) /* 0.364792317 */, 18 }, - /* 5439 */ { MAD_F(0x05d68e42) /* 0.364881762 */, 18 }, - - /* 5440 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 18 }, - /* 5441 */ { MAD_F(0x05d749db) /* 0.365060669 */, 18 }, - /* 5442 */ { MAD_F(0x05d7a7aa) /* 0.365150131 */, 18 }, - /* 5443 */ { MAD_F(0x05d8057a) /* 0.365239599 */, 18 }, - /* 5444 */ { MAD_F(0x05d8634c) /* 0.365329072 */, 18 }, - /* 5445 */ { MAD_F(0x05d8c11f) /* 0.365418550 */, 18 }, - /* 5446 */ { MAD_F(0x05d91ef4) /* 0.365508034 */, 18 }, - /* 5447 */ { MAD_F(0x05d97cca) /* 0.365597523 */, 18 }, - /* 5448 */ { MAD_F(0x05d9daa1) /* 0.365687018 */, 18 }, - /* 5449 */ { MAD_F(0x05da387a) /* 0.365776518 */, 18 }, - /* 5450 */ { MAD_F(0x05da9655) /* 0.365866024 */, 18 }, - /* 5451 */ { MAD_F(0x05daf431) /* 0.365955536 */, 18 }, - /* 5452 */ { MAD_F(0x05db520e) /* 0.366045052 */, 18 }, - /* 5453 */ { MAD_F(0x05dbafed) /* 0.366134574 */, 18 }, - /* 5454 */ { MAD_F(0x05dc0dce) /* 0.366224102 */, 18 }, - /* 5455 */ { MAD_F(0x05dc6baf) /* 0.366313635 */, 18 }, - - /* 5456 */ { MAD_F(0x05dcc993) /* 0.366403174 */, 18 }, - /* 5457 */ { MAD_F(0x05dd2778) /* 0.366492718 */, 18 }, - /* 5458 */ { MAD_F(0x05dd855e) /* 0.366582267 */, 18 }, - /* 5459 */ { MAD_F(0x05dde346) /* 0.366671822 */, 18 }, - /* 5460 */ { MAD_F(0x05de412f) /* 0.366761383 */, 18 }, - /* 5461 */ { MAD_F(0x05de9f1a) /* 0.366850949 */, 18 }, - /* 5462 */ { MAD_F(0x05defd06) /* 0.366940520 */, 18 }, - /* 5463 */ { MAD_F(0x05df5af3) /* 0.367030097 */, 18 }, - /* 5464 */ { MAD_F(0x05dfb8e2) /* 0.367119680 */, 18 }, - /* 5465 */ { MAD_F(0x05e016d3) /* 0.367209267 */, 18 }, - /* 5466 */ { MAD_F(0x05e074c5) /* 0.367298861 */, 18 }, - /* 5467 */ { MAD_F(0x05e0d2b8) /* 0.367388459 */, 18 }, - /* 5468 */ { MAD_F(0x05e130ad) /* 0.367478064 */, 18 }, - /* 5469 */ { MAD_F(0x05e18ea4) /* 0.367567673 */, 18 }, - /* 5470 */ { MAD_F(0x05e1ec9c) /* 0.367657288 */, 18 }, - /* 5471 */ { MAD_F(0x05e24a95) /* 0.367746909 */, 18 }, - - /* 5472 */ { MAD_F(0x05e2a890) /* 0.367836535 */, 18 }, - /* 5473 */ { MAD_F(0x05e3068c) /* 0.367926167 */, 18 }, - /* 5474 */ { MAD_F(0x05e3648a) /* 0.368015804 */, 18 }, - /* 5475 */ { MAD_F(0x05e3c289) /* 0.368105446 */, 18 }, - /* 5476 */ { MAD_F(0x05e4208a) /* 0.368195094 */, 18 }, - /* 5477 */ { MAD_F(0x05e47e8c) /* 0.368284747 */, 18 }, - /* 5478 */ { MAD_F(0x05e4dc8f) /* 0.368374406 */, 18 }, - /* 5479 */ { MAD_F(0x05e53a94) /* 0.368464070 */, 18 }, - /* 5480 */ { MAD_F(0x05e5989b) /* 0.368553740 */, 18 }, - /* 5481 */ { MAD_F(0x05e5f6a3) /* 0.368643415 */, 18 }, - /* 5482 */ { MAD_F(0x05e654ac) /* 0.368733096 */, 18 }, - /* 5483 */ { MAD_F(0x05e6b2b7) /* 0.368822782 */, 18 }, - /* 5484 */ { MAD_F(0x05e710c4) /* 0.368912473 */, 18 }, - /* 5485 */ { MAD_F(0x05e76ed2) /* 0.369002170 */, 18 }, - /* 5486 */ { MAD_F(0x05e7cce1) /* 0.369091873 */, 18 }, - /* 5487 */ { MAD_F(0x05e82af2) /* 0.369181581 */, 18 }, - - /* 5488 */ { MAD_F(0x05e88904) /* 0.369271294 */, 18 }, - /* 5489 */ { MAD_F(0x05e8e718) /* 0.369361013 */, 18 }, - /* 5490 */ { MAD_F(0x05e9452d) /* 0.369450737 */, 18 }, - /* 5491 */ { MAD_F(0x05e9a343) /* 0.369540467 */, 18 }, - /* 5492 */ { MAD_F(0x05ea015c) /* 0.369630202 */, 18 }, - /* 5493 */ { MAD_F(0x05ea5f75) /* 0.369719942 */, 18 }, - /* 5494 */ { MAD_F(0x05eabd90) /* 0.369809688 */, 18 }, - /* 5495 */ { MAD_F(0x05eb1bad) /* 0.369899440 */, 18 }, - /* 5496 */ { MAD_F(0x05eb79cb) /* 0.369989197 */, 18 }, - /* 5497 */ { MAD_F(0x05ebd7ea) /* 0.370078959 */, 18 }, - /* 5498 */ { MAD_F(0x05ec360b) /* 0.370168727 */, 18 }, - /* 5499 */ { MAD_F(0x05ec942d) /* 0.370258500 */, 18 }, - /* 5500 */ { MAD_F(0x05ecf251) /* 0.370348279 */, 18 }, - /* 5501 */ { MAD_F(0x05ed5076) /* 0.370438063 */, 18 }, - /* 5502 */ { MAD_F(0x05edae9d) /* 0.370527853 */, 18 }, - /* 5503 */ { MAD_F(0x05ee0cc5) /* 0.370617648 */, 18 }, - - /* 5504 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 18 }, - /* 5505 */ { MAD_F(0x05eec91a) /* 0.370797254 */, 18 }, - /* 5506 */ { MAD_F(0x05ef2746) /* 0.370887065 */, 18 }, - /* 5507 */ { MAD_F(0x05ef8574) /* 0.370976882 */, 18 }, - /* 5508 */ { MAD_F(0x05efe3a4) /* 0.371066704 */, 18 }, - /* 5509 */ { MAD_F(0x05f041d5) /* 0.371156532 */, 18 }, - /* 5510 */ { MAD_F(0x05f0a007) /* 0.371246365 */, 18 }, - /* 5511 */ { MAD_F(0x05f0fe3b) /* 0.371336203 */, 18 }, - /* 5512 */ { MAD_F(0x05f15c70) /* 0.371426047 */, 18 }, - /* 5513 */ { MAD_F(0x05f1baa7) /* 0.371515897 */, 18 }, - /* 5514 */ { MAD_F(0x05f218df) /* 0.371605751 */, 18 }, - /* 5515 */ { MAD_F(0x05f27719) /* 0.371695612 */, 18 }, - /* 5516 */ { MAD_F(0x05f2d554) /* 0.371785477 */, 18 }, - /* 5517 */ { MAD_F(0x05f33390) /* 0.371875348 */, 18 }, - /* 5518 */ { MAD_F(0x05f391cf) /* 0.371965225 */, 18 }, - /* 5519 */ { MAD_F(0x05f3f00e) /* 0.372055107 */, 18 }, - - /* 5520 */ { MAD_F(0x05f44e4f) /* 0.372144994 */, 18 }, - /* 5521 */ { MAD_F(0x05f4ac91) /* 0.372234887 */, 18 }, - /* 5522 */ { MAD_F(0x05f50ad5) /* 0.372324785 */, 18 }, - /* 5523 */ { MAD_F(0x05f5691b) /* 0.372414689 */, 18 }, - /* 5524 */ { MAD_F(0x05f5c761) /* 0.372504598 */, 18 }, - /* 5525 */ { MAD_F(0x05f625aa) /* 0.372594513 */, 18 }, - /* 5526 */ { MAD_F(0x05f683f3) /* 0.372684433 */, 18 }, - /* 5527 */ { MAD_F(0x05f6e23f) /* 0.372774358 */, 18 }, - /* 5528 */ { MAD_F(0x05f7408b) /* 0.372864289 */, 18 }, - /* 5529 */ { MAD_F(0x05f79ed9) /* 0.372954225 */, 18 }, - /* 5530 */ { MAD_F(0x05f7fd29) /* 0.373044167 */, 18 }, - /* 5531 */ { MAD_F(0x05f85b7a) /* 0.373134114 */, 18 }, - /* 5532 */ { MAD_F(0x05f8b9cc) /* 0.373224066 */, 18 }, - /* 5533 */ { MAD_F(0x05f91820) /* 0.373314024 */, 18 }, - /* 5534 */ { MAD_F(0x05f97675) /* 0.373403987 */, 18 }, - /* 5535 */ { MAD_F(0x05f9d4cc) /* 0.373493956 */, 18 }, - - /* 5536 */ { MAD_F(0x05fa3324) /* 0.373583930 */, 18 }, - /* 5537 */ { MAD_F(0x05fa917e) /* 0.373673910 */, 18 }, - /* 5538 */ { MAD_F(0x05faefd9) /* 0.373763895 */, 18 }, - /* 5539 */ { MAD_F(0x05fb4e36) /* 0.373853885 */, 18 }, - /* 5540 */ { MAD_F(0x05fbac94) /* 0.373943881 */, 18 }, - /* 5541 */ { MAD_F(0x05fc0af3) /* 0.374033882 */, 18 }, - /* 5542 */ { MAD_F(0x05fc6954) /* 0.374123889 */, 18 }, - /* 5543 */ { MAD_F(0x05fcc7b7) /* 0.374213901 */, 18 }, - /* 5544 */ { MAD_F(0x05fd261b) /* 0.374303918 */, 18 }, - /* 5545 */ { MAD_F(0x05fd8480) /* 0.374393941 */, 18 }, - /* 5546 */ { MAD_F(0x05fde2e7) /* 0.374483970 */, 18 }, - /* 5547 */ { MAD_F(0x05fe414f) /* 0.374574003 */, 18 }, - /* 5548 */ { MAD_F(0x05fe9fb9) /* 0.374664042 */, 18 }, - /* 5549 */ { MAD_F(0x05fefe24) /* 0.374754087 */, 18 }, - /* 5550 */ { MAD_F(0x05ff5c91) /* 0.374844137 */, 18 }, - /* 5551 */ { MAD_F(0x05ffbaff) /* 0.374934192 */, 18 }, - - /* 5552 */ { MAD_F(0x0600196e) /* 0.375024253 */, 18 }, - /* 5553 */ { MAD_F(0x060077df) /* 0.375114319 */, 18 }, - /* 5554 */ { MAD_F(0x0600d651) /* 0.375204391 */, 18 }, - /* 5555 */ { MAD_F(0x060134c5) /* 0.375294468 */, 18 }, - /* 5556 */ { MAD_F(0x0601933b) /* 0.375384550 */, 18 }, - /* 5557 */ { MAD_F(0x0601f1b1) /* 0.375474638 */, 18 }, - /* 5558 */ { MAD_F(0x0602502a) /* 0.375564731 */, 18 }, - /* 5559 */ { MAD_F(0x0602aea3) /* 0.375654830 */, 18 }, - /* 5560 */ { MAD_F(0x06030d1e) /* 0.375744934 */, 18 }, - /* 5561 */ { MAD_F(0x06036b9b) /* 0.375835043 */, 18 }, - /* 5562 */ { MAD_F(0x0603ca19) /* 0.375925158 */, 18 }, - /* 5563 */ { MAD_F(0x06042898) /* 0.376015278 */, 18 }, - /* 5564 */ { MAD_F(0x06048719) /* 0.376105404 */, 18 }, - /* 5565 */ { MAD_F(0x0604e59c) /* 0.376195535 */, 18 }, - /* 5566 */ { MAD_F(0x0605441f) /* 0.376285671 */, 18 }, - /* 5567 */ { MAD_F(0x0605a2a5) /* 0.376375813 */, 18 }, - - /* 5568 */ { MAD_F(0x0606012b) /* 0.376465960 */, 18 }, - /* 5569 */ { MAD_F(0x06065fb4) /* 0.376556113 */, 18 }, - /* 5570 */ { MAD_F(0x0606be3d) /* 0.376646271 */, 18 }, - /* 5571 */ { MAD_F(0x06071cc8) /* 0.376736434 */, 18 }, - /* 5572 */ { MAD_F(0x06077b55) /* 0.376826603 */, 18 }, - /* 5573 */ { MAD_F(0x0607d9e3) /* 0.376916777 */, 18 }, - /* 5574 */ { MAD_F(0x06083872) /* 0.377006957 */, 18 }, - /* 5575 */ { MAD_F(0x06089703) /* 0.377097141 */, 18 }, - /* 5576 */ { MAD_F(0x0608f595) /* 0.377187332 */, 18 }, - /* 5577 */ { MAD_F(0x06095429) /* 0.377277528 */, 18 }, - /* 5578 */ { MAD_F(0x0609b2be) /* 0.377367729 */, 18 }, - /* 5579 */ { MAD_F(0x060a1155) /* 0.377457935 */, 18 }, - /* 5580 */ { MAD_F(0x060a6fed) /* 0.377548147 */, 18 }, - /* 5581 */ { MAD_F(0x060ace86) /* 0.377638364 */, 18 }, - /* 5582 */ { MAD_F(0x060b2d21) /* 0.377728587 */, 18 }, - /* 5583 */ { MAD_F(0x060b8bbe) /* 0.377818815 */, 18 }, - - /* 5584 */ { MAD_F(0x060bea5c) /* 0.377909049 */, 18 }, - /* 5585 */ { MAD_F(0x060c48fb) /* 0.377999288 */, 18 }, - /* 5586 */ { MAD_F(0x060ca79c) /* 0.378089532 */, 18 }, - /* 5587 */ { MAD_F(0x060d063e) /* 0.378179781 */, 18 }, - /* 5588 */ { MAD_F(0x060d64e1) /* 0.378270036 */, 18 }, - /* 5589 */ { MAD_F(0x060dc387) /* 0.378360297 */, 18 }, - /* 5590 */ { MAD_F(0x060e222d) /* 0.378450563 */, 18 }, - /* 5591 */ { MAD_F(0x060e80d5) /* 0.378540834 */, 18 }, - /* 5592 */ { MAD_F(0x060edf7f) /* 0.378631110 */, 18 }, - /* 5593 */ { MAD_F(0x060f3e29) /* 0.378721392 */, 18 }, - /* 5594 */ { MAD_F(0x060f9cd6) /* 0.378811680 */, 18 }, - /* 5595 */ { MAD_F(0x060ffb83) /* 0.378901972 */, 18 }, - /* 5596 */ { MAD_F(0x06105a33) /* 0.378992270 */, 18 }, - /* 5597 */ { MAD_F(0x0610b8e3) /* 0.379082574 */, 18 }, - /* 5598 */ { MAD_F(0x06111795) /* 0.379172883 */, 18 }, - /* 5599 */ { MAD_F(0x06117649) /* 0.379263197 */, 18 }, - - /* 5600 */ { MAD_F(0x0611d4fe) /* 0.379353516 */, 18 }, - /* 5601 */ { MAD_F(0x061233b4) /* 0.379443841 */, 18 }, - /* 5602 */ { MAD_F(0x0612926c) /* 0.379534172 */, 18 }, - /* 5603 */ { MAD_F(0x0612f125) /* 0.379624507 */, 18 }, - /* 5604 */ { MAD_F(0x06134fe0) /* 0.379714848 */, 18 }, - /* 5605 */ { MAD_F(0x0613ae9c) /* 0.379805195 */, 18 }, - /* 5606 */ { MAD_F(0x06140d5a) /* 0.379895547 */, 18 }, - /* 5607 */ { MAD_F(0x06146c19) /* 0.379985904 */, 18 }, - /* 5608 */ { MAD_F(0x0614cada) /* 0.380076266 */, 18 }, - /* 5609 */ { MAD_F(0x0615299c) /* 0.380166634 */, 18 }, - /* 5610 */ { MAD_F(0x0615885f) /* 0.380257008 */, 18 }, - /* 5611 */ { MAD_F(0x0615e724) /* 0.380347386 */, 18 }, - /* 5612 */ { MAD_F(0x061645ea) /* 0.380437770 */, 18 }, - /* 5613 */ { MAD_F(0x0616a4b2) /* 0.380528160 */, 18 }, - /* 5614 */ { MAD_F(0x0617037b) /* 0.380618555 */, 18 }, - /* 5615 */ { MAD_F(0x06176246) /* 0.380708955 */, 18 }, - - /* 5616 */ { MAD_F(0x0617c112) /* 0.380799360 */, 18 }, - /* 5617 */ { MAD_F(0x06181fdf) /* 0.380889771 */, 18 }, - /* 5618 */ { MAD_F(0x06187eae) /* 0.380980187 */, 18 }, - /* 5619 */ { MAD_F(0x0618dd7e) /* 0.381070609 */, 18 }, - /* 5620 */ { MAD_F(0x06193c50) /* 0.381161036 */, 18 }, - /* 5621 */ { MAD_F(0x06199b24) /* 0.381251468 */, 18 }, - /* 5622 */ { MAD_F(0x0619f9f8) /* 0.381341906 */, 18 }, - /* 5623 */ { MAD_F(0x061a58ce) /* 0.381432349 */, 18 }, - /* 5624 */ { MAD_F(0x061ab7a6) /* 0.381522798 */, 18 }, - /* 5625 */ { MAD_F(0x061b167f) /* 0.381613251 */, 18 }, - /* 5626 */ { MAD_F(0x061b7559) /* 0.381703711 */, 18 }, - /* 5627 */ { MAD_F(0x061bd435) /* 0.381794175 */, 18 }, - /* 5628 */ { MAD_F(0x061c3313) /* 0.381884645 */, 18 }, - /* 5629 */ { MAD_F(0x061c91f1) /* 0.381975120 */, 18 }, - /* 5630 */ { MAD_F(0x061cf0d2) /* 0.382065601 */, 18 }, - /* 5631 */ { MAD_F(0x061d4fb3) /* 0.382156087 */, 18 }, - - /* 5632 */ { MAD_F(0x061dae96) /* 0.382246578 */, 18 }, - /* 5633 */ { MAD_F(0x061e0d7b) /* 0.382337075 */, 18 }, - /* 5634 */ { MAD_F(0x061e6c61) /* 0.382427577 */, 18 }, - /* 5635 */ { MAD_F(0x061ecb48) /* 0.382518084 */, 18 }, - /* 5636 */ { MAD_F(0x061f2a31) /* 0.382608597 */, 18 }, - /* 5637 */ { MAD_F(0x061f891b) /* 0.382699115 */, 18 }, - /* 5638 */ { MAD_F(0x061fe807) /* 0.382789638 */, 18 }, - /* 5639 */ { MAD_F(0x062046f4) /* 0.382880167 */, 18 }, - /* 5640 */ { MAD_F(0x0620a5e3) /* 0.382970701 */, 18 }, - /* 5641 */ { MAD_F(0x062104d3) /* 0.383061241 */, 18 }, - /* 5642 */ { MAD_F(0x062163c4) /* 0.383151786 */, 18 }, - /* 5643 */ { MAD_F(0x0621c2b7) /* 0.383242336 */, 18 }, - /* 5644 */ { MAD_F(0x062221ab) /* 0.383332891 */, 18 }, - /* 5645 */ { MAD_F(0x062280a1) /* 0.383423452 */, 18 }, - /* 5646 */ { MAD_F(0x0622df98) /* 0.383514018 */, 18 }, - /* 5647 */ { MAD_F(0x06233e91) /* 0.383604590 */, 18 }, - - /* 5648 */ { MAD_F(0x06239d8b) /* 0.383695167 */, 18 }, - /* 5649 */ { MAD_F(0x0623fc86) /* 0.383785749 */, 18 }, - /* 5650 */ { MAD_F(0x06245b83) /* 0.383876337 */, 18 }, - /* 5651 */ { MAD_F(0x0624ba82) /* 0.383966930 */, 18 }, - /* 5652 */ { MAD_F(0x06251981) /* 0.384057528 */, 18 }, - /* 5653 */ { MAD_F(0x06257883) /* 0.384148132 */, 18 }, - /* 5654 */ { MAD_F(0x0625d785) /* 0.384238741 */, 18 }, - /* 5655 */ { MAD_F(0x06263689) /* 0.384329355 */, 18 }, - /* 5656 */ { MAD_F(0x0626958f) /* 0.384419975 */, 18 }, - /* 5657 */ { MAD_F(0x0626f496) /* 0.384510600 */, 18 }, - /* 5658 */ { MAD_F(0x0627539e) /* 0.384601230 */, 18 }, - /* 5659 */ { MAD_F(0x0627b2a8) /* 0.384691866 */, 18 }, - /* 5660 */ { MAD_F(0x062811b3) /* 0.384782507 */, 18 }, - /* 5661 */ { MAD_F(0x062870c0) /* 0.384873153 */, 18 }, - /* 5662 */ { MAD_F(0x0628cfce) /* 0.384963805 */, 18 }, - /* 5663 */ { MAD_F(0x06292ede) /* 0.385054462 */, 18 }, - - /* 5664 */ { MAD_F(0x06298def) /* 0.385145124 */, 18 }, - /* 5665 */ { MAD_F(0x0629ed01) /* 0.385235792 */, 18 }, - /* 5666 */ { MAD_F(0x062a4c15) /* 0.385326465 */, 18 }, - /* 5667 */ { MAD_F(0x062aab2a) /* 0.385417143 */, 18 }, - /* 5668 */ { MAD_F(0x062b0a41) /* 0.385507827 */, 18 }, - /* 5669 */ { MAD_F(0x062b6959) /* 0.385598516 */, 18 }, - /* 5670 */ { MAD_F(0x062bc873) /* 0.385689211 */, 18 }, - /* 5671 */ { MAD_F(0x062c278e) /* 0.385779910 */, 18 }, - /* 5672 */ { MAD_F(0x062c86aa) /* 0.385870615 */, 18 }, - /* 5673 */ { MAD_F(0x062ce5c8) /* 0.385961326 */, 18 }, - /* 5674 */ { MAD_F(0x062d44e8) /* 0.386052041 */, 18 }, - /* 5675 */ { MAD_F(0x062da408) /* 0.386142762 */, 18 }, - /* 5676 */ { MAD_F(0x062e032a) /* 0.386233489 */, 18 }, - /* 5677 */ { MAD_F(0x062e624e) /* 0.386324221 */, 18 }, - /* 5678 */ { MAD_F(0x062ec173) /* 0.386414958 */, 18 }, - /* 5679 */ { MAD_F(0x062f209a) /* 0.386505700 */, 18 }, - - /* 5680 */ { MAD_F(0x062f7fc1) /* 0.386596448 */, 18 }, - /* 5681 */ { MAD_F(0x062fdeeb) /* 0.386687201 */, 18 }, - /* 5682 */ { MAD_F(0x06303e16) /* 0.386777959 */, 18 }, - /* 5683 */ { MAD_F(0x06309d42) /* 0.386868723 */, 18 }, - /* 5684 */ { MAD_F(0x0630fc6f) /* 0.386959492 */, 18 }, - /* 5685 */ { MAD_F(0x06315b9e) /* 0.387050266 */, 18 }, - /* 5686 */ { MAD_F(0x0631bacf) /* 0.387141045 */, 18 }, - /* 5687 */ { MAD_F(0x06321a01) /* 0.387231830 */, 18 }, - /* 5688 */ { MAD_F(0x06327934) /* 0.387322621 */, 18 }, - /* 5689 */ { MAD_F(0x0632d869) /* 0.387413416 */, 18 }, - /* 5690 */ { MAD_F(0x0633379f) /* 0.387504217 */, 18 }, - /* 5691 */ { MAD_F(0x063396d7) /* 0.387595023 */, 18 }, - /* 5692 */ { MAD_F(0x0633f610) /* 0.387685835 */, 18 }, - /* 5693 */ { MAD_F(0x0634554a) /* 0.387776652 */, 18 }, - /* 5694 */ { MAD_F(0x0634b486) /* 0.387867474 */, 18 }, - /* 5695 */ { MAD_F(0x063513c3) /* 0.387958301 */, 18 }, - - /* 5696 */ { MAD_F(0x06357302) /* 0.388049134 */, 18 }, - /* 5697 */ { MAD_F(0x0635d242) /* 0.388139972 */, 18 }, - /* 5698 */ { MAD_F(0x06363184) /* 0.388230816 */, 18 }, - /* 5699 */ { MAD_F(0x063690c7) /* 0.388321665 */, 18 }, - /* 5700 */ { MAD_F(0x0636f00b) /* 0.388412519 */, 18 }, - /* 5701 */ { MAD_F(0x06374f51) /* 0.388503378 */, 18 }, - /* 5702 */ { MAD_F(0x0637ae99) /* 0.388594243 */, 18 }, - /* 5703 */ { MAD_F(0x06380de1) /* 0.388685113 */, 18 }, - /* 5704 */ { MAD_F(0x06386d2b) /* 0.388775988 */, 18 }, - /* 5705 */ { MAD_F(0x0638cc77) /* 0.388866869 */, 18 }, - /* 5706 */ { MAD_F(0x06392bc4) /* 0.388957755 */, 18 }, - /* 5707 */ { MAD_F(0x06398b12) /* 0.389048646 */, 18 }, - /* 5708 */ { MAD_F(0x0639ea62) /* 0.389139542 */, 18 }, - /* 5709 */ { MAD_F(0x063a49b4) /* 0.389230444 */, 18 }, - /* 5710 */ { MAD_F(0x063aa906) /* 0.389321352 */, 18 }, - /* 5711 */ { MAD_F(0x063b085a) /* 0.389412264 */, 18 }, - - /* 5712 */ { MAD_F(0x063b67b0) /* 0.389503182 */, 18 }, - /* 5713 */ { MAD_F(0x063bc707) /* 0.389594105 */, 18 }, - /* 5714 */ { MAD_F(0x063c265f) /* 0.389685033 */, 18 }, - /* 5715 */ { MAD_F(0x063c85b9) /* 0.389775967 */, 18 }, - /* 5716 */ { MAD_F(0x063ce514) /* 0.389866906 */, 18 }, - /* 5717 */ { MAD_F(0x063d4471) /* 0.389957850 */, 18 }, - /* 5718 */ { MAD_F(0x063da3cf) /* 0.390048800 */, 18 }, - /* 5719 */ { MAD_F(0x063e032f) /* 0.390139755 */, 18 }, - /* 5720 */ { MAD_F(0x063e6290) /* 0.390230715 */, 18 }, - /* 5721 */ { MAD_F(0x063ec1f2) /* 0.390321681 */, 18 }, - /* 5722 */ { MAD_F(0x063f2156) /* 0.390412651 */, 18 }, - /* 5723 */ { MAD_F(0x063f80bb) /* 0.390503628 */, 18 }, - /* 5724 */ { MAD_F(0x063fe022) /* 0.390594609 */, 18 }, - /* 5725 */ { MAD_F(0x06403f8a) /* 0.390685596 */, 18 }, - /* 5726 */ { MAD_F(0x06409ef3) /* 0.390776588 */, 18 }, - /* 5727 */ { MAD_F(0x0640fe5e) /* 0.390867585 */, 18 }, - - /* 5728 */ { MAD_F(0x06415dcb) /* 0.390958588 */, 18 }, - /* 5729 */ { MAD_F(0x0641bd38) /* 0.391049596 */, 18 }, - /* 5730 */ { MAD_F(0x06421ca7) /* 0.391140609 */, 18 }, - /* 5731 */ { MAD_F(0x06427c18) /* 0.391231627 */, 18 }, - /* 5732 */ { MAD_F(0x0642db8a) /* 0.391322651 */, 18 }, - /* 5733 */ { MAD_F(0x06433afd) /* 0.391413680 */, 18 }, - /* 5734 */ { MAD_F(0x06439a72) /* 0.391504714 */, 18 }, - /* 5735 */ { MAD_F(0x0643f9e9) /* 0.391595754 */, 18 }, - /* 5736 */ { MAD_F(0x06445960) /* 0.391686799 */, 18 }, - /* 5737 */ { MAD_F(0x0644b8d9) /* 0.391777849 */, 18 }, - /* 5738 */ { MAD_F(0x06451854) /* 0.391868905 */, 18 }, - /* 5739 */ { MAD_F(0x064577d0) /* 0.391959966 */, 18 }, - /* 5740 */ { MAD_F(0x0645d74d) /* 0.392051032 */, 18 }, - /* 5741 */ { MAD_F(0x064636cc) /* 0.392142103 */, 18 }, - /* 5742 */ { MAD_F(0x0646964c) /* 0.392233180 */, 18 }, - /* 5743 */ { MAD_F(0x0646f5ce) /* 0.392324262 */, 18 }, - - /* 5744 */ { MAD_F(0x06475551) /* 0.392415349 */, 18 }, - /* 5745 */ { MAD_F(0x0647b4d5) /* 0.392506442 */, 18 }, - /* 5746 */ { MAD_F(0x0648145b) /* 0.392597540 */, 18 }, - /* 5747 */ { MAD_F(0x064873e3) /* 0.392688643 */, 18 }, - /* 5748 */ { MAD_F(0x0648d36b) /* 0.392779751 */, 18 }, - /* 5749 */ { MAD_F(0x064932f6) /* 0.392870865 */, 18 }, - /* 5750 */ { MAD_F(0x06499281) /* 0.392961984 */, 18 }, - /* 5751 */ { MAD_F(0x0649f20e) /* 0.393053108 */, 18 }, - /* 5752 */ { MAD_F(0x064a519c) /* 0.393144238 */, 18 }, - /* 5753 */ { MAD_F(0x064ab12c) /* 0.393235372 */, 18 }, - /* 5754 */ { MAD_F(0x064b10be) /* 0.393326513 */, 18 }, - /* 5755 */ { MAD_F(0x064b7050) /* 0.393417658 */, 18 }, - /* 5756 */ { MAD_F(0x064bcfe4) /* 0.393508809 */, 18 }, - /* 5757 */ { MAD_F(0x064c2f7a) /* 0.393599965 */, 18 }, - /* 5758 */ { MAD_F(0x064c8f11) /* 0.393691126 */, 18 }, - /* 5759 */ { MAD_F(0x064ceea9) /* 0.393782292 */, 18 }, - - /* 5760 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 18 }, - /* 5761 */ { MAD_F(0x064dadde) /* 0.393964641 */, 18 }, - /* 5762 */ { MAD_F(0x064e0d7a) /* 0.394055823 */, 18 }, - /* 5763 */ { MAD_F(0x064e6d18) /* 0.394147011 */, 18 }, - /* 5764 */ { MAD_F(0x064eccb8) /* 0.394238204 */, 18 }, - /* 5765 */ { MAD_F(0x064f2c59) /* 0.394329402 */, 18 }, - /* 5766 */ { MAD_F(0x064f8bfb) /* 0.394420605 */, 18 }, - /* 5767 */ { MAD_F(0x064feb9e) /* 0.394511814 */, 18 }, - /* 5768 */ { MAD_F(0x06504b44) /* 0.394603028 */, 18 }, - /* 5769 */ { MAD_F(0x0650aaea) /* 0.394694247 */, 18 }, - /* 5770 */ { MAD_F(0x06510a92) /* 0.394785472 */, 18 }, - /* 5771 */ { MAD_F(0x06516a3b) /* 0.394876702 */, 18 }, - /* 5772 */ { MAD_F(0x0651c9e6) /* 0.394967937 */, 18 }, - /* 5773 */ { MAD_F(0x06522992) /* 0.395059177 */, 18 }, - /* 5774 */ { MAD_F(0x06528940) /* 0.395150423 */, 18 }, - /* 5775 */ { MAD_F(0x0652e8ef) /* 0.395241673 */, 18 }, - - /* 5776 */ { MAD_F(0x0653489f) /* 0.395332930 */, 18 }, - /* 5777 */ { MAD_F(0x0653a851) /* 0.395424191 */, 18 }, - /* 5778 */ { MAD_F(0x06540804) /* 0.395515458 */, 18 }, - /* 5779 */ { MAD_F(0x065467b9) /* 0.395606730 */, 18 }, - /* 5780 */ { MAD_F(0x0654c76f) /* 0.395698007 */, 18 }, - /* 5781 */ { MAD_F(0x06552726) /* 0.395789289 */, 18 }, - /* 5782 */ { MAD_F(0x065586df) /* 0.395880577 */, 18 }, - /* 5783 */ { MAD_F(0x0655e699) /* 0.395971870 */, 18 }, - /* 5784 */ { MAD_F(0x06564655) /* 0.396063168 */, 18 }, - /* 5785 */ { MAD_F(0x0656a612) /* 0.396154472 */, 18 }, - /* 5786 */ { MAD_F(0x065705d0) /* 0.396245780 */, 18 }, - /* 5787 */ { MAD_F(0x06576590) /* 0.396337094 */, 18 }, - /* 5788 */ { MAD_F(0x0657c552) /* 0.396428414 */, 18 }, - /* 5789 */ { MAD_F(0x06582514) /* 0.396519738 */, 18 }, - /* 5790 */ { MAD_F(0x065884d9) /* 0.396611068 */, 18 }, - /* 5791 */ { MAD_F(0x0658e49e) /* 0.396702403 */, 18 }, - - /* 5792 */ { MAD_F(0x06594465) /* 0.396793743 */, 18 }, - /* 5793 */ { MAD_F(0x0659a42e) /* 0.396885089 */, 18 }, - /* 5794 */ { MAD_F(0x065a03f7) /* 0.396976440 */, 18 }, - /* 5795 */ { MAD_F(0x065a63c3) /* 0.397067796 */, 18 }, - /* 5796 */ { MAD_F(0x065ac38f) /* 0.397159157 */, 18 }, - /* 5797 */ { MAD_F(0x065b235d) /* 0.397250524 */, 18 }, - /* 5798 */ { MAD_F(0x065b832d) /* 0.397341896 */, 18 }, - /* 5799 */ { MAD_F(0x065be2fe) /* 0.397433273 */, 18 }, - /* 5800 */ { MAD_F(0x065c42d0) /* 0.397524655 */, 18 }, - /* 5801 */ { MAD_F(0x065ca2a3) /* 0.397616043 */, 18 }, - /* 5802 */ { MAD_F(0x065d0279) /* 0.397707436 */, 18 }, - /* 5803 */ { MAD_F(0x065d624f) /* 0.397798834 */, 18 }, - /* 5804 */ { MAD_F(0x065dc227) /* 0.397890237 */, 18 }, - /* 5805 */ { MAD_F(0x065e2200) /* 0.397981646 */, 18 }, - /* 5806 */ { MAD_F(0x065e81db) /* 0.398073059 */, 18 }, - /* 5807 */ { MAD_F(0x065ee1b7) /* 0.398164479 */, 18 }, - - /* 5808 */ { MAD_F(0x065f4195) /* 0.398255903 */, 18 }, - /* 5809 */ { MAD_F(0x065fa174) /* 0.398347333 */, 18 }, - /* 5810 */ { MAD_F(0x06600154) /* 0.398438767 */, 18 }, - /* 5811 */ { MAD_F(0x06606136) /* 0.398530207 */, 18 }, - /* 5812 */ { MAD_F(0x0660c119) /* 0.398621653 */, 18 }, - /* 5813 */ { MAD_F(0x066120fd) /* 0.398713103 */, 18 }, - /* 5814 */ { MAD_F(0x066180e3) /* 0.398804559 */, 18 }, - /* 5815 */ { MAD_F(0x0661e0cb) /* 0.398896020 */, 18 }, - /* 5816 */ { MAD_F(0x066240b4) /* 0.398987487 */, 18 }, - /* 5817 */ { MAD_F(0x0662a09e) /* 0.399078958 */, 18 }, - /* 5818 */ { MAD_F(0x06630089) /* 0.399170435 */, 18 }, - /* 5819 */ { MAD_F(0x06636077) /* 0.399261917 */, 18 }, - /* 5820 */ { MAD_F(0x0663c065) /* 0.399353404 */, 18 }, - /* 5821 */ { MAD_F(0x06642055) /* 0.399444897 */, 18 }, - /* 5822 */ { MAD_F(0x06648046) /* 0.399536395 */, 18 }, - /* 5823 */ { MAD_F(0x0664e039) /* 0.399627898 */, 18 }, - - /* 5824 */ { MAD_F(0x0665402d) /* 0.399719406 */, 18 }, - /* 5825 */ { MAD_F(0x0665a022) /* 0.399810919 */, 18 }, - /* 5826 */ { MAD_F(0x06660019) /* 0.399902438 */, 18 }, - /* 5827 */ { MAD_F(0x06666011) /* 0.399993962 */, 18 }, - /* 5828 */ { MAD_F(0x0666c00b) /* 0.400085491 */, 18 }, - /* 5829 */ { MAD_F(0x06672006) /* 0.400177026 */, 18 }, - /* 5830 */ { MAD_F(0x06678003) /* 0.400268565 */, 18 }, - /* 5831 */ { MAD_F(0x0667e000) /* 0.400360110 */, 18 }, - /* 5832 */ { MAD_F(0x06684000) /* 0.400451660 */, 18 }, - /* 5833 */ { MAD_F(0x0668a000) /* 0.400543216 */, 18 }, - /* 5834 */ { MAD_F(0x06690003) /* 0.400634776 */, 18 }, - /* 5835 */ { MAD_F(0x06696006) /* 0.400726342 */, 18 }, - /* 5836 */ { MAD_F(0x0669c00b) /* 0.400817913 */, 18 }, - /* 5837 */ { MAD_F(0x066a2011) /* 0.400909489 */, 18 }, - /* 5838 */ { MAD_F(0x066a8019) /* 0.401001071 */, 18 }, - /* 5839 */ { MAD_F(0x066ae022) /* 0.401092657 */, 18 }, - - /* 5840 */ { MAD_F(0x066b402d) /* 0.401184249 */, 18 }, - /* 5841 */ { MAD_F(0x066ba039) /* 0.401275847 */, 18 }, - /* 5842 */ { MAD_F(0x066c0046) /* 0.401367449 */, 18 }, - /* 5843 */ { MAD_F(0x066c6055) /* 0.401459057 */, 18 }, - /* 5844 */ { MAD_F(0x066cc065) /* 0.401550670 */, 18 }, - /* 5845 */ { MAD_F(0x066d2076) /* 0.401642288 */, 18 }, - /* 5846 */ { MAD_F(0x066d8089) /* 0.401733911 */, 18 }, - /* 5847 */ { MAD_F(0x066de09e) /* 0.401825540 */, 18 }, - /* 5848 */ { MAD_F(0x066e40b3) /* 0.401917173 */, 18 }, - /* 5849 */ { MAD_F(0x066ea0cb) /* 0.402008812 */, 18 }, - /* 5850 */ { MAD_F(0x066f00e3) /* 0.402100457 */, 18 }, - /* 5851 */ { MAD_F(0x066f60fd) /* 0.402192106 */, 18 }, - /* 5852 */ { MAD_F(0x066fc118) /* 0.402283761 */, 18 }, - /* 5853 */ { MAD_F(0x06702135) /* 0.402375420 */, 18 }, - /* 5854 */ { MAD_F(0x06708153) /* 0.402467086 */, 18 }, - /* 5855 */ { MAD_F(0x0670e173) /* 0.402558756 */, 18 }, - - /* 5856 */ { MAD_F(0x06714194) /* 0.402650431 */, 18 }, - /* 5857 */ { MAD_F(0x0671a1b6) /* 0.402742112 */, 18 }, - /* 5858 */ { MAD_F(0x067201da) /* 0.402833798 */, 18 }, - /* 5859 */ { MAD_F(0x067261ff) /* 0.402925489 */, 18 }, - /* 5860 */ { MAD_F(0x0672c226) /* 0.403017186 */, 18 }, - /* 5861 */ { MAD_F(0x0673224e) /* 0.403108887 */, 18 }, - /* 5862 */ { MAD_F(0x06738277) /* 0.403200594 */, 18 }, - /* 5863 */ { MAD_F(0x0673e2a2) /* 0.403292306 */, 18 }, - /* 5864 */ { MAD_F(0x067442ce) /* 0.403384024 */, 18 }, - /* 5865 */ { MAD_F(0x0674a2fc) /* 0.403475746 */, 18 }, - /* 5866 */ { MAD_F(0x0675032b) /* 0.403567474 */, 18 }, - /* 5867 */ { MAD_F(0x0675635b) /* 0.403659207 */, 18 }, - /* 5868 */ { MAD_F(0x0675c38d) /* 0.403750945 */, 18 }, - /* 5869 */ { MAD_F(0x067623c0) /* 0.403842688 */, 18 }, - /* 5870 */ { MAD_F(0x067683f4) /* 0.403934437 */, 18 }, - /* 5871 */ { MAD_F(0x0676e42a) /* 0.404026190 */, 18 }, - - /* 5872 */ { MAD_F(0x06774462) /* 0.404117949 */, 18 }, - /* 5873 */ { MAD_F(0x0677a49b) /* 0.404209714 */, 18 }, - /* 5874 */ { MAD_F(0x067804d5) /* 0.404301483 */, 18 }, - /* 5875 */ { MAD_F(0x06786510) /* 0.404393258 */, 18 }, - /* 5876 */ { MAD_F(0x0678c54d) /* 0.404485037 */, 18 }, - /* 5877 */ { MAD_F(0x0679258c) /* 0.404576822 */, 18 }, - /* 5878 */ { MAD_F(0x067985cb) /* 0.404668613 */, 18 }, - /* 5879 */ { MAD_F(0x0679e60c) /* 0.404760408 */, 18 }, - /* 5880 */ { MAD_F(0x067a464f) /* 0.404852209 */, 18 }, - /* 5881 */ { MAD_F(0x067aa693) /* 0.404944014 */, 18 }, - /* 5882 */ { MAD_F(0x067b06d8) /* 0.405035825 */, 18 }, - /* 5883 */ { MAD_F(0x067b671f) /* 0.405127642 */, 18 }, - /* 5884 */ { MAD_F(0x067bc767) /* 0.405219463 */, 18 }, - /* 5885 */ { MAD_F(0x067c27b1) /* 0.405311290 */, 18 }, - /* 5886 */ { MAD_F(0x067c87fc) /* 0.405403122 */, 18 }, - /* 5887 */ { MAD_F(0x067ce848) /* 0.405494959 */, 18 }, - - /* 5888 */ { MAD_F(0x067d4896) /* 0.405586801 */, 18 }, - /* 5889 */ { MAD_F(0x067da8e5) /* 0.405678648 */, 18 }, - /* 5890 */ { MAD_F(0x067e0935) /* 0.405770501 */, 18 }, - /* 5891 */ { MAD_F(0x067e6987) /* 0.405862359 */, 18 }, - /* 5892 */ { MAD_F(0x067ec9da) /* 0.405954222 */, 18 }, - /* 5893 */ { MAD_F(0x067f2a2f) /* 0.406046090 */, 18 }, - /* 5894 */ { MAD_F(0x067f8a85) /* 0.406137963 */, 18 }, - /* 5895 */ { MAD_F(0x067feadd) /* 0.406229842 */, 18 }, - /* 5896 */ { MAD_F(0x06804b36) /* 0.406321726 */, 18 }, - /* 5897 */ { MAD_F(0x0680ab90) /* 0.406413615 */, 18 }, - /* 5898 */ { MAD_F(0x06810beb) /* 0.406505509 */, 18 }, - /* 5899 */ { MAD_F(0x06816c49) /* 0.406597408 */, 18 }, - /* 5900 */ { MAD_F(0x0681cca7) /* 0.406689313 */, 18 }, - /* 5901 */ { MAD_F(0x06822d07) /* 0.406781223 */, 18 }, - /* 5902 */ { MAD_F(0x06828d68) /* 0.406873138 */, 18 }, - /* 5903 */ { MAD_F(0x0682edcb) /* 0.406965058 */, 18 }, - - /* 5904 */ { MAD_F(0x06834e2f) /* 0.407056983 */, 18 }, - /* 5905 */ { MAD_F(0x0683ae94) /* 0.407148914 */, 18 }, - /* 5906 */ { MAD_F(0x06840efb) /* 0.407240850 */, 18 }, - /* 5907 */ { MAD_F(0x06846f63) /* 0.407332791 */, 18 }, - /* 5908 */ { MAD_F(0x0684cfcd) /* 0.407424737 */, 18 }, - /* 5909 */ { MAD_F(0x06853038) /* 0.407516688 */, 18 }, - /* 5910 */ { MAD_F(0x068590a4) /* 0.407608645 */, 18 }, - /* 5911 */ { MAD_F(0x0685f112) /* 0.407700606 */, 18 }, - /* 5912 */ { MAD_F(0x06865181) /* 0.407792573 */, 18 }, - /* 5913 */ { MAD_F(0x0686b1f2) /* 0.407884545 */, 18 }, - /* 5914 */ { MAD_F(0x06871264) /* 0.407976522 */, 18 }, - /* 5915 */ { MAD_F(0x068772d7) /* 0.408068505 */, 18 }, - /* 5916 */ { MAD_F(0x0687d34c) /* 0.408160492 */, 18 }, - /* 5917 */ { MAD_F(0x068833c2) /* 0.408252485 */, 18 }, - /* 5918 */ { MAD_F(0x06889439) /* 0.408344483 */, 18 }, - /* 5919 */ { MAD_F(0x0688f4b2) /* 0.408436486 */, 18 }, - - /* 5920 */ { MAD_F(0x0689552c) /* 0.408528495 */, 18 }, - /* 5921 */ { MAD_F(0x0689b5a8) /* 0.408620508 */, 18 }, - /* 5922 */ { MAD_F(0x068a1625) /* 0.408712527 */, 18 }, - /* 5923 */ { MAD_F(0x068a76a4) /* 0.408804551 */, 18 }, - /* 5924 */ { MAD_F(0x068ad724) /* 0.408896580 */, 18 }, - /* 5925 */ { MAD_F(0x068b37a5) /* 0.408988614 */, 18 }, - /* 5926 */ { MAD_F(0x068b9827) /* 0.409080653 */, 18 }, - /* 5927 */ { MAD_F(0x068bf8ac) /* 0.409172698 */, 18 }, - /* 5928 */ { MAD_F(0x068c5931) /* 0.409264748 */, 18 }, - /* 5929 */ { MAD_F(0x068cb9b8) /* 0.409356803 */, 18 }, - /* 5930 */ { MAD_F(0x068d1a40) /* 0.409448863 */, 18 }, - /* 5931 */ { MAD_F(0x068d7aca) /* 0.409540928 */, 18 }, - /* 5932 */ { MAD_F(0x068ddb54) /* 0.409632999 */, 18 }, - /* 5933 */ { MAD_F(0x068e3be1) /* 0.409725074 */, 18 }, - /* 5934 */ { MAD_F(0x068e9c6f) /* 0.409817155 */, 18 }, - /* 5935 */ { MAD_F(0x068efcfe) /* 0.409909241 */, 18 }, - - /* 5936 */ { MAD_F(0x068f5d8e) /* 0.410001332 */, 18 }, - /* 5937 */ { MAD_F(0x068fbe20) /* 0.410093428 */, 18 }, - /* 5938 */ { MAD_F(0x06901eb4) /* 0.410185530 */, 18 }, - /* 5939 */ { MAD_F(0x06907f48) /* 0.410277637 */, 18 }, - /* 5940 */ { MAD_F(0x0690dfde) /* 0.410369748 */, 18 }, - /* 5941 */ { MAD_F(0x06914076) /* 0.410461865 */, 18 }, - /* 5942 */ { MAD_F(0x0691a10f) /* 0.410553988 */, 18 }, - /* 5943 */ { MAD_F(0x069201a9) /* 0.410646115 */, 18 }, - /* 5944 */ { MAD_F(0x06926245) /* 0.410738247 */, 18 }, - /* 5945 */ { MAD_F(0x0692c2e2) /* 0.410830385 */, 18 }, - /* 5946 */ { MAD_F(0x06932380) /* 0.410922528 */, 18 }, - /* 5947 */ { MAD_F(0x06938420) /* 0.411014676 */, 18 }, - /* 5948 */ { MAD_F(0x0693e4c1) /* 0.411106829 */, 18 }, - /* 5949 */ { MAD_F(0x06944563) /* 0.411198987 */, 18 }, - /* 5950 */ { MAD_F(0x0694a607) /* 0.411291151 */, 18 }, - /* 5951 */ { MAD_F(0x069506ad) /* 0.411383320 */, 18 }, - - /* 5952 */ { MAD_F(0x06956753) /* 0.411475493 */, 18 }, - /* 5953 */ { MAD_F(0x0695c7fc) /* 0.411567672 */, 18 }, - /* 5954 */ { MAD_F(0x069628a5) /* 0.411659857 */, 18 }, - /* 5955 */ { MAD_F(0x06968950) /* 0.411752046 */, 18 }, - /* 5956 */ { MAD_F(0x0696e9fc) /* 0.411844240 */, 18 }, - /* 5957 */ { MAD_F(0x06974aaa) /* 0.411936440 */, 18 }, - /* 5958 */ { MAD_F(0x0697ab59) /* 0.412028645 */, 18 }, - /* 5959 */ { MAD_F(0x06980c09) /* 0.412120855 */, 18 }, - /* 5960 */ { MAD_F(0x06986cbb) /* 0.412213070 */, 18 }, - /* 5961 */ { MAD_F(0x0698cd6e) /* 0.412305290 */, 18 }, - /* 5962 */ { MAD_F(0x06992e23) /* 0.412397516 */, 18 }, - /* 5963 */ { MAD_F(0x06998ed9) /* 0.412489746 */, 18 }, - /* 5964 */ { MAD_F(0x0699ef90) /* 0.412581982 */, 18 }, - /* 5965 */ { MAD_F(0x069a5049) /* 0.412674223 */, 18 }, - /* 5966 */ { MAD_F(0x069ab103) /* 0.412766469 */, 18 }, - /* 5967 */ { MAD_F(0x069b11bf) /* 0.412858720 */, 18 }, - - /* 5968 */ { MAD_F(0x069b727b) /* 0.412950976 */, 18 }, - /* 5969 */ { MAD_F(0x069bd33a) /* 0.413043238 */, 18 }, - /* 5970 */ { MAD_F(0x069c33f9) /* 0.413135505 */, 18 }, - /* 5971 */ { MAD_F(0x069c94ba) /* 0.413227776 */, 18 }, - /* 5972 */ { MAD_F(0x069cf57d) /* 0.413320053 */, 18 }, - /* 5973 */ { MAD_F(0x069d5641) /* 0.413412335 */, 18 }, - /* 5974 */ { MAD_F(0x069db706) /* 0.413504623 */, 18 }, - /* 5975 */ { MAD_F(0x069e17cc) /* 0.413596915 */, 18 }, - /* 5976 */ { MAD_F(0x069e7894) /* 0.413689213 */, 18 }, - /* 5977 */ { MAD_F(0x069ed95e) /* 0.413781515 */, 18 }, - /* 5978 */ { MAD_F(0x069f3a28) /* 0.413873823 */, 18 }, - /* 5979 */ { MAD_F(0x069f9af4) /* 0.413966136 */, 18 }, - /* 5980 */ { MAD_F(0x069ffbc2) /* 0.414058454 */, 18 }, - /* 5981 */ { MAD_F(0x06a05c91) /* 0.414150778 */, 18 }, - /* 5982 */ { MAD_F(0x06a0bd61) /* 0.414243106 */, 18 }, - /* 5983 */ { MAD_F(0x06a11e32) /* 0.414335440 */, 18 }, - - /* 5984 */ { MAD_F(0x06a17f05) /* 0.414427779 */, 18 }, - /* 5985 */ { MAD_F(0x06a1dfda) /* 0.414520122 */, 18 }, - /* 5986 */ { MAD_F(0x06a240b0) /* 0.414612471 */, 18 }, - /* 5987 */ { MAD_F(0x06a2a187) /* 0.414704826 */, 18 }, - /* 5988 */ { MAD_F(0x06a3025f) /* 0.414797185 */, 18 }, - /* 5989 */ { MAD_F(0x06a36339) /* 0.414889549 */, 18 }, - /* 5990 */ { MAD_F(0x06a3c414) /* 0.414981919 */, 18 }, - /* 5991 */ { MAD_F(0x06a424f1) /* 0.415074294 */, 18 }, - /* 5992 */ { MAD_F(0x06a485cf) /* 0.415166674 */, 18 }, - /* 5993 */ { MAD_F(0x06a4e6ae) /* 0.415259059 */, 18 }, - /* 5994 */ { MAD_F(0x06a5478f) /* 0.415351449 */, 18 }, - /* 5995 */ { MAD_F(0x06a5a871) /* 0.415443844 */, 18 }, - /* 5996 */ { MAD_F(0x06a60955) /* 0.415536244 */, 18 }, - /* 5997 */ { MAD_F(0x06a66a3a) /* 0.415628650 */, 18 }, - /* 5998 */ { MAD_F(0x06a6cb20) /* 0.415721061 */, 18 }, - /* 5999 */ { MAD_F(0x06a72c08) /* 0.415813476 */, 18 }, - - /* 6000 */ { MAD_F(0x06a78cf1) /* 0.415905897 */, 18 }, - /* 6001 */ { MAD_F(0x06a7eddb) /* 0.415998324 */, 18 }, - /* 6002 */ { MAD_F(0x06a84ec7) /* 0.416090755 */, 18 }, - /* 6003 */ { MAD_F(0x06a8afb4) /* 0.416183191 */, 18 }, - /* 6004 */ { MAD_F(0x06a910a3) /* 0.416275633 */, 18 }, - /* 6005 */ { MAD_F(0x06a97193) /* 0.416368079 */, 18 }, - /* 6006 */ { MAD_F(0x06a9d284) /* 0.416460531 */, 18 }, - /* 6007 */ { MAD_F(0x06aa3377) /* 0.416552988 */, 18 }, - /* 6008 */ { MAD_F(0x06aa946b) /* 0.416645450 */, 18 }, - /* 6009 */ { MAD_F(0x06aaf561) /* 0.416737917 */, 18 }, - /* 6010 */ { MAD_F(0x06ab5657) /* 0.416830389 */, 18 }, - /* 6011 */ { MAD_F(0x06abb750) /* 0.416922867 */, 18 }, - /* 6012 */ { MAD_F(0x06ac1849) /* 0.417015349 */, 18 }, - /* 6013 */ { MAD_F(0x06ac7944) /* 0.417107837 */, 18 }, - /* 6014 */ { MAD_F(0x06acda41) /* 0.417200330 */, 18 }, - /* 6015 */ { MAD_F(0x06ad3b3e) /* 0.417292828 */, 18 }, - - /* 6016 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 18 }, - /* 6017 */ { MAD_F(0x06adfd3e) /* 0.417477839 */, 18 }, - /* 6018 */ { MAD_F(0x06ae5e40) /* 0.417570352 */, 18 }, - /* 6019 */ { MAD_F(0x06aebf43) /* 0.417662871 */, 18 }, - /* 6020 */ { MAD_F(0x06af2047) /* 0.417755394 */, 18 }, - /* 6021 */ { MAD_F(0x06af814d) /* 0.417847923 */, 18 }, - /* 6022 */ { MAD_F(0x06afe255) /* 0.417940457 */, 18 }, - /* 6023 */ { MAD_F(0x06b0435e) /* 0.418032996 */, 18 }, - /* 6024 */ { MAD_F(0x06b0a468) /* 0.418125540 */, 18 }, - /* 6025 */ { MAD_F(0x06b10573) /* 0.418218089 */, 18 }, - /* 6026 */ { MAD_F(0x06b16680) /* 0.418310643 */, 18 }, - /* 6027 */ { MAD_F(0x06b1c78e) /* 0.418403203 */, 18 }, - /* 6028 */ { MAD_F(0x06b2289e) /* 0.418495767 */, 18 }, - /* 6029 */ { MAD_F(0x06b289af) /* 0.418588337 */, 18 }, - /* 6030 */ { MAD_F(0x06b2eac1) /* 0.418680911 */, 18 }, - /* 6031 */ { MAD_F(0x06b34bd5) /* 0.418773491 */, 18 }, - - /* 6032 */ { MAD_F(0x06b3acea) /* 0.418866076 */, 18 }, - /* 6033 */ { MAD_F(0x06b40e00) /* 0.418958666 */, 18 }, - /* 6034 */ { MAD_F(0x06b46f18) /* 0.419051262 */, 18 }, - /* 6035 */ { MAD_F(0x06b4d031) /* 0.419143862 */, 18 }, - /* 6036 */ { MAD_F(0x06b5314c) /* 0.419236467 */, 18 }, - /* 6037 */ { MAD_F(0x06b59268) /* 0.419329078 */, 18 }, - /* 6038 */ { MAD_F(0x06b5f385) /* 0.419421694 */, 18 }, - /* 6039 */ { MAD_F(0x06b654a4) /* 0.419514314 */, 18 }, - /* 6040 */ { MAD_F(0x06b6b5c4) /* 0.419606940 */, 18 }, - /* 6041 */ { MAD_F(0x06b716e6) /* 0.419699571 */, 18 }, - /* 6042 */ { MAD_F(0x06b77808) /* 0.419792208 */, 18 }, - /* 6043 */ { MAD_F(0x06b7d92d) /* 0.419884849 */, 18 }, - /* 6044 */ { MAD_F(0x06b83a52) /* 0.419977495 */, 18 }, - /* 6045 */ { MAD_F(0x06b89b79) /* 0.420070147 */, 18 }, - /* 6046 */ { MAD_F(0x06b8fca1) /* 0.420162803 */, 18 }, - /* 6047 */ { MAD_F(0x06b95dcb) /* 0.420255465 */, 18 }, - - /* 6048 */ { MAD_F(0x06b9bef6) /* 0.420348132 */, 18 }, - /* 6049 */ { MAD_F(0x06ba2023) /* 0.420440803 */, 18 }, - /* 6050 */ { MAD_F(0x06ba8150) /* 0.420533481 */, 18 }, - /* 6051 */ { MAD_F(0x06bae280) /* 0.420626163 */, 18 }, - /* 6052 */ { MAD_F(0x06bb43b0) /* 0.420718850 */, 18 }, - /* 6053 */ { MAD_F(0x06bba4e2) /* 0.420811542 */, 18 }, - /* 6054 */ { MAD_F(0x06bc0615) /* 0.420904240 */, 18 }, - /* 6055 */ { MAD_F(0x06bc674a) /* 0.420996942 */, 18 }, - /* 6056 */ { MAD_F(0x06bcc880) /* 0.421089650 */, 18 }, - /* 6057 */ { MAD_F(0x06bd29b7) /* 0.421182362 */, 18 }, - /* 6058 */ { MAD_F(0x06bd8af0) /* 0.421275080 */, 18 }, - /* 6059 */ { MAD_F(0x06bdec2a) /* 0.421367803 */, 18 }, - /* 6060 */ { MAD_F(0x06be4d66) /* 0.421460531 */, 18 }, - /* 6061 */ { MAD_F(0x06beaea3) /* 0.421553264 */, 18 }, - /* 6062 */ { MAD_F(0x06bf0fe1) /* 0.421646003 */, 18 }, - /* 6063 */ { MAD_F(0x06bf7120) /* 0.421738746 */, 18 }, - - /* 6064 */ { MAD_F(0x06bfd261) /* 0.421831494 */, 18 }, - /* 6065 */ { MAD_F(0x06c033a4) /* 0.421924248 */, 18 }, - /* 6066 */ { MAD_F(0x06c094e7) /* 0.422017007 */, 18 }, - /* 6067 */ { MAD_F(0x06c0f62c) /* 0.422109770 */, 18 }, - /* 6068 */ { MAD_F(0x06c15773) /* 0.422202539 */, 18 }, - /* 6069 */ { MAD_F(0x06c1b8bb) /* 0.422295313 */, 18 }, - /* 6070 */ { MAD_F(0x06c21a04) /* 0.422388092 */, 18 }, - /* 6071 */ { MAD_F(0x06c27b4e) /* 0.422480876 */, 18 }, - /* 6072 */ { MAD_F(0x06c2dc9a) /* 0.422573665 */, 18 }, - /* 6073 */ { MAD_F(0x06c33de8) /* 0.422666460 */, 18 }, - /* 6074 */ { MAD_F(0x06c39f36) /* 0.422759259 */, 18 }, - /* 6075 */ { MAD_F(0x06c40086) /* 0.422852064 */, 18 }, - /* 6076 */ { MAD_F(0x06c461d8) /* 0.422944873 */, 18 }, - /* 6077 */ { MAD_F(0x06c4c32a) /* 0.423037688 */, 18 }, - /* 6078 */ { MAD_F(0x06c5247f) /* 0.423130508 */, 18 }, - /* 6079 */ { MAD_F(0x06c585d4) /* 0.423223333 */, 18 }, - - /* 6080 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 18 }, - /* 6081 */ { MAD_F(0x06c64883) /* 0.423408997 */, 18 }, - /* 6082 */ { MAD_F(0x06c6a9dd) /* 0.423501838 */, 18 }, - /* 6083 */ { MAD_F(0x06c70b38) /* 0.423594683 */, 18 }, - /* 6084 */ { MAD_F(0x06c76c94) /* 0.423687533 */, 18 }, - /* 6085 */ { MAD_F(0x06c7cdf2) /* 0.423780389 */, 18 }, - /* 6086 */ { MAD_F(0x06c82f51) /* 0.423873249 */, 18 }, - /* 6087 */ { MAD_F(0x06c890b1) /* 0.423966115 */, 18 }, - /* 6088 */ { MAD_F(0x06c8f213) /* 0.424058985 */, 18 }, - /* 6089 */ { MAD_F(0x06c95376) /* 0.424151861 */, 18 }, - /* 6090 */ { MAD_F(0x06c9b4da) /* 0.424244742 */, 18 }, - /* 6091 */ { MAD_F(0x06ca1640) /* 0.424337628 */, 18 }, - /* 6092 */ { MAD_F(0x06ca77a8) /* 0.424430519 */, 18 }, - /* 6093 */ { MAD_F(0x06cad910) /* 0.424523415 */, 18 }, - /* 6094 */ { MAD_F(0x06cb3a7a) /* 0.424616316 */, 18 }, - /* 6095 */ { MAD_F(0x06cb9be5) /* 0.424709222 */, 18 }, - - /* 6096 */ { MAD_F(0x06cbfd52) /* 0.424802133 */, 18 }, - /* 6097 */ { MAD_F(0x06cc5ec0) /* 0.424895050 */, 18 }, - /* 6098 */ { MAD_F(0x06ccc030) /* 0.424987971 */, 18 }, - /* 6099 */ { MAD_F(0x06cd21a0) /* 0.425080898 */, 18 }, - /* 6100 */ { MAD_F(0x06cd8313) /* 0.425173829 */, 18 }, - /* 6101 */ { MAD_F(0x06cde486) /* 0.425266766 */, 18 }, - /* 6102 */ { MAD_F(0x06ce45fb) /* 0.425359708 */, 18 }, - /* 6103 */ { MAD_F(0x06cea771) /* 0.425452655 */, 18 }, - /* 6104 */ { MAD_F(0x06cf08e9) /* 0.425545607 */, 18 }, - /* 6105 */ { MAD_F(0x06cf6a62) /* 0.425638564 */, 18 }, - /* 6106 */ { MAD_F(0x06cfcbdc) /* 0.425731526 */, 18 }, - /* 6107 */ { MAD_F(0x06d02d58) /* 0.425824493 */, 18 }, - /* 6108 */ { MAD_F(0x06d08ed5) /* 0.425917465 */, 18 }, - /* 6109 */ { MAD_F(0x06d0f053) /* 0.426010443 */, 18 }, - /* 6110 */ { MAD_F(0x06d151d3) /* 0.426103425 */, 18 }, - /* 6111 */ { MAD_F(0x06d1b354) /* 0.426196412 */, 18 }, - - /* 6112 */ { MAD_F(0x06d214d7) /* 0.426289405 */, 18 }, - /* 6113 */ { MAD_F(0x06d2765a) /* 0.426382403 */, 18 }, - /* 6114 */ { MAD_F(0x06d2d7e0) /* 0.426475405 */, 18 }, - /* 6115 */ { MAD_F(0x06d33966) /* 0.426568413 */, 18 }, - /* 6116 */ { MAD_F(0x06d39aee) /* 0.426661426 */, 18 }, - /* 6117 */ { MAD_F(0x06d3fc77) /* 0.426754444 */, 18 }, - /* 6118 */ { MAD_F(0x06d45e02) /* 0.426847467 */, 18 }, - /* 6119 */ { MAD_F(0x06d4bf8e) /* 0.426940495 */, 18 }, - /* 6120 */ { MAD_F(0x06d5211c) /* 0.427033528 */, 18 }, - /* 6121 */ { MAD_F(0x06d582aa) /* 0.427126566 */, 18 }, - /* 6122 */ { MAD_F(0x06d5e43a) /* 0.427219609 */, 18 }, - /* 6123 */ { MAD_F(0x06d645cc) /* 0.427312657 */, 18 }, - /* 6124 */ { MAD_F(0x06d6a75f) /* 0.427405711 */, 18 }, - /* 6125 */ { MAD_F(0x06d708f3) /* 0.427498769 */, 18 }, - /* 6126 */ { MAD_F(0x06d76a88) /* 0.427591833 */, 18 }, - /* 6127 */ { MAD_F(0x06d7cc1f) /* 0.427684901 */, 18 }, - - /* 6128 */ { MAD_F(0x06d82db8) /* 0.427777975 */, 18 }, - /* 6129 */ { MAD_F(0x06d88f51) /* 0.427871054 */, 18 }, - /* 6130 */ { MAD_F(0x06d8f0ec) /* 0.427964137 */, 18 }, - /* 6131 */ { MAD_F(0x06d95288) /* 0.428057226 */, 18 }, - /* 6132 */ { MAD_F(0x06d9b426) /* 0.428150320 */, 18 }, - /* 6133 */ { MAD_F(0x06da15c5) /* 0.428243419 */, 18 }, - /* 6134 */ { MAD_F(0x06da7766) /* 0.428336523 */, 18 }, - /* 6135 */ { MAD_F(0x06dad907) /* 0.428429632 */, 18 }, - /* 6136 */ { MAD_F(0x06db3aaa) /* 0.428522746 */, 18 }, - /* 6137 */ { MAD_F(0x06db9c4f) /* 0.428615865 */, 18 }, - /* 6138 */ { MAD_F(0x06dbfdf5) /* 0.428708989 */, 18 }, - /* 6139 */ { MAD_F(0x06dc5f9c) /* 0.428802119 */, 18 }, - /* 6140 */ { MAD_F(0x06dcc145) /* 0.428895253 */, 18 }, - /* 6141 */ { MAD_F(0x06dd22ee) /* 0.428988392 */, 18 }, - /* 6142 */ { MAD_F(0x06dd849a) /* 0.429081537 */, 18 }, - /* 6143 */ { MAD_F(0x06dde646) /* 0.429174686 */, 18 }, - - /* 6144 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 18 }, - /* 6145 */ { MAD_F(0x06dea9a4) /* 0.429361001 */, 18 }, - /* 6146 */ { MAD_F(0x06df0b54) /* 0.429454165 */, 18 }, - /* 6147 */ { MAD_F(0x06df6d06) /* 0.429547335 */, 18 }, - /* 6148 */ { MAD_F(0x06dfceba) /* 0.429640510 */, 18 }, - /* 6149 */ { MAD_F(0x06e0306f) /* 0.429733690 */, 18 }, - /* 6150 */ { MAD_F(0x06e09225) /* 0.429826874 */, 18 }, - /* 6151 */ { MAD_F(0x06e0f3dc) /* 0.429920064 */, 18 }, - /* 6152 */ { MAD_F(0x06e15595) /* 0.430013259 */, 18 }, - /* 6153 */ { MAD_F(0x06e1b74f) /* 0.430106459 */, 18 }, - /* 6154 */ { MAD_F(0x06e2190b) /* 0.430199664 */, 18 }, - /* 6155 */ { MAD_F(0x06e27ac8) /* 0.430292875 */, 18 }, - /* 6156 */ { MAD_F(0x06e2dc86) /* 0.430386090 */, 18 }, - /* 6157 */ { MAD_F(0x06e33e46) /* 0.430479310 */, 18 }, - /* 6158 */ { MAD_F(0x06e3a007) /* 0.430572535 */, 18 }, - /* 6159 */ { MAD_F(0x06e401c9) /* 0.430665765 */, 18 }, - - /* 6160 */ { MAD_F(0x06e4638d) /* 0.430759001 */, 18 }, - /* 6161 */ { MAD_F(0x06e4c552) /* 0.430852241 */, 18 }, - /* 6162 */ { MAD_F(0x06e52718) /* 0.430945487 */, 18 }, - /* 6163 */ { MAD_F(0x06e588e0) /* 0.431038737 */, 18 }, - /* 6164 */ { MAD_F(0x06e5eaa9) /* 0.431131993 */, 18 }, - /* 6165 */ { MAD_F(0x06e64c73) /* 0.431225253 */, 18 }, - /* 6166 */ { MAD_F(0x06e6ae3f) /* 0.431318519 */, 18 }, - /* 6167 */ { MAD_F(0x06e7100c) /* 0.431411790 */, 18 }, - /* 6168 */ { MAD_F(0x06e771db) /* 0.431505065 */, 18 }, - /* 6169 */ { MAD_F(0x06e7d3ab) /* 0.431598346 */, 18 }, - /* 6170 */ { MAD_F(0x06e8357c) /* 0.431691632 */, 18 }, - /* 6171 */ { MAD_F(0x06e8974e) /* 0.431784923 */, 18 }, - /* 6172 */ { MAD_F(0x06e8f922) /* 0.431878218 */, 18 }, - /* 6173 */ { MAD_F(0x06e95af8) /* 0.431971519 */, 18 }, - /* 6174 */ { MAD_F(0x06e9bcce) /* 0.432064825 */, 18 }, - /* 6175 */ { MAD_F(0x06ea1ea6) /* 0.432158136 */, 18 }, - - /* 6176 */ { MAD_F(0x06ea807f) /* 0.432251452 */, 18 }, - /* 6177 */ { MAD_F(0x06eae25a) /* 0.432344773 */, 18 }, - /* 6178 */ { MAD_F(0x06eb4436) /* 0.432438099 */, 18 }, - /* 6179 */ { MAD_F(0x06eba614) /* 0.432531431 */, 18 }, - /* 6180 */ { MAD_F(0x06ec07f2) /* 0.432624767 */, 18 }, - /* 6181 */ { MAD_F(0x06ec69d2) /* 0.432718108 */, 18 }, - /* 6182 */ { MAD_F(0x06eccbb4) /* 0.432811454 */, 18 }, - /* 6183 */ { MAD_F(0x06ed2d97) /* 0.432904805 */, 18 }, - /* 6184 */ { MAD_F(0x06ed8f7b) /* 0.432998162 */, 18 }, - /* 6185 */ { MAD_F(0x06edf160) /* 0.433091523 */, 18 }, - /* 6186 */ { MAD_F(0x06ee5347) /* 0.433184889 */, 18 }, - /* 6187 */ { MAD_F(0x06eeb52f) /* 0.433278261 */, 18 }, - /* 6188 */ { MAD_F(0x06ef1719) /* 0.433371637 */, 18 }, - /* 6189 */ { MAD_F(0x06ef7904) /* 0.433465019 */, 18 }, - /* 6190 */ { MAD_F(0x06efdaf0) /* 0.433558405 */, 18 }, - /* 6191 */ { MAD_F(0x06f03cde) /* 0.433651797 */, 18 }, - - /* 6192 */ { MAD_F(0x06f09ecc) /* 0.433745193 */, 18 }, - /* 6193 */ { MAD_F(0x06f100bd) /* 0.433838595 */, 18 }, - /* 6194 */ { MAD_F(0x06f162ae) /* 0.433932001 */, 18 }, - /* 6195 */ { MAD_F(0x06f1c4a1) /* 0.434025413 */, 18 }, - /* 6196 */ { MAD_F(0x06f22696) /* 0.434118830 */, 18 }, - /* 6197 */ { MAD_F(0x06f2888b) /* 0.434212251 */, 18 }, - /* 6198 */ { MAD_F(0x06f2ea82) /* 0.434305678 */, 18 }, - /* 6199 */ { MAD_F(0x06f34c7b) /* 0.434399110 */, 18 }, - /* 6200 */ { MAD_F(0x06f3ae75) /* 0.434492546 */, 18 }, - /* 6201 */ { MAD_F(0x06f41070) /* 0.434585988 */, 18 }, - /* 6202 */ { MAD_F(0x06f4726c) /* 0.434679435 */, 18 }, - /* 6203 */ { MAD_F(0x06f4d46a) /* 0.434772887 */, 18 }, - /* 6204 */ { MAD_F(0x06f53669) /* 0.434866344 */, 18 }, - /* 6205 */ { MAD_F(0x06f59869) /* 0.434959806 */, 18 }, - /* 6206 */ { MAD_F(0x06f5fa6b) /* 0.435053272 */, 18 }, - /* 6207 */ { MAD_F(0x06f65c6e) /* 0.435146744 */, 18 }, - - /* 6208 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 18 }, - /* 6209 */ { MAD_F(0x06f72079) /* 0.435333703 */, 18 }, - /* 6210 */ { MAD_F(0x06f78280) /* 0.435427190 */, 18 }, - /* 6211 */ { MAD_F(0x06f7e489) /* 0.435520682 */, 18 }, - /* 6212 */ { MAD_F(0x06f84693) /* 0.435614179 */, 18 }, - /* 6213 */ { MAD_F(0x06f8a89e) /* 0.435707681 */, 18 }, - /* 6214 */ { MAD_F(0x06f90aaa) /* 0.435801188 */, 18 }, - /* 6215 */ { MAD_F(0x06f96cb8) /* 0.435894700 */, 18 }, - /* 6216 */ { MAD_F(0x06f9cec8) /* 0.435988217 */, 18 }, - /* 6217 */ { MAD_F(0x06fa30d8) /* 0.436081739 */, 18 }, - /* 6218 */ { MAD_F(0x06fa92ea) /* 0.436175266 */, 18 }, - /* 6219 */ { MAD_F(0x06faf4fe) /* 0.436268799 */, 18 }, - /* 6220 */ { MAD_F(0x06fb5712) /* 0.436362336 */, 18 }, - /* 6221 */ { MAD_F(0x06fbb928) /* 0.436455878 */, 18 }, - /* 6222 */ { MAD_F(0x06fc1b40) /* 0.436549425 */, 18 }, - /* 6223 */ { MAD_F(0x06fc7d58) /* 0.436642977 */, 18 }, - - /* 6224 */ { MAD_F(0x06fcdf72) /* 0.436736534 */, 18 }, - /* 6225 */ { MAD_F(0x06fd418e) /* 0.436830096 */, 18 }, - /* 6226 */ { MAD_F(0x06fda3ab) /* 0.436923664 */, 18 }, - /* 6227 */ { MAD_F(0x06fe05c9) /* 0.437017236 */, 18 }, - /* 6228 */ { MAD_F(0x06fe67e8) /* 0.437110813 */, 18 }, - /* 6229 */ { MAD_F(0x06feca09) /* 0.437204395 */, 18 }, - /* 6230 */ { MAD_F(0x06ff2c2b) /* 0.437297982 */, 18 }, - /* 6231 */ { MAD_F(0x06ff8e4f) /* 0.437391575 */, 18 }, - /* 6232 */ { MAD_F(0x06fff073) /* 0.437485172 */, 18 }, - /* 6233 */ { MAD_F(0x0700529a) /* 0.437578774 */, 18 }, - /* 6234 */ { MAD_F(0x0700b4c1) /* 0.437672381 */, 18 }, - /* 6235 */ { MAD_F(0x070116ea) /* 0.437765994 */, 18 }, - /* 6236 */ { MAD_F(0x07017914) /* 0.437859611 */, 18 }, - /* 6237 */ { MAD_F(0x0701db40) /* 0.437953233 */, 18 }, - /* 6238 */ { MAD_F(0x07023d6c) /* 0.438046860 */, 18 }, - /* 6239 */ { MAD_F(0x07029f9b) /* 0.438140493 */, 18 }, - - /* 6240 */ { MAD_F(0x070301ca) /* 0.438234130 */, 18 }, - /* 6241 */ { MAD_F(0x070363fb) /* 0.438327772 */, 18 }, - /* 6242 */ { MAD_F(0x0703c62d) /* 0.438421419 */, 18 }, - /* 6243 */ { MAD_F(0x07042861) /* 0.438515072 */, 18 }, - /* 6244 */ { MAD_F(0x07048a96) /* 0.438608729 */, 18 }, - /* 6245 */ { MAD_F(0x0704eccc) /* 0.438702391 */, 18 }, - /* 6246 */ { MAD_F(0x07054f04) /* 0.438796059 */, 18 }, - /* 6247 */ { MAD_F(0x0705b13d) /* 0.438889731 */, 18 }, - /* 6248 */ { MAD_F(0x07061377) /* 0.438983408 */, 18 }, - /* 6249 */ { MAD_F(0x070675b3) /* 0.439077090 */, 18 }, - /* 6250 */ { MAD_F(0x0706d7f0) /* 0.439170778 */, 18 }, - /* 6251 */ { MAD_F(0x07073a2e) /* 0.439264470 */, 18 }, - /* 6252 */ { MAD_F(0x07079c6e) /* 0.439358167 */, 18 }, - /* 6253 */ { MAD_F(0x0707feaf) /* 0.439451869 */, 18 }, - /* 6254 */ { MAD_F(0x070860f1) /* 0.439545577 */, 18 }, - /* 6255 */ { MAD_F(0x0708c335) /* 0.439639289 */, 18 }, - - /* 6256 */ { MAD_F(0x0709257a) /* 0.439733006 */, 18 }, - /* 6257 */ { MAD_F(0x070987c0) /* 0.439826728 */, 18 }, - /* 6258 */ { MAD_F(0x0709ea08) /* 0.439920456 */, 18 }, - /* 6259 */ { MAD_F(0x070a4c51) /* 0.440014188 */, 18 }, - /* 6260 */ { MAD_F(0x070aae9b) /* 0.440107925 */, 18 }, - /* 6261 */ { MAD_F(0x070b10e7) /* 0.440201667 */, 18 }, - /* 6262 */ { MAD_F(0x070b7334) /* 0.440295414 */, 18 }, - /* 6263 */ { MAD_F(0x070bd583) /* 0.440389167 */, 18 }, - /* 6264 */ { MAD_F(0x070c37d2) /* 0.440482924 */, 18 }, - /* 6265 */ { MAD_F(0x070c9a23) /* 0.440576686 */, 18 }, - /* 6266 */ { MAD_F(0x070cfc76) /* 0.440670453 */, 18 }, - /* 6267 */ { MAD_F(0x070d5eca) /* 0.440764225 */, 18 }, - /* 6268 */ { MAD_F(0x070dc11f) /* 0.440858002 */, 18 }, - /* 6269 */ { MAD_F(0x070e2375) /* 0.440951784 */, 18 }, - /* 6270 */ { MAD_F(0x070e85cd) /* 0.441045572 */, 18 }, - /* 6271 */ { MAD_F(0x070ee826) /* 0.441139364 */, 18 }, - - /* 6272 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 18 }, - /* 6273 */ { MAD_F(0x070facdc) /* 0.441326963 */, 18 }, - /* 6274 */ { MAD_F(0x07100f39) /* 0.441420770 */, 18 }, - /* 6275 */ { MAD_F(0x07107198) /* 0.441514582 */, 18 }, - /* 6276 */ { MAD_F(0x0710d3f8) /* 0.441608399 */, 18 }, - /* 6277 */ { MAD_F(0x07113659) /* 0.441702221 */, 18 }, - /* 6278 */ { MAD_F(0x071198bb) /* 0.441796048 */, 18 }, - /* 6279 */ { MAD_F(0x0711fb1f) /* 0.441889880 */, 18 }, - /* 6280 */ { MAD_F(0x07125d84) /* 0.441983717 */, 18 }, - /* 6281 */ { MAD_F(0x0712bfeb) /* 0.442077559 */, 18 }, - /* 6282 */ { MAD_F(0x07132253) /* 0.442171406 */, 18 }, - /* 6283 */ { MAD_F(0x071384bc) /* 0.442265257 */, 18 }, - /* 6284 */ { MAD_F(0x0713e726) /* 0.442359114 */, 18 }, - /* 6285 */ { MAD_F(0x07144992) /* 0.442452976 */, 18 }, - /* 6286 */ { MAD_F(0x0714abff) /* 0.442546843 */, 18 }, - /* 6287 */ { MAD_F(0x07150e6e) /* 0.442640715 */, 18 }, - - /* 6288 */ { MAD_F(0x071570de) /* 0.442734592 */, 18 }, - /* 6289 */ { MAD_F(0x0715d34f) /* 0.442828473 */, 18 }, - /* 6290 */ { MAD_F(0x071635c1) /* 0.442922360 */, 18 }, - /* 6291 */ { MAD_F(0x07169835) /* 0.443016252 */, 18 }, - /* 6292 */ { MAD_F(0x0716faaa) /* 0.443110148 */, 18 }, - /* 6293 */ { MAD_F(0x07175d21) /* 0.443204050 */, 18 }, - /* 6294 */ { MAD_F(0x0717bf99) /* 0.443297957 */, 18 }, - /* 6295 */ { MAD_F(0x07182212) /* 0.443391868 */, 18 }, - /* 6296 */ { MAD_F(0x0718848d) /* 0.443485785 */, 18 }, - /* 6297 */ { MAD_F(0x0718e709) /* 0.443579706 */, 18 }, - /* 6298 */ { MAD_F(0x07194986) /* 0.443673633 */, 18 }, - /* 6299 */ { MAD_F(0x0719ac04) /* 0.443767564 */, 18 }, - /* 6300 */ { MAD_F(0x071a0e84) /* 0.443861501 */, 18 }, - /* 6301 */ { MAD_F(0x071a7105) /* 0.443955442 */, 18 }, - /* 6302 */ { MAD_F(0x071ad388) /* 0.444049389 */, 18 }, - /* 6303 */ { MAD_F(0x071b360c) /* 0.444143340 */, 18 }, - - /* 6304 */ { MAD_F(0x071b9891) /* 0.444237296 */, 18 }, - /* 6305 */ { MAD_F(0x071bfb18) /* 0.444331258 */, 18 }, - /* 6306 */ { MAD_F(0x071c5d9f) /* 0.444425224 */, 18 }, - /* 6307 */ { MAD_F(0x071cc029) /* 0.444519195 */, 18 }, - /* 6308 */ { MAD_F(0x071d22b3) /* 0.444613171 */, 18 }, - /* 6309 */ { MAD_F(0x071d853f) /* 0.444707153 */, 18 }, - /* 6310 */ { MAD_F(0x071de7cc) /* 0.444801139 */, 18 }, - /* 6311 */ { MAD_F(0x071e4a5b) /* 0.444895130 */, 18 }, - /* 6312 */ { MAD_F(0x071eaceb) /* 0.444989126 */, 18 }, - /* 6313 */ { MAD_F(0x071f0f7c) /* 0.445083127 */, 18 }, - /* 6314 */ { MAD_F(0x071f720e) /* 0.445177133 */, 18 }, - /* 6315 */ { MAD_F(0x071fd4a2) /* 0.445271144 */, 18 }, - /* 6316 */ { MAD_F(0x07203737) /* 0.445365160 */, 18 }, - /* 6317 */ { MAD_F(0x072099ce) /* 0.445459181 */, 18 }, - /* 6318 */ { MAD_F(0x0720fc66) /* 0.445553206 */, 18 }, - /* 6319 */ { MAD_F(0x07215eff) /* 0.445647237 */, 18 }, - - /* 6320 */ { MAD_F(0x0721c19a) /* 0.445741273 */, 18 }, - /* 6321 */ { MAD_F(0x07222436) /* 0.445835314 */, 18 }, - /* 6322 */ { MAD_F(0x072286d3) /* 0.445929359 */, 18 }, - /* 6323 */ { MAD_F(0x0722e971) /* 0.446023410 */, 18 }, - /* 6324 */ { MAD_F(0x07234c11) /* 0.446117466 */, 18 }, - /* 6325 */ { MAD_F(0x0723aeb2) /* 0.446211526 */, 18 }, - /* 6326 */ { MAD_F(0x07241155) /* 0.446305592 */, 18 }, - /* 6327 */ { MAD_F(0x072473f9) /* 0.446399662 */, 18 }, - /* 6328 */ { MAD_F(0x0724d69e) /* 0.446493738 */, 18 }, - /* 6329 */ { MAD_F(0x07253944) /* 0.446587818 */, 18 }, - /* 6330 */ { MAD_F(0x07259bec) /* 0.446681903 */, 18 }, - /* 6331 */ { MAD_F(0x0725fe95) /* 0.446775994 */, 18 }, - /* 6332 */ { MAD_F(0x07266140) /* 0.446870089 */, 18 }, - /* 6333 */ { MAD_F(0x0726c3ec) /* 0.446964189 */, 18 }, - /* 6334 */ { MAD_F(0x07272699) /* 0.447058294 */, 18 }, - /* 6335 */ { MAD_F(0x07278947) /* 0.447152404 */, 18 }, - - /* 6336 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 18 }, - /* 6337 */ { MAD_F(0x07284ea8) /* 0.447340639 */, 18 }, - /* 6338 */ { MAD_F(0x0728b15b) /* 0.447434764 */, 18 }, - /* 6339 */ { MAD_F(0x0729140f) /* 0.447528894 */, 18 }, - /* 6340 */ { MAD_F(0x072976c4) /* 0.447623029 */, 18 }, - /* 6341 */ { MAD_F(0x0729d97a) /* 0.447717169 */, 18 }, - /* 6342 */ { MAD_F(0x072a3c32) /* 0.447811314 */, 18 }, - /* 6343 */ { MAD_F(0x072a9eeb) /* 0.447905463 */, 18 }, - /* 6344 */ { MAD_F(0x072b01a6) /* 0.447999618 */, 18 }, - /* 6345 */ { MAD_F(0x072b6461) /* 0.448093778 */, 18 }, - /* 6346 */ { MAD_F(0x072bc71e) /* 0.448187942 */, 18 }, - /* 6347 */ { MAD_F(0x072c29dd) /* 0.448282112 */, 18 }, - /* 6348 */ { MAD_F(0x072c8c9d) /* 0.448376286 */, 18 }, - /* 6349 */ { MAD_F(0x072cef5e) /* 0.448470466 */, 18 }, - /* 6350 */ { MAD_F(0x072d5220) /* 0.448564650 */, 18 }, - /* 6351 */ { MAD_F(0x072db4e4) /* 0.448658839 */, 18 }, - - /* 6352 */ { MAD_F(0x072e17a9) /* 0.448753033 */, 18 }, - /* 6353 */ { MAD_F(0x072e7a6f) /* 0.448847233 */, 18 }, - /* 6354 */ { MAD_F(0x072edd37) /* 0.448941437 */, 18 }, - /* 6355 */ { MAD_F(0x072f4000) /* 0.449035646 */, 18 }, - /* 6356 */ { MAD_F(0x072fa2ca) /* 0.449129860 */, 18 }, - /* 6357 */ { MAD_F(0x07300596) /* 0.449224079 */, 18 }, - /* 6358 */ { MAD_F(0x07306863) /* 0.449318303 */, 18 }, - /* 6359 */ { MAD_F(0x0730cb32) /* 0.449412531 */, 18 }, - /* 6360 */ { MAD_F(0x07312e01) /* 0.449506765 */, 18 }, - /* 6361 */ { MAD_F(0x073190d2) /* 0.449601004 */, 18 }, - /* 6362 */ { MAD_F(0x0731f3a5) /* 0.449695247 */, 18 }, - /* 6363 */ { MAD_F(0x07325678) /* 0.449789496 */, 18 }, - /* 6364 */ { MAD_F(0x0732b94d) /* 0.449883749 */, 18 }, - /* 6365 */ { MAD_F(0x07331c23) /* 0.449978008 */, 18 }, - /* 6366 */ { MAD_F(0x07337efb) /* 0.450072271 */, 18 }, - /* 6367 */ { MAD_F(0x0733e1d4) /* 0.450166540 */, 18 }, - - /* 6368 */ { MAD_F(0x073444ae) /* 0.450260813 */, 18 }, - /* 6369 */ { MAD_F(0x0734a78a) /* 0.450355091 */, 18 }, - /* 6370 */ { MAD_F(0x07350a67) /* 0.450449374 */, 18 }, - /* 6371 */ { MAD_F(0x07356d45) /* 0.450543662 */, 18 }, - /* 6372 */ { MAD_F(0x0735d025) /* 0.450637955 */, 18 }, - /* 6373 */ { MAD_F(0x07363306) /* 0.450732253 */, 18 }, - /* 6374 */ { MAD_F(0x073695e8) /* 0.450826556 */, 18 }, - /* 6375 */ { MAD_F(0x0736f8cb) /* 0.450920864 */, 18 }, - /* 6376 */ { MAD_F(0x07375bb0) /* 0.451015176 */, 18 }, - /* 6377 */ { MAD_F(0x0737be96) /* 0.451109494 */, 18 }, - /* 6378 */ { MAD_F(0x0738217e) /* 0.451203817 */, 18 }, - /* 6379 */ { MAD_F(0x07388467) /* 0.451298144 */, 18 }, - /* 6380 */ { MAD_F(0x0738e751) /* 0.451392477 */, 18 }, - /* 6381 */ { MAD_F(0x07394a3d) /* 0.451486814 */, 18 }, - /* 6382 */ { MAD_F(0x0739ad29) /* 0.451581156 */, 18 }, - /* 6383 */ { MAD_F(0x073a1017) /* 0.451675503 */, 18 }, - - /* 6384 */ { MAD_F(0x073a7307) /* 0.451769856 */, 18 }, - /* 6385 */ { MAD_F(0x073ad5f8) /* 0.451864213 */, 18 }, - /* 6386 */ { MAD_F(0x073b38ea) /* 0.451958575 */, 18 }, - /* 6387 */ { MAD_F(0x073b9bdd) /* 0.452052942 */, 18 }, - /* 6388 */ { MAD_F(0x073bfed2) /* 0.452147313 */, 18 }, - /* 6389 */ { MAD_F(0x073c61c8) /* 0.452241690 */, 18 }, - /* 6390 */ { MAD_F(0x073cc4bf) /* 0.452336072 */, 18 }, - /* 6391 */ { MAD_F(0x073d27b8) /* 0.452430458 */, 18 }, - /* 6392 */ { MAD_F(0x073d8ab2) /* 0.452524850 */, 18 }, - /* 6393 */ { MAD_F(0x073dedae) /* 0.452619246 */, 18 }, - /* 6394 */ { MAD_F(0x073e50aa) /* 0.452713648 */, 18 }, - /* 6395 */ { MAD_F(0x073eb3a8) /* 0.452808054 */, 18 }, - /* 6396 */ { MAD_F(0x073f16a8) /* 0.452902465 */, 18 }, - /* 6397 */ { MAD_F(0x073f79a8) /* 0.452996882 */, 18 }, - /* 6398 */ { MAD_F(0x073fdcaa) /* 0.453091303 */, 18 }, - /* 6399 */ { MAD_F(0x07403fad) /* 0.453185729 */, 18 }, - - /* 6400 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 18 }, - /* 6401 */ { MAD_F(0x074105b8) /* 0.453374595 */, 18 }, - /* 6402 */ { MAD_F(0x074168bf) /* 0.453469036 */, 18 }, - /* 6403 */ { MAD_F(0x0741cbc8) /* 0.453563482 */, 18 }, - /* 6404 */ { MAD_F(0x07422ed2) /* 0.453657932 */, 18 }, - /* 6405 */ { MAD_F(0x074291dd) /* 0.453752388 */, 18 }, - /* 6406 */ { MAD_F(0x0742f4e9) /* 0.453846848 */, 18 }, - /* 6407 */ { MAD_F(0x074357f7) /* 0.453941314 */, 18 }, - /* 6408 */ { MAD_F(0x0743bb06) /* 0.454035784 */, 18 }, - /* 6409 */ { MAD_F(0x07441e17) /* 0.454130259 */, 18 }, - /* 6410 */ { MAD_F(0x07448129) /* 0.454224739 */, 18 }, - /* 6411 */ { MAD_F(0x0744e43c) /* 0.454319224 */, 18 }, - /* 6412 */ { MAD_F(0x07454750) /* 0.454413714 */, 18 }, - /* 6413 */ { MAD_F(0x0745aa66) /* 0.454508209 */, 18 }, - /* 6414 */ { MAD_F(0x07460d7d) /* 0.454602708 */, 18 }, - /* 6415 */ { MAD_F(0x07467095) /* 0.454697213 */, 18 }, - - /* 6416 */ { MAD_F(0x0746d3af) /* 0.454791723 */, 18 }, - /* 6417 */ { MAD_F(0x074736ca) /* 0.454886237 */, 18 }, - /* 6418 */ { MAD_F(0x074799e7) /* 0.454980756 */, 18 }, - /* 6419 */ { MAD_F(0x0747fd04) /* 0.455075281 */, 18 }, - /* 6420 */ { MAD_F(0x07486023) /* 0.455169810 */, 18 }, - /* 6421 */ { MAD_F(0x0748c344) /* 0.455264344 */, 18 }, - /* 6422 */ { MAD_F(0x07492665) /* 0.455358883 */, 18 }, - /* 6423 */ { MAD_F(0x07498988) /* 0.455453427 */, 18 }, - /* 6424 */ { MAD_F(0x0749ecac) /* 0.455547976 */, 18 }, - /* 6425 */ { MAD_F(0x074a4fd2) /* 0.455642529 */, 18 }, - /* 6426 */ { MAD_F(0x074ab2f9) /* 0.455737088 */, 18 }, - /* 6427 */ { MAD_F(0x074b1621) /* 0.455831652 */, 18 }, - /* 6428 */ { MAD_F(0x074b794b) /* 0.455926220 */, 18 }, - /* 6429 */ { MAD_F(0x074bdc75) /* 0.456020793 */, 18 }, - /* 6430 */ { MAD_F(0x074c3fa1) /* 0.456115372 */, 18 }, - /* 6431 */ { MAD_F(0x074ca2cf) /* 0.456209955 */, 18 }, - - /* 6432 */ { MAD_F(0x074d05fe) /* 0.456304543 */, 18 }, - /* 6433 */ { MAD_F(0x074d692e) /* 0.456399136 */, 18 }, - /* 6434 */ { MAD_F(0x074dcc5f) /* 0.456493733 */, 18 }, - /* 6435 */ { MAD_F(0x074e2f92) /* 0.456588336 */, 18 }, - /* 6436 */ { MAD_F(0x074e92c6) /* 0.456682944 */, 18 }, - /* 6437 */ { MAD_F(0x074ef5fb) /* 0.456777556 */, 18 }, - /* 6438 */ { MAD_F(0x074f5932) /* 0.456872174 */, 18 }, - /* 6439 */ { MAD_F(0x074fbc6a) /* 0.456966796 */, 18 }, - /* 6440 */ { MAD_F(0x07501fa3) /* 0.457061423 */, 18 }, - /* 6441 */ { MAD_F(0x075082de) /* 0.457156056 */, 18 }, - /* 6442 */ { MAD_F(0x0750e61a) /* 0.457250693 */, 18 }, - /* 6443 */ { MAD_F(0x07514957) /* 0.457345335 */, 18 }, - /* 6444 */ { MAD_F(0x0751ac96) /* 0.457439981 */, 18 }, - /* 6445 */ { MAD_F(0x07520fd6) /* 0.457534633 */, 18 }, - /* 6446 */ { MAD_F(0x07527317) /* 0.457629290 */, 18 }, - /* 6447 */ { MAD_F(0x0752d659) /* 0.457723951 */, 18 }, - - /* 6448 */ { MAD_F(0x0753399d) /* 0.457818618 */, 18 }, - /* 6449 */ { MAD_F(0x07539ce2) /* 0.457913289 */, 18 }, - /* 6450 */ { MAD_F(0x07540029) /* 0.458007965 */, 18 }, - /* 6451 */ { MAD_F(0x07546371) /* 0.458102646 */, 18 }, - /* 6452 */ { MAD_F(0x0754c6ba) /* 0.458197332 */, 18 }, - /* 6453 */ { MAD_F(0x07552a04) /* 0.458292023 */, 18 }, - /* 6454 */ { MAD_F(0x07558d50) /* 0.458386719 */, 18 }, - /* 6455 */ { MAD_F(0x0755f09d) /* 0.458481420 */, 18 }, - /* 6456 */ { MAD_F(0x075653eb) /* 0.458576125 */, 18 }, - /* 6457 */ { MAD_F(0x0756b73b) /* 0.458670836 */, 18 }, - /* 6458 */ { MAD_F(0x07571a8c) /* 0.458765551 */, 18 }, - /* 6459 */ { MAD_F(0x07577dde) /* 0.458860271 */, 18 }, - /* 6460 */ { MAD_F(0x0757e131) /* 0.458954996 */, 18 }, - /* 6461 */ { MAD_F(0x07584486) /* 0.459049726 */, 18 }, - /* 6462 */ { MAD_F(0x0758a7dd) /* 0.459144461 */, 18 }, - /* 6463 */ { MAD_F(0x07590b34) /* 0.459239201 */, 18 }, - - /* 6464 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 18 }, - /* 6465 */ { MAD_F(0x0759d1e7) /* 0.459428695 */, 18 }, - /* 6466 */ { MAD_F(0x075a3542) /* 0.459523450 */, 18 }, - /* 6467 */ { MAD_F(0x075a989f) /* 0.459618209 */, 18 }, - /* 6468 */ { MAD_F(0x075afbfd) /* 0.459712973 */, 18 }, - /* 6469 */ { MAD_F(0x075b5f5d) /* 0.459807742 */, 18 }, - /* 6470 */ { MAD_F(0x075bc2bd) /* 0.459902516 */, 18 }, - /* 6471 */ { MAD_F(0x075c261f) /* 0.459997295 */, 18 }, - /* 6472 */ { MAD_F(0x075c8983) /* 0.460092079 */, 18 }, - /* 6473 */ { MAD_F(0x075cece7) /* 0.460186867 */, 18 }, - /* 6474 */ { MAD_F(0x075d504d) /* 0.460281661 */, 18 }, - /* 6475 */ { MAD_F(0x075db3b5) /* 0.460376459 */, 18 }, - /* 6476 */ { MAD_F(0x075e171d) /* 0.460471262 */, 18 }, - /* 6477 */ { MAD_F(0x075e7a87) /* 0.460566071 */, 18 }, - /* 6478 */ { MAD_F(0x075eddf2) /* 0.460660884 */, 18 }, - /* 6479 */ { MAD_F(0x075f415f) /* 0.460755701 */, 18 }, - - /* 6480 */ { MAD_F(0x075fa4cc) /* 0.460850524 */, 18 }, - /* 6481 */ { MAD_F(0x0760083b) /* 0.460945352 */, 18 }, - /* 6482 */ { MAD_F(0x07606bac) /* 0.461040184 */, 18 }, - /* 6483 */ { MAD_F(0x0760cf1e) /* 0.461135022 */, 18 }, - /* 6484 */ { MAD_F(0x07613291) /* 0.461229864 */, 18 }, - /* 6485 */ { MAD_F(0x07619605) /* 0.461324711 */, 18 }, - /* 6486 */ { MAD_F(0x0761f97b) /* 0.461419563 */, 18 }, - /* 6487 */ { MAD_F(0x07625cf2) /* 0.461514420 */, 18 }, - /* 6488 */ { MAD_F(0x0762c06a) /* 0.461609282 */, 18 }, - /* 6489 */ { MAD_F(0x076323e3) /* 0.461704149 */, 18 }, - /* 6490 */ { MAD_F(0x0763875e) /* 0.461799020 */, 18 }, - /* 6491 */ { MAD_F(0x0763eadb) /* 0.461893897 */, 18 }, - /* 6492 */ { MAD_F(0x07644e58) /* 0.461988778 */, 18 }, - /* 6493 */ { MAD_F(0x0764b1d7) /* 0.462083664 */, 18 }, - /* 6494 */ { MAD_F(0x07651557) /* 0.462178555 */, 18 }, - /* 6495 */ { MAD_F(0x076578d8) /* 0.462273451 */, 18 }, - - /* 6496 */ { MAD_F(0x0765dc5b) /* 0.462368352 */, 18 }, - /* 6497 */ { MAD_F(0x07663fdf) /* 0.462463257 */, 18 }, - /* 6498 */ { MAD_F(0x0766a364) /* 0.462558168 */, 18 }, - /* 6499 */ { MAD_F(0x076706eb) /* 0.462653083 */, 18 }, - /* 6500 */ { MAD_F(0x07676a73) /* 0.462748003 */, 18 }, - /* 6501 */ { MAD_F(0x0767cdfc) /* 0.462842928 */, 18 }, - /* 6502 */ { MAD_F(0x07683187) /* 0.462937858 */, 18 }, - /* 6503 */ { MAD_F(0x07689513) /* 0.463032793 */, 18 }, - /* 6504 */ { MAD_F(0x0768f8a0) /* 0.463127733 */, 18 }, - /* 6505 */ { MAD_F(0x07695c2e) /* 0.463222678 */, 18 }, - /* 6506 */ { MAD_F(0x0769bfbe) /* 0.463317627 */, 18 }, - /* 6507 */ { MAD_F(0x076a234f) /* 0.463412581 */, 18 }, - /* 6508 */ { MAD_F(0x076a86e2) /* 0.463507540 */, 18 }, - /* 6509 */ { MAD_F(0x076aea75) /* 0.463602504 */, 18 }, - /* 6510 */ { MAD_F(0x076b4e0a) /* 0.463697473 */, 18 }, - /* 6511 */ { MAD_F(0x076bb1a1) /* 0.463792447 */, 18 }, - - /* 6512 */ { MAD_F(0x076c1538) /* 0.463887426 */, 18 }, - /* 6513 */ { MAD_F(0x076c78d1) /* 0.463982409 */, 18 }, - /* 6514 */ { MAD_F(0x076cdc6c) /* 0.464077398 */, 18 }, - /* 6515 */ { MAD_F(0x076d4007) /* 0.464172391 */, 18 }, - /* 6516 */ { MAD_F(0x076da3a4) /* 0.464267389 */, 18 }, - /* 6517 */ { MAD_F(0x076e0742) /* 0.464362392 */, 18 }, - /* 6518 */ { MAD_F(0x076e6ae2) /* 0.464457399 */, 18 }, - /* 6519 */ { MAD_F(0x076ece82) /* 0.464552412 */, 18 }, - /* 6520 */ { MAD_F(0x076f3224) /* 0.464647430 */, 18 }, - /* 6521 */ { MAD_F(0x076f95c8) /* 0.464742452 */, 18 }, - /* 6522 */ { MAD_F(0x076ff96c) /* 0.464837479 */, 18 }, - /* 6523 */ { MAD_F(0x07705d12) /* 0.464932511 */, 18 }, - /* 6524 */ { MAD_F(0x0770c0ba) /* 0.465027548 */, 18 }, - /* 6525 */ { MAD_F(0x07712462) /* 0.465122590 */, 18 }, - /* 6526 */ { MAD_F(0x0771880c) /* 0.465217637 */, 18 }, - /* 6527 */ { MAD_F(0x0771ebb7) /* 0.465312688 */, 18 }, - - /* 6528 */ { MAD_F(0x07724f64) /* 0.465407744 */, 18 }, - /* 6529 */ { MAD_F(0x0772b312) /* 0.465502806 */, 18 }, - /* 6530 */ { MAD_F(0x077316c1) /* 0.465597872 */, 18 }, - /* 6531 */ { MAD_F(0x07737a71) /* 0.465692943 */, 18 }, - /* 6532 */ { MAD_F(0x0773de23) /* 0.465788018 */, 18 }, - /* 6533 */ { MAD_F(0x077441d6) /* 0.465883099 */, 18 }, - /* 6534 */ { MAD_F(0x0774a58a) /* 0.465978184 */, 18 }, - /* 6535 */ { MAD_F(0x07750940) /* 0.466073275 */, 18 }, - /* 6536 */ { MAD_F(0x07756cf7) /* 0.466168370 */, 18 }, - /* 6537 */ { MAD_F(0x0775d0af) /* 0.466263470 */, 18 }, - /* 6538 */ { MAD_F(0x07763468) /* 0.466358575 */, 18 }, - /* 6539 */ { MAD_F(0x07769823) /* 0.466453684 */, 18 }, - /* 6540 */ { MAD_F(0x0776fbdf) /* 0.466548799 */, 18 }, - /* 6541 */ { MAD_F(0x07775f9d) /* 0.466643918 */, 18 }, - /* 6542 */ { MAD_F(0x0777c35c) /* 0.466739043 */, 18 }, - /* 6543 */ { MAD_F(0x0778271c) /* 0.466834172 */, 18 }, - - /* 6544 */ { MAD_F(0x07788add) /* 0.466929306 */, 18 }, - /* 6545 */ { MAD_F(0x0778ee9f) /* 0.467024445 */, 18 }, - /* 6546 */ { MAD_F(0x07795263) /* 0.467119588 */, 18 }, - /* 6547 */ { MAD_F(0x0779b629) /* 0.467214737 */, 18 }, - /* 6548 */ { MAD_F(0x077a19ef) /* 0.467309890 */, 18 }, - /* 6549 */ { MAD_F(0x077a7db7) /* 0.467405048 */, 18 }, - /* 6550 */ { MAD_F(0x077ae180) /* 0.467500211 */, 18 }, - /* 6551 */ { MAD_F(0x077b454b) /* 0.467595379 */, 18 }, - /* 6552 */ { MAD_F(0x077ba916) /* 0.467690552 */, 18 }, - /* 6553 */ { MAD_F(0x077c0ce3) /* 0.467785729 */, 18 }, - /* 6554 */ { MAD_F(0x077c70b2) /* 0.467880912 */, 18 }, - /* 6555 */ { MAD_F(0x077cd481) /* 0.467976099 */, 18 }, - /* 6556 */ { MAD_F(0x077d3852) /* 0.468071291 */, 18 }, - /* 6557 */ { MAD_F(0x077d9c24) /* 0.468166488 */, 18 }, - /* 6558 */ { MAD_F(0x077dfff8) /* 0.468261690 */, 18 }, - /* 6559 */ { MAD_F(0x077e63cd) /* 0.468356896 */, 18 }, - - /* 6560 */ { MAD_F(0x077ec7a3) /* 0.468452108 */, 18 }, - /* 6561 */ { MAD_F(0x077f2b7a) /* 0.468547324 */, 18 }, - /* 6562 */ { MAD_F(0x077f8f53) /* 0.468642545 */, 18 }, - /* 6563 */ { MAD_F(0x077ff32d) /* 0.468737771 */, 18 }, - /* 6564 */ { MAD_F(0x07805708) /* 0.468833002 */, 18 }, - /* 6565 */ { MAD_F(0x0780bae5) /* 0.468928237 */, 18 }, - /* 6566 */ { MAD_F(0x07811ec3) /* 0.469023478 */, 18 }, - /* 6567 */ { MAD_F(0x078182a2) /* 0.469118723 */, 18 }, - /* 6568 */ { MAD_F(0x0781e683) /* 0.469213973 */, 18 }, - /* 6569 */ { MAD_F(0x07824a64) /* 0.469309228 */, 18 }, - /* 6570 */ { MAD_F(0x0782ae47) /* 0.469404488 */, 18 }, - /* 6571 */ { MAD_F(0x0783122c) /* 0.469499752 */, 18 }, - /* 6572 */ { MAD_F(0x07837612) /* 0.469595022 */, 18 }, - /* 6573 */ { MAD_F(0x0783d9f9) /* 0.469690296 */, 18 }, - /* 6574 */ { MAD_F(0x07843de1) /* 0.469785575 */, 18 }, - /* 6575 */ { MAD_F(0x0784a1ca) /* 0.469880859 */, 18 }, - - /* 6576 */ { MAD_F(0x078505b5) /* 0.469976148 */, 18 }, - /* 6577 */ { MAD_F(0x078569a2) /* 0.470071442 */, 18 }, - /* 6578 */ { MAD_F(0x0785cd8f) /* 0.470166740 */, 18 }, - /* 6579 */ { MAD_F(0x0786317e) /* 0.470262043 */, 18 }, - /* 6580 */ { MAD_F(0x0786956e) /* 0.470357351 */, 18 }, - /* 6581 */ { MAD_F(0x0786f95f) /* 0.470452664 */, 18 }, - /* 6582 */ { MAD_F(0x07875d52) /* 0.470547982 */, 18 }, - /* 6583 */ { MAD_F(0x0787c146) /* 0.470643305 */, 18 }, - /* 6584 */ { MAD_F(0x0788253b) /* 0.470738632 */, 18 }, - /* 6585 */ { MAD_F(0x07888932) /* 0.470833964 */, 18 }, - /* 6586 */ { MAD_F(0x0788ed2a) /* 0.470929301 */, 18 }, - /* 6587 */ { MAD_F(0x07895123) /* 0.471024643 */, 18 }, - /* 6588 */ { MAD_F(0x0789b51d) /* 0.471119990 */, 18 }, - /* 6589 */ { MAD_F(0x078a1919) /* 0.471215341 */, 18 }, - /* 6590 */ { MAD_F(0x078a7d16) /* 0.471310698 */, 18 }, - /* 6591 */ { MAD_F(0x078ae114) /* 0.471406059 */, 18 }, - - /* 6592 */ { MAD_F(0x078b4514) /* 0.471501425 */, 18 }, - /* 6593 */ { MAD_F(0x078ba915) /* 0.471596796 */, 18 }, - /* 6594 */ { MAD_F(0x078c0d17) /* 0.471692171 */, 18 }, - /* 6595 */ { MAD_F(0x078c711a) /* 0.471787552 */, 18 }, - /* 6596 */ { MAD_F(0x078cd51f) /* 0.471882937 */, 18 }, - /* 6597 */ { MAD_F(0x078d3925) /* 0.471978327 */, 18 }, - /* 6598 */ { MAD_F(0x078d9d2d) /* 0.472073722 */, 18 }, - /* 6599 */ { MAD_F(0x078e0135) /* 0.472169122 */, 18 }, - /* 6600 */ { MAD_F(0x078e653f) /* 0.472264527 */, 18 }, - /* 6601 */ { MAD_F(0x078ec94b) /* 0.472359936 */, 18 }, - /* 6602 */ { MAD_F(0x078f2d57) /* 0.472455350 */, 18 }, - /* 6603 */ { MAD_F(0x078f9165) /* 0.472550769 */, 18 }, - /* 6604 */ { MAD_F(0x078ff574) /* 0.472646193 */, 18 }, - /* 6605 */ { MAD_F(0x07905985) /* 0.472741622 */, 18 }, - /* 6606 */ { MAD_F(0x0790bd96) /* 0.472837055 */, 18 }, - /* 6607 */ { MAD_F(0x079121a9) /* 0.472932493 */, 18 }, - - /* 6608 */ { MAD_F(0x079185be) /* 0.473027937 */, 18 }, - /* 6609 */ { MAD_F(0x0791e9d3) /* 0.473123384 */, 18 }, - /* 6610 */ { MAD_F(0x07924dea) /* 0.473218837 */, 18 }, - /* 6611 */ { MAD_F(0x0792b202) /* 0.473314295 */, 18 }, - /* 6612 */ { MAD_F(0x0793161c) /* 0.473409757 */, 18 }, - /* 6613 */ { MAD_F(0x07937a37) /* 0.473505224 */, 18 }, - /* 6614 */ { MAD_F(0x0793de53) /* 0.473600696 */, 18 }, - /* 6615 */ { MAD_F(0x07944270) /* 0.473696173 */, 18 }, - /* 6616 */ { MAD_F(0x0794a68f) /* 0.473791655 */, 18 }, - /* 6617 */ { MAD_F(0x07950aaf) /* 0.473887141 */, 18 }, - /* 6618 */ { MAD_F(0x07956ed0) /* 0.473982632 */, 18 }, - /* 6619 */ { MAD_F(0x0795d2f2) /* 0.474078128 */, 18 }, - /* 6620 */ { MAD_F(0x07963716) /* 0.474173629 */, 18 }, - /* 6621 */ { MAD_F(0x07969b3b) /* 0.474269135 */, 18 }, - /* 6622 */ { MAD_F(0x0796ff62) /* 0.474364645 */, 18 }, - /* 6623 */ { MAD_F(0x07976389) /* 0.474460161 */, 18 }, - - /* 6624 */ { MAD_F(0x0797c7b2) /* 0.474555681 */, 18 }, - /* 6625 */ { MAD_F(0x07982bdd) /* 0.474651205 */, 18 }, - /* 6626 */ { MAD_F(0x07989008) /* 0.474746735 */, 18 }, - /* 6627 */ { MAD_F(0x0798f435) /* 0.474842270 */, 18 }, - /* 6628 */ { MAD_F(0x07995863) /* 0.474937809 */, 18 }, - /* 6629 */ { MAD_F(0x0799bc92) /* 0.475033353 */, 18 }, - /* 6630 */ { MAD_F(0x079a20c3) /* 0.475128902 */, 18 }, - /* 6631 */ { MAD_F(0x079a84f5) /* 0.475224456 */, 18 }, - /* 6632 */ { MAD_F(0x079ae929) /* 0.475320014 */, 18 }, - /* 6633 */ { MAD_F(0x079b4d5d) /* 0.475415578 */, 18 }, - /* 6634 */ { MAD_F(0x079bb193) /* 0.475511146 */, 18 }, - /* 6635 */ { MAD_F(0x079c15ca) /* 0.475606719 */, 18 }, - /* 6636 */ { MAD_F(0x079c7a03) /* 0.475702296 */, 18 }, - /* 6637 */ { MAD_F(0x079cde3c) /* 0.475797879 */, 18 }, - /* 6638 */ { MAD_F(0x079d4277) /* 0.475893466 */, 18 }, - /* 6639 */ { MAD_F(0x079da6b4) /* 0.475989058 */, 18 }, - - /* 6640 */ { MAD_F(0x079e0af1) /* 0.476084655 */, 18 }, - /* 6641 */ { MAD_F(0x079e6f30) /* 0.476180257 */, 18 }, - /* 6642 */ { MAD_F(0x079ed370) /* 0.476275863 */, 18 }, - /* 6643 */ { MAD_F(0x079f37b2) /* 0.476371475 */, 18 }, - /* 6644 */ { MAD_F(0x079f9bf5) /* 0.476467091 */, 18 }, - /* 6645 */ { MAD_F(0x07a00039) /* 0.476562712 */, 18 }, - /* 6646 */ { MAD_F(0x07a0647e) /* 0.476658338 */, 18 }, - /* 6647 */ { MAD_F(0x07a0c8c5) /* 0.476753968 */, 18 }, - /* 6648 */ { MAD_F(0x07a12d0c) /* 0.476849603 */, 18 }, - /* 6649 */ { MAD_F(0x07a19156) /* 0.476945243 */, 18 }, - /* 6650 */ { MAD_F(0x07a1f5a0) /* 0.477040888 */, 18 }, - /* 6651 */ { MAD_F(0x07a259ec) /* 0.477136538 */, 18 }, - /* 6652 */ { MAD_F(0x07a2be39) /* 0.477232193 */, 18 }, - /* 6653 */ { MAD_F(0x07a32287) /* 0.477327852 */, 18 }, - /* 6654 */ { MAD_F(0x07a386d7) /* 0.477423516 */, 18 }, - /* 6655 */ { MAD_F(0x07a3eb28) /* 0.477519185 */, 18 }, - - /* 6656 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 18 }, - /* 6657 */ { MAD_F(0x07a4b3ce) /* 0.477710537 */, 18 }, - /* 6658 */ { MAD_F(0x07a51822) /* 0.477806220 */, 18 }, - /* 6659 */ { MAD_F(0x07a57c78) /* 0.477901908 */, 18 }, - /* 6660 */ { MAD_F(0x07a5e0d0) /* 0.477997601 */, 18 }, - /* 6661 */ { MAD_F(0x07a64528) /* 0.478093299 */, 18 }, - /* 6662 */ { MAD_F(0x07a6a982) /* 0.478189001 */, 18 }, - /* 6663 */ { MAD_F(0x07a70ddd) /* 0.478284708 */, 18 }, - /* 6664 */ { MAD_F(0x07a7723a) /* 0.478380420 */, 18 }, - /* 6665 */ { MAD_F(0x07a7d698) /* 0.478476137 */, 18 }, - /* 6666 */ { MAD_F(0x07a83af7) /* 0.478571858 */, 18 }, - /* 6667 */ { MAD_F(0x07a89f57) /* 0.478667585 */, 18 }, - /* 6668 */ { MAD_F(0x07a903b9) /* 0.478763316 */, 18 }, - /* 6669 */ { MAD_F(0x07a9681c) /* 0.478859052 */, 18 }, - /* 6670 */ { MAD_F(0x07a9cc80) /* 0.478954793 */, 18 }, - /* 6671 */ { MAD_F(0x07aa30e5) /* 0.479050538 */, 18 }, - - /* 6672 */ { MAD_F(0x07aa954c) /* 0.479146288 */, 18 }, - /* 6673 */ { MAD_F(0x07aaf9b4) /* 0.479242043 */, 18 }, - /* 6674 */ { MAD_F(0x07ab5e1e) /* 0.479337803 */, 18 }, - /* 6675 */ { MAD_F(0x07abc288) /* 0.479433568 */, 18 }, - /* 6676 */ { MAD_F(0x07ac26f4) /* 0.479529337 */, 18 }, - /* 6677 */ { MAD_F(0x07ac8b61) /* 0.479625111 */, 18 }, - /* 6678 */ { MAD_F(0x07acefd0) /* 0.479720890 */, 18 }, - /* 6679 */ { MAD_F(0x07ad543f) /* 0.479816674 */, 18 }, - /* 6680 */ { MAD_F(0x07adb8b0) /* 0.479912463 */, 18 }, - /* 6681 */ { MAD_F(0x07ae1d23) /* 0.480008256 */, 18 }, - /* 6682 */ { MAD_F(0x07ae8196) /* 0.480104054 */, 18 }, - /* 6683 */ { MAD_F(0x07aee60b) /* 0.480199857 */, 18 }, - /* 6684 */ { MAD_F(0x07af4a81) /* 0.480295664 */, 18 }, - /* 6685 */ { MAD_F(0x07afaef9) /* 0.480391477 */, 18 }, - /* 6686 */ { MAD_F(0x07b01372) /* 0.480487294 */, 18 }, - /* 6687 */ { MAD_F(0x07b077ec) /* 0.480583116 */, 18 }, - - /* 6688 */ { MAD_F(0x07b0dc67) /* 0.480678943 */, 18 }, - /* 6689 */ { MAD_F(0x07b140e4) /* 0.480774774 */, 18 }, - /* 6690 */ { MAD_F(0x07b1a561) /* 0.480870611 */, 18 }, - /* 6691 */ { MAD_F(0x07b209e1) /* 0.480966452 */, 18 }, - /* 6692 */ { MAD_F(0x07b26e61) /* 0.481062298 */, 18 }, - /* 6693 */ { MAD_F(0x07b2d2e3) /* 0.481158148 */, 18 }, - /* 6694 */ { MAD_F(0x07b33766) /* 0.481254004 */, 18 }, - /* 6695 */ { MAD_F(0x07b39bea) /* 0.481349864 */, 18 }, - /* 6696 */ { MAD_F(0x07b4006f) /* 0.481445729 */, 18 }, - /* 6697 */ { MAD_F(0x07b464f6) /* 0.481541598 */, 18 }, - /* 6698 */ { MAD_F(0x07b4c97e) /* 0.481637473 */, 18 }, - /* 6699 */ { MAD_F(0x07b52e08) /* 0.481733352 */, 18 }, - /* 6700 */ { MAD_F(0x07b59292) /* 0.481829236 */, 18 }, - /* 6701 */ { MAD_F(0x07b5f71e) /* 0.481925125 */, 18 }, - /* 6702 */ { MAD_F(0x07b65bac) /* 0.482021019 */, 18 }, - /* 6703 */ { MAD_F(0x07b6c03a) /* 0.482116917 */, 18 }, - - /* 6704 */ { MAD_F(0x07b724ca) /* 0.482212820 */, 18 }, - /* 6705 */ { MAD_F(0x07b7895b) /* 0.482308728 */, 18 }, - /* 6706 */ { MAD_F(0x07b7eded) /* 0.482404640 */, 18 }, - /* 6707 */ { MAD_F(0x07b85281) /* 0.482500558 */, 18 }, - /* 6708 */ { MAD_F(0x07b8b716) /* 0.482596480 */, 18 }, - /* 6709 */ { MAD_F(0x07b91bac) /* 0.482692407 */, 18 }, - /* 6710 */ { MAD_F(0x07b98044) /* 0.482788339 */, 18 }, - /* 6711 */ { MAD_F(0x07b9e4dc) /* 0.482884275 */, 18 }, - /* 6712 */ { MAD_F(0x07ba4976) /* 0.482980216 */, 18 }, - /* 6713 */ { MAD_F(0x07baae12) /* 0.483076162 */, 18 }, - /* 6714 */ { MAD_F(0x07bb12ae) /* 0.483172113 */, 18 }, - /* 6715 */ { MAD_F(0x07bb774c) /* 0.483268069 */, 18 }, - /* 6716 */ { MAD_F(0x07bbdbeb) /* 0.483364029 */, 18 }, - /* 6717 */ { MAD_F(0x07bc408c) /* 0.483459994 */, 18 }, - /* 6718 */ { MAD_F(0x07bca52d) /* 0.483555964 */, 18 }, - /* 6719 */ { MAD_F(0x07bd09d0) /* 0.483651939 */, 18 }, - - /* 6720 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 18 }, - /* 6721 */ { MAD_F(0x07bdd31a) /* 0.483843902 */, 18 }, - /* 6722 */ { MAD_F(0x07be37c1) /* 0.483939891 */, 18 }, - /* 6723 */ { MAD_F(0x07be9c69) /* 0.484035885 */, 18 }, - /* 6724 */ { MAD_F(0x07bf0113) /* 0.484131883 */, 18 }, - /* 6725 */ { MAD_F(0x07bf65bd) /* 0.484227886 */, 18 }, - /* 6726 */ { MAD_F(0x07bfca69) /* 0.484323894 */, 18 }, - /* 6727 */ { MAD_F(0x07c02f16) /* 0.484419907 */, 18 }, - /* 6728 */ { MAD_F(0x07c093c5) /* 0.484515924 */, 18 }, - /* 6729 */ { MAD_F(0x07c0f875) /* 0.484611946 */, 18 }, - /* 6730 */ { MAD_F(0x07c15d26) /* 0.484707973 */, 18 }, - /* 6731 */ { MAD_F(0x07c1c1d8) /* 0.484804005 */, 18 }, - /* 6732 */ { MAD_F(0x07c2268b) /* 0.484900041 */, 18 }, - /* 6733 */ { MAD_F(0x07c28b40) /* 0.484996083 */, 18 }, - /* 6734 */ { MAD_F(0x07c2eff6) /* 0.485092128 */, 18 }, - /* 6735 */ { MAD_F(0x07c354ae) /* 0.485188179 */, 18 }, - - /* 6736 */ { MAD_F(0x07c3b967) /* 0.485284235 */, 18 }, - /* 6737 */ { MAD_F(0x07c41e21) /* 0.485380295 */, 18 }, - /* 6738 */ { MAD_F(0x07c482dc) /* 0.485476360 */, 18 }, - /* 6739 */ { MAD_F(0x07c4e798) /* 0.485572430 */, 18 }, - /* 6740 */ { MAD_F(0x07c54c56) /* 0.485668504 */, 18 }, - /* 6741 */ { MAD_F(0x07c5b115) /* 0.485764583 */, 18 }, - /* 6742 */ { MAD_F(0x07c615d6) /* 0.485860667 */, 18 }, - /* 6743 */ { MAD_F(0x07c67a97) /* 0.485956756 */, 18 }, - /* 6744 */ { MAD_F(0x07c6df5a) /* 0.486052849 */, 18 }, - /* 6745 */ { MAD_F(0x07c7441e) /* 0.486148948 */, 18 }, - /* 6746 */ { MAD_F(0x07c7a8e4) /* 0.486245051 */, 18 }, - /* 6747 */ { MAD_F(0x07c80daa) /* 0.486341158 */, 18 }, - /* 6748 */ { MAD_F(0x07c87272) /* 0.486437271 */, 18 }, - /* 6749 */ { MAD_F(0x07c8d73c) /* 0.486533388 */, 18 }, - /* 6750 */ { MAD_F(0x07c93c06) /* 0.486629510 */, 18 }, - /* 6751 */ { MAD_F(0x07c9a0d2) /* 0.486725637 */, 18 }, - - /* 6752 */ { MAD_F(0x07ca059f) /* 0.486821768 */, 18 }, - /* 6753 */ { MAD_F(0x07ca6a6d) /* 0.486917905 */, 18 }, - /* 6754 */ { MAD_F(0x07cacf3d) /* 0.487014045 */, 18 }, - /* 6755 */ { MAD_F(0x07cb340e) /* 0.487110191 */, 18 }, - /* 6756 */ { MAD_F(0x07cb98e0) /* 0.487206342 */, 18 }, - /* 6757 */ { MAD_F(0x07cbfdb4) /* 0.487302497 */, 18 }, - /* 6758 */ { MAD_F(0x07cc6288) /* 0.487398657 */, 18 }, - /* 6759 */ { MAD_F(0x07ccc75e) /* 0.487494821 */, 18 }, - /* 6760 */ { MAD_F(0x07cd2c36) /* 0.487590991 */, 18 }, - /* 6761 */ { MAD_F(0x07cd910e) /* 0.487687165 */, 18 }, - /* 6762 */ { MAD_F(0x07cdf5e8) /* 0.487783344 */, 18 }, - /* 6763 */ { MAD_F(0x07ce5ac3) /* 0.487879528 */, 18 }, - /* 6764 */ { MAD_F(0x07cebfa0) /* 0.487975716 */, 18 }, - /* 6765 */ { MAD_F(0x07cf247d) /* 0.488071909 */, 18 }, - /* 6766 */ { MAD_F(0x07cf895c) /* 0.488168107 */, 18 }, - /* 6767 */ { MAD_F(0x07cfee3c) /* 0.488264310 */, 18 }, - - /* 6768 */ { MAD_F(0x07d0531e) /* 0.488360517 */, 18 }, - /* 6769 */ { MAD_F(0x07d0b801) /* 0.488456729 */, 18 }, - /* 6770 */ { MAD_F(0x07d11ce5) /* 0.488552946 */, 18 }, - /* 6771 */ { MAD_F(0x07d181ca) /* 0.488649167 */, 18 }, - /* 6772 */ { MAD_F(0x07d1e6b0) /* 0.488745394 */, 18 }, - /* 6773 */ { MAD_F(0x07d24b98) /* 0.488841625 */, 18 }, - /* 6774 */ { MAD_F(0x07d2b081) /* 0.488937860 */, 18 }, - /* 6775 */ { MAD_F(0x07d3156c) /* 0.489034101 */, 18 }, - /* 6776 */ { MAD_F(0x07d37a57) /* 0.489130346 */, 18 }, - /* 6777 */ { MAD_F(0x07d3df44) /* 0.489226596 */, 18 }, - /* 6778 */ { MAD_F(0x07d44432) /* 0.489322851 */, 18 }, - /* 6779 */ { MAD_F(0x07d4a922) /* 0.489419110 */, 18 }, - /* 6780 */ { MAD_F(0x07d50e13) /* 0.489515375 */, 18 }, - /* 6781 */ { MAD_F(0x07d57305) /* 0.489611643 */, 18 }, - /* 6782 */ { MAD_F(0x07d5d7f8) /* 0.489707917 */, 18 }, - /* 6783 */ { MAD_F(0x07d63cec) /* 0.489804195 */, 18 }, - - /* 6784 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 18 }, - /* 6785 */ { MAD_F(0x07d706d9) /* 0.489996766 */, 18 }, - /* 6786 */ { MAD_F(0x07d76bd2) /* 0.490093059 */, 18 }, - /* 6787 */ { MAD_F(0x07d7d0cb) /* 0.490189356 */, 18 }, - /* 6788 */ { MAD_F(0x07d835c6) /* 0.490285658 */, 18 }, - /* 6789 */ { MAD_F(0x07d89ac2) /* 0.490381965 */, 18 }, - /* 6790 */ { MAD_F(0x07d8ffc0) /* 0.490478277 */, 18 }, - /* 6791 */ { MAD_F(0x07d964be) /* 0.490574593 */, 18 }, - /* 6792 */ { MAD_F(0x07d9c9be) /* 0.490670914 */, 18 }, - /* 6793 */ { MAD_F(0x07da2ebf) /* 0.490767239 */, 18 }, - /* 6794 */ { MAD_F(0x07da93c2) /* 0.490863570 */, 18 }, - /* 6795 */ { MAD_F(0x07daf8c6) /* 0.490959905 */, 18 }, - /* 6796 */ { MAD_F(0x07db5dcb) /* 0.491056245 */, 18 }, - /* 6797 */ { MAD_F(0x07dbc2d1) /* 0.491152589 */, 18 }, - /* 6798 */ { MAD_F(0x07dc27d9) /* 0.491248939 */, 18 }, - /* 6799 */ { MAD_F(0x07dc8ce1) /* 0.491345293 */, 18 }, - - /* 6800 */ { MAD_F(0x07dcf1ec) /* 0.491441651 */, 18 }, - /* 6801 */ { MAD_F(0x07dd56f7) /* 0.491538015 */, 18 }, - /* 6802 */ { MAD_F(0x07ddbc04) /* 0.491634383 */, 18 }, - /* 6803 */ { MAD_F(0x07de2111) /* 0.491730756 */, 18 }, - /* 6804 */ { MAD_F(0x07de8621) /* 0.491827134 */, 18 }, - /* 6805 */ { MAD_F(0x07deeb31) /* 0.491923516 */, 18 }, - /* 6806 */ { MAD_F(0x07df5043) /* 0.492019903 */, 18 }, - /* 6807 */ { MAD_F(0x07dfb556) /* 0.492116295 */, 18 }, - /* 6808 */ { MAD_F(0x07e01a6a) /* 0.492212691 */, 18 }, - /* 6809 */ { MAD_F(0x07e07f80) /* 0.492309093 */, 18 }, - /* 6810 */ { MAD_F(0x07e0e496) /* 0.492405499 */, 18 }, - /* 6811 */ { MAD_F(0x07e149ae) /* 0.492501909 */, 18 }, - /* 6812 */ { MAD_F(0x07e1aec8) /* 0.492598325 */, 18 }, - /* 6813 */ { MAD_F(0x07e213e2) /* 0.492694745 */, 18 }, - /* 6814 */ { MAD_F(0x07e278fe) /* 0.492791170 */, 18 }, - /* 6815 */ { MAD_F(0x07e2de1b) /* 0.492887599 */, 18 }, - - /* 6816 */ { MAD_F(0x07e3433a) /* 0.492984033 */, 18 }, - /* 6817 */ { MAD_F(0x07e3a859) /* 0.493080472 */, 18 }, - /* 6818 */ { MAD_F(0x07e40d7a) /* 0.493176916 */, 18 }, - /* 6819 */ { MAD_F(0x07e4729c) /* 0.493273365 */, 18 }, - /* 6820 */ { MAD_F(0x07e4d7c0) /* 0.493369818 */, 18 }, - /* 6821 */ { MAD_F(0x07e53ce4) /* 0.493466275 */, 18 }, - /* 6822 */ { MAD_F(0x07e5a20a) /* 0.493562738 */, 18 }, - /* 6823 */ { MAD_F(0x07e60732) /* 0.493659205 */, 18 }, - /* 6824 */ { MAD_F(0x07e66c5a) /* 0.493755677 */, 18 }, - /* 6825 */ { MAD_F(0x07e6d184) /* 0.493852154 */, 18 }, - /* 6826 */ { MAD_F(0x07e736af) /* 0.493948635 */, 18 }, - /* 6827 */ { MAD_F(0x07e79bdb) /* 0.494045122 */, 18 }, - /* 6828 */ { MAD_F(0x07e80109) /* 0.494141612 */, 18 }, - /* 6829 */ { MAD_F(0x07e86638) /* 0.494238108 */, 18 }, - /* 6830 */ { MAD_F(0x07e8cb68) /* 0.494334608 */, 18 }, - /* 6831 */ { MAD_F(0x07e93099) /* 0.494431113 */, 18 }, - - /* 6832 */ { MAD_F(0x07e995cc) /* 0.494527623 */, 18 }, - /* 6833 */ { MAD_F(0x07e9fb00) /* 0.494624137 */, 18 }, - /* 6834 */ { MAD_F(0x07ea6035) /* 0.494720656 */, 18 }, - /* 6835 */ { MAD_F(0x07eac56b) /* 0.494817180 */, 18 }, - /* 6836 */ { MAD_F(0x07eb2aa3) /* 0.494913709 */, 18 }, - /* 6837 */ { MAD_F(0x07eb8fdc) /* 0.495010242 */, 18 }, - /* 6838 */ { MAD_F(0x07ebf516) /* 0.495106780 */, 18 }, - /* 6839 */ { MAD_F(0x07ec5a51) /* 0.495203322 */, 18 }, - /* 6840 */ { MAD_F(0x07ecbf8e) /* 0.495299870 */, 18 }, - /* 6841 */ { MAD_F(0x07ed24cc) /* 0.495396422 */, 18 }, - /* 6842 */ { MAD_F(0x07ed8a0b) /* 0.495492978 */, 18 }, - /* 6843 */ { MAD_F(0x07edef4c) /* 0.495589540 */, 18 }, - /* 6844 */ { MAD_F(0x07ee548e) /* 0.495686106 */, 18 }, - /* 6845 */ { MAD_F(0x07eeb9d1) /* 0.495782677 */, 18 }, - /* 6846 */ { MAD_F(0x07ef1f15) /* 0.495879252 */, 18 }, - /* 6847 */ { MAD_F(0x07ef845b) /* 0.495975833 */, 18 }, - - /* 6848 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 18 }, - /* 6849 */ { MAD_F(0x07f04ee9) /* 0.496169007 */, 18 }, - /* 6850 */ { MAD_F(0x07f0b433) /* 0.496265602 */, 18 }, - /* 6851 */ { MAD_F(0x07f1197d) /* 0.496362201 */, 18 }, - /* 6852 */ { MAD_F(0x07f17ec9) /* 0.496458804 */, 18 }, - /* 6853 */ { MAD_F(0x07f1e416) /* 0.496555413 */, 18 }, - /* 6854 */ { MAD_F(0x07f24965) /* 0.496652026 */, 18 }, - /* 6855 */ { MAD_F(0x07f2aeb5) /* 0.496748644 */, 18 }, - /* 6856 */ { MAD_F(0x07f31405) /* 0.496845266 */, 18 }, - /* 6857 */ { MAD_F(0x07f37958) /* 0.496941894 */, 18 }, - /* 6858 */ { MAD_F(0x07f3deab) /* 0.497038526 */, 18 }, - /* 6859 */ { MAD_F(0x07f44400) /* 0.497135162 */, 18 }, - /* 6860 */ { MAD_F(0x07f4a956) /* 0.497231804 */, 18 }, - /* 6861 */ { MAD_F(0x07f50ead) /* 0.497328450 */, 18 }, - /* 6862 */ { MAD_F(0x07f57405) /* 0.497425100 */, 18 }, - /* 6863 */ { MAD_F(0x07f5d95f) /* 0.497521756 */, 18 }, - - /* 6864 */ { MAD_F(0x07f63eba) /* 0.497618416 */, 18 }, - /* 6865 */ { MAD_F(0x07f6a416) /* 0.497715081 */, 18 }, - /* 6866 */ { MAD_F(0x07f70974) /* 0.497811750 */, 18 }, - /* 6867 */ { MAD_F(0x07f76ed3) /* 0.497908425 */, 18 }, - /* 6868 */ { MAD_F(0x07f7d433) /* 0.498005103 */, 18 }, - /* 6869 */ { MAD_F(0x07f83994) /* 0.498101787 */, 18 }, - /* 6870 */ { MAD_F(0x07f89ef7) /* 0.498198475 */, 18 }, - /* 6871 */ { MAD_F(0x07f9045a) /* 0.498295168 */, 18 }, - /* 6872 */ { MAD_F(0x07f969c0) /* 0.498391866 */, 18 }, - /* 6873 */ { MAD_F(0x07f9cf26) /* 0.498488568 */, 18 }, - /* 6874 */ { MAD_F(0x07fa348e) /* 0.498585275 */, 18 }, - /* 6875 */ { MAD_F(0x07fa99f6) /* 0.498681987 */, 18 }, - /* 6876 */ { MAD_F(0x07faff60) /* 0.498778704 */, 18 }, - /* 6877 */ { MAD_F(0x07fb64cc) /* 0.498875425 */, 18 }, - /* 6878 */ { MAD_F(0x07fbca38) /* 0.498972150 */, 18 }, - /* 6879 */ { MAD_F(0x07fc2fa6) /* 0.499068881 */, 18 }, - - /* 6880 */ { MAD_F(0x07fc9516) /* 0.499165616 */, 18 }, - /* 6881 */ { MAD_F(0x07fcfa86) /* 0.499262356 */, 18 }, - /* 6882 */ { MAD_F(0x07fd5ff8) /* 0.499359101 */, 18 }, - /* 6883 */ { MAD_F(0x07fdc56b) /* 0.499455850 */, 18 }, - /* 6884 */ { MAD_F(0x07fe2adf) /* 0.499552604 */, 18 }, - /* 6885 */ { MAD_F(0x07fe9054) /* 0.499649362 */, 18 }, - /* 6886 */ { MAD_F(0x07fef5cb) /* 0.499746126 */, 18 }, - /* 6887 */ { MAD_F(0x07ff5b43) /* 0.499842894 */, 18 }, - /* 6888 */ { MAD_F(0x07ffc0bc) /* 0.499939666 */, 18 }, - /* 6889 */ { MAD_F(0x0400131b) /* 0.250018222 */, 19 }, - /* 6890 */ { MAD_F(0x040045d9) /* 0.250066613 */, 19 }, - /* 6891 */ { MAD_F(0x04007897) /* 0.250115006 */, 19 }, - /* 6892 */ { MAD_F(0x0400ab57) /* 0.250163402 */, 19 }, - /* 6893 */ { MAD_F(0x0400de16) /* 0.250211800 */, 19 }, - /* 6894 */ { MAD_F(0x040110d7) /* 0.250260200 */, 19 }, - /* 6895 */ { MAD_F(0x04014398) /* 0.250308603 */, 19 }, - - /* 6896 */ { MAD_F(0x04017659) /* 0.250357008 */, 19 }, - /* 6897 */ { MAD_F(0x0401a91c) /* 0.250405415 */, 19 }, - /* 6898 */ { MAD_F(0x0401dbdf) /* 0.250453825 */, 19 }, - /* 6899 */ { MAD_F(0x04020ea2) /* 0.250502237 */, 19 }, - /* 6900 */ { MAD_F(0x04024166) /* 0.250550652 */, 19 }, - /* 6901 */ { MAD_F(0x0402742b) /* 0.250599068 */, 19 }, - /* 6902 */ { MAD_F(0x0402a6f0) /* 0.250647488 */, 19 }, - /* 6903 */ { MAD_F(0x0402d9b6) /* 0.250695909 */, 19 }, - /* 6904 */ { MAD_F(0x04030c7d) /* 0.250744333 */, 19 }, - /* 6905 */ { MAD_F(0x04033f44) /* 0.250792759 */, 19 }, - /* 6906 */ { MAD_F(0x0403720c) /* 0.250841187 */, 19 }, - /* 6907 */ { MAD_F(0x0403a4d5) /* 0.250889618 */, 19 }, - /* 6908 */ { MAD_F(0x0403d79e) /* 0.250938051 */, 19 }, - /* 6909 */ { MAD_F(0x04040a68) /* 0.250986487 */, 19 }, - /* 6910 */ { MAD_F(0x04043d32) /* 0.251034924 */, 19 }, - /* 6911 */ { MAD_F(0x04046ffd) /* 0.251083365 */, 19 }, - - /* 6912 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 19 }, - /* 6913 */ { MAD_F(0x0404d595) /* 0.251180252 */, 19 }, - /* 6914 */ { MAD_F(0x04050862) /* 0.251228699 */, 19 }, - /* 6915 */ { MAD_F(0x04053b30) /* 0.251277148 */, 19 }, - /* 6916 */ { MAD_F(0x04056dfe) /* 0.251325600 */, 19 }, - /* 6917 */ { MAD_F(0x0405a0cd) /* 0.251374054 */, 19 }, - /* 6918 */ { MAD_F(0x0405d39c) /* 0.251422511 */, 19 }, - /* 6919 */ { MAD_F(0x0406066c) /* 0.251470970 */, 19 }, - /* 6920 */ { MAD_F(0x0406393d) /* 0.251519431 */, 19 }, - /* 6921 */ { MAD_F(0x04066c0e) /* 0.251567894 */, 19 }, - /* 6922 */ { MAD_F(0x04069ee0) /* 0.251616360 */, 19 }, - /* 6923 */ { MAD_F(0x0406d1b3) /* 0.251664828 */, 19 }, - /* 6924 */ { MAD_F(0x04070486) /* 0.251713299 */, 19 }, - /* 6925 */ { MAD_F(0x0407375a) /* 0.251761772 */, 19 }, - /* 6926 */ { MAD_F(0x04076a2e) /* 0.251810247 */, 19 }, - /* 6927 */ { MAD_F(0x04079d03) /* 0.251858724 */, 19 }, - - /* 6928 */ { MAD_F(0x0407cfd9) /* 0.251907204 */, 19 }, - /* 6929 */ { MAD_F(0x040802af) /* 0.251955686 */, 19 }, - /* 6930 */ { MAD_F(0x04083586) /* 0.252004171 */, 19 }, - /* 6931 */ { MAD_F(0x0408685e) /* 0.252052658 */, 19 }, - /* 6932 */ { MAD_F(0x04089b36) /* 0.252101147 */, 19 }, - /* 6933 */ { MAD_F(0x0408ce0f) /* 0.252149638 */, 19 }, - /* 6934 */ { MAD_F(0x040900e8) /* 0.252198132 */, 19 }, - /* 6935 */ { MAD_F(0x040933c2) /* 0.252246628 */, 19 }, - /* 6936 */ { MAD_F(0x0409669d) /* 0.252295127 */, 19 }, - /* 6937 */ { MAD_F(0x04099978) /* 0.252343627 */, 19 }, - /* 6938 */ { MAD_F(0x0409cc54) /* 0.252392131 */, 19 }, - /* 6939 */ { MAD_F(0x0409ff31) /* 0.252440636 */, 19 }, - /* 6940 */ { MAD_F(0x040a320e) /* 0.252489144 */, 19 }, - /* 6941 */ { MAD_F(0x040a64ec) /* 0.252537654 */, 19 }, - /* 6942 */ { MAD_F(0x040a97cb) /* 0.252586166 */, 19 }, - /* 6943 */ { MAD_F(0x040acaaa) /* 0.252634681 */, 19 }, - - /* 6944 */ { MAD_F(0x040afd89) /* 0.252683198 */, 19 }, - /* 6945 */ { MAD_F(0x040b306a) /* 0.252731718 */, 19 }, - /* 6946 */ { MAD_F(0x040b634b) /* 0.252780240 */, 19 }, - /* 6947 */ { MAD_F(0x040b962c) /* 0.252828764 */, 19 }, - /* 6948 */ { MAD_F(0x040bc90e) /* 0.252877290 */, 19 }, - /* 6949 */ { MAD_F(0x040bfbf1) /* 0.252925819 */, 19 }, - /* 6950 */ { MAD_F(0x040c2ed5) /* 0.252974350 */, 19 }, - /* 6951 */ { MAD_F(0x040c61b9) /* 0.253022883 */, 19 }, - /* 6952 */ { MAD_F(0x040c949e) /* 0.253071419 */, 19 }, - /* 6953 */ { MAD_F(0x040cc783) /* 0.253119957 */, 19 }, - /* 6954 */ { MAD_F(0x040cfa69) /* 0.253168498 */, 19 }, - /* 6955 */ { MAD_F(0x040d2d4f) /* 0.253217040 */, 19 }, - /* 6956 */ { MAD_F(0x040d6037) /* 0.253265585 */, 19 }, - /* 6957 */ { MAD_F(0x040d931e) /* 0.253314133 */, 19 }, - /* 6958 */ { MAD_F(0x040dc607) /* 0.253362682 */, 19 }, - /* 6959 */ { MAD_F(0x040df8f0) /* 0.253411234 */, 19 }, - - /* 6960 */ { MAD_F(0x040e2bda) /* 0.253459789 */, 19 }, - /* 6961 */ { MAD_F(0x040e5ec4) /* 0.253508345 */, 19 }, - /* 6962 */ { MAD_F(0x040e91af) /* 0.253556904 */, 19 }, - /* 6963 */ { MAD_F(0x040ec49b) /* 0.253605466 */, 19 }, - /* 6964 */ { MAD_F(0x040ef787) /* 0.253654029 */, 19 }, - /* 6965 */ { MAD_F(0x040f2a74) /* 0.253702595 */, 19 }, - /* 6966 */ { MAD_F(0x040f5d61) /* 0.253751164 */, 19 }, - /* 6967 */ { MAD_F(0x040f904f) /* 0.253799734 */, 19 }, - /* 6968 */ { MAD_F(0x040fc33e) /* 0.253848307 */, 19 }, - /* 6969 */ { MAD_F(0x040ff62d) /* 0.253896883 */, 19 }, - /* 6970 */ { MAD_F(0x0410291d) /* 0.253945460 */, 19 }, - /* 6971 */ { MAD_F(0x04105c0e) /* 0.253994040 */, 19 }, - /* 6972 */ { MAD_F(0x04108eff) /* 0.254042622 */, 19 }, - /* 6973 */ { MAD_F(0x0410c1f1) /* 0.254091207 */, 19 }, - /* 6974 */ { MAD_F(0x0410f4e3) /* 0.254139794 */, 19 }, - /* 6975 */ { MAD_F(0x041127d6) /* 0.254188383 */, 19 }, - - /* 6976 */ { MAD_F(0x04115aca) /* 0.254236974 */, 19 }, - /* 6977 */ { MAD_F(0x04118dbe) /* 0.254285568 */, 19 }, - /* 6978 */ { MAD_F(0x0411c0b3) /* 0.254334165 */, 19 }, - /* 6979 */ { MAD_F(0x0411f3a9) /* 0.254382763 */, 19 }, - /* 6980 */ { MAD_F(0x0412269f) /* 0.254431364 */, 19 }, - /* 6981 */ { MAD_F(0x04125996) /* 0.254479967 */, 19 }, - /* 6982 */ { MAD_F(0x04128c8d) /* 0.254528572 */, 19 }, - /* 6983 */ { MAD_F(0x0412bf85) /* 0.254577180 */, 19 }, - /* 6984 */ { MAD_F(0x0412f27e) /* 0.254625790 */, 19 }, - /* 6985 */ { MAD_F(0x04132577) /* 0.254674403 */, 19 }, - /* 6986 */ { MAD_F(0x04135871) /* 0.254723017 */, 19 }, - /* 6987 */ { MAD_F(0x04138b6c) /* 0.254771635 */, 19 }, - /* 6988 */ { MAD_F(0x0413be67) /* 0.254820254 */, 19 }, - /* 6989 */ { MAD_F(0x0413f163) /* 0.254868876 */, 19 }, - /* 6990 */ { MAD_F(0x0414245f) /* 0.254917500 */, 19 }, - /* 6991 */ { MAD_F(0x0414575c) /* 0.254966126 */, 19 }, - - /* 6992 */ { MAD_F(0x04148a5a) /* 0.255014755 */, 19 }, - /* 6993 */ { MAD_F(0x0414bd58) /* 0.255063386 */, 19 }, - /* 6994 */ { MAD_F(0x0414f057) /* 0.255112019 */, 19 }, - /* 6995 */ { MAD_F(0x04152356) /* 0.255160655 */, 19 }, - /* 6996 */ { MAD_F(0x04155657) /* 0.255209292 */, 19 }, - /* 6997 */ { MAD_F(0x04158957) /* 0.255257933 */, 19 }, - /* 6998 */ { MAD_F(0x0415bc59) /* 0.255306575 */, 19 }, - /* 6999 */ { MAD_F(0x0415ef5b) /* 0.255355220 */, 19 }, - /* 7000 */ { MAD_F(0x0416225d) /* 0.255403867 */, 19 }, - /* 7001 */ { MAD_F(0x04165561) /* 0.255452517 */, 19 }, - /* 7002 */ { MAD_F(0x04168864) /* 0.255501169 */, 19 }, - /* 7003 */ { MAD_F(0x0416bb69) /* 0.255549823 */, 19 }, - /* 7004 */ { MAD_F(0x0416ee6e) /* 0.255598479 */, 19 }, - /* 7005 */ { MAD_F(0x04172174) /* 0.255647138 */, 19 }, - /* 7006 */ { MAD_F(0x0417547a) /* 0.255695799 */, 19 }, - /* 7007 */ { MAD_F(0x04178781) /* 0.255744463 */, 19 }, - - /* 7008 */ { MAD_F(0x0417ba89) /* 0.255793128 */, 19 }, - /* 7009 */ { MAD_F(0x0417ed91) /* 0.255841796 */, 19 }, - /* 7010 */ { MAD_F(0x0418209a) /* 0.255890467 */, 19 }, - /* 7011 */ { MAD_F(0x041853a3) /* 0.255939139 */, 19 }, - /* 7012 */ { MAD_F(0x041886ad) /* 0.255987814 */, 19 }, - /* 7013 */ { MAD_F(0x0418b9b8) /* 0.256036492 */, 19 }, - /* 7014 */ { MAD_F(0x0418ecc3) /* 0.256085171 */, 19 }, - /* 7015 */ { MAD_F(0x04191fcf) /* 0.256133853 */, 19 }, - /* 7016 */ { MAD_F(0x041952dc) /* 0.256182537 */, 19 }, - /* 7017 */ { MAD_F(0x041985e9) /* 0.256231224 */, 19 }, - /* 7018 */ { MAD_F(0x0419b8f7) /* 0.256279913 */, 19 }, - /* 7019 */ { MAD_F(0x0419ec05) /* 0.256328604 */, 19 }, - /* 7020 */ { MAD_F(0x041a1f15) /* 0.256377297 */, 19 }, - /* 7021 */ { MAD_F(0x041a5224) /* 0.256425993 */, 19 }, - /* 7022 */ { MAD_F(0x041a8534) /* 0.256474691 */, 19 }, - /* 7023 */ { MAD_F(0x041ab845) /* 0.256523392 */, 19 }, - - /* 7024 */ { MAD_F(0x041aeb57) /* 0.256572095 */, 19 }, - /* 7025 */ { MAD_F(0x041b1e69) /* 0.256620800 */, 19 }, - /* 7026 */ { MAD_F(0x041b517c) /* 0.256669507 */, 19 }, - /* 7027 */ { MAD_F(0x041b848f) /* 0.256718217 */, 19 }, - /* 7028 */ { MAD_F(0x041bb7a3) /* 0.256766929 */, 19 }, - /* 7029 */ { MAD_F(0x041beab8) /* 0.256815643 */, 19 }, - /* 7030 */ { MAD_F(0x041c1dcd) /* 0.256864359 */, 19 }, - /* 7031 */ { MAD_F(0x041c50e3) /* 0.256913078 */, 19 }, - /* 7032 */ { MAD_F(0x041c83fa) /* 0.256961800 */, 19 }, - /* 7033 */ { MAD_F(0x041cb711) /* 0.257010523 */, 19 }, - /* 7034 */ { MAD_F(0x041cea28) /* 0.257059249 */, 19 }, - /* 7035 */ { MAD_F(0x041d1d41) /* 0.257107977 */, 19 }, - /* 7036 */ { MAD_F(0x041d505a) /* 0.257156708 */, 19 }, - /* 7037 */ { MAD_F(0x041d8373) /* 0.257205440 */, 19 }, - /* 7038 */ { MAD_F(0x041db68e) /* 0.257254175 */, 19 }, - /* 7039 */ { MAD_F(0x041de9a8) /* 0.257302913 */, 19 }, - - /* 7040 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 19 }, - /* 7041 */ { MAD_F(0x041e4fe0) /* 0.257400394 */, 19 }, - /* 7042 */ { MAD_F(0x041e82fd) /* 0.257449139 */, 19 }, - /* 7043 */ { MAD_F(0x041eb61a) /* 0.257497885 */, 19 }, - /* 7044 */ { MAD_F(0x041ee938) /* 0.257546634 */, 19 }, - /* 7045 */ { MAD_F(0x041f1c57) /* 0.257595386 */, 19 }, - /* 7046 */ { MAD_F(0x041f4f76) /* 0.257644139 */, 19 }, - /* 7047 */ { MAD_F(0x041f8296) /* 0.257692895 */, 19 }, - /* 7048 */ { MAD_F(0x041fb5b6) /* 0.257741653 */, 19 }, - /* 7049 */ { MAD_F(0x041fe8d7) /* 0.257790414 */, 19 }, - /* 7050 */ { MAD_F(0x04201bf9) /* 0.257839176 */, 19 }, - /* 7051 */ { MAD_F(0x04204f1b) /* 0.257887941 */, 19 }, - /* 7052 */ { MAD_F(0x0420823e) /* 0.257936709 */, 19 }, - /* 7053 */ { MAD_F(0x0420b561) /* 0.257985478 */, 19 }, - /* 7054 */ { MAD_F(0x0420e885) /* 0.258034250 */, 19 }, - /* 7055 */ { MAD_F(0x04211baa) /* 0.258083025 */, 19 }, - - /* 7056 */ { MAD_F(0x04214ed0) /* 0.258131801 */, 19 }, - /* 7057 */ { MAD_F(0x042181f6) /* 0.258180580 */, 19 }, - /* 7058 */ { MAD_F(0x0421b51c) /* 0.258229361 */, 19 }, - /* 7059 */ { MAD_F(0x0421e843) /* 0.258278145 */, 19 }, - /* 7060 */ { MAD_F(0x04221b6b) /* 0.258326931 */, 19 }, - /* 7061 */ { MAD_F(0x04224e94) /* 0.258375719 */, 19 }, - /* 7062 */ { MAD_F(0x042281bd) /* 0.258424509 */, 19 }, - /* 7063 */ { MAD_F(0x0422b4e6) /* 0.258473302 */, 19 }, - /* 7064 */ { MAD_F(0x0422e811) /* 0.258522097 */, 19 }, - /* 7065 */ { MAD_F(0x04231b3c) /* 0.258570894 */, 19 }, - /* 7066 */ { MAD_F(0x04234e67) /* 0.258619694 */, 19 }, - /* 7067 */ { MAD_F(0x04238193) /* 0.258668496 */, 19 }, - /* 7068 */ { MAD_F(0x0423b4c0) /* 0.258717300 */, 19 }, - /* 7069 */ { MAD_F(0x0423e7ee) /* 0.258766106 */, 19 }, - /* 7070 */ { MAD_F(0x04241b1c) /* 0.258814915 */, 19 }, - /* 7071 */ { MAD_F(0x04244e4a) /* 0.258863726 */, 19 }, - - /* 7072 */ { MAD_F(0x04248179) /* 0.258912540 */, 19 }, - /* 7073 */ { MAD_F(0x0424b4a9) /* 0.258961356 */, 19 }, - /* 7074 */ { MAD_F(0x0424e7da) /* 0.259010174 */, 19 }, - /* 7075 */ { MAD_F(0x04251b0b) /* 0.259058994 */, 19 }, - /* 7076 */ { MAD_F(0x04254e3d) /* 0.259107817 */, 19 }, - /* 7077 */ { MAD_F(0x0425816f) /* 0.259156642 */, 19 }, - /* 7078 */ { MAD_F(0x0425b4a2) /* 0.259205469 */, 19 }, - /* 7079 */ { MAD_F(0x0425e7d6) /* 0.259254298 */, 19 }, - /* 7080 */ { MAD_F(0x04261b0a) /* 0.259303130 */, 19 }, - /* 7081 */ { MAD_F(0x04264e3f) /* 0.259351964 */, 19 }, - /* 7082 */ { MAD_F(0x04268174) /* 0.259400801 */, 19 }, - /* 7083 */ { MAD_F(0x0426b4aa) /* 0.259449639 */, 19 }, - /* 7084 */ { MAD_F(0x0426e7e1) /* 0.259498480 */, 19 }, - /* 7085 */ { MAD_F(0x04271b18) /* 0.259547324 */, 19 }, - /* 7086 */ { MAD_F(0x04274e50) /* 0.259596169 */, 19 }, - /* 7087 */ { MAD_F(0x04278188) /* 0.259645017 */, 19 }, - - /* 7088 */ { MAD_F(0x0427b4c2) /* 0.259693868 */, 19 }, - /* 7089 */ { MAD_F(0x0427e7fb) /* 0.259742720 */, 19 }, - /* 7090 */ { MAD_F(0x04281b36) /* 0.259791575 */, 19 }, - /* 7091 */ { MAD_F(0x04284e71) /* 0.259840432 */, 19 }, - /* 7092 */ { MAD_F(0x042881ac) /* 0.259889291 */, 19 }, - /* 7093 */ { MAD_F(0x0428b4e8) /* 0.259938153 */, 19 }, - /* 7094 */ { MAD_F(0x0428e825) /* 0.259987017 */, 19 }, - /* 7095 */ { MAD_F(0x04291b63) /* 0.260035883 */, 19 }, - /* 7096 */ { MAD_F(0x04294ea1) /* 0.260084752 */, 19 }, - /* 7097 */ { MAD_F(0x042981df) /* 0.260133623 */, 19 }, - /* 7098 */ { MAD_F(0x0429b51f) /* 0.260182496 */, 19 }, - /* 7099 */ { MAD_F(0x0429e85f) /* 0.260231372 */, 19 }, - /* 7100 */ { MAD_F(0x042a1b9f) /* 0.260280249 */, 19 }, - /* 7101 */ { MAD_F(0x042a4ee0) /* 0.260329129 */, 19 }, - /* 7102 */ { MAD_F(0x042a8222) /* 0.260378012 */, 19 }, - /* 7103 */ { MAD_F(0x042ab564) /* 0.260426896 */, 19 }, - - /* 7104 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 19 }, - /* 7105 */ { MAD_F(0x042b1beb) /* 0.260524673 */, 19 }, - /* 7106 */ { MAD_F(0x042b4f2f) /* 0.260573564 */, 19 }, - /* 7107 */ { MAD_F(0x042b8274) /* 0.260622458 */, 19 }, - /* 7108 */ { MAD_F(0x042bb5ba) /* 0.260671354 */, 19 }, - /* 7109 */ { MAD_F(0x042be900) /* 0.260720252 */, 19 }, - /* 7110 */ { MAD_F(0x042c1c46) /* 0.260769153 */, 19 }, - /* 7111 */ { MAD_F(0x042c4f8e) /* 0.260818056 */, 19 }, - /* 7112 */ { MAD_F(0x042c82d6) /* 0.260866961 */, 19 }, - /* 7113 */ { MAD_F(0x042cb61e) /* 0.260915869 */, 19 }, - /* 7114 */ { MAD_F(0x042ce967) /* 0.260964779 */, 19 }, - /* 7115 */ { MAD_F(0x042d1cb1) /* 0.261013691 */, 19 }, - /* 7116 */ { MAD_F(0x042d4ffb) /* 0.261062606 */, 19 }, - /* 7117 */ { MAD_F(0x042d8346) /* 0.261111522 */, 19 }, - /* 7118 */ { MAD_F(0x042db692) /* 0.261160441 */, 19 }, - /* 7119 */ { MAD_F(0x042de9de) /* 0.261209363 */, 19 }, - - /* 7120 */ { MAD_F(0x042e1d2b) /* 0.261258286 */, 19 }, - /* 7121 */ { MAD_F(0x042e5078) /* 0.261307212 */, 19 }, - /* 7122 */ { MAD_F(0x042e83c6) /* 0.261356140 */, 19 }, - /* 7123 */ { MAD_F(0x042eb715) /* 0.261405071 */, 19 }, - /* 7124 */ { MAD_F(0x042eea64) /* 0.261454004 */, 19 }, - /* 7125 */ { MAD_F(0x042f1db4) /* 0.261502939 */, 19 }, - /* 7126 */ { MAD_F(0x042f5105) /* 0.261551876 */, 19 }, - /* 7127 */ { MAD_F(0x042f8456) /* 0.261600816 */, 19 }, - /* 7128 */ { MAD_F(0x042fb7a8) /* 0.261649758 */, 19 }, - /* 7129 */ { MAD_F(0x042feafa) /* 0.261698702 */, 19 }, - /* 7130 */ { MAD_F(0x04301e4d) /* 0.261747649 */, 19 }, - /* 7131 */ { MAD_F(0x043051a1) /* 0.261796597 */, 19 }, - /* 7132 */ { MAD_F(0x043084f5) /* 0.261845548 */, 19 }, - /* 7133 */ { MAD_F(0x0430b84a) /* 0.261894502 */, 19 }, - /* 7134 */ { MAD_F(0x0430eb9f) /* 0.261943458 */, 19 }, - /* 7135 */ { MAD_F(0x04311ef5) /* 0.261992416 */, 19 }, - - /* 7136 */ { MAD_F(0x0431524c) /* 0.262041376 */, 19 }, - /* 7137 */ { MAD_F(0x043185a3) /* 0.262090338 */, 19 }, - /* 7138 */ { MAD_F(0x0431b8fb) /* 0.262139303 */, 19 }, - /* 7139 */ { MAD_F(0x0431ec54) /* 0.262188270 */, 19 }, - /* 7140 */ { MAD_F(0x04321fad) /* 0.262237240 */, 19 }, - /* 7141 */ { MAD_F(0x04325306) /* 0.262286211 */, 19 }, - /* 7142 */ { MAD_F(0x04328661) /* 0.262335185 */, 19 }, - /* 7143 */ { MAD_F(0x0432b9bc) /* 0.262384162 */, 19 }, - /* 7144 */ { MAD_F(0x0432ed17) /* 0.262433140 */, 19 }, - /* 7145 */ { MAD_F(0x04332074) /* 0.262482121 */, 19 }, - /* 7146 */ { MAD_F(0x043353d0) /* 0.262531104 */, 19 }, - /* 7147 */ { MAD_F(0x0433872e) /* 0.262580089 */, 19 }, - /* 7148 */ { MAD_F(0x0433ba8c) /* 0.262629077 */, 19 }, - /* 7149 */ { MAD_F(0x0433edea) /* 0.262678067 */, 19 }, - /* 7150 */ { MAD_F(0x0434214a) /* 0.262727059 */, 19 }, - /* 7151 */ { MAD_F(0x043454aa) /* 0.262776054 */, 19 }, - - /* 7152 */ { MAD_F(0x0434880a) /* 0.262825051 */, 19 }, - /* 7153 */ { MAD_F(0x0434bb6b) /* 0.262874050 */, 19 }, - /* 7154 */ { MAD_F(0x0434eecd) /* 0.262923051 */, 19 }, - /* 7155 */ { MAD_F(0x0435222f) /* 0.262972055 */, 19 }, - /* 7156 */ { MAD_F(0x04355592) /* 0.263021061 */, 19 }, - /* 7157 */ { MAD_F(0x043588f6) /* 0.263070069 */, 19 }, - /* 7158 */ { MAD_F(0x0435bc5a) /* 0.263119079 */, 19 }, - /* 7159 */ { MAD_F(0x0435efbf) /* 0.263168092 */, 19 }, - /* 7160 */ { MAD_F(0x04362324) /* 0.263217107 */, 19 }, - /* 7161 */ { MAD_F(0x0436568a) /* 0.263266125 */, 19 }, - /* 7162 */ { MAD_F(0x043689f1) /* 0.263315144 */, 19 }, - /* 7163 */ { MAD_F(0x0436bd58) /* 0.263364166 */, 19 }, - /* 7164 */ { MAD_F(0x0436f0c0) /* 0.263413191 */, 19 }, - /* 7165 */ { MAD_F(0x04372428) /* 0.263462217 */, 19 }, - /* 7166 */ { MAD_F(0x04375791) /* 0.263511246 */, 19 }, - /* 7167 */ { MAD_F(0x04378afb) /* 0.263560277 */, 19 }, - - /* 7168 */ { MAD_F(0x0437be65) /* 0.263609310 */, 19 }, - /* 7169 */ { MAD_F(0x0437f1d0) /* 0.263658346 */, 19 }, - /* 7170 */ { MAD_F(0x0438253c) /* 0.263707384 */, 19 }, - /* 7171 */ { MAD_F(0x043858a8) /* 0.263756424 */, 19 }, - /* 7172 */ { MAD_F(0x04388c14) /* 0.263805466 */, 19 }, - /* 7173 */ { MAD_F(0x0438bf82) /* 0.263854511 */, 19 }, - /* 7174 */ { MAD_F(0x0438f2f0) /* 0.263903558 */, 19 }, - /* 7175 */ { MAD_F(0x0439265e) /* 0.263952607 */, 19 }, - /* 7176 */ { MAD_F(0x043959cd) /* 0.264001659 */, 19 }, - /* 7177 */ { MAD_F(0x04398d3d) /* 0.264050713 */, 19 }, - /* 7178 */ { MAD_F(0x0439c0ae) /* 0.264099769 */, 19 }, - /* 7179 */ { MAD_F(0x0439f41f) /* 0.264148827 */, 19 }, - /* 7180 */ { MAD_F(0x043a2790) /* 0.264197888 */, 19 }, - /* 7181 */ { MAD_F(0x043a5b02) /* 0.264246951 */, 19 }, - /* 7182 */ { MAD_F(0x043a8e75) /* 0.264296016 */, 19 }, - /* 7183 */ { MAD_F(0x043ac1e9) /* 0.264345084 */, 19 }, - - /* 7184 */ { MAD_F(0x043af55d) /* 0.264394153 */, 19 }, - /* 7185 */ { MAD_F(0x043b28d2) /* 0.264443225 */, 19 }, - /* 7186 */ { MAD_F(0x043b5c47) /* 0.264492300 */, 19 }, - /* 7187 */ { MAD_F(0x043b8fbd) /* 0.264541376 */, 19 }, - /* 7188 */ { MAD_F(0x043bc333) /* 0.264590455 */, 19 }, - /* 7189 */ { MAD_F(0x043bf6aa) /* 0.264639536 */, 19 }, - /* 7190 */ { MAD_F(0x043c2a22) /* 0.264688620 */, 19 }, - /* 7191 */ { MAD_F(0x043c5d9a) /* 0.264737706 */, 19 }, - /* 7192 */ { MAD_F(0x043c9113) /* 0.264786794 */, 19 }, - /* 7193 */ { MAD_F(0x043cc48d) /* 0.264835884 */, 19 }, - /* 7194 */ { MAD_F(0x043cf807) /* 0.264884976 */, 19 }, - /* 7195 */ { MAD_F(0x043d2b82) /* 0.264934071 */, 19 }, - /* 7196 */ { MAD_F(0x043d5efd) /* 0.264983168 */, 19 }, - /* 7197 */ { MAD_F(0x043d9279) /* 0.265032268 */, 19 }, - /* 7198 */ { MAD_F(0x043dc5f6) /* 0.265081369 */, 19 }, - /* 7199 */ { MAD_F(0x043df973) /* 0.265130473 */, 19 }, - - /* 7200 */ { MAD_F(0x043e2cf1) /* 0.265179580 */, 19 }, - /* 7201 */ { MAD_F(0x043e6070) /* 0.265228688 */, 19 }, - /* 7202 */ { MAD_F(0x043e93ef) /* 0.265277799 */, 19 }, - /* 7203 */ { MAD_F(0x043ec76e) /* 0.265326912 */, 19 }, - /* 7204 */ { MAD_F(0x043efaef) /* 0.265376027 */, 19 }, - /* 7205 */ { MAD_F(0x043f2e6f) /* 0.265425145 */, 19 }, - /* 7206 */ { MAD_F(0x043f61f1) /* 0.265474264 */, 19 }, - /* 7207 */ { MAD_F(0x043f9573) /* 0.265523387 */, 19 }, - /* 7208 */ { MAD_F(0x043fc8f6) /* 0.265572511 */, 19 }, - /* 7209 */ { MAD_F(0x043ffc79) /* 0.265621638 */, 19 }, - /* 7210 */ { MAD_F(0x04402ffd) /* 0.265670766 */, 19 }, - /* 7211 */ { MAD_F(0x04406382) /* 0.265719898 */, 19 }, - /* 7212 */ { MAD_F(0x04409707) /* 0.265769031 */, 19 }, - /* 7213 */ { MAD_F(0x0440ca8d) /* 0.265818167 */, 19 }, - /* 7214 */ { MAD_F(0x0440fe13) /* 0.265867305 */, 19 }, - /* 7215 */ { MAD_F(0x0441319a) /* 0.265916445 */, 19 }, - - /* 7216 */ { MAD_F(0x04416522) /* 0.265965588 */, 19 }, - /* 7217 */ { MAD_F(0x044198aa) /* 0.266014732 */, 19 }, - /* 7218 */ { MAD_F(0x0441cc33) /* 0.266063880 */, 19 }, - /* 7219 */ { MAD_F(0x0441ffbc) /* 0.266113029 */, 19 }, - /* 7220 */ { MAD_F(0x04423346) /* 0.266162181 */, 19 }, - /* 7221 */ { MAD_F(0x044266d1) /* 0.266211334 */, 19 }, - /* 7222 */ { MAD_F(0x04429a5c) /* 0.266260491 */, 19 }, - /* 7223 */ { MAD_F(0x0442cde8) /* 0.266309649 */, 19 }, - /* 7224 */ { MAD_F(0x04430174) /* 0.266358810 */, 19 }, - /* 7225 */ { MAD_F(0x04433501) /* 0.266407973 */, 19 }, - /* 7226 */ { MAD_F(0x0443688f) /* 0.266457138 */, 19 }, - /* 7227 */ { MAD_F(0x04439c1d) /* 0.266506305 */, 19 }, - /* 7228 */ { MAD_F(0x0443cfac) /* 0.266555475 */, 19 }, - /* 7229 */ { MAD_F(0x0444033c) /* 0.266604647 */, 19 }, - /* 7230 */ { MAD_F(0x044436cc) /* 0.266653822 */, 19 }, - /* 7231 */ { MAD_F(0x04446a5d) /* 0.266702998 */, 19 }, - - /* 7232 */ { MAD_F(0x04449dee) /* 0.266752177 */, 19 }, - /* 7233 */ { MAD_F(0x0444d180) /* 0.266801358 */, 19 }, - /* 7234 */ { MAD_F(0x04450513) /* 0.266850541 */, 19 }, - /* 7235 */ { MAD_F(0x044538a6) /* 0.266899727 */, 19 }, - /* 7236 */ { MAD_F(0x04456c39) /* 0.266948915 */, 19 }, - /* 7237 */ { MAD_F(0x04459fce) /* 0.266998105 */, 19 }, - /* 7238 */ { MAD_F(0x0445d363) /* 0.267047298 */, 19 }, - /* 7239 */ { MAD_F(0x044606f8) /* 0.267096492 */, 19 }, - /* 7240 */ { MAD_F(0x04463a8f) /* 0.267145689 */, 19 }, - /* 7241 */ { MAD_F(0x04466e25) /* 0.267194888 */, 19 }, - /* 7242 */ { MAD_F(0x0446a1bd) /* 0.267244090 */, 19 }, - /* 7243 */ { MAD_F(0x0446d555) /* 0.267293294 */, 19 }, - /* 7244 */ { MAD_F(0x044708ee) /* 0.267342500 */, 19 }, - /* 7245 */ { MAD_F(0x04473c87) /* 0.267391708 */, 19 }, - /* 7246 */ { MAD_F(0x04477021) /* 0.267440919 */, 19 }, - /* 7247 */ { MAD_F(0x0447a3bb) /* 0.267490131 */, 19 }, - - /* 7248 */ { MAD_F(0x0447d756) /* 0.267539347 */, 19 }, - /* 7249 */ { MAD_F(0x04480af2) /* 0.267588564 */, 19 }, - /* 7250 */ { MAD_F(0x04483e8e) /* 0.267637783 */, 19 }, - /* 7251 */ { MAD_F(0x0448722b) /* 0.267687005 */, 19 }, - /* 7252 */ { MAD_F(0x0448a5c9) /* 0.267736229 */, 19 }, - /* 7253 */ { MAD_F(0x0448d967) /* 0.267785456 */, 19 }, - /* 7254 */ { MAD_F(0x04490d05) /* 0.267834685 */, 19 }, - /* 7255 */ { MAD_F(0x044940a5) /* 0.267883915 */, 19 }, - /* 7256 */ { MAD_F(0x04497445) /* 0.267933149 */, 19 }, - /* 7257 */ { MAD_F(0x0449a7e5) /* 0.267982384 */, 19 }, - /* 7258 */ { MAD_F(0x0449db86) /* 0.268031622 */, 19 }, - /* 7259 */ { MAD_F(0x044a0f28) /* 0.268080862 */, 19 }, - /* 7260 */ { MAD_F(0x044a42ca) /* 0.268130104 */, 19 }, - /* 7261 */ { MAD_F(0x044a766d) /* 0.268179349 */, 19 }, - /* 7262 */ { MAD_F(0x044aaa11) /* 0.268228595 */, 19 }, - /* 7263 */ { MAD_F(0x044addb5) /* 0.268277844 */, 19 }, - - /* 7264 */ { MAD_F(0x044b115a) /* 0.268327096 */, 19 }, - /* 7265 */ { MAD_F(0x044b44ff) /* 0.268376349 */, 19 }, - /* 7266 */ { MAD_F(0x044b78a5) /* 0.268425605 */, 19 }, - /* 7267 */ { MAD_F(0x044bac4c) /* 0.268474863 */, 19 }, - /* 7268 */ { MAD_F(0x044bdff3) /* 0.268524123 */, 19 }, - /* 7269 */ { MAD_F(0x044c139b) /* 0.268573386 */, 19 }, - /* 7270 */ { MAD_F(0x044c4743) /* 0.268622651 */, 19 }, - /* 7271 */ { MAD_F(0x044c7aec) /* 0.268671918 */, 19 }, - /* 7272 */ { MAD_F(0x044cae96) /* 0.268721187 */, 19 }, - /* 7273 */ { MAD_F(0x044ce240) /* 0.268770459 */, 19 }, - /* 7274 */ { MAD_F(0x044d15eb) /* 0.268819733 */, 19 }, - /* 7275 */ { MAD_F(0x044d4997) /* 0.268869009 */, 19 }, - /* 7276 */ { MAD_F(0x044d7d43) /* 0.268918287 */, 19 }, - /* 7277 */ { MAD_F(0x044db0ef) /* 0.268967568 */, 19 }, - /* 7278 */ { MAD_F(0x044de49d) /* 0.269016851 */, 19 }, - /* 7279 */ { MAD_F(0x044e184b) /* 0.269066136 */, 19 }, - - /* 7280 */ { MAD_F(0x044e4bf9) /* 0.269115423 */, 19 }, - /* 7281 */ { MAD_F(0x044e7fa8) /* 0.269164713 */, 19 }, - /* 7282 */ { MAD_F(0x044eb358) /* 0.269214005 */, 19 }, - /* 7283 */ { MAD_F(0x044ee708) /* 0.269263299 */, 19 }, - /* 7284 */ { MAD_F(0x044f1ab9) /* 0.269312595 */, 19 }, - /* 7285 */ { MAD_F(0x044f4e6b) /* 0.269361894 */, 19 }, - /* 7286 */ { MAD_F(0x044f821d) /* 0.269411195 */, 19 }, - /* 7287 */ { MAD_F(0x044fb5cf) /* 0.269460498 */, 19 }, - /* 7288 */ { MAD_F(0x044fe983) /* 0.269509804 */, 19 }, - /* 7289 */ { MAD_F(0x04501d37) /* 0.269559111 */, 19 }, - /* 7290 */ { MAD_F(0x045050eb) /* 0.269608421 */, 19 }, - /* 7291 */ { MAD_F(0x045084a0) /* 0.269657734 */, 19 }, - /* 7292 */ { MAD_F(0x0450b856) /* 0.269707048 */, 19 }, - /* 7293 */ { MAD_F(0x0450ec0d) /* 0.269756365 */, 19 }, - /* 7294 */ { MAD_F(0x04511fc4) /* 0.269805684 */, 19 }, - /* 7295 */ { MAD_F(0x0451537b) /* 0.269855005 */, 19 }, - - /* 7296 */ { MAD_F(0x04518733) /* 0.269904329 */, 19 }, - /* 7297 */ { MAD_F(0x0451baec) /* 0.269953654 */, 19 }, - /* 7298 */ { MAD_F(0x0451eea5) /* 0.270002982 */, 19 }, - /* 7299 */ { MAD_F(0x0452225f) /* 0.270052313 */, 19 }, - /* 7300 */ { MAD_F(0x0452561a) /* 0.270101645 */, 19 }, - /* 7301 */ { MAD_F(0x045289d5) /* 0.270150980 */, 19 }, - /* 7302 */ { MAD_F(0x0452bd91) /* 0.270200317 */, 19 }, - /* 7303 */ { MAD_F(0x0452f14d) /* 0.270249656 */, 19 }, - /* 7304 */ { MAD_F(0x0453250a) /* 0.270298998 */, 19 }, - /* 7305 */ { MAD_F(0x045358c8) /* 0.270348341 */, 19 }, - /* 7306 */ { MAD_F(0x04538c86) /* 0.270397687 */, 19 }, - /* 7307 */ { MAD_F(0x0453c045) /* 0.270447036 */, 19 }, - /* 7308 */ { MAD_F(0x0453f405) /* 0.270496386 */, 19 }, - /* 7309 */ { MAD_F(0x045427c5) /* 0.270545739 */, 19 }, - /* 7310 */ { MAD_F(0x04545b85) /* 0.270595094 */, 19 }, - /* 7311 */ { MAD_F(0x04548f46) /* 0.270644451 */, 19 }, - - /* 7312 */ { MAD_F(0x0454c308) /* 0.270693811 */, 19 }, - /* 7313 */ { MAD_F(0x0454f6cb) /* 0.270743173 */, 19 }, - /* 7314 */ { MAD_F(0x04552a8e) /* 0.270792537 */, 19 }, - /* 7315 */ { MAD_F(0x04555e51) /* 0.270841903 */, 19 }, - /* 7316 */ { MAD_F(0x04559216) /* 0.270891271 */, 19 }, - /* 7317 */ { MAD_F(0x0455c5db) /* 0.270940642 */, 19 }, - /* 7318 */ { MAD_F(0x0455f9a0) /* 0.270990015 */, 19 }, - /* 7319 */ { MAD_F(0x04562d66) /* 0.271039390 */, 19 }, - /* 7320 */ { MAD_F(0x0456612d) /* 0.271088768 */, 19 }, - /* 7321 */ { MAD_F(0x045694f4) /* 0.271138148 */, 19 }, - /* 7322 */ { MAD_F(0x0456c8bc) /* 0.271187530 */, 19 }, - /* 7323 */ { MAD_F(0x0456fc84) /* 0.271236914 */, 19 }, - /* 7324 */ { MAD_F(0x0457304e) /* 0.271286301 */, 19 }, - /* 7325 */ { MAD_F(0x04576417) /* 0.271335689 */, 19 }, - /* 7326 */ { MAD_F(0x045797e2) /* 0.271385080 */, 19 }, - /* 7327 */ { MAD_F(0x0457cbac) /* 0.271434474 */, 19 }, - - /* 7328 */ { MAD_F(0x0457ff78) /* 0.271483869 */, 19 }, - /* 7329 */ { MAD_F(0x04583344) /* 0.271533267 */, 19 }, - /* 7330 */ { MAD_F(0x04586711) /* 0.271582667 */, 19 }, - /* 7331 */ { MAD_F(0x04589ade) /* 0.271632069 */, 19 }, - /* 7332 */ { MAD_F(0x0458ceac) /* 0.271681474 */, 19 }, - /* 7333 */ { MAD_F(0x0459027b) /* 0.271730880 */, 19 }, - /* 7334 */ { MAD_F(0x0459364a) /* 0.271780289 */, 19 }, - /* 7335 */ { MAD_F(0x04596a19) /* 0.271829701 */, 19 }, - /* 7336 */ { MAD_F(0x04599dea) /* 0.271879114 */, 19 }, - /* 7337 */ { MAD_F(0x0459d1bb) /* 0.271928530 */, 19 }, - /* 7338 */ { MAD_F(0x045a058c) /* 0.271977948 */, 19 }, - /* 7339 */ { MAD_F(0x045a395e) /* 0.272027368 */, 19 }, - /* 7340 */ { MAD_F(0x045a6d31) /* 0.272076790 */, 19 }, - /* 7341 */ { MAD_F(0x045aa104) /* 0.272126215 */, 19 }, - /* 7342 */ { MAD_F(0x045ad4d8) /* 0.272175642 */, 19 }, - /* 7343 */ { MAD_F(0x045b08ad) /* 0.272225071 */, 19 }, - - /* 7344 */ { MAD_F(0x045b3c82) /* 0.272274503 */, 19 }, - /* 7345 */ { MAD_F(0x045b7058) /* 0.272323936 */, 19 }, - /* 7346 */ { MAD_F(0x045ba42e) /* 0.272373372 */, 19 }, - /* 7347 */ { MAD_F(0x045bd805) /* 0.272422810 */, 19 }, - /* 7348 */ { MAD_F(0x045c0bdd) /* 0.272472251 */, 19 }, - /* 7349 */ { MAD_F(0x045c3fb5) /* 0.272521693 */, 19 }, - /* 7350 */ { MAD_F(0x045c738e) /* 0.272571138 */, 19 }, - /* 7351 */ { MAD_F(0x045ca767) /* 0.272620585 */, 19 }, - /* 7352 */ { MAD_F(0x045cdb41) /* 0.272670035 */, 19 }, - /* 7353 */ { MAD_F(0x045d0f1b) /* 0.272719486 */, 19 }, - /* 7354 */ { MAD_F(0x045d42f7) /* 0.272768940 */, 19 }, - /* 7355 */ { MAD_F(0x045d76d2) /* 0.272818396 */, 19 }, - /* 7356 */ { MAD_F(0x045daaaf) /* 0.272867855 */, 19 }, - /* 7357 */ { MAD_F(0x045dde8c) /* 0.272917315 */, 19 }, - /* 7358 */ { MAD_F(0x045e1269) /* 0.272966778 */, 19 }, - /* 7359 */ { MAD_F(0x045e4647) /* 0.273016243 */, 19 }, - - /* 7360 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 19 }, - /* 7361 */ { MAD_F(0x045eae06) /* 0.273115180 */, 19 }, - /* 7362 */ { MAD_F(0x045ee1e6) /* 0.273164652 */, 19 }, - /* 7363 */ { MAD_F(0x045f15c6) /* 0.273214126 */, 19 }, - /* 7364 */ { MAD_F(0x045f49a7) /* 0.273263602 */, 19 }, - /* 7365 */ { MAD_F(0x045f7d89) /* 0.273313081 */, 19 }, - /* 7366 */ { MAD_F(0x045fb16c) /* 0.273362561 */, 19 }, - /* 7367 */ { MAD_F(0x045fe54f) /* 0.273412044 */, 19 }, - /* 7368 */ { MAD_F(0x04601932) /* 0.273461530 */, 19 }, - /* 7369 */ { MAD_F(0x04604d16) /* 0.273511017 */, 19 }, - /* 7370 */ { MAD_F(0x046080fb) /* 0.273560507 */, 19 }, - /* 7371 */ { MAD_F(0x0460b4e1) /* 0.273609999 */, 19 }, - /* 7372 */ { MAD_F(0x0460e8c7) /* 0.273659493 */, 19 }, - /* 7373 */ { MAD_F(0x04611cad) /* 0.273708989 */, 19 }, - /* 7374 */ { MAD_F(0x04615094) /* 0.273758488 */, 19 }, - /* 7375 */ { MAD_F(0x0461847c) /* 0.273807989 */, 19 }, - - /* 7376 */ { MAD_F(0x0461b864) /* 0.273857492 */, 19 }, - /* 7377 */ { MAD_F(0x0461ec4d) /* 0.273906997 */, 19 }, - /* 7378 */ { MAD_F(0x04622037) /* 0.273956505 */, 19 }, - /* 7379 */ { MAD_F(0x04625421) /* 0.274006015 */, 19 }, - /* 7380 */ { MAD_F(0x0462880c) /* 0.274055527 */, 19 }, - /* 7381 */ { MAD_F(0x0462bbf7) /* 0.274105041 */, 19 }, - /* 7382 */ { MAD_F(0x0462efe3) /* 0.274154558 */, 19 }, - /* 7383 */ { MAD_F(0x046323d0) /* 0.274204076 */, 19 }, - /* 7384 */ { MAD_F(0x046357bd) /* 0.274253597 */, 19 }, - /* 7385 */ { MAD_F(0x04638bab) /* 0.274303121 */, 19 }, - /* 7386 */ { MAD_F(0x0463bf99) /* 0.274352646 */, 19 }, - /* 7387 */ { MAD_F(0x0463f388) /* 0.274402174 */, 19 }, - /* 7388 */ { MAD_F(0x04642778) /* 0.274451704 */, 19 }, - /* 7389 */ { MAD_F(0x04645b68) /* 0.274501236 */, 19 }, - /* 7390 */ { MAD_F(0x04648f59) /* 0.274550771 */, 19 }, - /* 7391 */ { MAD_F(0x0464c34a) /* 0.274600307 */, 19 }, - - /* 7392 */ { MAD_F(0x0464f73c) /* 0.274649846 */, 19 }, - /* 7393 */ { MAD_F(0x04652b2f) /* 0.274699387 */, 19 }, - /* 7394 */ { MAD_F(0x04655f22) /* 0.274748931 */, 19 }, - /* 7395 */ { MAD_F(0x04659316) /* 0.274798476 */, 19 }, - /* 7396 */ { MAD_F(0x0465c70a) /* 0.274848024 */, 19 }, - /* 7397 */ { MAD_F(0x0465faff) /* 0.274897574 */, 19 }, - /* 7398 */ { MAD_F(0x04662ef5) /* 0.274947126 */, 19 }, - /* 7399 */ { MAD_F(0x046662eb) /* 0.274996681 */, 19 }, - /* 7400 */ { MAD_F(0x046696e2) /* 0.275046238 */, 19 }, - /* 7401 */ { MAD_F(0x0466cad9) /* 0.275095797 */, 19 }, - /* 7402 */ { MAD_F(0x0466fed1) /* 0.275145358 */, 19 }, - /* 7403 */ { MAD_F(0x046732ca) /* 0.275194921 */, 19 }, - /* 7404 */ { MAD_F(0x046766c3) /* 0.275244487 */, 19 }, - /* 7405 */ { MAD_F(0x04679abd) /* 0.275294055 */, 19 }, - /* 7406 */ { MAD_F(0x0467ceb7) /* 0.275343625 */, 19 }, - /* 7407 */ { MAD_F(0x046802b2) /* 0.275393198 */, 19 }, - - /* 7408 */ { MAD_F(0x046836ae) /* 0.275442772 */, 19 }, - /* 7409 */ { MAD_F(0x04686aaa) /* 0.275492349 */, 19 }, - /* 7410 */ { MAD_F(0x04689ea7) /* 0.275541928 */, 19 }, - /* 7411 */ { MAD_F(0x0468d2a4) /* 0.275591509 */, 19 }, - /* 7412 */ { MAD_F(0x046906a2) /* 0.275641093 */, 19 }, - /* 7413 */ { MAD_F(0x04693aa1) /* 0.275690679 */, 19 }, - /* 7414 */ { MAD_F(0x04696ea0) /* 0.275740267 */, 19 }, - /* 7415 */ { MAD_F(0x0469a2a0) /* 0.275789857 */, 19 }, - /* 7416 */ { MAD_F(0x0469d6a0) /* 0.275839449 */, 19 }, - /* 7417 */ { MAD_F(0x046a0aa1) /* 0.275889044 */, 19 }, - /* 7418 */ { MAD_F(0x046a3ea3) /* 0.275938641 */, 19 }, - /* 7419 */ { MAD_F(0x046a72a5) /* 0.275988240 */, 19 }, - /* 7420 */ { MAD_F(0x046aa6a8) /* 0.276037842 */, 19 }, - /* 7421 */ { MAD_F(0x046adaab) /* 0.276087445 */, 19 }, - /* 7422 */ { MAD_F(0x046b0eaf) /* 0.276137051 */, 19 }, - /* 7423 */ { MAD_F(0x046b42b3) /* 0.276186659 */, 19 }, - - /* 7424 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 19 }, - /* 7425 */ { MAD_F(0x046baabe) /* 0.276285882 */, 19 }, - /* 7426 */ { MAD_F(0x046bdec5) /* 0.276335497 */, 19 }, - /* 7427 */ { MAD_F(0x046c12cc) /* 0.276385113 */, 19 }, - /* 7428 */ { MAD_F(0x046c46d3) /* 0.276434733 */, 19 }, - /* 7429 */ { MAD_F(0x046c7adb) /* 0.276484354 */, 19 }, - /* 7430 */ { MAD_F(0x046caee4) /* 0.276533978 */, 19 }, - /* 7431 */ { MAD_F(0x046ce2ee) /* 0.276583604 */, 19 }, - /* 7432 */ { MAD_F(0x046d16f7) /* 0.276633232 */, 19 }, - /* 7433 */ { MAD_F(0x046d4b02) /* 0.276682862 */, 19 }, - /* 7434 */ { MAD_F(0x046d7f0d) /* 0.276732495 */, 19 }, - /* 7435 */ { MAD_F(0x046db319) /* 0.276782129 */, 19 }, - /* 7436 */ { MAD_F(0x046de725) /* 0.276831766 */, 19 }, - /* 7437 */ { MAD_F(0x046e1b32) /* 0.276881406 */, 19 }, - /* 7438 */ { MAD_F(0x046e4f40) /* 0.276931047 */, 19 }, - /* 7439 */ { MAD_F(0x046e834e) /* 0.276980691 */, 19 }, - - /* 7440 */ { MAD_F(0x046eb75c) /* 0.277030337 */, 19 }, - /* 7441 */ { MAD_F(0x046eeb6c) /* 0.277079985 */, 19 }, - /* 7442 */ { MAD_F(0x046f1f7c) /* 0.277129635 */, 19 }, - /* 7443 */ { MAD_F(0x046f538c) /* 0.277179288 */, 19 }, - /* 7444 */ { MAD_F(0x046f879d) /* 0.277228942 */, 19 }, - /* 7445 */ { MAD_F(0x046fbbaf) /* 0.277278600 */, 19 }, - /* 7446 */ { MAD_F(0x046fefc1) /* 0.277328259 */, 19 }, - /* 7447 */ { MAD_F(0x047023d4) /* 0.277377920 */, 19 }, - /* 7448 */ { MAD_F(0x047057e8) /* 0.277427584 */, 19 }, - /* 7449 */ { MAD_F(0x04708bfc) /* 0.277477250 */, 19 }, - /* 7450 */ { MAD_F(0x0470c011) /* 0.277526918 */, 19 }, - /* 7451 */ { MAD_F(0x0470f426) /* 0.277576588 */, 19 }, - /* 7452 */ { MAD_F(0x0471283c) /* 0.277626261 */, 19 }, - /* 7453 */ { MAD_F(0x04715c52) /* 0.277675936 */, 19 }, - /* 7454 */ { MAD_F(0x04719069) /* 0.277725613 */, 19 }, - /* 7455 */ { MAD_F(0x0471c481) /* 0.277775292 */, 19 }, - - /* 7456 */ { MAD_F(0x0471f899) /* 0.277824973 */, 19 }, - /* 7457 */ { MAD_F(0x04722cb2) /* 0.277874657 */, 19 }, - /* 7458 */ { MAD_F(0x047260cc) /* 0.277924343 */, 19 }, - /* 7459 */ { MAD_F(0x047294e6) /* 0.277974031 */, 19 }, - /* 7460 */ { MAD_F(0x0472c900) /* 0.278023722 */, 19 }, - /* 7461 */ { MAD_F(0x0472fd1b) /* 0.278073414 */, 19 }, - /* 7462 */ { MAD_F(0x04733137) /* 0.278123109 */, 19 }, - /* 7463 */ { MAD_F(0x04736554) /* 0.278172806 */, 19 }, - /* 7464 */ { MAD_F(0x04739971) /* 0.278222505 */, 19 }, - /* 7465 */ { MAD_F(0x0473cd8e) /* 0.278272207 */, 19 }, - /* 7466 */ { MAD_F(0x047401ad) /* 0.278321910 */, 19 }, - /* 7467 */ { MAD_F(0x047435cb) /* 0.278371616 */, 19 }, - /* 7468 */ { MAD_F(0x047469eb) /* 0.278421324 */, 19 }, - /* 7469 */ { MAD_F(0x04749e0b) /* 0.278471035 */, 19 }, - /* 7470 */ { MAD_F(0x0474d22c) /* 0.278520747 */, 19 }, - /* 7471 */ { MAD_F(0x0475064d) /* 0.278570462 */, 19 }, - - /* 7472 */ { MAD_F(0x04753a6f) /* 0.278620179 */, 19 }, - /* 7473 */ { MAD_F(0x04756e91) /* 0.278669898 */, 19 }, - /* 7474 */ { MAD_F(0x0475a2b4) /* 0.278719619 */, 19 }, - /* 7475 */ { MAD_F(0x0475d6d7) /* 0.278769343 */, 19 }, - /* 7476 */ { MAD_F(0x04760afc) /* 0.278819069 */, 19 }, - /* 7477 */ { MAD_F(0x04763f20) /* 0.278868797 */, 19 }, - /* 7478 */ { MAD_F(0x04767346) /* 0.278918527 */, 19 }, - /* 7479 */ { MAD_F(0x0476a76c) /* 0.278968260 */, 19 }, - /* 7480 */ { MAD_F(0x0476db92) /* 0.279017995 */, 19 }, - /* 7481 */ { MAD_F(0x04770fba) /* 0.279067731 */, 19 }, - /* 7482 */ { MAD_F(0x047743e1) /* 0.279117471 */, 19 }, - /* 7483 */ { MAD_F(0x0477780a) /* 0.279167212 */, 19 }, - /* 7484 */ { MAD_F(0x0477ac33) /* 0.279216956 */, 19 }, - /* 7485 */ { MAD_F(0x0477e05c) /* 0.279266701 */, 19 }, - /* 7486 */ { MAD_F(0x04781486) /* 0.279316449 */, 19 }, - /* 7487 */ { MAD_F(0x047848b1) /* 0.279366200 */, 19 }, - - /* 7488 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 19 }, - /* 7489 */ { MAD_F(0x0478b108) /* 0.279465707 */, 19 }, - /* 7490 */ { MAD_F(0x0478e535) /* 0.279515464 */, 19 }, - /* 7491 */ { MAD_F(0x04791962) /* 0.279565223 */, 19 }, - /* 7492 */ { MAD_F(0x04794d8f) /* 0.279614984 */, 19 }, - /* 7493 */ { MAD_F(0x047981be) /* 0.279664748 */, 19 }, - /* 7494 */ { MAD_F(0x0479b5ed) /* 0.279714513 */, 19 }, - /* 7495 */ { MAD_F(0x0479ea1c) /* 0.279764281 */, 19 }, - /* 7496 */ { MAD_F(0x047a1e4c) /* 0.279814051 */, 19 }, - /* 7497 */ { MAD_F(0x047a527d) /* 0.279863824 */, 19 }, - /* 7498 */ { MAD_F(0x047a86ae) /* 0.279913598 */, 19 }, - /* 7499 */ { MAD_F(0x047abae0) /* 0.279963375 */, 19 }, - /* 7500 */ { MAD_F(0x047aef12) /* 0.280013154 */, 19 }, - /* 7501 */ { MAD_F(0x047b2346) /* 0.280062935 */, 19 }, - /* 7502 */ { MAD_F(0x047b5779) /* 0.280112719 */, 19 }, - /* 7503 */ { MAD_F(0x047b8bad) /* 0.280162504 */, 19 }, - - /* 7504 */ { MAD_F(0x047bbfe2) /* 0.280212292 */, 19 }, - /* 7505 */ { MAD_F(0x047bf418) /* 0.280262082 */, 19 }, - /* 7506 */ { MAD_F(0x047c284e) /* 0.280311875 */, 19 }, - /* 7507 */ { MAD_F(0x047c5c84) /* 0.280361669 */, 19 }, - /* 7508 */ { MAD_F(0x047c90bb) /* 0.280411466 */, 19 }, - /* 7509 */ { MAD_F(0x047cc4f3) /* 0.280461265 */, 19 }, - /* 7510 */ { MAD_F(0x047cf92c) /* 0.280511066 */, 19 }, - /* 7511 */ { MAD_F(0x047d2d65) /* 0.280560869 */, 19 }, - /* 7512 */ { MAD_F(0x047d619e) /* 0.280610675 */, 19 }, - /* 7513 */ { MAD_F(0x047d95d8) /* 0.280660483 */, 19 }, - /* 7514 */ { MAD_F(0x047dca13) /* 0.280710292 */, 19 }, - /* 7515 */ { MAD_F(0x047dfe4e) /* 0.280760105 */, 19 }, - /* 7516 */ { MAD_F(0x047e328a) /* 0.280809919 */, 19 }, - /* 7517 */ { MAD_F(0x047e66c7) /* 0.280859736 */, 19 }, - /* 7518 */ { MAD_F(0x047e9b04) /* 0.280909554 */, 19 }, - /* 7519 */ { MAD_F(0x047ecf42) /* 0.280959375 */, 19 }, - - /* 7520 */ { MAD_F(0x047f0380) /* 0.281009199 */, 19 }, - /* 7521 */ { MAD_F(0x047f37bf) /* 0.281059024 */, 19 }, - /* 7522 */ { MAD_F(0x047f6bff) /* 0.281108852 */, 19 }, - /* 7523 */ { MAD_F(0x047fa03f) /* 0.281158682 */, 19 }, - /* 7524 */ { MAD_F(0x047fd47f) /* 0.281208514 */, 19 }, - /* 7525 */ { MAD_F(0x048008c1) /* 0.281258348 */, 19 }, - /* 7526 */ { MAD_F(0x04803d02) /* 0.281308184 */, 19 }, - /* 7527 */ { MAD_F(0x04807145) /* 0.281358023 */, 19 }, - /* 7528 */ { MAD_F(0x0480a588) /* 0.281407864 */, 19 }, - /* 7529 */ { MAD_F(0x0480d9cc) /* 0.281457707 */, 19 }, - /* 7530 */ { MAD_F(0x04810e10) /* 0.281507552 */, 19 }, - /* 7531 */ { MAD_F(0x04814255) /* 0.281557400 */, 19 }, - /* 7532 */ { MAD_F(0x0481769a) /* 0.281607250 */, 19 }, - /* 7533 */ { MAD_F(0x0481aae0) /* 0.281657101 */, 19 }, - /* 7534 */ { MAD_F(0x0481df27) /* 0.281706956 */, 19 }, - /* 7535 */ { MAD_F(0x0482136e) /* 0.281756812 */, 19 }, - - /* 7536 */ { MAD_F(0x048247b6) /* 0.281806670 */, 19 }, - /* 7537 */ { MAD_F(0x04827bfe) /* 0.281856531 */, 19 }, - /* 7538 */ { MAD_F(0x0482b047) /* 0.281906394 */, 19 }, - /* 7539 */ { MAD_F(0x0482e491) /* 0.281956259 */, 19 }, - /* 7540 */ { MAD_F(0x048318db) /* 0.282006127 */, 19 }, - /* 7541 */ { MAD_F(0x04834d26) /* 0.282055996 */, 19 }, - /* 7542 */ { MAD_F(0x04838171) /* 0.282105868 */, 19 }, - /* 7543 */ { MAD_F(0x0483b5bd) /* 0.282155742 */, 19 }, - /* 7544 */ { MAD_F(0x0483ea0a) /* 0.282205618 */, 19 }, - /* 7545 */ { MAD_F(0x04841e57) /* 0.282255496 */, 19 }, - /* 7546 */ { MAD_F(0x048452a4) /* 0.282305377 */, 19 }, - /* 7547 */ { MAD_F(0x048486f3) /* 0.282355260 */, 19 }, - /* 7548 */ { MAD_F(0x0484bb42) /* 0.282405145 */, 19 }, - /* 7549 */ { MAD_F(0x0484ef91) /* 0.282455032 */, 19 }, - /* 7550 */ { MAD_F(0x048523e1) /* 0.282504921 */, 19 }, - /* 7551 */ { MAD_F(0x04855832) /* 0.282554813 */, 19 }, - - /* 7552 */ { MAD_F(0x04858c83) /* 0.282604707 */, 19 }, - /* 7553 */ { MAD_F(0x0485c0d5) /* 0.282654603 */, 19 }, - /* 7554 */ { MAD_F(0x0485f527) /* 0.282704501 */, 19 }, - /* 7555 */ { MAD_F(0x0486297a) /* 0.282754401 */, 19 }, - /* 7556 */ { MAD_F(0x04865dce) /* 0.282804304 */, 19 }, - /* 7557 */ { MAD_F(0x04869222) /* 0.282854209 */, 19 }, - /* 7558 */ { MAD_F(0x0486c677) /* 0.282904116 */, 19 }, - /* 7559 */ { MAD_F(0x0486facc) /* 0.282954025 */, 19 }, - /* 7560 */ { MAD_F(0x04872f22) /* 0.283003936 */, 19 }, - /* 7561 */ { MAD_F(0x04876379) /* 0.283053850 */, 19 }, - /* 7562 */ { MAD_F(0x048797d0) /* 0.283103766 */, 19 }, - /* 7563 */ { MAD_F(0x0487cc28) /* 0.283153684 */, 19 }, - /* 7564 */ { MAD_F(0x04880080) /* 0.283203604 */, 19 }, - /* 7565 */ { MAD_F(0x048834d9) /* 0.283253527 */, 19 }, - /* 7566 */ { MAD_F(0x04886933) /* 0.283303451 */, 19 }, - /* 7567 */ { MAD_F(0x04889d8d) /* 0.283353378 */, 19 }, - - /* 7568 */ { MAD_F(0x0488d1e8) /* 0.283403307 */, 19 }, - /* 7569 */ { MAD_F(0x04890643) /* 0.283453238 */, 19 }, - /* 7570 */ { MAD_F(0x04893a9f) /* 0.283503172 */, 19 }, - /* 7571 */ { MAD_F(0x04896efb) /* 0.283553107 */, 19 }, - /* 7572 */ { MAD_F(0x0489a358) /* 0.283603045 */, 19 }, - /* 7573 */ { MAD_F(0x0489d7b6) /* 0.283652985 */, 19 }, - /* 7574 */ { MAD_F(0x048a0c14) /* 0.283702927 */, 19 }, - /* 7575 */ { MAD_F(0x048a4073) /* 0.283752872 */, 19 }, - /* 7576 */ { MAD_F(0x048a74d3) /* 0.283802818 */, 19 }, - /* 7577 */ { MAD_F(0x048aa933) /* 0.283852767 */, 19 }, - /* 7578 */ { MAD_F(0x048add93) /* 0.283902718 */, 19 }, - /* 7579 */ { MAD_F(0x048b11f5) /* 0.283952671 */, 19 }, - /* 7580 */ { MAD_F(0x048b4656) /* 0.284002627 */, 19 }, - /* 7581 */ { MAD_F(0x048b7ab9) /* 0.284052584 */, 19 }, - /* 7582 */ { MAD_F(0x048baf1c) /* 0.284102544 */, 19 }, - /* 7583 */ { MAD_F(0x048be37f) /* 0.284152506 */, 19 }, - - /* 7584 */ { MAD_F(0x048c17e3) /* 0.284202470 */, 19 }, - /* 7585 */ { MAD_F(0x048c4c48) /* 0.284252436 */, 19 }, - /* 7586 */ { MAD_F(0x048c80ad) /* 0.284302405 */, 19 }, - /* 7587 */ { MAD_F(0x048cb513) /* 0.284352376 */, 19 }, - /* 7588 */ { MAD_F(0x048ce97a) /* 0.284402349 */, 19 }, - /* 7589 */ { MAD_F(0x048d1de1) /* 0.284452324 */, 19 }, - /* 7590 */ { MAD_F(0x048d5249) /* 0.284502301 */, 19 }, - /* 7591 */ { MAD_F(0x048d86b1) /* 0.284552281 */, 19 }, - /* 7592 */ { MAD_F(0x048dbb1a) /* 0.284602263 */, 19 }, - /* 7593 */ { MAD_F(0x048def83) /* 0.284652246 */, 19 }, - /* 7594 */ { MAD_F(0x048e23ed) /* 0.284702233 */, 19 }, - /* 7595 */ { MAD_F(0x048e5858) /* 0.284752221 */, 19 }, - /* 7596 */ { MAD_F(0x048e8cc3) /* 0.284802211 */, 19 }, - /* 7597 */ { MAD_F(0x048ec12f) /* 0.284852204 */, 19 }, - /* 7598 */ { MAD_F(0x048ef59b) /* 0.284902199 */, 19 }, - /* 7599 */ { MAD_F(0x048f2a08) /* 0.284952196 */, 19 }, - - /* 7600 */ { MAD_F(0x048f5e76) /* 0.285002195 */, 19 }, - /* 7601 */ { MAD_F(0x048f92e4) /* 0.285052197 */, 19 }, - /* 7602 */ { MAD_F(0x048fc753) /* 0.285102201 */, 19 }, - /* 7603 */ { MAD_F(0x048ffbc2) /* 0.285152206 */, 19 }, - /* 7604 */ { MAD_F(0x04903032) /* 0.285202214 */, 19 }, - /* 7605 */ { MAD_F(0x049064a3) /* 0.285252225 */, 19 }, - /* 7606 */ { MAD_F(0x04909914) /* 0.285302237 */, 19 }, - /* 7607 */ { MAD_F(0x0490cd86) /* 0.285352252 */, 19 }, - /* 7608 */ { MAD_F(0x049101f8) /* 0.285402269 */, 19 }, - /* 7609 */ { MAD_F(0x0491366b) /* 0.285452288 */, 19 }, - /* 7610 */ { MAD_F(0x04916ade) /* 0.285502309 */, 19 }, - /* 7611 */ { MAD_F(0x04919f52) /* 0.285552332 */, 19 }, - /* 7612 */ { MAD_F(0x0491d3c7) /* 0.285602358 */, 19 }, - /* 7613 */ { MAD_F(0x0492083c) /* 0.285652386 */, 19 }, - /* 7614 */ { MAD_F(0x04923cb2) /* 0.285702416 */, 19 }, - /* 7615 */ { MAD_F(0x04927128) /* 0.285752448 */, 19 }, - - /* 7616 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 19 }, - /* 7617 */ { MAD_F(0x0492da17) /* 0.285852519 */, 19 }, - /* 7618 */ { MAD_F(0x04930e8f) /* 0.285902557 */, 19 }, - /* 7619 */ { MAD_F(0x04934308) /* 0.285952598 */, 19 }, - /* 7620 */ { MAD_F(0x04937781) /* 0.286002641 */, 19 }, - /* 7621 */ { MAD_F(0x0493abfb) /* 0.286052687 */, 19 }, - /* 7622 */ { MAD_F(0x0493e076) /* 0.286102734 */, 19 }, - /* 7623 */ { MAD_F(0x049414f1) /* 0.286152784 */, 19 }, - /* 7624 */ { MAD_F(0x0494496c) /* 0.286202836 */, 19 }, - /* 7625 */ { MAD_F(0x04947de9) /* 0.286252890 */, 19 }, - /* 7626 */ { MAD_F(0x0494b266) /* 0.286302946 */, 19 }, - /* 7627 */ { MAD_F(0x0494e6e3) /* 0.286353005 */, 19 }, - /* 7628 */ { MAD_F(0x04951b61) /* 0.286403065 */, 19 }, - /* 7629 */ { MAD_F(0x04954fe0) /* 0.286453128 */, 19 }, - /* 7630 */ { MAD_F(0x0495845f) /* 0.286503193 */, 19 }, - /* 7631 */ { MAD_F(0x0495b8df) /* 0.286553260 */, 19 }, - - /* 7632 */ { MAD_F(0x0495ed5f) /* 0.286603329 */, 19 }, - /* 7633 */ { MAD_F(0x049621e0) /* 0.286653401 */, 19 }, - /* 7634 */ { MAD_F(0x04965662) /* 0.286703475 */, 19 }, - /* 7635 */ { MAD_F(0x04968ae4) /* 0.286753551 */, 19 }, - /* 7636 */ { MAD_F(0x0496bf67) /* 0.286803629 */, 19 }, - /* 7637 */ { MAD_F(0x0496f3ea) /* 0.286853709 */, 19 }, - /* 7638 */ { MAD_F(0x0497286e) /* 0.286903792 */, 19 }, - /* 7639 */ { MAD_F(0x04975cf2) /* 0.286953876 */, 19 }, - /* 7640 */ { MAD_F(0x04979177) /* 0.287003963 */, 19 }, - /* 7641 */ { MAD_F(0x0497c5fd) /* 0.287054052 */, 19 }, - /* 7642 */ { MAD_F(0x0497fa83) /* 0.287104143 */, 19 }, - /* 7643 */ { MAD_F(0x04982f0a) /* 0.287154237 */, 19 }, - /* 7644 */ { MAD_F(0x04986392) /* 0.287204332 */, 19 }, - /* 7645 */ { MAD_F(0x0498981a) /* 0.287254430 */, 19 }, - /* 7646 */ { MAD_F(0x0498cca2) /* 0.287304530 */, 19 }, - /* 7647 */ { MAD_F(0x0499012c) /* 0.287354632 */, 19 }, - - /* 7648 */ { MAD_F(0x049935b5) /* 0.287404737 */, 19 }, - /* 7649 */ { MAD_F(0x04996a40) /* 0.287454843 */, 19 }, - /* 7650 */ { MAD_F(0x04999ecb) /* 0.287504952 */, 19 }, - /* 7651 */ { MAD_F(0x0499d356) /* 0.287555063 */, 19 }, - /* 7652 */ { MAD_F(0x049a07e2) /* 0.287605176 */, 19 }, - /* 7653 */ { MAD_F(0x049a3c6f) /* 0.287655291 */, 19 }, - /* 7654 */ { MAD_F(0x049a70fc) /* 0.287705409 */, 19 }, - /* 7655 */ { MAD_F(0x049aa58a) /* 0.287755528 */, 19 }, - /* 7656 */ { MAD_F(0x049ada19) /* 0.287805650 */, 19 }, - /* 7657 */ { MAD_F(0x049b0ea8) /* 0.287855774 */, 19 }, - /* 7658 */ { MAD_F(0x049b4337) /* 0.287905900 */, 19 }, - /* 7659 */ { MAD_F(0x049b77c8) /* 0.287956028 */, 19 }, - /* 7660 */ { MAD_F(0x049bac58) /* 0.288006159 */, 19 }, - /* 7661 */ { MAD_F(0x049be0ea) /* 0.288056292 */, 19 }, - /* 7662 */ { MAD_F(0x049c157c) /* 0.288106427 */, 19 }, - /* 7663 */ { MAD_F(0x049c4a0e) /* 0.288156564 */, 19 }, - - /* 7664 */ { MAD_F(0x049c7ea1) /* 0.288206703 */, 19 }, - /* 7665 */ { MAD_F(0x049cb335) /* 0.288256844 */, 19 }, - /* 7666 */ { MAD_F(0x049ce7ca) /* 0.288306988 */, 19 }, - /* 7667 */ { MAD_F(0x049d1c5e) /* 0.288357134 */, 19 }, - /* 7668 */ { MAD_F(0x049d50f4) /* 0.288407282 */, 19 }, - /* 7669 */ { MAD_F(0x049d858a) /* 0.288457432 */, 19 }, - /* 7670 */ { MAD_F(0x049dba21) /* 0.288507584 */, 19 }, - /* 7671 */ { MAD_F(0x049deeb8) /* 0.288557739 */, 19 }, - /* 7672 */ { MAD_F(0x049e2350) /* 0.288607895 */, 19 }, - /* 7673 */ { MAD_F(0x049e57e8) /* 0.288658054 */, 19 }, - /* 7674 */ { MAD_F(0x049e8c81) /* 0.288708215 */, 19 }, - /* 7675 */ { MAD_F(0x049ec11b) /* 0.288758379 */, 19 }, - /* 7676 */ { MAD_F(0x049ef5b5) /* 0.288808544 */, 19 }, - /* 7677 */ { MAD_F(0x049f2a50) /* 0.288858712 */, 19 }, - /* 7678 */ { MAD_F(0x049f5eeb) /* 0.288908881 */, 19 }, - /* 7679 */ { MAD_F(0x049f9387) /* 0.288959053 */, 19 }, - - /* 7680 */ { MAD_F(0x049fc824) /* 0.289009227 */, 19 }, - /* 7681 */ { MAD_F(0x049ffcc1) /* 0.289059404 */, 19 }, - /* 7682 */ { MAD_F(0x04a0315e) /* 0.289109582 */, 19 }, - /* 7683 */ { MAD_F(0x04a065fd) /* 0.289159763 */, 19 }, - /* 7684 */ { MAD_F(0x04a09a9b) /* 0.289209946 */, 19 }, - /* 7685 */ { MAD_F(0x04a0cf3b) /* 0.289260131 */, 19 }, - /* 7686 */ { MAD_F(0x04a103db) /* 0.289310318 */, 19 }, - /* 7687 */ { MAD_F(0x04a1387b) /* 0.289360507 */, 19 }, - /* 7688 */ { MAD_F(0x04a16d1d) /* 0.289410699 */, 19 }, - /* 7689 */ { MAD_F(0x04a1a1be) /* 0.289460893 */, 19 }, - /* 7690 */ { MAD_F(0x04a1d661) /* 0.289511088 */, 19 }, - /* 7691 */ { MAD_F(0x04a20b04) /* 0.289561287 */, 19 }, - /* 7692 */ { MAD_F(0x04a23fa7) /* 0.289611487 */, 19 }, - /* 7693 */ { MAD_F(0x04a2744b) /* 0.289661689 */, 19 }, - /* 7694 */ { MAD_F(0x04a2a8f0) /* 0.289711894 */, 19 }, - /* 7695 */ { MAD_F(0x04a2dd95) /* 0.289762101 */, 19 }, - - /* 7696 */ { MAD_F(0x04a3123b) /* 0.289812309 */, 19 }, - /* 7697 */ { MAD_F(0x04a346e2) /* 0.289862521 */, 19 }, - /* 7698 */ { MAD_F(0x04a37b89) /* 0.289912734 */, 19 }, - /* 7699 */ { MAD_F(0x04a3b030) /* 0.289962949 */, 19 }, - /* 7700 */ { MAD_F(0x04a3e4d8) /* 0.290013167 */, 19 }, - /* 7701 */ { MAD_F(0x04a41981) /* 0.290063387 */, 19 }, - /* 7702 */ { MAD_F(0x04a44e2b) /* 0.290113609 */, 19 }, - /* 7703 */ { MAD_F(0x04a482d5) /* 0.290163833 */, 19 }, - /* 7704 */ { MAD_F(0x04a4b77f) /* 0.290214059 */, 19 }, - /* 7705 */ { MAD_F(0x04a4ec2a) /* 0.290264288 */, 19 }, - /* 7706 */ { MAD_F(0x04a520d6) /* 0.290314519 */, 19 }, - /* 7707 */ { MAD_F(0x04a55582) /* 0.290364751 */, 19 }, - /* 7708 */ { MAD_F(0x04a58a2f) /* 0.290414986 */, 19 }, - /* 7709 */ { MAD_F(0x04a5bedd) /* 0.290465224 */, 19 }, - /* 7710 */ { MAD_F(0x04a5f38b) /* 0.290515463 */, 19 }, - /* 7711 */ { MAD_F(0x04a62839) /* 0.290565705 */, 19 }, - - /* 7712 */ { MAD_F(0x04a65ce8) /* 0.290615948 */, 19 }, - /* 7713 */ { MAD_F(0x04a69198) /* 0.290666194 */, 19 }, - /* 7714 */ { MAD_F(0x04a6c648) /* 0.290716442 */, 19 }, - /* 7715 */ { MAD_F(0x04a6faf9) /* 0.290766692 */, 19 }, - /* 7716 */ { MAD_F(0x04a72fab) /* 0.290816945 */, 19 }, - /* 7717 */ { MAD_F(0x04a7645d) /* 0.290867199 */, 19 }, - /* 7718 */ { MAD_F(0x04a79910) /* 0.290917456 */, 19 }, - /* 7719 */ { MAD_F(0x04a7cdc3) /* 0.290967715 */, 19 }, - /* 7720 */ { MAD_F(0x04a80277) /* 0.291017976 */, 19 }, - /* 7721 */ { MAD_F(0x04a8372b) /* 0.291068239 */, 19 }, - /* 7722 */ { MAD_F(0x04a86be0) /* 0.291118505 */, 19 }, - /* 7723 */ { MAD_F(0x04a8a096) /* 0.291168772 */, 19 }, - /* 7724 */ { MAD_F(0x04a8d54c) /* 0.291219042 */, 19 }, - /* 7725 */ { MAD_F(0x04a90a03) /* 0.291269314 */, 19 }, - /* 7726 */ { MAD_F(0x04a93eba) /* 0.291319588 */, 19 }, - /* 7727 */ { MAD_F(0x04a97372) /* 0.291369865 */, 19 }, - - /* 7728 */ { MAD_F(0x04a9a82b) /* 0.291420143 */, 19 }, - /* 7729 */ { MAD_F(0x04a9dce4) /* 0.291470424 */, 19 }, - /* 7730 */ { MAD_F(0x04aa119d) /* 0.291520706 */, 19 }, - /* 7731 */ { MAD_F(0x04aa4658) /* 0.291570991 */, 19 }, - /* 7732 */ { MAD_F(0x04aa7b13) /* 0.291621278 */, 19 }, - /* 7733 */ { MAD_F(0x04aaafce) /* 0.291671568 */, 19 }, - /* 7734 */ { MAD_F(0x04aae48a) /* 0.291721859 */, 19 }, - /* 7735 */ { MAD_F(0x04ab1947) /* 0.291772153 */, 19 }, - /* 7736 */ { MAD_F(0x04ab4e04) /* 0.291822449 */, 19 }, - /* 7737 */ { MAD_F(0x04ab82c2) /* 0.291872747 */, 19 }, - /* 7738 */ { MAD_F(0x04abb780) /* 0.291923047 */, 19 }, - /* 7739 */ { MAD_F(0x04abec3f) /* 0.291973349 */, 19 }, - /* 7740 */ { MAD_F(0x04ac20fe) /* 0.292023653 */, 19 }, - /* 7741 */ { MAD_F(0x04ac55be) /* 0.292073960 */, 19 }, - /* 7742 */ { MAD_F(0x04ac8a7f) /* 0.292124269 */, 19 }, - /* 7743 */ { MAD_F(0x04acbf40) /* 0.292174580 */, 19 }, - - /* 7744 */ { MAD_F(0x04acf402) /* 0.292224893 */, 19 }, - /* 7745 */ { MAD_F(0x04ad28c5) /* 0.292275208 */, 19 }, - /* 7746 */ { MAD_F(0x04ad5d88) /* 0.292325526 */, 19 }, - /* 7747 */ { MAD_F(0x04ad924b) /* 0.292375845 */, 19 }, - /* 7748 */ { MAD_F(0x04adc70f) /* 0.292426167 */, 19 }, - /* 7749 */ { MAD_F(0x04adfbd4) /* 0.292476491 */, 19 }, - /* 7750 */ { MAD_F(0x04ae3099) /* 0.292526817 */, 19 }, - /* 7751 */ { MAD_F(0x04ae655f) /* 0.292577145 */, 19 }, - /* 7752 */ { MAD_F(0x04ae9a26) /* 0.292627476 */, 19 }, - /* 7753 */ { MAD_F(0x04aeceed) /* 0.292677808 */, 19 }, - /* 7754 */ { MAD_F(0x04af03b4) /* 0.292728143 */, 19 }, - /* 7755 */ { MAD_F(0x04af387d) /* 0.292778480 */, 19 }, - /* 7756 */ { MAD_F(0x04af6d45) /* 0.292828819 */, 19 }, - /* 7757 */ { MAD_F(0x04afa20f) /* 0.292879160 */, 19 }, - /* 7758 */ { MAD_F(0x04afd6d9) /* 0.292929504 */, 19 }, - /* 7759 */ { MAD_F(0x04b00ba3) /* 0.292979849 */, 19 }, - - /* 7760 */ { MAD_F(0x04b0406e) /* 0.293030197 */, 19 }, - /* 7761 */ { MAD_F(0x04b0753a) /* 0.293080547 */, 19 }, - /* 7762 */ { MAD_F(0x04b0aa06) /* 0.293130899 */, 19 }, - /* 7763 */ { MAD_F(0x04b0ded3) /* 0.293181253 */, 19 }, - /* 7764 */ { MAD_F(0x04b113a1) /* 0.293231610 */, 19 }, - /* 7765 */ { MAD_F(0x04b1486f) /* 0.293281968 */, 19 }, - /* 7766 */ { MAD_F(0x04b17d3d) /* 0.293332329 */, 19 }, - /* 7767 */ { MAD_F(0x04b1b20c) /* 0.293382692 */, 19 }, - /* 7768 */ { MAD_F(0x04b1e6dc) /* 0.293433057 */, 19 }, - /* 7769 */ { MAD_F(0x04b21bad) /* 0.293483424 */, 19 }, - /* 7770 */ { MAD_F(0x04b2507d) /* 0.293533794 */, 19 }, - /* 7771 */ { MAD_F(0x04b2854f) /* 0.293584165 */, 19 }, - /* 7772 */ { MAD_F(0x04b2ba21) /* 0.293634539 */, 19 }, - /* 7773 */ { MAD_F(0x04b2eef4) /* 0.293684915 */, 19 }, - /* 7774 */ { MAD_F(0x04b323c7) /* 0.293735293 */, 19 }, - /* 7775 */ { MAD_F(0x04b3589b) /* 0.293785673 */, 19 }, - - /* 7776 */ { MAD_F(0x04b38d6f) /* 0.293836055 */, 19 }, - /* 7777 */ { MAD_F(0x04b3c244) /* 0.293886440 */, 19 }, - /* 7778 */ { MAD_F(0x04b3f71a) /* 0.293936826 */, 19 }, - /* 7779 */ { MAD_F(0x04b42bf0) /* 0.293987215 */, 19 }, - /* 7780 */ { MAD_F(0x04b460c7) /* 0.294037606 */, 19 }, - /* 7781 */ { MAD_F(0x04b4959e) /* 0.294087999 */, 19 }, - /* 7782 */ { MAD_F(0x04b4ca76) /* 0.294138395 */, 19 }, - /* 7783 */ { MAD_F(0x04b4ff4e) /* 0.294188792 */, 19 }, - /* 7784 */ { MAD_F(0x04b53427) /* 0.294239192 */, 19 }, - /* 7785 */ { MAD_F(0x04b56901) /* 0.294289593 */, 19 }, - /* 7786 */ { MAD_F(0x04b59ddb) /* 0.294339997 */, 19 }, - /* 7787 */ { MAD_F(0x04b5d2b6) /* 0.294390403 */, 19 }, - /* 7788 */ { MAD_F(0x04b60791) /* 0.294440812 */, 19 }, - /* 7789 */ { MAD_F(0x04b63c6d) /* 0.294491222 */, 19 }, - /* 7790 */ { MAD_F(0x04b6714a) /* 0.294541635 */, 19 }, - /* 7791 */ { MAD_F(0x04b6a627) /* 0.294592049 */, 19 }, - - /* 7792 */ { MAD_F(0x04b6db05) /* 0.294642466 */, 19 }, - /* 7793 */ { MAD_F(0x04b70fe3) /* 0.294692885 */, 19 }, - /* 7794 */ { MAD_F(0x04b744c2) /* 0.294743306 */, 19 }, - /* 7795 */ { MAD_F(0x04b779a1) /* 0.294793730 */, 19 }, - /* 7796 */ { MAD_F(0x04b7ae81) /* 0.294844155 */, 19 }, - /* 7797 */ { MAD_F(0x04b7e362) /* 0.294894583 */, 19 }, - /* 7798 */ { MAD_F(0x04b81843) /* 0.294945013 */, 19 }, - /* 7799 */ { MAD_F(0x04b84d24) /* 0.294995445 */, 19 }, - /* 7800 */ { MAD_F(0x04b88207) /* 0.295045879 */, 19 }, - /* 7801 */ { MAD_F(0x04b8b6ea) /* 0.295096315 */, 19 }, - /* 7802 */ { MAD_F(0x04b8ebcd) /* 0.295146753 */, 19 }, - /* 7803 */ { MAD_F(0x04b920b1) /* 0.295197194 */, 19 }, - /* 7804 */ { MAD_F(0x04b95596) /* 0.295247637 */, 19 }, - /* 7805 */ { MAD_F(0x04b98a7b) /* 0.295298082 */, 19 }, - /* 7806 */ { MAD_F(0x04b9bf61) /* 0.295348529 */, 19 }, - /* 7807 */ { MAD_F(0x04b9f447) /* 0.295398978 */, 19 }, - - /* 7808 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 19 }, - /* 7809 */ { MAD_F(0x04ba5e16) /* 0.295499883 */, 19 }, - /* 7810 */ { MAD_F(0x04ba92fe) /* 0.295550338 */, 19 }, - /* 7811 */ { MAD_F(0x04bac7e6) /* 0.295600796 */, 19 }, - /* 7812 */ { MAD_F(0x04bafcd0) /* 0.295651256 */, 19 }, - /* 7813 */ { MAD_F(0x04bb31b9) /* 0.295701718 */, 19 }, - /* 7814 */ { MAD_F(0x04bb66a4) /* 0.295752183 */, 19 }, - /* 7815 */ { MAD_F(0x04bb9b8f) /* 0.295802649 */, 19 }, - /* 7816 */ { MAD_F(0x04bbd07a) /* 0.295853118 */, 19 }, - /* 7817 */ { MAD_F(0x04bc0566) /* 0.295903588 */, 19 }, - /* 7818 */ { MAD_F(0x04bc3a53) /* 0.295954061 */, 19 }, - /* 7819 */ { MAD_F(0x04bc6f40) /* 0.296004536 */, 19 }, - /* 7820 */ { MAD_F(0x04bca42e) /* 0.296055013 */, 19 }, - /* 7821 */ { MAD_F(0x04bcd91d) /* 0.296105493 */, 19 }, - /* 7822 */ { MAD_F(0x04bd0e0c) /* 0.296155974 */, 19 }, - /* 7823 */ { MAD_F(0x04bd42fb) /* 0.296206458 */, 19 }, - - /* 7824 */ { MAD_F(0x04bd77ec) /* 0.296256944 */, 19 }, - /* 7825 */ { MAD_F(0x04bdacdc) /* 0.296307432 */, 19 }, - /* 7826 */ { MAD_F(0x04bde1ce) /* 0.296357922 */, 19 }, - /* 7827 */ { MAD_F(0x04be16c0) /* 0.296408414 */, 19 }, - /* 7828 */ { MAD_F(0x04be4bb2) /* 0.296458908 */, 19 }, - /* 7829 */ { MAD_F(0x04be80a5) /* 0.296509405 */, 19 }, - /* 7830 */ { MAD_F(0x04beb599) /* 0.296559904 */, 19 }, - /* 7831 */ { MAD_F(0x04beea8d) /* 0.296610404 */, 19 }, - /* 7832 */ { MAD_F(0x04bf1f82) /* 0.296660907 */, 19 }, - /* 7833 */ { MAD_F(0x04bf5477) /* 0.296711413 */, 19 }, - /* 7834 */ { MAD_F(0x04bf896d) /* 0.296761920 */, 19 }, - /* 7835 */ { MAD_F(0x04bfbe64) /* 0.296812429 */, 19 }, - /* 7836 */ { MAD_F(0x04bff35b) /* 0.296862941 */, 19 }, - /* 7837 */ { MAD_F(0x04c02852) /* 0.296913455 */, 19 }, - /* 7838 */ { MAD_F(0x04c05d4b) /* 0.296963971 */, 19 }, - /* 7839 */ { MAD_F(0x04c09243) /* 0.297014489 */, 19 }, - - /* 7840 */ { MAD_F(0x04c0c73d) /* 0.297065009 */, 19 }, - /* 7841 */ { MAD_F(0x04c0fc37) /* 0.297115531 */, 19 }, - /* 7842 */ { MAD_F(0x04c13131) /* 0.297166056 */, 19 }, - /* 7843 */ { MAD_F(0x04c1662d) /* 0.297216582 */, 19 }, - /* 7844 */ { MAD_F(0x04c19b28) /* 0.297267111 */, 19 }, - /* 7845 */ { MAD_F(0x04c1d025) /* 0.297317642 */, 19 }, - /* 7846 */ { MAD_F(0x04c20521) /* 0.297368175 */, 19 }, - /* 7847 */ { MAD_F(0x04c23a1f) /* 0.297418710 */, 19 }, - /* 7848 */ { MAD_F(0x04c26f1d) /* 0.297469248 */, 19 }, - /* 7849 */ { MAD_F(0x04c2a41b) /* 0.297519787 */, 19 }, - /* 7850 */ { MAD_F(0x04c2d91b) /* 0.297570329 */, 19 }, - /* 7851 */ { MAD_F(0x04c30e1a) /* 0.297620873 */, 19 }, - /* 7852 */ { MAD_F(0x04c3431b) /* 0.297671418 */, 19 }, - /* 7853 */ { MAD_F(0x04c3781c) /* 0.297721967 */, 19 }, - /* 7854 */ { MAD_F(0x04c3ad1d) /* 0.297772517 */, 19 }, - /* 7855 */ { MAD_F(0x04c3e21f) /* 0.297823069 */, 19 }, - - /* 7856 */ { MAD_F(0x04c41722) /* 0.297873624 */, 19 }, - /* 7857 */ { MAD_F(0x04c44c25) /* 0.297924180 */, 19 }, - /* 7858 */ { MAD_F(0x04c48129) /* 0.297974739 */, 19 }, - /* 7859 */ { MAD_F(0x04c4b62d) /* 0.298025300 */, 19 }, - /* 7860 */ { MAD_F(0x04c4eb32) /* 0.298075863 */, 19 }, - /* 7861 */ { MAD_F(0x04c52038) /* 0.298126429 */, 19 }, - /* 7862 */ { MAD_F(0x04c5553e) /* 0.298176996 */, 19 }, - /* 7863 */ { MAD_F(0x04c58a44) /* 0.298227565 */, 19 }, - /* 7864 */ { MAD_F(0x04c5bf4c) /* 0.298278137 */, 19 }, - /* 7865 */ { MAD_F(0x04c5f453) /* 0.298328711 */, 19 }, - /* 7866 */ { MAD_F(0x04c6295c) /* 0.298379287 */, 19 }, - /* 7867 */ { MAD_F(0x04c65e65) /* 0.298429865 */, 19 }, - /* 7868 */ { MAD_F(0x04c6936e) /* 0.298480445 */, 19 }, - /* 7869 */ { MAD_F(0x04c6c878) /* 0.298531028 */, 19 }, - /* 7870 */ { MAD_F(0x04c6fd83) /* 0.298581612 */, 19 }, - /* 7871 */ { MAD_F(0x04c7328e) /* 0.298632199 */, 19 }, - - /* 7872 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 19 }, - /* 7873 */ { MAD_F(0x04c79ca7) /* 0.298733379 */, 19 }, - /* 7874 */ { MAD_F(0x04c7d1b4) /* 0.298783972 */, 19 }, - /* 7875 */ { MAD_F(0x04c806c1) /* 0.298834567 */, 19 }, - /* 7876 */ { MAD_F(0x04c83bcf) /* 0.298885165 */, 19 }, - /* 7877 */ { MAD_F(0x04c870de) /* 0.298935764 */, 19 }, - /* 7878 */ { MAD_F(0x04c8a5ed) /* 0.298986366 */, 19 }, - /* 7879 */ { MAD_F(0x04c8dafd) /* 0.299036970 */, 19 }, - /* 7880 */ { MAD_F(0x04c9100d) /* 0.299087576 */, 19 }, - /* 7881 */ { MAD_F(0x04c9451e) /* 0.299138184 */, 19 }, - /* 7882 */ { MAD_F(0x04c97a30) /* 0.299188794 */, 19 }, - /* 7883 */ { MAD_F(0x04c9af42) /* 0.299239406 */, 19 }, - /* 7884 */ { MAD_F(0x04c9e455) /* 0.299290021 */, 19 }, - /* 7885 */ { MAD_F(0x04ca1968) /* 0.299340638 */, 19 }, - /* 7886 */ { MAD_F(0x04ca4e7c) /* 0.299391256 */, 19 }, - /* 7887 */ { MAD_F(0x04ca8391) /* 0.299441877 */, 19 }, - - /* 7888 */ { MAD_F(0x04cab8a6) /* 0.299492500 */, 19 }, - /* 7889 */ { MAD_F(0x04caedbb) /* 0.299543126 */, 19 }, - /* 7890 */ { MAD_F(0x04cb22d1) /* 0.299593753 */, 19 }, - /* 7891 */ { MAD_F(0x04cb57e8) /* 0.299644382 */, 19 }, - /* 7892 */ { MAD_F(0x04cb8d00) /* 0.299695014 */, 19 }, - /* 7893 */ { MAD_F(0x04cbc217) /* 0.299745648 */, 19 }, - /* 7894 */ { MAD_F(0x04cbf730) /* 0.299796284 */, 19 }, - /* 7895 */ { MAD_F(0x04cc2c49) /* 0.299846922 */, 19 }, - /* 7896 */ { MAD_F(0x04cc6163) /* 0.299897562 */, 19 }, - /* 7897 */ { MAD_F(0x04cc967d) /* 0.299948204 */, 19 }, - /* 7898 */ { MAD_F(0x04cccb98) /* 0.299998849 */, 19 }, - /* 7899 */ { MAD_F(0x04cd00b3) /* 0.300049495 */, 19 }, - /* 7900 */ { MAD_F(0x04cd35cf) /* 0.300100144 */, 19 }, - /* 7901 */ { MAD_F(0x04cd6aeb) /* 0.300150795 */, 19 }, - /* 7902 */ { MAD_F(0x04cda008) /* 0.300201448 */, 19 }, - /* 7903 */ { MAD_F(0x04cdd526) /* 0.300252103 */, 19 }, - - /* 7904 */ { MAD_F(0x04ce0a44) /* 0.300302761 */, 19 }, - /* 7905 */ { MAD_F(0x04ce3f63) /* 0.300353420 */, 19 }, - /* 7906 */ { MAD_F(0x04ce7482) /* 0.300404082 */, 19 }, - /* 7907 */ { MAD_F(0x04cea9a2) /* 0.300454745 */, 19 }, - /* 7908 */ { MAD_F(0x04cedec3) /* 0.300505411 */, 19 }, - /* 7909 */ { MAD_F(0x04cf13e4) /* 0.300556079 */, 19 }, - /* 7910 */ { MAD_F(0x04cf4906) /* 0.300606749 */, 19 }, - /* 7911 */ { MAD_F(0x04cf7e28) /* 0.300657421 */, 19 }, - /* 7912 */ { MAD_F(0x04cfb34b) /* 0.300708096 */, 19 }, - /* 7913 */ { MAD_F(0x04cfe86e) /* 0.300758772 */, 19 }, - /* 7914 */ { MAD_F(0x04d01d92) /* 0.300809451 */, 19 }, - /* 7915 */ { MAD_F(0x04d052b6) /* 0.300860132 */, 19 }, - /* 7916 */ { MAD_F(0x04d087db) /* 0.300910815 */, 19 }, - /* 7917 */ { MAD_F(0x04d0bd01) /* 0.300961500 */, 19 }, - /* 7918 */ { MAD_F(0x04d0f227) /* 0.301012187 */, 19 }, - /* 7919 */ { MAD_F(0x04d1274e) /* 0.301062876 */, 19 }, - - /* 7920 */ { MAD_F(0x04d15c76) /* 0.301113568 */, 19 }, - /* 7921 */ { MAD_F(0x04d1919e) /* 0.301164261 */, 19 }, - /* 7922 */ { MAD_F(0x04d1c6c6) /* 0.301214957 */, 19 }, - /* 7923 */ { MAD_F(0x04d1fbef) /* 0.301265655 */, 19 }, - /* 7924 */ { MAD_F(0x04d23119) /* 0.301316355 */, 19 }, - /* 7925 */ { MAD_F(0x04d26643) /* 0.301367057 */, 19 }, - /* 7926 */ { MAD_F(0x04d29b6e) /* 0.301417761 */, 19 }, - /* 7927 */ { MAD_F(0x04d2d099) /* 0.301468468 */, 19 }, - /* 7928 */ { MAD_F(0x04d305c5) /* 0.301519176 */, 19 }, - /* 7929 */ { MAD_F(0x04d33af2) /* 0.301569887 */, 19 }, - /* 7930 */ { MAD_F(0x04d3701f) /* 0.301620599 */, 19 }, - /* 7931 */ { MAD_F(0x04d3a54d) /* 0.301671314 */, 19 }, - /* 7932 */ { MAD_F(0x04d3da7b) /* 0.301722031 */, 19 }, - /* 7933 */ { MAD_F(0x04d40faa) /* 0.301772751 */, 19 }, - /* 7934 */ { MAD_F(0x04d444d9) /* 0.301823472 */, 19 }, - /* 7935 */ { MAD_F(0x04d47a09) /* 0.301874195 */, 19 }, - - /* 7936 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 19 }, - /* 7937 */ { MAD_F(0x04d4e46b) /* 0.301975649 */, 19 }, - /* 7938 */ { MAD_F(0x04d5199c) /* 0.302026378 */, 19 }, - /* 7939 */ { MAD_F(0x04d54ecf) /* 0.302077110 */, 19 }, - /* 7940 */ { MAD_F(0x04d58401) /* 0.302127845 */, 19 }, - /* 7941 */ { MAD_F(0x04d5b935) /* 0.302178581 */, 19 }, - /* 7942 */ { MAD_F(0x04d5ee69) /* 0.302229319 */, 19 }, - /* 7943 */ { MAD_F(0x04d6239d) /* 0.302280060 */, 19 }, - /* 7944 */ { MAD_F(0x04d658d2) /* 0.302330802 */, 19 }, - /* 7945 */ { MAD_F(0x04d68e08) /* 0.302381547 */, 19 }, - /* 7946 */ { MAD_F(0x04d6c33e) /* 0.302432294 */, 19 }, - /* 7947 */ { MAD_F(0x04d6f875) /* 0.302483043 */, 19 }, - /* 7948 */ { MAD_F(0x04d72dad) /* 0.302533794 */, 19 }, - /* 7949 */ { MAD_F(0x04d762e5) /* 0.302584547 */, 19 }, - /* 7950 */ { MAD_F(0x04d7981d) /* 0.302635303 */, 19 }, - /* 7951 */ { MAD_F(0x04d7cd56) /* 0.302686060 */, 19 }, - - /* 7952 */ { MAD_F(0x04d80290) /* 0.302736820 */, 19 }, - /* 7953 */ { MAD_F(0x04d837ca) /* 0.302787581 */, 19 }, - /* 7954 */ { MAD_F(0x04d86d05) /* 0.302838345 */, 19 }, - /* 7955 */ { MAD_F(0x04d8a240) /* 0.302889111 */, 19 }, - /* 7956 */ { MAD_F(0x04d8d77c) /* 0.302939879 */, 19 }, - /* 7957 */ { MAD_F(0x04d90cb9) /* 0.302990650 */, 19 }, - /* 7958 */ { MAD_F(0x04d941f6) /* 0.303041422 */, 19 }, - /* 7959 */ { MAD_F(0x04d97734) /* 0.303092197 */, 19 }, - /* 7960 */ { MAD_F(0x04d9ac72) /* 0.303142973 */, 19 }, - /* 7961 */ { MAD_F(0x04d9e1b1) /* 0.303193752 */, 19 }, - /* 7962 */ { MAD_F(0x04da16f0) /* 0.303244533 */, 19 }, - /* 7963 */ { MAD_F(0x04da4c30) /* 0.303295316 */, 19 }, - /* 7964 */ { MAD_F(0x04da8171) /* 0.303346101 */, 19 }, - /* 7965 */ { MAD_F(0x04dab6b2) /* 0.303396889 */, 19 }, - /* 7966 */ { MAD_F(0x04daebf4) /* 0.303447678 */, 19 }, - /* 7967 */ { MAD_F(0x04db2136) /* 0.303498469 */, 19 }, - - /* 7968 */ { MAD_F(0x04db5679) /* 0.303549263 */, 19 }, - /* 7969 */ { MAD_F(0x04db8bbc) /* 0.303600059 */, 19 }, - /* 7970 */ { MAD_F(0x04dbc100) /* 0.303650857 */, 19 }, - /* 7971 */ { MAD_F(0x04dbf644) /* 0.303701657 */, 19 }, - /* 7972 */ { MAD_F(0x04dc2b8a) /* 0.303752459 */, 19 }, - /* 7973 */ { MAD_F(0x04dc60cf) /* 0.303803263 */, 19 }, - /* 7974 */ { MAD_F(0x04dc9616) /* 0.303854070 */, 19 }, - /* 7975 */ { MAD_F(0x04dccb5c) /* 0.303904878 */, 19 }, - /* 7976 */ { MAD_F(0x04dd00a4) /* 0.303955689 */, 19 }, - /* 7977 */ { MAD_F(0x04dd35ec) /* 0.304006502 */, 19 }, - /* 7978 */ { MAD_F(0x04dd6b34) /* 0.304057317 */, 19 }, - /* 7979 */ { MAD_F(0x04dda07d) /* 0.304108134 */, 19 }, - /* 7980 */ { MAD_F(0x04ddd5c7) /* 0.304158953 */, 19 }, - /* 7981 */ { MAD_F(0x04de0b11) /* 0.304209774 */, 19 }, - /* 7982 */ { MAD_F(0x04de405c) /* 0.304260597 */, 19 }, - /* 7983 */ { MAD_F(0x04de75a7) /* 0.304311423 */, 19 }, - - /* 7984 */ { MAD_F(0x04deaaf3) /* 0.304362251 */, 19 }, - /* 7985 */ { MAD_F(0x04dee040) /* 0.304413080 */, 19 }, - /* 7986 */ { MAD_F(0x04df158d) /* 0.304463912 */, 19 }, - /* 7987 */ { MAD_F(0x04df4adb) /* 0.304514746 */, 19 }, - /* 7988 */ { MAD_F(0x04df8029) /* 0.304565582 */, 19 }, - /* 7989 */ { MAD_F(0x04dfb578) /* 0.304616421 */, 19 }, - /* 7990 */ { MAD_F(0x04dfeac7) /* 0.304667261 */, 19 }, - /* 7991 */ { MAD_F(0x04e02017) /* 0.304718103 */, 19 }, - /* 7992 */ { MAD_F(0x04e05567) /* 0.304768948 */, 19 }, - /* 7993 */ { MAD_F(0x04e08ab8) /* 0.304819795 */, 19 }, - /* 7994 */ { MAD_F(0x04e0c00a) /* 0.304870644 */, 19 }, - /* 7995 */ { MAD_F(0x04e0f55c) /* 0.304921495 */, 19 }, - /* 7996 */ { MAD_F(0x04e12aaf) /* 0.304972348 */, 19 }, - /* 7997 */ { MAD_F(0x04e16002) /* 0.305023203 */, 19 }, - /* 7998 */ { MAD_F(0x04e19556) /* 0.305074060 */, 19 }, - /* 7999 */ { MAD_F(0x04e1caab) /* 0.305124920 */, 19 }, - - /* 8000 */ { MAD_F(0x04e20000) /* 0.305175781 */, 19 }, - /* 8001 */ { MAD_F(0x04e23555) /* 0.305226645 */, 19 }, - /* 8002 */ { MAD_F(0x04e26aac) /* 0.305277511 */, 19 }, - /* 8003 */ { MAD_F(0x04e2a002) /* 0.305328379 */, 19 }, - /* 8004 */ { MAD_F(0x04e2d55a) /* 0.305379249 */, 19 }, - /* 8005 */ { MAD_F(0x04e30ab2) /* 0.305430121 */, 19 }, - /* 8006 */ { MAD_F(0x04e3400a) /* 0.305480995 */, 19 }, - /* 8007 */ { MAD_F(0x04e37563) /* 0.305531872 */, 19 }, - /* 8008 */ { MAD_F(0x04e3aabd) /* 0.305582750 */, 19 }, - /* 8009 */ { MAD_F(0x04e3e017) /* 0.305633631 */, 19 }, - /* 8010 */ { MAD_F(0x04e41572) /* 0.305684513 */, 19 }, - /* 8011 */ { MAD_F(0x04e44acd) /* 0.305735398 */, 19 }, - /* 8012 */ { MAD_F(0x04e48029) /* 0.305786285 */, 19 }, - /* 8013 */ { MAD_F(0x04e4b585) /* 0.305837174 */, 19 }, - /* 8014 */ { MAD_F(0x04e4eae2) /* 0.305888066 */, 19 }, - /* 8015 */ { MAD_F(0x04e52040) /* 0.305938959 */, 19 }, - - /* 8016 */ { MAD_F(0x04e5559e) /* 0.305989854 */, 19 }, - /* 8017 */ { MAD_F(0x04e58afd) /* 0.306040752 */, 19 }, - /* 8018 */ { MAD_F(0x04e5c05c) /* 0.306091652 */, 19 }, - /* 8019 */ { MAD_F(0x04e5f5bc) /* 0.306142554 */, 19 }, - /* 8020 */ { MAD_F(0x04e62b1c) /* 0.306193457 */, 19 }, - /* 8021 */ { MAD_F(0x04e6607d) /* 0.306244364 */, 19 }, - /* 8022 */ { MAD_F(0x04e695df) /* 0.306295272 */, 19 }, - /* 8023 */ { MAD_F(0x04e6cb41) /* 0.306346182 */, 19 }, - /* 8024 */ { MAD_F(0x04e700a3) /* 0.306397094 */, 19 }, - /* 8025 */ { MAD_F(0x04e73607) /* 0.306448009 */, 19 }, - /* 8026 */ { MAD_F(0x04e76b6b) /* 0.306498925 */, 19 }, - /* 8027 */ { MAD_F(0x04e7a0cf) /* 0.306549844 */, 19 }, - /* 8028 */ { MAD_F(0x04e7d634) /* 0.306600765 */, 19 }, - /* 8029 */ { MAD_F(0x04e80b99) /* 0.306651688 */, 19 }, - /* 8030 */ { MAD_F(0x04e84100) /* 0.306702613 */, 19 }, - /* 8031 */ { MAD_F(0x04e87666) /* 0.306753540 */, 19 }, - - /* 8032 */ { MAD_F(0x04e8abcd) /* 0.306804470 */, 19 }, - /* 8033 */ { MAD_F(0x04e8e135) /* 0.306855401 */, 19 }, - /* 8034 */ { MAD_F(0x04e9169e) /* 0.306906334 */, 19 }, - /* 8035 */ { MAD_F(0x04e94c07) /* 0.306957270 */, 19 }, - /* 8036 */ { MAD_F(0x04e98170) /* 0.307008208 */, 19 }, - /* 8037 */ { MAD_F(0x04e9b6da) /* 0.307059148 */, 19 }, - /* 8038 */ { MAD_F(0x04e9ec45) /* 0.307110090 */, 19 }, - /* 8039 */ { MAD_F(0x04ea21b0) /* 0.307161034 */, 19 }, - /* 8040 */ { MAD_F(0x04ea571c) /* 0.307211980 */, 19 }, - /* 8041 */ { MAD_F(0x04ea8c88) /* 0.307262928 */, 19 }, - /* 8042 */ { MAD_F(0x04eac1f5) /* 0.307313879 */, 19 }, - /* 8043 */ { MAD_F(0x04eaf762) /* 0.307364831 */, 19 }, - /* 8044 */ { MAD_F(0x04eb2cd0) /* 0.307415786 */, 19 }, - /* 8045 */ { MAD_F(0x04eb623f) /* 0.307466743 */, 19 }, - /* 8046 */ { MAD_F(0x04eb97ae) /* 0.307517702 */, 19 }, - /* 8047 */ { MAD_F(0x04ebcd1e) /* 0.307568663 */, 19 }, - - /* 8048 */ { MAD_F(0x04ec028e) /* 0.307619626 */, 19 }, - /* 8049 */ { MAD_F(0x04ec37ff) /* 0.307670591 */, 19 }, - /* 8050 */ { MAD_F(0x04ec6d71) /* 0.307721558 */, 19 }, - /* 8051 */ { MAD_F(0x04eca2e3) /* 0.307772528 */, 19 }, - /* 8052 */ { MAD_F(0x04ecd855) /* 0.307823499 */, 19 }, - /* 8053 */ { MAD_F(0x04ed0dc8) /* 0.307874473 */, 19 }, - /* 8054 */ { MAD_F(0x04ed433c) /* 0.307925449 */, 19 }, - /* 8055 */ { MAD_F(0x04ed78b0) /* 0.307976426 */, 19 }, - /* 8056 */ { MAD_F(0x04edae25) /* 0.308027406 */, 19 }, - /* 8057 */ { MAD_F(0x04ede39a) /* 0.308078389 */, 19 }, - /* 8058 */ { MAD_F(0x04ee1910) /* 0.308129373 */, 19 }, - /* 8059 */ { MAD_F(0x04ee4e87) /* 0.308180359 */, 19 }, - /* 8060 */ { MAD_F(0x04ee83fe) /* 0.308231347 */, 19 }, - /* 8061 */ { MAD_F(0x04eeb976) /* 0.308282338 */, 19 }, - /* 8062 */ { MAD_F(0x04eeeeee) /* 0.308333331 */, 19 }, - /* 8063 */ { MAD_F(0x04ef2467) /* 0.308384325 */, 19 }, - - /* 8064 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 19 }, - /* 8065 */ { MAD_F(0x04ef8f5a) /* 0.308486321 */, 19 }, - /* 8066 */ { MAD_F(0x04efc4d5) /* 0.308537322 */, 19 }, - /* 8067 */ { MAD_F(0x04effa50) /* 0.308588325 */, 19 }, - /* 8068 */ { MAD_F(0x04f02fcb) /* 0.308639331 */, 19 }, - /* 8069 */ { MAD_F(0x04f06547) /* 0.308690338 */, 19 }, - /* 8070 */ { MAD_F(0x04f09ac4) /* 0.308741348 */, 19 }, - /* 8071 */ { MAD_F(0x04f0d041) /* 0.308792359 */, 19 }, - /* 8072 */ { MAD_F(0x04f105bf) /* 0.308843373 */, 19 }, - /* 8073 */ { MAD_F(0x04f13b3e) /* 0.308894389 */, 19 }, - /* 8074 */ { MAD_F(0x04f170bd) /* 0.308945407 */, 19 }, - /* 8075 */ { MAD_F(0x04f1a63c) /* 0.308996427 */, 19 }, - /* 8076 */ { MAD_F(0x04f1dbbd) /* 0.309047449 */, 19 }, - /* 8077 */ { MAD_F(0x04f2113d) /* 0.309098473 */, 19 }, - /* 8078 */ { MAD_F(0x04f246bf) /* 0.309149499 */, 19 }, - /* 8079 */ { MAD_F(0x04f27c40) /* 0.309200528 */, 19 }, - - /* 8080 */ { MAD_F(0x04f2b1c3) /* 0.309251558 */, 19 }, - /* 8081 */ { MAD_F(0x04f2e746) /* 0.309302591 */, 19 }, - /* 8082 */ { MAD_F(0x04f31cc9) /* 0.309353626 */, 19 }, - /* 8083 */ { MAD_F(0x04f3524d) /* 0.309404663 */, 19 }, - /* 8084 */ { MAD_F(0x04f387d2) /* 0.309455702 */, 19 }, - /* 8085 */ { MAD_F(0x04f3bd57) /* 0.309506743 */, 19 }, - /* 8086 */ { MAD_F(0x04f3f2dd) /* 0.309557786 */, 19 }, - /* 8087 */ { MAD_F(0x04f42864) /* 0.309608831 */, 19 }, - /* 8088 */ { MAD_F(0x04f45dea) /* 0.309659879 */, 19 }, - /* 8089 */ { MAD_F(0x04f49372) /* 0.309710928 */, 19 }, - /* 8090 */ { MAD_F(0x04f4c8fa) /* 0.309761980 */, 19 }, - /* 8091 */ { MAD_F(0x04f4fe83) /* 0.309813033 */, 19 }, - /* 8092 */ { MAD_F(0x04f5340c) /* 0.309864089 */, 19 }, - /* 8093 */ { MAD_F(0x04f56996) /* 0.309915147 */, 19 }, - /* 8094 */ { MAD_F(0x04f59f20) /* 0.309966207 */, 19 }, - /* 8095 */ { MAD_F(0x04f5d4ab) /* 0.310017269 */, 19 }, - - /* 8096 */ { MAD_F(0x04f60a36) /* 0.310068333 */, 19 }, - /* 8097 */ { MAD_F(0x04f63fc2) /* 0.310119400 */, 19 }, - /* 8098 */ { MAD_F(0x04f6754f) /* 0.310170468 */, 19 }, - /* 8099 */ { MAD_F(0x04f6aadc) /* 0.310221539 */, 19 }, - /* 8100 */ { MAD_F(0x04f6e06a) /* 0.310272611 */, 19 }, - /* 8101 */ { MAD_F(0x04f715f8) /* 0.310323686 */, 19 }, - /* 8102 */ { MAD_F(0x04f74b87) /* 0.310374763 */, 19 }, - /* 8103 */ { MAD_F(0x04f78116) /* 0.310425842 */, 19 }, - /* 8104 */ { MAD_F(0x04f7b6a6) /* 0.310476923 */, 19 }, - /* 8105 */ { MAD_F(0x04f7ec37) /* 0.310528006 */, 19 }, - /* 8106 */ { MAD_F(0x04f821c8) /* 0.310579091 */, 19 }, - /* 8107 */ { MAD_F(0x04f85759) /* 0.310630179 */, 19 }, - /* 8108 */ { MAD_F(0x04f88cec) /* 0.310681268 */, 19 }, - /* 8109 */ { MAD_F(0x04f8c27e) /* 0.310732360 */, 19 }, - /* 8110 */ { MAD_F(0x04f8f812) /* 0.310783453 */, 19 }, - /* 8111 */ { MAD_F(0x04f92da6) /* 0.310834549 */, 19 }, - - /* 8112 */ { MAD_F(0x04f9633a) /* 0.310885647 */, 19 }, - /* 8113 */ { MAD_F(0x04f998cf) /* 0.310936747 */, 19 }, - /* 8114 */ { MAD_F(0x04f9ce65) /* 0.310987849 */, 19 }, - /* 8115 */ { MAD_F(0x04fa03fb) /* 0.311038953 */, 19 }, - /* 8116 */ { MAD_F(0x04fa3992) /* 0.311090059 */, 19 }, - /* 8117 */ { MAD_F(0x04fa6f29) /* 0.311141168 */, 19 }, - /* 8118 */ { MAD_F(0x04faa4c1) /* 0.311192278 */, 19 }, - /* 8119 */ { MAD_F(0x04fada59) /* 0.311243390 */, 19 }, - /* 8120 */ { MAD_F(0x04fb0ff2) /* 0.311294505 */, 19 }, - /* 8121 */ { MAD_F(0x04fb458c) /* 0.311345622 */, 19 }, - /* 8122 */ { MAD_F(0x04fb7b26) /* 0.311396741 */, 19 }, - /* 8123 */ { MAD_F(0x04fbb0c1) /* 0.311447862 */, 19 }, - /* 8124 */ { MAD_F(0x04fbe65c) /* 0.311498985 */, 19 }, - /* 8125 */ { MAD_F(0x04fc1bf8) /* 0.311550110 */, 19 }, - /* 8126 */ { MAD_F(0x04fc5194) /* 0.311601237 */, 19 }, - /* 8127 */ { MAD_F(0x04fc8731) /* 0.311652366 */, 19 }, - - /* 8128 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 19 }, - /* 8129 */ { MAD_F(0x04fcf26c) /* 0.311754631 */, 19 }, - /* 8130 */ { MAD_F(0x04fd280b) /* 0.311805767 */, 19 }, - /* 8131 */ { MAD_F(0x04fd5daa) /* 0.311856905 */, 19 }, - /* 8132 */ { MAD_F(0x04fd934a) /* 0.311908044 */, 19 }, - /* 8133 */ { MAD_F(0x04fdc8ea) /* 0.311959186 */, 19 }, - /* 8134 */ { MAD_F(0x04fdfe8b) /* 0.312010330 */, 19 }, - /* 8135 */ { MAD_F(0x04fe342c) /* 0.312061476 */, 19 }, - /* 8136 */ { MAD_F(0x04fe69ce) /* 0.312112625 */, 19 }, - /* 8137 */ { MAD_F(0x04fe9f71) /* 0.312163775 */, 19 }, - /* 8138 */ { MAD_F(0x04fed514) /* 0.312214927 */, 19 }, - /* 8139 */ { MAD_F(0x04ff0ab8) /* 0.312266082 */, 19 }, - /* 8140 */ { MAD_F(0x04ff405c) /* 0.312317238 */, 19 }, - /* 8141 */ { MAD_F(0x04ff7601) /* 0.312368397 */, 19 }, - /* 8142 */ { MAD_F(0x04ffaba6) /* 0.312419558 */, 19 }, - /* 8143 */ { MAD_F(0x04ffe14c) /* 0.312470720 */, 19 }, - - /* 8144 */ { MAD_F(0x050016f3) /* 0.312521885 */, 19 }, - /* 8145 */ { MAD_F(0x05004c9a) /* 0.312573052 */, 19 }, - /* 8146 */ { MAD_F(0x05008241) /* 0.312624222 */, 19 }, - /* 8147 */ { MAD_F(0x0500b7e9) /* 0.312675393 */, 19 }, - /* 8148 */ { MAD_F(0x0500ed92) /* 0.312726566 */, 19 }, - /* 8149 */ { MAD_F(0x0501233b) /* 0.312777742 */, 19 }, - /* 8150 */ { MAD_F(0x050158e5) /* 0.312828919 */, 19 }, - /* 8151 */ { MAD_F(0x05018e90) /* 0.312880099 */, 19 }, - /* 8152 */ { MAD_F(0x0501c43b) /* 0.312931280 */, 19 }, - /* 8153 */ { MAD_F(0x0501f9e6) /* 0.312982464 */, 19 }, - /* 8154 */ { MAD_F(0x05022f92) /* 0.313033650 */, 19 }, - /* 8155 */ { MAD_F(0x0502653f) /* 0.313084838 */, 19 }, - /* 8156 */ { MAD_F(0x05029aec) /* 0.313136028 */, 19 }, - /* 8157 */ { MAD_F(0x0502d09a) /* 0.313187220 */, 19 }, - /* 8158 */ { MAD_F(0x05030648) /* 0.313238414 */, 19 }, - /* 8159 */ { MAD_F(0x05033bf7) /* 0.313289611 */, 19 }, - - /* 8160 */ { MAD_F(0x050371a7) /* 0.313340809 */, 19 }, - /* 8161 */ { MAD_F(0x0503a757) /* 0.313392010 */, 19 }, - /* 8162 */ { MAD_F(0x0503dd07) /* 0.313443212 */, 19 }, - /* 8163 */ { MAD_F(0x050412b9) /* 0.313494417 */, 19 }, - /* 8164 */ { MAD_F(0x0504486a) /* 0.313545624 */, 19 }, - /* 8165 */ { MAD_F(0x05047e1d) /* 0.313596833 */, 19 }, - /* 8166 */ { MAD_F(0x0504b3cf) /* 0.313648044 */, 19 }, - /* 8167 */ { MAD_F(0x0504e983) /* 0.313699257 */, 19 }, - /* 8168 */ { MAD_F(0x05051f37) /* 0.313750472 */, 19 }, - /* 8169 */ { MAD_F(0x050554eb) /* 0.313801689 */, 19 }, - /* 8170 */ { MAD_F(0x05058aa0) /* 0.313852909 */, 19 }, - /* 8171 */ { MAD_F(0x0505c056) /* 0.313904130 */, 19 }, - /* 8172 */ { MAD_F(0x0505f60c) /* 0.313955354 */, 19 }, - /* 8173 */ { MAD_F(0x05062bc3) /* 0.314006579 */, 19 }, - /* 8174 */ { MAD_F(0x0506617a) /* 0.314057807 */, 19 }, - /* 8175 */ { MAD_F(0x05069732) /* 0.314109037 */, 19 }, - - /* 8176 */ { MAD_F(0x0506cceb) /* 0.314160269 */, 19 }, - /* 8177 */ { MAD_F(0x050702a4) /* 0.314211502 */, 19 }, - /* 8178 */ { MAD_F(0x0507385d) /* 0.314262739 */, 19 }, - /* 8179 */ { MAD_F(0x05076e17) /* 0.314313977 */, 19 }, - /* 8180 */ { MAD_F(0x0507a3d2) /* 0.314365217 */, 19 }, - /* 8181 */ { MAD_F(0x0507d98d) /* 0.314416459 */, 19 }, - /* 8182 */ { MAD_F(0x05080f49) /* 0.314467704 */, 19 }, - /* 8183 */ { MAD_F(0x05084506) /* 0.314518950 */, 19 }, - /* 8184 */ { MAD_F(0x05087ac2) /* 0.314570199 */, 19 }, - /* 8185 */ { MAD_F(0x0508b080) /* 0.314621449 */, 19 }, - /* 8186 */ { MAD_F(0x0508e63e) /* 0.314672702 */, 19 }, - /* 8187 */ { MAD_F(0x05091bfd) /* 0.314723957 */, 19 }, - /* 8188 */ { MAD_F(0x050951bc) /* 0.314775214 */, 19 }, - /* 8189 */ { MAD_F(0x0509877c) /* 0.314826473 */, 19 }, - /* 8190 */ { MAD_F(0x0509bd3c) /* 0.314877734 */, 19 }, - /* 8191 */ { MAD_F(0x0509f2fd) /* 0.314928997 */, 19 }, - - /* 8192 */ { MAD_F(0x050a28be) /* 0.314980262 */, 19 }, - /* 8193 */ { MAD_F(0x050a5e80) /* 0.315031530 */, 19 }, - /* 8194 */ { MAD_F(0x050a9443) /* 0.315082799 */, 19 }, - /* 8195 */ { MAD_F(0x050aca06) /* 0.315134071 */, 19 }, - /* 8196 */ { MAD_F(0x050affc9) /* 0.315185344 */, 19 }, - /* 8197 */ { MAD_F(0x050b358e) /* 0.315236620 */, 19 }, - /* 8198 */ { MAD_F(0x050b6b52) /* 0.315287898 */, 19 }, - /* 8199 */ { MAD_F(0x050ba118) /* 0.315339178 */, 19 }, - /* 8200 */ { MAD_F(0x050bd6de) /* 0.315390460 */, 19 }, - /* 8201 */ { MAD_F(0x050c0ca4) /* 0.315441744 */, 19 }, - /* 8202 */ { MAD_F(0x050c426b) /* 0.315493030 */, 19 }, - /* 8203 */ { MAD_F(0x050c7833) /* 0.315544318 */, 19 }, - /* 8204 */ { MAD_F(0x050cadfb) /* 0.315595608 */, 19 }, - /* 8205 */ { MAD_F(0x050ce3c4) /* 0.315646901 */, 19 }, - /* 8206 */ { MAD_F(0x050d198d) /* 0.315698195 */, 19 } + This is the lookup table used to compute x^(4/3) for Layer III + requantization. To maintain the best possible accuracy, the value is + stored as a normalized mantissa with exponent. The requantization + algorithm recombines these parts with appropriate scaling. +*/ + +/* 0 */ { MAD_F(0x00000000) /* 0.000000000 */, 0 }, +/* 1 */ { MAD_F(0x04000000) /* 0.250000000 */, 2 }, +/* 2 */ { MAD_F(0x050a28be) /* 0.314980262 */, 3 }, +/* 3 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 4 }, +/* 4 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 4 }, +/* 5 */ { MAD_F(0x04466275) /* 0.267183742 */, 5 }, +/* 6 */ { MAD_F(0x05738c72) /* 0.340710111 */, 5 }, +/* 7 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 5 }, +/* 8 */ { MAD_F(0x04000000) /* 0.250000000 */, 6 }, +/* 9 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 6 }, +/* 10 */ { MAD_F(0x0562d694) /* 0.336630420 */, 6 }, +/* 11 */ { MAD_F(0x061dae96) /* 0.382246578 */, 6 }, +/* 12 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 6 }, +/* 13 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 6 }, +/* 14 */ { MAD_F(0x0437be65) /* 0.263609310 */, 7 }, +/* 15 */ { MAD_F(0x049fc824) /* 0.289009227 */, 7 }, + +/* 16 */ { MAD_F(0x050a28be) /* 0.314980262 */, 7 }, +/* 17 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 7 }, +/* 18 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 7 }, +/* 19 */ { MAD_F(0x06566361) /* 0.396090870 */, 7 }, +/* 20 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 7 }, +/* 21 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 7 }, +/* 22 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 7 }, +/* 23 */ { MAD_F(0x04168b05) /* 0.255503674 */, 8 }, +/* 24 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 8 }, +/* 25 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 8 }, +/* 26 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 8 }, +/* 27 */ { MAD_F(0x05100000) /* 0.316406250 */, 8 }, +/* 28 */ { MAD_F(0x05506451) /* 0.332126919 */, 8 }, +/* 29 */ { MAD_F(0x05918e15) /* 0.348035890 */, 8 }, +/* 30 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 8 }, +/* 31 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 8 }, + +/* 32 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 8 }, +/* 33 */ { MAD_F(0x069d9400) /* 0.413471222 */, 8 }, +/* 34 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 8 }, +/* 35 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 8 }, +/* 36 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 8 }, +/* 37 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 8 }, +/* 38 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 8 }, +/* 39 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 9 }, +/* 40 */ { MAD_F(0x04466275) /* 0.267183742 */, 9 }, +/* 41 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 9 }, +/* 42 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 9 }, +/* 43 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 9 }, +/* 44 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 9 }, +/* 45 */ { MAD_F(0x05007b49) /* 0.312617576 */, 9 }, +/* 46 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 9 }, +/* 47 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 9 }, + +/* 48 */ { MAD_F(0x05738c72) /* 0.340710111 */, 9 }, +/* 49 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 9 }, +/* 50 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 9 }, +/* 51 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 9 }, +/* 52 */ { MAD_F(0x0610b982) /* 0.379083164 */, 9 }, +/* 53 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 9 }, +/* 54 */ { MAD_F(0x0660db91) /* 0.398646895 */, 9 }, +/* 55 */ { MAD_F(0x06894c90) /* 0.408520284 */, 9 }, +/* 56 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 9 }, +/* 57 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 9 }, +/* 58 */ { MAD_F(0x07041636) /* 0.438497744 */, 9 }, +/* 59 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 9 }, +/* 60 */ { MAD_F(0x075722ef) /* 0.458773552 */, 9 }, +/* 61 */ { MAD_F(0x078102b8) /* 0.468996735 */, 9 }, +/* 62 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 9 }, +/* 63 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 9 }, + +/* 64 */ { MAD_F(0x04000000) /* 0.250000000 */, 10 }, +/* 65 */ { MAD_F(0x04156381) /* 0.255221850 */, 10 }, +/* 66 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 10 }, +/* 67 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 10 }, +/* 68 */ { MAD_F(0x045635cf) /* 0.271047409 */, 10 }, +/* 69 */ { MAD_F(0x046c083e) /* 0.276375048 */, 10 }, +/* 70 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 10 }, +/* 71 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 10 }, +/* 72 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 10 }, +/* 73 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 10 }, +/* 74 */ { MAD_F(0x04dab524) /* 0.303395408 */, 10 }, +/* 75 */ { MAD_F(0x04f12624) /* 0.308874267 */, 10 }, +/* 76 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 10 }, +/* 77 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 10 }, +/* 78 */ { MAD_F(0x053511cb) /* 0.325456423 */, 10 }, +/* 79 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 10 }, + +/* 80 */ { MAD_F(0x0562d694) /* 0.336630420 */, 10 }, +/* 81 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 10 }, +/* 82 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 10 }, +/* 83 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 10 }, +/* 84 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 10 }, +/* 85 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 10 }, +/* 86 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 10 }, +/* 87 */ { MAD_F(0x0606012b) /* 0.376465960 */, 10 }, +/* 88 */ { MAD_F(0x061dae96) /* 0.382246578 */, 10 }, +/* 89 */ { MAD_F(0x06357302) /* 0.388049134 */, 10 }, +/* 90 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 10 }, +/* 91 */ { MAD_F(0x0665402d) /* 0.399719406 */, 10 }, +/* 92 */ { MAD_F(0x067d4896) /* 0.405586801 */, 10 }, +/* 93 */ { MAD_F(0x06956753) /* 0.411475493 */, 10 }, +/* 94 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 10 }, +/* 95 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 10 }, + +/* 96 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 10 }, +/* 97 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 10 }, +/* 98 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 10 }, +/* 99 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 10 }, +/* 100 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 10 }, +/* 101 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 10 }, +/* 102 */ { MAD_F(0x07724f64) /* 0.465407744 */, 10 }, +/* 103 */ { MAD_F(0x078b4514) /* 0.471501425 */, 10 }, +/* 104 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 10 }, +/* 105 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 10 }, +/* 106 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 10 }, +/* 107 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 10 }, +/* 108 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 11 }, +/* 109 */ { MAD_F(0x04115aca) /* 0.254236974 */, 11 }, +/* 110 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 11 }, +/* 111 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 11 }, + +/* 112 */ { MAD_F(0x0437be65) /* 0.263609310 */, 11 }, +/* 113 */ { MAD_F(0x04449dee) /* 0.266752177 */, 11 }, +/* 114 */ { MAD_F(0x04518733) /* 0.269904329 */, 11 }, +/* 115 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 11 }, +/* 116 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 11 }, +/* 117 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 11 }, +/* 118 */ { MAD_F(0x04858c83) /* 0.282604707 */, 11 }, +/* 119 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 11 }, +/* 120 */ { MAD_F(0x049fc824) /* 0.289009227 */, 11 }, +/* 121 */ { MAD_F(0x04acf402) /* 0.292224893 */, 11 }, +/* 122 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 11 }, +/* 123 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 11 }, +/* 124 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 11 }, +/* 125 */ { MAD_F(0x04e20000) /* 0.305175781 */, 11 }, +/* 126 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 11 }, +/* 127 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 11 }, + +/* 128 */ { MAD_F(0x050a28be) /* 0.314980262 */, 11 }, +/* 129 */ { MAD_F(0x05179da4) /* 0.318265572 */, 11 }, +/* 130 */ { MAD_F(0x05251b73) /* 0.321559381 */, 11 }, +/* 131 */ { MAD_F(0x0532a220) /* 0.324861647 */, 11 }, +/* 132 */ { MAD_F(0x054031a0) /* 0.328172327 */, 11 }, +/* 133 */ { MAD_F(0x054dc9e7) /* 0.331491377 */, 11 }, +/* 134 */ { MAD_F(0x055b6ae9) /* 0.334818756 */, 11 }, +/* 135 */ { MAD_F(0x0569149c) /* 0.338154423 */, 11 }, +/* 136 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 11 }, +/* 137 */ { MAD_F(0x058481e9) /* 0.344850455 */, 11 }, +/* 138 */ { MAD_F(0x0592456d) /* 0.348210741 */, 11 }, +/* 139 */ { MAD_F(0x05a01176) /* 0.351579152 */, 11 }, +/* 140 */ { MAD_F(0x05ade5fa) /* 0.354955651 */, 11 }, +/* 141 */ { MAD_F(0x05bbc2ef) /* 0.358340200 */, 11 }, +/* 142 */ { MAD_F(0x05c9a84a) /* 0.361732758 */, 11 }, +/* 143 */ { MAD_F(0x05d79601) /* 0.365133291 */, 11 }, + +/* 144 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 11 }, +/* 145 */ { MAD_F(0x05f38a5d) /* 0.371958126 */, 11 }, +/* 146 */ { MAD_F(0x060190ee) /* 0.375382356 */, 11 }, +/* 147 */ { MAD_F(0x060f9fb3) /* 0.378814413 */, 11 }, +/* 148 */ { MAD_F(0x061db6a5) /* 0.382254261 */, 11 }, +/* 149 */ { MAD_F(0x062bd5b8) /* 0.385701865 */, 11 }, +/* 150 */ { MAD_F(0x0639fce4) /* 0.389157191 */, 11 }, +/* 151 */ { MAD_F(0x06482c1f) /* 0.392620204 */, 11 }, +/* 152 */ { MAD_F(0x06566361) /* 0.396090870 */, 11 }, +/* 153 */ { MAD_F(0x0664a2a0) /* 0.399569155 */, 11 }, +/* 154 */ { MAD_F(0x0672e9d4) /* 0.403055027 */, 11 }, +/* 155 */ { MAD_F(0x068138f3) /* 0.406548452 */, 11 }, +/* 156 */ { MAD_F(0x068f8ff5) /* 0.410049398 */, 11 }, +/* 157 */ { MAD_F(0x069deed1) /* 0.413557833 */, 11 }, +/* 158 */ { MAD_F(0x06ac557f) /* 0.417073724 */, 11 }, +/* 159 */ { MAD_F(0x06bac3f6) /* 0.420597041 */, 11 }, + +/* 160 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 11 }, +/* 161 */ { MAD_F(0x06d7b81f) /* 0.427665827 */, 11 }, +/* 162 */ { MAD_F(0x06e63dc0) /* 0.431211234 */, 11 }, +/* 163 */ { MAD_F(0x06f4cb09) /* 0.434763944 */, 11 }, +/* 164 */ { MAD_F(0x07035ff3) /* 0.438323927 */, 11 }, +/* 165 */ { MAD_F(0x0711fc75) /* 0.441891153 */, 11 }, +/* 166 */ { MAD_F(0x0720a087) /* 0.445465593 */, 11 }, +/* 167 */ { MAD_F(0x072f4c22) /* 0.449047217 */, 11 }, +/* 168 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 11 }, +/* 169 */ { MAD_F(0x074cb9d3) /* 0.456231906 */, 11 }, +/* 170 */ { MAD_F(0x075b7bdb) /* 0.459834914 */, 11 }, +/* 171 */ { MAD_F(0x076a454c) /* 0.463444993 */, 11 }, +/* 172 */ { MAD_F(0x07791620) /* 0.467062117 */, 11 }, +/* 173 */ { MAD_F(0x0787ee50) /* 0.470686258 */, 11 }, +/* 174 */ { MAD_F(0x0796cdd4) /* 0.474317388 */, 11 }, +/* 175 */ { MAD_F(0x07a5b4a5) /* 0.477955481 */, 11 }, + +/* 176 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 11 }, +/* 177 */ { MAD_F(0x07c39812) /* 0.485252449 */, 11 }, +/* 178 */ { MAD_F(0x07d294a0) /* 0.488911273 */, 11 }, +/* 179 */ { MAD_F(0x07e1985f) /* 0.492576954 */, 11 }, +/* 180 */ { MAD_F(0x07f0a348) /* 0.496249468 */, 11 }, +/* 181 */ { MAD_F(0x07ffb554) /* 0.499928790 */, 11 }, +/* 182 */ { MAD_F(0x0407673f) /* 0.251807447 */, 12 }, +/* 183 */ { MAD_F(0x040ef75e) /* 0.253653877 */, 12 }, +/* 184 */ { MAD_F(0x04168b05) /* 0.255503674 */, 12 }, +/* 185 */ { MAD_F(0x041e2230) /* 0.257356825 */, 12 }, +/* 186 */ { MAD_F(0x0425bcdd) /* 0.259213318 */, 12 }, +/* 187 */ { MAD_F(0x042d5b07) /* 0.261073141 */, 12 }, +/* 188 */ { MAD_F(0x0434fcad) /* 0.262936282 */, 12 }, +/* 189 */ { MAD_F(0x043ca1c9) /* 0.264802730 */, 12 }, +/* 190 */ { MAD_F(0x04444a5a) /* 0.266672472 */, 12 }, +/* 191 */ { MAD_F(0x044bf65d) /* 0.268545497 */, 12 }, + +/* 192 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 12 }, +/* 193 */ { MAD_F(0x045b58a9) /* 0.272301352 */, 12 }, +/* 194 */ { MAD_F(0x04630eed) /* 0.274184158 */, 12 }, +/* 195 */ { MAD_F(0x046ac896) /* 0.276070203 */, 12 }, +/* 196 */ { MAD_F(0x047285a2) /* 0.277959474 */, 12 }, +/* 197 */ { MAD_F(0x047a460c) /* 0.279851960 */, 12 }, +/* 198 */ { MAD_F(0x048209d3) /* 0.281747652 */, 12 }, +/* 199 */ { MAD_F(0x0489d0f4) /* 0.283646538 */, 12 }, +/* 200 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 12 }, +/* 201 */ { MAD_F(0x04996935) /* 0.287453849 */, 12 }, +/* 202 */ { MAD_F(0x04a13a50) /* 0.289362253 */, 12 }, +/* 203 */ { MAD_F(0x04a90eba) /* 0.291273810 */, 12 }, +/* 204 */ { MAD_F(0x04b0e66e) /* 0.293188507 */, 12 }, +/* 205 */ { MAD_F(0x04b8c16c) /* 0.295106336 */, 12 }, +/* 206 */ { MAD_F(0x04c09faf) /* 0.297027285 */, 12 }, +/* 207 */ { MAD_F(0x04c88135) /* 0.298951346 */, 12 }, + +/* 208 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 12 }, +/* 209 */ { MAD_F(0x04d84dff) /* 0.302808759 */, 12 }, +/* 210 */ { MAD_F(0x04e0393e) /* 0.304742092 */, 12 }, +/* 211 */ { MAD_F(0x04e827b6) /* 0.306678497 */, 12 }, +/* 212 */ { MAD_F(0x04f01963) /* 0.308617963 */, 12 }, +/* 213 */ { MAD_F(0x04f80e44) /* 0.310560480 */, 12 }, +/* 214 */ { MAD_F(0x05000655) /* 0.312506041 */, 12 }, +/* 215 */ { MAD_F(0x05080195) /* 0.314454634 */, 12 }, +/* 216 */ { MAD_F(0x05100000) /* 0.316406250 */, 12 }, +/* 217 */ { MAD_F(0x05180194) /* 0.318360880 */, 12 }, +/* 218 */ { MAD_F(0x0520064f) /* 0.320318516 */, 12 }, +/* 219 */ { MAD_F(0x05280e2d) /* 0.322279147 */, 12 }, +/* 220 */ { MAD_F(0x0530192e) /* 0.324242764 */, 12 }, +/* 221 */ { MAD_F(0x0538274e) /* 0.326209359 */, 12 }, +/* 222 */ { MAD_F(0x0540388a) /* 0.328178922 */, 12 }, +/* 223 */ { MAD_F(0x05484ce2) /* 0.330151445 */, 12 }, + +/* 224 */ { MAD_F(0x05506451) /* 0.332126919 */, 12 }, +/* 225 */ { MAD_F(0x05587ed5) /* 0.334105334 */, 12 }, +/* 226 */ { MAD_F(0x05609c6e) /* 0.336086683 */, 12 }, +/* 227 */ { MAD_F(0x0568bd17) /* 0.338070956 */, 12 }, +/* 228 */ { MAD_F(0x0570e0cf) /* 0.340058145 */, 12 }, +/* 229 */ { MAD_F(0x05790793) /* 0.342048241 */, 12 }, +/* 230 */ { MAD_F(0x05813162) /* 0.344041237 */, 12 }, +/* 231 */ { MAD_F(0x05895e39) /* 0.346037122 */, 12 }, +/* 232 */ { MAD_F(0x05918e15) /* 0.348035890 */, 12 }, +/* 233 */ { MAD_F(0x0599c0f4) /* 0.350037532 */, 12 }, +/* 234 */ { MAD_F(0x05a1f6d5) /* 0.352042040 */, 12 }, +/* 235 */ { MAD_F(0x05aa2fb5) /* 0.354049405 */, 12 }, +/* 236 */ { MAD_F(0x05b26b92) /* 0.356059619 */, 12 }, +/* 237 */ { MAD_F(0x05baaa69) /* 0.358072674 */, 12 }, +/* 238 */ { MAD_F(0x05c2ec39) /* 0.360088563 */, 12 }, +/* 239 */ { MAD_F(0x05cb3100) /* 0.362107278 */, 12 }, + +/* 240 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 12 }, +/* 241 */ { MAD_F(0x05dbc368) /* 0.366153151 */, 12 }, +/* 242 */ { MAD_F(0x05e41105) /* 0.368180294 */, 12 }, +/* 243 */ { MAD_F(0x05ec6190) /* 0.370210231 */, 12 }, +/* 244 */ { MAD_F(0x05f4b507) /* 0.372242955 */, 12 }, +/* 245 */ { MAD_F(0x05fd0b68) /* 0.374278458 */, 12 }, +/* 246 */ { MAD_F(0x060564b1) /* 0.376316732 */, 12 }, +/* 247 */ { MAD_F(0x060dc0e0) /* 0.378357769 */, 12 }, +/* 248 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 12 }, +/* 249 */ { MAD_F(0x061e81e8) /* 0.382448106 */, 12 }, +/* 250 */ { MAD_F(0x0626e6bc) /* 0.384497391 */, 12 }, +/* 251 */ { MAD_F(0x062f4e6f) /* 0.386549409 */, 12 }, +/* 252 */ { MAD_F(0x0637b8fd) /* 0.388604155 */, 12 }, +/* 253 */ { MAD_F(0x06402666) /* 0.390661620 */, 12 }, +/* 254 */ { MAD_F(0x064896a7) /* 0.392721798 */, 12 }, +/* 255 */ { MAD_F(0x065109be) /* 0.394784681 */, 12 }, + +/* 256 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 12 }, +/* 257 */ { MAD_F(0x0661f867) /* 0.398918536 */, 12 }, +/* 258 */ { MAD_F(0x066a73f5) /* 0.400989493 */, 12 }, +/* 259 */ { MAD_F(0x0672f252) /* 0.403063128 */, 12 }, +/* 260 */ { MAD_F(0x067b737c) /* 0.405139433 */, 12 }, +/* 261 */ { MAD_F(0x0683f771) /* 0.407218402 */, 12 }, +/* 262 */ { MAD_F(0x068c7e2f) /* 0.409300027 */, 12 }, +/* 263 */ { MAD_F(0x069507b5) /* 0.411384303 */, 12 }, +/* 264 */ { MAD_F(0x069d9400) /* 0.413471222 */, 12 }, +/* 265 */ { MAD_F(0x06a6230f) /* 0.415560778 */, 12 }, +/* 266 */ { MAD_F(0x06aeb4e0) /* 0.417652964 */, 12 }, +/* 267 */ { MAD_F(0x06b74971) /* 0.419747773 */, 12 }, +/* 268 */ { MAD_F(0x06bfe0c0) /* 0.421845199 */, 12 }, +/* 269 */ { MAD_F(0x06c87acc) /* 0.423945235 */, 12 }, +/* 270 */ { MAD_F(0x06d11794) /* 0.426047876 */, 12 }, +/* 271 */ { MAD_F(0x06d9b714) /* 0.428153114 */, 12 }, + +/* 272 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 12 }, +/* 273 */ { MAD_F(0x06eafe3a) /* 0.432371356 */, 12 }, +/* 274 */ { MAD_F(0x06f3a5dc) /* 0.434484348 */, 12 }, +/* 275 */ { MAD_F(0x06fc5030) /* 0.436599912 */, 12 }, +/* 276 */ { MAD_F(0x0704fd35) /* 0.438718042 */, 12 }, +/* 277 */ { MAD_F(0x070dacea) /* 0.440838732 */, 12 }, +/* 278 */ { MAD_F(0x07165f4b) /* 0.442961975 */, 12 }, +/* 279 */ { MAD_F(0x071f1459) /* 0.445087765 */, 12 }, +/* 280 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 12 }, +/* 281 */ { MAD_F(0x07308671) /* 0.449346964 */, 12 }, +/* 282 */ { MAD_F(0x07394378) /* 0.451480360 */, 12 }, +/* 283 */ { MAD_F(0x07420325) /* 0.453616280 */, 12 }, +/* 284 */ { MAD_F(0x074ac575) /* 0.455754717 */, 12 }, +/* 285 */ { MAD_F(0x07538a67) /* 0.457895665 */, 12 }, +/* 286 */ { MAD_F(0x075c51fa) /* 0.460039119 */, 12 }, +/* 287 */ { MAD_F(0x07651c2c) /* 0.462185072 */, 12 }, + +/* 288 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 12 }, +/* 289 */ { MAD_F(0x0776b867) /* 0.466484455 */, 12 }, +/* 290 */ { MAD_F(0x077f8a6d) /* 0.468637872 */, 12 }, +/* 291 */ { MAD_F(0x07885f0b) /* 0.470793767 */, 12 }, +/* 292 */ { MAD_F(0x07913641) /* 0.472952132 */, 12 }, +/* 293 */ { MAD_F(0x079a100c) /* 0.475112962 */, 12 }, +/* 294 */ { MAD_F(0x07a2ec6c) /* 0.477276252 */, 12 }, +/* 295 */ { MAD_F(0x07abcb5f) /* 0.479441997 */, 12 }, +/* 296 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 12 }, +/* 297 */ { MAD_F(0x07bd90f6) /* 0.483780825 */, 12 }, +/* 298 */ { MAD_F(0x07c67798) /* 0.485953899 */, 12 }, +/* 299 */ { MAD_F(0x07cf60c7) /* 0.488129404 */, 12 }, +/* 300 */ { MAD_F(0x07d84c81) /* 0.490307336 */, 12 }, +/* 301 */ { MAD_F(0x07e13ac5) /* 0.492487690 */, 12 }, +/* 302 */ { MAD_F(0x07ea2b92) /* 0.494670459 */, 12 }, +/* 303 */ { MAD_F(0x07f31ee6) /* 0.496855639 */, 12 }, + +/* 304 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 12 }, +/* 305 */ { MAD_F(0x0402868e) /* 0.250616605 */, 13 }, +/* 306 */ { MAD_F(0x040703ff) /* 0.251712795 */, 13 }, +/* 307 */ { MAD_F(0x040b82b0) /* 0.252810180 */, 13 }, +/* 308 */ { MAD_F(0x041002a1) /* 0.253908756 */, 13 }, +/* 309 */ { MAD_F(0x041483d1) /* 0.255008523 */, 13 }, +/* 310 */ { MAD_F(0x04190640) /* 0.256109476 */, 13 }, +/* 311 */ { MAD_F(0x041d89ed) /* 0.257211614 */, 13 }, +/* 312 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 13 }, +/* 313 */ { MAD_F(0x042694fe) /* 0.259419433 */, 13 }, +/* 314 */ { MAD_F(0x042b1c60) /* 0.260525110 */, 13 }, +/* 315 */ { MAD_F(0x042fa4fe) /* 0.261631960 */, 13 }, +/* 316 */ { MAD_F(0x04342ed7) /* 0.262739982 */, 13 }, +/* 317 */ { MAD_F(0x0438b9e9) /* 0.263849174 */, 13 }, +/* 318 */ { MAD_F(0x043d4635) /* 0.264959533 */, 13 }, +/* 319 */ { MAD_F(0x0441d3b9) /* 0.266071056 */, 13 }, + +/* 320 */ { MAD_F(0x04466275) /* 0.267183742 */, 13 }, +/* 321 */ { MAD_F(0x044af269) /* 0.268297587 */, 13 }, +/* 322 */ { MAD_F(0x044f8393) /* 0.269412589 */, 13 }, +/* 323 */ { MAD_F(0x045415f3) /* 0.270528746 */, 13 }, +/* 324 */ { MAD_F(0x0458a989) /* 0.271646056 */, 13 }, +/* 325 */ { MAD_F(0x045d3e53) /* 0.272764515 */, 13 }, +/* 326 */ { MAD_F(0x0461d451) /* 0.273884123 */, 13 }, +/* 327 */ { MAD_F(0x04666b83) /* 0.275004875 */, 13 }, +/* 328 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 13 }, +/* 329 */ { MAD_F(0x046f9d7e) /* 0.277249808 */, 13 }, +/* 330 */ { MAD_F(0x04743847) /* 0.278373983 */, 13 }, +/* 331 */ { MAD_F(0x0478d440) /* 0.279499294 */, 13 }, +/* 332 */ { MAD_F(0x047d716a) /* 0.280625739 */, 13 }, +/* 333 */ { MAD_F(0x04820fc3) /* 0.281753315 */, 13 }, +/* 334 */ { MAD_F(0x0486af4c) /* 0.282882021 */, 13 }, +/* 335 */ { MAD_F(0x048b5003) /* 0.284011853 */, 13 }, + +/* 336 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 13 }, +/* 337 */ { MAD_F(0x049494fb) /* 0.286274891 */, 13 }, +/* 338 */ { MAD_F(0x0499393a) /* 0.287408091 */, 13 }, +/* 339 */ { MAD_F(0x049ddea5) /* 0.288542409 */, 13 }, +/* 340 */ { MAD_F(0x04a2853c) /* 0.289677844 */, 13 }, +/* 341 */ { MAD_F(0x04a72cfe) /* 0.290814392 */, 13 }, +/* 342 */ { MAD_F(0x04abd5ea) /* 0.291952051 */, 13 }, +/* 343 */ { MAD_F(0x04b08000) /* 0.293090820 */, 13 }, +/* 344 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 13 }, +/* 345 */ { MAD_F(0x04b9d7a7) /* 0.295371678 */, 13 }, +/* 346 */ { MAD_F(0x04be8537) /* 0.296513762 */, 13 }, +/* 347 */ { MAD_F(0x04c333ee) /* 0.297656947 */, 13 }, +/* 348 */ { MAD_F(0x04c7e3cc) /* 0.298801231 */, 13 }, +/* 349 */ { MAD_F(0x04cc94d1) /* 0.299946611 */, 13 }, +/* 350 */ { MAD_F(0x04d146fb) /* 0.301093085 */, 13 }, +/* 351 */ { MAD_F(0x04d5fa4b) /* 0.302240653 */, 13 }, + +/* 352 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 13 }, +/* 353 */ { MAD_F(0x04df6458) /* 0.304539056 */, 13 }, +/* 354 */ { MAD_F(0x04e41b14) /* 0.305689888 */, 13 }, +/* 355 */ { MAD_F(0x04e8d2f3) /* 0.306841804 */, 13 }, +/* 356 */ { MAD_F(0x04ed8bf5) /* 0.307994802 */, 13 }, +/* 357 */ { MAD_F(0x04f24618) /* 0.309148880 */, 13 }, +/* 358 */ { MAD_F(0x04f7015d) /* 0.310304037 */, 13 }, +/* 359 */ { MAD_F(0x04fbbdc3) /* 0.311460269 */, 13 }, +/* 360 */ { MAD_F(0x05007b49) /* 0.312617576 */, 13 }, +/* 361 */ { MAD_F(0x050539ef) /* 0.313775954 */, 13 }, +/* 362 */ { MAD_F(0x0509f9b4) /* 0.314935403 */, 13 }, +/* 363 */ { MAD_F(0x050eba98) /* 0.316095920 */, 13 }, +/* 364 */ { MAD_F(0x05137c9a) /* 0.317257503 */, 13 }, +/* 365 */ { MAD_F(0x05183fba) /* 0.318420150 */, 13 }, +/* 366 */ { MAD_F(0x051d03f7) /* 0.319583859 */, 13 }, +/* 367 */ { MAD_F(0x0521c950) /* 0.320748629 */, 13 }, + +/* 368 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 13 }, +/* 369 */ { MAD_F(0x052b5757) /* 0.323081342 */, 13 }, +/* 370 */ { MAD_F(0x05302003) /* 0.324249281 */, 13 }, +/* 371 */ { MAD_F(0x0534e9ca) /* 0.325418273 */, 13 }, +/* 372 */ { MAD_F(0x0539b4ab) /* 0.326588316 */, 13 }, +/* 373 */ { MAD_F(0x053e80a6) /* 0.327759407 */, 13 }, +/* 374 */ { MAD_F(0x05434db9) /* 0.328931546 */, 13 }, +/* 375 */ { MAD_F(0x05481be5) /* 0.330104730 */, 13 }, +/* 376 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 13 }, +/* 377 */ { MAD_F(0x0551bb85) /* 0.332454225 */, 13 }, +/* 378 */ { MAD_F(0x05568cf8) /* 0.333630533 */, 13 }, +/* 379 */ { MAD_F(0x055b5f81) /* 0.334807879 */, 13 }, +/* 380 */ { MAD_F(0x05603321) /* 0.335986261 */, 13 }, +/* 381 */ { MAD_F(0x056507d6) /* 0.337165677 */, 13 }, +/* 382 */ { MAD_F(0x0569dda0) /* 0.338346125 */, 13 }, +/* 383 */ { MAD_F(0x056eb47f) /* 0.339527604 */, 13 }, + +/* 384 */ { MAD_F(0x05738c72) /* 0.340710111 */, 13 }, +/* 385 */ { MAD_F(0x05786578) /* 0.341893646 */, 13 }, +/* 386 */ { MAD_F(0x057d3f92) /* 0.343078205 */, 13 }, +/* 387 */ { MAD_F(0x05821abf) /* 0.344263788 */, 13 }, +/* 388 */ { MAD_F(0x0586f6fd) /* 0.345450393 */, 13 }, +/* 389 */ { MAD_F(0x058bd44e) /* 0.346638017 */, 13 }, +/* 390 */ { MAD_F(0x0590b2b0) /* 0.347826659 */, 13 }, +/* 391 */ { MAD_F(0x05959222) /* 0.349016318 */, 13 }, +/* 392 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 13 }, +/* 393 */ { MAD_F(0x059f5438) /* 0.351398678 */, 13 }, +/* 394 */ { MAD_F(0x05a436da) /* 0.352591376 */, 13 }, +/* 395 */ { MAD_F(0x05a91a8c) /* 0.353785083 */, 13 }, +/* 396 */ { MAD_F(0x05adff4c) /* 0.354979798 */, 13 }, +/* 397 */ { MAD_F(0x05b2e51a) /* 0.356175519 */, 13 }, +/* 398 */ { MAD_F(0x05b7cbf5) /* 0.357372244 */, 13 }, +/* 399 */ { MAD_F(0x05bcb3de) /* 0.358569972 */, 13 }, + +/* 400 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 13 }, +/* 401 */ { MAD_F(0x05c686d5) /* 0.360968429 */, 13 }, +/* 402 */ { MAD_F(0x05cb71e2) /* 0.362169156 */, 13 }, +/* 403 */ { MAD_F(0x05d05dfb) /* 0.363370878 */, 13 }, +/* 404 */ { MAD_F(0x05d54b1f) /* 0.364573594 */, 13 }, +/* 405 */ { MAD_F(0x05da394d) /* 0.365777304 */, 13 }, +/* 406 */ { MAD_F(0x05df2885) /* 0.366982004 */, 13 }, +/* 407 */ { MAD_F(0x05e418c7) /* 0.368187694 */, 13 }, +/* 408 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 13 }, +/* 409 */ { MAD_F(0x05edfc66) /* 0.370602036 */, 13 }, +/* 410 */ { MAD_F(0x05f2efc2) /* 0.371810684 */, 13 }, +/* 411 */ { MAD_F(0x05f7e426) /* 0.373020316 */, 13 }, +/* 412 */ { MAD_F(0x05fcd992) /* 0.374230929 */, 13 }, +/* 413 */ { MAD_F(0x0601d004) /* 0.375442522 */, 13 }, +/* 414 */ { MAD_F(0x0606c77d) /* 0.376655093 */, 13 }, +/* 415 */ { MAD_F(0x060bbffd) /* 0.377868641 */, 13 }, + +/* 416 */ { MAD_F(0x0610b982) /* 0.379083164 */, 13 }, +/* 417 */ { MAD_F(0x0615b40c) /* 0.380298661 */, 13 }, +/* 418 */ { MAD_F(0x061aaf9c) /* 0.381515130 */, 13 }, +/* 419 */ { MAD_F(0x061fac2f) /* 0.382732569 */, 13 }, +/* 420 */ { MAD_F(0x0624a9c7) /* 0.383950977 */, 13 }, +/* 421 */ { MAD_F(0x0629a863) /* 0.385170352 */, 13 }, +/* 422 */ { MAD_F(0x062ea802) /* 0.386390694 */, 13 }, +/* 423 */ { MAD_F(0x0633a8a3) /* 0.387611999 */, 13 }, +/* 424 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 13 }, +/* 425 */ { MAD_F(0x063dacee) /* 0.390057497 */, 13 }, +/* 426 */ { MAD_F(0x0642b096) /* 0.391281687 */, 13 }, +/* 427 */ { MAD_F(0x0647b53f) /* 0.392506834 */, 13 }, +/* 428 */ { MAD_F(0x064cbae9) /* 0.393732939 */, 13 }, +/* 429 */ { MAD_F(0x0651c193) /* 0.394959999 */, 13 }, +/* 430 */ { MAD_F(0x0656c93d) /* 0.396188012 */, 13 }, +/* 431 */ { MAD_F(0x065bd1e7) /* 0.397416978 */, 13 }, + +/* 432 */ { MAD_F(0x0660db91) /* 0.398646895 */, 13 }, +/* 433 */ { MAD_F(0x0665e639) /* 0.399877761 */, 13 }, +/* 434 */ { MAD_F(0x066af1df) /* 0.401109575 */, 13 }, +/* 435 */ { MAD_F(0x066ffe84) /* 0.402342335 */, 13 }, +/* 436 */ { MAD_F(0x06750c26) /* 0.403576041 */, 13 }, +/* 437 */ { MAD_F(0x067a1ac6) /* 0.404810690 */, 13 }, +/* 438 */ { MAD_F(0x067f2a62) /* 0.406046281 */, 13 }, +/* 439 */ { MAD_F(0x06843afb) /* 0.407282813 */, 13 }, +/* 440 */ { MAD_F(0x06894c90) /* 0.408520284 */, 13 }, +/* 441 */ { MAD_F(0x068e5f21) /* 0.409758693 */, 13 }, +/* 442 */ { MAD_F(0x069372ae) /* 0.410998038 */, 13 }, +/* 443 */ { MAD_F(0x06988735) /* 0.412238319 */, 13 }, +/* 444 */ { MAD_F(0x069d9cb7) /* 0.413479532 */, 13 }, +/* 445 */ { MAD_F(0x06a2b333) /* 0.414721679 */, 13 }, +/* 446 */ { MAD_F(0x06a7caa9) /* 0.415964756 */, 13 }, +/* 447 */ { MAD_F(0x06ace318) /* 0.417208762 */, 13 }, + +/* 448 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 13 }, +/* 449 */ { MAD_F(0x06b716e2) /* 0.419699557 */, 13 }, +/* 450 */ { MAD_F(0x06bc323b) /* 0.420946343 */, 13 }, +/* 451 */ { MAD_F(0x06c14e8d) /* 0.422194054 */, 13 }, +/* 452 */ { MAD_F(0x06c66bd6) /* 0.423442686 */, 13 }, +/* 453 */ { MAD_F(0x06cb8a17) /* 0.424692240 */, 13 }, +/* 454 */ { MAD_F(0x06d0a94e) /* 0.425942714 */, 13 }, +/* 455 */ { MAD_F(0x06d5c97c) /* 0.427194106 */, 13 }, +/* 456 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 13 }, +/* 457 */ { MAD_F(0x06e00cbb) /* 0.429699640 */, 13 }, +/* 458 */ { MAD_F(0x06e52fca) /* 0.430953779 */, 13 }, +/* 459 */ { MAD_F(0x06ea53cf) /* 0.432208832 */, 13 }, +/* 460 */ { MAD_F(0x06ef78c8) /* 0.433464796 */, 13 }, +/* 461 */ { MAD_F(0x06f49eb6) /* 0.434721671 */, 13 }, +/* 462 */ { MAD_F(0x06f9c597) /* 0.435979455 */, 13 }, +/* 463 */ { MAD_F(0x06feed6d) /* 0.437238146 */, 13 }, + +/* 464 */ { MAD_F(0x07041636) /* 0.438497744 */, 13 }, +/* 465 */ { MAD_F(0x07093ff2) /* 0.439758248 */, 13 }, +/* 466 */ { MAD_F(0x070e6aa0) /* 0.441019655 */, 13 }, +/* 467 */ { MAD_F(0x07139641) /* 0.442281965 */, 13 }, +/* 468 */ { MAD_F(0x0718c2d3) /* 0.443545176 */, 13 }, +/* 469 */ { MAD_F(0x071df058) /* 0.444809288 */, 13 }, +/* 470 */ { MAD_F(0x07231ecd) /* 0.446074298 */, 13 }, +/* 471 */ { MAD_F(0x07284e34) /* 0.447340205 */, 13 }, +/* 472 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 13 }, +/* 473 */ { MAD_F(0x0732afd2) /* 0.449874708 */, 13 }, +/* 474 */ { MAD_F(0x0737e209) /* 0.451143300 */, 13 }, +/* 475 */ { MAD_F(0x073d1530) /* 0.452412785 */, 13 }, +/* 476 */ { MAD_F(0x07424946) /* 0.453683161 */, 13 }, +/* 477 */ { MAD_F(0x07477e4b) /* 0.454954427 */, 13 }, +/* 478 */ { MAD_F(0x074cb43e) /* 0.456226581 */, 13 }, +/* 479 */ { MAD_F(0x0751eb20) /* 0.457499623 */, 13 }, + +/* 480 */ { MAD_F(0x075722ef) /* 0.458773552 */, 13 }, +/* 481 */ { MAD_F(0x075c5bac) /* 0.460048365 */, 13 }, +/* 482 */ { MAD_F(0x07619557) /* 0.461324062 */, 13 }, +/* 483 */ { MAD_F(0x0766cfee) /* 0.462600642 */, 13 }, +/* 484 */ { MAD_F(0x076c0b72) /* 0.463878102 */, 13 }, +/* 485 */ { MAD_F(0x077147e2) /* 0.465156443 */, 13 }, +/* 486 */ { MAD_F(0x0776853e) /* 0.466435663 */, 13 }, +/* 487 */ { MAD_F(0x077bc385) /* 0.467715761 */, 13 }, +/* 488 */ { MAD_F(0x078102b8) /* 0.468996735 */, 13 }, +/* 489 */ { MAD_F(0x078642d6) /* 0.470278584 */, 13 }, +/* 490 */ { MAD_F(0x078b83de) /* 0.471561307 */, 13 }, +/* 491 */ { MAD_F(0x0790c5d1) /* 0.472844904 */, 13 }, +/* 492 */ { MAD_F(0x079608ae) /* 0.474129372 */, 13 }, +/* 493 */ { MAD_F(0x079b4c74) /* 0.475414710 */, 13 }, +/* 494 */ { MAD_F(0x07a09124) /* 0.476700918 */, 13 }, +/* 495 */ { MAD_F(0x07a5d6bd) /* 0.477987994 */, 13 }, + +/* 496 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 13 }, +/* 497 */ { MAD_F(0x07b064a8) /* 0.480564746 */, 13 }, +/* 498 */ { MAD_F(0x07b5acfb) /* 0.481854420 */, 13 }, +/* 499 */ { MAD_F(0x07baf635) /* 0.483144957 */, 13 }, +/* 500 */ { MAD_F(0x07c04056) /* 0.484436356 */, 13 }, +/* 501 */ { MAD_F(0x07c58b5f) /* 0.485728617 */, 13 }, +/* 502 */ { MAD_F(0x07cad74e) /* 0.487021738 */, 13 }, +/* 503 */ { MAD_F(0x07d02424) /* 0.488315717 */, 13 }, +/* 504 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 13 }, +/* 505 */ { MAD_F(0x07dac083) /* 0.490906249 */, 13 }, +/* 506 */ { MAD_F(0x07e0100a) /* 0.492202799 */, 13 }, +/* 507 */ { MAD_F(0x07e56078) /* 0.493500203 */, 13 }, +/* 508 */ { MAD_F(0x07eab1ca) /* 0.494798460 */, 13 }, +/* 509 */ { MAD_F(0x07f00401) /* 0.496097570 */, 13 }, +/* 510 */ { MAD_F(0x07f5571d) /* 0.497397530 */, 13 }, +/* 511 */ { MAD_F(0x07faab1c) /* 0.498698341 */, 13 }, + +/* 512 */ { MAD_F(0x04000000) /* 0.250000000 */, 14 }, +/* 513 */ { MAD_F(0x0402aae3) /* 0.250651254 */, 14 }, +/* 514 */ { MAD_F(0x04055638) /* 0.251302930 */, 14 }, +/* 515 */ { MAD_F(0x040801ff) /* 0.251955030 */, 14 }, +/* 516 */ { MAD_F(0x040aae37) /* 0.252607552 */, 14 }, +/* 517 */ { MAD_F(0x040d5ae0) /* 0.253260495 */, 14 }, +/* 518 */ { MAD_F(0x041007fa) /* 0.253913860 */, 14 }, +/* 519 */ { MAD_F(0x0412b586) /* 0.254567645 */, 14 }, +/* 520 */ { MAD_F(0x04156381) /* 0.255221850 */, 14 }, +/* 521 */ { MAD_F(0x041811ee) /* 0.255876475 */, 14 }, +/* 522 */ { MAD_F(0x041ac0cb) /* 0.256531518 */, 14 }, +/* 523 */ { MAD_F(0x041d7018) /* 0.257186980 */, 14 }, +/* 524 */ { MAD_F(0x04201fd5) /* 0.257842860 */, 14 }, +/* 525 */ { MAD_F(0x0422d003) /* 0.258499157 */, 14 }, +/* 526 */ { MAD_F(0x042580a0) /* 0.259155872 */, 14 }, +/* 527 */ { MAD_F(0x042831ad) /* 0.259813002 */, 14 }, + +/* 528 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 14 }, +/* 529 */ { MAD_F(0x042d9516) /* 0.261128510 */, 14 }, +/* 530 */ { MAD_F(0x04304772) /* 0.261786886 */, 14 }, +/* 531 */ { MAD_F(0x0432fa3d) /* 0.262445676 */, 14 }, +/* 532 */ { MAD_F(0x0435ad76) /* 0.263104880 */, 14 }, +/* 533 */ { MAD_F(0x0438611f) /* 0.263764497 */, 14 }, +/* 534 */ { MAD_F(0x043b1536) /* 0.264424527 */, 14 }, +/* 535 */ { MAD_F(0x043dc9bc) /* 0.265084969 */, 14 }, +/* 536 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 14 }, +/* 537 */ { MAD_F(0x04433414) /* 0.266407088 */, 14 }, +/* 538 */ { MAD_F(0x0445e9e5) /* 0.267068763 */, 14 }, +/* 539 */ { MAD_F(0x0448a024) /* 0.267730848 */, 14 }, +/* 540 */ { MAD_F(0x044b56d1) /* 0.268393343 */, 14 }, +/* 541 */ { MAD_F(0x044e0dec) /* 0.269056248 */, 14 }, +/* 542 */ { MAD_F(0x0450c575) /* 0.269719560 */, 14 }, +/* 543 */ { MAD_F(0x04537d6b) /* 0.270383281 */, 14 }, + +/* 544 */ { MAD_F(0x045635cf) /* 0.271047409 */, 14 }, +/* 545 */ { MAD_F(0x0458ee9f) /* 0.271711944 */, 14 }, +/* 546 */ { MAD_F(0x045ba7dd) /* 0.272376886 */, 14 }, +/* 547 */ { MAD_F(0x045e6188) /* 0.273042234 */, 14 }, +/* 548 */ { MAD_F(0x04611ba0) /* 0.273707988 */, 14 }, +/* 549 */ { MAD_F(0x0463d625) /* 0.274374147 */, 14 }, +/* 550 */ { MAD_F(0x04669116) /* 0.275040710 */, 14 }, +/* 551 */ { MAD_F(0x04694c74) /* 0.275707677 */, 14 }, +/* 552 */ { MAD_F(0x046c083e) /* 0.276375048 */, 14 }, +/* 553 */ { MAD_F(0x046ec474) /* 0.277042822 */, 14 }, +/* 554 */ { MAD_F(0x04718116) /* 0.277710999 */, 14 }, +/* 555 */ { MAD_F(0x04743e25) /* 0.278379578 */, 14 }, +/* 556 */ { MAD_F(0x0476fb9f) /* 0.279048558 */, 14 }, +/* 557 */ { MAD_F(0x0479b984) /* 0.279717940 */, 14 }, +/* 558 */ { MAD_F(0x047c77d6) /* 0.280387722 */, 14 }, +/* 559 */ { MAD_F(0x047f3693) /* 0.281057905 */, 14 }, + +/* 560 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 14 }, +/* 561 */ { MAD_F(0x0484b54e) /* 0.282399469 */, 14 }, +/* 562 */ { MAD_F(0x0487754c) /* 0.283070849 */, 14 }, +/* 563 */ { MAD_F(0x048a35b6) /* 0.283742628 */, 14 }, +/* 564 */ { MAD_F(0x048cf68a) /* 0.284414805 */, 14 }, +/* 565 */ { MAD_F(0x048fb7c8) /* 0.285087379 */, 14 }, +/* 566 */ { MAD_F(0x04927972) /* 0.285760350 */, 14 }, +/* 567 */ { MAD_F(0x04953b85) /* 0.286433717 */, 14 }, +/* 568 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 14 }, +/* 569 */ { MAD_F(0x049ac0eb) /* 0.287781640 */, 14 }, +/* 570 */ { MAD_F(0x049d843e) /* 0.288456194 */, 14 }, +/* 571 */ { MAD_F(0x04a047fa) /* 0.289131142 */, 14 }, +/* 572 */ { MAD_F(0x04a30c20) /* 0.289806485 */, 14 }, +/* 573 */ { MAD_F(0x04a5d0af) /* 0.290482221 */, 14 }, +/* 574 */ { MAD_F(0x04a895a8) /* 0.291158351 */, 14 }, +/* 575 */ { MAD_F(0x04ab5b0b) /* 0.291834873 */, 14 }, + +/* 576 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 14 }, +/* 577 */ { MAD_F(0x04b0e70c) /* 0.293189094 */, 14 }, +/* 578 */ { MAD_F(0x04b3adaa) /* 0.293866792 */, 14 }, +/* 579 */ { MAD_F(0x04b674b1) /* 0.294544881 */, 14 }, +/* 580 */ { MAD_F(0x04b93c21) /* 0.295223360 */, 14 }, +/* 581 */ { MAD_F(0x04bc03fa) /* 0.295902229 */, 14 }, +/* 582 */ { MAD_F(0x04becc3b) /* 0.296581488 */, 14 }, +/* 583 */ { MAD_F(0x04c194e4) /* 0.297261136 */, 14 }, +/* 584 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 14 }, +/* 585 */ { MAD_F(0x04c72771) /* 0.298621598 */, 14 }, +/* 586 */ { MAD_F(0x04c9f153) /* 0.299302411 */, 14 }, +/* 587 */ { MAD_F(0x04ccbb9d) /* 0.299983611 */, 14 }, +/* 588 */ { MAD_F(0x04cf864f) /* 0.300665198 */, 14 }, +/* 589 */ { MAD_F(0x04d25169) /* 0.301347172 */, 14 }, +/* 590 */ { MAD_F(0x04d51ceb) /* 0.302029532 */, 14 }, +/* 591 */ { MAD_F(0x04d7e8d4) /* 0.302712277 */, 14 }, + +/* 592 */ { MAD_F(0x04dab524) /* 0.303395408 */, 14 }, +/* 593 */ { MAD_F(0x04dd81dc) /* 0.304078923 */, 14 }, +/* 594 */ { MAD_F(0x04e04efb) /* 0.304762823 */, 14 }, +/* 595 */ { MAD_F(0x04e31c81) /* 0.305447106 */, 14 }, +/* 596 */ { MAD_F(0x04e5ea6e) /* 0.306131773 */, 14 }, +/* 597 */ { MAD_F(0x04e8b8c2) /* 0.306816823 */, 14 }, +/* 598 */ { MAD_F(0x04eb877c) /* 0.307502256 */, 14 }, +/* 599 */ { MAD_F(0x04ee569d) /* 0.308188071 */, 14 }, +/* 600 */ { MAD_F(0x04f12624) /* 0.308874267 */, 14 }, +/* 601 */ { MAD_F(0x04f3f612) /* 0.309560845 */, 14 }, +/* 602 */ { MAD_F(0x04f6c666) /* 0.310247804 */, 14 }, +/* 603 */ { MAD_F(0x04f99721) /* 0.310935143 */, 14 }, +/* 604 */ { MAD_F(0x04fc6841) /* 0.311622862 */, 14 }, +/* 605 */ { MAD_F(0x04ff39c7) /* 0.312310961 */, 14 }, +/* 606 */ { MAD_F(0x05020bb3) /* 0.312999439 */, 14 }, +/* 607 */ { MAD_F(0x0504de05) /* 0.313688296 */, 14 }, + +/* 608 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 14 }, +/* 609 */ { MAD_F(0x050a83d8) /* 0.315067145 */, 14 }, +/* 610 */ { MAD_F(0x050d575b) /* 0.315757136 */, 14 }, +/* 611 */ { MAD_F(0x05102b42) /* 0.316447504 */, 14 }, +/* 612 */ { MAD_F(0x0512ff8e) /* 0.317138249 */, 14 }, +/* 613 */ { MAD_F(0x0515d440) /* 0.317829370 */, 14 }, +/* 614 */ { MAD_F(0x0518a956) /* 0.318520867 */, 14 }, +/* 615 */ { MAD_F(0x051b7ed1) /* 0.319212739 */, 14 }, +/* 616 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 14 }, +/* 617 */ { MAD_F(0x05212af5) /* 0.320597609 */, 14 }, +/* 618 */ { MAD_F(0x0524019e) /* 0.321290606 */, 14 }, +/* 619 */ { MAD_F(0x0526d8ab) /* 0.321983976 */, 14 }, +/* 620 */ { MAD_F(0x0529b01d) /* 0.322677720 */, 14 }, +/* 621 */ { MAD_F(0x052c87f2) /* 0.323371837 */, 14 }, +/* 622 */ { MAD_F(0x052f602c) /* 0.324066327 */, 14 }, +/* 623 */ { MAD_F(0x053238ca) /* 0.324761189 */, 14 }, + +/* 624 */ { MAD_F(0x053511cb) /* 0.325456423 */, 14 }, +/* 625 */ { MAD_F(0x0537eb30) /* 0.326152028 */, 14 }, +/* 626 */ { MAD_F(0x053ac4f9) /* 0.326848005 */, 14 }, +/* 627 */ { MAD_F(0x053d9f25) /* 0.327544352 */, 14 }, +/* 628 */ { MAD_F(0x054079b5) /* 0.328241070 */, 14 }, +/* 629 */ { MAD_F(0x054354a8) /* 0.328938157 */, 14 }, +/* 630 */ { MAD_F(0x05462ffe) /* 0.329635614 */, 14 }, +/* 631 */ { MAD_F(0x05490bb7) /* 0.330333440 */, 14 }, +/* 632 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 14 }, +/* 633 */ { MAD_F(0x054ec453) /* 0.331730198 */, 14 }, +/* 634 */ { MAD_F(0x0551a134) /* 0.332429129 */, 14 }, +/* 635 */ { MAD_F(0x05547e79) /* 0.333128427 */, 14 }, +/* 636 */ { MAD_F(0x05575c20) /* 0.333828093 */, 14 }, +/* 637 */ { MAD_F(0x055a3a2a) /* 0.334528126 */, 14 }, +/* 638 */ { MAD_F(0x055d1896) /* 0.335228525 */, 14 }, +/* 639 */ { MAD_F(0x055ff764) /* 0.335929290 */, 14 }, + +/* 640 */ { MAD_F(0x0562d694) /* 0.336630420 */, 14 }, +/* 641 */ { MAD_F(0x0565b627) /* 0.337331916 */, 14 }, +/* 642 */ { MAD_F(0x0568961b) /* 0.338033777 */, 14 }, +/* 643 */ { MAD_F(0x056b7671) /* 0.338736002 */, 14 }, +/* 644 */ { MAD_F(0x056e5729) /* 0.339438592 */, 14 }, +/* 645 */ { MAD_F(0x05713843) /* 0.340141545 */, 14 }, +/* 646 */ { MAD_F(0x057419be) /* 0.340844862 */, 14 }, +/* 647 */ { MAD_F(0x0576fb9a) /* 0.341548541 */, 14 }, +/* 648 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 14 }, +/* 649 */ { MAD_F(0x057cc077) /* 0.342956988 */, 14 }, +/* 650 */ { MAD_F(0x057fa378) /* 0.343661754 */, 14 }, +/* 651 */ { MAD_F(0x058286d9) /* 0.344366882 */, 14 }, +/* 652 */ { MAD_F(0x05856a9b) /* 0.345072371 */, 14 }, +/* 653 */ { MAD_F(0x05884ebe) /* 0.345778221 */, 14 }, +/* 654 */ { MAD_F(0x058b3342) /* 0.346484431 */, 14 }, +/* 655 */ { MAD_F(0x058e1827) /* 0.347191002 */, 14 }, + +/* 656 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 14 }, +/* 657 */ { MAD_F(0x0593e311) /* 0.348605221 */, 14 }, +/* 658 */ { MAD_F(0x0596c917) /* 0.349312869 */, 14 }, +/* 659 */ { MAD_F(0x0599af7d) /* 0.350020876 */, 14 }, +/* 660 */ { MAD_F(0x059c9643) /* 0.350729240 */, 14 }, +/* 661 */ { MAD_F(0x059f7d6a) /* 0.351437963 */, 14 }, +/* 662 */ { MAD_F(0x05a264f0) /* 0.352147044 */, 14 }, +/* 663 */ { MAD_F(0x05a54cd6) /* 0.352856481 */, 14 }, +/* 664 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 14 }, +/* 665 */ { MAD_F(0x05ab1dc2) /* 0.354276426 */, 14 }, +/* 666 */ { MAD_F(0x05ae06c7) /* 0.354986932 */, 14 }, +/* 667 */ { MAD_F(0x05b0f02b) /* 0.355697795 */, 14 }, +/* 668 */ { MAD_F(0x05b3d9f0) /* 0.356409012 */, 14 }, +/* 669 */ { MAD_F(0x05b6c413) /* 0.357120585 */, 14 }, +/* 670 */ { MAD_F(0x05b9ae95) /* 0.357832512 */, 14 }, +/* 671 */ { MAD_F(0x05bc9977) /* 0.358544794 */, 14 }, + +/* 672 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 14 }, +/* 673 */ { MAD_F(0x05c27057) /* 0.359970419 */, 14 }, +/* 674 */ { MAD_F(0x05c55c56) /* 0.360683761 */, 14 }, +/* 675 */ { MAD_F(0x05c848b3) /* 0.361397456 */, 14 }, +/* 676 */ { MAD_F(0x05cb356e) /* 0.362111504 */, 14 }, +/* 677 */ { MAD_F(0x05ce2289) /* 0.362825904 */, 14 }, +/* 678 */ { MAD_F(0x05d11001) /* 0.363540655 */, 14 }, +/* 679 */ { MAD_F(0x05d3fdd8) /* 0.364255759 */, 14 }, +/* 680 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 14 }, +/* 681 */ { MAD_F(0x05d9daa1) /* 0.365687018 */, 14 }, +/* 682 */ { MAD_F(0x05dcc993) /* 0.366403174 */, 14 }, +/* 683 */ { MAD_F(0x05dfb8e2) /* 0.367119680 */, 14 }, +/* 684 */ { MAD_F(0x05e2a890) /* 0.367836535 */, 14 }, +/* 685 */ { MAD_F(0x05e5989b) /* 0.368553740 */, 14 }, +/* 686 */ { MAD_F(0x05e88904) /* 0.369271294 */, 14 }, +/* 687 */ { MAD_F(0x05eb79cb) /* 0.369989197 */, 14 }, + +/* 688 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 14 }, +/* 689 */ { MAD_F(0x05f15c70) /* 0.371426047 */, 14 }, +/* 690 */ { MAD_F(0x05f44e4f) /* 0.372144994 */, 14 }, +/* 691 */ { MAD_F(0x05f7408b) /* 0.372864289 */, 14 }, +/* 692 */ { MAD_F(0x05fa3324) /* 0.373583930 */, 14 }, +/* 693 */ { MAD_F(0x05fd261b) /* 0.374303918 */, 14 }, +/* 694 */ { MAD_F(0x0600196e) /* 0.375024253 */, 14 }, +/* 695 */ { MAD_F(0x06030d1e) /* 0.375744934 */, 14 }, +/* 696 */ { MAD_F(0x0606012b) /* 0.376465960 */, 14 }, +/* 697 */ { MAD_F(0x0608f595) /* 0.377187332 */, 14 }, +/* 698 */ { MAD_F(0x060bea5c) /* 0.377909049 */, 14 }, +/* 699 */ { MAD_F(0x060edf7f) /* 0.378631110 */, 14 }, +/* 700 */ { MAD_F(0x0611d4fe) /* 0.379353516 */, 14 }, +/* 701 */ { MAD_F(0x0614cada) /* 0.380076266 */, 14 }, +/* 702 */ { MAD_F(0x0617c112) /* 0.380799360 */, 14 }, +/* 703 */ { MAD_F(0x061ab7a6) /* 0.381522798 */, 14 }, + +/* 704 */ { MAD_F(0x061dae96) /* 0.382246578 */, 14 }, +/* 705 */ { MAD_F(0x0620a5e3) /* 0.382970701 */, 14 }, +/* 706 */ { MAD_F(0x06239d8b) /* 0.383695167 */, 14 }, +/* 707 */ { MAD_F(0x0626958f) /* 0.384419975 */, 14 }, +/* 708 */ { MAD_F(0x06298def) /* 0.385145124 */, 14 }, +/* 709 */ { MAD_F(0x062c86aa) /* 0.385870615 */, 14 }, +/* 710 */ { MAD_F(0x062f7fc1) /* 0.386596448 */, 14 }, +/* 711 */ { MAD_F(0x06327934) /* 0.387322621 */, 14 }, +/* 712 */ { MAD_F(0x06357302) /* 0.388049134 */, 14 }, +/* 713 */ { MAD_F(0x06386d2b) /* 0.388775988 */, 14 }, +/* 714 */ { MAD_F(0x063b67b0) /* 0.389503182 */, 14 }, +/* 715 */ { MAD_F(0x063e6290) /* 0.390230715 */, 14 }, +/* 716 */ { MAD_F(0x06415dcb) /* 0.390958588 */, 14 }, +/* 717 */ { MAD_F(0x06445960) /* 0.391686799 */, 14 }, +/* 718 */ { MAD_F(0x06475551) /* 0.392415349 */, 14 }, +/* 719 */ { MAD_F(0x064a519c) /* 0.393144238 */, 14 }, + +/* 720 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 14 }, +/* 721 */ { MAD_F(0x06504b44) /* 0.394603028 */, 14 }, +/* 722 */ { MAD_F(0x0653489f) /* 0.395332930 */, 14 }, +/* 723 */ { MAD_F(0x06564655) /* 0.396063168 */, 14 }, +/* 724 */ { MAD_F(0x06594465) /* 0.396793743 */, 14 }, +/* 725 */ { MAD_F(0x065c42d0) /* 0.397524655 */, 14 }, +/* 726 */ { MAD_F(0x065f4195) /* 0.398255903 */, 14 }, +/* 727 */ { MAD_F(0x066240b4) /* 0.398987487 */, 14 }, +/* 728 */ { MAD_F(0x0665402d) /* 0.399719406 */, 14 }, +/* 729 */ { MAD_F(0x06684000) /* 0.400451660 */, 14 }, +/* 730 */ { MAD_F(0x066b402d) /* 0.401184249 */, 14 }, +/* 731 */ { MAD_F(0x066e40b3) /* 0.401917173 */, 14 }, +/* 732 */ { MAD_F(0x06714194) /* 0.402650431 */, 14 }, +/* 733 */ { MAD_F(0x067442ce) /* 0.403384024 */, 14 }, +/* 734 */ { MAD_F(0x06774462) /* 0.404117949 */, 14 }, +/* 735 */ { MAD_F(0x067a464f) /* 0.404852209 */, 14 }, + +/* 736 */ { MAD_F(0x067d4896) /* 0.405586801 */, 14 }, +/* 737 */ { MAD_F(0x06804b36) /* 0.406321726 */, 14 }, +/* 738 */ { MAD_F(0x06834e2f) /* 0.407056983 */, 14 }, +/* 739 */ { MAD_F(0x06865181) /* 0.407792573 */, 14 }, +/* 740 */ { MAD_F(0x0689552c) /* 0.408528495 */, 14 }, +/* 741 */ { MAD_F(0x068c5931) /* 0.409264748 */, 14 }, +/* 742 */ { MAD_F(0x068f5d8e) /* 0.410001332 */, 14 }, +/* 743 */ { MAD_F(0x06926245) /* 0.410738247 */, 14 }, +/* 744 */ { MAD_F(0x06956753) /* 0.411475493 */, 14 }, +/* 745 */ { MAD_F(0x06986cbb) /* 0.412213070 */, 14 }, +/* 746 */ { MAD_F(0x069b727b) /* 0.412950976 */, 14 }, +/* 747 */ { MAD_F(0x069e7894) /* 0.413689213 */, 14 }, +/* 748 */ { MAD_F(0x06a17f05) /* 0.414427779 */, 14 }, +/* 749 */ { MAD_F(0x06a485cf) /* 0.415166674 */, 14 }, +/* 750 */ { MAD_F(0x06a78cf1) /* 0.415905897 */, 14 }, +/* 751 */ { MAD_F(0x06aa946b) /* 0.416645450 */, 14 }, + +/* 752 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 14 }, +/* 753 */ { MAD_F(0x06b0a468) /* 0.418125540 */, 14 }, +/* 754 */ { MAD_F(0x06b3acea) /* 0.418866076 */, 14 }, +/* 755 */ { MAD_F(0x06b6b5c4) /* 0.419606940 */, 14 }, +/* 756 */ { MAD_F(0x06b9bef6) /* 0.420348132 */, 14 }, +/* 757 */ { MAD_F(0x06bcc880) /* 0.421089650 */, 14 }, +/* 758 */ { MAD_F(0x06bfd261) /* 0.421831494 */, 14 }, +/* 759 */ { MAD_F(0x06c2dc9a) /* 0.422573665 */, 14 }, +/* 760 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 14 }, +/* 761 */ { MAD_F(0x06c8f213) /* 0.424058985 */, 14 }, +/* 762 */ { MAD_F(0x06cbfd52) /* 0.424802133 */, 14 }, +/* 763 */ { MAD_F(0x06cf08e9) /* 0.425545607 */, 14 }, +/* 764 */ { MAD_F(0x06d214d7) /* 0.426289405 */, 14 }, +/* 765 */ { MAD_F(0x06d5211c) /* 0.427033528 */, 14 }, +/* 766 */ { MAD_F(0x06d82db8) /* 0.427777975 */, 14 }, +/* 767 */ { MAD_F(0x06db3aaa) /* 0.428522746 */, 14 }, + +/* 768 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 14 }, +/* 769 */ { MAD_F(0x06e15595) /* 0.430013259 */, 14 }, +/* 770 */ { MAD_F(0x06e4638d) /* 0.430759001 */, 14 }, +/* 771 */ { MAD_F(0x06e771db) /* 0.431505065 */, 14 }, +/* 772 */ { MAD_F(0x06ea807f) /* 0.432251452 */, 14 }, +/* 773 */ { MAD_F(0x06ed8f7b) /* 0.432998162 */, 14 }, +/* 774 */ { MAD_F(0x06f09ecc) /* 0.433745193 */, 14 }, +/* 775 */ { MAD_F(0x06f3ae75) /* 0.434492546 */, 14 }, +/* 776 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 14 }, +/* 777 */ { MAD_F(0x06f9cec8) /* 0.435988217 */, 14 }, +/* 778 */ { MAD_F(0x06fcdf72) /* 0.436736534 */, 14 }, +/* 779 */ { MAD_F(0x06fff073) /* 0.437485172 */, 14 }, +/* 780 */ { MAD_F(0x070301ca) /* 0.438234130 */, 14 }, +/* 781 */ { MAD_F(0x07061377) /* 0.438983408 */, 14 }, +/* 782 */ { MAD_F(0x0709257a) /* 0.439733006 */, 14 }, +/* 783 */ { MAD_F(0x070c37d2) /* 0.440482924 */, 14 }, + +/* 784 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 14 }, +/* 785 */ { MAD_F(0x07125d84) /* 0.441983717 */, 14 }, +/* 786 */ { MAD_F(0x071570de) /* 0.442734592 */, 14 }, +/* 787 */ { MAD_F(0x0718848d) /* 0.443485785 */, 14 }, +/* 788 */ { MAD_F(0x071b9891) /* 0.444237296 */, 14 }, +/* 789 */ { MAD_F(0x071eaceb) /* 0.444989126 */, 14 }, +/* 790 */ { MAD_F(0x0721c19a) /* 0.445741273 */, 14 }, +/* 791 */ { MAD_F(0x0724d69e) /* 0.446493738 */, 14 }, +/* 792 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 14 }, +/* 793 */ { MAD_F(0x072b01a6) /* 0.447999618 */, 14 }, +/* 794 */ { MAD_F(0x072e17a9) /* 0.448753033 */, 14 }, +/* 795 */ { MAD_F(0x07312e01) /* 0.449506765 */, 14 }, +/* 796 */ { MAD_F(0x073444ae) /* 0.450260813 */, 14 }, +/* 797 */ { MAD_F(0x07375bb0) /* 0.451015176 */, 14 }, +/* 798 */ { MAD_F(0x073a7307) /* 0.451769856 */, 14 }, +/* 799 */ { MAD_F(0x073d8ab2) /* 0.452524850 */, 14 }, + +/* 800 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 14 }, +/* 801 */ { MAD_F(0x0743bb06) /* 0.454035784 */, 14 }, +/* 802 */ { MAD_F(0x0746d3af) /* 0.454791723 */, 14 }, +/* 803 */ { MAD_F(0x0749ecac) /* 0.455547976 */, 14 }, +/* 804 */ { MAD_F(0x074d05fe) /* 0.456304543 */, 14 }, +/* 805 */ { MAD_F(0x07501fa3) /* 0.457061423 */, 14 }, +/* 806 */ { MAD_F(0x0753399d) /* 0.457818618 */, 14 }, +/* 807 */ { MAD_F(0x075653eb) /* 0.458576125 */, 14 }, +/* 808 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 14 }, +/* 809 */ { MAD_F(0x075c8983) /* 0.460092079 */, 14 }, +/* 810 */ { MAD_F(0x075fa4cc) /* 0.460850524 */, 14 }, +/* 811 */ { MAD_F(0x0762c06a) /* 0.461609282 */, 14 }, +/* 812 */ { MAD_F(0x0765dc5b) /* 0.462368352 */, 14 }, +/* 813 */ { MAD_F(0x0768f8a0) /* 0.463127733 */, 14 }, +/* 814 */ { MAD_F(0x076c1538) /* 0.463887426 */, 14 }, +/* 815 */ { MAD_F(0x076f3224) /* 0.464647430 */, 14 }, + +/* 816 */ { MAD_F(0x07724f64) /* 0.465407744 */, 14 }, +/* 817 */ { MAD_F(0x07756cf7) /* 0.466168370 */, 14 }, +/* 818 */ { MAD_F(0x07788add) /* 0.466929306 */, 14 }, +/* 819 */ { MAD_F(0x077ba916) /* 0.467690552 */, 14 }, +/* 820 */ { MAD_F(0x077ec7a3) /* 0.468452108 */, 14 }, +/* 821 */ { MAD_F(0x0781e683) /* 0.469213973 */, 14 }, +/* 822 */ { MAD_F(0x078505b5) /* 0.469976148 */, 14 }, +/* 823 */ { MAD_F(0x0788253b) /* 0.470738632 */, 14 }, +/* 824 */ { MAD_F(0x078b4514) /* 0.471501425 */, 14 }, +/* 825 */ { MAD_F(0x078e653f) /* 0.472264527 */, 14 }, +/* 826 */ { MAD_F(0x079185be) /* 0.473027937 */, 14 }, +/* 827 */ { MAD_F(0x0794a68f) /* 0.473791655 */, 14 }, +/* 828 */ { MAD_F(0x0797c7b2) /* 0.474555681 */, 14 }, +/* 829 */ { MAD_F(0x079ae929) /* 0.475320014 */, 14 }, +/* 830 */ { MAD_F(0x079e0af1) /* 0.476084655 */, 14 }, +/* 831 */ { MAD_F(0x07a12d0c) /* 0.476849603 */, 14 }, + +/* 832 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 14 }, +/* 833 */ { MAD_F(0x07a7723a) /* 0.478380420 */, 14 }, +/* 834 */ { MAD_F(0x07aa954c) /* 0.479146288 */, 14 }, +/* 835 */ { MAD_F(0x07adb8b0) /* 0.479912463 */, 14 }, +/* 836 */ { MAD_F(0x07b0dc67) /* 0.480678943 */, 14 }, +/* 837 */ { MAD_F(0x07b4006f) /* 0.481445729 */, 14 }, +/* 838 */ { MAD_F(0x07b724ca) /* 0.482212820 */, 14 }, +/* 839 */ { MAD_F(0x07ba4976) /* 0.482980216 */, 14 }, +/* 840 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 14 }, +/* 841 */ { MAD_F(0x07c093c5) /* 0.484515924 */, 14 }, +/* 842 */ { MAD_F(0x07c3b967) /* 0.485284235 */, 14 }, +/* 843 */ { MAD_F(0x07c6df5a) /* 0.486052849 */, 14 }, +/* 844 */ { MAD_F(0x07ca059f) /* 0.486821768 */, 14 }, +/* 845 */ { MAD_F(0x07cd2c36) /* 0.487590991 */, 14 }, +/* 846 */ { MAD_F(0x07d0531e) /* 0.488360517 */, 14 }, +/* 847 */ { MAD_F(0x07d37a57) /* 0.489130346 */, 14 }, + +/* 848 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 14 }, +/* 849 */ { MAD_F(0x07d9c9be) /* 0.490670914 */, 14 }, +/* 850 */ { MAD_F(0x07dcf1ec) /* 0.491441651 */, 14 }, +/* 851 */ { MAD_F(0x07e01a6a) /* 0.492212691 */, 14 }, +/* 852 */ { MAD_F(0x07e3433a) /* 0.492984033 */, 14 }, +/* 853 */ { MAD_F(0x07e66c5a) /* 0.493755677 */, 14 }, +/* 854 */ { MAD_F(0x07e995cc) /* 0.494527623 */, 14 }, +/* 855 */ { MAD_F(0x07ecbf8e) /* 0.495299870 */, 14 }, +/* 856 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 14 }, +/* 857 */ { MAD_F(0x07f31405) /* 0.496845266 */, 14 }, +/* 858 */ { MAD_F(0x07f63eba) /* 0.497618416 */, 14 }, +/* 859 */ { MAD_F(0x07f969c0) /* 0.498391866 */, 14 }, +/* 860 */ { MAD_F(0x07fc9516) /* 0.499165616 */, 14 }, +/* 861 */ { MAD_F(0x07ffc0bc) /* 0.499939666 */, 14 }, +/* 862 */ { MAD_F(0x04017659) /* 0.250357008 */, 15 }, +/* 863 */ { MAD_F(0x04030c7d) /* 0.250744333 */, 15 }, + +/* 864 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 15 }, +/* 865 */ { MAD_F(0x0406393d) /* 0.251519431 */, 15 }, +/* 866 */ { MAD_F(0x0407cfd9) /* 0.251907204 */, 15 }, +/* 867 */ { MAD_F(0x0409669d) /* 0.252295127 */, 15 }, +/* 868 */ { MAD_F(0x040afd89) /* 0.252683198 */, 15 }, +/* 869 */ { MAD_F(0x040c949e) /* 0.253071419 */, 15 }, +/* 870 */ { MAD_F(0x040e2bda) /* 0.253459789 */, 15 }, +/* 871 */ { MAD_F(0x040fc33e) /* 0.253848307 */, 15 }, +/* 872 */ { MAD_F(0x04115aca) /* 0.254236974 */, 15 }, +/* 873 */ { MAD_F(0x0412f27e) /* 0.254625790 */, 15 }, +/* 874 */ { MAD_F(0x04148a5a) /* 0.255014755 */, 15 }, +/* 875 */ { MAD_F(0x0416225d) /* 0.255403867 */, 15 }, +/* 876 */ { MAD_F(0x0417ba89) /* 0.255793128 */, 15 }, +/* 877 */ { MAD_F(0x041952dc) /* 0.256182537 */, 15 }, +/* 878 */ { MAD_F(0x041aeb57) /* 0.256572095 */, 15 }, +/* 879 */ { MAD_F(0x041c83fa) /* 0.256961800 */, 15 }, + +/* 880 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 15 }, +/* 881 */ { MAD_F(0x041fb5b6) /* 0.257741653 */, 15 }, +/* 882 */ { MAD_F(0x04214ed0) /* 0.258131801 */, 15 }, +/* 883 */ { MAD_F(0x0422e811) /* 0.258522097 */, 15 }, +/* 884 */ { MAD_F(0x04248179) /* 0.258912540 */, 15 }, +/* 885 */ { MAD_F(0x04261b0a) /* 0.259303130 */, 15 }, +/* 886 */ { MAD_F(0x0427b4c2) /* 0.259693868 */, 15 }, +/* 887 */ { MAD_F(0x04294ea1) /* 0.260084752 */, 15 }, +/* 888 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 15 }, +/* 889 */ { MAD_F(0x042c82d6) /* 0.260866961 */, 15 }, +/* 890 */ { MAD_F(0x042e1d2b) /* 0.261258286 */, 15 }, +/* 891 */ { MAD_F(0x042fb7a8) /* 0.261649758 */, 15 }, +/* 892 */ { MAD_F(0x0431524c) /* 0.262041376 */, 15 }, +/* 893 */ { MAD_F(0x0432ed17) /* 0.262433140 */, 15 }, +/* 894 */ { MAD_F(0x0434880a) /* 0.262825051 */, 15 }, +/* 895 */ { MAD_F(0x04362324) /* 0.263217107 */, 15 }, + +/* 896 */ { MAD_F(0x0437be65) /* 0.263609310 */, 15 }, +/* 897 */ { MAD_F(0x043959cd) /* 0.264001659 */, 15 }, +/* 898 */ { MAD_F(0x043af55d) /* 0.264394153 */, 15 }, +/* 899 */ { MAD_F(0x043c9113) /* 0.264786794 */, 15 }, +/* 900 */ { MAD_F(0x043e2cf1) /* 0.265179580 */, 15 }, +/* 901 */ { MAD_F(0x043fc8f6) /* 0.265572511 */, 15 }, +/* 902 */ { MAD_F(0x04416522) /* 0.265965588 */, 15 }, +/* 903 */ { MAD_F(0x04430174) /* 0.266358810 */, 15 }, +/* 904 */ { MAD_F(0x04449dee) /* 0.266752177 */, 15 }, +/* 905 */ { MAD_F(0x04463a8f) /* 0.267145689 */, 15 }, +/* 906 */ { MAD_F(0x0447d756) /* 0.267539347 */, 15 }, +/* 907 */ { MAD_F(0x04497445) /* 0.267933149 */, 15 }, +/* 908 */ { MAD_F(0x044b115a) /* 0.268327096 */, 15 }, +/* 909 */ { MAD_F(0x044cae96) /* 0.268721187 */, 15 }, +/* 910 */ { MAD_F(0x044e4bf9) /* 0.269115423 */, 15 }, +/* 911 */ { MAD_F(0x044fe983) /* 0.269509804 */, 15 }, + +/* 912 */ { MAD_F(0x04518733) /* 0.269904329 */, 15 }, +/* 913 */ { MAD_F(0x0453250a) /* 0.270298998 */, 15 }, +/* 914 */ { MAD_F(0x0454c308) /* 0.270693811 */, 15 }, +/* 915 */ { MAD_F(0x0456612d) /* 0.271088768 */, 15 }, +/* 916 */ { MAD_F(0x0457ff78) /* 0.271483869 */, 15 }, +/* 917 */ { MAD_F(0x04599dea) /* 0.271879114 */, 15 }, +/* 918 */ { MAD_F(0x045b3c82) /* 0.272274503 */, 15 }, +/* 919 */ { MAD_F(0x045cdb41) /* 0.272670035 */, 15 }, +/* 920 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 15 }, +/* 921 */ { MAD_F(0x04601932) /* 0.273461530 */, 15 }, +/* 922 */ { MAD_F(0x0461b864) /* 0.273857492 */, 15 }, +/* 923 */ { MAD_F(0x046357bd) /* 0.274253597 */, 15 }, +/* 924 */ { MAD_F(0x0464f73c) /* 0.274649846 */, 15 }, +/* 925 */ { MAD_F(0x046696e2) /* 0.275046238 */, 15 }, +/* 926 */ { MAD_F(0x046836ae) /* 0.275442772 */, 15 }, +/* 927 */ { MAD_F(0x0469d6a0) /* 0.275839449 */, 15 }, + +/* 928 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 15 }, +/* 929 */ { MAD_F(0x046d16f7) /* 0.276633232 */, 15 }, +/* 930 */ { MAD_F(0x046eb75c) /* 0.277030337 */, 15 }, +/* 931 */ { MAD_F(0x047057e8) /* 0.277427584 */, 15 }, +/* 932 */ { MAD_F(0x0471f899) /* 0.277824973 */, 15 }, +/* 933 */ { MAD_F(0x04739971) /* 0.278222505 */, 15 }, +/* 934 */ { MAD_F(0x04753a6f) /* 0.278620179 */, 15 }, +/* 935 */ { MAD_F(0x0476db92) /* 0.279017995 */, 15 }, +/* 936 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 15 }, +/* 937 */ { MAD_F(0x047a1e4c) /* 0.279814051 */, 15 }, +/* 938 */ { MAD_F(0x047bbfe2) /* 0.280212292 */, 15 }, +/* 939 */ { MAD_F(0x047d619e) /* 0.280610675 */, 15 }, +/* 940 */ { MAD_F(0x047f0380) /* 0.281009199 */, 15 }, +/* 941 */ { MAD_F(0x0480a588) /* 0.281407864 */, 15 }, +/* 942 */ { MAD_F(0x048247b6) /* 0.281806670 */, 15 }, +/* 943 */ { MAD_F(0x0483ea0a) /* 0.282205618 */, 15 }, + +/* 944 */ { MAD_F(0x04858c83) /* 0.282604707 */, 15 }, +/* 945 */ { MAD_F(0x04872f22) /* 0.283003936 */, 15 }, +/* 946 */ { MAD_F(0x0488d1e8) /* 0.283403307 */, 15 }, +/* 947 */ { MAD_F(0x048a74d3) /* 0.283802818 */, 15 }, +/* 948 */ { MAD_F(0x048c17e3) /* 0.284202470 */, 15 }, +/* 949 */ { MAD_F(0x048dbb1a) /* 0.284602263 */, 15 }, +/* 950 */ { MAD_F(0x048f5e76) /* 0.285002195 */, 15 }, +/* 951 */ { MAD_F(0x049101f8) /* 0.285402269 */, 15 }, +/* 952 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 15 }, +/* 953 */ { MAD_F(0x0494496c) /* 0.286202836 */, 15 }, +/* 954 */ { MAD_F(0x0495ed5f) /* 0.286603329 */, 15 }, +/* 955 */ { MAD_F(0x04979177) /* 0.287003963 */, 15 }, +/* 956 */ { MAD_F(0x049935b5) /* 0.287404737 */, 15 }, +/* 957 */ { MAD_F(0x049ada19) /* 0.287805650 */, 15 }, +/* 958 */ { MAD_F(0x049c7ea1) /* 0.288206703 */, 15 }, +/* 959 */ { MAD_F(0x049e2350) /* 0.288607895 */, 15 }, + +/* 960 */ { MAD_F(0x049fc824) /* 0.289009227 */, 15 }, +/* 961 */ { MAD_F(0x04a16d1d) /* 0.289410699 */, 15 }, +/* 962 */ { MAD_F(0x04a3123b) /* 0.289812309 */, 15 }, +/* 963 */ { MAD_F(0x04a4b77f) /* 0.290214059 */, 15 }, +/* 964 */ { MAD_F(0x04a65ce8) /* 0.290615948 */, 15 }, +/* 965 */ { MAD_F(0x04a80277) /* 0.291017976 */, 15 }, +/* 966 */ { MAD_F(0x04a9a82b) /* 0.291420143 */, 15 }, +/* 967 */ { MAD_F(0x04ab4e04) /* 0.291822449 */, 15 }, +/* 968 */ { MAD_F(0x04acf402) /* 0.292224893 */, 15 }, +/* 969 */ { MAD_F(0x04ae9a26) /* 0.292627476 */, 15 }, +/* 970 */ { MAD_F(0x04b0406e) /* 0.293030197 */, 15 }, +/* 971 */ { MAD_F(0x04b1e6dc) /* 0.293433057 */, 15 }, +/* 972 */ { MAD_F(0x04b38d6f) /* 0.293836055 */, 15 }, +/* 973 */ { MAD_F(0x04b53427) /* 0.294239192 */, 15 }, +/* 974 */ { MAD_F(0x04b6db05) /* 0.294642466 */, 15 }, +/* 975 */ { MAD_F(0x04b88207) /* 0.295045879 */, 15 }, + +/* 976 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 15 }, +/* 977 */ { MAD_F(0x04bbd07a) /* 0.295853118 */, 15 }, +/* 978 */ { MAD_F(0x04bd77ec) /* 0.296256944 */, 15 }, +/* 979 */ { MAD_F(0x04bf1f82) /* 0.296660907 */, 15 }, +/* 980 */ { MAD_F(0x04c0c73d) /* 0.297065009 */, 15 }, +/* 981 */ { MAD_F(0x04c26f1d) /* 0.297469248 */, 15 }, +/* 982 */ { MAD_F(0x04c41722) /* 0.297873624 */, 15 }, +/* 983 */ { MAD_F(0x04c5bf4c) /* 0.298278137 */, 15 }, +/* 984 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 15 }, +/* 985 */ { MAD_F(0x04c9100d) /* 0.299087576 */, 15 }, +/* 986 */ { MAD_F(0x04cab8a6) /* 0.299492500 */, 15 }, +/* 987 */ { MAD_F(0x04cc6163) /* 0.299897562 */, 15 }, +/* 988 */ { MAD_F(0x04ce0a44) /* 0.300302761 */, 15 }, +/* 989 */ { MAD_F(0x04cfb34b) /* 0.300708096 */, 15 }, +/* 990 */ { MAD_F(0x04d15c76) /* 0.301113568 */, 15 }, +/* 991 */ { MAD_F(0x04d305c5) /* 0.301519176 */, 15 }, + +/* 992 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 15 }, +/* 993 */ { MAD_F(0x04d658d2) /* 0.302330802 */, 15 }, +/* 994 */ { MAD_F(0x04d80290) /* 0.302736820 */, 15 }, +/* 995 */ { MAD_F(0x04d9ac72) /* 0.303142973 */, 15 }, +/* 996 */ { MAD_F(0x04db5679) /* 0.303549263 */, 15 }, +/* 997 */ { MAD_F(0x04dd00a4) /* 0.303955689 */, 15 }, +/* 998 */ { MAD_F(0x04deaaf3) /* 0.304362251 */, 15 }, +/* 999 */ { MAD_F(0x04e05567) /* 0.304768948 */, 15 }, +/* 1000 */ { MAD_F(0x04e20000) /* 0.305175781 */, 15 }, +/* 1001 */ { MAD_F(0x04e3aabd) /* 0.305582750 */, 15 }, +/* 1002 */ { MAD_F(0x04e5559e) /* 0.305989854 */, 15 }, +/* 1003 */ { MAD_F(0x04e700a3) /* 0.306397094 */, 15 }, +/* 1004 */ { MAD_F(0x04e8abcd) /* 0.306804470 */, 15 }, +/* 1005 */ { MAD_F(0x04ea571c) /* 0.307211980 */, 15 }, +/* 1006 */ { MAD_F(0x04ec028e) /* 0.307619626 */, 15 }, +/* 1007 */ { MAD_F(0x04edae25) /* 0.308027406 */, 15 }, + +/* 1008 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 15 }, +/* 1009 */ { MAD_F(0x04f105bf) /* 0.308843373 */, 15 }, +/* 1010 */ { MAD_F(0x04f2b1c3) /* 0.309251558 */, 15 }, +/* 1011 */ { MAD_F(0x04f45dea) /* 0.309659879 */, 15 }, +/* 1012 */ { MAD_F(0x04f60a36) /* 0.310068333 */, 15 }, +/* 1013 */ { MAD_F(0x04f7b6a6) /* 0.310476923 */, 15 }, +/* 1014 */ { MAD_F(0x04f9633a) /* 0.310885647 */, 15 }, +/* 1015 */ { MAD_F(0x04fb0ff2) /* 0.311294505 */, 15 }, +/* 1016 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 15 }, +/* 1017 */ { MAD_F(0x04fe69ce) /* 0.312112625 */, 15 }, +/* 1018 */ { MAD_F(0x050016f3) /* 0.312521885 */, 15 }, +/* 1019 */ { MAD_F(0x0501c43b) /* 0.312931280 */, 15 }, +/* 1020 */ { MAD_F(0x050371a7) /* 0.313340809 */, 15 }, +/* 1021 */ { MAD_F(0x05051f37) /* 0.313750472 */, 15 }, +/* 1022 */ { MAD_F(0x0506cceb) /* 0.314160269 */, 15 }, +/* 1023 */ { MAD_F(0x05087ac2) /* 0.314570199 */, 15 }, + +/* 1024 */ { MAD_F(0x050a28be) /* 0.314980262 */, 15 }, +/* 1025 */ { MAD_F(0x050bd6de) /* 0.315390460 */, 15 }, +/* 1026 */ { MAD_F(0x050d8521) /* 0.315800790 */, 15 }, +/* 1027 */ { MAD_F(0x050f3388) /* 0.316211255 */, 15 }, +/* 1028 */ { MAD_F(0x0510e213) /* 0.316621852 */, 15 }, +/* 1029 */ { MAD_F(0x051290c2) /* 0.317032582 */, 15 }, +/* 1030 */ { MAD_F(0x05143f94) /* 0.317443446 */, 15 }, +/* 1031 */ { MAD_F(0x0515ee8a) /* 0.317854442 */, 15 }, +/* 1032 */ { MAD_F(0x05179da4) /* 0.318265572 */, 15 }, +/* 1033 */ { MAD_F(0x05194ce1) /* 0.318676834 */, 15 }, +/* 1034 */ { MAD_F(0x051afc42) /* 0.319088229 */, 15 }, +/* 1035 */ { MAD_F(0x051cabc7) /* 0.319499756 */, 15 }, +/* 1036 */ { MAD_F(0x051e5b6f) /* 0.319911417 */, 15 }, +/* 1037 */ { MAD_F(0x05200b3a) /* 0.320323209 */, 15 }, +/* 1038 */ { MAD_F(0x0521bb2a) /* 0.320735134 */, 15 }, +/* 1039 */ { MAD_F(0x05236b3d) /* 0.321147192 */, 15 }, + +/* 1040 */ { MAD_F(0x05251b73) /* 0.321559381 */, 15 }, +/* 1041 */ { MAD_F(0x0526cbcd) /* 0.321971703 */, 15 }, +/* 1042 */ { MAD_F(0x05287c4a) /* 0.322384156 */, 15 }, +/* 1043 */ { MAD_F(0x052a2cea) /* 0.322796742 */, 15 }, +/* 1044 */ { MAD_F(0x052bddae) /* 0.323209460 */, 15 }, +/* 1045 */ { MAD_F(0x052d8e96) /* 0.323622309 */, 15 }, +/* 1046 */ { MAD_F(0x052f3fa1) /* 0.324035290 */, 15 }, +/* 1047 */ { MAD_F(0x0530f0cf) /* 0.324448403 */, 15 }, +/* 1048 */ { MAD_F(0x0532a220) /* 0.324861647 */, 15 }, +/* 1049 */ { MAD_F(0x05345395) /* 0.325275023 */, 15 }, +/* 1050 */ { MAD_F(0x0536052d) /* 0.325688530 */, 15 }, +/* 1051 */ { MAD_F(0x0537b6e8) /* 0.326102168 */, 15 }, +/* 1052 */ { MAD_F(0x053968c6) /* 0.326515938 */, 15 }, +/* 1053 */ { MAD_F(0x053b1ac8) /* 0.326929839 */, 15 }, +/* 1054 */ { MAD_F(0x053ccced) /* 0.327343870 */, 15 }, +/* 1055 */ { MAD_F(0x053e7f35) /* 0.327758033 */, 15 }, + +/* 1056 */ { MAD_F(0x054031a0) /* 0.328172327 */, 15 }, +/* 1057 */ { MAD_F(0x0541e42e) /* 0.328586751 */, 15 }, +/* 1058 */ { MAD_F(0x054396df) /* 0.329001306 */, 15 }, +/* 1059 */ { MAD_F(0x054549b4) /* 0.329415992 */, 15 }, +/* 1060 */ { MAD_F(0x0546fcab) /* 0.329830808 */, 15 }, +/* 1061 */ { MAD_F(0x0548afc6) /* 0.330245755 */, 15 }, +/* 1062 */ { MAD_F(0x054a6303) /* 0.330660832 */, 15 }, +/* 1063 */ { MAD_F(0x054c1663) /* 0.331076039 */, 15 }, +/* 1064 */ { MAD_F(0x054dc9e7) /* 0.331491377 */, 15 }, +/* 1065 */ { MAD_F(0x054f7d8d) /* 0.331906845 */, 15 }, +/* 1066 */ { MAD_F(0x05513156) /* 0.332322443 */, 15 }, +/* 1067 */ { MAD_F(0x0552e542) /* 0.332738170 */, 15 }, +/* 1068 */ { MAD_F(0x05549951) /* 0.333154028 */, 15 }, +/* 1069 */ { MAD_F(0x05564d83) /* 0.333570016 */, 15 }, +/* 1070 */ { MAD_F(0x055801d8) /* 0.333986133 */, 15 }, +/* 1071 */ { MAD_F(0x0559b64f) /* 0.334402380 */, 15 }, + +/* 1072 */ { MAD_F(0x055b6ae9) /* 0.334818756 */, 15 }, +/* 1073 */ { MAD_F(0x055d1fa6) /* 0.335235262 */, 15 }, +/* 1074 */ { MAD_F(0x055ed486) /* 0.335651898 */, 15 }, +/* 1075 */ { MAD_F(0x05608988) /* 0.336068662 */, 15 }, +/* 1076 */ { MAD_F(0x05623ead) /* 0.336485556 */, 15 }, +/* 1077 */ { MAD_F(0x0563f3f5) /* 0.336902579 */, 15 }, +/* 1078 */ { MAD_F(0x0565a960) /* 0.337319732 */, 15 }, +/* 1079 */ { MAD_F(0x05675eed) /* 0.337737013 */, 15 }, +/* 1080 */ { MAD_F(0x0569149c) /* 0.338154423 */, 15 }, +/* 1081 */ { MAD_F(0x056aca6f) /* 0.338571962 */, 15 }, +/* 1082 */ { MAD_F(0x056c8064) /* 0.338989630 */, 15 }, +/* 1083 */ { MAD_F(0x056e367b) /* 0.339407426 */, 15 }, +/* 1084 */ { MAD_F(0x056fecb5) /* 0.339825351 */, 15 }, +/* 1085 */ { MAD_F(0x0571a311) /* 0.340243405 */, 15 }, +/* 1086 */ { MAD_F(0x05735990) /* 0.340661587 */, 15 }, +/* 1087 */ { MAD_F(0x05751032) /* 0.341079898 */, 15 }, + +/* 1088 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 15 }, +/* 1089 */ { MAD_F(0x05787ddc) /* 0.341916903 */, 15 }, +/* 1090 */ { MAD_F(0x057a34e4) /* 0.342335598 */, 15 }, +/* 1091 */ { MAD_F(0x057bec0f) /* 0.342754421 */, 15 }, +/* 1092 */ { MAD_F(0x057da35d) /* 0.343173373 */, 15 }, +/* 1093 */ { MAD_F(0x057f5acc) /* 0.343592452 */, 15 }, +/* 1094 */ { MAD_F(0x0581125e) /* 0.344011659 */, 15 }, +/* 1095 */ { MAD_F(0x0582ca12) /* 0.344430993 */, 15 }, +/* 1096 */ { MAD_F(0x058481e9) /* 0.344850455 */, 15 }, +/* 1097 */ { MAD_F(0x058639e2) /* 0.345270045 */, 15 }, +/* 1098 */ { MAD_F(0x0587f1fd) /* 0.345689763 */, 15 }, +/* 1099 */ { MAD_F(0x0589aa3a) /* 0.346109608 */, 15 }, +/* 1100 */ { MAD_F(0x058b629a) /* 0.346529580 */, 15 }, +/* 1101 */ { MAD_F(0x058d1b1b) /* 0.346949679 */, 15 }, +/* 1102 */ { MAD_F(0x058ed3bf) /* 0.347369906 */, 15 }, +/* 1103 */ { MAD_F(0x05908c85) /* 0.347790260 */, 15 }, + +/* 1104 */ { MAD_F(0x0592456d) /* 0.348210741 */, 15 }, +/* 1105 */ { MAD_F(0x0593fe77) /* 0.348631348 */, 15 }, +/* 1106 */ { MAD_F(0x0595b7a3) /* 0.349052083 */, 15 }, +/* 1107 */ { MAD_F(0x059770f1) /* 0.349472945 */, 15 }, +/* 1108 */ { MAD_F(0x05992a61) /* 0.349893933 */, 15 }, +/* 1109 */ { MAD_F(0x059ae3f3) /* 0.350315048 */, 15 }, +/* 1110 */ { MAD_F(0x059c9da8) /* 0.350736290 */, 15 }, +/* 1111 */ { MAD_F(0x059e577e) /* 0.351157658 */, 15 }, +/* 1112 */ { MAD_F(0x05a01176) /* 0.351579152 */, 15 }, +/* 1113 */ { MAD_F(0x05a1cb90) /* 0.352000773 */, 15 }, +/* 1114 */ { MAD_F(0x05a385cc) /* 0.352422520 */, 15 }, +/* 1115 */ { MAD_F(0x05a5402a) /* 0.352844394 */, 15 }, +/* 1116 */ { MAD_F(0x05a6faa9) /* 0.353266393 */, 15 }, +/* 1117 */ { MAD_F(0x05a8b54b) /* 0.353688519 */, 15 }, +/* 1118 */ { MAD_F(0x05aa700e) /* 0.354110771 */, 15 }, +/* 1119 */ { MAD_F(0x05ac2af3) /* 0.354533148 */, 15 }, + +/* 1120 */ { MAD_F(0x05ade5fa) /* 0.354955651 */, 15 }, +/* 1121 */ { MAD_F(0x05afa123) /* 0.355378281 */, 15 }, +/* 1122 */ { MAD_F(0x05b15c6d) /* 0.355801035 */, 15 }, +/* 1123 */ { MAD_F(0x05b317d9) /* 0.356223916 */, 15 }, +/* 1124 */ { MAD_F(0x05b4d367) /* 0.356646922 */, 15 }, +/* 1125 */ { MAD_F(0x05b68f16) /* 0.357070053 */, 15 }, +/* 1126 */ { MAD_F(0x05b84ae7) /* 0.357493310 */, 15 }, +/* 1127 */ { MAD_F(0x05ba06da) /* 0.357916692 */, 15 }, +/* 1128 */ { MAD_F(0x05bbc2ef) /* 0.358340200 */, 15 }, +/* 1129 */ { MAD_F(0x05bd7f25) /* 0.358763832 */, 15 }, +/* 1130 */ { MAD_F(0x05bf3b7c) /* 0.359187590 */, 15 }, +/* 1131 */ { MAD_F(0x05c0f7f5) /* 0.359611472 */, 15 }, +/* 1132 */ { MAD_F(0x05c2b490) /* 0.360035480 */, 15 }, +/* 1133 */ { MAD_F(0x05c4714c) /* 0.360459613 */, 15 }, +/* 1134 */ { MAD_F(0x05c62e2a) /* 0.360883870 */, 15 }, +/* 1135 */ { MAD_F(0x05c7eb29) /* 0.361308252 */, 15 }, + +/* 1136 */ { MAD_F(0x05c9a84a) /* 0.361732758 */, 15 }, +/* 1137 */ { MAD_F(0x05cb658c) /* 0.362157390 */, 15 }, +/* 1138 */ { MAD_F(0x05cd22ef) /* 0.362582145 */, 15 }, +/* 1139 */ { MAD_F(0x05cee074) /* 0.363007026 */, 15 }, +/* 1140 */ { MAD_F(0x05d09e1b) /* 0.363432030 */, 15 }, +/* 1141 */ { MAD_F(0x05d25be2) /* 0.363857159 */, 15 }, +/* 1142 */ { MAD_F(0x05d419cb) /* 0.364282412 */, 15 }, +/* 1143 */ { MAD_F(0x05d5d7d5) /* 0.364707789 */, 15 }, +/* 1144 */ { MAD_F(0x05d79601) /* 0.365133291 */, 15 }, +/* 1145 */ { MAD_F(0x05d9544e) /* 0.365558916 */, 15 }, +/* 1146 */ { MAD_F(0x05db12bc) /* 0.365984665 */, 15 }, +/* 1147 */ { MAD_F(0x05dcd14c) /* 0.366410538 */, 15 }, +/* 1148 */ { MAD_F(0x05de8ffc) /* 0.366836535 */, 15 }, +/* 1149 */ { MAD_F(0x05e04ece) /* 0.367262655 */, 15 }, +/* 1150 */ { MAD_F(0x05e20dc1) /* 0.367688900 */, 15 }, +/* 1151 */ { MAD_F(0x05e3ccd5) /* 0.368115267 */, 15 }, + +/* 1152 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 15 }, +/* 1153 */ { MAD_F(0x05e74b61) /* 0.368968373 */, 15 }, +/* 1154 */ { MAD_F(0x05e90ad9) /* 0.369395111 */, 15 }, +/* 1155 */ { MAD_F(0x05eaca72) /* 0.369821973 */, 15 }, +/* 1156 */ { MAD_F(0x05ec8a2b) /* 0.370248957 */, 15 }, +/* 1157 */ { MAD_F(0x05ee4a06) /* 0.370676065 */, 15 }, +/* 1158 */ { MAD_F(0x05f00a02) /* 0.371103295 */, 15 }, +/* 1159 */ { MAD_F(0x05f1ca1f) /* 0.371530649 */, 15 }, +/* 1160 */ { MAD_F(0x05f38a5d) /* 0.371958126 */, 15 }, +/* 1161 */ { MAD_F(0x05f54abc) /* 0.372385725 */, 15 }, +/* 1162 */ { MAD_F(0x05f70b3c) /* 0.372813448 */, 15 }, +/* 1163 */ { MAD_F(0x05f8cbdc) /* 0.373241292 */, 15 }, +/* 1164 */ { MAD_F(0x05fa8c9e) /* 0.373669260 */, 15 }, +/* 1165 */ { MAD_F(0x05fc4d81) /* 0.374097350 */, 15 }, +/* 1166 */ { MAD_F(0x05fe0e84) /* 0.374525563 */, 15 }, +/* 1167 */ { MAD_F(0x05ffcfa8) /* 0.374953898 */, 15 }, + +/* 1168 */ { MAD_F(0x060190ee) /* 0.375382356 */, 15 }, +/* 1169 */ { MAD_F(0x06035254) /* 0.375810936 */, 15 }, +/* 1170 */ { MAD_F(0x060513da) /* 0.376239638 */, 15 }, +/* 1171 */ { MAD_F(0x0606d582) /* 0.376668462 */, 15 }, +/* 1172 */ { MAD_F(0x0608974a) /* 0.377097408 */, 15 }, +/* 1173 */ { MAD_F(0x060a5934) /* 0.377526476 */, 15 }, +/* 1174 */ { MAD_F(0x060c1b3d) /* 0.377955667 */, 15 }, +/* 1175 */ { MAD_F(0x060ddd68) /* 0.378384979 */, 15 }, +/* 1176 */ { MAD_F(0x060f9fb3) /* 0.378814413 */, 15 }, +/* 1177 */ { MAD_F(0x0611621f) /* 0.379243968 */, 15 }, +/* 1178 */ { MAD_F(0x061324ac) /* 0.379673646 */, 15 }, +/* 1179 */ { MAD_F(0x0614e759) /* 0.380103444 */, 15 }, +/* 1180 */ { MAD_F(0x0616aa27) /* 0.380533365 */, 15 }, +/* 1181 */ { MAD_F(0x06186d16) /* 0.380963407 */, 15 }, +/* 1182 */ { MAD_F(0x061a3025) /* 0.381393570 */, 15 }, +/* 1183 */ { MAD_F(0x061bf354) /* 0.381823855 */, 15 }, + +/* 1184 */ { MAD_F(0x061db6a5) /* 0.382254261 */, 15 }, +/* 1185 */ { MAD_F(0x061f7a15) /* 0.382684788 */, 15 }, +/* 1186 */ { MAD_F(0x06213da7) /* 0.383115436 */, 15 }, +/* 1187 */ { MAD_F(0x06230158) /* 0.383546205 */, 15 }, +/* 1188 */ { MAD_F(0x0624c52a) /* 0.383977096 */, 15 }, +/* 1189 */ { MAD_F(0x0626891d) /* 0.384408107 */, 15 }, +/* 1190 */ { MAD_F(0x06284d30) /* 0.384839239 */, 15 }, +/* 1191 */ { MAD_F(0x062a1164) /* 0.385270492 */, 15 }, +/* 1192 */ { MAD_F(0x062bd5b8) /* 0.385701865 */, 15 }, +/* 1193 */ { MAD_F(0x062d9a2c) /* 0.386133359 */, 15 }, +/* 1194 */ { MAD_F(0x062f5ec1) /* 0.386564974 */, 15 }, +/* 1195 */ { MAD_F(0x06312376) /* 0.386996709 */, 15 }, +/* 1196 */ { MAD_F(0x0632e84b) /* 0.387428565 */, 15 }, +/* 1197 */ { MAD_F(0x0634ad41) /* 0.387860541 */, 15 }, +/* 1198 */ { MAD_F(0x06367257) /* 0.388292637 */, 15 }, +/* 1199 */ { MAD_F(0x0638378d) /* 0.388724854 */, 15 }, + +/* 1200 */ { MAD_F(0x0639fce4) /* 0.389157191 */, 15 }, +/* 1201 */ { MAD_F(0x063bc25b) /* 0.389589648 */, 15 }, +/* 1202 */ { MAD_F(0x063d87f2) /* 0.390022225 */, 15 }, +/* 1203 */ { MAD_F(0x063f4da9) /* 0.390454922 */, 15 }, +/* 1204 */ { MAD_F(0x06411380) /* 0.390887739 */, 15 }, +/* 1205 */ { MAD_F(0x0642d978) /* 0.391320675 */, 15 }, +/* 1206 */ { MAD_F(0x06449f8f) /* 0.391753732 */, 15 }, +/* 1207 */ { MAD_F(0x064665c7) /* 0.392186908 */, 15 }, +/* 1208 */ { MAD_F(0x06482c1f) /* 0.392620204 */, 15 }, +/* 1209 */ { MAD_F(0x0649f297) /* 0.393053619 */, 15 }, +/* 1210 */ { MAD_F(0x064bb92f) /* 0.393487154 */, 15 }, +/* 1211 */ { MAD_F(0x064d7fe8) /* 0.393920808 */, 15 }, +/* 1212 */ { MAD_F(0x064f46c0) /* 0.394354582 */, 15 }, +/* 1213 */ { MAD_F(0x06510db8) /* 0.394788475 */, 15 }, +/* 1214 */ { MAD_F(0x0652d4d0) /* 0.395222488 */, 15 }, +/* 1215 */ { MAD_F(0x06549c09) /* 0.395656619 */, 15 }, + +/* 1216 */ { MAD_F(0x06566361) /* 0.396090870 */, 15 }, +/* 1217 */ { MAD_F(0x06582ad9) /* 0.396525239 */, 15 }, +/* 1218 */ { MAD_F(0x0659f271) /* 0.396959728 */, 15 }, +/* 1219 */ { MAD_F(0x065bba29) /* 0.397394336 */, 15 }, +/* 1220 */ { MAD_F(0x065d8201) /* 0.397829062 */, 15 }, +/* 1221 */ { MAD_F(0x065f49f9) /* 0.398263907 */, 15 }, +/* 1222 */ { MAD_F(0x06611211) /* 0.398698871 */, 15 }, +/* 1223 */ { MAD_F(0x0662da49) /* 0.399133954 */, 15 }, +/* 1224 */ { MAD_F(0x0664a2a0) /* 0.399569155 */, 15 }, +/* 1225 */ { MAD_F(0x06666b17) /* 0.400004475 */, 15 }, +/* 1226 */ { MAD_F(0x066833ae) /* 0.400439913 */, 15 }, +/* 1227 */ { MAD_F(0x0669fc65) /* 0.400875470 */, 15 }, +/* 1228 */ { MAD_F(0x066bc53c) /* 0.401311145 */, 15 }, +/* 1229 */ { MAD_F(0x066d8e32) /* 0.401746938 */, 15 }, +/* 1230 */ { MAD_F(0x066f5748) /* 0.402182850 */, 15 }, +/* 1231 */ { MAD_F(0x0671207e) /* 0.402618879 */, 15 }, + +/* 1232 */ { MAD_F(0x0672e9d4) /* 0.403055027 */, 15 }, +/* 1233 */ { MAD_F(0x0674b349) /* 0.403491293 */, 15 }, +/* 1234 */ { MAD_F(0x06767cde) /* 0.403927676 */, 15 }, +/* 1235 */ { MAD_F(0x06784692) /* 0.404364178 */, 15 }, +/* 1236 */ { MAD_F(0x067a1066) /* 0.404800797 */, 15 }, +/* 1237 */ { MAD_F(0x067bda5a) /* 0.405237535 */, 15 }, +/* 1238 */ { MAD_F(0x067da46d) /* 0.405674390 */, 15 }, +/* 1239 */ { MAD_F(0x067f6ea0) /* 0.406111362 */, 15 }, +/* 1240 */ { MAD_F(0x068138f3) /* 0.406548452 */, 15 }, +/* 1241 */ { MAD_F(0x06830365) /* 0.406985660 */, 15 }, +/* 1242 */ { MAD_F(0x0684cdf6) /* 0.407422985 */, 15 }, +/* 1243 */ { MAD_F(0x068698a8) /* 0.407860427 */, 15 }, +/* 1244 */ { MAD_F(0x06886378) /* 0.408297987 */, 15 }, +/* 1245 */ { MAD_F(0x068a2e68) /* 0.408735664 */, 15 }, +/* 1246 */ { MAD_F(0x068bf978) /* 0.409173458 */, 15 }, +/* 1247 */ { MAD_F(0x068dc4a7) /* 0.409611370 */, 15 }, + +/* 1248 */ { MAD_F(0x068f8ff5) /* 0.410049398 */, 15 }, +/* 1249 */ { MAD_F(0x06915b63) /* 0.410487544 */, 15 }, +/* 1250 */ { MAD_F(0x069326f0) /* 0.410925806 */, 15 }, +/* 1251 */ { MAD_F(0x0694f29c) /* 0.411364185 */, 15 }, +/* 1252 */ { MAD_F(0x0696be68) /* 0.411802681 */, 15 }, +/* 1253 */ { MAD_F(0x06988a54) /* 0.412241294 */, 15 }, +/* 1254 */ { MAD_F(0x069a565e) /* 0.412680024 */, 15 }, +/* 1255 */ { MAD_F(0x069c2288) /* 0.413118870 */, 15 }, +/* 1256 */ { MAD_F(0x069deed1) /* 0.413557833 */, 15 }, +/* 1257 */ { MAD_F(0x069fbb3a) /* 0.413996912 */, 15 }, +/* 1258 */ { MAD_F(0x06a187c1) /* 0.414436108 */, 15 }, +/* 1259 */ { MAD_F(0x06a35468) /* 0.414875420 */, 15 }, +/* 1260 */ { MAD_F(0x06a5212f) /* 0.415314849 */, 15 }, +/* 1261 */ { MAD_F(0x06a6ee14) /* 0.415754393 */, 15 }, +/* 1262 */ { MAD_F(0x06a8bb18) /* 0.416194054 */, 15 }, +/* 1263 */ { MAD_F(0x06aa883c) /* 0.416633831 */, 15 }, + +/* 1264 */ { MAD_F(0x06ac557f) /* 0.417073724 */, 15 }, +/* 1265 */ { MAD_F(0x06ae22e1) /* 0.417513734 */, 15 }, +/* 1266 */ { MAD_F(0x06aff062) /* 0.417953859 */, 15 }, +/* 1267 */ { MAD_F(0x06b1be03) /* 0.418394100 */, 15 }, +/* 1268 */ { MAD_F(0x06b38bc2) /* 0.418834457 */, 15 }, +/* 1269 */ { MAD_F(0x06b559a1) /* 0.419274929 */, 15 }, +/* 1270 */ { MAD_F(0x06b7279e) /* 0.419715518 */, 15 }, +/* 1271 */ { MAD_F(0x06b8f5bb) /* 0.420156222 */, 15 }, +/* 1272 */ { MAD_F(0x06bac3f6) /* 0.420597041 */, 15 }, +/* 1273 */ { MAD_F(0x06bc9251) /* 0.421037977 */, 15 }, +/* 1274 */ { MAD_F(0x06be60cb) /* 0.421479027 */, 15 }, +/* 1275 */ { MAD_F(0x06c02f63) /* 0.421920193 */, 15 }, +/* 1276 */ { MAD_F(0x06c1fe1b) /* 0.422361475 */, 15 }, +/* 1277 */ { MAD_F(0x06c3ccf1) /* 0.422802871 */, 15 }, +/* 1278 */ { MAD_F(0x06c59be7) /* 0.423244383 */, 15 }, +/* 1279 */ { MAD_F(0x06c76afb) /* 0.423686010 */, 15 }, + +/* 1280 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 15 }, +/* 1281 */ { MAD_F(0x06cb0981) /* 0.424569610 */, 15 }, +/* 1282 */ { MAD_F(0x06ccd8f2) /* 0.425011582 */, 15 }, +/* 1283 */ { MAD_F(0x06cea881) /* 0.425453669 */, 15 }, +/* 1284 */ { MAD_F(0x06d07830) /* 0.425895871 */, 15 }, +/* 1285 */ { MAD_F(0x06d247fe) /* 0.426338188 */, 15 }, +/* 1286 */ { MAD_F(0x06d417ea) /* 0.426780620 */, 15 }, +/* 1287 */ { MAD_F(0x06d5e7f5) /* 0.427223166 */, 15 }, +/* 1288 */ { MAD_F(0x06d7b81f) /* 0.427665827 */, 15 }, +/* 1289 */ { MAD_F(0x06d98868) /* 0.428108603 */, 15 }, +/* 1290 */ { MAD_F(0x06db58cf) /* 0.428551493 */, 15 }, +/* 1291 */ { MAD_F(0x06dd2955) /* 0.428994497 */, 15 }, +/* 1292 */ { MAD_F(0x06def9fa) /* 0.429437616 */, 15 }, +/* 1293 */ { MAD_F(0x06e0cabe) /* 0.429880849 */, 15 }, +/* 1294 */ { MAD_F(0x06e29ba0) /* 0.430324197 */, 15 }, +/* 1295 */ { MAD_F(0x06e46ca1) /* 0.430767659 */, 15 }, + +/* 1296 */ { MAD_F(0x06e63dc0) /* 0.431211234 */, 15 }, +/* 1297 */ { MAD_F(0x06e80efe) /* 0.431654924 */, 15 }, +/* 1298 */ { MAD_F(0x06e9e05b) /* 0.432098728 */, 15 }, +/* 1299 */ { MAD_F(0x06ebb1d6) /* 0.432542647 */, 15 }, +/* 1300 */ { MAD_F(0x06ed8370) /* 0.432986678 */, 15 }, +/* 1301 */ { MAD_F(0x06ef5529) /* 0.433430824 */, 15 }, +/* 1302 */ { MAD_F(0x06f12700) /* 0.433875084 */, 15 }, +/* 1303 */ { MAD_F(0x06f2f8f5) /* 0.434319457 */, 15 }, +/* 1304 */ { MAD_F(0x06f4cb09) /* 0.434763944 */, 15 }, +/* 1305 */ { MAD_F(0x06f69d3c) /* 0.435208545 */, 15 }, +/* 1306 */ { MAD_F(0x06f86f8d) /* 0.435653259 */, 15 }, +/* 1307 */ { MAD_F(0x06fa41fd) /* 0.436098087 */, 15 }, +/* 1308 */ { MAD_F(0x06fc148b) /* 0.436543029 */, 15 }, +/* 1309 */ { MAD_F(0x06fde737) /* 0.436988083 */, 15 }, +/* 1310 */ { MAD_F(0x06ffba02) /* 0.437433251 */, 15 }, +/* 1311 */ { MAD_F(0x07018ceb) /* 0.437878533 */, 15 }, + +/* 1312 */ { MAD_F(0x07035ff3) /* 0.438323927 */, 15 }, +/* 1313 */ { MAD_F(0x07053319) /* 0.438769435 */, 15 }, +/* 1314 */ { MAD_F(0x0707065d) /* 0.439215056 */, 15 }, +/* 1315 */ { MAD_F(0x0708d9c0) /* 0.439660790 */, 15 }, +/* 1316 */ { MAD_F(0x070aad41) /* 0.440106636 */, 15 }, +/* 1317 */ { MAD_F(0x070c80e1) /* 0.440552596 */, 15 }, +/* 1318 */ { MAD_F(0x070e549f) /* 0.440998669 */, 15 }, +/* 1319 */ { MAD_F(0x0710287b) /* 0.441444855 */, 15 }, +/* 1320 */ { MAD_F(0x0711fc75) /* 0.441891153 */, 15 }, +/* 1321 */ { MAD_F(0x0713d08d) /* 0.442337564 */, 15 }, +/* 1322 */ { MAD_F(0x0715a4c4) /* 0.442784088 */, 15 }, +/* 1323 */ { MAD_F(0x07177919) /* 0.443230724 */, 15 }, +/* 1324 */ { MAD_F(0x07194d8c) /* 0.443677473 */, 15 }, +/* 1325 */ { MAD_F(0x071b221e) /* 0.444124334 */, 15 }, +/* 1326 */ { MAD_F(0x071cf6ce) /* 0.444571308 */, 15 }, +/* 1327 */ { MAD_F(0x071ecb9b) /* 0.445018394 */, 15 }, + +/* 1328 */ { MAD_F(0x0720a087) /* 0.445465593 */, 15 }, +/* 1329 */ { MAD_F(0x07227591) /* 0.445912903 */, 15 }, +/* 1330 */ { MAD_F(0x07244ab9) /* 0.446360326 */, 15 }, +/* 1331 */ { MAD_F(0x07262000) /* 0.446807861 */, 15 }, +/* 1332 */ { MAD_F(0x0727f564) /* 0.447255509 */, 15 }, +/* 1333 */ { MAD_F(0x0729cae7) /* 0.447703268 */, 15 }, +/* 1334 */ { MAD_F(0x072ba087) /* 0.448151139 */, 15 }, +/* 1335 */ { MAD_F(0x072d7646) /* 0.448599122 */, 15 }, +/* 1336 */ { MAD_F(0x072f4c22) /* 0.449047217 */, 15 }, +/* 1337 */ { MAD_F(0x0731221d) /* 0.449495424 */, 15 }, +/* 1338 */ { MAD_F(0x0732f835) /* 0.449943742 */, 15 }, +/* 1339 */ { MAD_F(0x0734ce6c) /* 0.450392173 */, 15 }, +/* 1340 */ { MAD_F(0x0736a4c1) /* 0.450840715 */, 15 }, +/* 1341 */ { MAD_F(0x07387b33) /* 0.451289368 */, 15 }, +/* 1342 */ { MAD_F(0x073a51c4) /* 0.451738133 */, 15 }, +/* 1343 */ { MAD_F(0x073c2872) /* 0.452187010 */, 15 }, + +/* 1344 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 15 }, +/* 1345 */ { MAD_F(0x073fd628) /* 0.453085097 */, 15 }, +/* 1346 */ { MAD_F(0x0741ad30) /* 0.453534308 */, 15 }, +/* 1347 */ { MAD_F(0x07438456) /* 0.453983630 */, 15 }, +/* 1348 */ { MAD_F(0x07455b9a) /* 0.454433063 */, 15 }, +/* 1349 */ { MAD_F(0x074732fc) /* 0.454882607 */, 15 }, +/* 1350 */ { MAD_F(0x07490a7b) /* 0.455332262 */, 15 }, +/* 1351 */ { MAD_F(0x074ae218) /* 0.455782029 */, 15 }, +/* 1352 */ { MAD_F(0x074cb9d3) /* 0.456231906 */, 15 }, +/* 1353 */ { MAD_F(0x074e91ac) /* 0.456681894 */, 15 }, +/* 1354 */ { MAD_F(0x075069a3) /* 0.457131993 */, 15 }, +/* 1355 */ { MAD_F(0x075241b7) /* 0.457582203 */, 15 }, +/* 1356 */ { MAD_F(0x075419e9) /* 0.458032524 */, 15 }, +/* 1357 */ { MAD_F(0x0755f239) /* 0.458482956 */, 15 }, +/* 1358 */ { MAD_F(0x0757caa7) /* 0.458933498 */, 15 }, +/* 1359 */ { MAD_F(0x0759a332) /* 0.459384151 */, 15 }, + +/* 1360 */ { MAD_F(0x075b7bdb) /* 0.459834914 */, 15 }, +/* 1361 */ { MAD_F(0x075d54a1) /* 0.460285788 */, 15 }, +/* 1362 */ { MAD_F(0x075f2d85) /* 0.460736772 */, 15 }, +/* 1363 */ { MAD_F(0x07610687) /* 0.461187867 */, 15 }, +/* 1364 */ { MAD_F(0x0762dfa6) /* 0.461639071 */, 15 }, +/* 1365 */ { MAD_F(0x0764b8e3) /* 0.462090387 */, 15 }, +/* 1366 */ { MAD_F(0x0766923e) /* 0.462541812 */, 15 }, +/* 1367 */ { MAD_F(0x07686bb6) /* 0.462993348 */, 15 }, +/* 1368 */ { MAD_F(0x076a454c) /* 0.463444993 */, 15 }, +/* 1369 */ { MAD_F(0x076c1eff) /* 0.463896749 */, 15 }, +/* 1370 */ { MAD_F(0x076df8d0) /* 0.464348615 */, 15 }, +/* 1371 */ { MAD_F(0x076fd2be) /* 0.464800591 */, 15 }, +/* 1372 */ { MAD_F(0x0771acca) /* 0.465252676 */, 15 }, +/* 1373 */ { MAD_F(0x077386f3) /* 0.465704872 */, 15 }, +/* 1374 */ { MAD_F(0x0775613a) /* 0.466157177 */, 15 }, +/* 1375 */ { MAD_F(0x07773b9e) /* 0.466609592 */, 15 }, + +/* 1376 */ { MAD_F(0x07791620) /* 0.467062117 */, 15 }, +/* 1377 */ { MAD_F(0x077af0bf) /* 0.467514751 */, 15 }, +/* 1378 */ { MAD_F(0x077ccb7c) /* 0.467967495 */, 15 }, +/* 1379 */ { MAD_F(0x077ea656) /* 0.468420349 */, 15 }, +/* 1380 */ { MAD_F(0x0780814d) /* 0.468873312 */, 15 }, +/* 1381 */ { MAD_F(0x07825c62) /* 0.469326384 */, 15 }, +/* 1382 */ { MAD_F(0x07843794) /* 0.469779566 */, 15 }, +/* 1383 */ { MAD_F(0x078612e3) /* 0.470232857 */, 15 }, +/* 1384 */ { MAD_F(0x0787ee50) /* 0.470686258 */, 15 }, +/* 1385 */ { MAD_F(0x0789c9da) /* 0.471139767 */, 15 }, +/* 1386 */ { MAD_F(0x078ba581) /* 0.471593386 */, 15 }, +/* 1387 */ { MAD_F(0x078d8146) /* 0.472047114 */, 15 }, +/* 1388 */ { MAD_F(0x078f5d28) /* 0.472500951 */, 15 }, +/* 1389 */ { MAD_F(0x07913927) /* 0.472954896 */, 15 }, +/* 1390 */ { MAD_F(0x07931543) /* 0.473408951 */, 15 }, +/* 1391 */ { MAD_F(0x0794f17d) /* 0.473863115 */, 15 }, + +/* 1392 */ { MAD_F(0x0796cdd4) /* 0.474317388 */, 15 }, +/* 1393 */ { MAD_F(0x0798aa48) /* 0.474771769 */, 15 }, +/* 1394 */ { MAD_F(0x079a86d9) /* 0.475226259 */, 15 }, +/* 1395 */ { MAD_F(0x079c6388) /* 0.475680858 */, 15 }, +/* 1396 */ { MAD_F(0x079e4053) /* 0.476135565 */, 15 }, +/* 1397 */ { MAD_F(0x07a01d3c) /* 0.476590381 */, 15 }, +/* 1398 */ { MAD_F(0x07a1fa42) /* 0.477045306 */, 15 }, +/* 1399 */ { MAD_F(0x07a3d765) /* 0.477500339 */, 15 }, +/* 1400 */ { MAD_F(0x07a5b4a5) /* 0.477955481 */, 15 }, +/* 1401 */ { MAD_F(0x07a79202) /* 0.478410731 */, 15 }, +/* 1402 */ { MAD_F(0x07a96f7d) /* 0.478866089 */, 15 }, +/* 1403 */ { MAD_F(0x07ab4d14) /* 0.479321555 */, 15 }, +/* 1404 */ { MAD_F(0x07ad2ac8) /* 0.479777130 */, 15 }, +/* 1405 */ { MAD_F(0x07af089a) /* 0.480232813 */, 15 }, +/* 1406 */ { MAD_F(0x07b0e688) /* 0.480688604 */, 15 }, +/* 1407 */ { MAD_F(0x07b2c494) /* 0.481144503 */, 15 }, + +/* 1408 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 15 }, +/* 1409 */ { MAD_F(0x07b68102) /* 0.482056625 */, 15 }, +/* 1410 */ { MAD_F(0x07b85f64) /* 0.482512848 */, 15 }, +/* 1411 */ { MAD_F(0x07ba3de4) /* 0.482969179 */, 15 }, +/* 1412 */ { MAD_F(0x07bc1c80) /* 0.483425618 */, 15 }, +/* 1413 */ { MAD_F(0x07bdfb39) /* 0.483882164 */, 15 }, +/* 1414 */ { MAD_F(0x07bfda0f) /* 0.484338818 */, 15 }, +/* 1415 */ { MAD_F(0x07c1b902) /* 0.484795580 */, 15 }, +/* 1416 */ { MAD_F(0x07c39812) /* 0.485252449 */, 15 }, +/* 1417 */ { MAD_F(0x07c5773f) /* 0.485709426 */, 15 }, +/* 1418 */ { MAD_F(0x07c75689) /* 0.486166511 */, 15 }, +/* 1419 */ { MAD_F(0x07c935ef) /* 0.486623703 */, 15 }, +/* 1420 */ { MAD_F(0x07cb1573) /* 0.487081002 */, 15 }, +/* 1421 */ { MAD_F(0x07ccf513) /* 0.487538409 */, 15 }, +/* 1422 */ { MAD_F(0x07ced4d0) /* 0.487995923 */, 15 }, +/* 1423 */ { MAD_F(0x07d0b4aa) /* 0.488453544 */, 15 }, + +/* 1424 */ { MAD_F(0x07d294a0) /* 0.488911273 */, 15 }, +/* 1425 */ { MAD_F(0x07d474b3) /* 0.489369108 */, 15 }, +/* 1426 */ { MAD_F(0x07d654e4) /* 0.489827051 */, 15 }, +/* 1427 */ { MAD_F(0x07d83530) /* 0.490285101 */, 15 }, +/* 1428 */ { MAD_F(0x07da159a) /* 0.490743258 */, 15 }, +/* 1429 */ { MAD_F(0x07dbf620) /* 0.491201522 */, 15 }, +/* 1430 */ { MAD_F(0x07ddd6c3) /* 0.491659892 */, 15 }, +/* 1431 */ { MAD_F(0x07dfb783) /* 0.492118370 */, 15 }, +/* 1432 */ { MAD_F(0x07e1985f) /* 0.492576954 */, 15 }, +/* 1433 */ { MAD_F(0x07e37958) /* 0.493035645 */, 15 }, +/* 1434 */ { MAD_F(0x07e55a6e) /* 0.493494443 */, 15 }, +/* 1435 */ { MAD_F(0x07e73ba0) /* 0.493953348 */, 15 }, +/* 1436 */ { MAD_F(0x07e91cef) /* 0.494412359 */, 15 }, +/* 1437 */ { MAD_F(0x07eafe5a) /* 0.494871476 */, 15 }, +/* 1438 */ { MAD_F(0x07ecdfe2) /* 0.495330701 */, 15 }, +/* 1439 */ { MAD_F(0x07eec187) /* 0.495790031 */, 15 }, + +/* 1440 */ { MAD_F(0x07f0a348) /* 0.496249468 */, 15 }, +/* 1441 */ { MAD_F(0x07f28526) /* 0.496709012 */, 15 }, +/* 1442 */ { MAD_F(0x07f46720) /* 0.497168662 */, 15 }, +/* 1443 */ { MAD_F(0x07f64937) /* 0.497628418 */, 15 }, +/* 1444 */ { MAD_F(0x07f82b6a) /* 0.498088280 */, 15 }, +/* 1445 */ { MAD_F(0x07fa0dba) /* 0.498548248 */, 15 }, +/* 1446 */ { MAD_F(0x07fbf026) /* 0.499008323 */, 15 }, +/* 1447 */ { MAD_F(0x07fdd2af) /* 0.499468503 */, 15 }, +/* 1448 */ { MAD_F(0x07ffb554) /* 0.499928790 */, 15 }, +/* 1449 */ { MAD_F(0x0400cc0b) /* 0.250194591 */, 16 }, +/* 1450 */ { MAD_F(0x0401bd7a) /* 0.250424840 */, 16 }, +/* 1451 */ { MAD_F(0x0402aef7) /* 0.250655143 */, 16 }, +/* 1452 */ { MAD_F(0x0403a083) /* 0.250885498 */, 16 }, +/* 1453 */ { MAD_F(0x0404921c) /* 0.251115906 */, 16 }, +/* 1454 */ { MAD_F(0x040583c4) /* 0.251346367 */, 16 }, +/* 1455 */ { MAD_F(0x0406757a) /* 0.251576880 */, 16 }, + +/* 1456 */ { MAD_F(0x0407673f) /* 0.251807447 */, 16 }, +/* 1457 */ { MAD_F(0x04085911) /* 0.252038066 */, 16 }, +/* 1458 */ { MAD_F(0x04094af1) /* 0.252268738 */, 16 }, +/* 1459 */ { MAD_F(0x040a3ce0) /* 0.252499463 */, 16 }, +/* 1460 */ { MAD_F(0x040b2edd) /* 0.252730240 */, 16 }, +/* 1461 */ { MAD_F(0x040c20e8) /* 0.252961071 */, 16 }, +/* 1462 */ { MAD_F(0x040d1301) /* 0.253191953 */, 16 }, +/* 1463 */ { MAD_F(0x040e0529) /* 0.253422889 */, 16 }, +/* 1464 */ { MAD_F(0x040ef75e) /* 0.253653877 */, 16 }, +/* 1465 */ { MAD_F(0x040fe9a1) /* 0.253884918 */, 16 }, +/* 1466 */ { MAD_F(0x0410dbf3) /* 0.254116011 */, 16 }, +/* 1467 */ { MAD_F(0x0411ce53) /* 0.254347157 */, 16 }, +/* 1468 */ { MAD_F(0x0412c0c1) /* 0.254578356 */, 16 }, +/* 1469 */ { MAD_F(0x0413b33d) /* 0.254809606 */, 16 }, +/* 1470 */ { MAD_F(0x0414a5c7) /* 0.255040910 */, 16 }, +/* 1471 */ { MAD_F(0x0415985f) /* 0.255272266 */, 16 }, + +/* 1472 */ { MAD_F(0x04168b05) /* 0.255503674 */, 16 }, +/* 1473 */ { MAD_F(0x04177db9) /* 0.255735135 */, 16 }, +/* 1474 */ { MAD_F(0x0418707c) /* 0.255966648 */, 16 }, +/* 1475 */ { MAD_F(0x0419634c) /* 0.256198213 */, 16 }, +/* 1476 */ { MAD_F(0x041a562a) /* 0.256429831 */, 16 }, +/* 1477 */ { MAD_F(0x041b4917) /* 0.256661501 */, 16 }, +/* 1478 */ { MAD_F(0x041c3c11) /* 0.256893223 */, 16 }, +/* 1479 */ { MAD_F(0x041d2f1a) /* 0.257124998 */, 16 }, +/* 1480 */ { MAD_F(0x041e2230) /* 0.257356825 */, 16 }, +/* 1481 */ { MAD_F(0x041f1555) /* 0.257588704 */, 16 }, +/* 1482 */ { MAD_F(0x04200888) /* 0.257820635 */, 16 }, +/* 1483 */ { MAD_F(0x0420fbc8) /* 0.258052619 */, 16 }, +/* 1484 */ { MAD_F(0x0421ef17) /* 0.258284654 */, 16 }, +/* 1485 */ { MAD_F(0x0422e273) /* 0.258516742 */, 16 }, +/* 1486 */ { MAD_F(0x0423d5de) /* 0.258748882 */, 16 }, +/* 1487 */ { MAD_F(0x0424c956) /* 0.258981074 */, 16 }, + +/* 1488 */ { MAD_F(0x0425bcdd) /* 0.259213318 */, 16 }, +/* 1489 */ { MAD_F(0x0426b071) /* 0.259445614 */, 16 }, +/* 1490 */ { MAD_F(0x0427a414) /* 0.259677962 */, 16 }, +/* 1491 */ { MAD_F(0x042897c4) /* 0.259910362 */, 16 }, +/* 1492 */ { MAD_F(0x04298b83) /* 0.260142814 */, 16 }, +/* 1493 */ { MAD_F(0x042a7f4f) /* 0.260375318 */, 16 }, +/* 1494 */ { MAD_F(0x042b7329) /* 0.260607874 */, 16 }, +/* 1495 */ { MAD_F(0x042c6711) /* 0.260840481 */, 16 }, +/* 1496 */ { MAD_F(0x042d5b07) /* 0.261073141 */, 16 }, +/* 1497 */ { MAD_F(0x042e4f0b) /* 0.261305852 */, 16 }, +/* 1498 */ { MAD_F(0x042f431d) /* 0.261538616 */, 16 }, +/* 1499 */ { MAD_F(0x0430373d) /* 0.261771431 */, 16 }, +/* 1500 */ { MAD_F(0x04312b6b) /* 0.262004297 */, 16 }, +/* 1501 */ { MAD_F(0x04321fa6) /* 0.262237216 */, 16 }, +/* 1502 */ { MAD_F(0x043313f0) /* 0.262470186 */, 16 }, +/* 1503 */ { MAD_F(0x04340847) /* 0.262703208 */, 16 }, + +/* 1504 */ { MAD_F(0x0434fcad) /* 0.262936282 */, 16 }, +/* 1505 */ { MAD_F(0x0435f120) /* 0.263169407 */, 16 }, +/* 1506 */ { MAD_F(0x0436e5a1) /* 0.263402584 */, 16 }, +/* 1507 */ { MAD_F(0x0437da2f) /* 0.263635813 */, 16 }, +/* 1508 */ { MAD_F(0x0438cecc) /* 0.263869093 */, 16 }, +/* 1509 */ { MAD_F(0x0439c377) /* 0.264102425 */, 16 }, +/* 1510 */ { MAD_F(0x043ab82f) /* 0.264335808 */, 16 }, +/* 1511 */ { MAD_F(0x043bacf5) /* 0.264569243 */, 16 }, +/* 1512 */ { MAD_F(0x043ca1c9) /* 0.264802730 */, 16 }, +/* 1513 */ { MAD_F(0x043d96ab) /* 0.265036267 */, 16 }, +/* 1514 */ { MAD_F(0x043e8b9b) /* 0.265269857 */, 16 }, +/* 1515 */ { MAD_F(0x043f8098) /* 0.265503498 */, 16 }, +/* 1516 */ { MAD_F(0x044075a3) /* 0.265737190 */, 16 }, +/* 1517 */ { MAD_F(0x04416abc) /* 0.265970933 */, 16 }, +/* 1518 */ { MAD_F(0x04425fe3) /* 0.266204728 */, 16 }, +/* 1519 */ { MAD_F(0x04435518) /* 0.266438574 */, 16 }, + +/* 1520 */ { MAD_F(0x04444a5a) /* 0.266672472 */, 16 }, +/* 1521 */ { MAD_F(0x04453fab) /* 0.266906421 */, 16 }, +/* 1522 */ { MAD_F(0x04463508) /* 0.267140421 */, 16 }, +/* 1523 */ { MAD_F(0x04472a74) /* 0.267374472 */, 16 }, +/* 1524 */ { MAD_F(0x04481fee) /* 0.267608575 */, 16 }, +/* 1525 */ { MAD_F(0x04491575) /* 0.267842729 */, 16 }, +/* 1526 */ { MAD_F(0x044a0b0a) /* 0.268076934 */, 16 }, +/* 1527 */ { MAD_F(0x044b00ac) /* 0.268311190 */, 16 }, +/* 1528 */ { MAD_F(0x044bf65d) /* 0.268545497 */, 16 }, +/* 1529 */ { MAD_F(0x044cec1b) /* 0.268779856 */, 16 }, +/* 1530 */ { MAD_F(0x044de1e7) /* 0.269014265 */, 16 }, +/* 1531 */ { MAD_F(0x044ed7c0) /* 0.269248726 */, 16 }, +/* 1532 */ { MAD_F(0x044fcda8) /* 0.269483238 */, 16 }, +/* 1533 */ { MAD_F(0x0450c39c) /* 0.269717800 */, 16 }, +/* 1534 */ { MAD_F(0x0451b99f) /* 0.269952414 */, 16 }, +/* 1535 */ { MAD_F(0x0452afaf) /* 0.270187079 */, 16 }, + +/* 1536 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 16 }, +/* 1537 */ { MAD_F(0x04549bf9) /* 0.270656561 */, 16 }, +/* 1538 */ { MAD_F(0x04559232) /* 0.270891379 */, 16 }, +/* 1539 */ { MAD_F(0x04568879) /* 0.271126247 */, 16 }, +/* 1540 */ { MAD_F(0x04577ece) /* 0.271361166 */, 16 }, +/* 1541 */ { MAD_F(0x04587530) /* 0.271596136 */, 16 }, +/* 1542 */ { MAD_F(0x04596ba0) /* 0.271831157 */, 16 }, +/* 1543 */ { MAD_F(0x045a621e) /* 0.272066229 */, 16 }, +/* 1544 */ { MAD_F(0x045b58a9) /* 0.272301352 */, 16 }, +/* 1545 */ { MAD_F(0x045c4f42) /* 0.272536525 */, 16 }, +/* 1546 */ { MAD_F(0x045d45e9) /* 0.272771749 */, 16 }, +/* 1547 */ { MAD_F(0x045e3c9d) /* 0.273007024 */, 16 }, +/* 1548 */ { MAD_F(0x045f335e) /* 0.273242350 */, 16 }, +/* 1549 */ { MAD_F(0x04602a2e) /* 0.273477726 */, 16 }, +/* 1550 */ { MAD_F(0x0461210b) /* 0.273713153 */, 16 }, +/* 1551 */ { MAD_F(0x046217f5) /* 0.273948630 */, 16 }, + +/* 1552 */ { MAD_F(0x04630eed) /* 0.274184158 */, 16 }, +/* 1553 */ { MAD_F(0x046405f3) /* 0.274419737 */, 16 }, +/* 1554 */ { MAD_F(0x0464fd06) /* 0.274655366 */, 16 }, +/* 1555 */ { MAD_F(0x0465f427) /* 0.274891046 */, 16 }, +/* 1556 */ { MAD_F(0x0466eb55) /* 0.275126776 */, 16 }, +/* 1557 */ { MAD_F(0x0467e291) /* 0.275362557 */, 16 }, +/* 1558 */ { MAD_F(0x0468d9db) /* 0.275598389 */, 16 }, +/* 1559 */ { MAD_F(0x0469d132) /* 0.275834270 */, 16 }, +/* 1560 */ { MAD_F(0x046ac896) /* 0.276070203 */, 16 }, +/* 1561 */ { MAD_F(0x046bc009) /* 0.276306185 */, 16 }, +/* 1562 */ { MAD_F(0x046cb788) /* 0.276542218 */, 16 }, +/* 1563 */ { MAD_F(0x046daf15) /* 0.276778302 */, 16 }, +/* 1564 */ { MAD_F(0x046ea6b0) /* 0.277014435 */, 16 }, +/* 1565 */ { MAD_F(0x046f9e58) /* 0.277250619 */, 16 }, +/* 1566 */ { MAD_F(0x0470960e) /* 0.277486854 */, 16 }, +/* 1567 */ { MAD_F(0x04718dd1) /* 0.277723139 */, 16 }, + +/* 1568 */ { MAD_F(0x047285a2) /* 0.277959474 */, 16 }, +/* 1569 */ { MAD_F(0x04737d80) /* 0.278195859 */, 16 }, +/* 1570 */ { MAD_F(0x0474756c) /* 0.278432294 */, 16 }, +/* 1571 */ { MAD_F(0x04756d65) /* 0.278668780 */, 16 }, +/* 1572 */ { MAD_F(0x0476656b) /* 0.278905316 */, 16 }, +/* 1573 */ { MAD_F(0x04775d7f) /* 0.279141902 */, 16 }, +/* 1574 */ { MAD_F(0x047855a1) /* 0.279378538 */, 16 }, +/* 1575 */ { MAD_F(0x04794dd0) /* 0.279615224 */, 16 }, +/* 1576 */ { MAD_F(0x047a460c) /* 0.279851960 */, 16 }, +/* 1577 */ { MAD_F(0x047b3e56) /* 0.280088747 */, 16 }, +/* 1578 */ { MAD_F(0x047c36ae) /* 0.280325583 */, 16 }, +/* 1579 */ { MAD_F(0x047d2f12) /* 0.280562470 */, 16 }, +/* 1580 */ { MAD_F(0x047e2784) /* 0.280799406 */, 16 }, +/* 1581 */ { MAD_F(0x047f2004) /* 0.281036393 */, 16 }, +/* 1582 */ { MAD_F(0x04801891) /* 0.281273429 */, 16 }, +/* 1583 */ { MAD_F(0x0481112b) /* 0.281510516 */, 16 }, + +/* 1584 */ { MAD_F(0x048209d3) /* 0.281747652 */, 16 }, +/* 1585 */ { MAD_F(0x04830288) /* 0.281984838 */, 16 }, +/* 1586 */ { MAD_F(0x0483fb4b) /* 0.282222075 */, 16 }, +/* 1587 */ { MAD_F(0x0484f41b) /* 0.282459361 */, 16 }, +/* 1588 */ { MAD_F(0x0485ecf8) /* 0.282696697 */, 16 }, +/* 1589 */ { MAD_F(0x0486e5e3) /* 0.282934082 */, 16 }, +/* 1590 */ { MAD_F(0x0487dedb) /* 0.283171518 */, 16 }, +/* 1591 */ { MAD_F(0x0488d7e1) /* 0.283409003 */, 16 }, +/* 1592 */ { MAD_F(0x0489d0f4) /* 0.283646538 */, 16 }, +/* 1593 */ { MAD_F(0x048aca14) /* 0.283884123 */, 16 }, +/* 1594 */ { MAD_F(0x048bc341) /* 0.284121757 */, 16 }, +/* 1595 */ { MAD_F(0x048cbc7c) /* 0.284359441 */, 16 }, +/* 1596 */ { MAD_F(0x048db5c4) /* 0.284597175 */, 16 }, +/* 1597 */ { MAD_F(0x048eaf1a) /* 0.284834959 */, 16 }, +/* 1598 */ { MAD_F(0x048fa87d) /* 0.285072792 */, 16 }, +/* 1599 */ { MAD_F(0x0490a1ed) /* 0.285310675 */, 16 }, + +/* 1600 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 16 }, +/* 1601 */ { MAD_F(0x049294f5) /* 0.285786589 */, 16 }, +/* 1602 */ { MAD_F(0x04938e8d) /* 0.286024621 */, 16 }, +/* 1603 */ { MAD_F(0x04948833) /* 0.286262702 */, 16 }, +/* 1604 */ { MAD_F(0x049581e5) /* 0.286500832 */, 16 }, +/* 1605 */ { MAD_F(0x04967ba5) /* 0.286739012 */, 16 }, +/* 1606 */ { MAD_F(0x04977573) /* 0.286977242 */, 16 }, +/* 1607 */ { MAD_F(0x04986f4d) /* 0.287215521 */, 16 }, +/* 1608 */ { MAD_F(0x04996935) /* 0.287453849 */, 16 }, +/* 1609 */ { MAD_F(0x049a632a) /* 0.287692227 */, 16 }, +/* 1610 */ { MAD_F(0x049b5d2c) /* 0.287930654 */, 16 }, +/* 1611 */ { MAD_F(0x049c573c) /* 0.288169131 */, 16 }, +/* 1612 */ { MAD_F(0x049d5159) /* 0.288407657 */, 16 }, +/* 1613 */ { MAD_F(0x049e4b83) /* 0.288646232 */, 16 }, +/* 1614 */ { MAD_F(0x049f45ba) /* 0.288884857 */, 16 }, +/* 1615 */ { MAD_F(0x04a03ffe) /* 0.289123530 */, 16 }, + +/* 1616 */ { MAD_F(0x04a13a50) /* 0.289362253 */, 16 }, +/* 1617 */ { MAD_F(0x04a234af) /* 0.289601026 */, 16 }, +/* 1618 */ { MAD_F(0x04a32f1b) /* 0.289839847 */, 16 }, +/* 1619 */ { MAD_F(0x04a42995) /* 0.290078718 */, 16 }, +/* 1620 */ { MAD_F(0x04a5241b) /* 0.290317638 */, 16 }, +/* 1621 */ { MAD_F(0x04a61eaf) /* 0.290556607 */, 16 }, +/* 1622 */ { MAD_F(0x04a71950) /* 0.290795626 */, 16 }, +/* 1623 */ { MAD_F(0x04a813fe) /* 0.291034693 */, 16 }, +/* 1624 */ { MAD_F(0x04a90eba) /* 0.291273810 */, 16 }, +/* 1625 */ { MAD_F(0x04aa0982) /* 0.291512975 */, 16 }, +/* 1626 */ { MAD_F(0x04ab0458) /* 0.291752190 */, 16 }, +/* 1627 */ { MAD_F(0x04abff3b) /* 0.291991453 */, 16 }, +/* 1628 */ { MAD_F(0x04acfa2b) /* 0.292230766 */, 16 }, +/* 1629 */ { MAD_F(0x04adf528) /* 0.292470128 */, 16 }, +/* 1630 */ { MAD_F(0x04aef032) /* 0.292709539 */, 16 }, +/* 1631 */ { MAD_F(0x04afeb4a) /* 0.292948998 */, 16 }, + +/* 1632 */ { MAD_F(0x04b0e66e) /* 0.293188507 */, 16 }, +/* 1633 */ { MAD_F(0x04b1e1a0) /* 0.293428065 */, 16 }, +/* 1634 */ { MAD_F(0x04b2dcdf) /* 0.293667671 */, 16 }, +/* 1635 */ { MAD_F(0x04b3d82b) /* 0.293907326 */, 16 }, +/* 1636 */ { MAD_F(0x04b4d384) /* 0.294147031 */, 16 }, +/* 1637 */ { MAD_F(0x04b5ceea) /* 0.294386784 */, 16 }, +/* 1638 */ { MAD_F(0x04b6ca5e) /* 0.294626585 */, 16 }, +/* 1639 */ { MAD_F(0x04b7c5de) /* 0.294866436 */, 16 }, +/* 1640 */ { MAD_F(0x04b8c16c) /* 0.295106336 */, 16 }, +/* 1641 */ { MAD_F(0x04b9bd06) /* 0.295346284 */, 16 }, +/* 1642 */ { MAD_F(0x04bab8ae) /* 0.295586281 */, 16 }, +/* 1643 */ { MAD_F(0x04bbb463) /* 0.295826327 */, 16 }, +/* 1644 */ { MAD_F(0x04bcb024) /* 0.296066421 */, 16 }, +/* 1645 */ { MAD_F(0x04bdabf3) /* 0.296306564 */, 16 }, +/* 1646 */ { MAD_F(0x04bea7cf) /* 0.296546756 */, 16 }, +/* 1647 */ { MAD_F(0x04bfa3b8) /* 0.296786996 */, 16 }, + +/* 1648 */ { MAD_F(0x04c09faf) /* 0.297027285 */, 16 }, +/* 1649 */ { MAD_F(0x04c19bb2) /* 0.297267623 */, 16 }, +/* 1650 */ { MAD_F(0x04c297c2) /* 0.297508009 */, 16 }, +/* 1651 */ { MAD_F(0x04c393df) /* 0.297748444 */, 16 }, +/* 1652 */ { MAD_F(0x04c49009) /* 0.297988927 */, 16 }, +/* 1653 */ { MAD_F(0x04c58c41) /* 0.298229459 */, 16 }, +/* 1654 */ { MAD_F(0x04c68885) /* 0.298470039 */, 16 }, +/* 1655 */ { MAD_F(0x04c784d6) /* 0.298710668 */, 16 }, +/* 1656 */ { MAD_F(0x04c88135) /* 0.298951346 */, 16 }, +/* 1657 */ { MAD_F(0x04c97da0) /* 0.299192071 */, 16 }, +/* 1658 */ { MAD_F(0x04ca7a18) /* 0.299432846 */, 16 }, +/* 1659 */ { MAD_F(0x04cb769e) /* 0.299673668 */, 16 }, +/* 1660 */ { MAD_F(0x04cc7330) /* 0.299914539 */, 16 }, +/* 1661 */ { MAD_F(0x04cd6fcf) /* 0.300155459 */, 16 }, +/* 1662 */ { MAD_F(0x04ce6c7b) /* 0.300396426 */, 16 }, +/* 1663 */ { MAD_F(0x04cf6935) /* 0.300637443 */, 16 }, + +/* 1664 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 16 }, +/* 1665 */ { MAD_F(0x04d162ce) /* 0.301119620 */, 16 }, +/* 1666 */ { MAD_F(0x04d25fae) /* 0.301360781 */, 16 }, +/* 1667 */ { MAD_F(0x04d35c9b) /* 0.301601990 */, 16 }, +/* 1668 */ { MAD_F(0x04d45995) /* 0.301843247 */, 16 }, +/* 1669 */ { MAD_F(0x04d5569c) /* 0.302084553 */, 16 }, +/* 1670 */ { MAD_F(0x04d653b0) /* 0.302325907 */, 16 }, +/* 1671 */ { MAD_F(0x04d750d1) /* 0.302567309 */, 16 }, +/* 1672 */ { MAD_F(0x04d84dff) /* 0.302808759 */, 16 }, +/* 1673 */ { MAD_F(0x04d94b3a) /* 0.303050257 */, 16 }, +/* 1674 */ { MAD_F(0x04da4881) /* 0.303291804 */, 16 }, +/* 1675 */ { MAD_F(0x04db45d6) /* 0.303533399 */, 16 }, +/* 1676 */ { MAD_F(0x04dc4337) /* 0.303775041 */, 16 }, +/* 1677 */ { MAD_F(0x04dd40a6) /* 0.304016732 */, 16 }, +/* 1678 */ { MAD_F(0x04de3e21) /* 0.304258471 */, 16 }, +/* 1679 */ { MAD_F(0x04df3ba9) /* 0.304500257 */, 16 }, + +/* 1680 */ { MAD_F(0x04e0393e) /* 0.304742092 */, 16 }, +/* 1681 */ { MAD_F(0x04e136e0) /* 0.304983975 */, 16 }, +/* 1682 */ { MAD_F(0x04e2348f) /* 0.305225906 */, 16 }, +/* 1683 */ { MAD_F(0x04e3324b) /* 0.305467885 */, 16 }, +/* 1684 */ { MAD_F(0x04e43013) /* 0.305709911 */, 16 }, +/* 1685 */ { MAD_F(0x04e52de9) /* 0.305951986 */, 16 }, +/* 1686 */ { MAD_F(0x04e62bcb) /* 0.306194108 */, 16 }, +/* 1687 */ { MAD_F(0x04e729ba) /* 0.306436279 */, 16 }, +/* 1688 */ { MAD_F(0x04e827b6) /* 0.306678497 */, 16 }, +/* 1689 */ { MAD_F(0x04e925bf) /* 0.306920763 */, 16 }, +/* 1690 */ { MAD_F(0x04ea23d4) /* 0.307163077 */, 16 }, +/* 1691 */ { MAD_F(0x04eb21f7) /* 0.307405438 */, 16 }, +/* 1692 */ { MAD_F(0x04ec2026) /* 0.307647848 */, 16 }, +/* 1693 */ { MAD_F(0x04ed1e62) /* 0.307890305 */, 16 }, +/* 1694 */ { MAD_F(0x04ee1cab) /* 0.308132810 */, 16 }, +/* 1695 */ { MAD_F(0x04ef1b01) /* 0.308375362 */, 16 }, + +/* 1696 */ { MAD_F(0x04f01963) /* 0.308617963 */, 16 }, +/* 1697 */ { MAD_F(0x04f117d3) /* 0.308860611 */, 16 }, +/* 1698 */ { MAD_F(0x04f2164f) /* 0.309103306 */, 16 }, +/* 1699 */ { MAD_F(0x04f314d8) /* 0.309346050 */, 16 }, +/* 1700 */ { MAD_F(0x04f4136d) /* 0.309588841 */, 16 }, +/* 1701 */ { MAD_F(0x04f51210) /* 0.309831679 */, 16 }, +/* 1702 */ { MAD_F(0x04f610bf) /* 0.310074565 */, 16 }, +/* 1703 */ { MAD_F(0x04f70f7b) /* 0.310317499 */, 16 }, +/* 1704 */ { MAD_F(0x04f80e44) /* 0.310560480 */, 16 }, +/* 1705 */ { MAD_F(0x04f90d19) /* 0.310803509 */, 16 }, +/* 1706 */ { MAD_F(0x04fa0bfc) /* 0.311046586 */, 16 }, +/* 1707 */ { MAD_F(0x04fb0aeb) /* 0.311289710 */, 16 }, +/* 1708 */ { MAD_F(0x04fc09e7) /* 0.311532881 */, 16 }, +/* 1709 */ { MAD_F(0x04fd08ef) /* 0.311776100 */, 16 }, +/* 1710 */ { MAD_F(0x04fe0805) /* 0.312019366 */, 16 }, +/* 1711 */ { MAD_F(0x04ff0727) /* 0.312262680 */, 16 }, + +/* 1712 */ { MAD_F(0x05000655) /* 0.312506041 */, 16 }, +/* 1713 */ { MAD_F(0x05010591) /* 0.312749449 */, 16 }, +/* 1714 */ { MAD_F(0x050204d9) /* 0.312992905 */, 16 }, +/* 1715 */ { MAD_F(0x0503042e) /* 0.313236408 */, 16 }, +/* 1716 */ { MAD_F(0x0504038f) /* 0.313479959 */, 16 }, +/* 1717 */ { MAD_F(0x050502fe) /* 0.313723556 */, 16 }, +/* 1718 */ { MAD_F(0x05060279) /* 0.313967202 */, 16 }, +/* 1719 */ { MAD_F(0x05070200) /* 0.314210894 */, 16 }, +/* 1720 */ { MAD_F(0x05080195) /* 0.314454634 */, 16 }, +/* 1721 */ { MAD_F(0x05090136) /* 0.314698420 */, 16 }, +/* 1722 */ { MAD_F(0x050a00e3) /* 0.314942255 */, 16 }, +/* 1723 */ { MAD_F(0x050b009e) /* 0.315186136 */, 16 }, +/* 1724 */ { MAD_F(0x050c0065) /* 0.315430064 */, 16 }, +/* 1725 */ { MAD_F(0x050d0039) /* 0.315674040 */, 16 }, +/* 1726 */ { MAD_F(0x050e0019) /* 0.315918063 */, 16 }, +/* 1727 */ { MAD_F(0x050f0006) /* 0.316162133 */, 16 }, + +/* 1728 */ { MAD_F(0x05100000) /* 0.316406250 */, 16 }, +/* 1729 */ { MAD_F(0x05110006) /* 0.316650414 */, 16 }, +/* 1730 */ { MAD_F(0x05120019) /* 0.316894625 */, 16 }, +/* 1731 */ { MAD_F(0x05130039) /* 0.317138884 */, 16 }, +/* 1732 */ { MAD_F(0x05140065) /* 0.317383189 */, 16 }, +/* 1733 */ { MAD_F(0x0515009e) /* 0.317627541 */, 16 }, +/* 1734 */ { MAD_F(0x051600e3) /* 0.317871941 */, 16 }, +/* 1735 */ { MAD_F(0x05170135) /* 0.318116387 */, 16 }, +/* 1736 */ { MAD_F(0x05180194) /* 0.318360880 */, 16 }, +/* 1737 */ { MAD_F(0x051901ff) /* 0.318605421 */, 16 }, +/* 1738 */ { MAD_F(0x051a0277) /* 0.318850008 */, 16 }, +/* 1739 */ { MAD_F(0x051b02fc) /* 0.319094642 */, 16 }, +/* 1740 */ { MAD_F(0x051c038d) /* 0.319339323 */, 16 }, +/* 1741 */ { MAD_F(0x051d042a) /* 0.319584051 */, 16 }, +/* 1742 */ { MAD_F(0x051e04d4) /* 0.319828826 */, 16 }, +/* 1743 */ { MAD_F(0x051f058b) /* 0.320073647 */, 16 }, + +/* 1744 */ { MAD_F(0x0520064f) /* 0.320318516 */, 16 }, +/* 1745 */ { MAD_F(0x0521071f) /* 0.320563431 */, 16 }, +/* 1746 */ { MAD_F(0x052207fb) /* 0.320808393 */, 16 }, +/* 1747 */ { MAD_F(0x052308e4) /* 0.321053402 */, 16 }, +/* 1748 */ { MAD_F(0x052409da) /* 0.321298457 */, 16 }, +/* 1749 */ { MAD_F(0x05250adc) /* 0.321543560 */, 16 }, +/* 1750 */ { MAD_F(0x05260bea) /* 0.321788709 */, 16 }, +/* 1751 */ { MAD_F(0x05270d06) /* 0.322033904 */, 16 }, +/* 1752 */ { MAD_F(0x05280e2d) /* 0.322279147 */, 16 }, +/* 1753 */ { MAD_F(0x05290f62) /* 0.322524436 */, 16 }, +/* 1754 */ { MAD_F(0x052a10a3) /* 0.322769771 */, 16 }, +/* 1755 */ { MAD_F(0x052b11f0) /* 0.323015154 */, 16 }, +/* 1756 */ { MAD_F(0x052c134a) /* 0.323260583 */, 16 }, +/* 1757 */ { MAD_F(0x052d14b0) /* 0.323506058 */, 16 }, +/* 1758 */ { MAD_F(0x052e1623) /* 0.323751580 */, 16 }, +/* 1759 */ { MAD_F(0x052f17a2) /* 0.323997149 */, 16 }, + +/* 1760 */ { MAD_F(0x0530192e) /* 0.324242764 */, 16 }, +/* 1761 */ { MAD_F(0x05311ac6) /* 0.324488426 */, 16 }, +/* 1762 */ { MAD_F(0x05321c6b) /* 0.324734134 */, 16 }, +/* 1763 */ { MAD_F(0x05331e1c) /* 0.324979889 */, 16 }, +/* 1764 */ { MAD_F(0x05341fda) /* 0.325225690 */, 16 }, +/* 1765 */ { MAD_F(0x053521a4) /* 0.325471538 */, 16 }, +/* 1766 */ { MAD_F(0x0536237b) /* 0.325717432 */, 16 }, +/* 1767 */ { MAD_F(0x0537255e) /* 0.325963372 */, 16 }, +/* 1768 */ { MAD_F(0x0538274e) /* 0.326209359 */, 16 }, +/* 1769 */ { MAD_F(0x0539294a) /* 0.326455392 */, 16 }, +/* 1770 */ { MAD_F(0x053a2b52) /* 0.326701472 */, 16 }, +/* 1771 */ { MAD_F(0x053b2d67) /* 0.326947598 */, 16 }, +/* 1772 */ { MAD_F(0x053c2f89) /* 0.327193770 */, 16 }, +/* 1773 */ { MAD_F(0x053d31b6) /* 0.327439989 */, 16 }, +/* 1774 */ { MAD_F(0x053e33f1) /* 0.327686254 */, 16 }, +/* 1775 */ { MAD_F(0x053f3637) /* 0.327932565 */, 16 }, + +/* 1776 */ { MAD_F(0x0540388a) /* 0.328178922 */, 16 }, +/* 1777 */ { MAD_F(0x05413aea) /* 0.328425326 */, 16 }, +/* 1778 */ { MAD_F(0x05423d56) /* 0.328671776 */, 16 }, +/* 1779 */ { MAD_F(0x05433fce) /* 0.328918272 */, 16 }, +/* 1780 */ { MAD_F(0x05444253) /* 0.329164814 */, 16 }, +/* 1781 */ { MAD_F(0x054544e4) /* 0.329411403 */, 16 }, +/* 1782 */ { MAD_F(0x05464781) /* 0.329658038 */, 16 }, +/* 1783 */ { MAD_F(0x05474a2b) /* 0.329904718 */, 16 }, +/* 1784 */ { MAD_F(0x05484ce2) /* 0.330151445 */, 16 }, +/* 1785 */ { MAD_F(0x05494fa4) /* 0.330398218 */, 16 }, +/* 1786 */ { MAD_F(0x054a5273) /* 0.330645037 */, 16 }, +/* 1787 */ { MAD_F(0x054b554e) /* 0.330891903 */, 16 }, +/* 1788 */ { MAD_F(0x054c5836) /* 0.331138814 */, 16 }, +/* 1789 */ { MAD_F(0x054d5b2a) /* 0.331385771 */, 16 }, +/* 1790 */ { MAD_F(0x054e5e2b) /* 0.331632774 */, 16 }, +/* 1791 */ { MAD_F(0x054f6138) /* 0.331879824 */, 16 }, + +/* 1792 */ { MAD_F(0x05506451) /* 0.332126919 */, 16 }, +/* 1793 */ { MAD_F(0x05516776) /* 0.332374060 */, 16 }, +/* 1794 */ { MAD_F(0x05526aa8) /* 0.332621247 */, 16 }, +/* 1795 */ { MAD_F(0x05536de6) /* 0.332868480 */, 16 }, +/* 1796 */ { MAD_F(0x05547131) /* 0.333115759 */, 16 }, +/* 1797 */ { MAD_F(0x05557487) /* 0.333363084 */, 16 }, +/* 1798 */ { MAD_F(0x055677ea) /* 0.333610455 */, 16 }, +/* 1799 */ { MAD_F(0x05577b5a) /* 0.333857872 */, 16 }, +/* 1800 */ { MAD_F(0x05587ed5) /* 0.334105334 */, 16 }, +/* 1801 */ { MAD_F(0x0559825e) /* 0.334352843 */, 16 }, +/* 1802 */ { MAD_F(0x055a85f2) /* 0.334600397 */, 16 }, +/* 1803 */ { MAD_F(0x055b8992) /* 0.334847997 */, 16 }, +/* 1804 */ { MAD_F(0x055c8d3f) /* 0.335095642 */, 16 }, +/* 1805 */ { MAD_F(0x055d90f9) /* 0.335343334 */, 16 }, +/* 1806 */ { MAD_F(0x055e94be) /* 0.335591071 */, 16 }, +/* 1807 */ { MAD_F(0x055f9890) /* 0.335838854 */, 16 }, + +/* 1808 */ { MAD_F(0x05609c6e) /* 0.336086683 */, 16 }, +/* 1809 */ { MAD_F(0x0561a058) /* 0.336334557 */, 16 }, +/* 1810 */ { MAD_F(0x0562a44f) /* 0.336582477 */, 16 }, +/* 1811 */ { MAD_F(0x0563a851) /* 0.336830443 */, 16 }, +/* 1812 */ { MAD_F(0x0564ac60) /* 0.337078454 */, 16 }, +/* 1813 */ { MAD_F(0x0565b07c) /* 0.337326511 */, 16 }, +/* 1814 */ { MAD_F(0x0566b4a3) /* 0.337574614 */, 16 }, +/* 1815 */ { MAD_F(0x0567b8d7) /* 0.337822762 */, 16 }, +/* 1816 */ { MAD_F(0x0568bd17) /* 0.338070956 */, 16 }, +/* 1817 */ { MAD_F(0x0569c163) /* 0.338319195 */, 16 }, +/* 1818 */ { MAD_F(0x056ac5bc) /* 0.338567480 */, 16 }, +/* 1819 */ { MAD_F(0x056bca20) /* 0.338815811 */, 16 }, +/* 1820 */ { MAD_F(0x056cce91) /* 0.339064186 */, 16 }, +/* 1821 */ { MAD_F(0x056dd30e) /* 0.339312608 */, 16 }, +/* 1822 */ { MAD_F(0x056ed798) /* 0.339561075 */, 16 }, +/* 1823 */ { MAD_F(0x056fdc2d) /* 0.339809587 */, 16 }, + +/* 1824 */ { MAD_F(0x0570e0cf) /* 0.340058145 */, 16 }, +/* 1825 */ { MAD_F(0x0571e57d) /* 0.340306748 */, 16 }, +/* 1826 */ { MAD_F(0x0572ea37) /* 0.340555397 */, 16 }, +/* 1827 */ { MAD_F(0x0573eefd) /* 0.340804091 */, 16 }, +/* 1828 */ { MAD_F(0x0574f3d0) /* 0.341052830 */, 16 }, +/* 1829 */ { MAD_F(0x0575f8ae) /* 0.341301615 */, 16 }, +/* 1830 */ { MAD_F(0x0576fd99) /* 0.341550445 */, 16 }, +/* 1831 */ { MAD_F(0x05780290) /* 0.341799321 */, 16 }, +/* 1832 */ { MAD_F(0x05790793) /* 0.342048241 */, 16 }, +/* 1833 */ { MAD_F(0x057a0ca3) /* 0.342297207 */, 16 }, +/* 1834 */ { MAD_F(0x057b11be) /* 0.342546219 */, 16 }, +/* 1835 */ { MAD_F(0x057c16e6) /* 0.342795275 */, 16 }, +/* 1836 */ { MAD_F(0x057d1c1a) /* 0.343044377 */, 16 }, +/* 1837 */ { MAD_F(0x057e2159) /* 0.343293524 */, 16 }, +/* 1838 */ { MAD_F(0x057f26a6) /* 0.343542717 */, 16 }, +/* 1839 */ { MAD_F(0x05802bfe) /* 0.343791954 */, 16 }, + +/* 1840 */ { MAD_F(0x05813162) /* 0.344041237 */, 16 }, +/* 1841 */ { MAD_F(0x058236d2) /* 0.344290564 */, 16 }, +/* 1842 */ { MAD_F(0x05833c4f) /* 0.344539937 */, 16 }, +/* 1843 */ { MAD_F(0x058441d8) /* 0.344789356 */, 16 }, +/* 1844 */ { MAD_F(0x0585476c) /* 0.345038819 */, 16 }, +/* 1845 */ { MAD_F(0x05864d0d) /* 0.345288327 */, 16 }, +/* 1846 */ { MAD_F(0x058752ba) /* 0.345537880 */, 16 }, +/* 1847 */ { MAD_F(0x05885873) /* 0.345787479 */, 16 }, +/* 1848 */ { MAD_F(0x05895e39) /* 0.346037122 */, 16 }, +/* 1849 */ { MAD_F(0x058a640a) /* 0.346286811 */, 16 }, +/* 1850 */ { MAD_F(0x058b69e7) /* 0.346536545 */, 16 }, +/* 1851 */ { MAD_F(0x058c6fd1) /* 0.346786323 */, 16 }, +/* 1852 */ { MAD_F(0x058d75c6) /* 0.347036147 */, 16 }, +/* 1853 */ { MAD_F(0x058e7bc8) /* 0.347286015 */, 16 }, +/* 1854 */ { MAD_F(0x058f81d5) /* 0.347535929 */, 16 }, +/* 1855 */ { MAD_F(0x059087ef) /* 0.347785887 */, 16 }, + +/* 1856 */ { MAD_F(0x05918e15) /* 0.348035890 */, 16 }, +/* 1857 */ { MAD_F(0x05929447) /* 0.348285939 */, 16 }, +/* 1858 */ { MAD_F(0x05939a84) /* 0.348536032 */, 16 }, +/* 1859 */ { MAD_F(0x0594a0ce) /* 0.348786170 */, 16 }, +/* 1860 */ { MAD_F(0x0595a724) /* 0.349036353 */, 16 }, +/* 1861 */ { MAD_F(0x0596ad86) /* 0.349286580 */, 16 }, +/* 1862 */ { MAD_F(0x0597b3f4) /* 0.349536853 */, 16 }, +/* 1863 */ { MAD_F(0x0598ba6e) /* 0.349787170 */, 16 }, +/* 1864 */ { MAD_F(0x0599c0f4) /* 0.350037532 */, 16 }, +/* 1865 */ { MAD_F(0x059ac786) /* 0.350287939 */, 16 }, +/* 1866 */ { MAD_F(0x059bce25) /* 0.350538391 */, 16 }, +/* 1867 */ { MAD_F(0x059cd4cf) /* 0.350788887 */, 16 }, +/* 1868 */ { MAD_F(0x059ddb85) /* 0.351039428 */, 16 }, +/* 1869 */ { MAD_F(0x059ee247) /* 0.351290014 */, 16 }, +/* 1870 */ { MAD_F(0x059fe915) /* 0.351540645 */, 16 }, +/* 1871 */ { MAD_F(0x05a0efef) /* 0.351791320 */, 16 }, + +/* 1872 */ { MAD_F(0x05a1f6d5) /* 0.352042040 */, 16 }, +/* 1873 */ { MAD_F(0x05a2fdc7) /* 0.352292804 */, 16 }, +/* 1874 */ { MAD_F(0x05a404c5) /* 0.352543613 */, 16 }, +/* 1875 */ { MAD_F(0x05a50bcf) /* 0.352794467 */, 16 }, +/* 1876 */ { MAD_F(0x05a612e5) /* 0.353045365 */, 16 }, +/* 1877 */ { MAD_F(0x05a71a07) /* 0.353296308 */, 16 }, +/* 1878 */ { MAD_F(0x05a82135) /* 0.353547296 */, 16 }, +/* 1879 */ { MAD_F(0x05a9286f) /* 0.353798328 */, 16 }, +/* 1880 */ { MAD_F(0x05aa2fb5) /* 0.354049405 */, 16 }, +/* 1881 */ { MAD_F(0x05ab3707) /* 0.354300526 */, 16 }, +/* 1882 */ { MAD_F(0x05ac3e65) /* 0.354551691 */, 16 }, +/* 1883 */ { MAD_F(0x05ad45ce) /* 0.354802901 */, 16 }, +/* 1884 */ { MAD_F(0x05ae4d44) /* 0.355054156 */, 16 }, +/* 1885 */ { MAD_F(0x05af54c6) /* 0.355305455 */, 16 }, +/* 1886 */ { MAD_F(0x05b05c53) /* 0.355556799 */, 16 }, +/* 1887 */ { MAD_F(0x05b163ed) /* 0.355808187 */, 16 }, + +/* 1888 */ { MAD_F(0x05b26b92) /* 0.356059619 */, 16 }, +/* 1889 */ { MAD_F(0x05b37343) /* 0.356311096 */, 16 }, +/* 1890 */ { MAD_F(0x05b47b00) /* 0.356562617 */, 16 }, +/* 1891 */ { MAD_F(0x05b582c9) /* 0.356814182 */, 16 }, +/* 1892 */ { MAD_F(0x05b68a9e) /* 0.357065792 */, 16 }, +/* 1893 */ { MAD_F(0x05b7927f) /* 0.357317446 */, 16 }, +/* 1894 */ { MAD_F(0x05b89a6c) /* 0.357569145 */, 16 }, +/* 1895 */ { MAD_F(0x05b9a265) /* 0.357820887 */, 16 }, +/* 1896 */ { MAD_F(0x05baaa69) /* 0.358072674 */, 16 }, +/* 1897 */ { MAD_F(0x05bbb27a) /* 0.358324506 */, 16 }, +/* 1898 */ { MAD_F(0x05bcba96) /* 0.358576381 */, 16 }, +/* 1899 */ { MAD_F(0x05bdc2be) /* 0.358828301 */, 16 }, +/* 1900 */ { MAD_F(0x05becaf2) /* 0.359080265 */, 16 }, +/* 1901 */ { MAD_F(0x05bfd332) /* 0.359332273 */, 16 }, +/* 1902 */ { MAD_F(0x05c0db7e) /* 0.359584326 */, 16 }, +/* 1903 */ { MAD_F(0x05c1e3d6) /* 0.359836423 */, 16 }, + +/* 1904 */ { MAD_F(0x05c2ec39) /* 0.360088563 */, 16 }, +/* 1905 */ { MAD_F(0x05c3f4a9) /* 0.360340748 */, 16 }, +/* 1906 */ { MAD_F(0x05c4fd24) /* 0.360592977 */, 16 }, +/* 1907 */ { MAD_F(0x05c605ab) /* 0.360845251 */, 16 }, +/* 1908 */ { MAD_F(0x05c70e3e) /* 0.361097568 */, 16 }, +/* 1909 */ { MAD_F(0x05c816dd) /* 0.361349929 */, 16 }, +/* 1910 */ { MAD_F(0x05c91f87) /* 0.361602335 */, 16 }, +/* 1911 */ { MAD_F(0x05ca283e) /* 0.361854784 */, 16 }, +/* 1912 */ { MAD_F(0x05cb3100) /* 0.362107278 */, 16 }, +/* 1913 */ { MAD_F(0x05cc39ce) /* 0.362359815 */, 16 }, +/* 1914 */ { MAD_F(0x05cd42a8) /* 0.362612397 */, 16 }, +/* 1915 */ { MAD_F(0x05ce4b8d) /* 0.362865022 */, 16 }, +/* 1916 */ { MAD_F(0x05cf547f) /* 0.363117692 */, 16 }, +/* 1917 */ { MAD_F(0x05d05d7c) /* 0.363370405 */, 16 }, +/* 1918 */ { MAD_F(0x05d16685) /* 0.363623163 */, 16 }, +/* 1919 */ { MAD_F(0x05d26f9a) /* 0.363875964 */, 16 }, + +/* 1920 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 16 }, +/* 1921 */ { MAD_F(0x05d481e7) /* 0.364381698 */, 16 }, +/* 1922 */ { MAD_F(0x05d58b1f) /* 0.364634632 */, 16 }, +/* 1923 */ { MAD_F(0x05d69463) /* 0.364887608 */, 16 }, +/* 1924 */ { MAD_F(0x05d79db3) /* 0.365140629 */, 16 }, +/* 1925 */ { MAD_F(0x05d8a70f) /* 0.365393694 */, 16 }, +/* 1926 */ { MAD_F(0x05d9b076) /* 0.365646802 */, 16 }, +/* 1927 */ { MAD_F(0x05dab9e9) /* 0.365899955 */, 16 }, +/* 1928 */ { MAD_F(0x05dbc368) /* 0.366153151 */, 16 }, +/* 1929 */ { MAD_F(0x05dcccf2) /* 0.366406390 */, 16 }, +/* 1930 */ { MAD_F(0x05ddd689) /* 0.366659674 */, 16 }, +/* 1931 */ { MAD_F(0x05dee02b) /* 0.366913001 */, 16 }, +/* 1932 */ { MAD_F(0x05dfe9d8) /* 0.367166372 */, 16 }, +/* 1933 */ { MAD_F(0x05e0f392) /* 0.367419787 */, 16 }, +/* 1934 */ { MAD_F(0x05e1fd57) /* 0.367673246 */, 16 }, +/* 1935 */ { MAD_F(0x05e30728) /* 0.367926748 */, 16 }, + +/* 1936 */ { MAD_F(0x05e41105) /* 0.368180294 */, 16 }, +/* 1937 */ { MAD_F(0x05e51aed) /* 0.368433883 */, 16 }, +/* 1938 */ { MAD_F(0x05e624e1) /* 0.368687517 */, 16 }, +/* 1939 */ { MAD_F(0x05e72ee1) /* 0.368941193 */, 16 }, +/* 1940 */ { MAD_F(0x05e838ed) /* 0.369194914 */, 16 }, +/* 1941 */ { MAD_F(0x05e94304) /* 0.369448678 */, 16 }, +/* 1942 */ { MAD_F(0x05ea4d27) /* 0.369702485 */, 16 }, +/* 1943 */ { MAD_F(0x05eb5756) /* 0.369956336 */, 16 }, +/* 1944 */ { MAD_F(0x05ec6190) /* 0.370210231 */, 16 }, +/* 1945 */ { MAD_F(0x05ed6bd6) /* 0.370464169 */, 16 }, +/* 1946 */ { MAD_F(0x05ee7628) /* 0.370718151 */, 16 }, +/* 1947 */ { MAD_F(0x05ef8085) /* 0.370972177 */, 16 }, +/* 1948 */ { MAD_F(0x05f08aee) /* 0.371226245 */, 16 }, +/* 1949 */ { MAD_F(0x05f19563) /* 0.371480358 */, 16 }, +/* 1950 */ { MAD_F(0x05f29fe3) /* 0.371734513 */, 16 }, +/* 1951 */ { MAD_F(0x05f3aa6f) /* 0.371988712 */, 16 }, + +/* 1952 */ { MAD_F(0x05f4b507) /* 0.372242955 */, 16 }, +/* 1953 */ { MAD_F(0x05f5bfab) /* 0.372497241 */, 16 }, +/* 1954 */ { MAD_F(0x05f6ca5a) /* 0.372751570 */, 16 }, +/* 1955 */ { MAD_F(0x05f7d514) /* 0.373005943 */, 16 }, +/* 1956 */ { MAD_F(0x05f8dfdb) /* 0.373260359 */, 16 }, +/* 1957 */ { MAD_F(0x05f9eaad) /* 0.373514819 */, 16 }, +/* 1958 */ { MAD_F(0x05faf58a) /* 0.373769322 */, 16 }, +/* 1959 */ { MAD_F(0x05fc0073) /* 0.374023868 */, 16 }, +/* 1960 */ { MAD_F(0x05fd0b68) /* 0.374278458 */, 16 }, +/* 1961 */ { MAD_F(0x05fe1669) /* 0.374533091 */, 16 }, +/* 1962 */ { MAD_F(0x05ff2175) /* 0.374787767 */, 16 }, +/* 1963 */ { MAD_F(0x06002c8d) /* 0.375042486 */, 16 }, +/* 1964 */ { MAD_F(0x060137b0) /* 0.375297249 */, 16 }, +/* 1965 */ { MAD_F(0x060242df) /* 0.375552055 */, 16 }, +/* 1966 */ { MAD_F(0x06034e19) /* 0.375806904 */, 16 }, +/* 1967 */ { MAD_F(0x0604595f) /* 0.376061796 */, 16 }, + +/* 1968 */ { MAD_F(0x060564b1) /* 0.376316732 */, 16 }, +/* 1969 */ { MAD_F(0x0606700f) /* 0.376571710 */, 16 }, +/* 1970 */ { MAD_F(0x06077b77) /* 0.376826732 */, 16 }, +/* 1971 */ { MAD_F(0x060886ec) /* 0.377081797 */, 16 }, +/* 1972 */ { MAD_F(0x0609926c) /* 0.377336905 */, 16 }, +/* 1973 */ { MAD_F(0x060a9df8) /* 0.377592057 */, 16 }, +/* 1974 */ { MAD_F(0x060ba98f) /* 0.377847251 */, 16 }, +/* 1975 */ { MAD_F(0x060cb532) /* 0.378102489 */, 16 }, +/* 1976 */ { MAD_F(0x060dc0e0) /* 0.378357769 */, 16 }, +/* 1977 */ { MAD_F(0x060ecc9a) /* 0.378613093 */, 16 }, +/* 1978 */ { MAD_F(0x060fd860) /* 0.378868460 */, 16 }, +/* 1979 */ { MAD_F(0x0610e431) /* 0.379123870 */, 16 }, +/* 1980 */ { MAD_F(0x0611f00d) /* 0.379379322 */, 16 }, +/* 1981 */ { MAD_F(0x0612fbf5) /* 0.379634818 */, 16 }, +/* 1982 */ { MAD_F(0x061407e9) /* 0.379890357 */, 16 }, +/* 1983 */ { MAD_F(0x061513e8) /* 0.380145939 */, 16 }, + +/* 1984 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 16 }, +/* 1985 */ { MAD_F(0x06172c09) /* 0.380657231 */, 16 }, +/* 1986 */ { MAD_F(0x0618382b) /* 0.380912942 */, 16 }, +/* 1987 */ { MAD_F(0x06194458) /* 0.381168695 */, 16 }, +/* 1988 */ { MAD_F(0x061a5091) /* 0.381424492 */, 16 }, +/* 1989 */ { MAD_F(0x061b5cd5) /* 0.381680331 */, 16 }, +/* 1990 */ { MAD_F(0x061c6925) /* 0.381936213 */, 16 }, +/* 1991 */ { MAD_F(0x061d7581) /* 0.382192138 */, 16 }, +/* 1992 */ { MAD_F(0x061e81e8) /* 0.382448106 */, 16 }, +/* 1993 */ { MAD_F(0x061f8e5a) /* 0.382704117 */, 16 }, +/* 1994 */ { MAD_F(0x06209ad8) /* 0.382960171 */, 16 }, +/* 1995 */ { MAD_F(0x0621a761) /* 0.383216267 */, 16 }, +/* 1996 */ { MAD_F(0x0622b3f6) /* 0.383472406 */, 16 }, +/* 1997 */ { MAD_F(0x0623c096) /* 0.383728588 */, 16 }, +/* 1998 */ { MAD_F(0x0624cd42) /* 0.383984813 */, 16 }, +/* 1999 */ { MAD_F(0x0625d9f9) /* 0.384241080 */, 16 }, + +/* 2000 */ { MAD_F(0x0626e6bc) /* 0.384497391 */, 16 }, +/* 2001 */ { MAD_F(0x0627f38a) /* 0.384753744 */, 16 }, +/* 2002 */ { MAD_F(0x06290064) /* 0.385010139 */, 16 }, +/* 2003 */ { MAD_F(0x062a0d49) /* 0.385266578 */, 16 }, +/* 2004 */ { MAD_F(0x062b1a3a) /* 0.385523059 */, 16 }, +/* 2005 */ { MAD_F(0x062c2736) /* 0.385779582 */, 16 }, +/* 2006 */ { MAD_F(0x062d343d) /* 0.386036149 */, 16 }, +/* 2007 */ { MAD_F(0x062e4150) /* 0.386292758 */, 16 }, +/* 2008 */ { MAD_F(0x062f4e6f) /* 0.386549409 */, 16 }, +/* 2009 */ { MAD_F(0x06305b99) /* 0.386806104 */, 16 }, +/* 2010 */ { MAD_F(0x063168ce) /* 0.387062840 */, 16 }, +/* 2011 */ { MAD_F(0x0632760f) /* 0.387319620 */, 16 }, +/* 2012 */ { MAD_F(0x0633835b) /* 0.387576442 */, 16 }, +/* 2013 */ { MAD_F(0x063490b2) /* 0.387833306 */, 16 }, +/* 2014 */ { MAD_F(0x06359e15) /* 0.388090213 */, 16 }, +/* 2015 */ { MAD_F(0x0636ab83) /* 0.388347163 */, 16 }, + +/* 2016 */ { MAD_F(0x0637b8fd) /* 0.388604155 */, 16 }, +/* 2017 */ { MAD_F(0x0638c682) /* 0.388861190 */, 16 }, +/* 2018 */ { MAD_F(0x0639d413) /* 0.389118267 */, 16 }, +/* 2019 */ { MAD_F(0x063ae1af) /* 0.389375386 */, 16 }, +/* 2020 */ { MAD_F(0x063bef56) /* 0.389632548 */, 16 }, +/* 2021 */ { MAD_F(0x063cfd09) /* 0.389889752 */, 16 }, +/* 2022 */ { MAD_F(0x063e0ac7) /* 0.390146999 */, 16 }, +/* 2023 */ { MAD_F(0x063f1891) /* 0.390404289 */, 16 }, +/* 2024 */ { MAD_F(0x06402666) /* 0.390661620 */, 16 }, +/* 2025 */ { MAD_F(0x06413446) /* 0.390918994 */, 16 }, +/* 2026 */ { MAD_F(0x06424232) /* 0.391176411 */, 16 }, +/* 2027 */ { MAD_F(0x06435029) /* 0.391433869 */, 16 }, +/* 2028 */ { MAD_F(0x06445e2b) /* 0.391691371 */, 16 }, +/* 2029 */ { MAD_F(0x06456c39) /* 0.391948914 */, 16 }, +/* 2030 */ { MAD_F(0x06467a52) /* 0.392206500 */, 16 }, +/* 2031 */ { MAD_F(0x06478877) /* 0.392464128 */, 16 }, + +/* 2032 */ { MAD_F(0x064896a7) /* 0.392721798 */, 16 }, +/* 2033 */ { MAD_F(0x0649a4e2) /* 0.392979511 */, 16 }, +/* 2034 */ { MAD_F(0x064ab328) /* 0.393237266 */, 16 }, +/* 2035 */ { MAD_F(0x064bc17a) /* 0.393495063 */, 16 }, +/* 2036 */ { MAD_F(0x064ccfd8) /* 0.393752902 */, 16 }, +/* 2037 */ { MAD_F(0x064dde40) /* 0.394010784 */, 16 }, +/* 2038 */ { MAD_F(0x064eecb4) /* 0.394268707 */, 16 }, +/* 2039 */ { MAD_F(0x064ffb33) /* 0.394526673 */, 16 }, +/* 2040 */ { MAD_F(0x065109be) /* 0.394784681 */, 16 }, +/* 2041 */ { MAD_F(0x06521854) /* 0.395042732 */, 16 }, +/* 2042 */ { MAD_F(0x065326f5) /* 0.395300824 */, 16 }, +/* 2043 */ { MAD_F(0x065435a1) /* 0.395558959 */, 16 }, +/* 2044 */ { MAD_F(0x06554459) /* 0.395817135 */, 16 }, +/* 2045 */ { MAD_F(0x0656531c) /* 0.396075354 */, 16 }, +/* 2046 */ { MAD_F(0x065761ea) /* 0.396333615 */, 16 }, +/* 2047 */ { MAD_F(0x065870c4) /* 0.396591918 */, 16 }, + +/* 2048 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 16 }, +/* 2049 */ { MAD_F(0x065a8e99) /* 0.397108650 */, 16 }, +/* 2050 */ { MAD_F(0x065b9d95) /* 0.397367079 */, 16 }, +/* 2051 */ { MAD_F(0x065cac9c) /* 0.397625550 */, 16 }, +/* 2052 */ { MAD_F(0x065dbbae) /* 0.397884063 */, 16 }, +/* 2053 */ { MAD_F(0x065ecacb) /* 0.398142619 */, 16 }, +/* 2054 */ { MAD_F(0x065fd9f4) /* 0.398401216 */, 16 }, +/* 2055 */ { MAD_F(0x0660e928) /* 0.398659855 */, 16 }, +/* 2056 */ { MAD_F(0x0661f867) /* 0.398918536 */, 16 }, +/* 2057 */ { MAD_F(0x066307b1) /* 0.399177259 */, 16 }, +/* 2058 */ { MAD_F(0x06641707) /* 0.399436024 */, 16 }, +/* 2059 */ { MAD_F(0x06652668) /* 0.399694831 */, 16 }, +/* 2060 */ { MAD_F(0x066635d4) /* 0.399953679 */, 16 }, +/* 2061 */ { MAD_F(0x0667454c) /* 0.400212570 */, 16 }, +/* 2062 */ { MAD_F(0x066854ce) /* 0.400471503 */, 16 }, +/* 2063 */ { MAD_F(0x0669645c) /* 0.400730477 */, 16 }, + +/* 2064 */ { MAD_F(0x066a73f5) /* 0.400989493 */, 16 }, +/* 2065 */ { MAD_F(0x066b839a) /* 0.401248551 */, 16 }, +/* 2066 */ { MAD_F(0x066c9349) /* 0.401507651 */, 16 }, +/* 2067 */ { MAD_F(0x066da304) /* 0.401766793 */, 16 }, +/* 2068 */ { MAD_F(0x066eb2ca) /* 0.402025976 */, 16 }, +/* 2069 */ { MAD_F(0x066fc29b) /* 0.402285202 */, 16 }, +/* 2070 */ { MAD_F(0x0670d278) /* 0.402544469 */, 16 }, +/* 2071 */ { MAD_F(0x0671e25f) /* 0.402803777 */, 16 }, +/* 2072 */ { MAD_F(0x0672f252) /* 0.403063128 */, 16 }, +/* 2073 */ { MAD_F(0x06740250) /* 0.403322520 */, 16 }, +/* 2074 */ { MAD_F(0x0675125a) /* 0.403581954 */, 16 }, +/* 2075 */ { MAD_F(0x0676226e) /* 0.403841430 */, 16 }, +/* 2076 */ { MAD_F(0x0677328e) /* 0.404100947 */, 16 }, +/* 2077 */ { MAD_F(0x067842b9) /* 0.404360506 */, 16 }, +/* 2078 */ { MAD_F(0x067952ef) /* 0.404620107 */, 16 }, +/* 2079 */ { MAD_F(0x067a6330) /* 0.404879749 */, 16 }, + +/* 2080 */ { MAD_F(0x067b737c) /* 0.405139433 */, 16 }, +/* 2081 */ { MAD_F(0x067c83d4) /* 0.405399159 */, 16 }, +/* 2082 */ { MAD_F(0x067d9436) /* 0.405658926 */, 16 }, +/* 2083 */ { MAD_F(0x067ea4a4) /* 0.405918735 */, 16 }, +/* 2084 */ { MAD_F(0x067fb51d) /* 0.406178585 */, 16 }, +/* 2085 */ { MAD_F(0x0680c5a2) /* 0.406438477 */, 16 }, +/* 2086 */ { MAD_F(0x0681d631) /* 0.406698410 */, 16 }, +/* 2087 */ { MAD_F(0x0682e6cb) /* 0.406958385 */, 16 }, +/* 2088 */ { MAD_F(0x0683f771) /* 0.407218402 */, 16 }, +/* 2089 */ { MAD_F(0x06850822) /* 0.407478460 */, 16 }, +/* 2090 */ { MAD_F(0x068618de) /* 0.407738559 */, 16 }, +/* 2091 */ { MAD_F(0x068729a5) /* 0.407998700 */, 16 }, +/* 2092 */ { MAD_F(0x06883a77) /* 0.408258883 */, 16 }, +/* 2093 */ { MAD_F(0x06894b55) /* 0.408519107 */, 16 }, +/* 2094 */ { MAD_F(0x068a5c3d) /* 0.408779372 */, 16 }, +/* 2095 */ { MAD_F(0x068b6d31) /* 0.409039679 */, 16 }, + +/* 2096 */ { MAD_F(0x068c7e2f) /* 0.409300027 */, 16 }, +/* 2097 */ { MAD_F(0x068d8f39) /* 0.409560417 */, 16 }, +/* 2098 */ { MAD_F(0x068ea04e) /* 0.409820848 */, 16 }, +/* 2099 */ { MAD_F(0x068fb16e) /* 0.410081321 */, 16 }, +/* 2100 */ { MAD_F(0x0690c299) /* 0.410341834 */, 16 }, +/* 2101 */ { MAD_F(0x0691d3cf) /* 0.410602390 */, 16 }, +/* 2102 */ { MAD_F(0x0692e511) /* 0.410862986 */, 16 }, +/* 2103 */ { MAD_F(0x0693f65d) /* 0.411123624 */, 16 }, +/* 2104 */ { MAD_F(0x069507b5) /* 0.411384303 */, 16 }, +/* 2105 */ { MAD_F(0x06961917) /* 0.411645024 */, 16 }, +/* 2106 */ { MAD_F(0x06972a85) /* 0.411905785 */, 16 }, +/* 2107 */ { MAD_F(0x06983bfe) /* 0.412166588 */, 16 }, +/* 2108 */ { MAD_F(0x06994d82) /* 0.412427433 */, 16 }, +/* 2109 */ { MAD_F(0x069a5f11) /* 0.412688318 */, 16 }, +/* 2110 */ { MAD_F(0x069b70ab) /* 0.412949245 */, 16 }, +/* 2111 */ { MAD_F(0x069c8250) /* 0.413210213 */, 16 }, + +/* 2112 */ { MAD_F(0x069d9400) /* 0.413471222 */, 16 }, +/* 2113 */ { MAD_F(0x069ea5bb) /* 0.413732273 */, 16 }, +/* 2114 */ { MAD_F(0x069fb781) /* 0.413993364 */, 16 }, +/* 2115 */ { MAD_F(0x06a0c953) /* 0.414254497 */, 16 }, +/* 2116 */ { MAD_F(0x06a1db2f) /* 0.414515671 */, 16 }, +/* 2117 */ { MAD_F(0x06a2ed16) /* 0.414776886 */, 16 }, +/* 2118 */ { MAD_F(0x06a3ff09) /* 0.415038142 */, 16 }, +/* 2119 */ { MAD_F(0x06a51106) /* 0.415299440 */, 16 }, +/* 2120 */ { MAD_F(0x06a6230f) /* 0.415560778 */, 16 }, +/* 2121 */ { MAD_F(0x06a73522) /* 0.415822157 */, 16 }, +/* 2122 */ { MAD_F(0x06a84741) /* 0.416083578 */, 16 }, +/* 2123 */ { MAD_F(0x06a9596a) /* 0.416345040 */, 16 }, +/* 2124 */ { MAD_F(0x06aa6b9f) /* 0.416606542 */, 16 }, +/* 2125 */ { MAD_F(0x06ab7ddf) /* 0.416868086 */, 16 }, +/* 2126 */ { MAD_F(0x06ac9029) /* 0.417129671 */, 16 }, +/* 2127 */ { MAD_F(0x06ada27f) /* 0.417391297 */, 16 }, + +/* 2128 */ { MAD_F(0x06aeb4e0) /* 0.417652964 */, 16 }, +/* 2129 */ { MAD_F(0x06afc74b) /* 0.417914672 */, 16 }, +/* 2130 */ { MAD_F(0x06b0d9c2) /* 0.418176420 */, 16 }, +/* 2131 */ { MAD_F(0x06b1ec43) /* 0.418438210 */, 16 }, +/* 2132 */ { MAD_F(0x06b2fed0) /* 0.418700041 */, 16 }, +/* 2133 */ { MAD_F(0x06b41168) /* 0.418961912 */, 16 }, +/* 2134 */ { MAD_F(0x06b5240a) /* 0.419223825 */, 16 }, +/* 2135 */ { MAD_F(0x06b636b8) /* 0.419485778 */, 16 }, +/* 2136 */ { MAD_F(0x06b74971) /* 0.419747773 */, 16 }, +/* 2137 */ { MAD_F(0x06b85c34) /* 0.420009808 */, 16 }, +/* 2138 */ { MAD_F(0x06b96f03) /* 0.420271884 */, 16 }, +/* 2139 */ { MAD_F(0x06ba81dc) /* 0.420534001 */, 16 }, +/* 2140 */ { MAD_F(0x06bb94c1) /* 0.420796159 */, 16 }, +/* 2141 */ { MAD_F(0x06bca7b0) /* 0.421058358 */, 16 }, +/* 2142 */ { MAD_F(0x06bdbaaa) /* 0.421320597 */, 16 }, +/* 2143 */ { MAD_F(0x06becdb0) /* 0.421582878 */, 16 }, + +/* 2144 */ { MAD_F(0x06bfe0c0) /* 0.421845199 */, 16 }, +/* 2145 */ { MAD_F(0x06c0f3db) /* 0.422107561 */, 16 }, +/* 2146 */ { MAD_F(0x06c20702) /* 0.422369964 */, 16 }, +/* 2147 */ { MAD_F(0x06c31a33) /* 0.422632407 */, 16 }, +/* 2148 */ { MAD_F(0x06c42d6f) /* 0.422894891 */, 16 }, +/* 2149 */ { MAD_F(0x06c540b6) /* 0.423157416 */, 16 }, +/* 2150 */ { MAD_F(0x06c65408) /* 0.423419982 */, 16 }, +/* 2151 */ { MAD_F(0x06c76765) /* 0.423682588 */, 16 }, +/* 2152 */ { MAD_F(0x06c87acc) /* 0.423945235 */, 16 }, +/* 2153 */ { MAD_F(0x06c98e3f) /* 0.424207923 */, 16 }, +/* 2154 */ { MAD_F(0x06caa1bd) /* 0.424470652 */, 16 }, +/* 2155 */ { MAD_F(0x06cbb545) /* 0.424733421 */, 16 }, +/* 2156 */ { MAD_F(0x06ccc8d9) /* 0.424996230 */, 16 }, +/* 2157 */ { MAD_F(0x06cddc77) /* 0.425259081 */, 16 }, +/* 2158 */ { MAD_F(0x06cef020) /* 0.425521972 */, 16 }, +/* 2159 */ { MAD_F(0x06d003d4) /* 0.425784903 */, 16 }, + +/* 2160 */ { MAD_F(0x06d11794) /* 0.426047876 */, 16 }, +/* 2161 */ { MAD_F(0x06d22b5e) /* 0.426310889 */, 16 }, +/* 2162 */ { MAD_F(0x06d33f32) /* 0.426573942 */, 16 }, +/* 2163 */ { MAD_F(0x06d45312) /* 0.426837036 */, 16 }, +/* 2164 */ { MAD_F(0x06d566fd) /* 0.427100170 */, 16 }, +/* 2165 */ { MAD_F(0x06d67af2) /* 0.427363345 */, 16 }, +/* 2166 */ { MAD_F(0x06d78ef3) /* 0.427626561 */, 16 }, +/* 2167 */ { MAD_F(0x06d8a2fe) /* 0.427889817 */, 16 }, +/* 2168 */ { MAD_F(0x06d9b714) /* 0.428153114 */, 16 }, +/* 2169 */ { MAD_F(0x06dacb35) /* 0.428416451 */, 16 }, +/* 2170 */ { MAD_F(0x06dbdf61) /* 0.428679828 */, 16 }, +/* 2171 */ { MAD_F(0x06dcf398) /* 0.428943246 */, 16 }, +/* 2172 */ { MAD_F(0x06de07d9) /* 0.429206704 */, 16 }, +/* 2173 */ { MAD_F(0x06df1c26) /* 0.429470203 */, 16 }, +/* 2174 */ { MAD_F(0x06e0307d) /* 0.429733743 */, 16 }, +/* 2175 */ { MAD_F(0x06e144df) /* 0.429997322 */, 16 }, + +/* 2176 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 16 }, +/* 2177 */ { MAD_F(0x06e36dc4) /* 0.430524603 */, 16 }, +/* 2178 */ { MAD_F(0x06e48246) /* 0.430788304 */, 16 }, +/* 2179 */ { MAD_F(0x06e596d4) /* 0.431052045 */, 16 }, +/* 2180 */ { MAD_F(0x06e6ab6c) /* 0.431315826 */, 16 }, +/* 2181 */ { MAD_F(0x06e7c00f) /* 0.431579648 */, 16 }, +/* 2182 */ { MAD_F(0x06e8d4bd) /* 0.431843511 */, 16 }, +/* 2183 */ { MAD_F(0x06e9e976) /* 0.432107413 */, 16 }, +/* 2184 */ { MAD_F(0x06eafe3a) /* 0.432371356 */, 16 }, +/* 2185 */ { MAD_F(0x06ec1308) /* 0.432635339 */, 16 }, +/* 2186 */ { MAD_F(0x06ed27e2) /* 0.432899362 */, 16 }, +/* 2187 */ { MAD_F(0x06ee3cc6) /* 0.433163426 */, 16 }, +/* 2188 */ { MAD_F(0x06ef51b4) /* 0.433427530 */, 16 }, +/* 2189 */ { MAD_F(0x06f066ae) /* 0.433691674 */, 16 }, +/* 2190 */ { MAD_F(0x06f17bb3) /* 0.433955859 */, 16 }, +/* 2191 */ { MAD_F(0x06f290c2) /* 0.434220083 */, 16 }, + +/* 2192 */ { MAD_F(0x06f3a5dc) /* 0.434484348 */, 16 }, +/* 2193 */ { MAD_F(0x06f4bb01) /* 0.434748653 */, 16 }, +/* 2194 */ { MAD_F(0x06f5d030) /* 0.435012998 */, 16 }, +/* 2195 */ { MAD_F(0x06f6e56b) /* 0.435277383 */, 16 }, +/* 2196 */ { MAD_F(0x06f7fab0) /* 0.435541809 */, 16 }, +/* 2197 */ { MAD_F(0x06f91000) /* 0.435806274 */, 16 }, +/* 2198 */ { MAD_F(0x06fa255a) /* 0.436070780 */, 16 }, +/* 2199 */ { MAD_F(0x06fb3ac0) /* 0.436335326 */, 16 }, +/* 2200 */ { MAD_F(0x06fc5030) /* 0.436599912 */, 16 }, +/* 2201 */ { MAD_F(0x06fd65ab) /* 0.436864538 */, 16 }, +/* 2202 */ { MAD_F(0x06fe7b31) /* 0.437129204 */, 16 }, +/* 2203 */ { MAD_F(0x06ff90c2) /* 0.437393910 */, 16 }, +/* 2204 */ { MAD_F(0x0700a65d) /* 0.437658657 */, 16 }, +/* 2205 */ { MAD_F(0x0701bc03) /* 0.437923443 */, 16 }, +/* 2206 */ { MAD_F(0x0702d1b4) /* 0.438188269 */, 16 }, +/* 2207 */ { MAD_F(0x0703e76f) /* 0.438453136 */, 16 }, + +/* 2208 */ { MAD_F(0x0704fd35) /* 0.438718042 */, 16 }, +/* 2209 */ { MAD_F(0x07061306) /* 0.438982988 */, 16 }, +/* 2210 */ { MAD_F(0x070728e2) /* 0.439247975 */, 16 }, +/* 2211 */ { MAD_F(0x07083ec9) /* 0.439513001 */, 16 }, +/* 2212 */ { MAD_F(0x070954ba) /* 0.439778067 */, 16 }, +/* 2213 */ { MAD_F(0x070a6ab6) /* 0.440043173 */, 16 }, +/* 2214 */ { MAD_F(0x070b80bc) /* 0.440308320 */, 16 }, +/* 2215 */ { MAD_F(0x070c96ce) /* 0.440573506 */, 16 }, +/* 2216 */ { MAD_F(0x070dacea) /* 0.440838732 */, 16 }, +/* 2217 */ { MAD_F(0x070ec310) /* 0.441103997 */, 16 }, +/* 2218 */ { MAD_F(0x070fd942) /* 0.441369303 */, 16 }, +/* 2219 */ { MAD_F(0x0710ef7e) /* 0.441634649 */, 16 }, +/* 2220 */ { MAD_F(0x071205c5) /* 0.441900034 */, 16 }, +/* 2221 */ { MAD_F(0x07131c17) /* 0.442165460 */, 16 }, +/* 2222 */ { MAD_F(0x07143273) /* 0.442430925 */, 16 }, +/* 2223 */ { MAD_F(0x071548da) /* 0.442696430 */, 16 }, + +/* 2224 */ { MAD_F(0x07165f4b) /* 0.442961975 */, 16 }, +/* 2225 */ { MAD_F(0x071775c8) /* 0.443227559 */, 16 }, +/* 2226 */ { MAD_F(0x07188c4f) /* 0.443493184 */, 16 }, +/* 2227 */ { MAD_F(0x0719a2e0) /* 0.443758848 */, 16 }, +/* 2228 */ { MAD_F(0x071ab97d) /* 0.444024552 */, 16 }, +/* 2229 */ { MAD_F(0x071bd024) /* 0.444290296 */, 16 }, +/* 2230 */ { MAD_F(0x071ce6d6) /* 0.444556079 */, 16 }, +/* 2231 */ { MAD_F(0x071dfd92) /* 0.444821902 */, 16 }, +/* 2232 */ { MAD_F(0x071f1459) /* 0.445087765 */, 16 }, +/* 2233 */ { MAD_F(0x07202b2b) /* 0.445353668 */, 16 }, +/* 2234 */ { MAD_F(0x07214207) /* 0.445619610 */, 16 }, +/* 2235 */ { MAD_F(0x072258ee) /* 0.445885592 */, 16 }, +/* 2236 */ { MAD_F(0x07236fe0) /* 0.446151614 */, 16 }, +/* 2237 */ { MAD_F(0x072486dc) /* 0.446417675 */, 16 }, +/* 2238 */ { MAD_F(0x07259de3) /* 0.446683776 */, 16 }, +/* 2239 */ { MAD_F(0x0726b4f4) /* 0.446949917 */, 16 }, + +/* 2240 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 16 }, +/* 2241 */ { MAD_F(0x0728e338) /* 0.447482317 */, 16 }, +/* 2242 */ { MAD_F(0x0729fa69) /* 0.447748576 */, 16 }, +/* 2243 */ { MAD_F(0x072b11a5) /* 0.448014875 */, 16 }, +/* 2244 */ { MAD_F(0x072c28ec) /* 0.448281214 */, 16 }, +/* 2245 */ { MAD_F(0x072d403d) /* 0.448547592 */, 16 }, +/* 2246 */ { MAD_F(0x072e5799) /* 0.448814010 */, 16 }, +/* 2247 */ { MAD_F(0x072f6f00) /* 0.449080467 */, 16 }, +/* 2248 */ { MAD_F(0x07308671) /* 0.449346964 */, 16 }, +/* 2249 */ { MAD_F(0x07319ded) /* 0.449613501 */, 16 }, +/* 2250 */ { MAD_F(0x0732b573) /* 0.449880076 */, 16 }, +/* 2251 */ { MAD_F(0x0733cd04) /* 0.450146692 */, 16 }, +/* 2252 */ { MAD_F(0x0734e4a0) /* 0.450413347 */, 16 }, +/* 2253 */ { MAD_F(0x0735fc46) /* 0.450680041 */, 16 }, +/* 2254 */ { MAD_F(0x073713f7) /* 0.450946775 */, 16 }, +/* 2255 */ { MAD_F(0x07382bb2) /* 0.451213548 */, 16 }, + +/* 2256 */ { MAD_F(0x07394378) /* 0.451480360 */, 16 }, +/* 2257 */ { MAD_F(0x073a5b49) /* 0.451747213 */, 16 }, +/* 2258 */ { MAD_F(0x073b7324) /* 0.452014104 */, 16 }, +/* 2259 */ { MAD_F(0x073c8b0a) /* 0.452281035 */, 16 }, +/* 2260 */ { MAD_F(0x073da2fa) /* 0.452548005 */, 16 }, +/* 2261 */ { MAD_F(0x073ebaf5) /* 0.452815015 */, 16 }, +/* 2262 */ { MAD_F(0x073fd2fa) /* 0.453082064 */, 16 }, +/* 2263 */ { MAD_F(0x0740eb0a) /* 0.453349152 */, 16 }, +/* 2264 */ { MAD_F(0x07420325) /* 0.453616280 */, 16 }, +/* 2265 */ { MAD_F(0x07431b4a) /* 0.453883447 */, 16 }, +/* 2266 */ { MAD_F(0x0744337a) /* 0.454150653 */, 16 }, +/* 2267 */ { MAD_F(0x07454bb4) /* 0.454417899 */, 16 }, +/* 2268 */ { MAD_F(0x074663f8) /* 0.454685184 */, 16 }, +/* 2269 */ { MAD_F(0x07477c48) /* 0.454952508 */, 16 }, +/* 2270 */ { MAD_F(0x074894a2) /* 0.455219872 */, 16 }, +/* 2271 */ { MAD_F(0x0749ad06) /* 0.455487275 */, 16 }, + +/* 2272 */ { MAD_F(0x074ac575) /* 0.455754717 */, 16 }, +/* 2273 */ { MAD_F(0x074bddee) /* 0.456022198 */, 16 }, +/* 2274 */ { MAD_F(0x074cf672) /* 0.456289719 */, 16 }, +/* 2275 */ { MAD_F(0x074e0f01) /* 0.456557278 */, 16 }, +/* 2276 */ { MAD_F(0x074f279a) /* 0.456824877 */, 16 }, +/* 2277 */ { MAD_F(0x0750403e) /* 0.457092516 */, 16 }, +/* 2278 */ { MAD_F(0x075158ec) /* 0.457360193 */, 16 }, +/* 2279 */ { MAD_F(0x075271a4) /* 0.457627909 */, 16 }, +/* 2280 */ { MAD_F(0x07538a67) /* 0.457895665 */, 16 }, +/* 2281 */ { MAD_F(0x0754a335) /* 0.458163460 */, 16 }, +/* 2282 */ { MAD_F(0x0755bc0d) /* 0.458431294 */, 16 }, +/* 2283 */ { MAD_F(0x0756d4f0) /* 0.458699167 */, 16 }, +/* 2284 */ { MAD_F(0x0757eddd) /* 0.458967079 */, 16 }, +/* 2285 */ { MAD_F(0x075906d5) /* 0.459235030 */, 16 }, +/* 2286 */ { MAD_F(0x075a1fd7) /* 0.459503021 */, 16 }, +/* 2287 */ { MAD_F(0x075b38e3) /* 0.459771050 */, 16 }, + +/* 2288 */ { MAD_F(0x075c51fa) /* 0.460039119 */, 16 }, +/* 2289 */ { MAD_F(0x075d6b1c) /* 0.460307226 */, 16 }, +/* 2290 */ { MAD_F(0x075e8448) /* 0.460575373 */, 16 }, +/* 2291 */ { MAD_F(0x075f9d7f) /* 0.460843559 */, 16 }, +/* 2292 */ { MAD_F(0x0760b6c0) /* 0.461111783 */, 16 }, +/* 2293 */ { MAD_F(0x0761d00b) /* 0.461380047 */, 16 }, +/* 2294 */ { MAD_F(0x0762e961) /* 0.461648350 */, 16 }, +/* 2295 */ { MAD_F(0x076402c1) /* 0.461916691 */, 16 }, +/* 2296 */ { MAD_F(0x07651c2c) /* 0.462185072 */, 16 }, +/* 2297 */ { MAD_F(0x076635a2) /* 0.462453492 */, 16 }, +/* 2298 */ { MAD_F(0x07674f22) /* 0.462721950 */, 16 }, +/* 2299 */ { MAD_F(0x076868ac) /* 0.462990448 */, 16 }, +/* 2300 */ { MAD_F(0x07698240) /* 0.463258984 */, 16 }, +/* 2301 */ { MAD_F(0x076a9be0) /* 0.463527560 */, 16 }, +/* 2302 */ { MAD_F(0x076bb589) /* 0.463796174 */, 16 }, +/* 2303 */ { MAD_F(0x076ccf3d) /* 0.464064827 */, 16 }, + +/* 2304 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 16 }, +/* 2305 */ { MAD_F(0x076f02c5) /* 0.464602250 */, 16 }, +/* 2306 */ { MAD_F(0x07701c98) /* 0.464871020 */, 16 }, +/* 2307 */ { MAD_F(0x07713676) /* 0.465139829 */, 16 }, +/* 2308 */ { MAD_F(0x0772505e) /* 0.465408676 */, 16 }, +/* 2309 */ { MAD_F(0x07736a51) /* 0.465677563 */, 16 }, +/* 2310 */ { MAD_F(0x0774844e) /* 0.465946488 */, 16 }, +/* 2311 */ { MAD_F(0x07759e55) /* 0.466215452 */, 16 }, +/* 2312 */ { MAD_F(0x0776b867) /* 0.466484455 */, 16 }, +/* 2313 */ { MAD_F(0x0777d283) /* 0.466753496 */, 16 }, +/* 2314 */ { MAD_F(0x0778ecaa) /* 0.467022577 */, 16 }, +/* 2315 */ { MAD_F(0x077a06db) /* 0.467291696 */, 16 }, +/* 2316 */ { MAD_F(0x077b2117) /* 0.467560854 */, 16 }, +/* 2317 */ { MAD_F(0x077c3b5d) /* 0.467830050 */, 16 }, +/* 2318 */ { MAD_F(0x077d55ad) /* 0.468099285 */, 16 }, +/* 2319 */ { MAD_F(0x077e7008) /* 0.468368560 */, 16 }, + +/* 2320 */ { MAD_F(0x077f8a6d) /* 0.468637872 */, 16 }, +/* 2321 */ { MAD_F(0x0780a4dc) /* 0.468907224 */, 16 }, +/* 2322 */ { MAD_F(0x0781bf56) /* 0.469176614 */, 16 }, +/* 2323 */ { MAD_F(0x0782d9da) /* 0.469446043 */, 16 }, +/* 2324 */ { MAD_F(0x0783f469) /* 0.469715510 */, 16 }, +/* 2325 */ { MAD_F(0x07850f02) /* 0.469985016 */, 16 }, +/* 2326 */ { MAD_F(0x078629a5) /* 0.470254561 */, 16 }, +/* 2327 */ { MAD_F(0x07874453) /* 0.470524145 */, 16 }, +/* 2328 */ { MAD_F(0x07885f0b) /* 0.470793767 */, 16 }, +/* 2329 */ { MAD_F(0x078979ce) /* 0.471063427 */, 16 }, +/* 2330 */ { MAD_F(0x078a949a) /* 0.471333126 */, 16 }, +/* 2331 */ { MAD_F(0x078baf72) /* 0.471602864 */, 16 }, +/* 2332 */ { MAD_F(0x078cca53) /* 0.471872641 */, 16 }, +/* 2333 */ { MAD_F(0x078de53f) /* 0.472142456 */, 16 }, +/* 2334 */ { MAD_F(0x078f0035) /* 0.472412309 */, 16 }, +/* 2335 */ { MAD_F(0x07901b36) /* 0.472682201 */, 16 }, + +/* 2336 */ { MAD_F(0x07913641) /* 0.472952132 */, 16 }, +/* 2337 */ { MAD_F(0x07925156) /* 0.473222101 */, 16 }, +/* 2338 */ { MAD_F(0x07936c76) /* 0.473492108 */, 16 }, +/* 2339 */ { MAD_F(0x079487a0) /* 0.473762155 */, 16 }, +/* 2340 */ { MAD_F(0x0795a2d4) /* 0.474032239 */, 16 }, +/* 2341 */ { MAD_F(0x0796be13) /* 0.474302362 */, 16 }, +/* 2342 */ { MAD_F(0x0797d95c) /* 0.474572524 */, 16 }, +/* 2343 */ { MAD_F(0x0798f4af) /* 0.474842724 */, 16 }, +/* 2344 */ { MAD_F(0x079a100c) /* 0.475112962 */, 16 }, +/* 2345 */ { MAD_F(0x079b2b74) /* 0.475383239 */, 16 }, +/* 2346 */ { MAD_F(0x079c46e7) /* 0.475653554 */, 16 }, +/* 2347 */ { MAD_F(0x079d6263) /* 0.475923908 */, 16 }, +/* 2348 */ { MAD_F(0x079e7dea) /* 0.476194300 */, 16 }, +/* 2349 */ { MAD_F(0x079f997b) /* 0.476464731 */, 16 }, +/* 2350 */ { MAD_F(0x07a0b516) /* 0.476735200 */, 16 }, +/* 2351 */ { MAD_F(0x07a1d0bc) /* 0.477005707 */, 16 }, + +/* 2352 */ { MAD_F(0x07a2ec6c) /* 0.477276252 */, 16 }, +/* 2353 */ { MAD_F(0x07a40827) /* 0.477546836 */, 16 }, +/* 2354 */ { MAD_F(0x07a523eb) /* 0.477817459 */, 16 }, +/* 2355 */ { MAD_F(0x07a63fba) /* 0.478088119 */, 16 }, +/* 2356 */ { MAD_F(0x07a75b93) /* 0.478358818 */, 16 }, +/* 2357 */ { MAD_F(0x07a87777) /* 0.478629555 */, 16 }, +/* 2358 */ { MAD_F(0x07a99364) /* 0.478900331 */, 16 }, +/* 2359 */ { MAD_F(0x07aaaf5c) /* 0.479171145 */, 16 }, +/* 2360 */ { MAD_F(0x07abcb5f) /* 0.479441997 */, 16 }, +/* 2361 */ { MAD_F(0x07ace76b) /* 0.479712887 */, 16 }, +/* 2362 */ { MAD_F(0x07ae0382) /* 0.479983816 */, 16 }, +/* 2363 */ { MAD_F(0x07af1fa3) /* 0.480254782 */, 16 }, +/* 2364 */ { MAD_F(0x07b03bcf) /* 0.480525787 */, 16 }, +/* 2365 */ { MAD_F(0x07b15804) /* 0.480796831 */, 16 }, +/* 2366 */ { MAD_F(0x07b27444) /* 0.481067912 */, 16 }, +/* 2367 */ { MAD_F(0x07b3908e) /* 0.481339032 */, 16 }, + +/* 2368 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 16 }, +/* 2369 */ { MAD_F(0x07b5c941) /* 0.481881385 */, 16 }, +/* 2370 */ { MAD_F(0x07b6e5aa) /* 0.482152620 */, 16 }, +/* 2371 */ { MAD_F(0x07b8021d) /* 0.482423892 */, 16 }, +/* 2372 */ { MAD_F(0x07b91e9b) /* 0.482695202 */, 16 }, +/* 2373 */ { MAD_F(0x07ba3b22) /* 0.482966551 */, 16 }, +/* 2374 */ { MAD_F(0x07bb57b4) /* 0.483237938 */, 16 }, +/* 2375 */ { MAD_F(0x07bc7450) /* 0.483509362 */, 16 }, +/* 2376 */ { MAD_F(0x07bd90f6) /* 0.483780825 */, 16 }, +/* 2377 */ { MAD_F(0x07beada7) /* 0.484052326 */, 16 }, +/* 2378 */ { MAD_F(0x07bfca61) /* 0.484323865 */, 16 }, +/* 2379 */ { MAD_F(0x07c0e726) /* 0.484595443 */, 16 }, +/* 2380 */ { MAD_F(0x07c203f5) /* 0.484867058 */, 16 }, +/* 2381 */ { MAD_F(0x07c320cf) /* 0.485138711 */, 16 }, +/* 2382 */ { MAD_F(0x07c43db2) /* 0.485410402 */, 16 }, +/* 2383 */ { MAD_F(0x07c55aa0) /* 0.485682131 */, 16 }, + +/* 2384 */ { MAD_F(0x07c67798) /* 0.485953899 */, 16 }, +/* 2385 */ { MAD_F(0x07c7949a) /* 0.486225704 */, 16 }, +/* 2386 */ { MAD_F(0x07c8b1a7) /* 0.486497547 */, 16 }, +/* 2387 */ { MAD_F(0x07c9cebd) /* 0.486769429 */, 16 }, +/* 2388 */ { MAD_F(0x07caebde) /* 0.487041348 */, 16 }, +/* 2389 */ { MAD_F(0x07cc0909) /* 0.487313305 */, 16 }, +/* 2390 */ { MAD_F(0x07cd263e) /* 0.487585300 */, 16 }, +/* 2391 */ { MAD_F(0x07ce437d) /* 0.487857333 */, 16 }, +/* 2392 */ { MAD_F(0x07cf60c7) /* 0.488129404 */, 16 }, +/* 2393 */ { MAD_F(0x07d07e1b) /* 0.488401513 */, 16 }, +/* 2394 */ { MAD_F(0x07d19b79) /* 0.488673660 */, 16 }, +/* 2395 */ { MAD_F(0x07d2b8e1) /* 0.488945845 */, 16 }, +/* 2396 */ { MAD_F(0x07d3d653) /* 0.489218067 */, 16 }, +/* 2397 */ { MAD_F(0x07d4f3cf) /* 0.489490328 */, 16 }, +/* 2398 */ { MAD_F(0x07d61156) /* 0.489762626 */, 16 }, +/* 2399 */ { MAD_F(0x07d72ee6) /* 0.490034962 */, 16 }, + +/* 2400 */ { MAD_F(0x07d84c81) /* 0.490307336 */, 16 }, +/* 2401 */ { MAD_F(0x07d96a26) /* 0.490579748 */, 16 }, +/* 2402 */ { MAD_F(0x07da87d5) /* 0.490852198 */, 16 }, +/* 2403 */ { MAD_F(0x07dba58f) /* 0.491124686 */, 16 }, +/* 2404 */ { MAD_F(0x07dcc352) /* 0.491397211 */, 16 }, +/* 2405 */ { MAD_F(0x07dde120) /* 0.491669774 */, 16 }, +/* 2406 */ { MAD_F(0x07defef7) /* 0.491942375 */, 16 }, +/* 2407 */ { MAD_F(0x07e01cd9) /* 0.492215014 */, 16 }, +/* 2408 */ { MAD_F(0x07e13ac5) /* 0.492487690 */, 16 }, +/* 2409 */ { MAD_F(0x07e258bc) /* 0.492760404 */, 16 }, +/* 2410 */ { MAD_F(0x07e376bc) /* 0.493033156 */, 16 }, +/* 2411 */ { MAD_F(0x07e494c6) /* 0.493305946 */, 16 }, +/* 2412 */ { MAD_F(0x07e5b2db) /* 0.493578773 */, 16 }, +/* 2413 */ { MAD_F(0x07e6d0f9) /* 0.493851638 */, 16 }, +/* 2414 */ { MAD_F(0x07e7ef22) /* 0.494124541 */, 16 }, +/* 2415 */ { MAD_F(0x07e90d55) /* 0.494397481 */, 16 }, + +/* 2416 */ { MAD_F(0x07ea2b92) /* 0.494670459 */, 16 }, +/* 2417 */ { MAD_F(0x07eb49d9) /* 0.494943475 */, 16 }, +/* 2418 */ { MAD_F(0x07ec682a) /* 0.495216529 */, 16 }, +/* 2419 */ { MAD_F(0x07ed8686) /* 0.495489620 */, 16 }, +/* 2420 */ { MAD_F(0x07eea4eb) /* 0.495762748 */, 16 }, +/* 2421 */ { MAD_F(0x07efc35b) /* 0.496035915 */, 16 }, +/* 2422 */ { MAD_F(0x07f0e1d4) /* 0.496309119 */, 16 }, +/* 2423 */ { MAD_F(0x07f20058) /* 0.496582360 */, 16 }, +/* 2424 */ { MAD_F(0x07f31ee6) /* 0.496855639 */, 16 }, +/* 2425 */ { MAD_F(0x07f43d7e) /* 0.497128956 */, 16 }, +/* 2426 */ { MAD_F(0x07f55c20) /* 0.497402310 */, 16 }, +/* 2427 */ { MAD_F(0x07f67acc) /* 0.497675702 */, 16 }, +/* 2428 */ { MAD_F(0x07f79982) /* 0.497949132 */, 16 }, +/* 2429 */ { MAD_F(0x07f8b842) /* 0.498222598 */, 16 }, +/* 2430 */ { MAD_F(0x07f9d70c) /* 0.498496103 */, 16 }, +/* 2431 */ { MAD_F(0x07faf5e1) /* 0.498769645 */, 16 }, + +/* 2432 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 16 }, +/* 2433 */ { MAD_F(0x07fd33a8) /* 0.499316841 */, 16 }, +/* 2434 */ { MAD_F(0x07fe529a) /* 0.499590496 */, 16 }, +/* 2435 */ { MAD_F(0x07ff7197) /* 0.499864188 */, 16 }, +/* 2436 */ { MAD_F(0x0400484f) /* 0.250068959 */, 17 }, +/* 2437 */ { MAD_F(0x0400d7d7) /* 0.250205842 */, 17 }, +/* 2438 */ { MAD_F(0x04016764) /* 0.250342744 */, 17 }, +/* 2439 */ { MAD_F(0x0401f6f7) /* 0.250479665 */, 17 }, +/* 2440 */ { MAD_F(0x0402868e) /* 0.250616605 */, 17 }, +/* 2441 */ { MAD_F(0x0403162b) /* 0.250753563 */, 17 }, +/* 2442 */ { MAD_F(0x0403a5cc) /* 0.250890540 */, 17 }, +/* 2443 */ { MAD_F(0x04043573) /* 0.251027536 */, 17 }, +/* 2444 */ { MAD_F(0x0404c51e) /* 0.251164550 */, 17 }, +/* 2445 */ { MAD_F(0x040554cf) /* 0.251301583 */, 17 }, +/* 2446 */ { MAD_F(0x0405e484) /* 0.251438635 */, 17 }, +/* 2447 */ { MAD_F(0x0406743f) /* 0.251575706 */, 17 }, + +/* 2448 */ { MAD_F(0x040703ff) /* 0.251712795 */, 17 }, +/* 2449 */ { MAD_F(0x040793c3) /* 0.251849903 */, 17 }, +/* 2450 */ { MAD_F(0x0408238d) /* 0.251987029 */, 17 }, +/* 2451 */ { MAD_F(0x0408b35b) /* 0.252124174 */, 17 }, +/* 2452 */ { MAD_F(0x0409432f) /* 0.252261338 */, 17 }, +/* 2453 */ { MAD_F(0x0409d308) /* 0.252398520 */, 17 }, +/* 2454 */ { MAD_F(0x040a62e5) /* 0.252535721 */, 17 }, +/* 2455 */ { MAD_F(0x040af2c8) /* 0.252672941 */, 17 }, +/* 2456 */ { MAD_F(0x040b82b0) /* 0.252810180 */, 17 }, +/* 2457 */ { MAD_F(0x040c129c) /* 0.252947436 */, 17 }, +/* 2458 */ { MAD_F(0x040ca28e) /* 0.253084712 */, 17 }, +/* 2459 */ { MAD_F(0x040d3284) /* 0.253222006 */, 17 }, +/* 2460 */ { MAD_F(0x040dc280) /* 0.253359319 */, 17 }, +/* 2461 */ { MAD_F(0x040e5281) /* 0.253496651 */, 17 }, +/* 2462 */ { MAD_F(0x040ee286) /* 0.253634001 */, 17 }, +/* 2463 */ { MAD_F(0x040f7291) /* 0.253771369 */, 17 }, + +/* 2464 */ { MAD_F(0x041002a1) /* 0.253908756 */, 17 }, +/* 2465 */ { MAD_F(0x041092b5) /* 0.254046162 */, 17 }, +/* 2466 */ { MAD_F(0x041122cf) /* 0.254183587 */, 17 }, +/* 2467 */ { MAD_F(0x0411b2ed) /* 0.254321030 */, 17 }, +/* 2468 */ { MAD_F(0x04124311) /* 0.254458491 */, 17 }, +/* 2469 */ { MAD_F(0x0412d339) /* 0.254595971 */, 17 }, +/* 2470 */ { MAD_F(0x04136367) /* 0.254733470 */, 17 }, +/* 2471 */ { MAD_F(0x0413f399) /* 0.254870987 */, 17 }, +/* 2472 */ { MAD_F(0x041483d1) /* 0.255008523 */, 17 }, +/* 2473 */ { MAD_F(0x0415140d) /* 0.255146077 */, 17 }, +/* 2474 */ { MAD_F(0x0415a44f) /* 0.255283650 */, 17 }, +/* 2475 */ { MAD_F(0x04163495) /* 0.255421241 */, 17 }, +/* 2476 */ { MAD_F(0x0416c4e1) /* 0.255558851 */, 17 }, +/* 2477 */ { MAD_F(0x04175531) /* 0.255696480 */, 17 }, +/* 2478 */ { MAD_F(0x0417e586) /* 0.255834127 */, 17 }, +/* 2479 */ { MAD_F(0x041875e1) /* 0.255971792 */, 17 }, + +/* 2480 */ { MAD_F(0x04190640) /* 0.256109476 */, 17 }, +/* 2481 */ { MAD_F(0x041996a4) /* 0.256247179 */, 17 }, +/* 2482 */ { MAD_F(0x041a270d) /* 0.256384900 */, 17 }, +/* 2483 */ { MAD_F(0x041ab77b) /* 0.256522639 */, 17 }, +/* 2484 */ { MAD_F(0x041b47ef) /* 0.256660397 */, 17 }, +/* 2485 */ { MAD_F(0x041bd867) /* 0.256798174 */, 17 }, +/* 2486 */ { MAD_F(0x041c68e4) /* 0.256935969 */, 17 }, +/* 2487 */ { MAD_F(0x041cf966) /* 0.257073782 */, 17 }, +/* 2488 */ { MAD_F(0x041d89ed) /* 0.257211614 */, 17 }, +/* 2489 */ { MAD_F(0x041e1a79) /* 0.257349465 */, 17 }, +/* 2490 */ { MAD_F(0x041eab0a) /* 0.257487334 */, 17 }, +/* 2491 */ { MAD_F(0x041f3b9f) /* 0.257625221 */, 17 }, +/* 2492 */ { MAD_F(0x041fcc3a) /* 0.257763127 */, 17 }, +/* 2493 */ { MAD_F(0x04205cda) /* 0.257901051 */, 17 }, +/* 2494 */ { MAD_F(0x0420ed7f) /* 0.258038994 */, 17 }, +/* 2495 */ { MAD_F(0x04217e28) /* 0.258176955 */, 17 }, + +/* 2496 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 17 }, +/* 2497 */ { MAD_F(0x04229f8a) /* 0.258452932 */, 17 }, +/* 2498 */ { MAD_F(0x04233043) /* 0.258590948 */, 17 }, +/* 2499 */ { MAD_F(0x0423c100) /* 0.258728983 */, 17 }, +/* 2500 */ { MAD_F(0x042451c3) /* 0.258867036 */, 17 }, +/* 2501 */ { MAD_F(0x0424e28a) /* 0.259005108 */, 17 }, +/* 2502 */ { MAD_F(0x04257356) /* 0.259143198 */, 17 }, +/* 2503 */ { MAD_F(0x04260428) /* 0.259281307 */, 17 }, +/* 2504 */ { MAD_F(0x042694fe) /* 0.259419433 */, 17 }, +/* 2505 */ { MAD_F(0x042725d9) /* 0.259557579 */, 17 }, +/* 2506 */ { MAD_F(0x0427b6b9) /* 0.259695742 */, 17 }, +/* 2507 */ { MAD_F(0x0428479e) /* 0.259833924 */, 17 }, +/* 2508 */ { MAD_F(0x0428d888) /* 0.259972124 */, 17 }, +/* 2509 */ { MAD_F(0x04296976) /* 0.260110343 */, 17 }, +/* 2510 */ { MAD_F(0x0429fa6a) /* 0.260248580 */, 17 }, +/* 2511 */ { MAD_F(0x042a8b63) /* 0.260386836 */, 17 }, + +/* 2512 */ { MAD_F(0x042b1c60) /* 0.260525110 */, 17 }, +/* 2513 */ { MAD_F(0x042bad63) /* 0.260663402 */, 17 }, +/* 2514 */ { MAD_F(0x042c3e6a) /* 0.260801712 */, 17 }, +/* 2515 */ { MAD_F(0x042ccf77) /* 0.260940041 */, 17 }, +/* 2516 */ { MAD_F(0x042d6088) /* 0.261078388 */, 17 }, +/* 2517 */ { MAD_F(0x042df19e) /* 0.261216754 */, 17 }, +/* 2518 */ { MAD_F(0x042e82b9) /* 0.261355137 */, 17 }, +/* 2519 */ { MAD_F(0x042f13d9) /* 0.261493540 */, 17 }, +/* 2520 */ { MAD_F(0x042fa4fe) /* 0.261631960 */, 17 }, +/* 2521 */ { MAD_F(0x04303628) /* 0.261770399 */, 17 }, +/* 2522 */ { MAD_F(0x0430c757) /* 0.261908856 */, 17 }, +/* 2523 */ { MAD_F(0x0431588b) /* 0.262047331 */, 17 }, +/* 2524 */ { MAD_F(0x0431e9c3) /* 0.262185825 */, 17 }, +/* 2525 */ { MAD_F(0x04327b01) /* 0.262324337 */, 17 }, +/* 2526 */ { MAD_F(0x04330c43) /* 0.262462867 */, 17 }, +/* 2527 */ { MAD_F(0x04339d8a) /* 0.262601416 */, 17 }, + +/* 2528 */ { MAD_F(0x04342ed7) /* 0.262739982 */, 17 }, +/* 2529 */ { MAD_F(0x0434c028) /* 0.262878568 */, 17 }, +/* 2530 */ { MAD_F(0x0435517e) /* 0.263017171 */, 17 }, +/* 2531 */ { MAD_F(0x0435e2d9) /* 0.263155792 */, 17 }, +/* 2532 */ { MAD_F(0x04367439) /* 0.263294432 */, 17 }, +/* 2533 */ { MAD_F(0x0437059e) /* 0.263433090 */, 17 }, +/* 2534 */ { MAD_F(0x04379707) /* 0.263571767 */, 17 }, +/* 2535 */ { MAD_F(0x04382876) /* 0.263710461 */, 17 }, +/* 2536 */ { MAD_F(0x0438b9e9) /* 0.263849174 */, 17 }, +/* 2537 */ { MAD_F(0x04394b61) /* 0.263987905 */, 17 }, +/* 2538 */ { MAD_F(0x0439dcdf) /* 0.264126655 */, 17 }, +/* 2539 */ { MAD_F(0x043a6e61) /* 0.264265422 */, 17 }, +/* 2540 */ { MAD_F(0x043affe8) /* 0.264404208 */, 17 }, +/* 2541 */ { MAD_F(0x043b9174) /* 0.264543012 */, 17 }, +/* 2542 */ { MAD_F(0x043c2305) /* 0.264681834 */, 17 }, +/* 2543 */ { MAD_F(0x043cb49a) /* 0.264820674 */, 17 }, + +/* 2544 */ { MAD_F(0x043d4635) /* 0.264959533 */, 17 }, +/* 2545 */ { MAD_F(0x043dd7d4) /* 0.265098410 */, 17 }, +/* 2546 */ { MAD_F(0x043e6979) /* 0.265237305 */, 17 }, +/* 2547 */ { MAD_F(0x043efb22) /* 0.265376218 */, 17 }, +/* 2548 */ { MAD_F(0x043f8cd0) /* 0.265515149 */, 17 }, +/* 2549 */ { MAD_F(0x04401e83) /* 0.265654099 */, 17 }, +/* 2550 */ { MAD_F(0x0440b03b) /* 0.265793066 */, 17 }, +/* 2551 */ { MAD_F(0x044141f7) /* 0.265932052 */, 17 }, +/* 2552 */ { MAD_F(0x0441d3b9) /* 0.266071056 */, 17 }, +/* 2553 */ { MAD_F(0x04426580) /* 0.266210078 */, 17 }, +/* 2554 */ { MAD_F(0x0442f74b) /* 0.266349119 */, 17 }, +/* 2555 */ { MAD_F(0x0443891b) /* 0.266488177 */, 17 }, +/* 2556 */ { MAD_F(0x04441af0) /* 0.266627254 */, 17 }, +/* 2557 */ { MAD_F(0x0444acca) /* 0.266766349 */, 17 }, +/* 2558 */ { MAD_F(0x04453ea9) /* 0.266905462 */, 17 }, +/* 2559 */ { MAD_F(0x0445d08d) /* 0.267044593 */, 17 }, + +/* 2560 */ { MAD_F(0x04466275) /* 0.267183742 */, 17 }, +/* 2561 */ { MAD_F(0x0446f463) /* 0.267322909 */, 17 }, +/* 2562 */ { MAD_F(0x04478655) /* 0.267462094 */, 17 }, +/* 2563 */ { MAD_F(0x0448184c) /* 0.267601298 */, 17 }, +/* 2564 */ { MAD_F(0x0448aa48) /* 0.267740519 */, 17 }, +/* 2565 */ { MAD_F(0x04493c49) /* 0.267879759 */, 17 }, +/* 2566 */ { MAD_F(0x0449ce4f) /* 0.268019017 */, 17 }, +/* 2567 */ { MAD_F(0x044a6059) /* 0.268158293 */, 17 }, +/* 2568 */ { MAD_F(0x044af269) /* 0.268297587 */, 17 }, +/* 2569 */ { MAD_F(0x044b847d) /* 0.268436899 */, 17 }, +/* 2570 */ { MAD_F(0x044c1696) /* 0.268576229 */, 17 }, +/* 2571 */ { MAD_F(0x044ca8b4) /* 0.268715577 */, 17 }, +/* 2572 */ { MAD_F(0x044d3ad7) /* 0.268854943 */, 17 }, +/* 2573 */ { MAD_F(0x044dccff) /* 0.268994328 */, 17 }, +/* 2574 */ { MAD_F(0x044e5f2b) /* 0.269133730 */, 17 }, +/* 2575 */ { MAD_F(0x044ef15d) /* 0.269273150 */, 17 }, + +/* 2576 */ { MAD_F(0x044f8393) /* 0.269412589 */, 17 }, +/* 2577 */ { MAD_F(0x045015ce) /* 0.269552045 */, 17 }, +/* 2578 */ { MAD_F(0x0450a80e) /* 0.269691520 */, 17 }, +/* 2579 */ { MAD_F(0x04513a53) /* 0.269831013 */, 17 }, +/* 2580 */ { MAD_F(0x0451cc9c) /* 0.269970523 */, 17 }, +/* 2581 */ { MAD_F(0x04525eeb) /* 0.270110052 */, 17 }, +/* 2582 */ { MAD_F(0x0452f13e) /* 0.270249599 */, 17 }, +/* 2583 */ { MAD_F(0x04538396) /* 0.270389163 */, 17 }, +/* 2584 */ { MAD_F(0x045415f3) /* 0.270528746 */, 17 }, +/* 2585 */ { MAD_F(0x0454a855) /* 0.270668347 */, 17 }, +/* 2586 */ { MAD_F(0x04553abb) /* 0.270807965 */, 17 }, +/* 2587 */ { MAD_F(0x0455cd27) /* 0.270947602 */, 17 }, +/* 2588 */ { MAD_F(0x04565f97) /* 0.271087257 */, 17 }, +/* 2589 */ { MAD_F(0x0456f20c) /* 0.271226930 */, 17 }, +/* 2590 */ { MAD_F(0x04578486) /* 0.271366620 */, 17 }, +/* 2591 */ { MAD_F(0x04581705) /* 0.271506329 */, 17 }, + +/* 2592 */ { MAD_F(0x0458a989) /* 0.271646056 */, 17 }, +/* 2593 */ { MAD_F(0x04593c11) /* 0.271785800 */, 17 }, +/* 2594 */ { MAD_F(0x0459ce9e) /* 0.271925563 */, 17 }, +/* 2595 */ { MAD_F(0x045a6130) /* 0.272065343 */, 17 }, +/* 2596 */ { MAD_F(0x045af3c7) /* 0.272205142 */, 17 }, +/* 2597 */ { MAD_F(0x045b8663) /* 0.272344958 */, 17 }, +/* 2598 */ { MAD_F(0x045c1903) /* 0.272484793 */, 17 }, +/* 2599 */ { MAD_F(0x045caba9) /* 0.272624645 */, 17 }, +/* 2600 */ { MAD_F(0x045d3e53) /* 0.272764515 */, 17 }, +/* 2601 */ { MAD_F(0x045dd102) /* 0.272904403 */, 17 }, +/* 2602 */ { MAD_F(0x045e63b6) /* 0.273044310 */, 17 }, +/* 2603 */ { MAD_F(0x045ef66e) /* 0.273184234 */, 17 }, +/* 2604 */ { MAD_F(0x045f892b) /* 0.273324176 */, 17 }, +/* 2605 */ { MAD_F(0x04601bee) /* 0.273464136 */, 17 }, +/* 2606 */ { MAD_F(0x0460aeb5) /* 0.273604113 */, 17 }, +/* 2607 */ { MAD_F(0x04614180) /* 0.273744109 */, 17 }, + +/* 2608 */ { MAD_F(0x0461d451) /* 0.273884123 */, 17 }, +/* 2609 */ { MAD_F(0x04626727) /* 0.274024154 */, 17 }, +/* 2610 */ { MAD_F(0x0462fa01) /* 0.274164204 */, 17 }, +/* 2611 */ { MAD_F(0x04638ce0) /* 0.274304271 */, 17 }, +/* 2612 */ { MAD_F(0x04641fc4) /* 0.274444356 */, 17 }, +/* 2613 */ { MAD_F(0x0464b2ac) /* 0.274584459 */, 17 }, +/* 2614 */ { MAD_F(0x0465459a) /* 0.274724580 */, 17 }, +/* 2615 */ { MAD_F(0x0465d88c) /* 0.274864719 */, 17 }, +/* 2616 */ { MAD_F(0x04666b83) /* 0.275004875 */, 17 }, +/* 2617 */ { MAD_F(0x0466fe7f) /* 0.275145050 */, 17 }, +/* 2618 */ { MAD_F(0x0467917f) /* 0.275285242 */, 17 }, +/* 2619 */ { MAD_F(0x04682485) /* 0.275425452 */, 17 }, +/* 2620 */ { MAD_F(0x0468b78f) /* 0.275565681 */, 17 }, +/* 2621 */ { MAD_F(0x04694a9e) /* 0.275705926 */, 17 }, +/* 2622 */ { MAD_F(0x0469ddb2) /* 0.275846190 */, 17 }, +/* 2623 */ { MAD_F(0x046a70ca) /* 0.275986472 */, 17 }, + +/* 2624 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 17 }, +/* 2625 */ { MAD_F(0x046b970a) /* 0.276267088 */, 17 }, +/* 2626 */ { MAD_F(0x046c2a31) /* 0.276407423 */, 17 }, +/* 2627 */ { MAD_F(0x046cbd5c) /* 0.276547776 */, 17 }, +/* 2628 */ { MAD_F(0x046d508d) /* 0.276688147 */, 17 }, +/* 2629 */ { MAD_F(0x046de3c2) /* 0.276828535 */, 17 }, +/* 2630 */ { MAD_F(0x046e76fc) /* 0.276968942 */, 17 }, +/* 2631 */ { MAD_F(0x046f0a3b) /* 0.277109366 */, 17 }, +/* 2632 */ { MAD_F(0x046f9d7e) /* 0.277249808 */, 17 }, +/* 2633 */ { MAD_F(0x047030c7) /* 0.277390267 */, 17 }, +/* 2634 */ { MAD_F(0x0470c414) /* 0.277530745 */, 17 }, +/* 2635 */ { MAD_F(0x04715766) /* 0.277671240 */, 17 }, +/* 2636 */ { MAD_F(0x0471eabc) /* 0.277811753 */, 17 }, +/* 2637 */ { MAD_F(0x04727e18) /* 0.277952284 */, 17 }, +/* 2638 */ { MAD_F(0x04731178) /* 0.278092832 */, 17 }, +/* 2639 */ { MAD_F(0x0473a4dd) /* 0.278233399 */, 17 }, + +/* 2640 */ { MAD_F(0x04743847) /* 0.278373983 */, 17 }, +/* 2641 */ { MAD_F(0x0474cbb5) /* 0.278514584 */, 17 }, +/* 2642 */ { MAD_F(0x04755f29) /* 0.278655204 */, 17 }, +/* 2643 */ { MAD_F(0x0475f2a1) /* 0.278795841 */, 17 }, +/* 2644 */ { MAD_F(0x0476861d) /* 0.278936496 */, 17 }, +/* 2645 */ { MAD_F(0x0477199f) /* 0.279077169 */, 17 }, +/* 2646 */ { MAD_F(0x0477ad25) /* 0.279217860 */, 17 }, +/* 2647 */ { MAD_F(0x047840b0) /* 0.279358568 */, 17 }, +/* 2648 */ { MAD_F(0x0478d440) /* 0.279499294 */, 17 }, +/* 2649 */ { MAD_F(0x047967d5) /* 0.279640037 */, 17 }, +/* 2650 */ { MAD_F(0x0479fb6e) /* 0.279780799 */, 17 }, +/* 2651 */ { MAD_F(0x047a8f0c) /* 0.279921578 */, 17 }, +/* 2652 */ { MAD_F(0x047b22af) /* 0.280062375 */, 17 }, +/* 2653 */ { MAD_F(0x047bb657) /* 0.280203189 */, 17 }, +/* 2654 */ { MAD_F(0x047c4a03) /* 0.280344021 */, 17 }, +/* 2655 */ { MAD_F(0x047cddb4) /* 0.280484871 */, 17 }, + +/* 2656 */ { MAD_F(0x047d716a) /* 0.280625739 */, 17 }, +/* 2657 */ { MAD_F(0x047e0524) /* 0.280766624 */, 17 }, +/* 2658 */ { MAD_F(0x047e98e4) /* 0.280907527 */, 17 }, +/* 2659 */ { MAD_F(0x047f2ca8) /* 0.281048447 */, 17 }, +/* 2660 */ { MAD_F(0x047fc071) /* 0.281189385 */, 17 }, +/* 2661 */ { MAD_F(0x0480543e) /* 0.281330341 */, 17 }, +/* 2662 */ { MAD_F(0x0480e811) /* 0.281471315 */, 17 }, +/* 2663 */ { MAD_F(0x04817be8) /* 0.281612306 */, 17 }, +/* 2664 */ { MAD_F(0x04820fc3) /* 0.281753315 */, 17 }, +/* 2665 */ { MAD_F(0x0482a3a4) /* 0.281894341 */, 17 }, +/* 2666 */ { MAD_F(0x04833789) /* 0.282035386 */, 17 }, +/* 2667 */ { MAD_F(0x0483cb73) /* 0.282176447 */, 17 }, +/* 2668 */ { MAD_F(0x04845f62) /* 0.282317527 */, 17 }, +/* 2669 */ { MAD_F(0x0484f355) /* 0.282458624 */, 17 }, +/* 2670 */ { MAD_F(0x0485874d) /* 0.282599738 */, 17 }, +/* 2671 */ { MAD_F(0x04861b4a) /* 0.282740871 */, 17 }, + +/* 2672 */ { MAD_F(0x0486af4c) /* 0.282882021 */, 17 }, +/* 2673 */ { MAD_F(0x04874352) /* 0.283023188 */, 17 }, +/* 2674 */ { MAD_F(0x0487d75d) /* 0.283164373 */, 17 }, +/* 2675 */ { MAD_F(0x04886b6d) /* 0.283305576 */, 17 }, +/* 2676 */ { MAD_F(0x0488ff82) /* 0.283446796 */, 17 }, +/* 2677 */ { MAD_F(0x0489939b) /* 0.283588034 */, 17 }, +/* 2678 */ { MAD_F(0x048a27b9) /* 0.283729290 */, 17 }, +/* 2679 */ { MAD_F(0x048abbdc) /* 0.283870563 */, 17 }, +/* 2680 */ { MAD_F(0x048b5003) /* 0.284011853 */, 17 }, +/* 2681 */ { MAD_F(0x048be42f) /* 0.284153161 */, 17 }, +/* 2682 */ { MAD_F(0x048c7860) /* 0.284294487 */, 17 }, +/* 2683 */ { MAD_F(0x048d0c96) /* 0.284435831 */, 17 }, +/* 2684 */ { MAD_F(0x048da0d0) /* 0.284577192 */, 17 }, +/* 2685 */ { MAD_F(0x048e350f) /* 0.284718570 */, 17 }, +/* 2686 */ { MAD_F(0x048ec953) /* 0.284859966 */, 17 }, +/* 2687 */ { MAD_F(0x048f5d9b) /* 0.285001380 */, 17 }, + +/* 2688 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 17 }, +/* 2689 */ { MAD_F(0x0490863a) /* 0.285284259 */, 17 }, +/* 2690 */ { MAD_F(0x04911a91) /* 0.285425726 */, 17 }, +/* 2691 */ { MAD_F(0x0491aeec) /* 0.285567209 */, 17 }, +/* 2692 */ { MAD_F(0x0492434c) /* 0.285708711 */, 17 }, +/* 2693 */ { MAD_F(0x0492d7b0) /* 0.285850229 */, 17 }, +/* 2694 */ { MAD_F(0x04936c1a) /* 0.285991766 */, 17 }, +/* 2695 */ { MAD_F(0x04940088) /* 0.286133319 */, 17 }, +/* 2696 */ { MAD_F(0x049494fb) /* 0.286274891 */, 17 }, +/* 2697 */ { MAD_F(0x04952972) /* 0.286416480 */, 17 }, +/* 2698 */ { MAD_F(0x0495bdee) /* 0.286558086 */, 17 }, +/* 2699 */ { MAD_F(0x0496526f) /* 0.286699710 */, 17 }, +/* 2700 */ { MAD_F(0x0496e6f5) /* 0.286841351 */, 17 }, +/* 2701 */ { MAD_F(0x04977b7f) /* 0.286983010 */, 17 }, +/* 2702 */ { MAD_F(0x0498100e) /* 0.287124686 */, 17 }, +/* 2703 */ { MAD_F(0x0498a4a1) /* 0.287266380 */, 17 }, + +/* 2704 */ { MAD_F(0x0499393a) /* 0.287408091 */, 17 }, +/* 2705 */ { MAD_F(0x0499cdd7) /* 0.287549820 */, 17 }, +/* 2706 */ { MAD_F(0x049a6278) /* 0.287691566 */, 17 }, +/* 2707 */ { MAD_F(0x049af71f) /* 0.287833330 */, 17 }, +/* 2708 */ { MAD_F(0x049b8bca) /* 0.287975111 */, 17 }, +/* 2709 */ { MAD_F(0x049c207a) /* 0.288116909 */, 17 }, +/* 2710 */ { MAD_F(0x049cb52e) /* 0.288258725 */, 17 }, +/* 2711 */ { MAD_F(0x049d49e7) /* 0.288400559 */, 17 }, +/* 2712 */ { MAD_F(0x049ddea5) /* 0.288542409 */, 17 }, +/* 2713 */ { MAD_F(0x049e7367) /* 0.288684278 */, 17 }, +/* 2714 */ { MAD_F(0x049f082f) /* 0.288826163 */, 17 }, +/* 2715 */ { MAD_F(0x049f9cfa) /* 0.288968067 */, 17 }, +/* 2716 */ { MAD_F(0x04a031cb) /* 0.289109987 */, 17 }, +/* 2717 */ { MAD_F(0x04a0c6a0) /* 0.289251925 */, 17 }, +/* 2718 */ { MAD_F(0x04a15b7a) /* 0.289393881 */, 17 }, +/* 2719 */ { MAD_F(0x04a1f059) /* 0.289535854 */, 17 }, + +/* 2720 */ { MAD_F(0x04a2853c) /* 0.289677844 */, 17 }, +/* 2721 */ { MAD_F(0x04a31a24) /* 0.289819851 */, 17 }, +/* 2722 */ { MAD_F(0x04a3af10) /* 0.289961876 */, 17 }, +/* 2723 */ { MAD_F(0x04a44401) /* 0.290103919 */, 17 }, +/* 2724 */ { MAD_F(0x04a4d8f7) /* 0.290245979 */, 17 }, +/* 2725 */ { MAD_F(0x04a56df2) /* 0.290388056 */, 17 }, +/* 2726 */ { MAD_F(0x04a602f1) /* 0.290530150 */, 17 }, +/* 2727 */ { MAD_F(0x04a697f5) /* 0.290672262 */, 17 }, +/* 2728 */ { MAD_F(0x04a72cfe) /* 0.290814392 */, 17 }, +/* 2729 */ { MAD_F(0x04a7c20b) /* 0.290956538 */, 17 }, +/* 2730 */ { MAD_F(0x04a8571d) /* 0.291098703 */, 17 }, +/* 2731 */ { MAD_F(0x04a8ec33) /* 0.291240884 */, 17 }, +/* 2732 */ { MAD_F(0x04a9814e) /* 0.291383083 */, 17 }, +/* 2733 */ { MAD_F(0x04aa166e) /* 0.291525299 */, 17 }, +/* 2734 */ { MAD_F(0x04aaab93) /* 0.291667532 */, 17 }, +/* 2735 */ { MAD_F(0x04ab40bc) /* 0.291809783 */, 17 }, + +/* 2736 */ { MAD_F(0x04abd5ea) /* 0.291952051 */, 17 }, +/* 2737 */ { MAD_F(0x04ac6b1c) /* 0.292094337 */, 17 }, +/* 2738 */ { MAD_F(0x04ad0053) /* 0.292236640 */, 17 }, +/* 2739 */ { MAD_F(0x04ad958f) /* 0.292378960 */, 17 }, +/* 2740 */ { MAD_F(0x04ae2ad0) /* 0.292521297 */, 17 }, +/* 2741 */ { MAD_F(0x04aec015) /* 0.292663652 */, 17 }, +/* 2742 */ { MAD_F(0x04af555e) /* 0.292806024 */, 17 }, +/* 2743 */ { MAD_F(0x04afeaad) /* 0.292948414 */, 17 }, +/* 2744 */ { MAD_F(0x04b08000) /* 0.293090820 */, 17 }, +/* 2745 */ { MAD_F(0x04b11557) /* 0.293233244 */, 17 }, +/* 2746 */ { MAD_F(0x04b1aab4) /* 0.293375686 */, 17 }, +/* 2747 */ { MAD_F(0x04b24015) /* 0.293518144 */, 17 }, +/* 2748 */ { MAD_F(0x04b2d57a) /* 0.293660620 */, 17 }, +/* 2749 */ { MAD_F(0x04b36ae4) /* 0.293803113 */, 17 }, +/* 2750 */ { MAD_F(0x04b40053) /* 0.293945624 */, 17 }, +/* 2751 */ { MAD_F(0x04b495c7) /* 0.294088151 */, 17 }, + +/* 2752 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 17 }, +/* 2753 */ { MAD_F(0x04b5c0bc) /* 0.294373259 */, 17 }, +/* 2754 */ { MAD_F(0x04b6563d) /* 0.294515838 */, 17 }, +/* 2755 */ { MAD_F(0x04b6ebc3) /* 0.294658435 */, 17 }, +/* 2756 */ { MAD_F(0x04b7814e) /* 0.294801049 */, 17 }, +/* 2757 */ { MAD_F(0x04b816dd) /* 0.294943680 */, 17 }, +/* 2758 */ { MAD_F(0x04b8ac71) /* 0.295086329 */, 17 }, +/* 2759 */ { MAD_F(0x04b9420a) /* 0.295228995 */, 17 }, +/* 2760 */ { MAD_F(0x04b9d7a7) /* 0.295371678 */, 17 }, +/* 2761 */ { MAD_F(0x04ba6d49) /* 0.295514378 */, 17 }, +/* 2762 */ { MAD_F(0x04bb02ef) /* 0.295657095 */, 17 }, +/* 2763 */ { MAD_F(0x04bb989a) /* 0.295799830 */, 17 }, +/* 2764 */ { MAD_F(0x04bc2e4a) /* 0.295942582 */, 17 }, +/* 2765 */ { MAD_F(0x04bcc3fe) /* 0.296085351 */, 17 }, +/* 2766 */ { MAD_F(0x04bd59b7) /* 0.296228138 */, 17 }, +/* 2767 */ { MAD_F(0x04bdef74) /* 0.296370941 */, 17 }, + +/* 2768 */ { MAD_F(0x04be8537) /* 0.296513762 */, 17 }, +/* 2769 */ { MAD_F(0x04bf1afd) /* 0.296656600 */, 17 }, +/* 2770 */ { MAD_F(0x04bfb0c9) /* 0.296799455 */, 17 }, +/* 2771 */ { MAD_F(0x04c04699) /* 0.296942327 */, 17 }, +/* 2772 */ { MAD_F(0x04c0dc6d) /* 0.297085217 */, 17 }, +/* 2773 */ { MAD_F(0x04c17247) /* 0.297228124 */, 17 }, +/* 2774 */ { MAD_F(0x04c20824) /* 0.297371048 */, 17 }, +/* 2775 */ { MAD_F(0x04c29e07) /* 0.297513989 */, 17 }, +/* 2776 */ { MAD_F(0x04c333ee) /* 0.297656947 */, 17 }, +/* 2777 */ { MAD_F(0x04c3c9da) /* 0.297799922 */, 17 }, +/* 2778 */ { MAD_F(0x04c45fca) /* 0.297942915 */, 17 }, +/* 2779 */ { MAD_F(0x04c4f5bf) /* 0.298085925 */, 17 }, +/* 2780 */ { MAD_F(0x04c58bb8) /* 0.298228951 */, 17 }, +/* 2781 */ { MAD_F(0x04c621b6) /* 0.298371996 */, 17 }, +/* 2782 */ { MAD_F(0x04c6b7b9) /* 0.298515057 */, 17 }, +/* 2783 */ { MAD_F(0x04c74dc0) /* 0.298658135 */, 17 }, + +/* 2784 */ { MAD_F(0x04c7e3cc) /* 0.298801231 */, 17 }, +/* 2785 */ { MAD_F(0x04c879dd) /* 0.298944343 */, 17 }, +/* 2786 */ { MAD_F(0x04c90ff2) /* 0.299087473 */, 17 }, +/* 2787 */ { MAD_F(0x04c9a60c) /* 0.299230620 */, 17 }, +/* 2788 */ { MAD_F(0x04ca3c2a) /* 0.299373784 */, 17 }, +/* 2789 */ { MAD_F(0x04cad24d) /* 0.299516965 */, 17 }, +/* 2790 */ { MAD_F(0x04cb6874) /* 0.299660163 */, 17 }, +/* 2791 */ { MAD_F(0x04cbfea0) /* 0.299803378 */, 17 }, +/* 2792 */ { MAD_F(0x04cc94d1) /* 0.299946611 */, 17 }, +/* 2793 */ { MAD_F(0x04cd2b06) /* 0.300089860 */, 17 }, +/* 2794 */ { MAD_F(0x04cdc140) /* 0.300233127 */, 17 }, +/* 2795 */ { MAD_F(0x04ce577f) /* 0.300376411 */, 17 }, +/* 2796 */ { MAD_F(0x04ceedc2) /* 0.300519711 */, 17 }, +/* 2797 */ { MAD_F(0x04cf8409) /* 0.300663029 */, 17 }, +/* 2798 */ { MAD_F(0x04d01a55) /* 0.300806364 */, 17 }, +/* 2799 */ { MAD_F(0x04d0b0a6) /* 0.300949716 */, 17 }, + +/* 2800 */ { MAD_F(0x04d146fb) /* 0.301093085 */, 17 }, +/* 2801 */ { MAD_F(0x04d1dd55) /* 0.301236472 */, 17 }, +/* 2802 */ { MAD_F(0x04d273b4) /* 0.301379875 */, 17 }, +/* 2803 */ { MAD_F(0x04d30a17) /* 0.301523295 */, 17 }, +/* 2804 */ { MAD_F(0x04d3a07f) /* 0.301666733 */, 17 }, +/* 2805 */ { MAD_F(0x04d436eb) /* 0.301810187 */, 17 }, +/* 2806 */ { MAD_F(0x04d4cd5c) /* 0.301953659 */, 17 }, +/* 2807 */ { MAD_F(0x04d563d1) /* 0.302097147 */, 17 }, +/* 2808 */ { MAD_F(0x04d5fa4b) /* 0.302240653 */, 17 }, +/* 2809 */ { MAD_F(0x04d690ca) /* 0.302384175 */, 17 }, +/* 2810 */ { MAD_F(0x04d7274d) /* 0.302527715 */, 17 }, +/* 2811 */ { MAD_F(0x04d7bdd5) /* 0.302671271 */, 17 }, +/* 2812 */ { MAD_F(0x04d85461) /* 0.302814845 */, 17 }, +/* 2813 */ { MAD_F(0x04d8eaf2) /* 0.302958436 */, 17 }, +/* 2814 */ { MAD_F(0x04d98187) /* 0.303102044 */, 17 }, +/* 2815 */ { MAD_F(0x04da1821) /* 0.303245668 */, 17 }, + +/* 2816 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 17 }, +/* 2817 */ { MAD_F(0x04db4563) /* 0.303532969 */, 17 }, +/* 2818 */ { MAD_F(0x04dbdc0a) /* 0.303676645 */, 17 }, +/* 2819 */ { MAD_F(0x04dc72b7) /* 0.303820337 */, 17 }, +/* 2820 */ { MAD_F(0x04dd0967) /* 0.303964047 */, 17 }, +/* 2821 */ { MAD_F(0x04dda01d) /* 0.304107774 */, 17 }, +/* 2822 */ { MAD_F(0x04de36d7) /* 0.304251517 */, 17 }, +/* 2823 */ { MAD_F(0x04decd95) /* 0.304395278 */, 17 }, +/* 2824 */ { MAD_F(0x04df6458) /* 0.304539056 */, 17 }, +/* 2825 */ { MAD_F(0x04dffb20) /* 0.304682850 */, 17 }, +/* 2826 */ { MAD_F(0x04e091ec) /* 0.304826662 */, 17 }, +/* 2827 */ { MAD_F(0x04e128bc) /* 0.304970491 */, 17 }, +/* 2828 */ { MAD_F(0x04e1bf92) /* 0.305114336 */, 17 }, +/* 2829 */ { MAD_F(0x04e2566b) /* 0.305258199 */, 17 }, +/* 2830 */ { MAD_F(0x04e2ed4a) /* 0.305402078 */, 17 }, +/* 2831 */ { MAD_F(0x04e3842d) /* 0.305545974 */, 17 }, + +/* 2832 */ { MAD_F(0x04e41b14) /* 0.305689888 */, 17 }, +/* 2833 */ { MAD_F(0x04e4b200) /* 0.305833818 */, 17 }, +/* 2834 */ { MAD_F(0x04e548f1) /* 0.305977765 */, 17 }, +/* 2835 */ { MAD_F(0x04e5dfe6) /* 0.306121729 */, 17 }, +/* 2836 */ { MAD_F(0x04e676df) /* 0.306265710 */, 17 }, +/* 2837 */ { MAD_F(0x04e70dde) /* 0.306409708 */, 17 }, +/* 2838 */ { MAD_F(0x04e7a4e0) /* 0.306553723 */, 17 }, +/* 2839 */ { MAD_F(0x04e83be7) /* 0.306697755 */, 17 }, +/* 2840 */ { MAD_F(0x04e8d2f3) /* 0.306841804 */, 17 }, +/* 2841 */ { MAD_F(0x04e96a04) /* 0.306985869 */, 17 }, +/* 2842 */ { MAD_F(0x04ea0118) /* 0.307129952 */, 17 }, +/* 2843 */ { MAD_F(0x04ea9832) /* 0.307274051 */, 17 }, +/* 2844 */ { MAD_F(0x04eb2f50) /* 0.307418168 */, 17 }, +/* 2845 */ { MAD_F(0x04ebc672) /* 0.307562301 */, 17 }, +/* 2846 */ { MAD_F(0x04ec5d99) /* 0.307706451 */, 17 }, +/* 2847 */ { MAD_F(0x04ecf4c5) /* 0.307850618 */, 17 }, + +/* 2848 */ { MAD_F(0x04ed8bf5) /* 0.307994802 */, 17 }, +/* 2849 */ { MAD_F(0x04ee2329) /* 0.308139003 */, 17 }, +/* 2850 */ { MAD_F(0x04eeba63) /* 0.308283220 */, 17 }, +/* 2851 */ { MAD_F(0x04ef51a0) /* 0.308427455 */, 17 }, +/* 2852 */ { MAD_F(0x04efe8e2) /* 0.308571706 */, 17 }, +/* 2853 */ { MAD_F(0x04f08029) /* 0.308715974 */, 17 }, +/* 2854 */ { MAD_F(0x04f11774) /* 0.308860260 */, 17 }, +/* 2855 */ { MAD_F(0x04f1aec4) /* 0.309004561 */, 17 }, +/* 2856 */ { MAD_F(0x04f24618) /* 0.309148880 */, 17 }, +/* 2857 */ { MAD_F(0x04f2dd71) /* 0.309293216 */, 17 }, +/* 2858 */ { MAD_F(0x04f374cf) /* 0.309437568 */, 17 }, +/* 2859 */ { MAD_F(0x04f40c30) /* 0.309581938 */, 17 }, +/* 2860 */ { MAD_F(0x04f4a397) /* 0.309726324 */, 17 }, +/* 2861 */ { MAD_F(0x04f53b02) /* 0.309870727 */, 17 }, +/* 2862 */ { MAD_F(0x04f5d271) /* 0.310015147 */, 17 }, +/* 2863 */ { MAD_F(0x04f669e5) /* 0.310159583 */, 17 }, + +/* 2864 */ { MAD_F(0x04f7015d) /* 0.310304037 */, 17 }, +/* 2865 */ { MAD_F(0x04f798da) /* 0.310448507 */, 17 }, +/* 2866 */ { MAD_F(0x04f8305c) /* 0.310592994 */, 17 }, +/* 2867 */ { MAD_F(0x04f8c7e2) /* 0.310737498 */, 17 }, +/* 2868 */ { MAD_F(0x04f95f6c) /* 0.310882018 */, 17 }, +/* 2869 */ { MAD_F(0x04f9f6fb) /* 0.311026556 */, 17 }, +/* 2870 */ { MAD_F(0x04fa8e8f) /* 0.311171110 */, 17 }, +/* 2871 */ { MAD_F(0x04fb2627) /* 0.311315681 */, 17 }, +/* 2872 */ { MAD_F(0x04fbbdc3) /* 0.311460269 */, 17 }, +/* 2873 */ { MAD_F(0x04fc5564) /* 0.311604874 */, 17 }, +/* 2874 */ { MAD_F(0x04fced0a) /* 0.311749495 */, 17 }, +/* 2875 */ { MAD_F(0x04fd84b4) /* 0.311894133 */, 17 }, +/* 2876 */ { MAD_F(0x04fe1c62) /* 0.312038788 */, 17 }, +/* 2877 */ { MAD_F(0x04feb415) /* 0.312183460 */, 17 }, +/* 2878 */ { MAD_F(0x04ff4bcd) /* 0.312328148 */, 17 }, +/* 2879 */ { MAD_F(0x04ffe389) /* 0.312472854 */, 17 }, + +/* 2880 */ { MAD_F(0x05007b49) /* 0.312617576 */, 17 }, +/* 2881 */ { MAD_F(0x0501130e) /* 0.312762314 */, 17 }, +/* 2882 */ { MAD_F(0x0501aad8) /* 0.312907070 */, 17 }, +/* 2883 */ { MAD_F(0x050242a6) /* 0.313051842 */, 17 }, +/* 2884 */ { MAD_F(0x0502da78) /* 0.313196631 */, 17 }, +/* 2885 */ { MAD_F(0x0503724f) /* 0.313341437 */, 17 }, +/* 2886 */ { MAD_F(0x05040a2b) /* 0.313486259 */, 17 }, +/* 2887 */ { MAD_F(0x0504a20b) /* 0.313631098 */, 17 }, +/* 2888 */ { MAD_F(0x050539ef) /* 0.313775954 */, 17 }, +/* 2889 */ { MAD_F(0x0505d1d8) /* 0.313920827 */, 17 }, +/* 2890 */ { MAD_F(0x050669c5) /* 0.314065716 */, 17 }, +/* 2891 */ { MAD_F(0x050701b7) /* 0.314210622 */, 17 }, +/* 2892 */ { MAD_F(0x050799ae) /* 0.314355545 */, 17 }, +/* 2893 */ { MAD_F(0x050831a9) /* 0.314500484 */, 17 }, +/* 2894 */ { MAD_F(0x0508c9a8) /* 0.314645440 */, 17 }, +/* 2895 */ { MAD_F(0x050961ac) /* 0.314790413 */, 17 }, + +/* 2896 */ { MAD_F(0x0509f9b4) /* 0.314935403 */, 17 }, +/* 2897 */ { MAD_F(0x050a91c1) /* 0.315080409 */, 17 }, +/* 2898 */ { MAD_F(0x050b29d2) /* 0.315225432 */, 17 }, +/* 2899 */ { MAD_F(0x050bc1e8) /* 0.315370472 */, 17 }, +/* 2900 */ { MAD_F(0x050c5a02) /* 0.315515528 */, 17 }, +/* 2901 */ { MAD_F(0x050cf221) /* 0.315660601 */, 17 }, +/* 2902 */ { MAD_F(0x050d8a44) /* 0.315805690 */, 17 }, +/* 2903 */ { MAD_F(0x050e226c) /* 0.315950797 */, 17 }, +/* 2904 */ { MAD_F(0x050eba98) /* 0.316095920 */, 17 }, +/* 2905 */ { MAD_F(0x050f52c9) /* 0.316241059 */, 17 }, +/* 2906 */ { MAD_F(0x050feafe) /* 0.316386216 */, 17 }, +/* 2907 */ { MAD_F(0x05108337) /* 0.316531388 */, 17 }, +/* 2908 */ { MAD_F(0x05111b75) /* 0.316676578 */, 17 }, +/* 2909 */ { MAD_F(0x0511b3b8) /* 0.316821784 */, 17 }, +/* 2910 */ { MAD_F(0x05124bff) /* 0.316967007 */, 17 }, +/* 2911 */ { MAD_F(0x0512e44a) /* 0.317112247 */, 17 }, + +/* 2912 */ { MAD_F(0x05137c9a) /* 0.317257503 */, 17 }, +/* 2913 */ { MAD_F(0x051414ee) /* 0.317402775 */, 17 }, +/* 2914 */ { MAD_F(0x0514ad47) /* 0.317548065 */, 17 }, +/* 2915 */ { MAD_F(0x051545a5) /* 0.317693371 */, 17 }, +/* 2916 */ { MAD_F(0x0515de06) /* 0.317838693 */, 17 }, +/* 2917 */ { MAD_F(0x0516766d) /* 0.317984033 */, 17 }, +/* 2918 */ { MAD_F(0x05170ed7) /* 0.318129388 */, 17 }, +/* 2919 */ { MAD_F(0x0517a746) /* 0.318274761 */, 17 }, +/* 2920 */ { MAD_F(0x05183fba) /* 0.318420150 */, 17 }, +/* 2921 */ { MAD_F(0x0518d832) /* 0.318565555 */, 17 }, +/* 2922 */ { MAD_F(0x051970ae) /* 0.318710978 */, 17 }, +/* 2923 */ { MAD_F(0x051a092f) /* 0.318856416 */, 17 }, +/* 2924 */ { MAD_F(0x051aa1b5) /* 0.319001872 */, 17 }, +/* 2925 */ { MAD_F(0x051b3a3f) /* 0.319147344 */, 17 }, +/* 2926 */ { MAD_F(0x051bd2cd) /* 0.319292832 */, 17 }, +/* 2927 */ { MAD_F(0x051c6b60) /* 0.319438338 */, 17 }, + +/* 2928 */ { MAD_F(0x051d03f7) /* 0.319583859 */, 17 }, +/* 2929 */ { MAD_F(0x051d9c92) /* 0.319729398 */, 17 }, +/* 2930 */ { MAD_F(0x051e3532) /* 0.319874952 */, 17 }, +/* 2931 */ { MAD_F(0x051ecdd7) /* 0.320020524 */, 17 }, +/* 2932 */ { MAD_F(0x051f6680) /* 0.320166112 */, 17 }, +/* 2933 */ { MAD_F(0x051fff2d) /* 0.320311716 */, 17 }, +/* 2934 */ { MAD_F(0x052097df) /* 0.320457337 */, 17 }, +/* 2935 */ { MAD_F(0x05213095) /* 0.320602975 */, 17 }, +/* 2936 */ { MAD_F(0x0521c950) /* 0.320748629 */, 17 }, +/* 2937 */ { MAD_F(0x0522620f) /* 0.320894300 */, 17 }, +/* 2938 */ { MAD_F(0x0522fad3) /* 0.321039987 */, 17 }, +/* 2939 */ { MAD_F(0x0523939b) /* 0.321185691 */, 17 }, +/* 2940 */ { MAD_F(0x05242c68) /* 0.321331411 */, 17 }, +/* 2941 */ { MAD_F(0x0524c538) /* 0.321477148 */, 17 }, +/* 2942 */ { MAD_F(0x05255e0e) /* 0.321622901 */, 17 }, +/* 2943 */ { MAD_F(0x0525f6e8) /* 0.321768671 */, 17 }, + +/* 2944 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 17 }, +/* 2945 */ { MAD_F(0x052728a9) /* 0.322060260 */, 17 }, +/* 2946 */ { MAD_F(0x0527c190) /* 0.322206079 */, 17 }, +/* 2947 */ { MAD_F(0x05285a7b) /* 0.322351915 */, 17 }, +/* 2948 */ { MAD_F(0x0528f36b) /* 0.322497768 */, 17 }, +/* 2949 */ { MAD_F(0x05298c5f) /* 0.322643636 */, 17 }, +/* 2950 */ { MAD_F(0x052a2558) /* 0.322789522 */, 17 }, +/* 2951 */ { MAD_F(0x052abe55) /* 0.322935424 */, 17 }, +/* 2952 */ { MAD_F(0x052b5757) /* 0.323081342 */, 17 }, +/* 2953 */ { MAD_F(0x052bf05d) /* 0.323227277 */, 17 }, +/* 2954 */ { MAD_F(0x052c8968) /* 0.323373228 */, 17 }, +/* 2955 */ { MAD_F(0x052d2277) /* 0.323519196 */, 17 }, +/* 2956 */ { MAD_F(0x052dbb8a) /* 0.323665180 */, 17 }, +/* 2957 */ { MAD_F(0x052e54a2) /* 0.323811180 */, 17 }, +/* 2958 */ { MAD_F(0x052eedbe) /* 0.323957197 */, 17 }, +/* 2959 */ { MAD_F(0x052f86de) /* 0.324103231 */, 17 }, + +/* 2960 */ { MAD_F(0x05302003) /* 0.324249281 */, 17 }, +/* 2961 */ { MAD_F(0x0530b92d) /* 0.324395347 */, 17 }, +/* 2962 */ { MAD_F(0x0531525b) /* 0.324541430 */, 17 }, +/* 2963 */ { MAD_F(0x0531eb8d) /* 0.324687530 */, 17 }, +/* 2964 */ { MAD_F(0x053284c4) /* 0.324833646 */, 17 }, +/* 2965 */ { MAD_F(0x05331dff) /* 0.324979778 */, 17 }, +/* 2966 */ { MAD_F(0x0533b73e) /* 0.325125926 */, 17 }, +/* 2967 */ { MAD_F(0x05345082) /* 0.325272091 */, 17 }, +/* 2968 */ { MAD_F(0x0534e9ca) /* 0.325418273 */, 17 }, +/* 2969 */ { MAD_F(0x05358317) /* 0.325564471 */, 17 }, +/* 2970 */ { MAD_F(0x05361c68) /* 0.325710685 */, 17 }, +/* 2971 */ { MAD_F(0x0536b5be) /* 0.325856916 */, 17 }, +/* 2972 */ { MAD_F(0x05374f17) /* 0.326003163 */, 17 }, +/* 2973 */ { MAD_F(0x0537e876) /* 0.326149427 */, 17 }, +/* 2974 */ { MAD_F(0x053881d9) /* 0.326295707 */, 17 }, +/* 2975 */ { MAD_F(0x05391b40) /* 0.326442003 */, 17 }, + +/* 2976 */ { MAD_F(0x0539b4ab) /* 0.326588316 */, 17 }, +/* 2977 */ { MAD_F(0x053a4e1b) /* 0.326734645 */, 17 }, +/* 2978 */ { MAD_F(0x053ae78f) /* 0.326880990 */, 17 }, +/* 2979 */ { MAD_F(0x053b8108) /* 0.327027352 */, 17 }, +/* 2980 */ { MAD_F(0x053c1a85) /* 0.327173730 */, 17 }, +/* 2981 */ { MAD_F(0x053cb407) /* 0.327320125 */, 17 }, +/* 2982 */ { MAD_F(0x053d4d8d) /* 0.327466536 */, 17 }, +/* 2983 */ { MAD_F(0x053de717) /* 0.327612963 */, 17 }, +/* 2984 */ { MAD_F(0x053e80a6) /* 0.327759407 */, 17 }, +/* 2985 */ { MAD_F(0x053f1a39) /* 0.327905867 */, 17 }, +/* 2986 */ { MAD_F(0x053fb3d0) /* 0.328052344 */, 17 }, +/* 2987 */ { MAD_F(0x05404d6c) /* 0.328198837 */, 17 }, +/* 2988 */ { MAD_F(0x0540e70c) /* 0.328345346 */, 17 }, +/* 2989 */ { MAD_F(0x054180b1) /* 0.328491871 */, 17 }, +/* 2990 */ { MAD_F(0x05421a5a) /* 0.328638413 */, 17 }, +/* 2991 */ { MAD_F(0x0542b407) /* 0.328784971 */, 17 }, + +/* 2992 */ { MAD_F(0x05434db9) /* 0.328931546 */, 17 }, +/* 2993 */ { MAD_F(0x0543e76f) /* 0.329078137 */, 17 }, +/* 2994 */ { MAD_F(0x0544812a) /* 0.329224744 */, 17 }, +/* 2995 */ { MAD_F(0x05451ae9) /* 0.329371367 */, 17 }, +/* 2996 */ { MAD_F(0x0545b4ac) /* 0.329518007 */, 17 }, +/* 2997 */ { MAD_F(0x05464e74) /* 0.329664663 */, 17 }, +/* 2998 */ { MAD_F(0x0546e840) /* 0.329811336 */, 17 }, +/* 2999 */ { MAD_F(0x05478211) /* 0.329958024 */, 17 }, +/* 3000 */ { MAD_F(0x05481be5) /* 0.330104730 */, 17 }, +/* 3001 */ { MAD_F(0x0548b5bf) /* 0.330251451 */, 17 }, +/* 3002 */ { MAD_F(0x05494f9c) /* 0.330398189 */, 17 }, +/* 3003 */ { MAD_F(0x0549e97e) /* 0.330544943 */, 17 }, +/* 3004 */ { MAD_F(0x054a8364) /* 0.330691713 */, 17 }, +/* 3005 */ { MAD_F(0x054b1d4f) /* 0.330838499 */, 17 }, +/* 3006 */ { MAD_F(0x054bb73e) /* 0.330985302 */, 17 }, +/* 3007 */ { MAD_F(0x054c5132) /* 0.331132121 */, 17 }, + +/* 3008 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 17 }, +/* 3009 */ { MAD_F(0x054d8526) /* 0.331425808 */, 17 }, +/* 3010 */ { MAD_F(0x054e1f26) /* 0.331572676 */, 17 }, +/* 3011 */ { MAD_F(0x054eb92b) /* 0.331719560 */, 17 }, +/* 3012 */ { MAD_F(0x054f5334) /* 0.331866461 */, 17 }, +/* 3013 */ { MAD_F(0x054fed42) /* 0.332013377 */, 17 }, +/* 3014 */ { MAD_F(0x05508754) /* 0.332160310 */, 17 }, +/* 3015 */ { MAD_F(0x0551216b) /* 0.332307260 */, 17 }, +/* 3016 */ { MAD_F(0x0551bb85) /* 0.332454225 */, 17 }, +/* 3017 */ { MAD_F(0x055255a4) /* 0.332601207 */, 17 }, +/* 3018 */ { MAD_F(0x0552efc8) /* 0.332748205 */, 17 }, +/* 3019 */ { MAD_F(0x055389f0) /* 0.332895219 */, 17 }, +/* 3020 */ { MAD_F(0x0554241c) /* 0.333042249 */, 17 }, +/* 3021 */ { MAD_F(0x0554be4c) /* 0.333189296 */, 17 }, +/* 3022 */ { MAD_F(0x05555881) /* 0.333336359 */, 17 }, +/* 3023 */ { MAD_F(0x0555f2ba) /* 0.333483438 */, 17 }, + +/* 3024 */ { MAD_F(0x05568cf8) /* 0.333630533 */, 17 }, +/* 3025 */ { MAD_F(0x0557273a) /* 0.333777645 */, 17 }, +/* 3026 */ { MAD_F(0x0557c180) /* 0.333924772 */, 17 }, +/* 3027 */ { MAD_F(0x05585bcb) /* 0.334071916 */, 17 }, +/* 3028 */ { MAD_F(0x0558f61a) /* 0.334219076 */, 17 }, +/* 3029 */ { MAD_F(0x0559906d) /* 0.334366253 */, 17 }, +/* 3030 */ { MAD_F(0x055a2ac5) /* 0.334513445 */, 17 }, +/* 3031 */ { MAD_F(0x055ac521) /* 0.334660654 */, 17 }, +/* 3032 */ { MAD_F(0x055b5f81) /* 0.334807879 */, 17 }, +/* 3033 */ { MAD_F(0x055bf9e6) /* 0.334955120 */, 17 }, +/* 3034 */ { MAD_F(0x055c944f) /* 0.335102377 */, 17 }, +/* 3035 */ { MAD_F(0x055d2ebd) /* 0.335249651 */, 17 }, +/* 3036 */ { MAD_F(0x055dc92e) /* 0.335396941 */, 17 }, +/* 3037 */ { MAD_F(0x055e63a5) /* 0.335544246 */, 17 }, +/* 3038 */ { MAD_F(0x055efe1f) /* 0.335691568 */, 17 }, +/* 3039 */ { MAD_F(0x055f989e) /* 0.335838906 */, 17 }, + +/* 3040 */ { MAD_F(0x05603321) /* 0.335986261 */, 17 }, +/* 3041 */ { MAD_F(0x0560cda8) /* 0.336133631 */, 17 }, +/* 3042 */ { MAD_F(0x05616834) /* 0.336281018 */, 17 }, +/* 3043 */ { MAD_F(0x056202c4) /* 0.336428421 */, 17 }, +/* 3044 */ { MAD_F(0x05629d59) /* 0.336575840 */, 17 }, +/* 3045 */ { MAD_F(0x056337f2) /* 0.336723275 */, 17 }, +/* 3046 */ { MAD_F(0x0563d28f) /* 0.336870726 */, 17 }, +/* 3047 */ { MAD_F(0x05646d30) /* 0.337018193 */, 17 }, +/* 3048 */ { MAD_F(0x056507d6) /* 0.337165677 */, 17 }, +/* 3049 */ { MAD_F(0x0565a280) /* 0.337313176 */, 17 }, +/* 3050 */ { MAD_F(0x05663d2f) /* 0.337460692 */, 17 }, +/* 3051 */ { MAD_F(0x0566d7e1) /* 0.337608224 */, 17 }, +/* 3052 */ { MAD_F(0x05677298) /* 0.337755772 */, 17 }, +/* 3053 */ { MAD_F(0x05680d54) /* 0.337903336 */, 17 }, +/* 3054 */ { MAD_F(0x0568a814) /* 0.338050916 */, 17 }, +/* 3055 */ { MAD_F(0x056942d8) /* 0.338198513 */, 17 }, + +/* 3056 */ { MAD_F(0x0569dda0) /* 0.338346125 */, 17 }, +/* 3057 */ { MAD_F(0x056a786d) /* 0.338493753 */, 17 }, +/* 3058 */ { MAD_F(0x056b133e) /* 0.338641398 */, 17 }, +/* 3059 */ { MAD_F(0x056bae13) /* 0.338789059 */, 17 }, +/* 3060 */ { MAD_F(0x056c48ed) /* 0.338936736 */, 17 }, +/* 3061 */ { MAD_F(0x056ce3cb) /* 0.339084429 */, 17 }, +/* 3062 */ { MAD_F(0x056d7ead) /* 0.339232138 */, 17 }, +/* 3063 */ { MAD_F(0x056e1994) /* 0.339379863 */, 17 }, +/* 3064 */ { MAD_F(0x056eb47f) /* 0.339527604 */, 17 }, +/* 3065 */ { MAD_F(0x056f4f6e) /* 0.339675361 */, 17 }, +/* 3066 */ { MAD_F(0x056fea62) /* 0.339823134 */, 17 }, +/* 3067 */ { MAD_F(0x0570855a) /* 0.339970924 */, 17 }, +/* 3068 */ { MAD_F(0x05712056) /* 0.340118729 */, 17 }, +/* 3069 */ { MAD_F(0x0571bb56) /* 0.340266550 */, 17 }, +/* 3070 */ { MAD_F(0x0572565b) /* 0.340414388 */, 17 }, +/* 3071 */ { MAD_F(0x0572f164) /* 0.340562242 */, 17 }, + +/* 3072 */ { MAD_F(0x05738c72) /* 0.340710111 */, 17 }, +/* 3073 */ { MAD_F(0x05742784) /* 0.340857997 */, 17 }, +/* 3074 */ { MAD_F(0x0574c29a) /* 0.341005899 */, 17 }, +/* 3075 */ { MAD_F(0x05755db4) /* 0.341153816 */, 17 }, +/* 3076 */ { MAD_F(0x0575f8d3) /* 0.341301750 */, 17 }, +/* 3077 */ { MAD_F(0x057693f6) /* 0.341449700 */, 17 }, +/* 3078 */ { MAD_F(0x05772f1d) /* 0.341597666 */, 17 }, +/* 3079 */ { MAD_F(0x0577ca49) /* 0.341745648 */, 17 }, +/* 3080 */ { MAD_F(0x05786578) /* 0.341893646 */, 17 }, +/* 3081 */ { MAD_F(0x057900ad) /* 0.342041659 */, 17 }, +/* 3082 */ { MAD_F(0x05799be5) /* 0.342189689 */, 17 }, +/* 3083 */ { MAD_F(0x057a3722) /* 0.342337735 */, 17 }, +/* 3084 */ { MAD_F(0x057ad263) /* 0.342485797 */, 17 }, +/* 3085 */ { MAD_F(0x057b6da8) /* 0.342633875 */, 17 }, +/* 3086 */ { MAD_F(0x057c08f2) /* 0.342781969 */, 17 }, +/* 3087 */ { MAD_F(0x057ca440) /* 0.342930079 */, 17 }, + +/* 3088 */ { MAD_F(0x057d3f92) /* 0.343078205 */, 17 }, +/* 3089 */ { MAD_F(0x057ddae9) /* 0.343226347 */, 17 }, +/* 3090 */ { MAD_F(0x057e7644) /* 0.343374505 */, 17 }, +/* 3091 */ { MAD_F(0x057f11a3) /* 0.343522679 */, 17 }, +/* 3092 */ { MAD_F(0x057fad06) /* 0.343670869 */, 17 }, +/* 3093 */ { MAD_F(0x0580486e) /* 0.343819075 */, 17 }, +/* 3094 */ { MAD_F(0x0580e3da) /* 0.343967296 */, 17 }, +/* 3095 */ { MAD_F(0x05817f4a) /* 0.344115534 */, 17 }, +/* 3096 */ { MAD_F(0x05821abf) /* 0.344263788 */, 17 }, +/* 3097 */ { MAD_F(0x0582b638) /* 0.344412058 */, 17 }, +/* 3098 */ { MAD_F(0x058351b5) /* 0.344560343 */, 17 }, +/* 3099 */ { MAD_F(0x0583ed36) /* 0.344708645 */, 17 }, +/* 3100 */ { MAD_F(0x058488bc) /* 0.344856963 */, 17 }, +/* 3101 */ { MAD_F(0x05852446) /* 0.345005296 */, 17 }, +/* 3102 */ { MAD_F(0x0585bfd4) /* 0.345153646 */, 17 }, +/* 3103 */ { MAD_F(0x05865b67) /* 0.345302011 */, 17 }, + +/* 3104 */ { MAD_F(0x0586f6fd) /* 0.345450393 */, 17 }, +/* 3105 */ { MAD_F(0x05879298) /* 0.345598790 */, 17 }, +/* 3106 */ { MAD_F(0x05882e38) /* 0.345747203 */, 17 }, +/* 3107 */ { MAD_F(0x0588c9dc) /* 0.345895632 */, 17 }, +/* 3108 */ { MAD_F(0x05896583) /* 0.346044077 */, 17 }, +/* 3109 */ { MAD_F(0x058a0130) /* 0.346192538 */, 17 }, +/* 3110 */ { MAD_F(0x058a9ce0) /* 0.346341015 */, 17 }, +/* 3111 */ { MAD_F(0x058b3895) /* 0.346489508 */, 17 }, +/* 3112 */ { MAD_F(0x058bd44e) /* 0.346638017 */, 17 }, +/* 3113 */ { MAD_F(0x058c700b) /* 0.346786542 */, 17 }, +/* 3114 */ { MAD_F(0x058d0bcd) /* 0.346935082 */, 17 }, +/* 3115 */ { MAD_F(0x058da793) /* 0.347083639 */, 17 }, +/* 3116 */ { MAD_F(0x058e435d) /* 0.347232211 */, 17 }, +/* 3117 */ { MAD_F(0x058edf2b) /* 0.347380799 */, 17 }, +/* 3118 */ { MAD_F(0x058f7afe) /* 0.347529403 */, 17 }, +/* 3119 */ { MAD_F(0x059016d5) /* 0.347678023 */, 17 }, + +/* 3120 */ { MAD_F(0x0590b2b0) /* 0.347826659 */, 17 }, +/* 3121 */ { MAD_F(0x05914e8f) /* 0.347975311 */, 17 }, +/* 3122 */ { MAD_F(0x0591ea73) /* 0.348123979 */, 17 }, +/* 3123 */ { MAD_F(0x0592865b) /* 0.348272662 */, 17 }, +/* 3124 */ { MAD_F(0x05932247) /* 0.348421362 */, 17 }, +/* 3125 */ { MAD_F(0x0593be37) /* 0.348570077 */, 17 }, +/* 3126 */ { MAD_F(0x05945a2c) /* 0.348718808 */, 17 }, +/* 3127 */ { MAD_F(0x0594f625) /* 0.348867555 */, 17 }, +/* 3128 */ { MAD_F(0x05959222) /* 0.349016318 */, 17 }, +/* 3129 */ { MAD_F(0x05962e24) /* 0.349165097 */, 17 }, +/* 3130 */ { MAD_F(0x0596ca2a) /* 0.349313892 */, 17 }, +/* 3131 */ { MAD_F(0x05976634) /* 0.349462702 */, 17 }, +/* 3132 */ { MAD_F(0x05980242) /* 0.349611528 */, 17 }, +/* 3133 */ { MAD_F(0x05989e54) /* 0.349760370 */, 17 }, +/* 3134 */ { MAD_F(0x05993a6b) /* 0.349909228 */, 17 }, +/* 3135 */ { MAD_F(0x0599d686) /* 0.350058102 */, 17 }, + +/* 3136 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 17 }, +/* 3137 */ { MAD_F(0x059b0ec9) /* 0.350355897 */, 17 }, +/* 3138 */ { MAD_F(0x059baaf1) /* 0.350504818 */, 17 }, +/* 3139 */ { MAD_F(0x059c471d) /* 0.350653756 */, 17 }, +/* 3140 */ { MAD_F(0x059ce34d) /* 0.350802708 */, 17 }, +/* 3141 */ { MAD_F(0x059d7f81) /* 0.350951677 */, 17 }, +/* 3142 */ { MAD_F(0x059e1bba) /* 0.351100662 */, 17 }, +/* 3143 */ { MAD_F(0x059eb7f7) /* 0.351249662 */, 17 }, +/* 3144 */ { MAD_F(0x059f5438) /* 0.351398678 */, 17 }, +/* 3145 */ { MAD_F(0x059ff07e) /* 0.351547710 */, 17 }, +/* 3146 */ { MAD_F(0x05a08cc7) /* 0.351696758 */, 17 }, +/* 3147 */ { MAD_F(0x05a12915) /* 0.351845821 */, 17 }, +/* 3148 */ { MAD_F(0x05a1c567) /* 0.351994901 */, 17 }, +/* 3149 */ { MAD_F(0x05a261be) /* 0.352143996 */, 17 }, +/* 3150 */ { MAD_F(0x05a2fe18) /* 0.352293107 */, 17 }, +/* 3151 */ { MAD_F(0x05a39a77) /* 0.352442233 */, 17 }, + +/* 3152 */ { MAD_F(0x05a436da) /* 0.352591376 */, 17 }, +/* 3153 */ { MAD_F(0x05a4d342) /* 0.352740534 */, 17 }, +/* 3154 */ { MAD_F(0x05a56fad) /* 0.352889708 */, 17 }, +/* 3155 */ { MAD_F(0x05a60c1d) /* 0.353038898 */, 17 }, +/* 3156 */ { MAD_F(0x05a6a891) /* 0.353188103 */, 17 }, +/* 3157 */ { MAD_F(0x05a7450a) /* 0.353337325 */, 17 }, +/* 3158 */ { MAD_F(0x05a7e186) /* 0.353486562 */, 17 }, +/* 3159 */ { MAD_F(0x05a87e07) /* 0.353635814 */, 17 }, +/* 3160 */ { MAD_F(0x05a91a8c) /* 0.353785083 */, 17 }, +/* 3161 */ { MAD_F(0x05a9b715) /* 0.353934367 */, 17 }, +/* 3162 */ { MAD_F(0x05aa53a2) /* 0.354083667 */, 17 }, +/* 3163 */ { MAD_F(0x05aaf034) /* 0.354232983 */, 17 }, +/* 3164 */ { MAD_F(0x05ab8cca) /* 0.354382314 */, 17 }, +/* 3165 */ { MAD_F(0x05ac2964) /* 0.354531662 */, 17 }, +/* 3166 */ { MAD_F(0x05acc602) /* 0.354681025 */, 17 }, +/* 3167 */ { MAD_F(0x05ad62a5) /* 0.354830403 */, 17 }, + +/* 3168 */ { MAD_F(0x05adff4c) /* 0.354979798 */, 17 }, +/* 3169 */ { MAD_F(0x05ae9bf7) /* 0.355129208 */, 17 }, +/* 3170 */ { MAD_F(0x05af38a6) /* 0.355278634 */, 17 }, +/* 3171 */ { MAD_F(0x05afd559) /* 0.355428075 */, 17 }, +/* 3172 */ { MAD_F(0x05b07211) /* 0.355577533 */, 17 }, +/* 3173 */ { MAD_F(0x05b10ecd) /* 0.355727006 */, 17 }, +/* 3174 */ { MAD_F(0x05b1ab8d) /* 0.355876494 */, 17 }, +/* 3175 */ { MAD_F(0x05b24851) /* 0.356025999 */, 17 }, +/* 3176 */ { MAD_F(0x05b2e51a) /* 0.356175519 */, 17 }, +/* 3177 */ { MAD_F(0x05b381e6) /* 0.356325054 */, 17 }, +/* 3178 */ { MAD_F(0x05b41eb7) /* 0.356474606 */, 17 }, +/* 3179 */ { MAD_F(0x05b4bb8c) /* 0.356624173 */, 17 }, +/* 3180 */ { MAD_F(0x05b55866) /* 0.356773756 */, 17 }, +/* 3181 */ { MAD_F(0x05b5f543) /* 0.356923354 */, 17 }, +/* 3182 */ { MAD_F(0x05b69225) /* 0.357072969 */, 17 }, +/* 3183 */ { MAD_F(0x05b72f0b) /* 0.357222598 */, 17 }, + +/* 3184 */ { MAD_F(0x05b7cbf5) /* 0.357372244 */, 17 }, +/* 3185 */ { MAD_F(0x05b868e3) /* 0.357521905 */, 17 }, +/* 3186 */ { MAD_F(0x05b905d6) /* 0.357671582 */, 17 }, +/* 3187 */ { MAD_F(0x05b9a2cd) /* 0.357821275 */, 17 }, +/* 3188 */ { MAD_F(0x05ba3fc8) /* 0.357970983 */, 17 }, +/* 3189 */ { MAD_F(0x05badcc7) /* 0.358120707 */, 17 }, +/* 3190 */ { MAD_F(0x05bb79ca) /* 0.358270446 */, 17 }, +/* 3191 */ { MAD_F(0x05bc16d2) /* 0.358420201 */, 17 }, +/* 3192 */ { MAD_F(0x05bcb3de) /* 0.358569972 */, 17 }, +/* 3193 */ { MAD_F(0x05bd50ee) /* 0.358719758 */, 17 }, +/* 3194 */ { MAD_F(0x05bdee02) /* 0.358869560 */, 17 }, +/* 3195 */ { MAD_F(0x05be8b1a) /* 0.359019378 */, 17 }, +/* 3196 */ { MAD_F(0x05bf2837) /* 0.359169211 */, 17 }, +/* 3197 */ { MAD_F(0x05bfc558) /* 0.359319060 */, 17 }, +/* 3198 */ { MAD_F(0x05c0627d) /* 0.359468925 */, 17 }, +/* 3199 */ { MAD_F(0x05c0ffa6) /* 0.359618805 */, 17 }, + +/* 3200 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 17 }, +/* 3201 */ { MAD_F(0x05c23a05) /* 0.359918612 */, 17 }, +/* 3202 */ { MAD_F(0x05c2d73a) /* 0.360068540 */, 17 }, +/* 3203 */ { MAD_F(0x05c37474) /* 0.360218482 */, 17 }, +/* 3204 */ { MAD_F(0x05c411b2) /* 0.360368440 */, 17 }, +/* 3205 */ { MAD_F(0x05c4aef5) /* 0.360518414 */, 17 }, +/* 3206 */ { MAD_F(0x05c54c3b) /* 0.360668404 */, 17 }, +/* 3207 */ { MAD_F(0x05c5e986) /* 0.360818409 */, 17 }, +/* 3208 */ { MAD_F(0x05c686d5) /* 0.360968429 */, 17 }, +/* 3209 */ { MAD_F(0x05c72428) /* 0.361118466 */, 17 }, +/* 3210 */ { MAD_F(0x05c7c17f) /* 0.361268517 */, 17 }, +/* 3211 */ { MAD_F(0x05c85eda) /* 0.361418585 */, 17 }, +/* 3212 */ { MAD_F(0x05c8fc3a) /* 0.361568668 */, 17 }, +/* 3213 */ { MAD_F(0x05c9999e) /* 0.361718766 */, 17 }, +/* 3214 */ { MAD_F(0x05ca3706) /* 0.361868881 */, 17 }, +/* 3215 */ { MAD_F(0x05cad472) /* 0.362019010 */, 17 }, + +/* 3216 */ { MAD_F(0x05cb71e2) /* 0.362169156 */, 17 }, +/* 3217 */ { MAD_F(0x05cc0f57) /* 0.362319316 */, 17 }, +/* 3218 */ { MAD_F(0x05ccaccf) /* 0.362469493 */, 17 }, +/* 3219 */ { MAD_F(0x05cd4a4c) /* 0.362619685 */, 17 }, +/* 3220 */ { MAD_F(0x05cde7cd) /* 0.362769892 */, 17 }, +/* 3221 */ { MAD_F(0x05ce8552) /* 0.362920115 */, 17 }, +/* 3222 */ { MAD_F(0x05cf22dc) /* 0.363070354 */, 17 }, +/* 3223 */ { MAD_F(0x05cfc069) /* 0.363220608 */, 17 }, +/* 3224 */ { MAD_F(0x05d05dfb) /* 0.363370878 */, 17 }, +/* 3225 */ { MAD_F(0x05d0fb91) /* 0.363521163 */, 17 }, +/* 3226 */ { MAD_F(0x05d1992b) /* 0.363671464 */, 17 }, +/* 3227 */ { MAD_F(0x05d236c9) /* 0.363821780 */, 17 }, +/* 3228 */ { MAD_F(0x05d2d46c) /* 0.363972112 */, 17 }, +/* 3229 */ { MAD_F(0x05d37212) /* 0.364122459 */, 17 }, +/* 3230 */ { MAD_F(0x05d40fbd) /* 0.364272822 */, 17 }, +/* 3231 */ { MAD_F(0x05d4ad6c) /* 0.364423200 */, 17 }, + +/* 3232 */ { MAD_F(0x05d54b1f) /* 0.364573594 */, 17 }, +/* 3233 */ { MAD_F(0x05d5e8d6) /* 0.364724004 */, 17 }, +/* 3234 */ { MAD_F(0x05d68691) /* 0.364874429 */, 17 }, +/* 3235 */ { MAD_F(0x05d72451) /* 0.365024869 */, 17 }, +/* 3236 */ { MAD_F(0x05d7c215) /* 0.365175325 */, 17 }, +/* 3237 */ { MAD_F(0x05d85fdc) /* 0.365325796 */, 17 }, +/* 3238 */ { MAD_F(0x05d8fda8) /* 0.365476283 */, 17 }, +/* 3239 */ { MAD_F(0x05d99b79) /* 0.365626786 */, 17 }, +/* 3240 */ { MAD_F(0x05da394d) /* 0.365777304 */, 17 }, +/* 3241 */ { MAD_F(0x05dad726) /* 0.365927837 */, 17 }, +/* 3242 */ { MAD_F(0x05db7502) /* 0.366078386 */, 17 }, +/* 3243 */ { MAD_F(0x05dc12e3) /* 0.366228950 */, 17 }, +/* 3244 */ { MAD_F(0x05dcb0c8) /* 0.366379530 */, 17 }, +/* 3245 */ { MAD_F(0x05dd4eb1) /* 0.366530125 */, 17 }, +/* 3246 */ { MAD_F(0x05ddec9e) /* 0.366680736 */, 17 }, +/* 3247 */ { MAD_F(0x05de8a90) /* 0.366831362 */, 17 }, + +/* 3248 */ { MAD_F(0x05df2885) /* 0.366982004 */, 17 }, +/* 3249 */ { MAD_F(0x05dfc67f) /* 0.367132661 */, 17 }, +/* 3250 */ { MAD_F(0x05e0647d) /* 0.367283334 */, 17 }, +/* 3251 */ { MAD_F(0x05e1027f) /* 0.367434022 */, 17 }, +/* 3252 */ { MAD_F(0x05e1a085) /* 0.367584725 */, 17 }, +/* 3253 */ { MAD_F(0x05e23e8f) /* 0.367735444 */, 17 }, +/* 3254 */ { MAD_F(0x05e2dc9e) /* 0.367886179 */, 17 }, +/* 3255 */ { MAD_F(0x05e37ab0) /* 0.368036929 */, 17 }, +/* 3256 */ { MAD_F(0x05e418c7) /* 0.368187694 */, 17 }, +/* 3257 */ { MAD_F(0x05e4b6e2) /* 0.368338475 */, 17 }, +/* 3258 */ { MAD_F(0x05e55501) /* 0.368489271 */, 17 }, +/* 3259 */ { MAD_F(0x05e5f324) /* 0.368640082 */, 17 }, +/* 3260 */ { MAD_F(0x05e6914c) /* 0.368790909 */, 17 }, +/* 3261 */ { MAD_F(0x05e72f77) /* 0.368941752 */, 17 }, +/* 3262 */ { MAD_F(0x05e7cda7) /* 0.369092610 */, 17 }, +/* 3263 */ { MAD_F(0x05e86bda) /* 0.369243483 */, 17 }, + +/* 3264 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 17 }, +/* 3265 */ { MAD_F(0x05e9a84e) /* 0.369545276 */, 17 }, +/* 3266 */ { MAD_F(0x05ea468e) /* 0.369696195 */, 17 }, +/* 3267 */ { MAD_F(0x05eae4d3) /* 0.369847130 */, 17 }, +/* 3268 */ { MAD_F(0x05eb831b) /* 0.369998080 */, 17 }, +/* 3269 */ { MAD_F(0x05ec2168) /* 0.370149046 */, 17 }, +/* 3270 */ { MAD_F(0x05ecbfb8) /* 0.370300027 */, 17 }, +/* 3271 */ { MAD_F(0x05ed5e0d) /* 0.370451024 */, 17 }, +/* 3272 */ { MAD_F(0x05edfc66) /* 0.370602036 */, 17 }, +/* 3273 */ { MAD_F(0x05ee9ac3) /* 0.370753063 */, 17 }, +/* 3274 */ { MAD_F(0x05ef3924) /* 0.370904105 */, 17 }, +/* 3275 */ { MAD_F(0x05efd78a) /* 0.371055163 */, 17 }, +/* 3276 */ { MAD_F(0x05f075f3) /* 0.371206237 */, 17 }, +/* 3277 */ { MAD_F(0x05f11461) /* 0.371357326 */, 17 }, +/* 3278 */ { MAD_F(0x05f1b2d3) /* 0.371508430 */, 17 }, +/* 3279 */ { MAD_F(0x05f25148) /* 0.371659549 */, 17 }, + +/* 3280 */ { MAD_F(0x05f2efc2) /* 0.371810684 */, 17 }, +/* 3281 */ { MAD_F(0x05f38e40) /* 0.371961834 */, 17 }, +/* 3282 */ { MAD_F(0x05f42cc3) /* 0.372113000 */, 17 }, +/* 3283 */ { MAD_F(0x05f4cb49) /* 0.372264181 */, 17 }, +/* 3284 */ { MAD_F(0x05f569d3) /* 0.372415377 */, 17 }, +/* 3285 */ { MAD_F(0x05f60862) /* 0.372566589 */, 17 }, +/* 3286 */ { MAD_F(0x05f6a6f5) /* 0.372717816 */, 17 }, +/* 3287 */ { MAD_F(0x05f7458b) /* 0.372869058 */, 17 }, +/* 3288 */ { MAD_F(0x05f7e426) /* 0.373020316 */, 17 }, +/* 3289 */ { MAD_F(0x05f882c5) /* 0.373171589 */, 17 }, +/* 3290 */ { MAD_F(0x05f92169) /* 0.373322877 */, 17 }, +/* 3291 */ { MAD_F(0x05f9c010) /* 0.373474181 */, 17 }, +/* 3292 */ { MAD_F(0x05fa5ebb) /* 0.373625500 */, 17 }, +/* 3293 */ { MAD_F(0x05fafd6b) /* 0.373776834 */, 17 }, +/* 3294 */ { MAD_F(0x05fb9c1e) /* 0.373928184 */, 17 }, +/* 3295 */ { MAD_F(0x05fc3ad6) /* 0.374079549 */, 17 }, + +/* 3296 */ { MAD_F(0x05fcd992) /* 0.374230929 */, 17 }, +/* 3297 */ { MAD_F(0x05fd7852) /* 0.374382325 */, 17 }, +/* 3298 */ { MAD_F(0x05fe1716) /* 0.374533735 */, 17 }, +/* 3299 */ { MAD_F(0x05feb5de) /* 0.374685162 */, 17 }, +/* 3300 */ { MAD_F(0x05ff54aa) /* 0.374836603 */, 17 }, +/* 3301 */ { MAD_F(0x05fff37b) /* 0.374988060 */, 17 }, +/* 3302 */ { MAD_F(0x0600924f) /* 0.375139532 */, 17 }, +/* 3303 */ { MAD_F(0x06013128) /* 0.375291019 */, 17 }, +/* 3304 */ { MAD_F(0x0601d004) /* 0.375442522 */, 17 }, +/* 3305 */ { MAD_F(0x06026ee5) /* 0.375594040 */, 17 }, +/* 3306 */ { MAD_F(0x06030dca) /* 0.375745573 */, 17 }, +/* 3307 */ { MAD_F(0x0603acb3) /* 0.375897122 */, 17 }, +/* 3308 */ { MAD_F(0x06044ba0) /* 0.376048685 */, 17 }, +/* 3309 */ { MAD_F(0x0604ea91) /* 0.376200265 */, 17 }, +/* 3310 */ { MAD_F(0x06058987) /* 0.376351859 */, 17 }, +/* 3311 */ { MAD_F(0x06062880) /* 0.376503468 */, 17 }, + +/* 3312 */ { MAD_F(0x0606c77d) /* 0.376655093 */, 17 }, +/* 3313 */ { MAD_F(0x0607667f) /* 0.376806733 */, 17 }, +/* 3314 */ { MAD_F(0x06080585) /* 0.376958389 */, 17 }, +/* 3315 */ { MAD_F(0x0608a48f) /* 0.377110059 */, 17 }, +/* 3316 */ { MAD_F(0x0609439c) /* 0.377261745 */, 17 }, +/* 3317 */ { MAD_F(0x0609e2ae) /* 0.377413446 */, 17 }, +/* 3318 */ { MAD_F(0x060a81c4) /* 0.377565163 */, 17 }, +/* 3319 */ { MAD_F(0x060b20df) /* 0.377716894 */, 17 }, +/* 3320 */ { MAD_F(0x060bbffd) /* 0.377868641 */, 17 }, +/* 3321 */ { MAD_F(0x060c5f1f) /* 0.378020403 */, 17 }, +/* 3322 */ { MAD_F(0x060cfe46) /* 0.378172181 */, 17 }, +/* 3323 */ { MAD_F(0x060d9d70) /* 0.378323973 */, 17 }, +/* 3324 */ { MAD_F(0x060e3c9f) /* 0.378475781 */, 17 }, +/* 3325 */ { MAD_F(0x060edbd1) /* 0.378627604 */, 17 }, +/* 3326 */ { MAD_F(0x060f7b08) /* 0.378779442 */, 17 }, +/* 3327 */ { MAD_F(0x06101a43) /* 0.378931296 */, 17 }, + +/* 3328 */ { MAD_F(0x0610b982) /* 0.379083164 */, 17 }, +/* 3329 */ { MAD_F(0x061158c5) /* 0.379235048 */, 17 }, +/* 3330 */ { MAD_F(0x0611f80c) /* 0.379386947 */, 17 }, +/* 3331 */ { MAD_F(0x06129757) /* 0.379538862 */, 17 }, +/* 3332 */ { MAD_F(0x061336a6) /* 0.379690791 */, 17 }, +/* 3333 */ { MAD_F(0x0613d5fa) /* 0.379842736 */, 17 }, +/* 3334 */ { MAD_F(0x06147551) /* 0.379994696 */, 17 }, +/* 3335 */ { MAD_F(0x061514ad) /* 0.380146671 */, 17 }, +/* 3336 */ { MAD_F(0x0615b40c) /* 0.380298661 */, 17 }, +/* 3337 */ { MAD_F(0x06165370) /* 0.380450666 */, 17 }, +/* 3338 */ { MAD_F(0x0616f2d8) /* 0.380602687 */, 17 }, +/* 3339 */ { MAD_F(0x06179243) /* 0.380754723 */, 17 }, +/* 3340 */ { MAD_F(0x061831b3) /* 0.380906774 */, 17 }, +/* 3341 */ { MAD_F(0x0618d127) /* 0.381058840 */, 17 }, +/* 3342 */ { MAD_F(0x0619709f) /* 0.381210921 */, 17 }, +/* 3343 */ { MAD_F(0x061a101b) /* 0.381363018 */, 17 }, + +/* 3344 */ { MAD_F(0x061aaf9c) /* 0.381515130 */, 17 }, +/* 3345 */ { MAD_F(0x061b4f20) /* 0.381667257 */, 17 }, +/* 3346 */ { MAD_F(0x061beea8) /* 0.381819399 */, 17 }, +/* 3347 */ { MAD_F(0x061c8e34) /* 0.381971556 */, 17 }, +/* 3348 */ { MAD_F(0x061d2dc5) /* 0.382123728 */, 17 }, +/* 3349 */ { MAD_F(0x061dcd59) /* 0.382275916 */, 17 }, +/* 3350 */ { MAD_F(0x061e6cf2) /* 0.382428118 */, 17 }, +/* 3351 */ { MAD_F(0x061f0c8f) /* 0.382580336 */, 17 }, +/* 3352 */ { MAD_F(0x061fac2f) /* 0.382732569 */, 17 }, +/* 3353 */ { MAD_F(0x06204bd4) /* 0.382884817 */, 17 }, +/* 3354 */ { MAD_F(0x0620eb7d) /* 0.383037080 */, 17 }, +/* 3355 */ { MAD_F(0x06218b2a) /* 0.383189358 */, 17 }, +/* 3356 */ { MAD_F(0x06222adb) /* 0.383341652 */, 17 }, +/* 3357 */ { MAD_F(0x0622ca90) /* 0.383493960 */, 17 }, +/* 3358 */ { MAD_F(0x06236a49) /* 0.383646284 */, 17 }, +/* 3359 */ { MAD_F(0x06240a06) /* 0.383798623 */, 17 }, + +/* 3360 */ { MAD_F(0x0624a9c7) /* 0.383950977 */, 17 }, +/* 3361 */ { MAD_F(0x0625498d) /* 0.384103346 */, 17 }, +/* 3362 */ { MAD_F(0x0625e956) /* 0.384255730 */, 17 }, +/* 3363 */ { MAD_F(0x06268923) /* 0.384408129 */, 17 }, +/* 3364 */ { MAD_F(0x062728f5) /* 0.384560544 */, 17 }, +/* 3365 */ { MAD_F(0x0627c8ca) /* 0.384712973 */, 17 }, +/* 3366 */ { MAD_F(0x062868a4) /* 0.384865418 */, 17 }, +/* 3367 */ { MAD_F(0x06290881) /* 0.385017878 */, 17 }, +/* 3368 */ { MAD_F(0x0629a863) /* 0.385170352 */, 17 }, +/* 3369 */ { MAD_F(0x062a4849) /* 0.385322842 */, 17 }, +/* 3370 */ { MAD_F(0x062ae832) /* 0.385475347 */, 17 }, +/* 3371 */ { MAD_F(0x062b8820) /* 0.385627867 */, 17 }, +/* 3372 */ { MAD_F(0x062c2812) /* 0.385780402 */, 17 }, +/* 3373 */ { MAD_F(0x062cc808) /* 0.385932953 */, 17 }, +/* 3374 */ { MAD_F(0x062d6802) /* 0.386085518 */, 17 }, +/* 3375 */ { MAD_F(0x062e0800) /* 0.386238098 */, 17 }, + +/* 3376 */ { MAD_F(0x062ea802) /* 0.386390694 */, 17 }, +/* 3377 */ { MAD_F(0x062f4808) /* 0.386543304 */, 17 }, +/* 3378 */ { MAD_F(0x062fe812) /* 0.386695930 */, 17 }, +/* 3379 */ { MAD_F(0x06308820) /* 0.386848570 */, 17 }, +/* 3380 */ { MAD_F(0x06312832) /* 0.387001226 */, 17 }, +/* 3381 */ { MAD_F(0x0631c849) /* 0.387153897 */, 17 }, +/* 3382 */ { MAD_F(0x06326863) /* 0.387306582 */, 17 }, +/* 3383 */ { MAD_F(0x06330881) /* 0.387459283 */, 17 }, +/* 3384 */ { MAD_F(0x0633a8a3) /* 0.387611999 */, 17 }, +/* 3385 */ { MAD_F(0x063448ca) /* 0.387764730 */, 17 }, +/* 3386 */ { MAD_F(0x0634e8f4) /* 0.387917476 */, 17 }, +/* 3387 */ { MAD_F(0x06358923) /* 0.388070237 */, 17 }, +/* 3388 */ { MAD_F(0x06362955) /* 0.388223013 */, 17 }, +/* 3389 */ { MAD_F(0x0636c98c) /* 0.388375804 */, 17 }, +/* 3390 */ { MAD_F(0x063769c6) /* 0.388528610 */, 17 }, +/* 3391 */ { MAD_F(0x06380a05) /* 0.388681431 */, 17 }, + +/* 3392 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 17 }, +/* 3393 */ { MAD_F(0x06394a8e) /* 0.388987119 */, 17 }, +/* 3394 */ { MAD_F(0x0639ead9) /* 0.389139985 */, 17 }, +/* 3395 */ { MAD_F(0x063a8b28) /* 0.389292866 */, 17 }, +/* 3396 */ { MAD_F(0x063b2b7b) /* 0.389445762 */, 17 }, +/* 3397 */ { MAD_F(0x063bcbd1) /* 0.389598674 */, 17 }, +/* 3398 */ { MAD_F(0x063c6c2c) /* 0.389751600 */, 17 }, +/* 3399 */ { MAD_F(0x063d0c8b) /* 0.389904541 */, 17 }, +/* 3400 */ { MAD_F(0x063dacee) /* 0.390057497 */, 17 }, +/* 3401 */ { MAD_F(0x063e4d55) /* 0.390210468 */, 17 }, +/* 3402 */ { MAD_F(0x063eedc0) /* 0.390363455 */, 17 }, +/* 3403 */ { MAD_F(0x063f8e2f) /* 0.390516456 */, 17 }, +/* 3404 */ { MAD_F(0x06402ea2) /* 0.390669472 */, 17 }, +/* 3405 */ { MAD_F(0x0640cf19) /* 0.390822503 */, 17 }, +/* 3406 */ { MAD_F(0x06416f94) /* 0.390975549 */, 17 }, +/* 3407 */ { MAD_F(0x06421013) /* 0.391128611 */, 17 }, + +/* 3408 */ { MAD_F(0x0642b096) /* 0.391281687 */, 17 }, +/* 3409 */ { MAD_F(0x0643511d) /* 0.391434778 */, 17 }, +/* 3410 */ { MAD_F(0x0643f1a8) /* 0.391587884 */, 17 }, +/* 3411 */ { MAD_F(0x06449237) /* 0.391741005 */, 17 }, +/* 3412 */ { MAD_F(0x064532ca) /* 0.391894141 */, 17 }, +/* 3413 */ { MAD_F(0x0645d361) /* 0.392047292 */, 17 }, +/* 3414 */ { MAD_F(0x064673fc) /* 0.392200458 */, 17 }, +/* 3415 */ { MAD_F(0x0647149c) /* 0.392353638 */, 17 }, +/* 3416 */ { MAD_F(0x0647b53f) /* 0.392506834 */, 17 }, +/* 3417 */ { MAD_F(0x064855e6) /* 0.392660045 */, 17 }, +/* 3418 */ { MAD_F(0x0648f691) /* 0.392813271 */, 17 }, +/* 3419 */ { MAD_F(0x06499740) /* 0.392966511 */, 17 }, +/* 3420 */ { MAD_F(0x064a37f4) /* 0.393119767 */, 17 }, +/* 3421 */ { MAD_F(0x064ad8ab) /* 0.393273038 */, 17 }, +/* 3422 */ { MAD_F(0x064b7966) /* 0.393426323 */, 17 }, +/* 3423 */ { MAD_F(0x064c1a25) /* 0.393579623 */, 17 }, + +/* 3424 */ { MAD_F(0x064cbae9) /* 0.393732939 */, 17 }, +/* 3425 */ { MAD_F(0x064d5bb0) /* 0.393886269 */, 17 }, +/* 3426 */ { MAD_F(0x064dfc7b) /* 0.394039614 */, 17 }, +/* 3427 */ { MAD_F(0x064e9d4b) /* 0.394192974 */, 17 }, +/* 3428 */ { MAD_F(0x064f3e1e) /* 0.394346349 */, 17 }, +/* 3429 */ { MAD_F(0x064fdef5) /* 0.394499739 */, 17 }, +/* 3430 */ { MAD_F(0x06507fd0) /* 0.394653144 */, 17 }, +/* 3431 */ { MAD_F(0x065120b0) /* 0.394806564 */, 17 }, +/* 3432 */ { MAD_F(0x0651c193) /* 0.394959999 */, 17 }, +/* 3433 */ { MAD_F(0x0652627a) /* 0.395113448 */, 17 }, +/* 3434 */ { MAD_F(0x06530366) /* 0.395266913 */, 17 }, +/* 3435 */ { MAD_F(0x0653a455) /* 0.395420392 */, 17 }, +/* 3436 */ { MAD_F(0x06544548) /* 0.395573886 */, 17 }, +/* 3437 */ { MAD_F(0x0654e640) /* 0.395727395 */, 17 }, +/* 3438 */ { MAD_F(0x0655873b) /* 0.395880919 */, 17 }, +/* 3439 */ { MAD_F(0x0656283a) /* 0.396034458 */, 17 }, + +/* 3440 */ { MAD_F(0x0656c93d) /* 0.396188012 */, 17 }, +/* 3441 */ { MAD_F(0x06576a45) /* 0.396341581 */, 17 }, +/* 3442 */ { MAD_F(0x06580b50) /* 0.396495164 */, 17 }, +/* 3443 */ { MAD_F(0x0658ac5f) /* 0.396648763 */, 17 }, +/* 3444 */ { MAD_F(0x06594d73) /* 0.396802376 */, 17 }, +/* 3445 */ { MAD_F(0x0659ee8a) /* 0.396956004 */, 17 }, +/* 3446 */ { MAD_F(0x065a8fa5) /* 0.397109647 */, 17 }, +/* 3447 */ { MAD_F(0x065b30c4) /* 0.397263305 */, 17 }, +/* 3448 */ { MAD_F(0x065bd1e7) /* 0.397416978 */, 17 }, +/* 3449 */ { MAD_F(0x065c730f) /* 0.397570666 */, 17 }, +/* 3450 */ { MAD_F(0x065d143a) /* 0.397724368 */, 17 }, +/* 3451 */ { MAD_F(0x065db569) /* 0.397878085 */, 17 }, +/* 3452 */ { MAD_F(0x065e569c) /* 0.398031818 */, 17 }, +/* 3453 */ { MAD_F(0x065ef7d3) /* 0.398185565 */, 17 }, +/* 3454 */ { MAD_F(0x065f990e) /* 0.398339326 */, 17 }, +/* 3455 */ { MAD_F(0x06603a4e) /* 0.398493103 */, 17 }, + +/* 3456 */ { MAD_F(0x0660db91) /* 0.398646895 */, 17 }, +/* 3457 */ { MAD_F(0x06617cd8) /* 0.398800701 */, 17 }, +/* 3458 */ { MAD_F(0x06621e23) /* 0.398954522 */, 17 }, +/* 3459 */ { MAD_F(0x0662bf72) /* 0.399108358 */, 17 }, +/* 3460 */ { MAD_F(0x066360c5) /* 0.399262209 */, 17 }, +/* 3461 */ { MAD_F(0x0664021c) /* 0.399416075 */, 17 }, +/* 3462 */ { MAD_F(0x0664a377) /* 0.399569955 */, 17 }, +/* 3463 */ { MAD_F(0x066544d6) /* 0.399723851 */, 17 }, +/* 3464 */ { MAD_F(0x0665e639) /* 0.399877761 */, 17 }, +/* 3465 */ { MAD_F(0x066687a0) /* 0.400031686 */, 17 }, +/* 3466 */ { MAD_F(0x0667290b) /* 0.400185625 */, 17 }, +/* 3467 */ { MAD_F(0x0667ca79) /* 0.400339580 */, 17 }, +/* 3468 */ { MAD_F(0x06686bec) /* 0.400493549 */, 17 }, +/* 3469 */ { MAD_F(0x06690d63) /* 0.400647534 */, 17 }, +/* 3470 */ { MAD_F(0x0669aede) /* 0.400801533 */, 17 }, +/* 3471 */ { MAD_F(0x066a505d) /* 0.400955546 */, 17 }, + +/* 3472 */ { MAD_F(0x066af1df) /* 0.401109575 */, 17 }, +/* 3473 */ { MAD_F(0x066b9366) /* 0.401263618 */, 17 }, +/* 3474 */ { MAD_F(0x066c34f1) /* 0.401417676 */, 17 }, +/* 3475 */ { MAD_F(0x066cd67f) /* 0.401571749 */, 17 }, +/* 3476 */ { MAD_F(0x066d7812) /* 0.401725837 */, 17 }, +/* 3477 */ { MAD_F(0x066e19a9) /* 0.401879939 */, 17 }, +/* 3478 */ { MAD_F(0x066ebb43) /* 0.402034056 */, 17 }, +/* 3479 */ { MAD_F(0x066f5ce2) /* 0.402188188 */, 17 }, +/* 3480 */ { MAD_F(0x066ffe84) /* 0.402342335 */, 17 }, +/* 3481 */ { MAD_F(0x0670a02a) /* 0.402496497 */, 17 }, +/* 3482 */ { MAD_F(0x067141d5) /* 0.402650673 */, 17 }, +/* 3483 */ { MAD_F(0x0671e383) /* 0.402804864 */, 17 }, +/* 3484 */ { MAD_F(0x06728535) /* 0.402959070 */, 17 }, +/* 3485 */ { MAD_F(0x067326ec) /* 0.403113291 */, 17 }, +/* 3486 */ { MAD_F(0x0673c8a6) /* 0.403267526 */, 17 }, +/* 3487 */ { MAD_F(0x06746a64) /* 0.403421776 */, 17 }, + +/* 3488 */ { MAD_F(0x06750c26) /* 0.403576041 */, 17 }, +/* 3489 */ { MAD_F(0x0675adec) /* 0.403730320 */, 17 }, +/* 3490 */ { MAD_F(0x06764fb6) /* 0.403884615 */, 17 }, +/* 3491 */ { MAD_F(0x0676f184) /* 0.404038924 */, 17 }, +/* 3492 */ { MAD_F(0x06779356) /* 0.404193247 */, 17 }, +/* 3493 */ { MAD_F(0x0678352c) /* 0.404347586 */, 17 }, +/* 3494 */ { MAD_F(0x0678d706) /* 0.404501939 */, 17 }, +/* 3495 */ { MAD_F(0x067978e4) /* 0.404656307 */, 17 }, +/* 3496 */ { MAD_F(0x067a1ac6) /* 0.404810690 */, 17 }, +/* 3497 */ { MAD_F(0x067abcac) /* 0.404965087 */, 17 }, +/* 3498 */ { MAD_F(0x067b5e95) /* 0.405119499 */, 17 }, +/* 3499 */ { MAD_F(0x067c0083) /* 0.405273926 */, 17 }, +/* 3500 */ { MAD_F(0x067ca275) /* 0.405428368 */, 17 }, +/* 3501 */ { MAD_F(0x067d446a) /* 0.405582824 */, 17 }, +/* 3502 */ { MAD_F(0x067de664) /* 0.405737295 */, 17 }, +/* 3503 */ { MAD_F(0x067e8861) /* 0.405891781 */, 17 }, + +/* 3504 */ { MAD_F(0x067f2a62) /* 0.406046281 */, 17 }, +/* 3505 */ { MAD_F(0x067fcc68) /* 0.406200796 */, 17 }, +/* 3506 */ { MAD_F(0x06806e71) /* 0.406355326 */, 17 }, +/* 3507 */ { MAD_F(0x0681107e) /* 0.406509870 */, 17 }, +/* 3508 */ { MAD_F(0x0681b28f) /* 0.406664429 */, 17 }, +/* 3509 */ { MAD_F(0x068254a4) /* 0.406819003 */, 17 }, +/* 3510 */ { MAD_F(0x0682f6bd) /* 0.406973592 */, 17 }, +/* 3511 */ { MAD_F(0x068398da) /* 0.407128195 */, 17 }, +/* 3512 */ { MAD_F(0x06843afb) /* 0.407282813 */, 17 }, +/* 3513 */ { MAD_F(0x0684dd20) /* 0.407437445 */, 17 }, +/* 3514 */ { MAD_F(0x06857f49) /* 0.407592093 */, 17 }, +/* 3515 */ { MAD_F(0x06862176) /* 0.407746754 */, 17 }, +/* 3516 */ { MAD_F(0x0686c3a6) /* 0.407901431 */, 17 }, +/* 3517 */ { MAD_F(0x068765db) /* 0.408056122 */, 17 }, +/* 3518 */ { MAD_F(0x06880814) /* 0.408210828 */, 17 }, +/* 3519 */ { MAD_F(0x0688aa50) /* 0.408365549 */, 17 }, + +/* 3520 */ { MAD_F(0x06894c90) /* 0.408520284 */, 17 }, +/* 3521 */ { MAD_F(0x0689eed5) /* 0.408675034 */, 17 }, +/* 3522 */ { MAD_F(0x068a911d) /* 0.408829798 */, 17 }, +/* 3523 */ { MAD_F(0x068b3369) /* 0.408984577 */, 17 }, +/* 3524 */ { MAD_F(0x068bd5b9) /* 0.409139371 */, 17 }, +/* 3525 */ { MAD_F(0x068c780e) /* 0.409294180 */, 17 }, +/* 3526 */ { MAD_F(0x068d1a66) /* 0.409449003 */, 17 }, +/* 3527 */ { MAD_F(0x068dbcc1) /* 0.409603840 */, 17 }, +/* 3528 */ { MAD_F(0x068e5f21) /* 0.409758693 */, 17 }, +/* 3529 */ { MAD_F(0x068f0185) /* 0.409913560 */, 17 }, +/* 3530 */ { MAD_F(0x068fa3ed) /* 0.410068441 */, 17 }, +/* 3531 */ { MAD_F(0x06904658) /* 0.410223338 */, 17 }, +/* 3532 */ { MAD_F(0x0690e8c8) /* 0.410378249 */, 17 }, +/* 3533 */ { MAD_F(0x06918b3c) /* 0.410533174 */, 17 }, +/* 3534 */ { MAD_F(0x06922db3) /* 0.410688114 */, 17 }, +/* 3535 */ { MAD_F(0x0692d02e) /* 0.410843069 */, 17 }, + +/* 3536 */ { MAD_F(0x069372ae) /* 0.410998038 */, 17 }, +/* 3537 */ { MAD_F(0x06941531) /* 0.411153022 */, 17 }, +/* 3538 */ { MAD_F(0x0694b7b8) /* 0.411308021 */, 17 }, +/* 3539 */ { MAD_F(0x06955a43) /* 0.411463034 */, 17 }, +/* 3540 */ { MAD_F(0x0695fcd2) /* 0.411618062 */, 17 }, +/* 3541 */ { MAD_F(0x06969f65) /* 0.411773104 */, 17 }, +/* 3542 */ { MAD_F(0x069741fb) /* 0.411928161 */, 17 }, +/* 3543 */ { MAD_F(0x0697e496) /* 0.412083232 */, 17 }, +/* 3544 */ { MAD_F(0x06988735) /* 0.412238319 */, 17 }, +/* 3545 */ { MAD_F(0x069929d7) /* 0.412393419 */, 17 }, +/* 3546 */ { MAD_F(0x0699cc7e) /* 0.412548535 */, 17 }, +/* 3547 */ { MAD_F(0x069a6f28) /* 0.412703664 */, 17 }, +/* 3548 */ { MAD_F(0x069b11d6) /* 0.412858809 */, 17 }, +/* 3549 */ { MAD_F(0x069bb489) /* 0.413013968 */, 17 }, +/* 3550 */ { MAD_F(0x069c573f) /* 0.413169142 */, 17 }, +/* 3551 */ { MAD_F(0x069cf9f9) /* 0.413324330 */, 17 }, + +/* 3552 */ { MAD_F(0x069d9cb7) /* 0.413479532 */, 17 }, +/* 3553 */ { MAD_F(0x069e3f78) /* 0.413634750 */, 17 }, +/* 3554 */ { MAD_F(0x069ee23e) /* 0.413789982 */, 17 }, +/* 3555 */ { MAD_F(0x069f8508) /* 0.413945228 */, 17 }, +/* 3556 */ { MAD_F(0x06a027d5) /* 0.414100489 */, 17 }, +/* 3557 */ { MAD_F(0x06a0caa7) /* 0.414255765 */, 17 }, +/* 3558 */ { MAD_F(0x06a16d7c) /* 0.414411055 */, 17 }, +/* 3559 */ { MAD_F(0x06a21055) /* 0.414566359 */, 17 }, +/* 3560 */ { MAD_F(0x06a2b333) /* 0.414721679 */, 17 }, +/* 3561 */ { MAD_F(0x06a35614) /* 0.414877012 */, 17 }, +/* 3562 */ { MAD_F(0x06a3f8f9) /* 0.415032361 */, 17 }, +/* 3563 */ { MAD_F(0x06a49be2) /* 0.415187723 */, 17 }, +/* 3564 */ { MAD_F(0x06a53ece) /* 0.415343101 */, 17 }, +/* 3565 */ { MAD_F(0x06a5e1bf) /* 0.415498493 */, 17 }, +/* 3566 */ { MAD_F(0x06a684b4) /* 0.415653899 */, 17 }, +/* 3567 */ { MAD_F(0x06a727ac) /* 0.415809320 */, 17 }, + +/* 3568 */ { MAD_F(0x06a7caa9) /* 0.415964756 */, 17 }, +/* 3569 */ { MAD_F(0x06a86da9) /* 0.416120206 */, 17 }, +/* 3570 */ { MAD_F(0x06a910ad) /* 0.416275670 */, 17 }, +/* 3571 */ { MAD_F(0x06a9b3b5) /* 0.416431149 */, 17 }, +/* 3572 */ { MAD_F(0x06aa56c1) /* 0.416586643 */, 17 }, +/* 3573 */ { MAD_F(0x06aaf9d1) /* 0.416742151 */, 17 }, +/* 3574 */ { MAD_F(0x06ab9ce5) /* 0.416897673 */, 17 }, +/* 3575 */ { MAD_F(0x06ac3ffc) /* 0.417053210 */, 17 }, +/* 3576 */ { MAD_F(0x06ace318) /* 0.417208762 */, 17 }, +/* 3577 */ { MAD_F(0x06ad8637) /* 0.417364328 */, 17 }, +/* 3578 */ { MAD_F(0x06ae295b) /* 0.417519909 */, 17 }, +/* 3579 */ { MAD_F(0x06aecc82) /* 0.417675504 */, 17 }, +/* 3580 */ { MAD_F(0x06af6fad) /* 0.417831113 */, 17 }, +/* 3581 */ { MAD_F(0x06b012dc) /* 0.417986737 */, 17 }, +/* 3582 */ { MAD_F(0x06b0b60f) /* 0.418142376 */, 17 }, +/* 3583 */ { MAD_F(0x06b15946) /* 0.418298029 */, 17 }, + +/* 3584 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 17 }, +/* 3585 */ { MAD_F(0x06b29fbf) /* 0.418609378 */, 17 }, +/* 3586 */ { MAD_F(0x06b34302) /* 0.418765075 */, 17 }, +/* 3587 */ { MAD_F(0x06b3e648) /* 0.418920786 */, 17 }, +/* 3588 */ { MAD_F(0x06b48992) /* 0.419076511 */, 17 }, +/* 3589 */ { MAD_F(0x06b52ce0) /* 0.419232251 */, 17 }, +/* 3590 */ { MAD_F(0x06b5d032) /* 0.419388005 */, 17 }, +/* 3591 */ { MAD_F(0x06b67388) /* 0.419543774 */, 17 }, +/* 3592 */ { MAD_F(0x06b716e2) /* 0.419699557 */, 17 }, +/* 3593 */ { MAD_F(0x06b7ba3f) /* 0.419855355 */, 17 }, +/* 3594 */ { MAD_F(0x06b85da1) /* 0.420011167 */, 17 }, +/* 3595 */ { MAD_F(0x06b90106) /* 0.420166994 */, 17 }, +/* 3596 */ { MAD_F(0x06b9a470) /* 0.420322835 */, 17 }, +/* 3597 */ { MAD_F(0x06ba47dd) /* 0.420478690 */, 17 }, +/* 3598 */ { MAD_F(0x06baeb4e) /* 0.420634560 */, 17 }, +/* 3599 */ { MAD_F(0x06bb8ec3) /* 0.420790445 */, 17 }, + +/* 3600 */ { MAD_F(0x06bc323b) /* 0.420946343 */, 17 }, +/* 3601 */ { MAD_F(0x06bcd5b8) /* 0.421102257 */, 17 }, +/* 3602 */ { MAD_F(0x06bd7939) /* 0.421258184 */, 17 }, +/* 3603 */ { MAD_F(0x06be1cbd) /* 0.421414127 */, 17 }, +/* 3604 */ { MAD_F(0x06bec045) /* 0.421570083 */, 17 }, +/* 3605 */ { MAD_F(0x06bf63d1) /* 0.421726054 */, 17 }, +/* 3606 */ { MAD_F(0x06c00761) /* 0.421882040 */, 17 }, +/* 3607 */ { MAD_F(0x06c0aaf5) /* 0.422038039 */, 17 }, +/* 3608 */ { MAD_F(0x06c14e8d) /* 0.422194054 */, 17 }, +/* 3609 */ { MAD_F(0x06c1f229) /* 0.422350082 */, 17 }, +/* 3610 */ { MAD_F(0x06c295c8) /* 0.422506125 */, 17 }, +/* 3611 */ { MAD_F(0x06c3396c) /* 0.422662183 */, 17 }, +/* 3612 */ { MAD_F(0x06c3dd13) /* 0.422818255 */, 17 }, +/* 3613 */ { MAD_F(0x06c480be) /* 0.422974341 */, 17 }, +/* 3614 */ { MAD_F(0x06c5246d) /* 0.423130442 */, 17 }, +/* 3615 */ { MAD_F(0x06c5c820) /* 0.423286557 */, 17 }, + +/* 3616 */ { MAD_F(0x06c66bd6) /* 0.423442686 */, 17 }, +/* 3617 */ { MAD_F(0x06c70f91) /* 0.423598830 */, 17 }, +/* 3618 */ { MAD_F(0x06c7b34f) /* 0.423754988 */, 17 }, +/* 3619 */ { MAD_F(0x06c85712) /* 0.423911161 */, 17 }, +/* 3620 */ { MAD_F(0x06c8fad8) /* 0.424067348 */, 17 }, +/* 3621 */ { MAD_F(0x06c99ea2) /* 0.424223550 */, 17 }, +/* 3622 */ { MAD_F(0x06ca4270) /* 0.424379765 */, 17 }, +/* 3623 */ { MAD_F(0x06cae641) /* 0.424535996 */, 17 }, +/* 3624 */ { MAD_F(0x06cb8a17) /* 0.424692240 */, 17 }, +/* 3625 */ { MAD_F(0x06cc2df0) /* 0.424848499 */, 17 }, +/* 3626 */ { MAD_F(0x06ccd1ce) /* 0.425004772 */, 17 }, +/* 3627 */ { MAD_F(0x06cd75af) /* 0.425161060 */, 17 }, +/* 3628 */ { MAD_F(0x06ce1994) /* 0.425317362 */, 17 }, +/* 3629 */ { MAD_F(0x06cebd7d) /* 0.425473678 */, 17 }, +/* 3630 */ { MAD_F(0x06cf6169) /* 0.425630009 */, 17 }, +/* 3631 */ { MAD_F(0x06d0055a) /* 0.425786354 */, 17 }, + +/* 3632 */ { MAD_F(0x06d0a94e) /* 0.425942714 */, 17 }, +/* 3633 */ { MAD_F(0x06d14d47) /* 0.426099088 */, 17 }, +/* 3634 */ { MAD_F(0x06d1f143) /* 0.426255476 */, 17 }, +/* 3635 */ { MAD_F(0x06d29543) /* 0.426411878 */, 17 }, +/* 3636 */ { MAD_F(0x06d33947) /* 0.426568295 */, 17 }, +/* 3637 */ { MAD_F(0x06d3dd4e) /* 0.426724726 */, 17 }, +/* 3638 */ { MAD_F(0x06d4815a) /* 0.426881172 */, 17 }, +/* 3639 */ { MAD_F(0x06d52569) /* 0.427037632 */, 17 }, +/* 3640 */ { MAD_F(0x06d5c97c) /* 0.427194106 */, 17 }, +/* 3641 */ { MAD_F(0x06d66d93) /* 0.427350594 */, 17 }, +/* 3642 */ { MAD_F(0x06d711ae) /* 0.427507097 */, 17 }, +/* 3643 */ { MAD_F(0x06d7b5cd) /* 0.427663614 */, 17 }, +/* 3644 */ { MAD_F(0x06d859f0) /* 0.427820146 */, 17 }, +/* 3645 */ { MAD_F(0x06d8fe16) /* 0.427976692 */, 17 }, +/* 3646 */ { MAD_F(0x06d9a240) /* 0.428133252 */, 17 }, +/* 3647 */ { MAD_F(0x06da466f) /* 0.428289826 */, 17 }, + +/* 3648 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 17 }, +/* 3649 */ { MAD_F(0x06db8ed6) /* 0.428603018 */, 17 }, +/* 3650 */ { MAD_F(0x06dc3310) /* 0.428759635 */, 17 }, +/* 3651 */ { MAD_F(0x06dcd74d) /* 0.428916267 */, 17 }, +/* 3652 */ { MAD_F(0x06dd7b8f) /* 0.429072913 */, 17 }, +/* 3653 */ { MAD_F(0x06de1fd4) /* 0.429229573 */, 17 }, +/* 3654 */ { MAD_F(0x06dec41d) /* 0.429386248 */, 17 }, +/* 3655 */ { MAD_F(0x06df686a) /* 0.429542937 */, 17 }, +/* 3656 */ { MAD_F(0x06e00cbb) /* 0.429699640 */, 17 }, +/* 3657 */ { MAD_F(0x06e0b10f) /* 0.429856357 */, 17 }, +/* 3658 */ { MAD_F(0x06e15567) /* 0.430013089 */, 17 }, +/* 3659 */ { MAD_F(0x06e1f9c4) /* 0.430169835 */, 17 }, +/* 3660 */ { MAD_F(0x06e29e24) /* 0.430326595 */, 17 }, +/* 3661 */ { MAD_F(0x06e34287) /* 0.430483370 */, 17 }, +/* 3662 */ { MAD_F(0x06e3e6ef) /* 0.430640159 */, 17 }, +/* 3663 */ { MAD_F(0x06e48b5b) /* 0.430796962 */, 17 }, + +/* 3664 */ { MAD_F(0x06e52fca) /* 0.430953779 */, 17 }, +/* 3665 */ { MAD_F(0x06e5d43d) /* 0.431110611 */, 17 }, +/* 3666 */ { MAD_F(0x06e678b4) /* 0.431267457 */, 17 }, +/* 3667 */ { MAD_F(0x06e71d2f) /* 0.431424317 */, 17 }, +/* 3668 */ { MAD_F(0x06e7c1ae) /* 0.431581192 */, 17 }, +/* 3669 */ { MAD_F(0x06e86630) /* 0.431738080 */, 17 }, +/* 3670 */ { MAD_F(0x06e90ab7) /* 0.431894983 */, 17 }, +/* 3671 */ { MAD_F(0x06e9af41) /* 0.432051900 */, 17 }, +/* 3672 */ { MAD_F(0x06ea53cf) /* 0.432208832 */, 17 }, +/* 3673 */ { MAD_F(0x06eaf860) /* 0.432365778 */, 17 }, +/* 3674 */ { MAD_F(0x06eb9cf6) /* 0.432522737 */, 17 }, +/* 3675 */ { MAD_F(0x06ec418f) /* 0.432679712 */, 17 }, +/* 3676 */ { MAD_F(0x06ece62d) /* 0.432836700 */, 17 }, +/* 3677 */ { MAD_F(0x06ed8ace) /* 0.432993703 */, 17 }, +/* 3678 */ { MAD_F(0x06ee2f73) /* 0.433150720 */, 17 }, +/* 3679 */ { MAD_F(0x06eed41b) /* 0.433307751 */, 17 }, + +/* 3680 */ { MAD_F(0x06ef78c8) /* 0.433464796 */, 17 }, +/* 3681 */ { MAD_F(0x06f01d78) /* 0.433621856 */, 17 }, +/* 3682 */ { MAD_F(0x06f0c22c) /* 0.433778929 */, 17 }, +/* 3683 */ { MAD_F(0x06f166e4) /* 0.433936017 */, 17 }, +/* 3684 */ { MAD_F(0x06f20ba0) /* 0.434093120 */, 17 }, +/* 3685 */ { MAD_F(0x06f2b060) /* 0.434250236 */, 17 }, +/* 3686 */ { MAD_F(0x06f35523) /* 0.434407367 */, 17 }, +/* 3687 */ { MAD_F(0x06f3f9eb) /* 0.434564512 */, 17 }, +/* 3688 */ { MAD_F(0x06f49eb6) /* 0.434721671 */, 17 }, +/* 3689 */ { MAD_F(0x06f54385) /* 0.434878844 */, 17 }, +/* 3690 */ { MAD_F(0x06f5e857) /* 0.435036032 */, 17 }, +/* 3691 */ { MAD_F(0x06f68d2e) /* 0.435193233 */, 17 }, +/* 3692 */ { MAD_F(0x06f73208) /* 0.435350449 */, 17 }, +/* 3693 */ { MAD_F(0x06f7d6e6) /* 0.435507679 */, 17 }, +/* 3694 */ { MAD_F(0x06f87bc8) /* 0.435664924 */, 17 }, +/* 3695 */ { MAD_F(0x06f920ae) /* 0.435822182 */, 17 }, + +/* 3696 */ { MAD_F(0x06f9c597) /* 0.435979455 */, 17 }, +/* 3697 */ { MAD_F(0x06fa6a85) /* 0.436136741 */, 17 }, +/* 3698 */ { MAD_F(0x06fb0f76) /* 0.436294042 */, 17 }, +/* 3699 */ { MAD_F(0x06fbb46b) /* 0.436451358 */, 17 }, +/* 3700 */ { MAD_F(0x06fc5964) /* 0.436608687 */, 17 }, +/* 3701 */ { MAD_F(0x06fcfe60) /* 0.436766031 */, 17 }, +/* 3702 */ { MAD_F(0x06fda361) /* 0.436923388 */, 17 }, +/* 3703 */ { MAD_F(0x06fe4865) /* 0.437080760 */, 17 }, +/* 3704 */ { MAD_F(0x06feed6d) /* 0.437238146 */, 17 }, +/* 3705 */ { MAD_F(0x06ff9279) /* 0.437395547 */, 17 }, +/* 3706 */ { MAD_F(0x07003788) /* 0.437552961 */, 17 }, +/* 3707 */ { MAD_F(0x0700dc9c) /* 0.437710389 */, 17 }, +/* 3708 */ { MAD_F(0x070181b3) /* 0.437867832 */, 17 }, +/* 3709 */ { MAD_F(0x070226ce) /* 0.438025289 */, 17 }, +/* 3710 */ { MAD_F(0x0702cbed) /* 0.438182760 */, 17 }, +/* 3711 */ { MAD_F(0x0703710f) /* 0.438340245 */, 17 }, + +/* 3712 */ { MAD_F(0x07041636) /* 0.438497744 */, 17 }, +/* 3713 */ { MAD_F(0x0704bb60) /* 0.438655258 */, 17 }, +/* 3714 */ { MAD_F(0x0705608e) /* 0.438812785 */, 17 }, +/* 3715 */ { MAD_F(0x070605c0) /* 0.438970327 */, 17 }, +/* 3716 */ { MAD_F(0x0706aaf5) /* 0.439127883 */, 17 }, +/* 3717 */ { MAD_F(0x0707502f) /* 0.439285453 */, 17 }, +/* 3718 */ { MAD_F(0x0707f56c) /* 0.439443037 */, 17 }, +/* 3719 */ { MAD_F(0x07089aad) /* 0.439600635 */, 17 }, +/* 3720 */ { MAD_F(0x07093ff2) /* 0.439758248 */, 17 }, +/* 3721 */ { MAD_F(0x0709e53a) /* 0.439915874 */, 17 }, +/* 3722 */ { MAD_F(0x070a8a86) /* 0.440073515 */, 17 }, +/* 3723 */ { MAD_F(0x070b2fd7) /* 0.440231170 */, 17 }, +/* 3724 */ { MAD_F(0x070bd52a) /* 0.440388839 */, 17 }, +/* 3725 */ { MAD_F(0x070c7a82) /* 0.440546522 */, 17 }, +/* 3726 */ { MAD_F(0x070d1fde) /* 0.440704219 */, 17 }, +/* 3727 */ { MAD_F(0x070dc53d) /* 0.440861930 */, 17 }, + +/* 3728 */ { MAD_F(0x070e6aa0) /* 0.441019655 */, 17 }, +/* 3729 */ { MAD_F(0x070f1007) /* 0.441177395 */, 17 }, +/* 3730 */ { MAD_F(0x070fb571) /* 0.441335148 */, 17 }, +/* 3731 */ { MAD_F(0x07105ae0) /* 0.441492916 */, 17 }, +/* 3732 */ { MAD_F(0x07110052) /* 0.441650697 */, 17 }, +/* 3733 */ { MAD_F(0x0711a5c8) /* 0.441808493 */, 17 }, +/* 3734 */ { MAD_F(0x07124b42) /* 0.441966303 */, 17 }, +/* 3735 */ { MAD_F(0x0712f0bf) /* 0.442124127 */, 17 }, +/* 3736 */ { MAD_F(0x07139641) /* 0.442281965 */, 17 }, +/* 3737 */ { MAD_F(0x07143bc6) /* 0.442439817 */, 17 }, +/* 3738 */ { MAD_F(0x0714e14f) /* 0.442597683 */, 17 }, +/* 3739 */ { MAD_F(0x071586db) /* 0.442755564 */, 17 }, +/* 3740 */ { MAD_F(0x07162c6c) /* 0.442913458 */, 17 }, +/* 3741 */ { MAD_F(0x0716d200) /* 0.443071366 */, 17 }, +/* 3742 */ { MAD_F(0x07177798) /* 0.443229289 */, 17 }, +/* 3743 */ { MAD_F(0x07181d34) /* 0.443387226 */, 17 }, + +/* 3744 */ { MAD_F(0x0718c2d3) /* 0.443545176 */, 17 }, +/* 3745 */ { MAD_F(0x07196877) /* 0.443703141 */, 17 }, +/* 3746 */ { MAD_F(0x071a0e1e) /* 0.443861120 */, 17 }, +/* 3747 */ { MAD_F(0x071ab3c9) /* 0.444019113 */, 17 }, +/* 3748 */ { MAD_F(0x071b5977) /* 0.444177119 */, 17 }, +/* 3749 */ { MAD_F(0x071bff2a) /* 0.444335140 */, 17 }, +/* 3750 */ { MAD_F(0x071ca4e0) /* 0.444493175 */, 17 }, +/* 3751 */ { MAD_F(0x071d4a9a) /* 0.444651224 */, 17 }, +/* 3752 */ { MAD_F(0x071df058) /* 0.444809288 */, 17 }, +/* 3753 */ { MAD_F(0x071e9619) /* 0.444967365 */, 17 }, +/* 3754 */ { MAD_F(0x071f3bde) /* 0.445125456 */, 17 }, +/* 3755 */ { MAD_F(0x071fe1a8) /* 0.445283561 */, 17 }, +/* 3756 */ { MAD_F(0x07208774) /* 0.445441680 */, 17 }, +/* 3757 */ { MAD_F(0x07212d45) /* 0.445599814 */, 17 }, +/* 3758 */ { MAD_F(0x0721d319) /* 0.445757961 */, 17 }, +/* 3759 */ { MAD_F(0x072278f1) /* 0.445916122 */, 17 }, + +/* 3760 */ { MAD_F(0x07231ecd) /* 0.446074298 */, 17 }, +/* 3761 */ { MAD_F(0x0723c4ad) /* 0.446232487 */, 17 }, +/* 3762 */ { MAD_F(0x07246a90) /* 0.446390690 */, 17 }, +/* 3763 */ { MAD_F(0x07251077) /* 0.446548908 */, 17 }, +/* 3764 */ { MAD_F(0x0725b662) /* 0.446707139 */, 17 }, +/* 3765 */ { MAD_F(0x07265c51) /* 0.446865385 */, 17 }, +/* 3766 */ { MAD_F(0x07270244) /* 0.447023644 */, 17 }, +/* 3767 */ { MAD_F(0x0727a83a) /* 0.447181918 */, 17 }, +/* 3768 */ { MAD_F(0x07284e34) /* 0.447340205 */, 17 }, +/* 3769 */ { MAD_F(0x0728f431) /* 0.447498507 */, 17 }, +/* 3770 */ { MAD_F(0x07299a33) /* 0.447656822 */, 17 }, +/* 3771 */ { MAD_F(0x072a4038) /* 0.447815152 */, 17 }, +/* 3772 */ { MAD_F(0x072ae641) /* 0.447973495 */, 17 }, +/* 3773 */ { MAD_F(0x072b8c4e) /* 0.448131853 */, 17 }, +/* 3774 */ { MAD_F(0x072c325e) /* 0.448290224 */, 17 }, +/* 3775 */ { MAD_F(0x072cd873) /* 0.448448609 */, 17 }, + +/* 3776 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 17 }, +/* 3777 */ { MAD_F(0x072e24a7) /* 0.448765422 */, 17 }, +/* 3778 */ { MAD_F(0x072ecac6) /* 0.448923850 */, 17 }, +/* 3779 */ { MAD_F(0x072f70e9) /* 0.449082291 */, 17 }, +/* 3780 */ { MAD_F(0x07301710) /* 0.449240746 */, 17 }, +/* 3781 */ { MAD_F(0x0730bd3b) /* 0.449399216 */, 17 }, +/* 3782 */ { MAD_F(0x0731636a) /* 0.449557699 */, 17 }, +/* 3783 */ { MAD_F(0x0732099c) /* 0.449716196 */, 17 }, +/* 3784 */ { MAD_F(0x0732afd2) /* 0.449874708 */, 17 }, +/* 3785 */ { MAD_F(0x0733560c) /* 0.450033233 */, 17 }, +/* 3786 */ { MAD_F(0x0733fc49) /* 0.450191772 */, 17 }, +/* 3787 */ { MAD_F(0x0734a28b) /* 0.450350325 */, 17 }, +/* 3788 */ { MAD_F(0x073548d0) /* 0.450508892 */, 17 }, +/* 3789 */ { MAD_F(0x0735ef18) /* 0.450667473 */, 17 }, +/* 3790 */ { MAD_F(0x07369565) /* 0.450826068 */, 17 }, +/* 3791 */ { MAD_F(0x07373bb5) /* 0.450984677 */, 17 }, + +/* 3792 */ { MAD_F(0x0737e209) /* 0.451143300 */, 17 }, +/* 3793 */ { MAD_F(0x07388861) /* 0.451301937 */, 17 }, +/* 3794 */ { MAD_F(0x07392ebc) /* 0.451460588 */, 17 }, +/* 3795 */ { MAD_F(0x0739d51c) /* 0.451619252 */, 17 }, +/* 3796 */ { MAD_F(0x073a7b7f) /* 0.451777931 */, 17 }, +/* 3797 */ { MAD_F(0x073b21e5) /* 0.451936623 */, 17 }, +/* 3798 */ { MAD_F(0x073bc850) /* 0.452095330 */, 17 }, +/* 3799 */ { MAD_F(0x073c6ebe) /* 0.452254050 */, 17 }, +/* 3800 */ { MAD_F(0x073d1530) /* 0.452412785 */, 17 }, +/* 3801 */ { MAD_F(0x073dbba6) /* 0.452571533 */, 17 }, +/* 3802 */ { MAD_F(0x073e621f) /* 0.452730295 */, 17 }, +/* 3803 */ { MAD_F(0x073f089c) /* 0.452889071 */, 17 }, +/* 3804 */ { MAD_F(0x073faf1d) /* 0.453047861 */, 17 }, +/* 3805 */ { MAD_F(0x074055a2) /* 0.453206665 */, 17 }, +/* 3806 */ { MAD_F(0x0740fc2a) /* 0.453365483 */, 17 }, +/* 3807 */ { MAD_F(0x0741a2b6) /* 0.453524315 */, 17 }, + +/* 3808 */ { MAD_F(0x07424946) /* 0.453683161 */, 17 }, +/* 3809 */ { MAD_F(0x0742efd9) /* 0.453842020 */, 17 }, +/* 3810 */ { MAD_F(0x07439671) /* 0.454000894 */, 17 }, +/* 3811 */ { MAD_F(0x07443d0c) /* 0.454159781 */, 17 }, +/* 3812 */ { MAD_F(0x0744e3aa) /* 0.454318683 */, 17 }, +/* 3813 */ { MAD_F(0x07458a4d) /* 0.454477598 */, 17 }, +/* 3814 */ { MAD_F(0x074630f3) /* 0.454636527 */, 17 }, +/* 3815 */ { MAD_F(0x0746d79d) /* 0.454795470 */, 17 }, +/* 3816 */ { MAD_F(0x07477e4b) /* 0.454954427 */, 17 }, +/* 3817 */ { MAD_F(0x074824fc) /* 0.455113397 */, 17 }, +/* 3818 */ { MAD_F(0x0748cbb1) /* 0.455272382 */, 17 }, +/* 3819 */ { MAD_F(0x0749726a) /* 0.455431381 */, 17 }, +/* 3820 */ { MAD_F(0x074a1927) /* 0.455590393 */, 17 }, +/* 3821 */ { MAD_F(0x074abfe7) /* 0.455749419 */, 17 }, +/* 3822 */ { MAD_F(0x074b66ab) /* 0.455908459 */, 17 }, +/* 3823 */ { MAD_F(0x074c0d73) /* 0.456067513 */, 17 }, + +/* 3824 */ { MAD_F(0x074cb43e) /* 0.456226581 */, 17 }, +/* 3825 */ { MAD_F(0x074d5b0d) /* 0.456385663 */, 17 }, +/* 3826 */ { MAD_F(0x074e01e0) /* 0.456544759 */, 17 }, +/* 3827 */ { MAD_F(0x074ea8b7) /* 0.456703868 */, 17 }, +/* 3828 */ { MAD_F(0x074f4f91) /* 0.456862992 */, 17 }, +/* 3829 */ { MAD_F(0x074ff66f) /* 0.457022129 */, 17 }, +/* 3830 */ { MAD_F(0x07509d51) /* 0.457181280 */, 17 }, +/* 3831 */ { MAD_F(0x07514437) /* 0.457340445 */, 17 }, +/* 3832 */ { MAD_F(0x0751eb20) /* 0.457499623 */, 17 }, +/* 3833 */ { MAD_F(0x0752920d) /* 0.457658816 */, 17 }, +/* 3834 */ { MAD_F(0x075338fd) /* 0.457818022 */, 17 }, +/* 3835 */ { MAD_F(0x0753dff2) /* 0.457977243 */, 17 }, +/* 3836 */ { MAD_F(0x075486ea) /* 0.458136477 */, 17 }, +/* 3837 */ { MAD_F(0x07552de6) /* 0.458295725 */, 17 }, +/* 3838 */ { MAD_F(0x0755d4e5) /* 0.458454987 */, 17 }, +/* 3839 */ { MAD_F(0x07567be8) /* 0.458614262 */, 17 }, + +/* 3840 */ { MAD_F(0x075722ef) /* 0.458773552 */, 17 }, +/* 3841 */ { MAD_F(0x0757c9fa) /* 0.458932855 */, 17 }, +/* 3842 */ { MAD_F(0x07587108) /* 0.459092172 */, 17 }, +/* 3843 */ { MAD_F(0x0759181a) /* 0.459251503 */, 17 }, +/* 3844 */ { MAD_F(0x0759bf30) /* 0.459410848 */, 17 }, +/* 3845 */ { MAD_F(0x075a664a) /* 0.459570206 */, 17 }, +/* 3846 */ { MAD_F(0x075b0d67) /* 0.459729579 */, 17 }, +/* 3847 */ { MAD_F(0x075bb488) /* 0.459888965 */, 17 }, +/* 3848 */ { MAD_F(0x075c5bac) /* 0.460048365 */, 17 }, +/* 3849 */ { MAD_F(0x075d02d5) /* 0.460207779 */, 17 }, +/* 3850 */ { MAD_F(0x075daa01) /* 0.460367206 */, 17 }, +/* 3851 */ { MAD_F(0x075e5130) /* 0.460526648 */, 17 }, +/* 3852 */ { MAD_F(0x075ef864) /* 0.460686103 */, 17 }, +/* 3853 */ { MAD_F(0x075f9f9b) /* 0.460845572 */, 17 }, +/* 3854 */ { MAD_F(0x076046d6) /* 0.461005055 */, 17 }, +/* 3855 */ { MAD_F(0x0760ee14) /* 0.461164552 */, 17 }, + +/* 3856 */ { MAD_F(0x07619557) /* 0.461324062 */, 17 }, +/* 3857 */ { MAD_F(0x07623c9d) /* 0.461483586 */, 17 }, +/* 3858 */ { MAD_F(0x0762e3e6) /* 0.461643124 */, 17 }, +/* 3859 */ { MAD_F(0x07638b34) /* 0.461802676 */, 17 }, +/* 3860 */ { MAD_F(0x07643285) /* 0.461962242 */, 17 }, +/* 3861 */ { MAD_F(0x0764d9d9) /* 0.462121821 */, 17 }, +/* 3862 */ { MAD_F(0x07658132) /* 0.462281414 */, 17 }, +/* 3863 */ { MAD_F(0x0766288e) /* 0.462441021 */, 17 }, +/* 3864 */ { MAD_F(0x0766cfee) /* 0.462600642 */, 17 }, +/* 3865 */ { MAD_F(0x07677751) /* 0.462760276 */, 17 }, +/* 3866 */ { MAD_F(0x07681eb9) /* 0.462919924 */, 17 }, +/* 3867 */ { MAD_F(0x0768c624) /* 0.463079586 */, 17 }, +/* 3868 */ { MAD_F(0x07696d92) /* 0.463239262 */, 17 }, +/* 3869 */ { MAD_F(0x076a1505) /* 0.463398951 */, 17 }, +/* 3870 */ { MAD_F(0x076abc7b) /* 0.463558655 */, 17 }, +/* 3871 */ { MAD_F(0x076b63f4) /* 0.463718372 */, 17 }, + +/* 3872 */ { MAD_F(0x076c0b72) /* 0.463878102 */, 17 }, +/* 3873 */ { MAD_F(0x076cb2f3) /* 0.464037847 */, 17 }, +/* 3874 */ { MAD_F(0x076d5a78) /* 0.464197605 */, 17 }, +/* 3875 */ { MAD_F(0x076e0200) /* 0.464357377 */, 17 }, +/* 3876 */ { MAD_F(0x076ea98c) /* 0.464517163 */, 17 }, +/* 3877 */ { MAD_F(0x076f511c) /* 0.464676962 */, 17 }, +/* 3878 */ { MAD_F(0x076ff8b0) /* 0.464836776 */, 17 }, +/* 3879 */ { MAD_F(0x0770a047) /* 0.464996603 */, 17 }, +/* 3880 */ { MAD_F(0x077147e2) /* 0.465156443 */, 17 }, +/* 3881 */ { MAD_F(0x0771ef80) /* 0.465316298 */, 17 }, +/* 3882 */ { MAD_F(0x07729723) /* 0.465476166 */, 17 }, +/* 3883 */ { MAD_F(0x07733ec9) /* 0.465636048 */, 17 }, +/* 3884 */ { MAD_F(0x0773e672) /* 0.465795943 */, 17 }, +/* 3885 */ { MAD_F(0x07748e20) /* 0.465955853 */, 17 }, +/* 3886 */ { MAD_F(0x077535d1) /* 0.466115776 */, 17 }, +/* 3887 */ { MAD_F(0x0775dd85) /* 0.466275713 */, 17 }, + +/* 3888 */ { MAD_F(0x0776853e) /* 0.466435663 */, 17 }, +/* 3889 */ { MAD_F(0x07772cfa) /* 0.466595627 */, 17 }, +/* 3890 */ { MAD_F(0x0777d4ba) /* 0.466755605 */, 17 }, +/* 3891 */ { MAD_F(0x07787c7d) /* 0.466915597 */, 17 }, +/* 3892 */ { MAD_F(0x07792444) /* 0.467075602 */, 17 }, +/* 3893 */ { MAD_F(0x0779cc0f) /* 0.467235621 */, 17 }, +/* 3894 */ { MAD_F(0x077a73dd) /* 0.467395654 */, 17 }, +/* 3895 */ { MAD_F(0x077b1baf) /* 0.467555701 */, 17 }, +/* 3896 */ { MAD_F(0x077bc385) /* 0.467715761 */, 17 }, +/* 3897 */ { MAD_F(0x077c6b5f) /* 0.467875835 */, 17 }, +/* 3898 */ { MAD_F(0x077d133c) /* 0.468035922 */, 17 }, +/* 3899 */ { MAD_F(0x077dbb1d) /* 0.468196023 */, 17 }, +/* 3900 */ { MAD_F(0x077e6301) /* 0.468356138 */, 17 }, +/* 3901 */ { MAD_F(0x077f0ae9) /* 0.468516267 */, 17 }, +/* 3902 */ { MAD_F(0x077fb2d5) /* 0.468676409 */, 17 }, +/* 3903 */ { MAD_F(0x07805ac5) /* 0.468836565 */, 17 }, + +/* 3904 */ { MAD_F(0x078102b8) /* 0.468996735 */, 17 }, +/* 3905 */ { MAD_F(0x0781aaaf) /* 0.469156918 */, 17 }, +/* 3906 */ { MAD_F(0x078252aa) /* 0.469317115 */, 17 }, +/* 3907 */ { MAD_F(0x0782faa8) /* 0.469477326 */, 17 }, +/* 3908 */ { MAD_F(0x0783a2aa) /* 0.469637550 */, 17 }, +/* 3909 */ { MAD_F(0x07844aaf) /* 0.469797788 */, 17 }, +/* 3910 */ { MAD_F(0x0784f2b8) /* 0.469958040 */, 17 }, +/* 3911 */ { MAD_F(0x07859ac5) /* 0.470118305 */, 17 }, +/* 3912 */ { MAD_F(0x078642d6) /* 0.470278584 */, 17 }, +/* 3913 */ { MAD_F(0x0786eaea) /* 0.470438877 */, 17 }, +/* 3914 */ { MAD_F(0x07879302) /* 0.470599183 */, 17 }, +/* 3915 */ { MAD_F(0x07883b1e) /* 0.470759503 */, 17 }, +/* 3916 */ { MAD_F(0x0788e33d) /* 0.470919836 */, 17 }, +/* 3917 */ { MAD_F(0x07898b60) /* 0.471080184 */, 17 }, +/* 3918 */ { MAD_F(0x078a3386) /* 0.471240545 */, 17 }, +/* 3919 */ { MAD_F(0x078adbb0) /* 0.471400919 */, 17 }, + +/* 3920 */ { MAD_F(0x078b83de) /* 0.471561307 */, 17 }, +/* 3921 */ { MAD_F(0x078c2c10) /* 0.471721709 */, 17 }, +/* 3922 */ { MAD_F(0x078cd445) /* 0.471882125 */, 17 }, +/* 3923 */ { MAD_F(0x078d7c7e) /* 0.472042554 */, 17 }, +/* 3924 */ { MAD_F(0x078e24ba) /* 0.472202996 */, 17 }, +/* 3925 */ { MAD_F(0x078eccfb) /* 0.472363453 */, 17 }, +/* 3926 */ { MAD_F(0x078f753e) /* 0.472523923 */, 17 }, +/* 3927 */ { MAD_F(0x07901d86) /* 0.472684406 */, 17 }, +/* 3928 */ { MAD_F(0x0790c5d1) /* 0.472844904 */, 17 }, +/* 3929 */ { MAD_F(0x07916e20) /* 0.473005414 */, 17 }, +/* 3930 */ { MAD_F(0x07921672) /* 0.473165939 */, 17 }, +/* 3931 */ { MAD_F(0x0792bec8) /* 0.473326477 */, 17 }, +/* 3932 */ { MAD_F(0x07936722) /* 0.473487029 */, 17 }, +/* 3933 */ { MAD_F(0x07940f80) /* 0.473647594 */, 17 }, +/* 3934 */ { MAD_F(0x0794b7e1) /* 0.473808173 */, 17 }, +/* 3935 */ { MAD_F(0x07956045) /* 0.473968765 */, 17 }, + +/* 3936 */ { MAD_F(0x079608ae) /* 0.474129372 */, 17 }, +/* 3937 */ { MAD_F(0x0796b11a) /* 0.474289991 */, 17 }, +/* 3938 */ { MAD_F(0x0797598a) /* 0.474450625 */, 17 }, +/* 3939 */ { MAD_F(0x079801fd) /* 0.474611272 */, 17 }, +/* 3940 */ { MAD_F(0x0798aa74) /* 0.474771932 */, 17 }, +/* 3941 */ { MAD_F(0x079952ee) /* 0.474932606 */, 17 }, +/* 3942 */ { MAD_F(0x0799fb6d) /* 0.475093294 */, 17 }, +/* 3943 */ { MAD_F(0x079aa3ef) /* 0.475253995 */, 17 }, +/* 3944 */ { MAD_F(0x079b4c74) /* 0.475414710 */, 17 }, +/* 3945 */ { MAD_F(0x079bf4fd) /* 0.475575439 */, 17 }, +/* 3946 */ { MAD_F(0x079c9d8a) /* 0.475736181 */, 17 }, +/* 3947 */ { MAD_F(0x079d461b) /* 0.475896936 */, 17 }, +/* 3948 */ { MAD_F(0x079deeaf) /* 0.476057705 */, 17 }, +/* 3949 */ { MAD_F(0x079e9747) /* 0.476218488 */, 17 }, +/* 3950 */ { MAD_F(0x079f3fe2) /* 0.476379285 */, 17 }, +/* 3951 */ { MAD_F(0x079fe881) /* 0.476540095 */, 17 }, + +/* 3952 */ { MAD_F(0x07a09124) /* 0.476700918 */, 17 }, +/* 3953 */ { MAD_F(0x07a139ca) /* 0.476861755 */, 17 }, +/* 3954 */ { MAD_F(0x07a1e274) /* 0.477022606 */, 17 }, +/* 3955 */ { MAD_F(0x07a28b22) /* 0.477183470 */, 17 }, +/* 3956 */ { MAD_F(0x07a333d3) /* 0.477344348 */, 17 }, +/* 3957 */ { MAD_F(0x07a3dc88) /* 0.477505239 */, 17 }, +/* 3958 */ { MAD_F(0x07a48541) /* 0.477666144 */, 17 }, +/* 3959 */ { MAD_F(0x07a52dfd) /* 0.477827062 */, 17 }, +/* 3960 */ { MAD_F(0x07a5d6bd) /* 0.477987994 */, 17 }, +/* 3961 */ { MAD_F(0x07a67f80) /* 0.478148940 */, 17 }, +/* 3962 */ { MAD_F(0x07a72847) /* 0.478309899 */, 17 }, +/* 3963 */ { MAD_F(0x07a7d112) /* 0.478470871 */, 17 }, +/* 3964 */ { MAD_F(0x07a879e1) /* 0.478631857 */, 17 }, +/* 3965 */ { MAD_F(0x07a922b3) /* 0.478792857 */, 17 }, +/* 3966 */ { MAD_F(0x07a9cb88) /* 0.478953870 */, 17 }, +/* 3967 */ { MAD_F(0x07aa7462) /* 0.479114897 */, 17 }, + +/* 3968 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 17 }, +/* 3969 */ { MAD_F(0x07abc61f) /* 0.479436991 */, 17 }, +/* 3970 */ { MAD_F(0x07ac6f03) /* 0.479598058 */, 17 }, +/* 3971 */ { MAD_F(0x07ad17eb) /* 0.479759139 */, 17 }, +/* 3972 */ { MAD_F(0x07adc0d6) /* 0.479920233 */, 17 }, +/* 3973 */ { MAD_F(0x07ae69c6) /* 0.480081341 */, 17 }, +/* 3974 */ { MAD_F(0x07af12b8) /* 0.480242463 */, 17 }, +/* 3975 */ { MAD_F(0x07afbbaf) /* 0.480403598 */, 17 }, +/* 3976 */ { MAD_F(0x07b064a8) /* 0.480564746 */, 17 }, +/* 3977 */ { MAD_F(0x07b10da6) /* 0.480725908 */, 17 }, +/* 3978 */ { MAD_F(0x07b1b6a7) /* 0.480887083 */, 17 }, +/* 3979 */ { MAD_F(0x07b25fac) /* 0.481048272 */, 17 }, +/* 3980 */ { MAD_F(0x07b308b5) /* 0.481209475 */, 17 }, +/* 3981 */ { MAD_F(0x07b3b1c1) /* 0.481370691 */, 17 }, +/* 3982 */ { MAD_F(0x07b45ad0) /* 0.481531920 */, 17 }, +/* 3983 */ { MAD_F(0x07b503e4) /* 0.481693163 */, 17 }, + +/* 3984 */ { MAD_F(0x07b5acfb) /* 0.481854420 */, 17 }, +/* 3985 */ { MAD_F(0x07b65615) /* 0.482015690 */, 17 }, +/* 3986 */ { MAD_F(0x07b6ff33) /* 0.482176973 */, 17 }, +/* 3987 */ { MAD_F(0x07b7a855) /* 0.482338270 */, 17 }, +/* 3988 */ { MAD_F(0x07b8517b) /* 0.482499580 */, 17 }, +/* 3989 */ { MAD_F(0x07b8faa4) /* 0.482660904 */, 17 }, +/* 3990 */ { MAD_F(0x07b9a3d0) /* 0.482822242 */, 17 }, +/* 3991 */ { MAD_F(0x07ba4d01) /* 0.482983592 */, 17 }, +/* 3992 */ { MAD_F(0x07baf635) /* 0.483144957 */, 17 }, +/* 3993 */ { MAD_F(0x07bb9f6c) /* 0.483306335 */, 17 }, +/* 3994 */ { MAD_F(0x07bc48a7) /* 0.483467726 */, 17 }, +/* 3995 */ { MAD_F(0x07bcf1e6) /* 0.483629131 */, 17 }, +/* 3996 */ { MAD_F(0x07bd9b28) /* 0.483790549 */, 17 }, +/* 3997 */ { MAD_F(0x07be446e) /* 0.483951980 */, 17 }, +/* 3998 */ { MAD_F(0x07beedb8) /* 0.484113426 */, 17 }, +/* 3999 */ { MAD_F(0x07bf9705) /* 0.484274884 */, 17 }, + +/* 4000 */ { MAD_F(0x07c04056) /* 0.484436356 */, 17 }, +/* 4001 */ { MAD_F(0x07c0e9aa) /* 0.484597842 */, 17 }, +/* 4002 */ { MAD_F(0x07c19302) /* 0.484759341 */, 17 }, +/* 4003 */ { MAD_F(0x07c23c5e) /* 0.484920853 */, 17 }, +/* 4004 */ { MAD_F(0x07c2e5bd) /* 0.485082379 */, 17 }, +/* 4005 */ { MAD_F(0x07c38f20) /* 0.485243918 */, 17 }, +/* 4006 */ { MAD_F(0x07c43887) /* 0.485405471 */, 17 }, +/* 4007 */ { MAD_F(0x07c4e1f1) /* 0.485567037 */, 17 }, +/* 4008 */ { MAD_F(0x07c58b5f) /* 0.485728617 */, 17 }, +/* 4009 */ { MAD_F(0x07c634d0) /* 0.485890210 */, 17 }, +/* 4010 */ { MAD_F(0x07c6de45) /* 0.486051817 */, 17 }, +/* 4011 */ { MAD_F(0x07c787bd) /* 0.486213436 */, 17 }, +/* 4012 */ { MAD_F(0x07c83139) /* 0.486375070 */, 17 }, +/* 4013 */ { MAD_F(0x07c8dab9) /* 0.486536717 */, 17 }, +/* 4014 */ { MAD_F(0x07c9843c) /* 0.486698377 */, 17 }, +/* 4015 */ { MAD_F(0x07ca2dc3) /* 0.486860051 */, 17 }, + +/* 4016 */ { MAD_F(0x07cad74e) /* 0.487021738 */, 17 }, +/* 4017 */ { MAD_F(0x07cb80dc) /* 0.487183438 */, 17 }, +/* 4018 */ { MAD_F(0x07cc2a6e) /* 0.487345152 */, 17 }, +/* 4019 */ { MAD_F(0x07ccd403) /* 0.487506879 */, 17 }, +/* 4020 */ { MAD_F(0x07cd7d9c) /* 0.487668620 */, 17 }, +/* 4021 */ { MAD_F(0x07ce2739) /* 0.487830374 */, 17 }, +/* 4022 */ { MAD_F(0x07ced0d9) /* 0.487992142 */, 17 }, +/* 4023 */ { MAD_F(0x07cf7a7d) /* 0.488153923 */, 17 }, +/* 4024 */ { MAD_F(0x07d02424) /* 0.488315717 */, 17 }, +/* 4025 */ { MAD_F(0x07d0cdcf) /* 0.488477525 */, 17 }, +/* 4026 */ { MAD_F(0x07d1777e) /* 0.488639346 */, 17 }, +/* 4027 */ { MAD_F(0x07d22130) /* 0.488801181 */, 17 }, +/* 4028 */ { MAD_F(0x07d2cae5) /* 0.488963029 */, 17 }, +/* 4029 */ { MAD_F(0x07d3749f) /* 0.489124890 */, 17 }, +/* 4030 */ { MAD_F(0x07d41e5c) /* 0.489286765 */, 17 }, +/* 4031 */ { MAD_F(0x07d4c81c) /* 0.489448653 */, 17 }, + +/* 4032 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 17 }, +/* 4033 */ { MAD_F(0x07d61ba8) /* 0.489772470 */, 17 }, +/* 4034 */ { MAD_F(0x07d6c573) /* 0.489934398 */, 17 }, +/* 4035 */ { MAD_F(0x07d76f42) /* 0.490096340 */, 17 }, +/* 4036 */ { MAD_F(0x07d81915) /* 0.490258295 */, 17 }, +/* 4037 */ { MAD_F(0x07d8c2eb) /* 0.490420263 */, 17 }, +/* 4038 */ { MAD_F(0x07d96cc4) /* 0.490582245 */, 17 }, +/* 4039 */ { MAD_F(0x07da16a2) /* 0.490744240 */, 17 }, +/* 4040 */ { MAD_F(0x07dac083) /* 0.490906249 */, 17 }, +/* 4041 */ { MAD_F(0x07db6a67) /* 0.491068271 */, 17 }, +/* 4042 */ { MAD_F(0x07dc144f) /* 0.491230306 */, 17 }, +/* 4043 */ { MAD_F(0x07dcbe3b) /* 0.491392355 */, 17 }, +/* 4044 */ { MAD_F(0x07dd682a) /* 0.491554417 */, 17 }, +/* 4045 */ { MAD_F(0x07de121d) /* 0.491716492 */, 17 }, +/* 4046 */ { MAD_F(0x07debc13) /* 0.491878581 */, 17 }, +/* 4047 */ { MAD_F(0x07df660d) /* 0.492040683 */, 17 }, + +/* 4048 */ { MAD_F(0x07e0100a) /* 0.492202799 */, 17 }, +/* 4049 */ { MAD_F(0x07e0ba0c) /* 0.492364928 */, 17 }, +/* 4050 */ { MAD_F(0x07e16410) /* 0.492527070 */, 17 }, +/* 4051 */ { MAD_F(0x07e20e19) /* 0.492689225 */, 17 }, +/* 4052 */ { MAD_F(0x07e2b824) /* 0.492851394 */, 17 }, +/* 4053 */ { MAD_F(0x07e36234) /* 0.493013576 */, 17 }, +/* 4054 */ { MAD_F(0x07e40c47) /* 0.493175772 */, 17 }, +/* 4055 */ { MAD_F(0x07e4b65e) /* 0.493337981 */, 17 }, +/* 4056 */ { MAD_F(0x07e56078) /* 0.493500203 */, 17 }, +/* 4057 */ { MAD_F(0x07e60a95) /* 0.493662438 */, 17 }, +/* 4058 */ { MAD_F(0x07e6b4b7) /* 0.493824687 */, 17 }, +/* 4059 */ { MAD_F(0x07e75edc) /* 0.493986949 */, 17 }, +/* 4060 */ { MAD_F(0x07e80904) /* 0.494149225 */, 17 }, +/* 4061 */ { MAD_F(0x07e8b330) /* 0.494311514 */, 17 }, +/* 4062 */ { MAD_F(0x07e95d60) /* 0.494473816 */, 17 }, +/* 4063 */ { MAD_F(0x07ea0793) /* 0.494636131 */, 17 }, + +/* 4064 */ { MAD_F(0x07eab1ca) /* 0.494798460 */, 17 }, +/* 4065 */ { MAD_F(0x07eb5c04) /* 0.494960802 */, 17 }, +/* 4066 */ { MAD_F(0x07ec0642) /* 0.495123158 */, 17 }, +/* 4067 */ { MAD_F(0x07ecb084) /* 0.495285526 */, 17 }, +/* 4068 */ { MAD_F(0x07ed5ac9) /* 0.495447908 */, 17 }, +/* 4069 */ { MAD_F(0x07ee0512) /* 0.495610304 */, 17 }, +/* 4070 */ { MAD_F(0x07eeaf5e) /* 0.495772712 */, 17 }, +/* 4071 */ { MAD_F(0x07ef59ae) /* 0.495935134 */, 17 }, +/* 4072 */ { MAD_F(0x07f00401) /* 0.496097570 */, 17 }, +/* 4073 */ { MAD_F(0x07f0ae58) /* 0.496260018 */, 17 }, +/* 4074 */ { MAD_F(0x07f158b3) /* 0.496422480 */, 17 }, +/* 4075 */ { MAD_F(0x07f20311) /* 0.496584955 */, 17 }, +/* 4076 */ { MAD_F(0x07f2ad72) /* 0.496747444 */, 17 }, +/* 4077 */ { MAD_F(0x07f357d8) /* 0.496909945 */, 17 }, +/* 4078 */ { MAD_F(0x07f40240) /* 0.497072460 */, 17 }, +/* 4079 */ { MAD_F(0x07f4acad) /* 0.497234989 */, 17 }, + +/* 4080 */ { MAD_F(0x07f5571d) /* 0.497397530 */, 17 }, +/* 4081 */ { MAD_F(0x07f60190) /* 0.497560085 */, 17 }, +/* 4082 */ { MAD_F(0x07f6ac07) /* 0.497722653 */, 17 }, +/* 4083 */ { MAD_F(0x07f75682) /* 0.497885235 */, 17 }, +/* 4084 */ { MAD_F(0x07f80100) /* 0.498047829 */, 17 }, +/* 4085 */ { MAD_F(0x07f8ab82) /* 0.498210437 */, 17 }, +/* 4086 */ { MAD_F(0x07f95607) /* 0.498373058 */, 17 }, +/* 4087 */ { MAD_F(0x07fa0090) /* 0.498535693 */, 17 }, +/* 4088 */ { MAD_F(0x07faab1c) /* 0.498698341 */, 17 }, +/* 4089 */ { MAD_F(0x07fb55ac) /* 0.498861002 */, 17 }, +/* 4090 */ { MAD_F(0x07fc0040) /* 0.499023676 */, 17 }, +/* 4091 */ { MAD_F(0x07fcaad7) /* 0.499186364 */, 17 }, +/* 4092 */ { MAD_F(0x07fd5572) /* 0.499349064 */, 17 }, +/* 4093 */ { MAD_F(0x07fe0010) /* 0.499511778 */, 17 }, +/* 4094 */ { MAD_F(0x07feaab2) /* 0.499674506 */, 17 }, +/* 4095 */ { MAD_F(0x07ff5557) /* 0.499837246 */, 17 }, + +/* 4096 */ { MAD_F(0x04000000) /* 0.250000000 */, 18 }, +/* 4097 */ { MAD_F(0x04005556) /* 0.250081384 */, 18 }, +/* 4098 */ { MAD_F(0x0400aaae) /* 0.250162774 */, 18 }, +/* 4099 */ { MAD_F(0x04010008) /* 0.250244170 */, 18 }, +/* 4100 */ { MAD_F(0x04015563) /* 0.250325574 */, 18 }, +/* 4101 */ { MAD_F(0x0401aac1) /* 0.250406984 */, 18 }, +/* 4102 */ { MAD_F(0x04020020) /* 0.250488400 */, 18 }, +/* 4103 */ { MAD_F(0x04025581) /* 0.250569824 */, 18 }, +/* 4104 */ { MAD_F(0x0402aae3) /* 0.250651254 */, 18 }, +/* 4105 */ { MAD_F(0x04030048) /* 0.250732690 */, 18 }, +/* 4106 */ { MAD_F(0x040355ae) /* 0.250814133 */, 18 }, +/* 4107 */ { MAD_F(0x0403ab16) /* 0.250895583 */, 18 }, +/* 4108 */ { MAD_F(0x04040080) /* 0.250977039 */, 18 }, +/* 4109 */ { MAD_F(0x040455eb) /* 0.251058502 */, 18 }, +/* 4110 */ { MAD_F(0x0404ab59) /* 0.251139971 */, 18 }, +/* 4111 */ { MAD_F(0x040500c8) /* 0.251221448 */, 18 }, + +/* 4112 */ { MAD_F(0x04055638) /* 0.251302930 */, 18 }, +/* 4113 */ { MAD_F(0x0405abab) /* 0.251384420 */, 18 }, +/* 4114 */ { MAD_F(0x0406011f) /* 0.251465916 */, 18 }, +/* 4115 */ { MAD_F(0x04065696) /* 0.251547418 */, 18 }, +/* 4116 */ { MAD_F(0x0406ac0e) /* 0.251628927 */, 18 }, +/* 4117 */ { MAD_F(0x04070187) /* 0.251710443 */, 18 }, +/* 4118 */ { MAD_F(0x04075703) /* 0.251791965 */, 18 }, +/* 4119 */ { MAD_F(0x0407ac80) /* 0.251873494 */, 18 }, +/* 4120 */ { MAD_F(0x040801ff) /* 0.251955030 */, 18 }, +/* 4121 */ { MAD_F(0x04085780) /* 0.252036572 */, 18 }, +/* 4122 */ { MAD_F(0x0408ad02) /* 0.252118121 */, 18 }, +/* 4123 */ { MAD_F(0x04090287) /* 0.252199676 */, 18 }, +/* 4124 */ { MAD_F(0x0409580d) /* 0.252281238 */, 18 }, +/* 4125 */ { MAD_F(0x0409ad95) /* 0.252362807 */, 18 }, +/* 4126 */ { MAD_F(0x040a031e) /* 0.252444382 */, 18 }, +/* 4127 */ { MAD_F(0x040a58aa) /* 0.252525963 */, 18 }, + +/* 4128 */ { MAD_F(0x040aae37) /* 0.252607552 */, 18 }, +/* 4129 */ { MAD_F(0x040b03c6) /* 0.252689147 */, 18 }, +/* 4130 */ { MAD_F(0x040b5957) /* 0.252770748 */, 18 }, +/* 4131 */ { MAD_F(0x040baee9) /* 0.252852356 */, 18 }, +/* 4132 */ { MAD_F(0x040c047e) /* 0.252933971 */, 18 }, +/* 4133 */ { MAD_F(0x040c5a14) /* 0.253015592 */, 18 }, +/* 4134 */ { MAD_F(0x040cafab) /* 0.253097220 */, 18 }, +/* 4135 */ { MAD_F(0x040d0545) /* 0.253178854 */, 18 }, +/* 4136 */ { MAD_F(0x040d5ae0) /* 0.253260495 */, 18 }, +/* 4137 */ { MAD_F(0x040db07d) /* 0.253342143 */, 18 }, +/* 4138 */ { MAD_F(0x040e061c) /* 0.253423797 */, 18 }, +/* 4139 */ { MAD_F(0x040e5bbd) /* 0.253505457 */, 18 }, +/* 4140 */ { MAD_F(0x040eb15f) /* 0.253587125 */, 18 }, +/* 4141 */ { MAD_F(0x040f0703) /* 0.253668799 */, 18 }, +/* 4142 */ { MAD_F(0x040f5ca9) /* 0.253750479 */, 18 }, +/* 4143 */ { MAD_F(0x040fb251) /* 0.253832166 */, 18 }, + +/* 4144 */ { MAD_F(0x041007fa) /* 0.253913860 */, 18 }, +/* 4145 */ { MAD_F(0x04105da6) /* 0.253995560 */, 18 }, +/* 4146 */ { MAD_F(0x0410b353) /* 0.254077266 */, 18 }, +/* 4147 */ { MAD_F(0x04110901) /* 0.254158980 */, 18 }, +/* 4148 */ { MAD_F(0x04115eb2) /* 0.254240700 */, 18 }, +/* 4149 */ { MAD_F(0x0411b464) /* 0.254322426 */, 18 }, +/* 4150 */ { MAD_F(0x04120a18) /* 0.254404159 */, 18 }, +/* 4151 */ { MAD_F(0x04125fce) /* 0.254485899 */, 18 }, +/* 4152 */ { MAD_F(0x0412b586) /* 0.254567645 */, 18 }, +/* 4153 */ { MAD_F(0x04130b3f) /* 0.254649397 */, 18 }, +/* 4154 */ { MAD_F(0x041360fa) /* 0.254731157 */, 18 }, +/* 4155 */ { MAD_F(0x0413b6b7) /* 0.254812922 */, 18 }, +/* 4156 */ { MAD_F(0x04140c75) /* 0.254894695 */, 18 }, +/* 4157 */ { MAD_F(0x04146236) /* 0.254976474 */, 18 }, +/* 4158 */ { MAD_F(0x0414b7f8) /* 0.255058259 */, 18 }, +/* 4159 */ { MAD_F(0x04150dbc) /* 0.255140051 */, 18 }, + +/* 4160 */ { MAD_F(0x04156381) /* 0.255221850 */, 18 }, +/* 4161 */ { MAD_F(0x0415b949) /* 0.255303655 */, 18 }, +/* 4162 */ { MAD_F(0x04160f12) /* 0.255385467 */, 18 }, +/* 4163 */ { MAD_F(0x041664dd) /* 0.255467285 */, 18 }, +/* 4164 */ { MAD_F(0x0416baaa) /* 0.255549110 */, 18 }, +/* 4165 */ { MAD_F(0x04171078) /* 0.255630941 */, 18 }, +/* 4166 */ { MAD_F(0x04176648) /* 0.255712779 */, 18 }, +/* 4167 */ { MAD_F(0x0417bc1a) /* 0.255794624 */, 18 }, +/* 4168 */ { MAD_F(0x041811ee) /* 0.255876475 */, 18 }, +/* 4169 */ { MAD_F(0x041867c3) /* 0.255958332 */, 18 }, +/* 4170 */ { MAD_F(0x0418bd9b) /* 0.256040196 */, 18 }, +/* 4171 */ { MAD_F(0x04191374) /* 0.256122067 */, 18 }, +/* 4172 */ { MAD_F(0x0419694e) /* 0.256203944 */, 18 }, +/* 4173 */ { MAD_F(0x0419bf2b) /* 0.256285828 */, 18 }, +/* 4174 */ { MAD_F(0x041a1509) /* 0.256367718 */, 18 }, +/* 4175 */ { MAD_F(0x041a6ae9) /* 0.256449615 */, 18 }, + +/* 4176 */ { MAD_F(0x041ac0cb) /* 0.256531518 */, 18 }, +/* 4177 */ { MAD_F(0x041b16ae) /* 0.256613428 */, 18 }, +/* 4178 */ { MAD_F(0x041b6c94) /* 0.256695344 */, 18 }, +/* 4179 */ { MAD_F(0x041bc27b) /* 0.256777267 */, 18 }, +/* 4180 */ { MAD_F(0x041c1863) /* 0.256859197 */, 18 }, +/* 4181 */ { MAD_F(0x041c6e4e) /* 0.256941133 */, 18 }, +/* 4182 */ { MAD_F(0x041cc43a) /* 0.257023076 */, 18 }, +/* 4183 */ { MAD_F(0x041d1a28) /* 0.257105025 */, 18 }, +/* 4184 */ { MAD_F(0x041d7018) /* 0.257186980 */, 18 }, +/* 4185 */ { MAD_F(0x041dc60a) /* 0.257268942 */, 18 }, +/* 4186 */ { MAD_F(0x041e1bfd) /* 0.257350911 */, 18 }, +/* 4187 */ { MAD_F(0x041e71f2) /* 0.257432886 */, 18 }, +/* 4188 */ { MAD_F(0x041ec7e9) /* 0.257514868 */, 18 }, +/* 4189 */ { MAD_F(0x041f1de1) /* 0.257596856 */, 18 }, +/* 4190 */ { MAD_F(0x041f73dc) /* 0.257678851 */, 18 }, +/* 4191 */ { MAD_F(0x041fc9d8) /* 0.257760852 */, 18 }, + +/* 4192 */ { MAD_F(0x04201fd5) /* 0.257842860 */, 18 }, +/* 4193 */ { MAD_F(0x042075d5) /* 0.257924875 */, 18 }, +/* 4194 */ { MAD_F(0x0420cbd6) /* 0.258006895 */, 18 }, +/* 4195 */ { MAD_F(0x042121d9) /* 0.258088923 */, 18 }, +/* 4196 */ { MAD_F(0x042177de) /* 0.258170957 */, 18 }, +/* 4197 */ { MAD_F(0x0421cde5) /* 0.258252997 */, 18 }, +/* 4198 */ { MAD_F(0x042223ed) /* 0.258335044 */, 18 }, +/* 4199 */ { MAD_F(0x042279f7) /* 0.258417097 */, 18 }, +/* 4200 */ { MAD_F(0x0422d003) /* 0.258499157 */, 18 }, +/* 4201 */ { MAD_F(0x04232611) /* 0.258581224 */, 18 }, +/* 4202 */ { MAD_F(0x04237c20) /* 0.258663297 */, 18 }, +/* 4203 */ { MAD_F(0x0423d231) /* 0.258745376 */, 18 }, +/* 4204 */ { MAD_F(0x04242844) /* 0.258827462 */, 18 }, +/* 4205 */ { MAD_F(0x04247e58) /* 0.258909555 */, 18 }, +/* 4206 */ { MAD_F(0x0424d46e) /* 0.258991654 */, 18 }, +/* 4207 */ { MAD_F(0x04252a87) /* 0.259073760 */, 18 }, + +/* 4208 */ { MAD_F(0x042580a0) /* 0.259155872 */, 18 }, +/* 4209 */ { MAD_F(0x0425d6bc) /* 0.259237990 */, 18 }, +/* 4210 */ { MAD_F(0x04262cd9) /* 0.259320115 */, 18 }, +/* 4211 */ { MAD_F(0x042682f8) /* 0.259402247 */, 18 }, +/* 4212 */ { MAD_F(0x0426d919) /* 0.259484385 */, 18 }, +/* 4213 */ { MAD_F(0x04272f3b) /* 0.259566529 */, 18 }, +/* 4214 */ { MAD_F(0x04278560) /* 0.259648680 */, 18 }, +/* 4215 */ { MAD_F(0x0427db86) /* 0.259730838 */, 18 }, +/* 4216 */ { MAD_F(0x042831ad) /* 0.259813002 */, 18 }, +/* 4217 */ { MAD_F(0x042887d7) /* 0.259895173 */, 18 }, +/* 4218 */ { MAD_F(0x0428de02) /* 0.259977350 */, 18 }, +/* 4219 */ { MAD_F(0x0429342f) /* 0.260059533 */, 18 }, +/* 4220 */ { MAD_F(0x04298a5e) /* 0.260141723 */, 18 }, +/* 4221 */ { MAD_F(0x0429e08e) /* 0.260223920 */, 18 }, +/* 4222 */ { MAD_F(0x042a36c0) /* 0.260306123 */, 18 }, +/* 4223 */ { MAD_F(0x042a8cf4) /* 0.260388332 */, 18 }, + +/* 4224 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 18 }, +/* 4225 */ { MAD_F(0x042b3962) /* 0.260552771 */, 18 }, +/* 4226 */ { MAD_F(0x042b8f9b) /* 0.260635000 */, 18 }, +/* 4227 */ { MAD_F(0x042be5d6) /* 0.260717235 */, 18 }, +/* 4228 */ { MAD_F(0x042c3c12) /* 0.260799477 */, 18 }, +/* 4229 */ { MAD_F(0x042c9251) /* 0.260881725 */, 18 }, +/* 4230 */ { MAD_F(0x042ce891) /* 0.260963980 */, 18 }, +/* 4231 */ { MAD_F(0x042d3ed3) /* 0.261046242 */, 18 }, +/* 4232 */ { MAD_F(0x042d9516) /* 0.261128510 */, 18 }, +/* 4233 */ { MAD_F(0x042deb5c) /* 0.261210784 */, 18 }, +/* 4234 */ { MAD_F(0x042e41a3) /* 0.261293065 */, 18 }, +/* 4235 */ { MAD_F(0x042e97ec) /* 0.261375352 */, 18 }, +/* 4236 */ { MAD_F(0x042eee36) /* 0.261457646 */, 18 }, +/* 4237 */ { MAD_F(0x042f4482) /* 0.261539946 */, 18 }, +/* 4238 */ { MAD_F(0x042f9ad1) /* 0.261622253 */, 18 }, +/* 4239 */ { MAD_F(0x042ff120) /* 0.261704566 */, 18 }, + +/* 4240 */ { MAD_F(0x04304772) /* 0.261786886 */, 18 }, +/* 4241 */ { MAD_F(0x04309dc5) /* 0.261869212 */, 18 }, +/* 4242 */ { MAD_F(0x0430f41a) /* 0.261951545 */, 18 }, +/* 4243 */ { MAD_F(0x04314a71) /* 0.262033884 */, 18 }, +/* 4244 */ { MAD_F(0x0431a0c9) /* 0.262116229 */, 18 }, +/* 4245 */ { MAD_F(0x0431f723) /* 0.262198581 */, 18 }, +/* 4246 */ { MAD_F(0x04324d7f) /* 0.262280940 */, 18 }, +/* 4247 */ { MAD_F(0x0432a3dd) /* 0.262363305 */, 18 }, +/* 4248 */ { MAD_F(0x0432fa3d) /* 0.262445676 */, 18 }, +/* 4249 */ { MAD_F(0x0433509e) /* 0.262528054 */, 18 }, +/* 4250 */ { MAD_F(0x0433a701) /* 0.262610438 */, 18 }, +/* 4251 */ { MAD_F(0x0433fd65) /* 0.262692829 */, 18 }, +/* 4252 */ { MAD_F(0x043453cc) /* 0.262775227 */, 18 }, +/* 4253 */ { MAD_F(0x0434aa34) /* 0.262857630 */, 18 }, +/* 4254 */ { MAD_F(0x0435009d) /* 0.262940040 */, 18 }, +/* 4255 */ { MAD_F(0x04355709) /* 0.263022457 */, 18 }, + +/* 4256 */ { MAD_F(0x0435ad76) /* 0.263104880 */, 18 }, +/* 4257 */ { MAD_F(0x043603e5) /* 0.263187310 */, 18 }, +/* 4258 */ { MAD_F(0x04365a56) /* 0.263269746 */, 18 }, +/* 4259 */ { MAD_F(0x0436b0c9) /* 0.263352188 */, 18 }, +/* 4260 */ { MAD_F(0x0437073d) /* 0.263434637 */, 18 }, +/* 4261 */ { MAD_F(0x04375db3) /* 0.263517093 */, 18 }, +/* 4262 */ { MAD_F(0x0437b42a) /* 0.263599554 */, 18 }, +/* 4263 */ { MAD_F(0x04380aa4) /* 0.263682023 */, 18 }, +/* 4264 */ { MAD_F(0x0438611f) /* 0.263764497 */, 18 }, +/* 4265 */ { MAD_F(0x0438b79c) /* 0.263846979 */, 18 }, +/* 4266 */ { MAD_F(0x04390e1a) /* 0.263929466 */, 18 }, +/* 4267 */ { MAD_F(0x0439649b) /* 0.264011960 */, 18 }, +/* 4268 */ { MAD_F(0x0439bb1d) /* 0.264094461 */, 18 }, +/* 4269 */ { MAD_F(0x043a11a1) /* 0.264176968 */, 18 }, +/* 4270 */ { MAD_F(0x043a6826) /* 0.264259481 */, 18 }, +/* 4271 */ { MAD_F(0x043abead) /* 0.264342001 */, 18 }, + +/* 4272 */ { MAD_F(0x043b1536) /* 0.264424527 */, 18 }, +/* 4273 */ { MAD_F(0x043b6bc1) /* 0.264507060 */, 18 }, +/* 4274 */ { MAD_F(0x043bc24d) /* 0.264589599 */, 18 }, +/* 4275 */ { MAD_F(0x043c18dc) /* 0.264672145 */, 18 }, +/* 4276 */ { MAD_F(0x043c6f6c) /* 0.264754697 */, 18 }, +/* 4277 */ { MAD_F(0x043cc5fd) /* 0.264837255 */, 18 }, +/* 4278 */ { MAD_F(0x043d1c91) /* 0.264919820 */, 18 }, +/* 4279 */ { MAD_F(0x043d7326) /* 0.265002392 */, 18 }, +/* 4280 */ { MAD_F(0x043dc9bc) /* 0.265084969 */, 18 }, +/* 4281 */ { MAD_F(0x043e2055) /* 0.265167554 */, 18 }, +/* 4282 */ { MAD_F(0x043e76ef) /* 0.265250144 */, 18 }, +/* 4283 */ { MAD_F(0x043ecd8b) /* 0.265332741 */, 18 }, +/* 4284 */ { MAD_F(0x043f2429) /* 0.265415345 */, 18 }, +/* 4285 */ { MAD_F(0x043f7ac8) /* 0.265497955 */, 18 }, +/* 4286 */ { MAD_F(0x043fd169) /* 0.265580571 */, 18 }, +/* 4287 */ { MAD_F(0x0440280c) /* 0.265663194 */, 18 }, + +/* 4288 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 18 }, +/* 4289 */ { MAD_F(0x0440d557) /* 0.265828459 */, 18 }, +/* 4290 */ { MAD_F(0x04412bff) /* 0.265911101 */, 18 }, +/* 4291 */ { MAD_F(0x044182a9) /* 0.265993749 */, 18 }, +/* 4292 */ { MAD_F(0x0441d955) /* 0.266076404 */, 18 }, +/* 4293 */ { MAD_F(0x04423002) /* 0.266159065 */, 18 }, +/* 4294 */ { MAD_F(0x044286b1) /* 0.266241733 */, 18 }, +/* 4295 */ { MAD_F(0x0442dd61) /* 0.266324407 */, 18 }, +/* 4296 */ { MAD_F(0x04433414) /* 0.266407088 */, 18 }, +/* 4297 */ { MAD_F(0x04438ac8) /* 0.266489775 */, 18 }, +/* 4298 */ { MAD_F(0x0443e17e) /* 0.266572468 */, 18 }, +/* 4299 */ { MAD_F(0x04443835) /* 0.266655168 */, 18 }, +/* 4300 */ { MAD_F(0x04448eef) /* 0.266737874 */, 18 }, +/* 4301 */ { MAD_F(0x0444e5aa) /* 0.266820587 */, 18 }, +/* 4302 */ { MAD_F(0x04453c66) /* 0.266903306 */, 18 }, +/* 4303 */ { MAD_F(0x04459325) /* 0.266986031 */, 18 }, + +/* 4304 */ { MAD_F(0x0445e9e5) /* 0.267068763 */, 18 }, +/* 4305 */ { MAD_F(0x044640a7) /* 0.267151501 */, 18 }, +/* 4306 */ { MAD_F(0x0446976a) /* 0.267234246 */, 18 }, +/* 4307 */ { MAD_F(0x0446ee30) /* 0.267316997 */, 18 }, +/* 4308 */ { MAD_F(0x044744f7) /* 0.267399755 */, 18 }, +/* 4309 */ { MAD_F(0x04479bc0) /* 0.267482518 */, 18 }, +/* 4310 */ { MAD_F(0x0447f28a) /* 0.267565289 */, 18 }, +/* 4311 */ { MAD_F(0x04484956) /* 0.267648065 */, 18 }, +/* 4312 */ { MAD_F(0x0448a024) /* 0.267730848 */, 18 }, +/* 4313 */ { MAD_F(0x0448f6f4) /* 0.267813638 */, 18 }, +/* 4314 */ { MAD_F(0x04494dc5) /* 0.267896434 */, 18 }, +/* 4315 */ { MAD_F(0x0449a498) /* 0.267979236 */, 18 }, +/* 4316 */ { MAD_F(0x0449fb6d) /* 0.268062045 */, 18 }, +/* 4317 */ { MAD_F(0x044a5243) /* 0.268144860 */, 18 }, +/* 4318 */ { MAD_F(0x044aa91c) /* 0.268227681 */, 18 }, +/* 4319 */ { MAD_F(0x044afff6) /* 0.268310509 */, 18 }, + +/* 4320 */ { MAD_F(0x044b56d1) /* 0.268393343 */, 18 }, +/* 4321 */ { MAD_F(0x044badaf) /* 0.268476184 */, 18 }, +/* 4322 */ { MAD_F(0x044c048e) /* 0.268559031 */, 18 }, +/* 4323 */ { MAD_F(0x044c5b6f) /* 0.268641885 */, 18 }, +/* 4324 */ { MAD_F(0x044cb251) /* 0.268724744 */, 18 }, +/* 4325 */ { MAD_F(0x044d0935) /* 0.268807611 */, 18 }, +/* 4326 */ { MAD_F(0x044d601b) /* 0.268890483 */, 18 }, +/* 4327 */ { MAD_F(0x044db703) /* 0.268973362 */, 18 }, +/* 4328 */ { MAD_F(0x044e0dec) /* 0.269056248 */, 18 }, +/* 4329 */ { MAD_F(0x044e64d7) /* 0.269139139 */, 18 }, +/* 4330 */ { MAD_F(0x044ebbc4) /* 0.269222037 */, 18 }, +/* 4331 */ { MAD_F(0x044f12b3) /* 0.269304942 */, 18 }, +/* 4332 */ { MAD_F(0x044f69a3) /* 0.269387853 */, 18 }, +/* 4333 */ { MAD_F(0x044fc095) /* 0.269470770 */, 18 }, +/* 4334 */ { MAD_F(0x04501788) /* 0.269553694 */, 18 }, +/* 4335 */ { MAD_F(0x04506e7e) /* 0.269636624 */, 18 }, + +/* 4336 */ { MAD_F(0x0450c575) /* 0.269719560 */, 18 }, +/* 4337 */ { MAD_F(0x04511c6e) /* 0.269802503 */, 18 }, +/* 4338 */ { MAD_F(0x04517368) /* 0.269885452 */, 18 }, +/* 4339 */ { MAD_F(0x0451ca64) /* 0.269968408 */, 18 }, +/* 4340 */ { MAD_F(0x04522162) /* 0.270051370 */, 18 }, +/* 4341 */ { MAD_F(0x04527862) /* 0.270134338 */, 18 }, +/* 4342 */ { MAD_F(0x0452cf63) /* 0.270217312 */, 18 }, +/* 4343 */ { MAD_F(0x04532666) /* 0.270300293 */, 18 }, +/* 4344 */ { MAD_F(0x04537d6b) /* 0.270383281 */, 18 }, +/* 4345 */ { MAD_F(0x0453d472) /* 0.270466275 */, 18 }, +/* 4346 */ { MAD_F(0x04542b7a) /* 0.270549275 */, 18 }, +/* 4347 */ { MAD_F(0x04548284) /* 0.270632281 */, 18 }, +/* 4348 */ { MAD_F(0x0454d98f) /* 0.270715294 */, 18 }, +/* 4349 */ { MAD_F(0x0455309c) /* 0.270798313 */, 18 }, +/* 4350 */ { MAD_F(0x045587ab) /* 0.270881339 */, 18 }, +/* 4351 */ { MAD_F(0x0455debc) /* 0.270964371 */, 18 }, + +/* 4352 */ { MAD_F(0x045635cf) /* 0.271047409 */, 18 }, +/* 4353 */ { MAD_F(0x04568ce3) /* 0.271130454 */, 18 }, +/* 4354 */ { MAD_F(0x0456e3f9) /* 0.271213505 */, 18 }, +/* 4355 */ { MAD_F(0x04573b10) /* 0.271296562 */, 18 }, +/* 4356 */ { MAD_F(0x04579229) /* 0.271379626 */, 18 }, +/* 4357 */ { MAD_F(0x0457e944) /* 0.271462696 */, 18 }, +/* 4358 */ { MAD_F(0x04584061) /* 0.271545772 */, 18 }, +/* 4359 */ { MAD_F(0x0458977f) /* 0.271628855 */, 18 }, +/* 4360 */ { MAD_F(0x0458ee9f) /* 0.271711944 */, 18 }, +/* 4361 */ { MAD_F(0x045945c1) /* 0.271795040 */, 18 }, +/* 4362 */ { MAD_F(0x04599ce5) /* 0.271878142 */, 18 }, +/* 4363 */ { MAD_F(0x0459f40a) /* 0.271961250 */, 18 }, +/* 4364 */ { MAD_F(0x045a4b31) /* 0.272044365 */, 18 }, +/* 4365 */ { MAD_F(0x045aa259) /* 0.272127486 */, 18 }, +/* 4366 */ { MAD_F(0x045af984) /* 0.272210613 */, 18 }, +/* 4367 */ { MAD_F(0x045b50b0) /* 0.272293746 */, 18 }, + +/* 4368 */ { MAD_F(0x045ba7dd) /* 0.272376886 */, 18 }, +/* 4369 */ { MAD_F(0x045bff0d) /* 0.272460033 */, 18 }, +/* 4370 */ { MAD_F(0x045c563e) /* 0.272543185 */, 18 }, +/* 4371 */ { MAD_F(0x045cad71) /* 0.272626344 */, 18 }, +/* 4372 */ { MAD_F(0x045d04a5) /* 0.272709510 */, 18 }, +/* 4373 */ { MAD_F(0x045d5bdc) /* 0.272792681 */, 18 }, +/* 4374 */ { MAD_F(0x045db313) /* 0.272875859 */, 18 }, +/* 4375 */ { MAD_F(0x045e0a4d) /* 0.272959044 */, 18 }, +/* 4376 */ { MAD_F(0x045e6188) /* 0.273042234 */, 18 }, +/* 4377 */ { MAD_F(0x045eb8c5) /* 0.273125431 */, 18 }, +/* 4378 */ { MAD_F(0x045f1004) /* 0.273208635 */, 18 }, +/* 4379 */ { MAD_F(0x045f6745) /* 0.273291844 */, 18 }, +/* 4380 */ { MAD_F(0x045fbe87) /* 0.273375060 */, 18 }, +/* 4381 */ { MAD_F(0x046015cb) /* 0.273458283 */, 18 }, +/* 4382 */ { MAD_F(0x04606d10) /* 0.273541511 */, 18 }, +/* 4383 */ { MAD_F(0x0460c457) /* 0.273624747 */, 18 }, + +/* 4384 */ { MAD_F(0x04611ba0) /* 0.273707988 */, 18 }, +/* 4385 */ { MAD_F(0x046172eb) /* 0.273791236 */, 18 }, +/* 4386 */ { MAD_F(0x0461ca37) /* 0.273874490 */, 18 }, +/* 4387 */ { MAD_F(0x04622185) /* 0.273957750 */, 18 }, +/* 4388 */ { MAD_F(0x046278d5) /* 0.274041017 */, 18 }, +/* 4389 */ { MAD_F(0x0462d026) /* 0.274124290 */, 18 }, +/* 4390 */ { MAD_F(0x0463277a) /* 0.274207569 */, 18 }, +/* 4391 */ { MAD_F(0x04637ece) /* 0.274290855 */, 18 }, +/* 4392 */ { MAD_F(0x0463d625) /* 0.274374147 */, 18 }, +/* 4393 */ { MAD_F(0x04642d7d) /* 0.274457445 */, 18 }, +/* 4394 */ { MAD_F(0x046484d7) /* 0.274540749 */, 18 }, +/* 4395 */ { MAD_F(0x0464dc33) /* 0.274624060 */, 18 }, +/* 4396 */ { MAD_F(0x04653390) /* 0.274707378 */, 18 }, +/* 4397 */ { MAD_F(0x04658aef) /* 0.274790701 */, 18 }, +/* 4398 */ { MAD_F(0x0465e250) /* 0.274874031 */, 18 }, +/* 4399 */ { MAD_F(0x046639b2) /* 0.274957367 */, 18 }, + +/* 4400 */ { MAD_F(0x04669116) /* 0.275040710 */, 18 }, +/* 4401 */ { MAD_F(0x0466e87c) /* 0.275124059 */, 18 }, +/* 4402 */ { MAD_F(0x04673fe3) /* 0.275207414 */, 18 }, +/* 4403 */ { MAD_F(0x0467974d) /* 0.275290775 */, 18 }, +/* 4404 */ { MAD_F(0x0467eeb7) /* 0.275374143 */, 18 }, +/* 4405 */ { MAD_F(0x04684624) /* 0.275457517 */, 18 }, +/* 4406 */ { MAD_F(0x04689d92) /* 0.275540897 */, 18 }, +/* 4407 */ { MAD_F(0x0468f502) /* 0.275624284 */, 18 }, +/* 4408 */ { MAD_F(0x04694c74) /* 0.275707677 */, 18 }, +/* 4409 */ { MAD_F(0x0469a3e7) /* 0.275791076 */, 18 }, +/* 4410 */ { MAD_F(0x0469fb5c) /* 0.275874482 */, 18 }, +/* 4411 */ { MAD_F(0x046a52d3) /* 0.275957894 */, 18 }, +/* 4412 */ { MAD_F(0x046aaa4b) /* 0.276041312 */, 18 }, +/* 4413 */ { MAD_F(0x046b01c5) /* 0.276124737 */, 18 }, +/* 4414 */ { MAD_F(0x046b5941) /* 0.276208167 */, 18 }, +/* 4415 */ { MAD_F(0x046bb0bf) /* 0.276291605 */, 18 }, + +/* 4416 */ { MAD_F(0x046c083e) /* 0.276375048 */, 18 }, +/* 4417 */ { MAD_F(0x046c5fbf) /* 0.276458498 */, 18 }, +/* 4418 */ { MAD_F(0x046cb741) /* 0.276541954 */, 18 }, +/* 4419 */ { MAD_F(0x046d0ec5) /* 0.276625416 */, 18 }, +/* 4420 */ { MAD_F(0x046d664b) /* 0.276708885 */, 18 }, +/* 4421 */ { MAD_F(0x046dbdd3) /* 0.276792360 */, 18 }, +/* 4422 */ { MAD_F(0x046e155c) /* 0.276875841 */, 18 }, +/* 4423 */ { MAD_F(0x046e6ce7) /* 0.276959328 */, 18 }, +/* 4424 */ { MAD_F(0x046ec474) /* 0.277042822 */, 18 }, +/* 4425 */ { MAD_F(0x046f1c02) /* 0.277126322 */, 18 }, +/* 4426 */ { MAD_F(0x046f7392) /* 0.277209829 */, 18 }, +/* 4427 */ { MAD_F(0x046fcb24) /* 0.277293341 */, 18 }, +/* 4428 */ { MAD_F(0x047022b8) /* 0.277376860 */, 18 }, +/* 4429 */ { MAD_F(0x04707a4d) /* 0.277460385 */, 18 }, +/* 4430 */ { MAD_F(0x0470d1e4) /* 0.277543917 */, 18 }, +/* 4431 */ { MAD_F(0x0471297c) /* 0.277627455 */, 18 }, + +/* 4432 */ { MAD_F(0x04718116) /* 0.277710999 */, 18 }, +/* 4433 */ { MAD_F(0x0471d8b2) /* 0.277794549 */, 18 }, +/* 4434 */ { MAD_F(0x04723050) /* 0.277878106 */, 18 }, +/* 4435 */ { MAD_F(0x047287ef) /* 0.277961669 */, 18 }, +/* 4436 */ { MAD_F(0x0472df90) /* 0.278045238 */, 18 }, +/* 4437 */ { MAD_F(0x04733733) /* 0.278128813 */, 18 }, +/* 4438 */ { MAD_F(0x04738ed7) /* 0.278212395 */, 18 }, +/* 4439 */ { MAD_F(0x0473e67d) /* 0.278295983 */, 18 }, +/* 4440 */ { MAD_F(0x04743e25) /* 0.278379578 */, 18 }, +/* 4441 */ { MAD_F(0x047495ce) /* 0.278463178 */, 18 }, +/* 4442 */ { MAD_F(0x0474ed79) /* 0.278546785 */, 18 }, +/* 4443 */ { MAD_F(0x04754526) /* 0.278630398 */, 18 }, +/* 4444 */ { MAD_F(0x04759cd4) /* 0.278714018 */, 18 }, +/* 4445 */ { MAD_F(0x0475f484) /* 0.278797643 */, 18 }, +/* 4446 */ { MAD_F(0x04764c36) /* 0.278881275 */, 18 }, +/* 4447 */ { MAD_F(0x0476a3ea) /* 0.278964914 */, 18 }, + +/* 4448 */ { MAD_F(0x0476fb9f) /* 0.279048558 */, 18 }, +/* 4449 */ { MAD_F(0x04775356) /* 0.279132209 */, 18 }, +/* 4450 */ { MAD_F(0x0477ab0e) /* 0.279215866 */, 18 }, +/* 4451 */ { MAD_F(0x047802c8) /* 0.279299529 */, 18 }, +/* 4452 */ { MAD_F(0x04785a84) /* 0.279383199 */, 18 }, +/* 4453 */ { MAD_F(0x0478b242) /* 0.279466875 */, 18 }, +/* 4454 */ { MAD_F(0x04790a01) /* 0.279550557 */, 18 }, +/* 4455 */ { MAD_F(0x047961c2) /* 0.279634245 */, 18 }, +/* 4456 */ { MAD_F(0x0479b984) /* 0.279717940 */, 18 }, +/* 4457 */ { MAD_F(0x047a1149) /* 0.279801641 */, 18 }, +/* 4458 */ { MAD_F(0x047a690f) /* 0.279885348 */, 18 }, +/* 4459 */ { MAD_F(0x047ac0d6) /* 0.279969061 */, 18 }, +/* 4460 */ { MAD_F(0x047b18a0) /* 0.280052781 */, 18 }, +/* 4461 */ { MAD_F(0x047b706b) /* 0.280136507 */, 18 }, +/* 4462 */ { MAD_F(0x047bc837) /* 0.280220239 */, 18 }, +/* 4463 */ { MAD_F(0x047c2006) /* 0.280303978 */, 18 }, + +/* 4464 */ { MAD_F(0x047c77d6) /* 0.280387722 */, 18 }, +/* 4465 */ { MAD_F(0x047ccfa8) /* 0.280471473 */, 18 }, +/* 4466 */ { MAD_F(0x047d277b) /* 0.280555230 */, 18 }, +/* 4467 */ { MAD_F(0x047d7f50) /* 0.280638994 */, 18 }, +/* 4468 */ { MAD_F(0x047dd727) /* 0.280722764 */, 18 }, +/* 4469 */ { MAD_F(0x047e2eff) /* 0.280806540 */, 18 }, +/* 4470 */ { MAD_F(0x047e86d9) /* 0.280890322 */, 18 }, +/* 4471 */ { MAD_F(0x047edeb5) /* 0.280974110 */, 18 }, +/* 4472 */ { MAD_F(0x047f3693) /* 0.281057905 */, 18 }, +/* 4473 */ { MAD_F(0x047f8e72) /* 0.281141706 */, 18 }, +/* 4474 */ { MAD_F(0x047fe653) /* 0.281225513 */, 18 }, +/* 4475 */ { MAD_F(0x04803e35) /* 0.281309326 */, 18 }, +/* 4476 */ { MAD_F(0x04809619) /* 0.281393146 */, 18 }, +/* 4477 */ { MAD_F(0x0480edff) /* 0.281476972 */, 18 }, +/* 4478 */ { MAD_F(0x048145e7) /* 0.281560804 */, 18 }, +/* 4479 */ { MAD_F(0x04819dd0) /* 0.281644643 */, 18 }, + +/* 4480 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 18 }, +/* 4481 */ { MAD_F(0x04824da7) /* 0.281812338 */, 18 }, +/* 4482 */ { MAD_F(0x0482a595) /* 0.281896195 */, 18 }, +/* 4483 */ { MAD_F(0x0482fd85) /* 0.281980059 */, 18 }, +/* 4484 */ { MAD_F(0x04835577) /* 0.282063928 */, 18 }, +/* 4485 */ { MAD_F(0x0483ad6a) /* 0.282147804 */, 18 }, +/* 4486 */ { MAD_F(0x0484055f) /* 0.282231686 */, 18 }, +/* 4487 */ { MAD_F(0x04845d56) /* 0.282315574 */, 18 }, +/* 4488 */ { MAD_F(0x0484b54e) /* 0.282399469 */, 18 }, +/* 4489 */ { MAD_F(0x04850d48) /* 0.282483370 */, 18 }, +/* 4490 */ { MAD_F(0x04856544) /* 0.282567277 */, 18 }, +/* 4491 */ { MAD_F(0x0485bd41) /* 0.282651190 */, 18 }, +/* 4492 */ { MAD_F(0x04861540) /* 0.282735109 */, 18 }, +/* 4493 */ { MAD_F(0x04866d40) /* 0.282819035 */, 18 }, +/* 4494 */ { MAD_F(0x0486c543) /* 0.282902967 */, 18 }, +/* 4495 */ { MAD_F(0x04871d47) /* 0.282986905 */, 18 }, + +/* 4496 */ { MAD_F(0x0487754c) /* 0.283070849 */, 18 }, +/* 4497 */ { MAD_F(0x0487cd54) /* 0.283154800 */, 18 }, +/* 4498 */ { MAD_F(0x0488255d) /* 0.283238757 */, 18 }, +/* 4499 */ { MAD_F(0x04887d67) /* 0.283322720 */, 18 }, +/* 4500 */ { MAD_F(0x0488d574) /* 0.283406689 */, 18 }, +/* 4501 */ { MAD_F(0x04892d82) /* 0.283490665 */, 18 }, +/* 4502 */ { MAD_F(0x04898591) /* 0.283574646 */, 18 }, +/* 4503 */ { MAD_F(0x0489dda3) /* 0.283658634 */, 18 }, +/* 4504 */ { MAD_F(0x048a35b6) /* 0.283742628 */, 18 }, +/* 4505 */ { MAD_F(0x048a8dca) /* 0.283826629 */, 18 }, +/* 4506 */ { MAD_F(0x048ae5e1) /* 0.283910635 */, 18 }, +/* 4507 */ { MAD_F(0x048b3df9) /* 0.283994648 */, 18 }, +/* 4508 */ { MAD_F(0x048b9612) /* 0.284078667 */, 18 }, +/* 4509 */ { MAD_F(0x048bee2e) /* 0.284162692 */, 18 }, +/* 4510 */ { MAD_F(0x048c464b) /* 0.284246723 */, 18 }, +/* 4511 */ { MAD_F(0x048c9e69) /* 0.284330761 */, 18 }, + +/* 4512 */ { MAD_F(0x048cf68a) /* 0.284414805 */, 18 }, +/* 4513 */ { MAD_F(0x048d4eac) /* 0.284498855 */, 18 }, +/* 4514 */ { MAD_F(0x048da6cf) /* 0.284582911 */, 18 }, +/* 4515 */ { MAD_F(0x048dfef5) /* 0.284666974 */, 18 }, +/* 4516 */ { MAD_F(0x048e571c) /* 0.284751042 */, 18 }, +/* 4517 */ { MAD_F(0x048eaf44) /* 0.284835117 */, 18 }, +/* 4518 */ { MAD_F(0x048f076f) /* 0.284919198 */, 18 }, +/* 4519 */ { MAD_F(0x048f5f9b) /* 0.285003285 */, 18 }, +/* 4520 */ { MAD_F(0x048fb7c8) /* 0.285087379 */, 18 }, +/* 4521 */ { MAD_F(0x04900ff8) /* 0.285171479 */, 18 }, +/* 4522 */ { MAD_F(0x04906829) /* 0.285255584 */, 18 }, +/* 4523 */ { MAD_F(0x0490c05b) /* 0.285339697 */, 18 }, +/* 4524 */ { MAD_F(0x04911890) /* 0.285423815 */, 18 }, +/* 4525 */ { MAD_F(0x049170c6) /* 0.285507939 */, 18 }, +/* 4526 */ { MAD_F(0x0491c8fd) /* 0.285592070 */, 18 }, +/* 4527 */ { MAD_F(0x04922137) /* 0.285676207 */, 18 }, + +/* 4528 */ { MAD_F(0x04927972) /* 0.285760350 */, 18 }, +/* 4529 */ { MAD_F(0x0492d1ae) /* 0.285844499 */, 18 }, +/* 4530 */ { MAD_F(0x049329ed) /* 0.285928655 */, 18 }, +/* 4531 */ { MAD_F(0x0493822c) /* 0.286012816 */, 18 }, +/* 4532 */ { MAD_F(0x0493da6e) /* 0.286096984 */, 18 }, +/* 4533 */ { MAD_F(0x049432b1) /* 0.286181158 */, 18 }, +/* 4534 */ { MAD_F(0x04948af6) /* 0.286265338 */, 18 }, +/* 4535 */ { MAD_F(0x0494e33d) /* 0.286349525 */, 18 }, +/* 4536 */ { MAD_F(0x04953b85) /* 0.286433717 */, 18 }, +/* 4537 */ { MAD_F(0x049593cf) /* 0.286517916 */, 18 }, +/* 4538 */ { MAD_F(0x0495ec1b) /* 0.286602121 */, 18 }, +/* 4539 */ { MAD_F(0x04964468) /* 0.286686332 */, 18 }, +/* 4540 */ { MAD_F(0x04969cb7) /* 0.286770550 */, 18 }, +/* 4541 */ { MAD_F(0x0496f508) /* 0.286854773 */, 18 }, +/* 4542 */ { MAD_F(0x04974d5a) /* 0.286939003 */, 18 }, +/* 4543 */ { MAD_F(0x0497a5ae) /* 0.287023239 */, 18 }, + +/* 4544 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 18 }, +/* 4545 */ { MAD_F(0x0498565a) /* 0.287191729 */, 18 }, +/* 4546 */ { MAD_F(0x0498aeb3) /* 0.287275983 */, 18 }, +/* 4547 */ { MAD_F(0x0499070e) /* 0.287360244 */, 18 }, +/* 4548 */ { MAD_F(0x04995f6a) /* 0.287444511 */, 18 }, +/* 4549 */ { MAD_F(0x0499b7c8) /* 0.287528784 */, 18 }, +/* 4550 */ { MAD_F(0x049a1027) /* 0.287613063 */, 18 }, +/* 4551 */ { MAD_F(0x049a6889) /* 0.287697348 */, 18 }, +/* 4552 */ { MAD_F(0x049ac0eb) /* 0.287781640 */, 18 }, +/* 4553 */ { MAD_F(0x049b1950) /* 0.287865937 */, 18 }, +/* 4554 */ { MAD_F(0x049b71b6) /* 0.287950241 */, 18 }, +/* 4555 */ { MAD_F(0x049bca1e) /* 0.288034551 */, 18 }, +/* 4556 */ { MAD_F(0x049c2287) /* 0.288118867 */, 18 }, +/* 4557 */ { MAD_F(0x049c7af2) /* 0.288203190 */, 18 }, +/* 4558 */ { MAD_F(0x049cd35f) /* 0.288287518 */, 18 }, +/* 4559 */ { MAD_F(0x049d2bce) /* 0.288371853 */, 18 }, + +/* 4560 */ { MAD_F(0x049d843e) /* 0.288456194 */, 18 }, +/* 4561 */ { MAD_F(0x049ddcaf) /* 0.288540541 */, 18 }, +/* 4562 */ { MAD_F(0x049e3523) /* 0.288624894 */, 18 }, +/* 4563 */ { MAD_F(0x049e8d98) /* 0.288709253 */, 18 }, +/* 4564 */ { MAD_F(0x049ee60e) /* 0.288793619 */, 18 }, +/* 4565 */ { MAD_F(0x049f3e87) /* 0.288877990 */, 18 }, +/* 4566 */ { MAD_F(0x049f9701) /* 0.288962368 */, 18 }, +/* 4567 */ { MAD_F(0x049fef7c) /* 0.289046752 */, 18 }, +/* 4568 */ { MAD_F(0x04a047fa) /* 0.289131142 */, 18 }, +/* 4569 */ { MAD_F(0x04a0a079) /* 0.289215538 */, 18 }, +/* 4570 */ { MAD_F(0x04a0f8f9) /* 0.289299941 */, 18 }, +/* 4571 */ { MAD_F(0x04a1517c) /* 0.289384349 */, 18 }, +/* 4572 */ { MAD_F(0x04a1a9ff) /* 0.289468764 */, 18 }, +/* 4573 */ { MAD_F(0x04a20285) /* 0.289553185 */, 18 }, +/* 4574 */ { MAD_F(0x04a25b0c) /* 0.289637612 */, 18 }, +/* 4575 */ { MAD_F(0x04a2b395) /* 0.289722045 */, 18 }, + +/* 4576 */ { MAD_F(0x04a30c20) /* 0.289806485 */, 18 }, +/* 4577 */ { MAD_F(0x04a364ac) /* 0.289890930 */, 18 }, +/* 4578 */ { MAD_F(0x04a3bd3a) /* 0.289975382 */, 18 }, +/* 4579 */ { MAD_F(0x04a415c9) /* 0.290059840 */, 18 }, +/* 4580 */ { MAD_F(0x04a46e5a) /* 0.290144304 */, 18 }, +/* 4581 */ { MAD_F(0x04a4c6ed) /* 0.290228774 */, 18 }, +/* 4582 */ { MAD_F(0x04a51f81) /* 0.290313250 */, 18 }, +/* 4583 */ { MAD_F(0x04a57818) /* 0.290397733 */, 18 }, +/* 4584 */ { MAD_F(0x04a5d0af) /* 0.290482221 */, 18 }, +/* 4585 */ { MAD_F(0x04a62949) /* 0.290566716 */, 18 }, +/* 4586 */ { MAD_F(0x04a681e4) /* 0.290651217 */, 18 }, +/* 4587 */ { MAD_F(0x04a6da80) /* 0.290735724 */, 18 }, +/* 4588 */ { MAD_F(0x04a7331f) /* 0.290820237 */, 18 }, +/* 4589 */ { MAD_F(0x04a78bbf) /* 0.290904756 */, 18 }, +/* 4590 */ { MAD_F(0x04a7e460) /* 0.290989281 */, 18 }, +/* 4591 */ { MAD_F(0x04a83d03) /* 0.291073813 */, 18 }, + +/* 4592 */ { MAD_F(0x04a895a8) /* 0.291158351 */, 18 }, +/* 4593 */ { MAD_F(0x04a8ee4f) /* 0.291242894 */, 18 }, +/* 4594 */ { MAD_F(0x04a946f7) /* 0.291327444 */, 18 }, +/* 4595 */ { MAD_F(0x04a99fa1) /* 0.291412001 */, 18 }, +/* 4596 */ { MAD_F(0x04a9f84c) /* 0.291496563 */, 18 }, +/* 4597 */ { MAD_F(0x04aa50fa) /* 0.291581131 */, 18 }, +/* 4598 */ { MAD_F(0x04aaa9a8) /* 0.291665706 */, 18 }, +/* 4599 */ { MAD_F(0x04ab0259) /* 0.291750286 */, 18 }, +/* 4600 */ { MAD_F(0x04ab5b0b) /* 0.291834873 */, 18 }, +/* 4601 */ { MAD_F(0x04abb3bf) /* 0.291919466 */, 18 }, +/* 4602 */ { MAD_F(0x04ac0c74) /* 0.292004065 */, 18 }, +/* 4603 */ { MAD_F(0x04ac652b) /* 0.292088670 */, 18 }, +/* 4604 */ { MAD_F(0x04acbde4) /* 0.292173281 */, 18 }, +/* 4605 */ { MAD_F(0x04ad169e) /* 0.292257899 */, 18 }, +/* 4606 */ { MAD_F(0x04ad6f5a) /* 0.292342522 */, 18 }, +/* 4607 */ { MAD_F(0x04adc818) /* 0.292427152 */, 18 }, + +/* 4608 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 18 }, +/* 4609 */ { MAD_F(0x04ae7998) /* 0.292596430 */, 18 }, +/* 4610 */ { MAD_F(0x04aed25a) /* 0.292681078 */, 18 }, +/* 4611 */ { MAD_F(0x04af2b1e) /* 0.292765732 */, 18 }, +/* 4612 */ { MAD_F(0x04af83e4) /* 0.292850392 */, 18 }, +/* 4613 */ { MAD_F(0x04afdcac) /* 0.292935058 */, 18 }, +/* 4614 */ { MAD_F(0x04b03575) /* 0.293019731 */, 18 }, +/* 4615 */ { MAD_F(0x04b08e40) /* 0.293104409 */, 18 }, +/* 4616 */ { MAD_F(0x04b0e70c) /* 0.293189094 */, 18 }, +/* 4617 */ { MAD_F(0x04b13fda) /* 0.293273785 */, 18 }, +/* 4618 */ { MAD_F(0x04b198aa) /* 0.293358482 */, 18 }, +/* 4619 */ { MAD_F(0x04b1f17b) /* 0.293443185 */, 18 }, +/* 4620 */ { MAD_F(0x04b24a4e) /* 0.293527894 */, 18 }, +/* 4621 */ { MAD_F(0x04b2a322) /* 0.293612609 */, 18 }, +/* 4622 */ { MAD_F(0x04b2fbf9) /* 0.293697331 */, 18 }, +/* 4623 */ { MAD_F(0x04b354d1) /* 0.293782058 */, 18 }, + +/* 4624 */ { MAD_F(0x04b3adaa) /* 0.293866792 */, 18 }, +/* 4625 */ { MAD_F(0x04b40685) /* 0.293951532 */, 18 }, +/* 4626 */ { MAD_F(0x04b45f62) /* 0.294036278 */, 18 }, +/* 4627 */ { MAD_F(0x04b4b840) /* 0.294121029 */, 18 }, +/* 4628 */ { MAD_F(0x04b51120) /* 0.294205788 */, 18 }, +/* 4629 */ { MAD_F(0x04b56a02) /* 0.294290552 */, 18 }, +/* 4630 */ { MAD_F(0x04b5c2e6) /* 0.294375322 */, 18 }, +/* 4631 */ { MAD_F(0x04b61bcb) /* 0.294460098 */, 18 }, +/* 4632 */ { MAD_F(0x04b674b1) /* 0.294544881 */, 18 }, +/* 4633 */ { MAD_F(0x04b6cd99) /* 0.294629669 */, 18 }, +/* 4634 */ { MAD_F(0x04b72683) /* 0.294714464 */, 18 }, +/* 4635 */ { MAD_F(0x04b77f6f) /* 0.294799265 */, 18 }, +/* 4636 */ { MAD_F(0x04b7d85c) /* 0.294884072 */, 18 }, +/* 4637 */ { MAD_F(0x04b8314b) /* 0.294968885 */, 18 }, +/* 4638 */ { MAD_F(0x04b88a3b) /* 0.295053704 */, 18 }, +/* 4639 */ { MAD_F(0x04b8e32d) /* 0.295138529 */, 18 }, + +/* 4640 */ { MAD_F(0x04b93c21) /* 0.295223360 */, 18 }, +/* 4641 */ { MAD_F(0x04b99516) /* 0.295308197 */, 18 }, +/* 4642 */ { MAD_F(0x04b9ee0d) /* 0.295393041 */, 18 }, +/* 4643 */ { MAD_F(0x04ba4706) /* 0.295477890 */, 18 }, +/* 4644 */ { MAD_F(0x04baa000) /* 0.295562746 */, 18 }, +/* 4645 */ { MAD_F(0x04baf8fc) /* 0.295647608 */, 18 }, +/* 4646 */ { MAD_F(0x04bb51fa) /* 0.295732476 */, 18 }, +/* 4647 */ { MAD_F(0x04bbaaf9) /* 0.295817349 */, 18 }, +/* 4648 */ { MAD_F(0x04bc03fa) /* 0.295902229 */, 18 }, +/* 4649 */ { MAD_F(0x04bc5cfc) /* 0.295987115 */, 18 }, +/* 4650 */ { MAD_F(0x04bcb600) /* 0.296072008 */, 18 }, +/* 4651 */ { MAD_F(0x04bd0f06) /* 0.296156906 */, 18 }, +/* 4652 */ { MAD_F(0x04bd680d) /* 0.296241810 */, 18 }, +/* 4653 */ { MAD_F(0x04bdc116) /* 0.296326721 */, 18 }, +/* 4654 */ { MAD_F(0x04be1a21) /* 0.296411637 */, 18 }, +/* 4655 */ { MAD_F(0x04be732d) /* 0.296496560 */, 18 }, + +/* 4656 */ { MAD_F(0x04becc3b) /* 0.296581488 */, 18 }, +/* 4657 */ { MAD_F(0x04bf254a) /* 0.296666423 */, 18 }, +/* 4658 */ { MAD_F(0x04bf7e5b) /* 0.296751364 */, 18 }, +/* 4659 */ { MAD_F(0x04bfd76e) /* 0.296836311 */, 18 }, +/* 4660 */ { MAD_F(0x04c03083) /* 0.296921264 */, 18 }, +/* 4661 */ { MAD_F(0x04c08999) /* 0.297006223 */, 18 }, +/* 4662 */ { MAD_F(0x04c0e2b0) /* 0.297091188 */, 18 }, +/* 4663 */ { MAD_F(0x04c13bca) /* 0.297176159 */, 18 }, +/* 4664 */ { MAD_F(0x04c194e4) /* 0.297261136 */, 18 }, +/* 4665 */ { MAD_F(0x04c1ee01) /* 0.297346120 */, 18 }, +/* 4666 */ { MAD_F(0x04c2471f) /* 0.297431109 */, 18 }, +/* 4667 */ { MAD_F(0x04c2a03f) /* 0.297516105 */, 18 }, +/* 4668 */ { MAD_F(0x04c2f960) /* 0.297601106 */, 18 }, +/* 4669 */ { MAD_F(0x04c35283) /* 0.297686114 */, 18 }, +/* 4670 */ { MAD_F(0x04c3aba8) /* 0.297771128 */, 18 }, +/* 4671 */ { MAD_F(0x04c404ce) /* 0.297856147 */, 18 }, + +/* 4672 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 18 }, +/* 4673 */ { MAD_F(0x04c4b720) /* 0.298026205 */, 18 }, +/* 4674 */ { MAD_F(0x04c5104b) /* 0.298111243 */, 18 }, +/* 4675 */ { MAD_F(0x04c56978) /* 0.298196287 */, 18 }, +/* 4676 */ { MAD_F(0x04c5c2a7) /* 0.298281337 */, 18 }, +/* 4677 */ { MAD_F(0x04c61bd7) /* 0.298366393 */, 18 }, +/* 4678 */ { MAD_F(0x04c67508) /* 0.298451456 */, 18 }, +/* 4679 */ { MAD_F(0x04c6ce3c) /* 0.298536524 */, 18 }, +/* 4680 */ { MAD_F(0x04c72771) /* 0.298621598 */, 18 }, +/* 4681 */ { MAD_F(0x04c780a7) /* 0.298706679 */, 18 }, +/* 4682 */ { MAD_F(0x04c7d9df) /* 0.298791765 */, 18 }, +/* 4683 */ { MAD_F(0x04c83319) /* 0.298876858 */, 18 }, +/* 4684 */ { MAD_F(0x04c88c55) /* 0.298961956 */, 18 }, +/* 4685 */ { MAD_F(0x04c8e592) /* 0.299047061 */, 18 }, +/* 4686 */ { MAD_F(0x04c93ed1) /* 0.299132172 */, 18 }, +/* 4687 */ { MAD_F(0x04c99811) /* 0.299217288 */, 18 }, + +/* 4688 */ { MAD_F(0x04c9f153) /* 0.299302411 */, 18 }, +/* 4689 */ { MAD_F(0x04ca4a97) /* 0.299387540 */, 18 }, +/* 4690 */ { MAD_F(0x04caa3dc) /* 0.299472675 */, 18 }, +/* 4691 */ { MAD_F(0x04cafd23) /* 0.299557816 */, 18 }, +/* 4692 */ { MAD_F(0x04cb566b) /* 0.299642963 */, 18 }, +/* 4693 */ { MAD_F(0x04cbafb5) /* 0.299728116 */, 18 }, +/* 4694 */ { MAD_F(0x04cc0901) /* 0.299813275 */, 18 }, +/* 4695 */ { MAD_F(0x04cc624e) /* 0.299898440 */, 18 }, +/* 4696 */ { MAD_F(0x04ccbb9d) /* 0.299983611 */, 18 }, +/* 4697 */ { MAD_F(0x04cd14ee) /* 0.300068789 */, 18 }, +/* 4698 */ { MAD_F(0x04cd6e40) /* 0.300153972 */, 18 }, +/* 4699 */ { MAD_F(0x04cdc794) /* 0.300239161 */, 18 }, +/* 4700 */ { MAD_F(0x04ce20e9) /* 0.300324357 */, 18 }, +/* 4701 */ { MAD_F(0x04ce7a40) /* 0.300409558 */, 18 }, +/* 4702 */ { MAD_F(0x04ced399) /* 0.300494765 */, 18 }, +/* 4703 */ { MAD_F(0x04cf2cf3) /* 0.300579979 */, 18 }, + +/* 4704 */ { MAD_F(0x04cf864f) /* 0.300665198 */, 18 }, +/* 4705 */ { MAD_F(0x04cfdfad) /* 0.300750424 */, 18 }, +/* 4706 */ { MAD_F(0x04d0390c) /* 0.300835656 */, 18 }, +/* 4707 */ { MAD_F(0x04d0926d) /* 0.300920893 */, 18 }, +/* 4708 */ { MAD_F(0x04d0ebcf) /* 0.301006137 */, 18 }, +/* 4709 */ { MAD_F(0x04d14533) /* 0.301091387 */, 18 }, +/* 4710 */ { MAD_F(0x04d19e99) /* 0.301176643 */, 18 }, +/* 4711 */ { MAD_F(0x04d1f800) /* 0.301261904 */, 18 }, +/* 4712 */ { MAD_F(0x04d25169) /* 0.301347172 */, 18 }, +/* 4713 */ { MAD_F(0x04d2aad4) /* 0.301432446 */, 18 }, +/* 4714 */ { MAD_F(0x04d30440) /* 0.301517726 */, 18 }, +/* 4715 */ { MAD_F(0x04d35dae) /* 0.301603012 */, 18 }, +/* 4716 */ { MAD_F(0x04d3b71d) /* 0.301688304 */, 18 }, +/* 4717 */ { MAD_F(0x04d4108e) /* 0.301773602 */, 18 }, +/* 4718 */ { MAD_F(0x04d46a01) /* 0.301858906 */, 18 }, +/* 4719 */ { MAD_F(0x04d4c375) /* 0.301944216 */, 18 }, + +/* 4720 */ { MAD_F(0x04d51ceb) /* 0.302029532 */, 18 }, +/* 4721 */ { MAD_F(0x04d57662) /* 0.302114854 */, 18 }, +/* 4722 */ { MAD_F(0x04d5cfdb) /* 0.302200182 */, 18 }, +/* 4723 */ { MAD_F(0x04d62956) /* 0.302285516 */, 18 }, +/* 4724 */ { MAD_F(0x04d682d2) /* 0.302370856 */, 18 }, +/* 4725 */ { MAD_F(0x04d6dc50) /* 0.302456203 */, 18 }, +/* 4726 */ { MAD_F(0x04d735d0) /* 0.302541555 */, 18 }, +/* 4727 */ { MAD_F(0x04d78f51) /* 0.302626913 */, 18 }, +/* 4728 */ { MAD_F(0x04d7e8d4) /* 0.302712277 */, 18 }, +/* 4729 */ { MAD_F(0x04d84258) /* 0.302797648 */, 18 }, +/* 4730 */ { MAD_F(0x04d89bde) /* 0.302883024 */, 18 }, +/* 4731 */ { MAD_F(0x04d8f566) /* 0.302968406 */, 18 }, +/* 4732 */ { MAD_F(0x04d94eef) /* 0.303053794 */, 18 }, +/* 4733 */ { MAD_F(0x04d9a87a) /* 0.303139189 */, 18 }, +/* 4734 */ { MAD_F(0x04da0207) /* 0.303224589 */, 18 }, +/* 4735 */ { MAD_F(0x04da5b95) /* 0.303309995 */, 18 }, + +/* 4736 */ { MAD_F(0x04dab524) /* 0.303395408 */, 18 }, +/* 4737 */ { MAD_F(0x04db0eb6) /* 0.303480826 */, 18 }, +/* 4738 */ { MAD_F(0x04db6849) /* 0.303566251 */, 18 }, +/* 4739 */ { MAD_F(0x04dbc1dd) /* 0.303651681 */, 18 }, +/* 4740 */ { MAD_F(0x04dc1b73) /* 0.303737117 */, 18 }, +/* 4741 */ { MAD_F(0x04dc750b) /* 0.303822560 */, 18 }, +/* 4742 */ { MAD_F(0x04dccea5) /* 0.303908008 */, 18 }, +/* 4743 */ { MAD_F(0x04dd2840) /* 0.303993463 */, 18 }, +/* 4744 */ { MAD_F(0x04dd81dc) /* 0.304078923 */, 18 }, +/* 4745 */ { MAD_F(0x04dddb7a) /* 0.304164390 */, 18 }, +/* 4746 */ { MAD_F(0x04de351a) /* 0.304249862 */, 18 }, +/* 4747 */ { MAD_F(0x04de8ebc) /* 0.304335340 */, 18 }, +/* 4748 */ { MAD_F(0x04dee85f) /* 0.304420825 */, 18 }, +/* 4749 */ { MAD_F(0x04df4203) /* 0.304506315 */, 18 }, +/* 4750 */ { MAD_F(0x04df9baa) /* 0.304591812 */, 18 }, +/* 4751 */ { MAD_F(0x04dff552) /* 0.304677314 */, 18 }, + +/* 4752 */ { MAD_F(0x04e04efb) /* 0.304762823 */, 18 }, +/* 4753 */ { MAD_F(0x04e0a8a6) /* 0.304848337 */, 18 }, +/* 4754 */ { MAD_F(0x04e10253) /* 0.304933858 */, 18 }, +/* 4755 */ { MAD_F(0x04e15c01) /* 0.305019384 */, 18 }, +/* 4756 */ { MAD_F(0x04e1b5b1) /* 0.305104917 */, 18 }, +/* 4757 */ { MAD_F(0x04e20f63) /* 0.305190455 */, 18 }, +/* 4758 */ { MAD_F(0x04e26916) /* 0.305275999 */, 18 }, +/* 4759 */ { MAD_F(0x04e2c2cb) /* 0.305361550 */, 18 }, +/* 4760 */ { MAD_F(0x04e31c81) /* 0.305447106 */, 18 }, +/* 4761 */ { MAD_F(0x04e37639) /* 0.305532669 */, 18 }, +/* 4762 */ { MAD_F(0x04e3cff3) /* 0.305618237 */, 18 }, +/* 4763 */ { MAD_F(0x04e429ae) /* 0.305703811 */, 18 }, +/* 4764 */ { MAD_F(0x04e4836b) /* 0.305789392 */, 18 }, +/* 4765 */ { MAD_F(0x04e4dd29) /* 0.305874978 */, 18 }, +/* 4766 */ { MAD_F(0x04e536e9) /* 0.305960571 */, 18 }, +/* 4767 */ { MAD_F(0x04e590ab) /* 0.306046169 */, 18 }, + +/* 4768 */ { MAD_F(0x04e5ea6e) /* 0.306131773 */, 18 }, +/* 4769 */ { MAD_F(0x04e64433) /* 0.306217383 */, 18 }, +/* 4770 */ { MAD_F(0x04e69df9) /* 0.306303000 */, 18 }, +/* 4771 */ { MAD_F(0x04e6f7c1) /* 0.306388622 */, 18 }, +/* 4772 */ { MAD_F(0x04e7518b) /* 0.306474250 */, 18 }, +/* 4773 */ { MAD_F(0x04e7ab56) /* 0.306559885 */, 18 }, +/* 4774 */ { MAD_F(0x04e80523) /* 0.306645525 */, 18 }, +/* 4775 */ { MAD_F(0x04e85ef2) /* 0.306731171 */, 18 }, +/* 4776 */ { MAD_F(0x04e8b8c2) /* 0.306816823 */, 18 }, +/* 4777 */ { MAD_F(0x04e91293) /* 0.306902481 */, 18 }, +/* 4778 */ { MAD_F(0x04e96c67) /* 0.306988145 */, 18 }, +/* 4779 */ { MAD_F(0x04e9c63b) /* 0.307073816 */, 18 }, +/* 4780 */ { MAD_F(0x04ea2012) /* 0.307159492 */, 18 }, +/* 4781 */ { MAD_F(0x04ea79ea) /* 0.307245174 */, 18 }, +/* 4782 */ { MAD_F(0x04ead3c4) /* 0.307330862 */, 18 }, +/* 4783 */ { MAD_F(0x04eb2d9f) /* 0.307416556 */, 18 }, + +/* 4784 */ { MAD_F(0x04eb877c) /* 0.307502256 */, 18 }, +/* 4785 */ { MAD_F(0x04ebe15b) /* 0.307587962 */, 18 }, +/* 4786 */ { MAD_F(0x04ec3b3b) /* 0.307673674 */, 18 }, +/* 4787 */ { MAD_F(0x04ec951c) /* 0.307759392 */, 18 }, +/* 4788 */ { MAD_F(0x04ecef00) /* 0.307845115 */, 18 }, +/* 4789 */ { MAD_F(0x04ed48e5) /* 0.307930845 */, 18 }, +/* 4790 */ { MAD_F(0x04eda2cb) /* 0.308016581 */, 18 }, +/* 4791 */ { MAD_F(0x04edfcb3) /* 0.308102323 */, 18 }, +/* 4792 */ { MAD_F(0x04ee569d) /* 0.308188071 */, 18 }, +/* 4793 */ { MAD_F(0x04eeb088) /* 0.308273824 */, 18 }, +/* 4794 */ { MAD_F(0x04ef0a75) /* 0.308359584 */, 18 }, +/* 4795 */ { MAD_F(0x04ef6464) /* 0.308445350 */, 18 }, +/* 4796 */ { MAD_F(0x04efbe54) /* 0.308531121 */, 18 }, +/* 4797 */ { MAD_F(0x04f01846) /* 0.308616899 */, 18 }, +/* 4798 */ { MAD_F(0x04f07239) /* 0.308702682 */, 18 }, +/* 4799 */ { MAD_F(0x04f0cc2e) /* 0.308788472 */, 18 }, + +/* 4800 */ { MAD_F(0x04f12624) /* 0.308874267 */, 18 }, +/* 4801 */ { MAD_F(0x04f1801d) /* 0.308960068 */, 18 }, +/* 4802 */ { MAD_F(0x04f1da16) /* 0.309045876 */, 18 }, +/* 4803 */ { MAD_F(0x04f23412) /* 0.309131689 */, 18 }, +/* 4804 */ { MAD_F(0x04f28e0f) /* 0.309217508 */, 18 }, +/* 4805 */ { MAD_F(0x04f2e80d) /* 0.309303334 */, 18 }, +/* 4806 */ { MAD_F(0x04f3420d) /* 0.309389165 */, 18 }, +/* 4807 */ { MAD_F(0x04f39c0f) /* 0.309475002 */, 18 }, +/* 4808 */ { MAD_F(0x04f3f612) /* 0.309560845 */, 18 }, +/* 4809 */ { MAD_F(0x04f45017) /* 0.309646694 */, 18 }, +/* 4810 */ { MAD_F(0x04f4aa1e) /* 0.309732549 */, 18 }, +/* 4811 */ { MAD_F(0x04f50426) /* 0.309818410 */, 18 }, +/* 4812 */ { MAD_F(0x04f55e30) /* 0.309904277 */, 18 }, +/* 4813 */ { MAD_F(0x04f5b83b) /* 0.309990150 */, 18 }, +/* 4814 */ { MAD_F(0x04f61248) /* 0.310076028 */, 18 }, +/* 4815 */ { MAD_F(0x04f66c56) /* 0.310161913 */, 18 }, + +/* 4816 */ { MAD_F(0x04f6c666) /* 0.310247804 */, 18 }, +/* 4817 */ { MAD_F(0x04f72078) /* 0.310333700 */, 18 }, +/* 4818 */ { MAD_F(0x04f77a8b) /* 0.310419603 */, 18 }, +/* 4819 */ { MAD_F(0x04f7d4a0) /* 0.310505511 */, 18 }, +/* 4820 */ { MAD_F(0x04f82eb7) /* 0.310591426 */, 18 }, +/* 4821 */ { MAD_F(0x04f888cf) /* 0.310677346 */, 18 }, +/* 4822 */ { MAD_F(0x04f8e2e9) /* 0.310763272 */, 18 }, +/* 4823 */ { MAD_F(0x04f93d04) /* 0.310849205 */, 18 }, +/* 4824 */ { MAD_F(0x04f99721) /* 0.310935143 */, 18 }, +/* 4825 */ { MAD_F(0x04f9f13f) /* 0.311021087 */, 18 }, +/* 4826 */ { MAD_F(0x04fa4b5f) /* 0.311107037 */, 18 }, +/* 4827 */ { MAD_F(0x04faa581) /* 0.311192993 */, 18 }, +/* 4828 */ { MAD_F(0x04faffa4) /* 0.311278955 */, 18 }, +/* 4829 */ { MAD_F(0x04fb59c9) /* 0.311364923 */, 18 }, +/* 4830 */ { MAD_F(0x04fbb3ef) /* 0.311450897 */, 18 }, +/* 4831 */ { MAD_F(0x04fc0e17) /* 0.311536877 */, 18 }, + +/* 4832 */ { MAD_F(0x04fc6841) /* 0.311622862 */, 18 }, +/* 4833 */ { MAD_F(0x04fcc26c) /* 0.311708854 */, 18 }, +/* 4834 */ { MAD_F(0x04fd1c99) /* 0.311794851 */, 18 }, +/* 4835 */ { MAD_F(0x04fd76c7) /* 0.311880855 */, 18 }, +/* 4836 */ { MAD_F(0x04fdd0f7) /* 0.311966864 */, 18 }, +/* 4837 */ { MAD_F(0x04fe2b29) /* 0.312052880 */, 18 }, +/* 4838 */ { MAD_F(0x04fe855c) /* 0.312138901 */, 18 }, +/* 4839 */ { MAD_F(0x04fedf91) /* 0.312224928 */, 18 }, +/* 4840 */ { MAD_F(0x04ff39c7) /* 0.312310961 */, 18 }, +/* 4841 */ { MAD_F(0x04ff93ff) /* 0.312397000 */, 18 }, +/* 4842 */ { MAD_F(0x04ffee38) /* 0.312483045 */, 18 }, +/* 4843 */ { MAD_F(0x05004874) /* 0.312569096 */, 18 }, +/* 4844 */ { MAD_F(0x0500a2b0) /* 0.312655153 */, 18 }, +/* 4845 */ { MAD_F(0x0500fcef) /* 0.312741216 */, 18 }, +/* 4846 */ { MAD_F(0x0501572e) /* 0.312827284 */, 18 }, +/* 4847 */ { MAD_F(0x0501b170) /* 0.312913359 */, 18 }, + +/* 4848 */ { MAD_F(0x05020bb3) /* 0.312999439 */, 18 }, +/* 4849 */ { MAD_F(0x050265f8) /* 0.313085526 */, 18 }, +/* 4850 */ { MAD_F(0x0502c03e) /* 0.313171618 */, 18 }, +/* 4851 */ { MAD_F(0x05031a86) /* 0.313257716 */, 18 }, +/* 4852 */ { MAD_F(0x050374cf) /* 0.313343820 */, 18 }, +/* 4853 */ { MAD_F(0x0503cf1a) /* 0.313429931 */, 18 }, +/* 4854 */ { MAD_F(0x05042967) /* 0.313516047 */, 18 }, +/* 4855 */ { MAD_F(0x050483b5) /* 0.313602168 */, 18 }, +/* 4856 */ { MAD_F(0x0504de05) /* 0.313688296 */, 18 }, +/* 4857 */ { MAD_F(0x05053856) /* 0.313774430 */, 18 }, +/* 4858 */ { MAD_F(0x050592a9) /* 0.313860570 */, 18 }, +/* 4859 */ { MAD_F(0x0505ecfd) /* 0.313946715 */, 18 }, +/* 4860 */ { MAD_F(0x05064754) /* 0.314032867 */, 18 }, +/* 4861 */ { MAD_F(0x0506a1ab) /* 0.314119024 */, 18 }, +/* 4862 */ { MAD_F(0x0506fc04) /* 0.314205187 */, 18 }, +/* 4863 */ { MAD_F(0x0507565f) /* 0.314291357 */, 18 }, + +/* 4864 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 18 }, +/* 4865 */ { MAD_F(0x05080b1a) /* 0.314463713 */, 18 }, +/* 4866 */ { MAD_F(0x05086579) /* 0.314549900 */, 18 }, +/* 4867 */ { MAD_F(0x0508bfdb) /* 0.314636092 */, 18 }, +/* 4868 */ { MAD_F(0x05091a3d) /* 0.314722291 */, 18 }, +/* 4869 */ { MAD_F(0x050974a2) /* 0.314808496 */, 18 }, +/* 4870 */ { MAD_F(0x0509cf08) /* 0.314894706 */, 18 }, +/* 4871 */ { MAD_F(0x050a296f) /* 0.314980923 */, 18 }, +/* 4872 */ { MAD_F(0x050a83d8) /* 0.315067145 */, 18 }, +/* 4873 */ { MAD_F(0x050ade43) /* 0.315153373 */, 18 }, +/* 4874 */ { MAD_F(0x050b38af) /* 0.315239607 */, 18 }, +/* 4875 */ { MAD_F(0x050b931d) /* 0.315325847 */, 18 }, +/* 4876 */ { MAD_F(0x050bed8d) /* 0.315412093 */, 18 }, +/* 4877 */ { MAD_F(0x050c47fe) /* 0.315498345 */, 18 }, +/* 4878 */ { MAD_F(0x050ca271) /* 0.315584603 */, 18 }, +/* 4879 */ { MAD_F(0x050cfce5) /* 0.315670866 */, 18 }, + +/* 4880 */ { MAD_F(0x050d575b) /* 0.315757136 */, 18 }, +/* 4881 */ { MAD_F(0x050db1d2) /* 0.315843411 */, 18 }, +/* 4882 */ { MAD_F(0x050e0c4b) /* 0.315929693 */, 18 }, +/* 4883 */ { MAD_F(0x050e66c5) /* 0.316015980 */, 18 }, +/* 4884 */ { MAD_F(0x050ec141) /* 0.316102273 */, 18 }, +/* 4885 */ { MAD_F(0x050f1bbf) /* 0.316188572 */, 18 }, +/* 4886 */ { MAD_F(0x050f763e) /* 0.316274877 */, 18 }, +/* 4887 */ { MAD_F(0x050fd0bf) /* 0.316361187 */, 18 }, +/* 4888 */ { MAD_F(0x05102b42) /* 0.316447504 */, 18 }, +/* 4889 */ { MAD_F(0x051085c6) /* 0.316533826 */, 18 }, +/* 4890 */ { MAD_F(0x0510e04b) /* 0.316620155 */, 18 }, +/* 4891 */ { MAD_F(0x05113ad3) /* 0.316706489 */, 18 }, +/* 4892 */ { MAD_F(0x0511955b) /* 0.316792829 */, 18 }, +/* 4893 */ { MAD_F(0x0511efe6) /* 0.316879175 */, 18 }, +/* 4894 */ { MAD_F(0x05124a72) /* 0.316965527 */, 18 }, +/* 4895 */ { MAD_F(0x0512a4ff) /* 0.317051885 */, 18 }, + +/* 4896 */ { MAD_F(0x0512ff8e) /* 0.317138249 */, 18 }, +/* 4897 */ { MAD_F(0x05135a1f) /* 0.317224618 */, 18 }, +/* 4898 */ { MAD_F(0x0513b4b1) /* 0.317310994 */, 18 }, +/* 4899 */ { MAD_F(0x05140f45) /* 0.317397375 */, 18 }, +/* 4900 */ { MAD_F(0x051469da) /* 0.317483762 */, 18 }, +/* 4901 */ { MAD_F(0x0514c471) /* 0.317570155 */, 18 }, +/* 4902 */ { MAD_F(0x05151f0a) /* 0.317656554 */, 18 }, +/* 4903 */ { MAD_F(0x051579a4) /* 0.317742959 */, 18 }, +/* 4904 */ { MAD_F(0x0515d440) /* 0.317829370 */, 18 }, +/* 4905 */ { MAD_F(0x05162edd) /* 0.317915786 */, 18 }, +/* 4906 */ { MAD_F(0x0516897c) /* 0.318002209 */, 18 }, +/* 4907 */ { MAD_F(0x0516e41c) /* 0.318088637 */, 18 }, +/* 4908 */ { MAD_F(0x05173ebe) /* 0.318175071 */, 18 }, +/* 4909 */ { MAD_F(0x05179962) /* 0.318261511 */, 18 }, +/* 4910 */ { MAD_F(0x0517f407) /* 0.318347957 */, 18 }, +/* 4911 */ { MAD_F(0x05184eae) /* 0.318434409 */, 18 }, + +/* 4912 */ { MAD_F(0x0518a956) /* 0.318520867 */, 18 }, +/* 4913 */ { MAD_F(0x05190400) /* 0.318607330 */, 18 }, +/* 4914 */ { MAD_F(0x05195eab) /* 0.318693800 */, 18 }, +/* 4915 */ { MAD_F(0x0519b958) /* 0.318780275 */, 18 }, +/* 4916 */ { MAD_F(0x051a1407) /* 0.318866756 */, 18 }, +/* 4917 */ { MAD_F(0x051a6eb7) /* 0.318953243 */, 18 }, +/* 4918 */ { MAD_F(0x051ac969) /* 0.319039736 */, 18 }, +/* 4919 */ { MAD_F(0x051b241c) /* 0.319126235 */, 18 }, +/* 4920 */ { MAD_F(0x051b7ed1) /* 0.319212739 */, 18 }, +/* 4921 */ { MAD_F(0x051bd987) /* 0.319299250 */, 18 }, +/* 4922 */ { MAD_F(0x051c3440) /* 0.319385766 */, 18 }, +/* 4923 */ { MAD_F(0x051c8ef9) /* 0.319472288 */, 18 }, +/* 4924 */ { MAD_F(0x051ce9b4) /* 0.319558816 */, 18 }, +/* 4925 */ { MAD_F(0x051d4471) /* 0.319645350 */, 18 }, +/* 4926 */ { MAD_F(0x051d9f2f) /* 0.319731890 */, 18 }, +/* 4927 */ { MAD_F(0x051df9ef) /* 0.319818435 */, 18 }, + +/* 4928 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 18 }, +/* 4929 */ { MAD_F(0x051eaf74) /* 0.319991544 */, 18 }, +/* 4930 */ { MAD_F(0x051f0a38) /* 0.320078107 */, 18 }, +/* 4931 */ { MAD_F(0x051f64ff) /* 0.320164676 */, 18 }, +/* 4932 */ { MAD_F(0x051fbfc6) /* 0.320251251 */, 18 }, +/* 4933 */ { MAD_F(0x05201a90) /* 0.320337832 */, 18 }, +/* 4934 */ { MAD_F(0x0520755b) /* 0.320424419 */, 18 }, +/* 4935 */ { MAD_F(0x0520d027) /* 0.320511011 */, 18 }, +/* 4936 */ { MAD_F(0x05212af5) /* 0.320597609 */, 18 }, +/* 4937 */ { MAD_F(0x052185c5) /* 0.320684213 */, 18 }, +/* 4938 */ { MAD_F(0x0521e096) /* 0.320770823 */, 18 }, +/* 4939 */ { MAD_F(0x05223b69) /* 0.320857439 */, 18 }, +/* 4940 */ { MAD_F(0x0522963d) /* 0.320944061 */, 18 }, +/* 4941 */ { MAD_F(0x0522f113) /* 0.321030688 */, 18 }, +/* 4942 */ { MAD_F(0x05234bea) /* 0.321117322 */, 18 }, +/* 4943 */ { MAD_F(0x0523a6c3) /* 0.321203961 */, 18 }, + +/* 4944 */ { MAD_F(0x0524019e) /* 0.321290606 */, 18 }, +/* 4945 */ { MAD_F(0x05245c7a) /* 0.321377257 */, 18 }, +/* 4946 */ { MAD_F(0x0524b758) /* 0.321463913 */, 18 }, +/* 4947 */ { MAD_F(0x05251237) /* 0.321550576 */, 18 }, +/* 4948 */ { MAD_F(0x05256d18) /* 0.321637244 */, 18 }, +/* 4949 */ { MAD_F(0x0525c7fb) /* 0.321723919 */, 18 }, +/* 4950 */ { MAD_F(0x052622df) /* 0.321810599 */, 18 }, +/* 4951 */ { MAD_F(0x05267dc4) /* 0.321897285 */, 18 }, +/* 4952 */ { MAD_F(0x0526d8ab) /* 0.321983976 */, 18 }, +/* 4953 */ { MAD_F(0x05273394) /* 0.322070674 */, 18 }, +/* 4954 */ { MAD_F(0x05278e7e) /* 0.322157377 */, 18 }, +/* 4955 */ { MAD_F(0x0527e96a) /* 0.322244087 */, 18 }, +/* 4956 */ { MAD_F(0x05284457) /* 0.322330802 */, 18 }, +/* 4957 */ { MAD_F(0x05289f46) /* 0.322417523 */, 18 }, +/* 4958 */ { MAD_F(0x0528fa37) /* 0.322504249 */, 18 }, +/* 4959 */ { MAD_F(0x05295529) /* 0.322590982 */, 18 }, + +/* 4960 */ { MAD_F(0x0529b01d) /* 0.322677720 */, 18 }, +/* 4961 */ { MAD_F(0x052a0b12) /* 0.322764465 */, 18 }, +/* 4962 */ { MAD_F(0x052a6609) /* 0.322851215 */, 18 }, +/* 4963 */ { MAD_F(0x052ac101) /* 0.322937971 */, 18 }, +/* 4964 */ { MAD_F(0x052b1bfb) /* 0.323024732 */, 18 }, +/* 4965 */ { MAD_F(0x052b76f7) /* 0.323111500 */, 18 }, +/* 4966 */ { MAD_F(0x052bd1f4) /* 0.323198273 */, 18 }, +/* 4967 */ { MAD_F(0x052c2cf2) /* 0.323285052 */, 18 }, +/* 4968 */ { MAD_F(0x052c87f2) /* 0.323371837 */, 18 }, +/* 4969 */ { MAD_F(0x052ce2f4) /* 0.323458628 */, 18 }, +/* 4970 */ { MAD_F(0x052d3df7) /* 0.323545425 */, 18 }, +/* 4971 */ { MAD_F(0x052d98fc) /* 0.323632227 */, 18 }, +/* 4972 */ { MAD_F(0x052df403) /* 0.323719036 */, 18 }, +/* 4973 */ { MAD_F(0x052e4f0b) /* 0.323805850 */, 18 }, +/* 4974 */ { MAD_F(0x052eaa14) /* 0.323892670 */, 18 }, +/* 4975 */ { MAD_F(0x052f051f) /* 0.323979496 */, 18 }, + +/* 4976 */ { MAD_F(0x052f602c) /* 0.324066327 */, 18 }, +/* 4977 */ { MAD_F(0x052fbb3a) /* 0.324153165 */, 18 }, +/* 4978 */ { MAD_F(0x0530164a) /* 0.324240008 */, 18 }, +/* 4979 */ { MAD_F(0x0530715b) /* 0.324326857 */, 18 }, +/* 4980 */ { MAD_F(0x0530cc6e) /* 0.324413712 */, 18 }, +/* 4981 */ { MAD_F(0x05312783) /* 0.324500572 */, 18 }, +/* 4982 */ { MAD_F(0x05318299) /* 0.324587439 */, 18 }, +/* 4983 */ { MAD_F(0x0531ddb0) /* 0.324674311 */, 18 }, +/* 4984 */ { MAD_F(0x053238ca) /* 0.324761189 */, 18 }, +/* 4985 */ { MAD_F(0x053293e4) /* 0.324848073 */, 18 }, +/* 4986 */ { MAD_F(0x0532ef01) /* 0.324934963 */, 18 }, +/* 4987 */ { MAD_F(0x05334a1e) /* 0.325021858 */, 18 }, +/* 4988 */ { MAD_F(0x0533a53e) /* 0.325108760 */, 18 }, +/* 4989 */ { MAD_F(0x0534005f) /* 0.325195667 */, 18 }, +/* 4990 */ { MAD_F(0x05345b81) /* 0.325282580 */, 18 }, +/* 4991 */ { MAD_F(0x0534b6a5) /* 0.325369498 */, 18 }, + +/* 4992 */ { MAD_F(0x053511cb) /* 0.325456423 */, 18 }, +/* 4993 */ { MAD_F(0x05356cf2) /* 0.325543353 */, 18 }, +/* 4994 */ { MAD_F(0x0535c81b) /* 0.325630290 */, 18 }, +/* 4995 */ { MAD_F(0x05362345) /* 0.325717232 */, 18 }, +/* 4996 */ { MAD_F(0x05367e71) /* 0.325804179 */, 18 }, +/* 4997 */ { MAD_F(0x0536d99f) /* 0.325891133 */, 18 }, +/* 4998 */ { MAD_F(0x053734ce) /* 0.325978092 */, 18 }, +/* 4999 */ { MAD_F(0x05378ffe) /* 0.326065057 */, 18 }, +/* 5000 */ { MAD_F(0x0537eb30) /* 0.326152028 */, 18 }, +/* 5001 */ { MAD_F(0x05384664) /* 0.326239005 */, 18 }, +/* 5002 */ { MAD_F(0x0538a199) /* 0.326325988 */, 18 }, +/* 5003 */ { MAD_F(0x0538fcd0) /* 0.326412976 */, 18 }, +/* 5004 */ { MAD_F(0x05395808) /* 0.326499970 */, 18 }, +/* 5005 */ { MAD_F(0x0539b342) /* 0.326586970 */, 18 }, +/* 5006 */ { MAD_F(0x053a0e7d) /* 0.326673976 */, 18 }, +/* 5007 */ { MAD_F(0x053a69ba) /* 0.326760988 */, 18 }, + +/* 5008 */ { MAD_F(0x053ac4f9) /* 0.326848005 */, 18 }, +/* 5009 */ { MAD_F(0x053b2039) /* 0.326935028 */, 18 }, +/* 5010 */ { MAD_F(0x053b7b7b) /* 0.327022057 */, 18 }, +/* 5011 */ { MAD_F(0x053bd6be) /* 0.327109092 */, 18 }, +/* 5012 */ { MAD_F(0x053c3203) /* 0.327196132 */, 18 }, +/* 5013 */ { MAD_F(0x053c8d49) /* 0.327283178 */, 18 }, +/* 5014 */ { MAD_F(0x053ce891) /* 0.327370231 */, 18 }, +/* 5015 */ { MAD_F(0x053d43da) /* 0.327457288 */, 18 }, +/* 5016 */ { MAD_F(0x053d9f25) /* 0.327544352 */, 18 }, +/* 5017 */ { MAD_F(0x053dfa72) /* 0.327631421 */, 18 }, +/* 5018 */ { MAD_F(0x053e55c0) /* 0.327718497 */, 18 }, +/* 5019 */ { MAD_F(0x053eb10f) /* 0.327805578 */, 18 }, +/* 5020 */ { MAD_F(0x053f0c61) /* 0.327892665 */, 18 }, +/* 5021 */ { MAD_F(0x053f67b3) /* 0.327979757 */, 18 }, +/* 5022 */ { MAD_F(0x053fc308) /* 0.328066855 */, 18 }, +/* 5023 */ { MAD_F(0x05401e5e) /* 0.328153960 */, 18 }, + +/* 5024 */ { MAD_F(0x054079b5) /* 0.328241070 */, 18 }, +/* 5025 */ { MAD_F(0x0540d50e) /* 0.328328185 */, 18 }, +/* 5026 */ { MAD_F(0x05413068) /* 0.328415307 */, 18 }, +/* 5027 */ { MAD_F(0x05418bc4) /* 0.328502434 */, 18 }, +/* 5028 */ { MAD_F(0x0541e722) /* 0.328589567 */, 18 }, +/* 5029 */ { MAD_F(0x05424281) /* 0.328676706 */, 18 }, +/* 5030 */ { MAD_F(0x05429de2) /* 0.328763850 */, 18 }, +/* 5031 */ { MAD_F(0x0542f944) /* 0.328851001 */, 18 }, +/* 5032 */ { MAD_F(0x054354a8) /* 0.328938157 */, 18 }, +/* 5033 */ { MAD_F(0x0543b00d) /* 0.329025319 */, 18 }, +/* 5034 */ { MAD_F(0x05440b74) /* 0.329112486 */, 18 }, +/* 5035 */ { MAD_F(0x054466dd) /* 0.329199660 */, 18 }, +/* 5036 */ { MAD_F(0x0544c247) /* 0.329286839 */, 18 }, +/* 5037 */ { MAD_F(0x05451db2) /* 0.329374024 */, 18 }, +/* 5038 */ { MAD_F(0x0545791f) /* 0.329461215 */, 18 }, +/* 5039 */ { MAD_F(0x0545d48e) /* 0.329548411 */, 18 }, + +/* 5040 */ { MAD_F(0x05462ffe) /* 0.329635614 */, 18 }, +/* 5041 */ { MAD_F(0x05468b70) /* 0.329722822 */, 18 }, +/* 5042 */ { MAD_F(0x0546e6e3) /* 0.329810036 */, 18 }, +/* 5043 */ { MAD_F(0x05474258) /* 0.329897255 */, 18 }, +/* 5044 */ { MAD_F(0x05479dce) /* 0.329984481 */, 18 }, +/* 5045 */ { MAD_F(0x0547f946) /* 0.330071712 */, 18 }, +/* 5046 */ { MAD_F(0x054854c0) /* 0.330158949 */, 18 }, +/* 5047 */ { MAD_F(0x0548b03b) /* 0.330246191 */, 18 }, +/* 5048 */ { MAD_F(0x05490bb7) /* 0.330333440 */, 18 }, +/* 5049 */ { MAD_F(0x05496735) /* 0.330420694 */, 18 }, +/* 5050 */ { MAD_F(0x0549c2b5) /* 0.330507954 */, 18 }, +/* 5051 */ { MAD_F(0x054a1e36) /* 0.330595220 */, 18 }, +/* 5052 */ { MAD_F(0x054a79b9) /* 0.330682491 */, 18 }, +/* 5053 */ { MAD_F(0x054ad53d) /* 0.330769768 */, 18 }, +/* 5054 */ { MAD_F(0x054b30c3) /* 0.330857051 */, 18 }, +/* 5055 */ { MAD_F(0x054b8c4b) /* 0.330944340 */, 18 }, + +/* 5056 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 18 }, +/* 5057 */ { MAD_F(0x054c435e) /* 0.331118935 */, 18 }, +/* 5058 */ { MAD_F(0x054c9eea) /* 0.331206241 */, 18 }, +/* 5059 */ { MAD_F(0x054cfa78) /* 0.331293553 */, 18 }, +/* 5060 */ { MAD_F(0x054d5607) /* 0.331380870 */, 18 }, +/* 5061 */ { MAD_F(0x054db197) /* 0.331468193 */, 18 }, +/* 5062 */ { MAD_F(0x054e0d2a) /* 0.331555522 */, 18 }, +/* 5063 */ { MAD_F(0x054e68bd) /* 0.331642857 */, 18 }, +/* 5064 */ { MAD_F(0x054ec453) /* 0.331730198 */, 18 }, +/* 5065 */ { MAD_F(0x054f1fe9) /* 0.331817544 */, 18 }, +/* 5066 */ { MAD_F(0x054f7b82) /* 0.331904896 */, 18 }, +/* 5067 */ { MAD_F(0x054fd71c) /* 0.331992254 */, 18 }, +/* 5068 */ { MAD_F(0x055032b7) /* 0.332079617 */, 18 }, +/* 5069 */ { MAD_F(0x05508e54) /* 0.332166986 */, 18 }, +/* 5070 */ { MAD_F(0x0550e9f3) /* 0.332254361 */, 18 }, +/* 5071 */ { MAD_F(0x05514593) /* 0.332341742 */, 18 }, + +/* 5072 */ { MAD_F(0x0551a134) /* 0.332429129 */, 18 }, +/* 5073 */ { MAD_F(0x0551fcd8) /* 0.332516521 */, 18 }, +/* 5074 */ { MAD_F(0x0552587c) /* 0.332603919 */, 18 }, +/* 5075 */ { MAD_F(0x0552b423) /* 0.332691323 */, 18 }, +/* 5076 */ { MAD_F(0x05530fca) /* 0.332778732 */, 18 }, +/* 5077 */ { MAD_F(0x05536b74) /* 0.332866147 */, 18 }, +/* 5078 */ { MAD_F(0x0553c71f) /* 0.332953568 */, 18 }, +/* 5079 */ { MAD_F(0x055422cb) /* 0.333040995 */, 18 }, +/* 5080 */ { MAD_F(0x05547e79) /* 0.333128427 */, 18 }, +/* 5081 */ { MAD_F(0x0554da29) /* 0.333215865 */, 18 }, +/* 5082 */ { MAD_F(0x055535da) /* 0.333303309 */, 18 }, +/* 5083 */ { MAD_F(0x0555918c) /* 0.333390759 */, 18 }, +/* 5084 */ { MAD_F(0x0555ed40) /* 0.333478214 */, 18 }, +/* 5085 */ { MAD_F(0x055648f6) /* 0.333565675 */, 18 }, +/* 5086 */ { MAD_F(0x0556a4ad) /* 0.333653142 */, 18 }, +/* 5087 */ { MAD_F(0x05570066) /* 0.333740615 */, 18 }, + +/* 5088 */ { MAD_F(0x05575c20) /* 0.333828093 */, 18 }, +/* 5089 */ { MAD_F(0x0557b7dc) /* 0.333915577 */, 18 }, +/* 5090 */ { MAD_F(0x05581399) /* 0.334003067 */, 18 }, +/* 5091 */ { MAD_F(0x05586f58) /* 0.334090562 */, 18 }, +/* 5092 */ { MAD_F(0x0558cb19) /* 0.334178063 */, 18 }, +/* 5093 */ { MAD_F(0x055926db) /* 0.334265570 */, 18 }, +/* 5094 */ { MAD_F(0x0559829e) /* 0.334353083 */, 18 }, +/* 5095 */ { MAD_F(0x0559de63) /* 0.334440601 */, 18 }, +/* 5096 */ { MAD_F(0x055a3a2a) /* 0.334528126 */, 18 }, +/* 5097 */ { MAD_F(0x055a95f2) /* 0.334615655 */, 18 }, +/* 5098 */ { MAD_F(0x055af1bb) /* 0.334703191 */, 18 }, +/* 5099 */ { MAD_F(0x055b4d87) /* 0.334790732 */, 18 }, +/* 5100 */ { MAD_F(0x055ba953) /* 0.334878279 */, 18 }, +/* 5101 */ { MAD_F(0x055c0522) /* 0.334965832 */, 18 }, +/* 5102 */ { MAD_F(0x055c60f1) /* 0.335053391 */, 18 }, +/* 5103 */ { MAD_F(0x055cbcc3) /* 0.335140955 */, 18 }, + +/* 5104 */ { MAD_F(0x055d1896) /* 0.335228525 */, 18 }, +/* 5105 */ { MAD_F(0x055d746a) /* 0.335316100 */, 18 }, +/* 5106 */ { MAD_F(0x055dd040) /* 0.335403682 */, 18 }, +/* 5107 */ { MAD_F(0x055e2c17) /* 0.335491269 */, 18 }, +/* 5108 */ { MAD_F(0x055e87f0) /* 0.335578861 */, 18 }, +/* 5109 */ { MAD_F(0x055ee3cb) /* 0.335666460 */, 18 }, +/* 5110 */ { MAD_F(0x055f3fa7) /* 0.335754064 */, 18 }, +/* 5111 */ { MAD_F(0x055f9b85) /* 0.335841674 */, 18 }, +/* 5112 */ { MAD_F(0x055ff764) /* 0.335929290 */, 18 }, +/* 5113 */ { MAD_F(0x05605344) /* 0.336016911 */, 18 }, +/* 5114 */ { MAD_F(0x0560af27) /* 0.336104538 */, 18 }, +/* 5115 */ { MAD_F(0x05610b0a) /* 0.336192171 */, 18 }, +/* 5116 */ { MAD_F(0x056166f0) /* 0.336279809 */, 18 }, +/* 5117 */ { MAD_F(0x0561c2d7) /* 0.336367453 */, 18 }, +/* 5118 */ { MAD_F(0x05621ebf) /* 0.336455103 */, 18 }, +/* 5119 */ { MAD_F(0x05627aa9) /* 0.336542759 */, 18 }, + +/* 5120 */ { MAD_F(0x0562d694) /* 0.336630420 */, 18 }, +/* 5121 */ { MAD_F(0x05633281) /* 0.336718087 */, 18 }, +/* 5122 */ { MAD_F(0x05638e70) /* 0.336805760 */, 18 }, +/* 5123 */ { MAD_F(0x0563ea60) /* 0.336893439 */, 18 }, +/* 5124 */ { MAD_F(0x05644651) /* 0.336981123 */, 18 }, +/* 5125 */ { MAD_F(0x0564a244) /* 0.337068813 */, 18 }, +/* 5126 */ { MAD_F(0x0564fe39) /* 0.337156508 */, 18 }, +/* 5127 */ { MAD_F(0x05655a2f) /* 0.337244209 */, 18 }, +/* 5128 */ { MAD_F(0x0565b627) /* 0.337331916 */, 18 }, +/* 5129 */ { MAD_F(0x05661220) /* 0.337419629 */, 18 }, +/* 5130 */ { MAD_F(0x05666e1a) /* 0.337507347 */, 18 }, +/* 5131 */ { MAD_F(0x0566ca17) /* 0.337595071 */, 18 }, +/* 5132 */ { MAD_F(0x05672614) /* 0.337682801 */, 18 }, +/* 5133 */ { MAD_F(0x05678214) /* 0.337770537 */, 18 }, +/* 5134 */ { MAD_F(0x0567de15) /* 0.337858278 */, 18 }, +/* 5135 */ { MAD_F(0x05683a17) /* 0.337946025 */, 18 }, + +/* 5136 */ { MAD_F(0x0568961b) /* 0.338033777 */, 18 }, +/* 5137 */ { MAD_F(0x0568f220) /* 0.338121535 */, 18 }, +/* 5138 */ { MAD_F(0x05694e27) /* 0.338209299 */, 18 }, +/* 5139 */ { MAD_F(0x0569aa30) /* 0.338297069 */, 18 }, +/* 5140 */ { MAD_F(0x056a063a) /* 0.338384844 */, 18 }, +/* 5141 */ { MAD_F(0x056a6245) /* 0.338472625 */, 18 }, +/* 5142 */ { MAD_F(0x056abe52) /* 0.338560412 */, 18 }, +/* 5143 */ { MAD_F(0x056b1a61) /* 0.338648204 */, 18 }, +/* 5144 */ { MAD_F(0x056b7671) /* 0.338736002 */, 18 }, +/* 5145 */ { MAD_F(0x056bd283) /* 0.338823806 */, 18 }, +/* 5146 */ { MAD_F(0x056c2e96) /* 0.338911616 */, 18 }, +/* 5147 */ { MAD_F(0x056c8aab) /* 0.338999431 */, 18 }, +/* 5148 */ { MAD_F(0x056ce6c1) /* 0.339087252 */, 18 }, +/* 5149 */ { MAD_F(0x056d42d9) /* 0.339175078 */, 18 }, +/* 5150 */ { MAD_F(0x056d9ef2) /* 0.339262910 */, 18 }, +/* 5151 */ { MAD_F(0x056dfb0d) /* 0.339350748 */, 18 }, + +/* 5152 */ { MAD_F(0x056e5729) /* 0.339438592 */, 18 }, +/* 5153 */ { MAD_F(0x056eb347) /* 0.339526441 */, 18 }, +/* 5154 */ { MAD_F(0x056f0f66) /* 0.339614296 */, 18 }, +/* 5155 */ { MAD_F(0x056f6b87) /* 0.339702157 */, 18 }, +/* 5156 */ { MAD_F(0x056fc7aa) /* 0.339790023 */, 18 }, +/* 5157 */ { MAD_F(0x057023cd) /* 0.339877895 */, 18 }, +/* 5158 */ { MAD_F(0x05707ff3) /* 0.339965773 */, 18 }, +/* 5159 */ { MAD_F(0x0570dc1a) /* 0.340053656 */, 18 }, +/* 5160 */ { MAD_F(0x05713843) /* 0.340141545 */, 18 }, +/* 5161 */ { MAD_F(0x0571946d) /* 0.340229440 */, 18 }, +/* 5162 */ { MAD_F(0x0571f098) /* 0.340317340 */, 18 }, +/* 5163 */ { MAD_F(0x05724cc5) /* 0.340405246 */, 18 }, +/* 5164 */ { MAD_F(0x0572a8f4) /* 0.340493158 */, 18 }, +/* 5165 */ { MAD_F(0x05730524) /* 0.340581075 */, 18 }, +/* 5166 */ { MAD_F(0x05736156) /* 0.340668999 */, 18 }, +/* 5167 */ { MAD_F(0x0573bd89) /* 0.340756927 */, 18 }, + +/* 5168 */ { MAD_F(0x057419be) /* 0.340844862 */, 18 }, +/* 5169 */ { MAD_F(0x057475f4) /* 0.340932802 */, 18 }, +/* 5170 */ { MAD_F(0x0574d22c) /* 0.341020748 */, 18 }, +/* 5171 */ { MAD_F(0x05752e65) /* 0.341108699 */, 18 }, +/* 5172 */ { MAD_F(0x05758aa0) /* 0.341196656 */, 18 }, +/* 5173 */ { MAD_F(0x0575e6dc) /* 0.341284619 */, 18 }, +/* 5174 */ { MAD_F(0x0576431a) /* 0.341372587 */, 18 }, +/* 5175 */ { MAD_F(0x05769f59) /* 0.341460562 */, 18 }, +/* 5176 */ { MAD_F(0x0576fb9a) /* 0.341548541 */, 18 }, +/* 5177 */ { MAD_F(0x057757dd) /* 0.341636527 */, 18 }, +/* 5178 */ { MAD_F(0x0577b421) /* 0.341724518 */, 18 }, +/* 5179 */ { MAD_F(0x05781066) /* 0.341812515 */, 18 }, +/* 5180 */ { MAD_F(0x05786cad) /* 0.341900517 */, 18 }, +/* 5181 */ { MAD_F(0x0578c8f5) /* 0.341988525 */, 18 }, +/* 5182 */ { MAD_F(0x0579253f) /* 0.342076539 */, 18 }, +/* 5183 */ { MAD_F(0x0579818b) /* 0.342164558 */, 18 }, + +/* 5184 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 18 }, +/* 5185 */ { MAD_F(0x057a3a27) /* 0.342340614 */, 18 }, +/* 5186 */ { MAD_F(0x057a9677) /* 0.342428651 */, 18 }, +/* 5187 */ { MAD_F(0x057af2c8) /* 0.342516693 */, 18 }, +/* 5188 */ { MAD_F(0x057b4f1c) /* 0.342604741 */, 18 }, +/* 5189 */ { MAD_F(0x057bab70) /* 0.342692794 */, 18 }, +/* 5190 */ { MAD_F(0x057c07c6) /* 0.342780853 */, 18 }, +/* 5191 */ { MAD_F(0x057c641e) /* 0.342868918 */, 18 }, +/* 5192 */ { MAD_F(0x057cc077) /* 0.342956988 */, 18 }, +/* 5193 */ { MAD_F(0x057d1cd2) /* 0.343045064 */, 18 }, +/* 5194 */ { MAD_F(0x057d792e) /* 0.343133146 */, 18 }, +/* 5195 */ { MAD_F(0x057dd58c) /* 0.343221233 */, 18 }, +/* 5196 */ { MAD_F(0x057e31eb) /* 0.343309326 */, 18 }, +/* 5197 */ { MAD_F(0x057e8e4c) /* 0.343397425 */, 18 }, +/* 5198 */ { MAD_F(0x057eeaae) /* 0.343485529 */, 18 }, +/* 5199 */ { MAD_F(0x057f4712) /* 0.343573639 */, 18 }, + +/* 5200 */ { MAD_F(0x057fa378) /* 0.343661754 */, 18 }, +/* 5201 */ { MAD_F(0x057fffde) /* 0.343749876 */, 18 }, +/* 5202 */ { MAD_F(0x05805c47) /* 0.343838003 */, 18 }, +/* 5203 */ { MAD_F(0x0580b8b1) /* 0.343926135 */, 18 }, +/* 5204 */ { MAD_F(0x0581151c) /* 0.344014273 */, 18 }, +/* 5205 */ { MAD_F(0x05817189) /* 0.344102417 */, 18 }, +/* 5206 */ { MAD_F(0x0581cdf7) /* 0.344190566 */, 18 }, +/* 5207 */ { MAD_F(0x05822a67) /* 0.344278722 */, 18 }, +/* 5208 */ { MAD_F(0x058286d9) /* 0.344366882 */, 18 }, +/* 5209 */ { MAD_F(0x0582e34c) /* 0.344455049 */, 18 }, +/* 5210 */ { MAD_F(0x05833fc0) /* 0.344543221 */, 18 }, +/* 5211 */ { MAD_F(0x05839c36) /* 0.344631398 */, 18 }, +/* 5212 */ { MAD_F(0x0583f8ae) /* 0.344719582 */, 18 }, +/* 5213 */ { MAD_F(0x05845527) /* 0.344807771 */, 18 }, +/* 5214 */ { MAD_F(0x0584b1a1) /* 0.344895965 */, 18 }, +/* 5215 */ { MAD_F(0x05850e1e) /* 0.344984165 */, 18 }, + +/* 5216 */ { MAD_F(0x05856a9b) /* 0.345072371 */, 18 }, +/* 5217 */ { MAD_F(0x0585c71a) /* 0.345160583 */, 18 }, +/* 5218 */ { MAD_F(0x0586239b) /* 0.345248800 */, 18 }, +/* 5219 */ { MAD_F(0x0586801d) /* 0.345337023 */, 18 }, +/* 5220 */ { MAD_F(0x0586dca1) /* 0.345425251 */, 18 }, +/* 5221 */ { MAD_F(0x05873926) /* 0.345513485 */, 18 }, +/* 5222 */ { MAD_F(0x058795ac) /* 0.345601725 */, 18 }, +/* 5223 */ { MAD_F(0x0587f235) /* 0.345689970 */, 18 }, +/* 5224 */ { MAD_F(0x05884ebe) /* 0.345778221 */, 18 }, +/* 5225 */ { MAD_F(0x0588ab49) /* 0.345866478 */, 18 }, +/* 5226 */ { MAD_F(0x058907d6) /* 0.345954740 */, 18 }, +/* 5227 */ { MAD_F(0x05896464) /* 0.346043008 */, 18 }, +/* 5228 */ { MAD_F(0x0589c0f4) /* 0.346131281 */, 18 }, +/* 5229 */ { MAD_F(0x058a1d85) /* 0.346219560 */, 18 }, +/* 5230 */ { MAD_F(0x058a7a18) /* 0.346307845 */, 18 }, +/* 5231 */ { MAD_F(0x058ad6ac) /* 0.346396135 */, 18 }, + +/* 5232 */ { MAD_F(0x058b3342) /* 0.346484431 */, 18 }, +/* 5233 */ { MAD_F(0x058b8fd9) /* 0.346572733 */, 18 }, +/* 5234 */ { MAD_F(0x058bec72) /* 0.346661040 */, 18 }, +/* 5235 */ { MAD_F(0x058c490c) /* 0.346749353 */, 18 }, +/* 5236 */ { MAD_F(0x058ca5a8) /* 0.346837671 */, 18 }, +/* 5237 */ { MAD_F(0x058d0246) /* 0.346925996 */, 18 }, +/* 5238 */ { MAD_F(0x058d5ee4) /* 0.347014325 */, 18 }, +/* 5239 */ { MAD_F(0x058dbb85) /* 0.347102661 */, 18 }, +/* 5240 */ { MAD_F(0x058e1827) /* 0.347191002 */, 18 }, +/* 5241 */ { MAD_F(0x058e74ca) /* 0.347279348 */, 18 }, +/* 5242 */ { MAD_F(0x058ed16f) /* 0.347367700 */, 18 }, +/* 5243 */ { MAD_F(0x058f2e15) /* 0.347456058 */, 18 }, +/* 5244 */ { MAD_F(0x058f8abd) /* 0.347544422 */, 18 }, +/* 5245 */ { MAD_F(0x058fe766) /* 0.347632791 */, 18 }, +/* 5246 */ { MAD_F(0x05904411) /* 0.347721165 */, 18 }, +/* 5247 */ { MAD_F(0x0590a0be) /* 0.347809546 */, 18 }, + +/* 5248 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 18 }, +/* 5249 */ { MAD_F(0x05915a1b) /* 0.347986323 */, 18 }, +/* 5250 */ { MAD_F(0x0591b6cc) /* 0.348074720 */, 18 }, +/* 5251 */ { MAD_F(0x0592137e) /* 0.348163123 */, 18 }, +/* 5252 */ { MAD_F(0x05927032) /* 0.348251531 */, 18 }, +/* 5253 */ { MAD_F(0x0592cce8) /* 0.348339945 */, 18 }, +/* 5254 */ { MAD_F(0x0593299f) /* 0.348428365 */, 18 }, +/* 5255 */ { MAD_F(0x05938657) /* 0.348516790 */, 18 }, +/* 5256 */ { MAD_F(0x0593e311) /* 0.348605221 */, 18 }, +/* 5257 */ { MAD_F(0x05943fcd) /* 0.348693657 */, 18 }, +/* 5258 */ { MAD_F(0x05949c8a) /* 0.348782099 */, 18 }, +/* 5259 */ { MAD_F(0x0594f948) /* 0.348870547 */, 18 }, +/* 5260 */ { MAD_F(0x05955608) /* 0.348959000 */, 18 }, +/* 5261 */ { MAD_F(0x0595b2ca) /* 0.349047459 */, 18 }, +/* 5262 */ { MAD_F(0x05960f8c) /* 0.349135923 */, 18 }, +/* 5263 */ { MAD_F(0x05966c51) /* 0.349224393 */, 18 }, + +/* 5264 */ { MAD_F(0x0596c917) /* 0.349312869 */, 18 }, +/* 5265 */ { MAD_F(0x059725de) /* 0.349401350 */, 18 }, +/* 5266 */ { MAD_F(0x059782a7) /* 0.349489837 */, 18 }, +/* 5267 */ { MAD_F(0x0597df72) /* 0.349578329 */, 18 }, +/* 5268 */ { MAD_F(0x05983c3e) /* 0.349666827 */, 18 }, +/* 5269 */ { MAD_F(0x0598990c) /* 0.349755331 */, 18 }, +/* 5270 */ { MAD_F(0x0598f5db) /* 0.349843840 */, 18 }, +/* 5271 */ { MAD_F(0x059952ab) /* 0.349932355 */, 18 }, +/* 5272 */ { MAD_F(0x0599af7d) /* 0.350020876 */, 18 }, +/* 5273 */ { MAD_F(0x059a0c51) /* 0.350109402 */, 18 }, +/* 5274 */ { MAD_F(0x059a6926) /* 0.350197933 */, 18 }, +/* 5275 */ { MAD_F(0x059ac5fc) /* 0.350286470 */, 18 }, +/* 5276 */ { MAD_F(0x059b22d4) /* 0.350375013 */, 18 }, +/* 5277 */ { MAD_F(0x059b7fae) /* 0.350463562 */, 18 }, +/* 5278 */ { MAD_F(0x059bdc89) /* 0.350552116 */, 18 }, +/* 5279 */ { MAD_F(0x059c3965) /* 0.350640675 */, 18 }, + +/* 5280 */ { MAD_F(0x059c9643) /* 0.350729240 */, 18 }, +/* 5281 */ { MAD_F(0x059cf323) /* 0.350817811 */, 18 }, +/* 5282 */ { MAD_F(0x059d5004) /* 0.350906388 */, 18 }, +/* 5283 */ { MAD_F(0x059dace6) /* 0.350994970 */, 18 }, +/* 5284 */ { MAD_F(0x059e09cb) /* 0.351083557 */, 18 }, +/* 5285 */ { MAD_F(0x059e66b0) /* 0.351172150 */, 18 }, +/* 5286 */ { MAD_F(0x059ec397) /* 0.351260749 */, 18 }, +/* 5287 */ { MAD_F(0x059f2080) /* 0.351349353 */, 18 }, +/* 5288 */ { MAD_F(0x059f7d6a) /* 0.351437963 */, 18 }, +/* 5289 */ { MAD_F(0x059fda55) /* 0.351526579 */, 18 }, +/* 5290 */ { MAD_F(0x05a03742) /* 0.351615200 */, 18 }, +/* 5291 */ { MAD_F(0x05a09431) /* 0.351703827 */, 18 }, +/* 5292 */ { MAD_F(0x05a0f121) /* 0.351792459 */, 18 }, +/* 5293 */ { MAD_F(0x05a14e12) /* 0.351881097 */, 18 }, +/* 5294 */ { MAD_F(0x05a1ab05) /* 0.351969740 */, 18 }, +/* 5295 */ { MAD_F(0x05a207fa) /* 0.352058389 */, 18 }, + +/* 5296 */ { MAD_F(0x05a264f0) /* 0.352147044 */, 18 }, +/* 5297 */ { MAD_F(0x05a2c1e7) /* 0.352235704 */, 18 }, +/* 5298 */ { MAD_F(0x05a31ee1) /* 0.352324369 */, 18 }, +/* 5299 */ { MAD_F(0x05a37bdb) /* 0.352413041 */, 18 }, +/* 5300 */ { MAD_F(0x05a3d8d7) /* 0.352501718 */, 18 }, +/* 5301 */ { MAD_F(0x05a435d5) /* 0.352590400 */, 18 }, +/* 5302 */ { MAD_F(0x05a492d4) /* 0.352679088 */, 18 }, +/* 5303 */ { MAD_F(0x05a4efd4) /* 0.352767782 */, 18 }, +/* 5304 */ { MAD_F(0x05a54cd6) /* 0.352856481 */, 18 }, +/* 5305 */ { MAD_F(0x05a5a9da) /* 0.352945186 */, 18 }, +/* 5306 */ { MAD_F(0x05a606df) /* 0.353033896 */, 18 }, +/* 5307 */ { MAD_F(0x05a663e5) /* 0.353122612 */, 18 }, +/* 5308 */ { MAD_F(0x05a6c0ed) /* 0.353211333 */, 18 }, +/* 5309 */ { MAD_F(0x05a71df7) /* 0.353300061 */, 18 }, +/* 5310 */ { MAD_F(0x05a77b02) /* 0.353388793 */, 18 }, +/* 5311 */ { MAD_F(0x05a7d80e) /* 0.353477531 */, 18 }, + +/* 5312 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 18 }, +/* 5313 */ { MAD_F(0x05a8922c) /* 0.353655024 */, 18 }, +/* 5314 */ { MAD_F(0x05a8ef3c) /* 0.353743779 */, 18 }, +/* 5315 */ { MAD_F(0x05a94c4f) /* 0.353832540 */, 18 }, +/* 5316 */ { MAD_F(0x05a9a963) /* 0.353921306 */, 18 }, +/* 5317 */ { MAD_F(0x05aa0678) /* 0.354010077 */, 18 }, +/* 5318 */ { MAD_F(0x05aa638f) /* 0.354098855 */, 18 }, +/* 5319 */ { MAD_F(0x05aac0a8) /* 0.354187637 */, 18 }, +/* 5320 */ { MAD_F(0x05ab1dc2) /* 0.354276426 */, 18 }, +/* 5321 */ { MAD_F(0x05ab7add) /* 0.354365220 */, 18 }, +/* 5322 */ { MAD_F(0x05abd7fa) /* 0.354454019 */, 18 }, +/* 5323 */ { MAD_F(0x05ac3518) /* 0.354542824 */, 18 }, +/* 5324 */ { MAD_F(0x05ac9238) /* 0.354631635 */, 18 }, +/* 5325 */ { MAD_F(0x05acef5a) /* 0.354720451 */, 18 }, +/* 5326 */ { MAD_F(0x05ad4c7d) /* 0.354809272 */, 18 }, +/* 5327 */ { MAD_F(0x05ada9a1) /* 0.354898100 */, 18 }, + +/* 5328 */ { MAD_F(0x05ae06c7) /* 0.354986932 */, 18 }, +/* 5329 */ { MAD_F(0x05ae63ee) /* 0.355075771 */, 18 }, +/* 5330 */ { MAD_F(0x05aec117) /* 0.355164615 */, 18 }, +/* 5331 */ { MAD_F(0x05af1e41) /* 0.355253464 */, 18 }, +/* 5332 */ { MAD_F(0x05af7b6d) /* 0.355342319 */, 18 }, +/* 5333 */ { MAD_F(0x05afd89b) /* 0.355431180 */, 18 }, +/* 5334 */ { MAD_F(0x05b035c9) /* 0.355520046 */, 18 }, +/* 5335 */ { MAD_F(0x05b092fa) /* 0.355608917 */, 18 }, +/* 5336 */ { MAD_F(0x05b0f02b) /* 0.355697795 */, 18 }, +/* 5337 */ { MAD_F(0x05b14d5f) /* 0.355786677 */, 18 }, +/* 5338 */ { MAD_F(0x05b1aa94) /* 0.355875566 */, 18 }, +/* 5339 */ { MAD_F(0x05b207ca) /* 0.355964460 */, 18 }, +/* 5340 */ { MAD_F(0x05b26502) /* 0.356053359 */, 18 }, +/* 5341 */ { MAD_F(0x05b2c23b) /* 0.356142264 */, 18 }, +/* 5342 */ { MAD_F(0x05b31f76) /* 0.356231175 */, 18 }, +/* 5343 */ { MAD_F(0x05b37cb2) /* 0.356320091 */, 18 }, + +/* 5344 */ { MAD_F(0x05b3d9f0) /* 0.356409012 */, 18 }, +/* 5345 */ { MAD_F(0x05b4372f) /* 0.356497940 */, 18 }, +/* 5346 */ { MAD_F(0x05b4946f) /* 0.356586872 */, 18 }, +/* 5347 */ { MAD_F(0x05b4f1b2) /* 0.356675811 */, 18 }, +/* 5348 */ { MAD_F(0x05b54ef5) /* 0.356764754 */, 18 }, +/* 5349 */ { MAD_F(0x05b5ac3a) /* 0.356853704 */, 18 }, +/* 5350 */ { MAD_F(0x05b60981) /* 0.356942659 */, 18 }, +/* 5351 */ { MAD_F(0x05b666c9) /* 0.357031619 */, 18 }, +/* 5352 */ { MAD_F(0x05b6c413) /* 0.357120585 */, 18 }, +/* 5353 */ { MAD_F(0x05b7215e) /* 0.357209557 */, 18 }, +/* 5354 */ { MAD_F(0x05b77eab) /* 0.357298534 */, 18 }, +/* 5355 */ { MAD_F(0x05b7dbf9) /* 0.357387516 */, 18 }, +/* 5356 */ { MAD_F(0x05b83948) /* 0.357476504 */, 18 }, +/* 5357 */ { MAD_F(0x05b89699) /* 0.357565498 */, 18 }, +/* 5358 */ { MAD_F(0x05b8f3ec) /* 0.357654497 */, 18 }, +/* 5359 */ { MAD_F(0x05b95140) /* 0.357743502 */, 18 }, + +/* 5360 */ { MAD_F(0x05b9ae95) /* 0.357832512 */, 18 }, +/* 5361 */ { MAD_F(0x05ba0bec) /* 0.357921528 */, 18 }, +/* 5362 */ { MAD_F(0x05ba6945) /* 0.358010550 */, 18 }, +/* 5363 */ { MAD_F(0x05bac69f) /* 0.358099576 */, 18 }, +/* 5364 */ { MAD_F(0x05bb23fa) /* 0.358188609 */, 18 }, +/* 5365 */ { MAD_F(0x05bb8157) /* 0.358277647 */, 18 }, +/* 5366 */ { MAD_F(0x05bbdeb6) /* 0.358366690 */, 18 }, +/* 5367 */ { MAD_F(0x05bc3c16) /* 0.358455739 */, 18 }, +/* 5368 */ { MAD_F(0x05bc9977) /* 0.358544794 */, 18 }, +/* 5369 */ { MAD_F(0x05bcf6da) /* 0.358633854 */, 18 }, +/* 5370 */ { MAD_F(0x05bd543e) /* 0.358722920 */, 18 }, +/* 5371 */ { MAD_F(0x05bdb1a4) /* 0.358811991 */, 18 }, +/* 5372 */ { MAD_F(0x05be0f0b) /* 0.358901067 */, 18 }, +/* 5373 */ { MAD_F(0x05be6c74) /* 0.358990150 */, 18 }, +/* 5374 */ { MAD_F(0x05bec9df) /* 0.359079237 */, 18 }, +/* 5375 */ { MAD_F(0x05bf274a) /* 0.359168331 */, 18 }, + +/* 5376 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 18 }, +/* 5377 */ { MAD_F(0x05bfe226) /* 0.359346534 */, 18 }, +/* 5378 */ { MAD_F(0x05c03f97) /* 0.359435644 */, 18 }, +/* 5379 */ { MAD_F(0x05c09d08) /* 0.359524759 */, 18 }, +/* 5380 */ { MAD_F(0x05c0fa7c) /* 0.359613880 */, 18 }, +/* 5381 */ { MAD_F(0x05c157f0) /* 0.359703006 */, 18 }, +/* 5382 */ { MAD_F(0x05c1b566) /* 0.359792138 */, 18 }, +/* 5383 */ { MAD_F(0x05c212de) /* 0.359881276 */, 18 }, +/* 5384 */ { MAD_F(0x05c27057) /* 0.359970419 */, 18 }, +/* 5385 */ { MAD_F(0x05c2cdd2) /* 0.360059567 */, 18 }, +/* 5386 */ { MAD_F(0x05c32b4e) /* 0.360148721 */, 18 }, +/* 5387 */ { MAD_F(0x05c388cb) /* 0.360237881 */, 18 }, +/* 5388 */ { MAD_F(0x05c3e64b) /* 0.360327046 */, 18 }, +/* 5389 */ { MAD_F(0x05c443cb) /* 0.360416216 */, 18 }, +/* 5390 */ { MAD_F(0x05c4a14d) /* 0.360505392 */, 18 }, +/* 5391 */ { MAD_F(0x05c4fed1) /* 0.360594574 */, 18 }, + +/* 5392 */ { MAD_F(0x05c55c56) /* 0.360683761 */, 18 }, +/* 5393 */ { MAD_F(0x05c5b9dc) /* 0.360772953 */, 18 }, +/* 5394 */ { MAD_F(0x05c61764) /* 0.360862152 */, 18 }, +/* 5395 */ { MAD_F(0x05c674ed) /* 0.360951355 */, 18 }, +/* 5396 */ { MAD_F(0x05c6d278) /* 0.361040564 */, 18 }, +/* 5397 */ { MAD_F(0x05c73005) /* 0.361129779 */, 18 }, +/* 5398 */ { MAD_F(0x05c78d93) /* 0.361218999 */, 18 }, +/* 5399 */ { MAD_F(0x05c7eb22) /* 0.361308225 */, 18 }, +/* 5400 */ { MAD_F(0x05c848b3) /* 0.361397456 */, 18 }, +/* 5401 */ { MAD_F(0x05c8a645) /* 0.361486693 */, 18 }, +/* 5402 */ { MAD_F(0x05c903d9) /* 0.361575935 */, 18 }, +/* 5403 */ { MAD_F(0x05c9616e) /* 0.361665183 */, 18 }, +/* 5404 */ { MAD_F(0x05c9bf05) /* 0.361754436 */, 18 }, +/* 5405 */ { MAD_F(0x05ca1c9d) /* 0.361843695 */, 18 }, +/* 5406 */ { MAD_F(0x05ca7a37) /* 0.361932959 */, 18 }, +/* 5407 */ { MAD_F(0x05cad7d2) /* 0.362022229 */, 18 }, + +/* 5408 */ { MAD_F(0x05cb356e) /* 0.362111504 */, 18 }, +/* 5409 */ { MAD_F(0x05cb930d) /* 0.362200785 */, 18 }, +/* 5410 */ { MAD_F(0x05cbf0ac) /* 0.362290071 */, 18 }, +/* 5411 */ { MAD_F(0x05cc4e4d) /* 0.362379362 */, 18 }, +/* 5412 */ { MAD_F(0x05ccabf0) /* 0.362468660 */, 18 }, +/* 5413 */ { MAD_F(0x05cd0994) /* 0.362557962 */, 18 }, +/* 5414 */ { MAD_F(0x05cd6739) /* 0.362647271 */, 18 }, +/* 5415 */ { MAD_F(0x05cdc4e0) /* 0.362736584 */, 18 }, +/* 5416 */ { MAD_F(0x05ce2289) /* 0.362825904 */, 18 }, +/* 5417 */ { MAD_F(0x05ce8033) /* 0.362915228 */, 18 }, +/* 5418 */ { MAD_F(0x05ceddde) /* 0.363004559 */, 18 }, +/* 5419 */ { MAD_F(0x05cf3b8b) /* 0.363093894 */, 18 }, +/* 5420 */ { MAD_F(0x05cf9939) /* 0.363183236 */, 18 }, +/* 5421 */ { MAD_F(0x05cff6e9) /* 0.363272582 */, 18 }, +/* 5422 */ { MAD_F(0x05d0549a) /* 0.363361935 */, 18 }, +/* 5423 */ { MAD_F(0x05d0b24d) /* 0.363451292 */, 18 }, + +/* 5424 */ { MAD_F(0x05d11001) /* 0.363540655 */, 18 }, +/* 5425 */ { MAD_F(0x05d16db7) /* 0.363630024 */, 18 }, +/* 5426 */ { MAD_F(0x05d1cb6e) /* 0.363719398 */, 18 }, +/* 5427 */ { MAD_F(0x05d22927) /* 0.363808778 */, 18 }, +/* 5428 */ { MAD_F(0x05d286e1) /* 0.363898163 */, 18 }, +/* 5429 */ { MAD_F(0x05d2e49d) /* 0.363987554 */, 18 }, +/* 5430 */ { MAD_F(0x05d3425a) /* 0.364076950 */, 18 }, +/* 5431 */ { MAD_F(0x05d3a018) /* 0.364166352 */, 18 }, +/* 5432 */ { MAD_F(0x05d3fdd8) /* 0.364255759 */, 18 }, +/* 5433 */ { MAD_F(0x05d45b9a) /* 0.364345171 */, 18 }, +/* 5434 */ { MAD_F(0x05d4b95d) /* 0.364434589 */, 18 }, +/* 5435 */ { MAD_F(0x05d51721) /* 0.364524013 */, 18 }, +/* 5436 */ { MAD_F(0x05d574e7) /* 0.364613442 */, 18 }, +/* 5437 */ { MAD_F(0x05d5d2af) /* 0.364702877 */, 18 }, +/* 5438 */ { MAD_F(0x05d63078) /* 0.364792317 */, 18 }, +/* 5439 */ { MAD_F(0x05d68e42) /* 0.364881762 */, 18 }, + +/* 5440 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 18 }, +/* 5441 */ { MAD_F(0x05d749db) /* 0.365060669 */, 18 }, +/* 5442 */ { MAD_F(0x05d7a7aa) /* 0.365150131 */, 18 }, +/* 5443 */ { MAD_F(0x05d8057a) /* 0.365239599 */, 18 }, +/* 5444 */ { MAD_F(0x05d8634c) /* 0.365329072 */, 18 }, +/* 5445 */ { MAD_F(0x05d8c11f) /* 0.365418550 */, 18 }, +/* 5446 */ { MAD_F(0x05d91ef4) /* 0.365508034 */, 18 }, +/* 5447 */ { MAD_F(0x05d97cca) /* 0.365597523 */, 18 }, +/* 5448 */ { MAD_F(0x05d9daa1) /* 0.365687018 */, 18 }, +/* 5449 */ { MAD_F(0x05da387a) /* 0.365776518 */, 18 }, +/* 5450 */ { MAD_F(0x05da9655) /* 0.365866024 */, 18 }, +/* 5451 */ { MAD_F(0x05daf431) /* 0.365955536 */, 18 }, +/* 5452 */ { MAD_F(0x05db520e) /* 0.366045052 */, 18 }, +/* 5453 */ { MAD_F(0x05dbafed) /* 0.366134574 */, 18 }, +/* 5454 */ { MAD_F(0x05dc0dce) /* 0.366224102 */, 18 }, +/* 5455 */ { MAD_F(0x05dc6baf) /* 0.366313635 */, 18 }, + +/* 5456 */ { MAD_F(0x05dcc993) /* 0.366403174 */, 18 }, +/* 5457 */ { MAD_F(0x05dd2778) /* 0.366492718 */, 18 }, +/* 5458 */ { MAD_F(0x05dd855e) /* 0.366582267 */, 18 }, +/* 5459 */ { MAD_F(0x05dde346) /* 0.366671822 */, 18 }, +/* 5460 */ { MAD_F(0x05de412f) /* 0.366761383 */, 18 }, +/* 5461 */ { MAD_F(0x05de9f1a) /* 0.366850949 */, 18 }, +/* 5462 */ { MAD_F(0x05defd06) /* 0.366940520 */, 18 }, +/* 5463 */ { MAD_F(0x05df5af3) /* 0.367030097 */, 18 }, +/* 5464 */ { MAD_F(0x05dfb8e2) /* 0.367119680 */, 18 }, +/* 5465 */ { MAD_F(0x05e016d3) /* 0.367209267 */, 18 }, +/* 5466 */ { MAD_F(0x05e074c5) /* 0.367298861 */, 18 }, +/* 5467 */ { MAD_F(0x05e0d2b8) /* 0.367388459 */, 18 }, +/* 5468 */ { MAD_F(0x05e130ad) /* 0.367478064 */, 18 }, +/* 5469 */ { MAD_F(0x05e18ea4) /* 0.367567673 */, 18 }, +/* 5470 */ { MAD_F(0x05e1ec9c) /* 0.367657288 */, 18 }, +/* 5471 */ { MAD_F(0x05e24a95) /* 0.367746909 */, 18 }, + +/* 5472 */ { MAD_F(0x05e2a890) /* 0.367836535 */, 18 }, +/* 5473 */ { MAD_F(0x05e3068c) /* 0.367926167 */, 18 }, +/* 5474 */ { MAD_F(0x05e3648a) /* 0.368015804 */, 18 }, +/* 5475 */ { MAD_F(0x05e3c289) /* 0.368105446 */, 18 }, +/* 5476 */ { MAD_F(0x05e4208a) /* 0.368195094 */, 18 }, +/* 5477 */ { MAD_F(0x05e47e8c) /* 0.368284747 */, 18 }, +/* 5478 */ { MAD_F(0x05e4dc8f) /* 0.368374406 */, 18 }, +/* 5479 */ { MAD_F(0x05e53a94) /* 0.368464070 */, 18 }, +/* 5480 */ { MAD_F(0x05e5989b) /* 0.368553740 */, 18 }, +/* 5481 */ { MAD_F(0x05e5f6a3) /* 0.368643415 */, 18 }, +/* 5482 */ { MAD_F(0x05e654ac) /* 0.368733096 */, 18 }, +/* 5483 */ { MAD_F(0x05e6b2b7) /* 0.368822782 */, 18 }, +/* 5484 */ { MAD_F(0x05e710c4) /* 0.368912473 */, 18 }, +/* 5485 */ { MAD_F(0x05e76ed2) /* 0.369002170 */, 18 }, +/* 5486 */ { MAD_F(0x05e7cce1) /* 0.369091873 */, 18 }, +/* 5487 */ { MAD_F(0x05e82af2) /* 0.369181581 */, 18 }, + +/* 5488 */ { MAD_F(0x05e88904) /* 0.369271294 */, 18 }, +/* 5489 */ { MAD_F(0x05e8e718) /* 0.369361013 */, 18 }, +/* 5490 */ { MAD_F(0x05e9452d) /* 0.369450737 */, 18 }, +/* 5491 */ { MAD_F(0x05e9a343) /* 0.369540467 */, 18 }, +/* 5492 */ { MAD_F(0x05ea015c) /* 0.369630202 */, 18 }, +/* 5493 */ { MAD_F(0x05ea5f75) /* 0.369719942 */, 18 }, +/* 5494 */ { MAD_F(0x05eabd90) /* 0.369809688 */, 18 }, +/* 5495 */ { MAD_F(0x05eb1bad) /* 0.369899440 */, 18 }, +/* 5496 */ { MAD_F(0x05eb79cb) /* 0.369989197 */, 18 }, +/* 5497 */ { MAD_F(0x05ebd7ea) /* 0.370078959 */, 18 }, +/* 5498 */ { MAD_F(0x05ec360b) /* 0.370168727 */, 18 }, +/* 5499 */ { MAD_F(0x05ec942d) /* 0.370258500 */, 18 }, +/* 5500 */ { MAD_F(0x05ecf251) /* 0.370348279 */, 18 }, +/* 5501 */ { MAD_F(0x05ed5076) /* 0.370438063 */, 18 }, +/* 5502 */ { MAD_F(0x05edae9d) /* 0.370527853 */, 18 }, +/* 5503 */ { MAD_F(0x05ee0cc5) /* 0.370617648 */, 18 }, + +/* 5504 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 18 }, +/* 5505 */ { MAD_F(0x05eec91a) /* 0.370797254 */, 18 }, +/* 5506 */ { MAD_F(0x05ef2746) /* 0.370887065 */, 18 }, +/* 5507 */ { MAD_F(0x05ef8574) /* 0.370976882 */, 18 }, +/* 5508 */ { MAD_F(0x05efe3a4) /* 0.371066704 */, 18 }, +/* 5509 */ { MAD_F(0x05f041d5) /* 0.371156532 */, 18 }, +/* 5510 */ { MAD_F(0x05f0a007) /* 0.371246365 */, 18 }, +/* 5511 */ { MAD_F(0x05f0fe3b) /* 0.371336203 */, 18 }, +/* 5512 */ { MAD_F(0x05f15c70) /* 0.371426047 */, 18 }, +/* 5513 */ { MAD_F(0x05f1baa7) /* 0.371515897 */, 18 }, +/* 5514 */ { MAD_F(0x05f218df) /* 0.371605751 */, 18 }, +/* 5515 */ { MAD_F(0x05f27719) /* 0.371695612 */, 18 }, +/* 5516 */ { MAD_F(0x05f2d554) /* 0.371785477 */, 18 }, +/* 5517 */ { MAD_F(0x05f33390) /* 0.371875348 */, 18 }, +/* 5518 */ { MAD_F(0x05f391cf) /* 0.371965225 */, 18 }, +/* 5519 */ { MAD_F(0x05f3f00e) /* 0.372055107 */, 18 }, + +/* 5520 */ { MAD_F(0x05f44e4f) /* 0.372144994 */, 18 }, +/* 5521 */ { MAD_F(0x05f4ac91) /* 0.372234887 */, 18 }, +/* 5522 */ { MAD_F(0x05f50ad5) /* 0.372324785 */, 18 }, +/* 5523 */ { MAD_F(0x05f5691b) /* 0.372414689 */, 18 }, +/* 5524 */ { MAD_F(0x05f5c761) /* 0.372504598 */, 18 }, +/* 5525 */ { MAD_F(0x05f625aa) /* 0.372594513 */, 18 }, +/* 5526 */ { MAD_F(0x05f683f3) /* 0.372684433 */, 18 }, +/* 5527 */ { MAD_F(0x05f6e23f) /* 0.372774358 */, 18 }, +/* 5528 */ { MAD_F(0x05f7408b) /* 0.372864289 */, 18 }, +/* 5529 */ { MAD_F(0x05f79ed9) /* 0.372954225 */, 18 }, +/* 5530 */ { MAD_F(0x05f7fd29) /* 0.373044167 */, 18 }, +/* 5531 */ { MAD_F(0x05f85b7a) /* 0.373134114 */, 18 }, +/* 5532 */ { MAD_F(0x05f8b9cc) /* 0.373224066 */, 18 }, +/* 5533 */ { MAD_F(0x05f91820) /* 0.373314024 */, 18 }, +/* 5534 */ { MAD_F(0x05f97675) /* 0.373403987 */, 18 }, +/* 5535 */ { MAD_F(0x05f9d4cc) /* 0.373493956 */, 18 }, + +/* 5536 */ { MAD_F(0x05fa3324) /* 0.373583930 */, 18 }, +/* 5537 */ { MAD_F(0x05fa917e) /* 0.373673910 */, 18 }, +/* 5538 */ { MAD_F(0x05faefd9) /* 0.373763895 */, 18 }, +/* 5539 */ { MAD_F(0x05fb4e36) /* 0.373853885 */, 18 }, +/* 5540 */ { MAD_F(0x05fbac94) /* 0.373943881 */, 18 }, +/* 5541 */ { MAD_F(0x05fc0af3) /* 0.374033882 */, 18 }, +/* 5542 */ { MAD_F(0x05fc6954) /* 0.374123889 */, 18 }, +/* 5543 */ { MAD_F(0x05fcc7b7) /* 0.374213901 */, 18 }, +/* 5544 */ { MAD_F(0x05fd261b) /* 0.374303918 */, 18 }, +/* 5545 */ { MAD_F(0x05fd8480) /* 0.374393941 */, 18 }, +/* 5546 */ { MAD_F(0x05fde2e7) /* 0.374483970 */, 18 }, +/* 5547 */ { MAD_F(0x05fe414f) /* 0.374574003 */, 18 }, +/* 5548 */ { MAD_F(0x05fe9fb9) /* 0.374664042 */, 18 }, +/* 5549 */ { MAD_F(0x05fefe24) /* 0.374754087 */, 18 }, +/* 5550 */ { MAD_F(0x05ff5c91) /* 0.374844137 */, 18 }, +/* 5551 */ { MAD_F(0x05ffbaff) /* 0.374934192 */, 18 }, + +/* 5552 */ { MAD_F(0x0600196e) /* 0.375024253 */, 18 }, +/* 5553 */ { MAD_F(0x060077df) /* 0.375114319 */, 18 }, +/* 5554 */ { MAD_F(0x0600d651) /* 0.375204391 */, 18 }, +/* 5555 */ { MAD_F(0x060134c5) /* 0.375294468 */, 18 }, +/* 5556 */ { MAD_F(0x0601933b) /* 0.375384550 */, 18 }, +/* 5557 */ { MAD_F(0x0601f1b1) /* 0.375474638 */, 18 }, +/* 5558 */ { MAD_F(0x0602502a) /* 0.375564731 */, 18 }, +/* 5559 */ { MAD_F(0x0602aea3) /* 0.375654830 */, 18 }, +/* 5560 */ { MAD_F(0x06030d1e) /* 0.375744934 */, 18 }, +/* 5561 */ { MAD_F(0x06036b9b) /* 0.375835043 */, 18 }, +/* 5562 */ { MAD_F(0x0603ca19) /* 0.375925158 */, 18 }, +/* 5563 */ { MAD_F(0x06042898) /* 0.376015278 */, 18 }, +/* 5564 */ { MAD_F(0x06048719) /* 0.376105404 */, 18 }, +/* 5565 */ { MAD_F(0x0604e59c) /* 0.376195535 */, 18 }, +/* 5566 */ { MAD_F(0x0605441f) /* 0.376285671 */, 18 }, +/* 5567 */ { MAD_F(0x0605a2a5) /* 0.376375813 */, 18 }, + +/* 5568 */ { MAD_F(0x0606012b) /* 0.376465960 */, 18 }, +/* 5569 */ { MAD_F(0x06065fb4) /* 0.376556113 */, 18 }, +/* 5570 */ { MAD_F(0x0606be3d) /* 0.376646271 */, 18 }, +/* 5571 */ { MAD_F(0x06071cc8) /* 0.376736434 */, 18 }, +/* 5572 */ { MAD_F(0x06077b55) /* 0.376826603 */, 18 }, +/* 5573 */ { MAD_F(0x0607d9e3) /* 0.376916777 */, 18 }, +/* 5574 */ { MAD_F(0x06083872) /* 0.377006957 */, 18 }, +/* 5575 */ { MAD_F(0x06089703) /* 0.377097141 */, 18 }, +/* 5576 */ { MAD_F(0x0608f595) /* 0.377187332 */, 18 }, +/* 5577 */ { MAD_F(0x06095429) /* 0.377277528 */, 18 }, +/* 5578 */ { MAD_F(0x0609b2be) /* 0.377367729 */, 18 }, +/* 5579 */ { MAD_F(0x060a1155) /* 0.377457935 */, 18 }, +/* 5580 */ { MAD_F(0x060a6fed) /* 0.377548147 */, 18 }, +/* 5581 */ { MAD_F(0x060ace86) /* 0.377638364 */, 18 }, +/* 5582 */ { MAD_F(0x060b2d21) /* 0.377728587 */, 18 }, +/* 5583 */ { MAD_F(0x060b8bbe) /* 0.377818815 */, 18 }, + +/* 5584 */ { MAD_F(0x060bea5c) /* 0.377909049 */, 18 }, +/* 5585 */ { MAD_F(0x060c48fb) /* 0.377999288 */, 18 }, +/* 5586 */ { MAD_F(0x060ca79c) /* 0.378089532 */, 18 }, +/* 5587 */ { MAD_F(0x060d063e) /* 0.378179781 */, 18 }, +/* 5588 */ { MAD_F(0x060d64e1) /* 0.378270036 */, 18 }, +/* 5589 */ { MAD_F(0x060dc387) /* 0.378360297 */, 18 }, +/* 5590 */ { MAD_F(0x060e222d) /* 0.378450563 */, 18 }, +/* 5591 */ { MAD_F(0x060e80d5) /* 0.378540834 */, 18 }, +/* 5592 */ { MAD_F(0x060edf7f) /* 0.378631110 */, 18 }, +/* 5593 */ { MAD_F(0x060f3e29) /* 0.378721392 */, 18 }, +/* 5594 */ { MAD_F(0x060f9cd6) /* 0.378811680 */, 18 }, +/* 5595 */ { MAD_F(0x060ffb83) /* 0.378901972 */, 18 }, +/* 5596 */ { MAD_F(0x06105a33) /* 0.378992270 */, 18 }, +/* 5597 */ { MAD_F(0x0610b8e3) /* 0.379082574 */, 18 }, +/* 5598 */ { MAD_F(0x06111795) /* 0.379172883 */, 18 }, +/* 5599 */ { MAD_F(0x06117649) /* 0.379263197 */, 18 }, + +/* 5600 */ { MAD_F(0x0611d4fe) /* 0.379353516 */, 18 }, +/* 5601 */ { MAD_F(0x061233b4) /* 0.379443841 */, 18 }, +/* 5602 */ { MAD_F(0x0612926c) /* 0.379534172 */, 18 }, +/* 5603 */ { MAD_F(0x0612f125) /* 0.379624507 */, 18 }, +/* 5604 */ { MAD_F(0x06134fe0) /* 0.379714848 */, 18 }, +/* 5605 */ { MAD_F(0x0613ae9c) /* 0.379805195 */, 18 }, +/* 5606 */ { MAD_F(0x06140d5a) /* 0.379895547 */, 18 }, +/* 5607 */ { MAD_F(0x06146c19) /* 0.379985904 */, 18 }, +/* 5608 */ { MAD_F(0x0614cada) /* 0.380076266 */, 18 }, +/* 5609 */ { MAD_F(0x0615299c) /* 0.380166634 */, 18 }, +/* 5610 */ { MAD_F(0x0615885f) /* 0.380257008 */, 18 }, +/* 5611 */ { MAD_F(0x0615e724) /* 0.380347386 */, 18 }, +/* 5612 */ { MAD_F(0x061645ea) /* 0.380437770 */, 18 }, +/* 5613 */ { MAD_F(0x0616a4b2) /* 0.380528160 */, 18 }, +/* 5614 */ { MAD_F(0x0617037b) /* 0.380618555 */, 18 }, +/* 5615 */ { MAD_F(0x06176246) /* 0.380708955 */, 18 }, + +/* 5616 */ { MAD_F(0x0617c112) /* 0.380799360 */, 18 }, +/* 5617 */ { MAD_F(0x06181fdf) /* 0.380889771 */, 18 }, +/* 5618 */ { MAD_F(0x06187eae) /* 0.380980187 */, 18 }, +/* 5619 */ { MAD_F(0x0618dd7e) /* 0.381070609 */, 18 }, +/* 5620 */ { MAD_F(0x06193c50) /* 0.381161036 */, 18 }, +/* 5621 */ { MAD_F(0x06199b24) /* 0.381251468 */, 18 }, +/* 5622 */ { MAD_F(0x0619f9f8) /* 0.381341906 */, 18 }, +/* 5623 */ { MAD_F(0x061a58ce) /* 0.381432349 */, 18 }, +/* 5624 */ { MAD_F(0x061ab7a6) /* 0.381522798 */, 18 }, +/* 5625 */ { MAD_F(0x061b167f) /* 0.381613251 */, 18 }, +/* 5626 */ { MAD_F(0x061b7559) /* 0.381703711 */, 18 }, +/* 5627 */ { MAD_F(0x061bd435) /* 0.381794175 */, 18 }, +/* 5628 */ { MAD_F(0x061c3313) /* 0.381884645 */, 18 }, +/* 5629 */ { MAD_F(0x061c91f1) /* 0.381975120 */, 18 }, +/* 5630 */ { MAD_F(0x061cf0d2) /* 0.382065601 */, 18 }, +/* 5631 */ { MAD_F(0x061d4fb3) /* 0.382156087 */, 18 }, + +/* 5632 */ { MAD_F(0x061dae96) /* 0.382246578 */, 18 }, +/* 5633 */ { MAD_F(0x061e0d7b) /* 0.382337075 */, 18 }, +/* 5634 */ { MAD_F(0x061e6c61) /* 0.382427577 */, 18 }, +/* 5635 */ { MAD_F(0x061ecb48) /* 0.382518084 */, 18 }, +/* 5636 */ { MAD_F(0x061f2a31) /* 0.382608597 */, 18 }, +/* 5637 */ { MAD_F(0x061f891b) /* 0.382699115 */, 18 }, +/* 5638 */ { MAD_F(0x061fe807) /* 0.382789638 */, 18 }, +/* 5639 */ { MAD_F(0x062046f4) /* 0.382880167 */, 18 }, +/* 5640 */ { MAD_F(0x0620a5e3) /* 0.382970701 */, 18 }, +/* 5641 */ { MAD_F(0x062104d3) /* 0.383061241 */, 18 }, +/* 5642 */ { MAD_F(0x062163c4) /* 0.383151786 */, 18 }, +/* 5643 */ { MAD_F(0x0621c2b7) /* 0.383242336 */, 18 }, +/* 5644 */ { MAD_F(0x062221ab) /* 0.383332891 */, 18 }, +/* 5645 */ { MAD_F(0x062280a1) /* 0.383423452 */, 18 }, +/* 5646 */ { MAD_F(0x0622df98) /* 0.383514018 */, 18 }, +/* 5647 */ { MAD_F(0x06233e91) /* 0.383604590 */, 18 }, + +/* 5648 */ { MAD_F(0x06239d8b) /* 0.383695167 */, 18 }, +/* 5649 */ { MAD_F(0x0623fc86) /* 0.383785749 */, 18 }, +/* 5650 */ { MAD_F(0x06245b83) /* 0.383876337 */, 18 }, +/* 5651 */ { MAD_F(0x0624ba82) /* 0.383966930 */, 18 }, +/* 5652 */ { MAD_F(0x06251981) /* 0.384057528 */, 18 }, +/* 5653 */ { MAD_F(0x06257883) /* 0.384148132 */, 18 }, +/* 5654 */ { MAD_F(0x0625d785) /* 0.384238741 */, 18 }, +/* 5655 */ { MAD_F(0x06263689) /* 0.384329355 */, 18 }, +/* 5656 */ { MAD_F(0x0626958f) /* 0.384419975 */, 18 }, +/* 5657 */ { MAD_F(0x0626f496) /* 0.384510600 */, 18 }, +/* 5658 */ { MAD_F(0x0627539e) /* 0.384601230 */, 18 }, +/* 5659 */ { MAD_F(0x0627b2a8) /* 0.384691866 */, 18 }, +/* 5660 */ { MAD_F(0x062811b3) /* 0.384782507 */, 18 }, +/* 5661 */ { MAD_F(0x062870c0) /* 0.384873153 */, 18 }, +/* 5662 */ { MAD_F(0x0628cfce) /* 0.384963805 */, 18 }, +/* 5663 */ { MAD_F(0x06292ede) /* 0.385054462 */, 18 }, + +/* 5664 */ { MAD_F(0x06298def) /* 0.385145124 */, 18 }, +/* 5665 */ { MAD_F(0x0629ed01) /* 0.385235792 */, 18 }, +/* 5666 */ { MAD_F(0x062a4c15) /* 0.385326465 */, 18 }, +/* 5667 */ { MAD_F(0x062aab2a) /* 0.385417143 */, 18 }, +/* 5668 */ { MAD_F(0x062b0a41) /* 0.385507827 */, 18 }, +/* 5669 */ { MAD_F(0x062b6959) /* 0.385598516 */, 18 }, +/* 5670 */ { MAD_F(0x062bc873) /* 0.385689211 */, 18 }, +/* 5671 */ { MAD_F(0x062c278e) /* 0.385779910 */, 18 }, +/* 5672 */ { MAD_F(0x062c86aa) /* 0.385870615 */, 18 }, +/* 5673 */ { MAD_F(0x062ce5c8) /* 0.385961326 */, 18 }, +/* 5674 */ { MAD_F(0x062d44e8) /* 0.386052041 */, 18 }, +/* 5675 */ { MAD_F(0x062da408) /* 0.386142762 */, 18 }, +/* 5676 */ { MAD_F(0x062e032a) /* 0.386233489 */, 18 }, +/* 5677 */ { MAD_F(0x062e624e) /* 0.386324221 */, 18 }, +/* 5678 */ { MAD_F(0x062ec173) /* 0.386414958 */, 18 }, +/* 5679 */ { MAD_F(0x062f209a) /* 0.386505700 */, 18 }, + +/* 5680 */ { MAD_F(0x062f7fc1) /* 0.386596448 */, 18 }, +/* 5681 */ { MAD_F(0x062fdeeb) /* 0.386687201 */, 18 }, +/* 5682 */ { MAD_F(0x06303e16) /* 0.386777959 */, 18 }, +/* 5683 */ { MAD_F(0x06309d42) /* 0.386868723 */, 18 }, +/* 5684 */ { MAD_F(0x0630fc6f) /* 0.386959492 */, 18 }, +/* 5685 */ { MAD_F(0x06315b9e) /* 0.387050266 */, 18 }, +/* 5686 */ { MAD_F(0x0631bacf) /* 0.387141045 */, 18 }, +/* 5687 */ { MAD_F(0x06321a01) /* 0.387231830 */, 18 }, +/* 5688 */ { MAD_F(0x06327934) /* 0.387322621 */, 18 }, +/* 5689 */ { MAD_F(0x0632d869) /* 0.387413416 */, 18 }, +/* 5690 */ { MAD_F(0x0633379f) /* 0.387504217 */, 18 }, +/* 5691 */ { MAD_F(0x063396d7) /* 0.387595023 */, 18 }, +/* 5692 */ { MAD_F(0x0633f610) /* 0.387685835 */, 18 }, +/* 5693 */ { MAD_F(0x0634554a) /* 0.387776652 */, 18 }, +/* 5694 */ { MAD_F(0x0634b486) /* 0.387867474 */, 18 }, +/* 5695 */ { MAD_F(0x063513c3) /* 0.387958301 */, 18 }, + +/* 5696 */ { MAD_F(0x06357302) /* 0.388049134 */, 18 }, +/* 5697 */ { MAD_F(0x0635d242) /* 0.388139972 */, 18 }, +/* 5698 */ { MAD_F(0x06363184) /* 0.388230816 */, 18 }, +/* 5699 */ { MAD_F(0x063690c7) /* 0.388321665 */, 18 }, +/* 5700 */ { MAD_F(0x0636f00b) /* 0.388412519 */, 18 }, +/* 5701 */ { MAD_F(0x06374f51) /* 0.388503378 */, 18 }, +/* 5702 */ { MAD_F(0x0637ae99) /* 0.388594243 */, 18 }, +/* 5703 */ { MAD_F(0x06380de1) /* 0.388685113 */, 18 }, +/* 5704 */ { MAD_F(0x06386d2b) /* 0.388775988 */, 18 }, +/* 5705 */ { MAD_F(0x0638cc77) /* 0.388866869 */, 18 }, +/* 5706 */ { MAD_F(0x06392bc4) /* 0.388957755 */, 18 }, +/* 5707 */ { MAD_F(0x06398b12) /* 0.389048646 */, 18 }, +/* 5708 */ { MAD_F(0x0639ea62) /* 0.389139542 */, 18 }, +/* 5709 */ { MAD_F(0x063a49b4) /* 0.389230444 */, 18 }, +/* 5710 */ { MAD_F(0x063aa906) /* 0.389321352 */, 18 }, +/* 5711 */ { MAD_F(0x063b085a) /* 0.389412264 */, 18 }, + +/* 5712 */ { MAD_F(0x063b67b0) /* 0.389503182 */, 18 }, +/* 5713 */ { MAD_F(0x063bc707) /* 0.389594105 */, 18 }, +/* 5714 */ { MAD_F(0x063c265f) /* 0.389685033 */, 18 }, +/* 5715 */ { MAD_F(0x063c85b9) /* 0.389775967 */, 18 }, +/* 5716 */ { MAD_F(0x063ce514) /* 0.389866906 */, 18 }, +/* 5717 */ { MAD_F(0x063d4471) /* 0.389957850 */, 18 }, +/* 5718 */ { MAD_F(0x063da3cf) /* 0.390048800 */, 18 }, +/* 5719 */ { MAD_F(0x063e032f) /* 0.390139755 */, 18 }, +/* 5720 */ { MAD_F(0x063e6290) /* 0.390230715 */, 18 }, +/* 5721 */ { MAD_F(0x063ec1f2) /* 0.390321681 */, 18 }, +/* 5722 */ { MAD_F(0x063f2156) /* 0.390412651 */, 18 }, +/* 5723 */ { MAD_F(0x063f80bb) /* 0.390503628 */, 18 }, +/* 5724 */ { MAD_F(0x063fe022) /* 0.390594609 */, 18 }, +/* 5725 */ { MAD_F(0x06403f8a) /* 0.390685596 */, 18 }, +/* 5726 */ { MAD_F(0x06409ef3) /* 0.390776588 */, 18 }, +/* 5727 */ { MAD_F(0x0640fe5e) /* 0.390867585 */, 18 }, + +/* 5728 */ { MAD_F(0x06415dcb) /* 0.390958588 */, 18 }, +/* 5729 */ { MAD_F(0x0641bd38) /* 0.391049596 */, 18 }, +/* 5730 */ { MAD_F(0x06421ca7) /* 0.391140609 */, 18 }, +/* 5731 */ { MAD_F(0x06427c18) /* 0.391231627 */, 18 }, +/* 5732 */ { MAD_F(0x0642db8a) /* 0.391322651 */, 18 }, +/* 5733 */ { MAD_F(0x06433afd) /* 0.391413680 */, 18 }, +/* 5734 */ { MAD_F(0x06439a72) /* 0.391504714 */, 18 }, +/* 5735 */ { MAD_F(0x0643f9e9) /* 0.391595754 */, 18 }, +/* 5736 */ { MAD_F(0x06445960) /* 0.391686799 */, 18 }, +/* 5737 */ { MAD_F(0x0644b8d9) /* 0.391777849 */, 18 }, +/* 5738 */ { MAD_F(0x06451854) /* 0.391868905 */, 18 }, +/* 5739 */ { MAD_F(0x064577d0) /* 0.391959966 */, 18 }, +/* 5740 */ { MAD_F(0x0645d74d) /* 0.392051032 */, 18 }, +/* 5741 */ { MAD_F(0x064636cc) /* 0.392142103 */, 18 }, +/* 5742 */ { MAD_F(0x0646964c) /* 0.392233180 */, 18 }, +/* 5743 */ { MAD_F(0x0646f5ce) /* 0.392324262 */, 18 }, + +/* 5744 */ { MAD_F(0x06475551) /* 0.392415349 */, 18 }, +/* 5745 */ { MAD_F(0x0647b4d5) /* 0.392506442 */, 18 }, +/* 5746 */ { MAD_F(0x0648145b) /* 0.392597540 */, 18 }, +/* 5747 */ { MAD_F(0x064873e3) /* 0.392688643 */, 18 }, +/* 5748 */ { MAD_F(0x0648d36b) /* 0.392779751 */, 18 }, +/* 5749 */ { MAD_F(0x064932f6) /* 0.392870865 */, 18 }, +/* 5750 */ { MAD_F(0x06499281) /* 0.392961984 */, 18 }, +/* 5751 */ { MAD_F(0x0649f20e) /* 0.393053108 */, 18 }, +/* 5752 */ { MAD_F(0x064a519c) /* 0.393144238 */, 18 }, +/* 5753 */ { MAD_F(0x064ab12c) /* 0.393235372 */, 18 }, +/* 5754 */ { MAD_F(0x064b10be) /* 0.393326513 */, 18 }, +/* 5755 */ { MAD_F(0x064b7050) /* 0.393417658 */, 18 }, +/* 5756 */ { MAD_F(0x064bcfe4) /* 0.393508809 */, 18 }, +/* 5757 */ { MAD_F(0x064c2f7a) /* 0.393599965 */, 18 }, +/* 5758 */ { MAD_F(0x064c8f11) /* 0.393691126 */, 18 }, +/* 5759 */ { MAD_F(0x064ceea9) /* 0.393782292 */, 18 }, + +/* 5760 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 18 }, +/* 5761 */ { MAD_F(0x064dadde) /* 0.393964641 */, 18 }, +/* 5762 */ { MAD_F(0x064e0d7a) /* 0.394055823 */, 18 }, +/* 5763 */ { MAD_F(0x064e6d18) /* 0.394147011 */, 18 }, +/* 5764 */ { MAD_F(0x064eccb8) /* 0.394238204 */, 18 }, +/* 5765 */ { MAD_F(0x064f2c59) /* 0.394329402 */, 18 }, +/* 5766 */ { MAD_F(0x064f8bfb) /* 0.394420605 */, 18 }, +/* 5767 */ { MAD_F(0x064feb9e) /* 0.394511814 */, 18 }, +/* 5768 */ { MAD_F(0x06504b44) /* 0.394603028 */, 18 }, +/* 5769 */ { MAD_F(0x0650aaea) /* 0.394694247 */, 18 }, +/* 5770 */ { MAD_F(0x06510a92) /* 0.394785472 */, 18 }, +/* 5771 */ { MAD_F(0x06516a3b) /* 0.394876702 */, 18 }, +/* 5772 */ { MAD_F(0x0651c9e6) /* 0.394967937 */, 18 }, +/* 5773 */ { MAD_F(0x06522992) /* 0.395059177 */, 18 }, +/* 5774 */ { MAD_F(0x06528940) /* 0.395150423 */, 18 }, +/* 5775 */ { MAD_F(0x0652e8ef) /* 0.395241673 */, 18 }, + +/* 5776 */ { MAD_F(0x0653489f) /* 0.395332930 */, 18 }, +/* 5777 */ { MAD_F(0x0653a851) /* 0.395424191 */, 18 }, +/* 5778 */ { MAD_F(0x06540804) /* 0.395515458 */, 18 }, +/* 5779 */ { MAD_F(0x065467b9) /* 0.395606730 */, 18 }, +/* 5780 */ { MAD_F(0x0654c76f) /* 0.395698007 */, 18 }, +/* 5781 */ { MAD_F(0x06552726) /* 0.395789289 */, 18 }, +/* 5782 */ { MAD_F(0x065586df) /* 0.395880577 */, 18 }, +/* 5783 */ { MAD_F(0x0655e699) /* 0.395971870 */, 18 }, +/* 5784 */ { MAD_F(0x06564655) /* 0.396063168 */, 18 }, +/* 5785 */ { MAD_F(0x0656a612) /* 0.396154472 */, 18 }, +/* 5786 */ { MAD_F(0x065705d0) /* 0.396245780 */, 18 }, +/* 5787 */ { MAD_F(0x06576590) /* 0.396337094 */, 18 }, +/* 5788 */ { MAD_F(0x0657c552) /* 0.396428414 */, 18 }, +/* 5789 */ { MAD_F(0x06582514) /* 0.396519738 */, 18 }, +/* 5790 */ { MAD_F(0x065884d9) /* 0.396611068 */, 18 }, +/* 5791 */ { MAD_F(0x0658e49e) /* 0.396702403 */, 18 }, + +/* 5792 */ { MAD_F(0x06594465) /* 0.396793743 */, 18 }, +/* 5793 */ { MAD_F(0x0659a42e) /* 0.396885089 */, 18 }, +/* 5794 */ { MAD_F(0x065a03f7) /* 0.396976440 */, 18 }, +/* 5795 */ { MAD_F(0x065a63c3) /* 0.397067796 */, 18 }, +/* 5796 */ { MAD_F(0x065ac38f) /* 0.397159157 */, 18 }, +/* 5797 */ { MAD_F(0x065b235d) /* 0.397250524 */, 18 }, +/* 5798 */ { MAD_F(0x065b832d) /* 0.397341896 */, 18 }, +/* 5799 */ { MAD_F(0x065be2fe) /* 0.397433273 */, 18 }, +/* 5800 */ { MAD_F(0x065c42d0) /* 0.397524655 */, 18 }, +/* 5801 */ { MAD_F(0x065ca2a3) /* 0.397616043 */, 18 }, +/* 5802 */ { MAD_F(0x065d0279) /* 0.397707436 */, 18 }, +/* 5803 */ { MAD_F(0x065d624f) /* 0.397798834 */, 18 }, +/* 5804 */ { MAD_F(0x065dc227) /* 0.397890237 */, 18 }, +/* 5805 */ { MAD_F(0x065e2200) /* 0.397981646 */, 18 }, +/* 5806 */ { MAD_F(0x065e81db) /* 0.398073059 */, 18 }, +/* 5807 */ { MAD_F(0x065ee1b7) /* 0.398164479 */, 18 }, + +/* 5808 */ { MAD_F(0x065f4195) /* 0.398255903 */, 18 }, +/* 5809 */ { MAD_F(0x065fa174) /* 0.398347333 */, 18 }, +/* 5810 */ { MAD_F(0x06600154) /* 0.398438767 */, 18 }, +/* 5811 */ { MAD_F(0x06606136) /* 0.398530207 */, 18 }, +/* 5812 */ { MAD_F(0x0660c119) /* 0.398621653 */, 18 }, +/* 5813 */ { MAD_F(0x066120fd) /* 0.398713103 */, 18 }, +/* 5814 */ { MAD_F(0x066180e3) /* 0.398804559 */, 18 }, +/* 5815 */ { MAD_F(0x0661e0cb) /* 0.398896020 */, 18 }, +/* 5816 */ { MAD_F(0x066240b4) /* 0.398987487 */, 18 }, +/* 5817 */ { MAD_F(0x0662a09e) /* 0.399078958 */, 18 }, +/* 5818 */ { MAD_F(0x06630089) /* 0.399170435 */, 18 }, +/* 5819 */ { MAD_F(0x06636077) /* 0.399261917 */, 18 }, +/* 5820 */ { MAD_F(0x0663c065) /* 0.399353404 */, 18 }, +/* 5821 */ { MAD_F(0x06642055) /* 0.399444897 */, 18 }, +/* 5822 */ { MAD_F(0x06648046) /* 0.399536395 */, 18 }, +/* 5823 */ { MAD_F(0x0664e039) /* 0.399627898 */, 18 }, + +/* 5824 */ { MAD_F(0x0665402d) /* 0.399719406 */, 18 }, +/* 5825 */ { MAD_F(0x0665a022) /* 0.399810919 */, 18 }, +/* 5826 */ { MAD_F(0x06660019) /* 0.399902438 */, 18 }, +/* 5827 */ { MAD_F(0x06666011) /* 0.399993962 */, 18 }, +/* 5828 */ { MAD_F(0x0666c00b) /* 0.400085491 */, 18 }, +/* 5829 */ { MAD_F(0x06672006) /* 0.400177026 */, 18 }, +/* 5830 */ { MAD_F(0x06678003) /* 0.400268565 */, 18 }, +/* 5831 */ { MAD_F(0x0667e000) /* 0.400360110 */, 18 }, +/* 5832 */ { MAD_F(0x06684000) /* 0.400451660 */, 18 }, +/* 5833 */ { MAD_F(0x0668a000) /* 0.400543216 */, 18 }, +/* 5834 */ { MAD_F(0x06690003) /* 0.400634776 */, 18 }, +/* 5835 */ { MAD_F(0x06696006) /* 0.400726342 */, 18 }, +/* 5836 */ { MAD_F(0x0669c00b) /* 0.400817913 */, 18 }, +/* 5837 */ { MAD_F(0x066a2011) /* 0.400909489 */, 18 }, +/* 5838 */ { MAD_F(0x066a8019) /* 0.401001071 */, 18 }, +/* 5839 */ { MAD_F(0x066ae022) /* 0.401092657 */, 18 }, + +/* 5840 */ { MAD_F(0x066b402d) /* 0.401184249 */, 18 }, +/* 5841 */ { MAD_F(0x066ba039) /* 0.401275847 */, 18 }, +/* 5842 */ { MAD_F(0x066c0046) /* 0.401367449 */, 18 }, +/* 5843 */ { MAD_F(0x066c6055) /* 0.401459057 */, 18 }, +/* 5844 */ { MAD_F(0x066cc065) /* 0.401550670 */, 18 }, +/* 5845 */ { MAD_F(0x066d2076) /* 0.401642288 */, 18 }, +/* 5846 */ { MAD_F(0x066d8089) /* 0.401733911 */, 18 }, +/* 5847 */ { MAD_F(0x066de09e) /* 0.401825540 */, 18 }, +/* 5848 */ { MAD_F(0x066e40b3) /* 0.401917173 */, 18 }, +/* 5849 */ { MAD_F(0x066ea0cb) /* 0.402008812 */, 18 }, +/* 5850 */ { MAD_F(0x066f00e3) /* 0.402100457 */, 18 }, +/* 5851 */ { MAD_F(0x066f60fd) /* 0.402192106 */, 18 }, +/* 5852 */ { MAD_F(0x066fc118) /* 0.402283761 */, 18 }, +/* 5853 */ { MAD_F(0x06702135) /* 0.402375420 */, 18 }, +/* 5854 */ { MAD_F(0x06708153) /* 0.402467086 */, 18 }, +/* 5855 */ { MAD_F(0x0670e173) /* 0.402558756 */, 18 }, + +/* 5856 */ { MAD_F(0x06714194) /* 0.402650431 */, 18 }, +/* 5857 */ { MAD_F(0x0671a1b6) /* 0.402742112 */, 18 }, +/* 5858 */ { MAD_F(0x067201da) /* 0.402833798 */, 18 }, +/* 5859 */ { MAD_F(0x067261ff) /* 0.402925489 */, 18 }, +/* 5860 */ { MAD_F(0x0672c226) /* 0.403017186 */, 18 }, +/* 5861 */ { MAD_F(0x0673224e) /* 0.403108887 */, 18 }, +/* 5862 */ { MAD_F(0x06738277) /* 0.403200594 */, 18 }, +/* 5863 */ { MAD_F(0x0673e2a2) /* 0.403292306 */, 18 }, +/* 5864 */ { MAD_F(0x067442ce) /* 0.403384024 */, 18 }, +/* 5865 */ { MAD_F(0x0674a2fc) /* 0.403475746 */, 18 }, +/* 5866 */ { MAD_F(0x0675032b) /* 0.403567474 */, 18 }, +/* 5867 */ { MAD_F(0x0675635b) /* 0.403659207 */, 18 }, +/* 5868 */ { MAD_F(0x0675c38d) /* 0.403750945 */, 18 }, +/* 5869 */ { MAD_F(0x067623c0) /* 0.403842688 */, 18 }, +/* 5870 */ { MAD_F(0x067683f4) /* 0.403934437 */, 18 }, +/* 5871 */ { MAD_F(0x0676e42a) /* 0.404026190 */, 18 }, + +/* 5872 */ { MAD_F(0x06774462) /* 0.404117949 */, 18 }, +/* 5873 */ { MAD_F(0x0677a49b) /* 0.404209714 */, 18 }, +/* 5874 */ { MAD_F(0x067804d5) /* 0.404301483 */, 18 }, +/* 5875 */ { MAD_F(0x06786510) /* 0.404393258 */, 18 }, +/* 5876 */ { MAD_F(0x0678c54d) /* 0.404485037 */, 18 }, +/* 5877 */ { MAD_F(0x0679258c) /* 0.404576822 */, 18 }, +/* 5878 */ { MAD_F(0x067985cb) /* 0.404668613 */, 18 }, +/* 5879 */ { MAD_F(0x0679e60c) /* 0.404760408 */, 18 }, +/* 5880 */ { MAD_F(0x067a464f) /* 0.404852209 */, 18 }, +/* 5881 */ { MAD_F(0x067aa693) /* 0.404944014 */, 18 }, +/* 5882 */ { MAD_F(0x067b06d8) /* 0.405035825 */, 18 }, +/* 5883 */ { MAD_F(0x067b671f) /* 0.405127642 */, 18 }, +/* 5884 */ { MAD_F(0x067bc767) /* 0.405219463 */, 18 }, +/* 5885 */ { MAD_F(0x067c27b1) /* 0.405311290 */, 18 }, +/* 5886 */ { MAD_F(0x067c87fc) /* 0.405403122 */, 18 }, +/* 5887 */ { MAD_F(0x067ce848) /* 0.405494959 */, 18 }, + +/* 5888 */ { MAD_F(0x067d4896) /* 0.405586801 */, 18 }, +/* 5889 */ { MAD_F(0x067da8e5) /* 0.405678648 */, 18 }, +/* 5890 */ { MAD_F(0x067e0935) /* 0.405770501 */, 18 }, +/* 5891 */ { MAD_F(0x067e6987) /* 0.405862359 */, 18 }, +/* 5892 */ { MAD_F(0x067ec9da) /* 0.405954222 */, 18 }, +/* 5893 */ { MAD_F(0x067f2a2f) /* 0.406046090 */, 18 }, +/* 5894 */ { MAD_F(0x067f8a85) /* 0.406137963 */, 18 }, +/* 5895 */ { MAD_F(0x067feadd) /* 0.406229842 */, 18 }, +/* 5896 */ { MAD_F(0x06804b36) /* 0.406321726 */, 18 }, +/* 5897 */ { MAD_F(0x0680ab90) /* 0.406413615 */, 18 }, +/* 5898 */ { MAD_F(0x06810beb) /* 0.406505509 */, 18 }, +/* 5899 */ { MAD_F(0x06816c49) /* 0.406597408 */, 18 }, +/* 5900 */ { MAD_F(0x0681cca7) /* 0.406689313 */, 18 }, +/* 5901 */ { MAD_F(0x06822d07) /* 0.406781223 */, 18 }, +/* 5902 */ { MAD_F(0x06828d68) /* 0.406873138 */, 18 }, +/* 5903 */ { MAD_F(0x0682edcb) /* 0.406965058 */, 18 }, + +/* 5904 */ { MAD_F(0x06834e2f) /* 0.407056983 */, 18 }, +/* 5905 */ { MAD_F(0x0683ae94) /* 0.407148914 */, 18 }, +/* 5906 */ { MAD_F(0x06840efb) /* 0.407240850 */, 18 }, +/* 5907 */ { MAD_F(0x06846f63) /* 0.407332791 */, 18 }, +/* 5908 */ { MAD_F(0x0684cfcd) /* 0.407424737 */, 18 }, +/* 5909 */ { MAD_F(0x06853038) /* 0.407516688 */, 18 }, +/* 5910 */ { MAD_F(0x068590a4) /* 0.407608645 */, 18 }, +/* 5911 */ { MAD_F(0x0685f112) /* 0.407700606 */, 18 }, +/* 5912 */ { MAD_F(0x06865181) /* 0.407792573 */, 18 }, +/* 5913 */ { MAD_F(0x0686b1f2) /* 0.407884545 */, 18 }, +/* 5914 */ { MAD_F(0x06871264) /* 0.407976522 */, 18 }, +/* 5915 */ { MAD_F(0x068772d7) /* 0.408068505 */, 18 }, +/* 5916 */ { MAD_F(0x0687d34c) /* 0.408160492 */, 18 }, +/* 5917 */ { MAD_F(0x068833c2) /* 0.408252485 */, 18 }, +/* 5918 */ { MAD_F(0x06889439) /* 0.408344483 */, 18 }, +/* 5919 */ { MAD_F(0x0688f4b2) /* 0.408436486 */, 18 }, + +/* 5920 */ { MAD_F(0x0689552c) /* 0.408528495 */, 18 }, +/* 5921 */ { MAD_F(0x0689b5a8) /* 0.408620508 */, 18 }, +/* 5922 */ { MAD_F(0x068a1625) /* 0.408712527 */, 18 }, +/* 5923 */ { MAD_F(0x068a76a4) /* 0.408804551 */, 18 }, +/* 5924 */ { MAD_F(0x068ad724) /* 0.408896580 */, 18 }, +/* 5925 */ { MAD_F(0x068b37a5) /* 0.408988614 */, 18 }, +/* 5926 */ { MAD_F(0x068b9827) /* 0.409080653 */, 18 }, +/* 5927 */ { MAD_F(0x068bf8ac) /* 0.409172698 */, 18 }, +/* 5928 */ { MAD_F(0x068c5931) /* 0.409264748 */, 18 }, +/* 5929 */ { MAD_F(0x068cb9b8) /* 0.409356803 */, 18 }, +/* 5930 */ { MAD_F(0x068d1a40) /* 0.409448863 */, 18 }, +/* 5931 */ { MAD_F(0x068d7aca) /* 0.409540928 */, 18 }, +/* 5932 */ { MAD_F(0x068ddb54) /* 0.409632999 */, 18 }, +/* 5933 */ { MAD_F(0x068e3be1) /* 0.409725074 */, 18 }, +/* 5934 */ { MAD_F(0x068e9c6f) /* 0.409817155 */, 18 }, +/* 5935 */ { MAD_F(0x068efcfe) /* 0.409909241 */, 18 }, + +/* 5936 */ { MAD_F(0x068f5d8e) /* 0.410001332 */, 18 }, +/* 5937 */ { MAD_F(0x068fbe20) /* 0.410093428 */, 18 }, +/* 5938 */ { MAD_F(0x06901eb4) /* 0.410185530 */, 18 }, +/* 5939 */ { MAD_F(0x06907f48) /* 0.410277637 */, 18 }, +/* 5940 */ { MAD_F(0x0690dfde) /* 0.410369748 */, 18 }, +/* 5941 */ { MAD_F(0x06914076) /* 0.410461865 */, 18 }, +/* 5942 */ { MAD_F(0x0691a10f) /* 0.410553988 */, 18 }, +/* 5943 */ { MAD_F(0x069201a9) /* 0.410646115 */, 18 }, +/* 5944 */ { MAD_F(0x06926245) /* 0.410738247 */, 18 }, +/* 5945 */ { MAD_F(0x0692c2e2) /* 0.410830385 */, 18 }, +/* 5946 */ { MAD_F(0x06932380) /* 0.410922528 */, 18 }, +/* 5947 */ { MAD_F(0x06938420) /* 0.411014676 */, 18 }, +/* 5948 */ { MAD_F(0x0693e4c1) /* 0.411106829 */, 18 }, +/* 5949 */ { MAD_F(0x06944563) /* 0.411198987 */, 18 }, +/* 5950 */ { MAD_F(0x0694a607) /* 0.411291151 */, 18 }, +/* 5951 */ { MAD_F(0x069506ad) /* 0.411383320 */, 18 }, + +/* 5952 */ { MAD_F(0x06956753) /* 0.411475493 */, 18 }, +/* 5953 */ { MAD_F(0x0695c7fc) /* 0.411567672 */, 18 }, +/* 5954 */ { MAD_F(0x069628a5) /* 0.411659857 */, 18 }, +/* 5955 */ { MAD_F(0x06968950) /* 0.411752046 */, 18 }, +/* 5956 */ { MAD_F(0x0696e9fc) /* 0.411844240 */, 18 }, +/* 5957 */ { MAD_F(0x06974aaa) /* 0.411936440 */, 18 }, +/* 5958 */ { MAD_F(0x0697ab59) /* 0.412028645 */, 18 }, +/* 5959 */ { MAD_F(0x06980c09) /* 0.412120855 */, 18 }, +/* 5960 */ { MAD_F(0x06986cbb) /* 0.412213070 */, 18 }, +/* 5961 */ { MAD_F(0x0698cd6e) /* 0.412305290 */, 18 }, +/* 5962 */ { MAD_F(0x06992e23) /* 0.412397516 */, 18 }, +/* 5963 */ { MAD_F(0x06998ed9) /* 0.412489746 */, 18 }, +/* 5964 */ { MAD_F(0x0699ef90) /* 0.412581982 */, 18 }, +/* 5965 */ { MAD_F(0x069a5049) /* 0.412674223 */, 18 }, +/* 5966 */ { MAD_F(0x069ab103) /* 0.412766469 */, 18 }, +/* 5967 */ { MAD_F(0x069b11bf) /* 0.412858720 */, 18 }, + +/* 5968 */ { MAD_F(0x069b727b) /* 0.412950976 */, 18 }, +/* 5969 */ { MAD_F(0x069bd33a) /* 0.413043238 */, 18 }, +/* 5970 */ { MAD_F(0x069c33f9) /* 0.413135505 */, 18 }, +/* 5971 */ { MAD_F(0x069c94ba) /* 0.413227776 */, 18 }, +/* 5972 */ { MAD_F(0x069cf57d) /* 0.413320053 */, 18 }, +/* 5973 */ { MAD_F(0x069d5641) /* 0.413412335 */, 18 }, +/* 5974 */ { MAD_F(0x069db706) /* 0.413504623 */, 18 }, +/* 5975 */ { MAD_F(0x069e17cc) /* 0.413596915 */, 18 }, +/* 5976 */ { MAD_F(0x069e7894) /* 0.413689213 */, 18 }, +/* 5977 */ { MAD_F(0x069ed95e) /* 0.413781515 */, 18 }, +/* 5978 */ { MAD_F(0x069f3a28) /* 0.413873823 */, 18 }, +/* 5979 */ { MAD_F(0x069f9af4) /* 0.413966136 */, 18 }, +/* 5980 */ { MAD_F(0x069ffbc2) /* 0.414058454 */, 18 }, +/* 5981 */ { MAD_F(0x06a05c91) /* 0.414150778 */, 18 }, +/* 5982 */ { MAD_F(0x06a0bd61) /* 0.414243106 */, 18 }, +/* 5983 */ { MAD_F(0x06a11e32) /* 0.414335440 */, 18 }, + +/* 5984 */ { MAD_F(0x06a17f05) /* 0.414427779 */, 18 }, +/* 5985 */ { MAD_F(0x06a1dfda) /* 0.414520122 */, 18 }, +/* 5986 */ { MAD_F(0x06a240b0) /* 0.414612471 */, 18 }, +/* 5987 */ { MAD_F(0x06a2a187) /* 0.414704826 */, 18 }, +/* 5988 */ { MAD_F(0x06a3025f) /* 0.414797185 */, 18 }, +/* 5989 */ { MAD_F(0x06a36339) /* 0.414889549 */, 18 }, +/* 5990 */ { MAD_F(0x06a3c414) /* 0.414981919 */, 18 }, +/* 5991 */ { MAD_F(0x06a424f1) /* 0.415074294 */, 18 }, +/* 5992 */ { MAD_F(0x06a485cf) /* 0.415166674 */, 18 }, +/* 5993 */ { MAD_F(0x06a4e6ae) /* 0.415259059 */, 18 }, +/* 5994 */ { MAD_F(0x06a5478f) /* 0.415351449 */, 18 }, +/* 5995 */ { MAD_F(0x06a5a871) /* 0.415443844 */, 18 }, +/* 5996 */ { MAD_F(0x06a60955) /* 0.415536244 */, 18 }, +/* 5997 */ { MAD_F(0x06a66a3a) /* 0.415628650 */, 18 }, +/* 5998 */ { MAD_F(0x06a6cb20) /* 0.415721061 */, 18 }, +/* 5999 */ { MAD_F(0x06a72c08) /* 0.415813476 */, 18 }, + +/* 6000 */ { MAD_F(0x06a78cf1) /* 0.415905897 */, 18 }, +/* 6001 */ { MAD_F(0x06a7eddb) /* 0.415998324 */, 18 }, +/* 6002 */ { MAD_F(0x06a84ec7) /* 0.416090755 */, 18 }, +/* 6003 */ { MAD_F(0x06a8afb4) /* 0.416183191 */, 18 }, +/* 6004 */ { MAD_F(0x06a910a3) /* 0.416275633 */, 18 }, +/* 6005 */ { MAD_F(0x06a97193) /* 0.416368079 */, 18 }, +/* 6006 */ { MAD_F(0x06a9d284) /* 0.416460531 */, 18 }, +/* 6007 */ { MAD_F(0x06aa3377) /* 0.416552988 */, 18 }, +/* 6008 */ { MAD_F(0x06aa946b) /* 0.416645450 */, 18 }, +/* 6009 */ { MAD_F(0x06aaf561) /* 0.416737917 */, 18 }, +/* 6010 */ { MAD_F(0x06ab5657) /* 0.416830389 */, 18 }, +/* 6011 */ { MAD_F(0x06abb750) /* 0.416922867 */, 18 }, +/* 6012 */ { MAD_F(0x06ac1849) /* 0.417015349 */, 18 }, +/* 6013 */ { MAD_F(0x06ac7944) /* 0.417107837 */, 18 }, +/* 6014 */ { MAD_F(0x06acda41) /* 0.417200330 */, 18 }, +/* 6015 */ { MAD_F(0x06ad3b3e) /* 0.417292828 */, 18 }, + +/* 6016 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 18 }, +/* 6017 */ { MAD_F(0x06adfd3e) /* 0.417477839 */, 18 }, +/* 6018 */ { MAD_F(0x06ae5e40) /* 0.417570352 */, 18 }, +/* 6019 */ { MAD_F(0x06aebf43) /* 0.417662871 */, 18 }, +/* 6020 */ { MAD_F(0x06af2047) /* 0.417755394 */, 18 }, +/* 6021 */ { MAD_F(0x06af814d) /* 0.417847923 */, 18 }, +/* 6022 */ { MAD_F(0x06afe255) /* 0.417940457 */, 18 }, +/* 6023 */ { MAD_F(0x06b0435e) /* 0.418032996 */, 18 }, +/* 6024 */ { MAD_F(0x06b0a468) /* 0.418125540 */, 18 }, +/* 6025 */ { MAD_F(0x06b10573) /* 0.418218089 */, 18 }, +/* 6026 */ { MAD_F(0x06b16680) /* 0.418310643 */, 18 }, +/* 6027 */ { MAD_F(0x06b1c78e) /* 0.418403203 */, 18 }, +/* 6028 */ { MAD_F(0x06b2289e) /* 0.418495767 */, 18 }, +/* 6029 */ { MAD_F(0x06b289af) /* 0.418588337 */, 18 }, +/* 6030 */ { MAD_F(0x06b2eac1) /* 0.418680911 */, 18 }, +/* 6031 */ { MAD_F(0x06b34bd5) /* 0.418773491 */, 18 }, + +/* 6032 */ { MAD_F(0x06b3acea) /* 0.418866076 */, 18 }, +/* 6033 */ { MAD_F(0x06b40e00) /* 0.418958666 */, 18 }, +/* 6034 */ { MAD_F(0x06b46f18) /* 0.419051262 */, 18 }, +/* 6035 */ { MAD_F(0x06b4d031) /* 0.419143862 */, 18 }, +/* 6036 */ { MAD_F(0x06b5314c) /* 0.419236467 */, 18 }, +/* 6037 */ { MAD_F(0x06b59268) /* 0.419329078 */, 18 }, +/* 6038 */ { MAD_F(0x06b5f385) /* 0.419421694 */, 18 }, +/* 6039 */ { MAD_F(0x06b654a4) /* 0.419514314 */, 18 }, +/* 6040 */ { MAD_F(0x06b6b5c4) /* 0.419606940 */, 18 }, +/* 6041 */ { MAD_F(0x06b716e6) /* 0.419699571 */, 18 }, +/* 6042 */ { MAD_F(0x06b77808) /* 0.419792208 */, 18 }, +/* 6043 */ { MAD_F(0x06b7d92d) /* 0.419884849 */, 18 }, +/* 6044 */ { MAD_F(0x06b83a52) /* 0.419977495 */, 18 }, +/* 6045 */ { MAD_F(0x06b89b79) /* 0.420070147 */, 18 }, +/* 6046 */ { MAD_F(0x06b8fca1) /* 0.420162803 */, 18 }, +/* 6047 */ { MAD_F(0x06b95dcb) /* 0.420255465 */, 18 }, + +/* 6048 */ { MAD_F(0x06b9bef6) /* 0.420348132 */, 18 }, +/* 6049 */ { MAD_F(0x06ba2023) /* 0.420440803 */, 18 }, +/* 6050 */ { MAD_F(0x06ba8150) /* 0.420533481 */, 18 }, +/* 6051 */ { MAD_F(0x06bae280) /* 0.420626163 */, 18 }, +/* 6052 */ { MAD_F(0x06bb43b0) /* 0.420718850 */, 18 }, +/* 6053 */ { MAD_F(0x06bba4e2) /* 0.420811542 */, 18 }, +/* 6054 */ { MAD_F(0x06bc0615) /* 0.420904240 */, 18 }, +/* 6055 */ { MAD_F(0x06bc674a) /* 0.420996942 */, 18 }, +/* 6056 */ { MAD_F(0x06bcc880) /* 0.421089650 */, 18 }, +/* 6057 */ { MAD_F(0x06bd29b7) /* 0.421182362 */, 18 }, +/* 6058 */ { MAD_F(0x06bd8af0) /* 0.421275080 */, 18 }, +/* 6059 */ { MAD_F(0x06bdec2a) /* 0.421367803 */, 18 }, +/* 6060 */ { MAD_F(0x06be4d66) /* 0.421460531 */, 18 }, +/* 6061 */ { MAD_F(0x06beaea3) /* 0.421553264 */, 18 }, +/* 6062 */ { MAD_F(0x06bf0fe1) /* 0.421646003 */, 18 }, +/* 6063 */ { MAD_F(0x06bf7120) /* 0.421738746 */, 18 }, + +/* 6064 */ { MAD_F(0x06bfd261) /* 0.421831494 */, 18 }, +/* 6065 */ { MAD_F(0x06c033a4) /* 0.421924248 */, 18 }, +/* 6066 */ { MAD_F(0x06c094e7) /* 0.422017007 */, 18 }, +/* 6067 */ { MAD_F(0x06c0f62c) /* 0.422109770 */, 18 }, +/* 6068 */ { MAD_F(0x06c15773) /* 0.422202539 */, 18 }, +/* 6069 */ { MAD_F(0x06c1b8bb) /* 0.422295313 */, 18 }, +/* 6070 */ { MAD_F(0x06c21a04) /* 0.422388092 */, 18 }, +/* 6071 */ { MAD_F(0x06c27b4e) /* 0.422480876 */, 18 }, +/* 6072 */ { MAD_F(0x06c2dc9a) /* 0.422573665 */, 18 }, +/* 6073 */ { MAD_F(0x06c33de8) /* 0.422666460 */, 18 }, +/* 6074 */ { MAD_F(0x06c39f36) /* 0.422759259 */, 18 }, +/* 6075 */ { MAD_F(0x06c40086) /* 0.422852064 */, 18 }, +/* 6076 */ { MAD_F(0x06c461d8) /* 0.422944873 */, 18 }, +/* 6077 */ { MAD_F(0x06c4c32a) /* 0.423037688 */, 18 }, +/* 6078 */ { MAD_F(0x06c5247f) /* 0.423130508 */, 18 }, +/* 6079 */ { MAD_F(0x06c585d4) /* 0.423223333 */, 18 }, + +/* 6080 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 18 }, +/* 6081 */ { MAD_F(0x06c64883) /* 0.423408997 */, 18 }, +/* 6082 */ { MAD_F(0x06c6a9dd) /* 0.423501838 */, 18 }, +/* 6083 */ { MAD_F(0x06c70b38) /* 0.423594683 */, 18 }, +/* 6084 */ { MAD_F(0x06c76c94) /* 0.423687533 */, 18 }, +/* 6085 */ { MAD_F(0x06c7cdf2) /* 0.423780389 */, 18 }, +/* 6086 */ { MAD_F(0x06c82f51) /* 0.423873249 */, 18 }, +/* 6087 */ { MAD_F(0x06c890b1) /* 0.423966115 */, 18 }, +/* 6088 */ { MAD_F(0x06c8f213) /* 0.424058985 */, 18 }, +/* 6089 */ { MAD_F(0x06c95376) /* 0.424151861 */, 18 }, +/* 6090 */ { MAD_F(0x06c9b4da) /* 0.424244742 */, 18 }, +/* 6091 */ { MAD_F(0x06ca1640) /* 0.424337628 */, 18 }, +/* 6092 */ { MAD_F(0x06ca77a8) /* 0.424430519 */, 18 }, +/* 6093 */ { MAD_F(0x06cad910) /* 0.424523415 */, 18 }, +/* 6094 */ { MAD_F(0x06cb3a7a) /* 0.424616316 */, 18 }, +/* 6095 */ { MAD_F(0x06cb9be5) /* 0.424709222 */, 18 }, + +/* 6096 */ { MAD_F(0x06cbfd52) /* 0.424802133 */, 18 }, +/* 6097 */ { MAD_F(0x06cc5ec0) /* 0.424895050 */, 18 }, +/* 6098 */ { MAD_F(0x06ccc030) /* 0.424987971 */, 18 }, +/* 6099 */ { MAD_F(0x06cd21a0) /* 0.425080898 */, 18 }, +/* 6100 */ { MAD_F(0x06cd8313) /* 0.425173829 */, 18 }, +/* 6101 */ { MAD_F(0x06cde486) /* 0.425266766 */, 18 }, +/* 6102 */ { MAD_F(0x06ce45fb) /* 0.425359708 */, 18 }, +/* 6103 */ { MAD_F(0x06cea771) /* 0.425452655 */, 18 }, +/* 6104 */ { MAD_F(0x06cf08e9) /* 0.425545607 */, 18 }, +/* 6105 */ { MAD_F(0x06cf6a62) /* 0.425638564 */, 18 }, +/* 6106 */ { MAD_F(0x06cfcbdc) /* 0.425731526 */, 18 }, +/* 6107 */ { MAD_F(0x06d02d58) /* 0.425824493 */, 18 }, +/* 6108 */ { MAD_F(0x06d08ed5) /* 0.425917465 */, 18 }, +/* 6109 */ { MAD_F(0x06d0f053) /* 0.426010443 */, 18 }, +/* 6110 */ { MAD_F(0x06d151d3) /* 0.426103425 */, 18 }, +/* 6111 */ { MAD_F(0x06d1b354) /* 0.426196412 */, 18 }, + +/* 6112 */ { MAD_F(0x06d214d7) /* 0.426289405 */, 18 }, +/* 6113 */ { MAD_F(0x06d2765a) /* 0.426382403 */, 18 }, +/* 6114 */ { MAD_F(0x06d2d7e0) /* 0.426475405 */, 18 }, +/* 6115 */ { MAD_F(0x06d33966) /* 0.426568413 */, 18 }, +/* 6116 */ { MAD_F(0x06d39aee) /* 0.426661426 */, 18 }, +/* 6117 */ { MAD_F(0x06d3fc77) /* 0.426754444 */, 18 }, +/* 6118 */ { MAD_F(0x06d45e02) /* 0.426847467 */, 18 }, +/* 6119 */ { MAD_F(0x06d4bf8e) /* 0.426940495 */, 18 }, +/* 6120 */ { MAD_F(0x06d5211c) /* 0.427033528 */, 18 }, +/* 6121 */ { MAD_F(0x06d582aa) /* 0.427126566 */, 18 }, +/* 6122 */ { MAD_F(0x06d5e43a) /* 0.427219609 */, 18 }, +/* 6123 */ { MAD_F(0x06d645cc) /* 0.427312657 */, 18 }, +/* 6124 */ { MAD_F(0x06d6a75f) /* 0.427405711 */, 18 }, +/* 6125 */ { MAD_F(0x06d708f3) /* 0.427498769 */, 18 }, +/* 6126 */ { MAD_F(0x06d76a88) /* 0.427591833 */, 18 }, +/* 6127 */ { MAD_F(0x06d7cc1f) /* 0.427684901 */, 18 }, + +/* 6128 */ { MAD_F(0x06d82db8) /* 0.427777975 */, 18 }, +/* 6129 */ { MAD_F(0x06d88f51) /* 0.427871054 */, 18 }, +/* 6130 */ { MAD_F(0x06d8f0ec) /* 0.427964137 */, 18 }, +/* 6131 */ { MAD_F(0x06d95288) /* 0.428057226 */, 18 }, +/* 6132 */ { MAD_F(0x06d9b426) /* 0.428150320 */, 18 }, +/* 6133 */ { MAD_F(0x06da15c5) /* 0.428243419 */, 18 }, +/* 6134 */ { MAD_F(0x06da7766) /* 0.428336523 */, 18 }, +/* 6135 */ { MAD_F(0x06dad907) /* 0.428429632 */, 18 }, +/* 6136 */ { MAD_F(0x06db3aaa) /* 0.428522746 */, 18 }, +/* 6137 */ { MAD_F(0x06db9c4f) /* 0.428615865 */, 18 }, +/* 6138 */ { MAD_F(0x06dbfdf5) /* 0.428708989 */, 18 }, +/* 6139 */ { MAD_F(0x06dc5f9c) /* 0.428802119 */, 18 }, +/* 6140 */ { MAD_F(0x06dcc145) /* 0.428895253 */, 18 }, +/* 6141 */ { MAD_F(0x06dd22ee) /* 0.428988392 */, 18 }, +/* 6142 */ { MAD_F(0x06dd849a) /* 0.429081537 */, 18 }, +/* 6143 */ { MAD_F(0x06dde646) /* 0.429174686 */, 18 }, + +/* 6144 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 18 }, +/* 6145 */ { MAD_F(0x06dea9a4) /* 0.429361001 */, 18 }, +/* 6146 */ { MAD_F(0x06df0b54) /* 0.429454165 */, 18 }, +/* 6147 */ { MAD_F(0x06df6d06) /* 0.429547335 */, 18 }, +/* 6148 */ { MAD_F(0x06dfceba) /* 0.429640510 */, 18 }, +/* 6149 */ { MAD_F(0x06e0306f) /* 0.429733690 */, 18 }, +/* 6150 */ { MAD_F(0x06e09225) /* 0.429826874 */, 18 }, +/* 6151 */ { MAD_F(0x06e0f3dc) /* 0.429920064 */, 18 }, +/* 6152 */ { MAD_F(0x06e15595) /* 0.430013259 */, 18 }, +/* 6153 */ { MAD_F(0x06e1b74f) /* 0.430106459 */, 18 }, +/* 6154 */ { MAD_F(0x06e2190b) /* 0.430199664 */, 18 }, +/* 6155 */ { MAD_F(0x06e27ac8) /* 0.430292875 */, 18 }, +/* 6156 */ { MAD_F(0x06e2dc86) /* 0.430386090 */, 18 }, +/* 6157 */ { MAD_F(0x06e33e46) /* 0.430479310 */, 18 }, +/* 6158 */ { MAD_F(0x06e3a007) /* 0.430572535 */, 18 }, +/* 6159 */ { MAD_F(0x06e401c9) /* 0.430665765 */, 18 }, + +/* 6160 */ { MAD_F(0x06e4638d) /* 0.430759001 */, 18 }, +/* 6161 */ { MAD_F(0x06e4c552) /* 0.430852241 */, 18 }, +/* 6162 */ { MAD_F(0x06e52718) /* 0.430945487 */, 18 }, +/* 6163 */ { MAD_F(0x06e588e0) /* 0.431038737 */, 18 }, +/* 6164 */ { MAD_F(0x06e5eaa9) /* 0.431131993 */, 18 }, +/* 6165 */ { MAD_F(0x06e64c73) /* 0.431225253 */, 18 }, +/* 6166 */ { MAD_F(0x06e6ae3f) /* 0.431318519 */, 18 }, +/* 6167 */ { MAD_F(0x06e7100c) /* 0.431411790 */, 18 }, +/* 6168 */ { MAD_F(0x06e771db) /* 0.431505065 */, 18 }, +/* 6169 */ { MAD_F(0x06e7d3ab) /* 0.431598346 */, 18 }, +/* 6170 */ { MAD_F(0x06e8357c) /* 0.431691632 */, 18 }, +/* 6171 */ { MAD_F(0x06e8974e) /* 0.431784923 */, 18 }, +/* 6172 */ { MAD_F(0x06e8f922) /* 0.431878218 */, 18 }, +/* 6173 */ { MAD_F(0x06e95af8) /* 0.431971519 */, 18 }, +/* 6174 */ { MAD_F(0x06e9bcce) /* 0.432064825 */, 18 }, +/* 6175 */ { MAD_F(0x06ea1ea6) /* 0.432158136 */, 18 }, + +/* 6176 */ { MAD_F(0x06ea807f) /* 0.432251452 */, 18 }, +/* 6177 */ { MAD_F(0x06eae25a) /* 0.432344773 */, 18 }, +/* 6178 */ { MAD_F(0x06eb4436) /* 0.432438099 */, 18 }, +/* 6179 */ { MAD_F(0x06eba614) /* 0.432531431 */, 18 }, +/* 6180 */ { MAD_F(0x06ec07f2) /* 0.432624767 */, 18 }, +/* 6181 */ { MAD_F(0x06ec69d2) /* 0.432718108 */, 18 }, +/* 6182 */ { MAD_F(0x06eccbb4) /* 0.432811454 */, 18 }, +/* 6183 */ { MAD_F(0x06ed2d97) /* 0.432904805 */, 18 }, +/* 6184 */ { MAD_F(0x06ed8f7b) /* 0.432998162 */, 18 }, +/* 6185 */ { MAD_F(0x06edf160) /* 0.433091523 */, 18 }, +/* 6186 */ { MAD_F(0x06ee5347) /* 0.433184889 */, 18 }, +/* 6187 */ { MAD_F(0x06eeb52f) /* 0.433278261 */, 18 }, +/* 6188 */ { MAD_F(0x06ef1719) /* 0.433371637 */, 18 }, +/* 6189 */ { MAD_F(0x06ef7904) /* 0.433465019 */, 18 }, +/* 6190 */ { MAD_F(0x06efdaf0) /* 0.433558405 */, 18 }, +/* 6191 */ { MAD_F(0x06f03cde) /* 0.433651797 */, 18 }, + +/* 6192 */ { MAD_F(0x06f09ecc) /* 0.433745193 */, 18 }, +/* 6193 */ { MAD_F(0x06f100bd) /* 0.433838595 */, 18 }, +/* 6194 */ { MAD_F(0x06f162ae) /* 0.433932001 */, 18 }, +/* 6195 */ { MAD_F(0x06f1c4a1) /* 0.434025413 */, 18 }, +/* 6196 */ { MAD_F(0x06f22696) /* 0.434118830 */, 18 }, +/* 6197 */ { MAD_F(0x06f2888b) /* 0.434212251 */, 18 }, +/* 6198 */ { MAD_F(0x06f2ea82) /* 0.434305678 */, 18 }, +/* 6199 */ { MAD_F(0x06f34c7b) /* 0.434399110 */, 18 }, +/* 6200 */ { MAD_F(0x06f3ae75) /* 0.434492546 */, 18 }, +/* 6201 */ { MAD_F(0x06f41070) /* 0.434585988 */, 18 }, +/* 6202 */ { MAD_F(0x06f4726c) /* 0.434679435 */, 18 }, +/* 6203 */ { MAD_F(0x06f4d46a) /* 0.434772887 */, 18 }, +/* 6204 */ { MAD_F(0x06f53669) /* 0.434866344 */, 18 }, +/* 6205 */ { MAD_F(0x06f59869) /* 0.434959806 */, 18 }, +/* 6206 */ { MAD_F(0x06f5fa6b) /* 0.435053272 */, 18 }, +/* 6207 */ { MAD_F(0x06f65c6e) /* 0.435146744 */, 18 }, + +/* 6208 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 18 }, +/* 6209 */ { MAD_F(0x06f72079) /* 0.435333703 */, 18 }, +/* 6210 */ { MAD_F(0x06f78280) /* 0.435427190 */, 18 }, +/* 6211 */ { MAD_F(0x06f7e489) /* 0.435520682 */, 18 }, +/* 6212 */ { MAD_F(0x06f84693) /* 0.435614179 */, 18 }, +/* 6213 */ { MAD_F(0x06f8a89e) /* 0.435707681 */, 18 }, +/* 6214 */ { MAD_F(0x06f90aaa) /* 0.435801188 */, 18 }, +/* 6215 */ { MAD_F(0x06f96cb8) /* 0.435894700 */, 18 }, +/* 6216 */ { MAD_F(0x06f9cec8) /* 0.435988217 */, 18 }, +/* 6217 */ { MAD_F(0x06fa30d8) /* 0.436081739 */, 18 }, +/* 6218 */ { MAD_F(0x06fa92ea) /* 0.436175266 */, 18 }, +/* 6219 */ { MAD_F(0x06faf4fe) /* 0.436268799 */, 18 }, +/* 6220 */ { MAD_F(0x06fb5712) /* 0.436362336 */, 18 }, +/* 6221 */ { MAD_F(0x06fbb928) /* 0.436455878 */, 18 }, +/* 6222 */ { MAD_F(0x06fc1b40) /* 0.436549425 */, 18 }, +/* 6223 */ { MAD_F(0x06fc7d58) /* 0.436642977 */, 18 }, + +/* 6224 */ { MAD_F(0x06fcdf72) /* 0.436736534 */, 18 }, +/* 6225 */ { MAD_F(0x06fd418e) /* 0.436830096 */, 18 }, +/* 6226 */ { MAD_F(0x06fda3ab) /* 0.436923664 */, 18 }, +/* 6227 */ { MAD_F(0x06fe05c9) /* 0.437017236 */, 18 }, +/* 6228 */ { MAD_F(0x06fe67e8) /* 0.437110813 */, 18 }, +/* 6229 */ { MAD_F(0x06feca09) /* 0.437204395 */, 18 }, +/* 6230 */ { MAD_F(0x06ff2c2b) /* 0.437297982 */, 18 }, +/* 6231 */ { MAD_F(0x06ff8e4f) /* 0.437391575 */, 18 }, +/* 6232 */ { MAD_F(0x06fff073) /* 0.437485172 */, 18 }, +/* 6233 */ { MAD_F(0x0700529a) /* 0.437578774 */, 18 }, +/* 6234 */ { MAD_F(0x0700b4c1) /* 0.437672381 */, 18 }, +/* 6235 */ { MAD_F(0x070116ea) /* 0.437765994 */, 18 }, +/* 6236 */ { MAD_F(0x07017914) /* 0.437859611 */, 18 }, +/* 6237 */ { MAD_F(0x0701db40) /* 0.437953233 */, 18 }, +/* 6238 */ { MAD_F(0x07023d6c) /* 0.438046860 */, 18 }, +/* 6239 */ { MAD_F(0x07029f9b) /* 0.438140493 */, 18 }, + +/* 6240 */ { MAD_F(0x070301ca) /* 0.438234130 */, 18 }, +/* 6241 */ { MAD_F(0x070363fb) /* 0.438327772 */, 18 }, +/* 6242 */ { MAD_F(0x0703c62d) /* 0.438421419 */, 18 }, +/* 6243 */ { MAD_F(0x07042861) /* 0.438515072 */, 18 }, +/* 6244 */ { MAD_F(0x07048a96) /* 0.438608729 */, 18 }, +/* 6245 */ { MAD_F(0x0704eccc) /* 0.438702391 */, 18 }, +/* 6246 */ { MAD_F(0x07054f04) /* 0.438796059 */, 18 }, +/* 6247 */ { MAD_F(0x0705b13d) /* 0.438889731 */, 18 }, +/* 6248 */ { MAD_F(0x07061377) /* 0.438983408 */, 18 }, +/* 6249 */ { MAD_F(0x070675b3) /* 0.439077090 */, 18 }, +/* 6250 */ { MAD_F(0x0706d7f0) /* 0.439170778 */, 18 }, +/* 6251 */ { MAD_F(0x07073a2e) /* 0.439264470 */, 18 }, +/* 6252 */ { MAD_F(0x07079c6e) /* 0.439358167 */, 18 }, +/* 6253 */ { MAD_F(0x0707feaf) /* 0.439451869 */, 18 }, +/* 6254 */ { MAD_F(0x070860f1) /* 0.439545577 */, 18 }, +/* 6255 */ { MAD_F(0x0708c335) /* 0.439639289 */, 18 }, + +/* 6256 */ { MAD_F(0x0709257a) /* 0.439733006 */, 18 }, +/* 6257 */ { MAD_F(0x070987c0) /* 0.439826728 */, 18 }, +/* 6258 */ { MAD_F(0x0709ea08) /* 0.439920456 */, 18 }, +/* 6259 */ { MAD_F(0x070a4c51) /* 0.440014188 */, 18 }, +/* 6260 */ { MAD_F(0x070aae9b) /* 0.440107925 */, 18 }, +/* 6261 */ { MAD_F(0x070b10e7) /* 0.440201667 */, 18 }, +/* 6262 */ { MAD_F(0x070b7334) /* 0.440295414 */, 18 }, +/* 6263 */ { MAD_F(0x070bd583) /* 0.440389167 */, 18 }, +/* 6264 */ { MAD_F(0x070c37d2) /* 0.440482924 */, 18 }, +/* 6265 */ { MAD_F(0x070c9a23) /* 0.440576686 */, 18 }, +/* 6266 */ { MAD_F(0x070cfc76) /* 0.440670453 */, 18 }, +/* 6267 */ { MAD_F(0x070d5eca) /* 0.440764225 */, 18 }, +/* 6268 */ { MAD_F(0x070dc11f) /* 0.440858002 */, 18 }, +/* 6269 */ { MAD_F(0x070e2375) /* 0.440951784 */, 18 }, +/* 6270 */ { MAD_F(0x070e85cd) /* 0.441045572 */, 18 }, +/* 6271 */ { MAD_F(0x070ee826) /* 0.441139364 */, 18 }, + +/* 6272 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 18 }, +/* 6273 */ { MAD_F(0x070facdc) /* 0.441326963 */, 18 }, +/* 6274 */ { MAD_F(0x07100f39) /* 0.441420770 */, 18 }, +/* 6275 */ { MAD_F(0x07107198) /* 0.441514582 */, 18 }, +/* 6276 */ { MAD_F(0x0710d3f8) /* 0.441608399 */, 18 }, +/* 6277 */ { MAD_F(0x07113659) /* 0.441702221 */, 18 }, +/* 6278 */ { MAD_F(0x071198bb) /* 0.441796048 */, 18 }, +/* 6279 */ { MAD_F(0x0711fb1f) /* 0.441889880 */, 18 }, +/* 6280 */ { MAD_F(0x07125d84) /* 0.441983717 */, 18 }, +/* 6281 */ { MAD_F(0x0712bfeb) /* 0.442077559 */, 18 }, +/* 6282 */ { MAD_F(0x07132253) /* 0.442171406 */, 18 }, +/* 6283 */ { MAD_F(0x071384bc) /* 0.442265257 */, 18 }, +/* 6284 */ { MAD_F(0x0713e726) /* 0.442359114 */, 18 }, +/* 6285 */ { MAD_F(0x07144992) /* 0.442452976 */, 18 }, +/* 6286 */ { MAD_F(0x0714abff) /* 0.442546843 */, 18 }, +/* 6287 */ { MAD_F(0x07150e6e) /* 0.442640715 */, 18 }, + +/* 6288 */ { MAD_F(0x071570de) /* 0.442734592 */, 18 }, +/* 6289 */ { MAD_F(0x0715d34f) /* 0.442828473 */, 18 }, +/* 6290 */ { MAD_F(0x071635c1) /* 0.442922360 */, 18 }, +/* 6291 */ { MAD_F(0x07169835) /* 0.443016252 */, 18 }, +/* 6292 */ { MAD_F(0x0716faaa) /* 0.443110148 */, 18 }, +/* 6293 */ { MAD_F(0x07175d21) /* 0.443204050 */, 18 }, +/* 6294 */ { MAD_F(0x0717bf99) /* 0.443297957 */, 18 }, +/* 6295 */ { MAD_F(0x07182212) /* 0.443391868 */, 18 }, +/* 6296 */ { MAD_F(0x0718848d) /* 0.443485785 */, 18 }, +/* 6297 */ { MAD_F(0x0718e709) /* 0.443579706 */, 18 }, +/* 6298 */ { MAD_F(0x07194986) /* 0.443673633 */, 18 }, +/* 6299 */ { MAD_F(0x0719ac04) /* 0.443767564 */, 18 }, +/* 6300 */ { MAD_F(0x071a0e84) /* 0.443861501 */, 18 }, +/* 6301 */ { MAD_F(0x071a7105) /* 0.443955442 */, 18 }, +/* 6302 */ { MAD_F(0x071ad388) /* 0.444049389 */, 18 }, +/* 6303 */ { MAD_F(0x071b360c) /* 0.444143340 */, 18 }, + +/* 6304 */ { MAD_F(0x071b9891) /* 0.444237296 */, 18 }, +/* 6305 */ { MAD_F(0x071bfb18) /* 0.444331258 */, 18 }, +/* 6306 */ { MAD_F(0x071c5d9f) /* 0.444425224 */, 18 }, +/* 6307 */ { MAD_F(0x071cc029) /* 0.444519195 */, 18 }, +/* 6308 */ { MAD_F(0x071d22b3) /* 0.444613171 */, 18 }, +/* 6309 */ { MAD_F(0x071d853f) /* 0.444707153 */, 18 }, +/* 6310 */ { MAD_F(0x071de7cc) /* 0.444801139 */, 18 }, +/* 6311 */ { MAD_F(0x071e4a5b) /* 0.444895130 */, 18 }, +/* 6312 */ { MAD_F(0x071eaceb) /* 0.444989126 */, 18 }, +/* 6313 */ { MAD_F(0x071f0f7c) /* 0.445083127 */, 18 }, +/* 6314 */ { MAD_F(0x071f720e) /* 0.445177133 */, 18 }, +/* 6315 */ { MAD_F(0x071fd4a2) /* 0.445271144 */, 18 }, +/* 6316 */ { MAD_F(0x07203737) /* 0.445365160 */, 18 }, +/* 6317 */ { MAD_F(0x072099ce) /* 0.445459181 */, 18 }, +/* 6318 */ { MAD_F(0x0720fc66) /* 0.445553206 */, 18 }, +/* 6319 */ { MAD_F(0x07215eff) /* 0.445647237 */, 18 }, + +/* 6320 */ { MAD_F(0x0721c19a) /* 0.445741273 */, 18 }, +/* 6321 */ { MAD_F(0x07222436) /* 0.445835314 */, 18 }, +/* 6322 */ { MAD_F(0x072286d3) /* 0.445929359 */, 18 }, +/* 6323 */ { MAD_F(0x0722e971) /* 0.446023410 */, 18 }, +/* 6324 */ { MAD_F(0x07234c11) /* 0.446117466 */, 18 }, +/* 6325 */ { MAD_F(0x0723aeb2) /* 0.446211526 */, 18 }, +/* 6326 */ { MAD_F(0x07241155) /* 0.446305592 */, 18 }, +/* 6327 */ { MAD_F(0x072473f9) /* 0.446399662 */, 18 }, +/* 6328 */ { MAD_F(0x0724d69e) /* 0.446493738 */, 18 }, +/* 6329 */ { MAD_F(0x07253944) /* 0.446587818 */, 18 }, +/* 6330 */ { MAD_F(0x07259bec) /* 0.446681903 */, 18 }, +/* 6331 */ { MAD_F(0x0725fe95) /* 0.446775994 */, 18 }, +/* 6332 */ { MAD_F(0x07266140) /* 0.446870089 */, 18 }, +/* 6333 */ { MAD_F(0x0726c3ec) /* 0.446964189 */, 18 }, +/* 6334 */ { MAD_F(0x07272699) /* 0.447058294 */, 18 }, +/* 6335 */ { MAD_F(0x07278947) /* 0.447152404 */, 18 }, + +/* 6336 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 18 }, +/* 6337 */ { MAD_F(0x07284ea8) /* 0.447340639 */, 18 }, +/* 6338 */ { MAD_F(0x0728b15b) /* 0.447434764 */, 18 }, +/* 6339 */ { MAD_F(0x0729140f) /* 0.447528894 */, 18 }, +/* 6340 */ { MAD_F(0x072976c4) /* 0.447623029 */, 18 }, +/* 6341 */ { MAD_F(0x0729d97a) /* 0.447717169 */, 18 }, +/* 6342 */ { MAD_F(0x072a3c32) /* 0.447811314 */, 18 }, +/* 6343 */ { MAD_F(0x072a9eeb) /* 0.447905463 */, 18 }, +/* 6344 */ { MAD_F(0x072b01a6) /* 0.447999618 */, 18 }, +/* 6345 */ { MAD_F(0x072b6461) /* 0.448093778 */, 18 }, +/* 6346 */ { MAD_F(0x072bc71e) /* 0.448187942 */, 18 }, +/* 6347 */ { MAD_F(0x072c29dd) /* 0.448282112 */, 18 }, +/* 6348 */ { MAD_F(0x072c8c9d) /* 0.448376286 */, 18 }, +/* 6349 */ { MAD_F(0x072cef5e) /* 0.448470466 */, 18 }, +/* 6350 */ { MAD_F(0x072d5220) /* 0.448564650 */, 18 }, +/* 6351 */ { MAD_F(0x072db4e4) /* 0.448658839 */, 18 }, + +/* 6352 */ { MAD_F(0x072e17a9) /* 0.448753033 */, 18 }, +/* 6353 */ { MAD_F(0x072e7a6f) /* 0.448847233 */, 18 }, +/* 6354 */ { MAD_F(0x072edd37) /* 0.448941437 */, 18 }, +/* 6355 */ { MAD_F(0x072f4000) /* 0.449035646 */, 18 }, +/* 6356 */ { MAD_F(0x072fa2ca) /* 0.449129860 */, 18 }, +/* 6357 */ { MAD_F(0x07300596) /* 0.449224079 */, 18 }, +/* 6358 */ { MAD_F(0x07306863) /* 0.449318303 */, 18 }, +/* 6359 */ { MAD_F(0x0730cb32) /* 0.449412531 */, 18 }, +/* 6360 */ { MAD_F(0x07312e01) /* 0.449506765 */, 18 }, +/* 6361 */ { MAD_F(0x073190d2) /* 0.449601004 */, 18 }, +/* 6362 */ { MAD_F(0x0731f3a5) /* 0.449695247 */, 18 }, +/* 6363 */ { MAD_F(0x07325678) /* 0.449789496 */, 18 }, +/* 6364 */ { MAD_F(0x0732b94d) /* 0.449883749 */, 18 }, +/* 6365 */ { MAD_F(0x07331c23) /* 0.449978008 */, 18 }, +/* 6366 */ { MAD_F(0x07337efb) /* 0.450072271 */, 18 }, +/* 6367 */ { MAD_F(0x0733e1d4) /* 0.450166540 */, 18 }, + +/* 6368 */ { MAD_F(0x073444ae) /* 0.450260813 */, 18 }, +/* 6369 */ { MAD_F(0x0734a78a) /* 0.450355091 */, 18 }, +/* 6370 */ { MAD_F(0x07350a67) /* 0.450449374 */, 18 }, +/* 6371 */ { MAD_F(0x07356d45) /* 0.450543662 */, 18 }, +/* 6372 */ { MAD_F(0x0735d025) /* 0.450637955 */, 18 }, +/* 6373 */ { MAD_F(0x07363306) /* 0.450732253 */, 18 }, +/* 6374 */ { MAD_F(0x073695e8) /* 0.450826556 */, 18 }, +/* 6375 */ { MAD_F(0x0736f8cb) /* 0.450920864 */, 18 }, +/* 6376 */ { MAD_F(0x07375bb0) /* 0.451015176 */, 18 }, +/* 6377 */ { MAD_F(0x0737be96) /* 0.451109494 */, 18 }, +/* 6378 */ { MAD_F(0x0738217e) /* 0.451203817 */, 18 }, +/* 6379 */ { MAD_F(0x07388467) /* 0.451298144 */, 18 }, +/* 6380 */ { MAD_F(0x0738e751) /* 0.451392477 */, 18 }, +/* 6381 */ { MAD_F(0x07394a3d) /* 0.451486814 */, 18 }, +/* 6382 */ { MAD_F(0x0739ad29) /* 0.451581156 */, 18 }, +/* 6383 */ { MAD_F(0x073a1017) /* 0.451675503 */, 18 }, + +/* 6384 */ { MAD_F(0x073a7307) /* 0.451769856 */, 18 }, +/* 6385 */ { MAD_F(0x073ad5f8) /* 0.451864213 */, 18 }, +/* 6386 */ { MAD_F(0x073b38ea) /* 0.451958575 */, 18 }, +/* 6387 */ { MAD_F(0x073b9bdd) /* 0.452052942 */, 18 }, +/* 6388 */ { MAD_F(0x073bfed2) /* 0.452147313 */, 18 }, +/* 6389 */ { MAD_F(0x073c61c8) /* 0.452241690 */, 18 }, +/* 6390 */ { MAD_F(0x073cc4bf) /* 0.452336072 */, 18 }, +/* 6391 */ { MAD_F(0x073d27b8) /* 0.452430458 */, 18 }, +/* 6392 */ { MAD_F(0x073d8ab2) /* 0.452524850 */, 18 }, +/* 6393 */ { MAD_F(0x073dedae) /* 0.452619246 */, 18 }, +/* 6394 */ { MAD_F(0x073e50aa) /* 0.452713648 */, 18 }, +/* 6395 */ { MAD_F(0x073eb3a8) /* 0.452808054 */, 18 }, +/* 6396 */ { MAD_F(0x073f16a8) /* 0.452902465 */, 18 }, +/* 6397 */ { MAD_F(0x073f79a8) /* 0.452996882 */, 18 }, +/* 6398 */ { MAD_F(0x073fdcaa) /* 0.453091303 */, 18 }, +/* 6399 */ { MAD_F(0x07403fad) /* 0.453185729 */, 18 }, + +/* 6400 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 18 }, +/* 6401 */ { MAD_F(0x074105b8) /* 0.453374595 */, 18 }, +/* 6402 */ { MAD_F(0x074168bf) /* 0.453469036 */, 18 }, +/* 6403 */ { MAD_F(0x0741cbc8) /* 0.453563482 */, 18 }, +/* 6404 */ { MAD_F(0x07422ed2) /* 0.453657932 */, 18 }, +/* 6405 */ { MAD_F(0x074291dd) /* 0.453752388 */, 18 }, +/* 6406 */ { MAD_F(0x0742f4e9) /* 0.453846848 */, 18 }, +/* 6407 */ { MAD_F(0x074357f7) /* 0.453941314 */, 18 }, +/* 6408 */ { MAD_F(0x0743bb06) /* 0.454035784 */, 18 }, +/* 6409 */ { MAD_F(0x07441e17) /* 0.454130259 */, 18 }, +/* 6410 */ { MAD_F(0x07448129) /* 0.454224739 */, 18 }, +/* 6411 */ { MAD_F(0x0744e43c) /* 0.454319224 */, 18 }, +/* 6412 */ { MAD_F(0x07454750) /* 0.454413714 */, 18 }, +/* 6413 */ { MAD_F(0x0745aa66) /* 0.454508209 */, 18 }, +/* 6414 */ { MAD_F(0x07460d7d) /* 0.454602708 */, 18 }, +/* 6415 */ { MAD_F(0x07467095) /* 0.454697213 */, 18 }, + +/* 6416 */ { MAD_F(0x0746d3af) /* 0.454791723 */, 18 }, +/* 6417 */ { MAD_F(0x074736ca) /* 0.454886237 */, 18 }, +/* 6418 */ { MAD_F(0x074799e7) /* 0.454980756 */, 18 }, +/* 6419 */ { MAD_F(0x0747fd04) /* 0.455075281 */, 18 }, +/* 6420 */ { MAD_F(0x07486023) /* 0.455169810 */, 18 }, +/* 6421 */ { MAD_F(0x0748c344) /* 0.455264344 */, 18 }, +/* 6422 */ { MAD_F(0x07492665) /* 0.455358883 */, 18 }, +/* 6423 */ { MAD_F(0x07498988) /* 0.455453427 */, 18 }, +/* 6424 */ { MAD_F(0x0749ecac) /* 0.455547976 */, 18 }, +/* 6425 */ { MAD_F(0x074a4fd2) /* 0.455642529 */, 18 }, +/* 6426 */ { MAD_F(0x074ab2f9) /* 0.455737088 */, 18 }, +/* 6427 */ { MAD_F(0x074b1621) /* 0.455831652 */, 18 }, +/* 6428 */ { MAD_F(0x074b794b) /* 0.455926220 */, 18 }, +/* 6429 */ { MAD_F(0x074bdc75) /* 0.456020793 */, 18 }, +/* 6430 */ { MAD_F(0x074c3fa1) /* 0.456115372 */, 18 }, +/* 6431 */ { MAD_F(0x074ca2cf) /* 0.456209955 */, 18 }, + +/* 6432 */ { MAD_F(0x074d05fe) /* 0.456304543 */, 18 }, +/* 6433 */ { MAD_F(0x074d692e) /* 0.456399136 */, 18 }, +/* 6434 */ { MAD_F(0x074dcc5f) /* 0.456493733 */, 18 }, +/* 6435 */ { MAD_F(0x074e2f92) /* 0.456588336 */, 18 }, +/* 6436 */ { MAD_F(0x074e92c6) /* 0.456682944 */, 18 }, +/* 6437 */ { MAD_F(0x074ef5fb) /* 0.456777556 */, 18 }, +/* 6438 */ { MAD_F(0x074f5932) /* 0.456872174 */, 18 }, +/* 6439 */ { MAD_F(0x074fbc6a) /* 0.456966796 */, 18 }, +/* 6440 */ { MAD_F(0x07501fa3) /* 0.457061423 */, 18 }, +/* 6441 */ { MAD_F(0x075082de) /* 0.457156056 */, 18 }, +/* 6442 */ { MAD_F(0x0750e61a) /* 0.457250693 */, 18 }, +/* 6443 */ { MAD_F(0x07514957) /* 0.457345335 */, 18 }, +/* 6444 */ { MAD_F(0x0751ac96) /* 0.457439981 */, 18 }, +/* 6445 */ { MAD_F(0x07520fd6) /* 0.457534633 */, 18 }, +/* 6446 */ { MAD_F(0x07527317) /* 0.457629290 */, 18 }, +/* 6447 */ { MAD_F(0x0752d659) /* 0.457723951 */, 18 }, + +/* 6448 */ { MAD_F(0x0753399d) /* 0.457818618 */, 18 }, +/* 6449 */ { MAD_F(0x07539ce2) /* 0.457913289 */, 18 }, +/* 6450 */ { MAD_F(0x07540029) /* 0.458007965 */, 18 }, +/* 6451 */ { MAD_F(0x07546371) /* 0.458102646 */, 18 }, +/* 6452 */ { MAD_F(0x0754c6ba) /* 0.458197332 */, 18 }, +/* 6453 */ { MAD_F(0x07552a04) /* 0.458292023 */, 18 }, +/* 6454 */ { MAD_F(0x07558d50) /* 0.458386719 */, 18 }, +/* 6455 */ { MAD_F(0x0755f09d) /* 0.458481420 */, 18 }, +/* 6456 */ { MAD_F(0x075653eb) /* 0.458576125 */, 18 }, +/* 6457 */ { MAD_F(0x0756b73b) /* 0.458670836 */, 18 }, +/* 6458 */ { MAD_F(0x07571a8c) /* 0.458765551 */, 18 }, +/* 6459 */ { MAD_F(0x07577dde) /* 0.458860271 */, 18 }, +/* 6460 */ { MAD_F(0x0757e131) /* 0.458954996 */, 18 }, +/* 6461 */ { MAD_F(0x07584486) /* 0.459049726 */, 18 }, +/* 6462 */ { MAD_F(0x0758a7dd) /* 0.459144461 */, 18 }, +/* 6463 */ { MAD_F(0x07590b34) /* 0.459239201 */, 18 }, + +/* 6464 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 18 }, +/* 6465 */ { MAD_F(0x0759d1e7) /* 0.459428695 */, 18 }, +/* 6466 */ { MAD_F(0x075a3542) /* 0.459523450 */, 18 }, +/* 6467 */ { MAD_F(0x075a989f) /* 0.459618209 */, 18 }, +/* 6468 */ { MAD_F(0x075afbfd) /* 0.459712973 */, 18 }, +/* 6469 */ { MAD_F(0x075b5f5d) /* 0.459807742 */, 18 }, +/* 6470 */ { MAD_F(0x075bc2bd) /* 0.459902516 */, 18 }, +/* 6471 */ { MAD_F(0x075c261f) /* 0.459997295 */, 18 }, +/* 6472 */ { MAD_F(0x075c8983) /* 0.460092079 */, 18 }, +/* 6473 */ { MAD_F(0x075cece7) /* 0.460186867 */, 18 }, +/* 6474 */ { MAD_F(0x075d504d) /* 0.460281661 */, 18 }, +/* 6475 */ { MAD_F(0x075db3b5) /* 0.460376459 */, 18 }, +/* 6476 */ { MAD_F(0x075e171d) /* 0.460471262 */, 18 }, +/* 6477 */ { MAD_F(0x075e7a87) /* 0.460566071 */, 18 }, +/* 6478 */ { MAD_F(0x075eddf2) /* 0.460660884 */, 18 }, +/* 6479 */ { MAD_F(0x075f415f) /* 0.460755701 */, 18 }, + +/* 6480 */ { MAD_F(0x075fa4cc) /* 0.460850524 */, 18 }, +/* 6481 */ { MAD_F(0x0760083b) /* 0.460945352 */, 18 }, +/* 6482 */ { MAD_F(0x07606bac) /* 0.461040184 */, 18 }, +/* 6483 */ { MAD_F(0x0760cf1e) /* 0.461135022 */, 18 }, +/* 6484 */ { MAD_F(0x07613291) /* 0.461229864 */, 18 }, +/* 6485 */ { MAD_F(0x07619605) /* 0.461324711 */, 18 }, +/* 6486 */ { MAD_F(0x0761f97b) /* 0.461419563 */, 18 }, +/* 6487 */ { MAD_F(0x07625cf2) /* 0.461514420 */, 18 }, +/* 6488 */ { MAD_F(0x0762c06a) /* 0.461609282 */, 18 }, +/* 6489 */ { MAD_F(0x076323e3) /* 0.461704149 */, 18 }, +/* 6490 */ { MAD_F(0x0763875e) /* 0.461799020 */, 18 }, +/* 6491 */ { MAD_F(0x0763eadb) /* 0.461893897 */, 18 }, +/* 6492 */ { MAD_F(0x07644e58) /* 0.461988778 */, 18 }, +/* 6493 */ { MAD_F(0x0764b1d7) /* 0.462083664 */, 18 }, +/* 6494 */ { MAD_F(0x07651557) /* 0.462178555 */, 18 }, +/* 6495 */ { MAD_F(0x076578d8) /* 0.462273451 */, 18 }, + +/* 6496 */ { MAD_F(0x0765dc5b) /* 0.462368352 */, 18 }, +/* 6497 */ { MAD_F(0x07663fdf) /* 0.462463257 */, 18 }, +/* 6498 */ { MAD_F(0x0766a364) /* 0.462558168 */, 18 }, +/* 6499 */ { MAD_F(0x076706eb) /* 0.462653083 */, 18 }, +/* 6500 */ { MAD_F(0x07676a73) /* 0.462748003 */, 18 }, +/* 6501 */ { MAD_F(0x0767cdfc) /* 0.462842928 */, 18 }, +/* 6502 */ { MAD_F(0x07683187) /* 0.462937858 */, 18 }, +/* 6503 */ { MAD_F(0x07689513) /* 0.463032793 */, 18 }, +/* 6504 */ { MAD_F(0x0768f8a0) /* 0.463127733 */, 18 }, +/* 6505 */ { MAD_F(0x07695c2e) /* 0.463222678 */, 18 }, +/* 6506 */ { MAD_F(0x0769bfbe) /* 0.463317627 */, 18 }, +/* 6507 */ { MAD_F(0x076a234f) /* 0.463412581 */, 18 }, +/* 6508 */ { MAD_F(0x076a86e2) /* 0.463507540 */, 18 }, +/* 6509 */ { MAD_F(0x076aea75) /* 0.463602504 */, 18 }, +/* 6510 */ { MAD_F(0x076b4e0a) /* 0.463697473 */, 18 }, +/* 6511 */ { MAD_F(0x076bb1a1) /* 0.463792447 */, 18 }, + +/* 6512 */ { MAD_F(0x076c1538) /* 0.463887426 */, 18 }, +/* 6513 */ { MAD_F(0x076c78d1) /* 0.463982409 */, 18 }, +/* 6514 */ { MAD_F(0x076cdc6c) /* 0.464077398 */, 18 }, +/* 6515 */ { MAD_F(0x076d4007) /* 0.464172391 */, 18 }, +/* 6516 */ { MAD_F(0x076da3a4) /* 0.464267389 */, 18 }, +/* 6517 */ { MAD_F(0x076e0742) /* 0.464362392 */, 18 }, +/* 6518 */ { MAD_F(0x076e6ae2) /* 0.464457399 */, 18 }, +/* 6519 */ { MAD_F(0x076ece82) /* 0.464552412 */, 18 }, +/* 6520 */ { MAD_F(0x076f3224) /* 0.464647430 */, 18 }, +/* 6521 */ { MAD_F(0x076f95c8) /* 0.464742452 */, 18 }, +/* 6522 */ { MAD_F(0x076ff96c) /* 0.464837479 */, 18 }, +/* 6523 */ { MAD_F(0x07705d12) /* 0.464932511 */, 18 }, +/* 6524 */ { MAD_F(0x0770c0ba) /* 0.465027548 */, 18 }, +/* 6525 */ { MAD_F(0x07712462) /* 0.465122590 */, 18 }, +/* 6526 */ { MAD_F(0x0771880c) /* 0.465217637 */, 18 }, +/* 6527 */ { MAD_F(0x0771ebb7) /* 0.465312688 */, 18 }, + +/* 6528 */ { MAD_F(0x07724f64) /* 0.465407744 */, 18 }, +/* 6529 */ { MAD_F(0x0772b312) /* 0.465502806 */, 18 }, +/* 6530 */ { MAD_F(0x077316c1) /* 0.465597872 */, 18 }, +/* 6531 */ { MAD_F(0x07737a71) /* 0.465692943 */, 18 }, +/* 6532 */ { MAD_F(0x0773de23) /* 0.465788018 */, 18 }, +/* 6533 */ { MAD_F(0x077441d6) /* 0.465883099 */, 18 }, +/* 6534 */ { MAD_F(0x0774a58a) /* 0.465978184 */, 18 }, +/* 6535 */ { MAD_F(0x07750940) /* 0.466073275 */, 18 }, +/* 6536 */ { MAD_F(0x07756cf7) /* 0.466168370 */, 18 }, +/* 6537 */ { MAD_F(0x0775d0af) /* 0.466263470 */, 18 }, +/* 6538 */ { MAD_F(0x07763468) /* 0.466358575 */, 18 }, +/* 6539 */ { MAD_F(0x07769823) /* 0.466453684 */, 18 }, +/* 6540 */ { MAD_F(0x0776fbdf) /* 0.466548799 */, 18 }, +/* 6541 */ { MAD_F(0x07775f9d) /* 0.466643918 */, 18 }, +/* 6542 */ { MAD_F(0x0777c35c) /* 0.466739043 */, 18 }, +/* 6543 */ { MAD_F(0x0778271c) /* 0.466834172 */, 18 }, + +/* 6544 */ { MAD_F(0x07788add) /* 0.466929306 */, 18 }, +/* 6545 */ { MAD_F(0x0778ee9f) /* 0.467024445 */, 18 }, +/* 6546 */ { MAD_F(0x07795263) /* 0.467119588 */, 18 }, +/* 6547 */ { MAD_F(0x0779b629) /* 0.467214737 */, 18 }, +/* 6548 */ { MAD_F(0x077a19ef) /* 0.467309890 */, 18 }, +/* 6549 */ { MAD_F(0x077a7db7) /* 0.467405048 */, 18 }, +/* 6550 */ { MAD_F(0x077ae180) /* 0.467500211 */, 18 }, +/* 6551 */ { MAD_F(0x077b454b) /* 0.467595379 */, 18 }, +/* 6552 */ { MAD_F(0x077ba916) /* 0.467690552 */, 18 }, +/* 6553 */ { MAD_F(0x077c0ce3) /* 0.467785729 */, 18 }, +/* 6554 */ { MAD_F(0x077c70b2) /* 0.467880912 */, 18 }, +/* 6555 */ { MAD_F(0x077cd481) /* 0.467976099 */, 18 }, +/* 6556 */ { MAD_F(0x077d3852) /* 0.468071291 */, 18 }, +/* 6557 */ { MAD_F(0x077d9c24) /* 0.468166488 */, 18 }, +/* 6558 */ { MAD_F(0x077dfff8) /* 0.468261690 */, 18 }, +/* 6559 */ { MAD_F(0x077e63cd) /* 0.468356896 */, 18 }, + +/* 6560 */ { MAD_F(0x077ec7a3) /* 0.468452108 */, 18 }, +/* 6561 */ { MAD_F(0x077f2b7a) /* 0.468547324 */, 18 }, +/* 6562 */ { MAD_F(0x077f8f53) /* 0.468642545 */, 18 }, +/* 6563 */ { MAD_F(0x077ff32d) /* 0.468737771 */, 18 }, +/* 6564 */ { MAD_F(0x07805708) /* 0.468833002 */, 18 }, +/* 6565 */ { MAD_F(0x0780bae5) /* 0.468928237 */, 18 }, +/* 6566 */ { MAD_F(0x07811ec3) /* 0.469023478 */, 18 }, +/* 6567 */ { MAD_F(0x078182a2) /* 0.469118723 */, 18 }, +/* 6568 */ { MAD_F(0x0781e683) /* 0.469213973 */, 18 }, +/* 6569 */ { MAD_F(0x07824a64) /* 0.469309228 */, 18 }, +/* 6570 */ { MAD_F(0x0782ae47) /* 0.469404488 */, 18 }, +/* 6571 */ { MAD_F(0x0783122c) /* 0.469499752 */, 18 }, +/* 6572 */ { MAD_F(0x07837612) /* 0.469595022 */, 18 }, +/* 6573 */ { MAD_F(0x0783d9f9) /* 0.469690296 */, 18 }, +/* 6574 */ { MAD_F(0x07843de1) /* 0.469785575 */, 18 }, +/* 6575 */ { MAD_F(0x0784a1ca) /* 0.469880859 */, 18 }, + +/* 6576 */ { MAD_F(0x078505b5) /* 0.469976148 */, 18 }, +/* 6577 */ { MAD_F(0x078569a2) /* 0.470071442 */, 18 }, +/* 6578 */ { MAD_F(0x0785cd8f) /* 0.470166740 */, 18 }, +/* 6579 */ { MAD_F(0x0786317e) /* 0.470262043 */, 18 }, +/* 6580 */ { MAD_F(0x0786956e) /* 0.470357351 */, 18 }, +/* 6581 */ { MAD_F(0x0786f95f) /* 0.470452664 */, 18 }, +/* 6582 */ { MAD_F(0x07875d52) /* 0.470547982 */, 18 }, +/* 6583 */ { MAD_F(0x0787c146) /* 0.470643305 */, 18 }, +/* 6584 */ { MAD_F(0x0788253b) /* 0.470738632 */, 18 }, +/* 6585 */ { MAD_F(0x07888932) /* 0.470833964 */, 18 }, +/* 6586 */ { MAD_F(0x0788ed2a) /* 0.470929301 */, 18 }, +/* 6587 */ { MAD_F(0x07895123) /* 0.471024643 */, 18 }, +/* 6588 */ { MAD_F(0x0789b51d) /* 0.471119990 */, 18 }, +/* 6589 */ { MAD_F(0x078a1919) /* 0.471215341 */, 18 }, +/* 6590 */ { MAD_F(0x078a7d16) /* 0.471310698 */, 18 }, +/* 6591 */ { MAD_F(0x078ae114) /* 0.471406059 */, 18 }, + +/* 6592 */ { MAD_F(0x078b4514) /* 0.471501425 */, 18 }, +/* 6593 */ { MAD_F(0x078ba915) /* 0.471596796 */, 18 }, +/* 6594 */ { MAD_F(0x078c0d17) /* 0.471692171 */, 18 }, +/* 6595 */ { MAD_F(0x078c711a) /* 0.471787552 */, 18 }, +/* 6596 */ { MAD_F(0x078cd51f) /* 0.471882937 */, 18 }, +/* 6597 */ { MAD_F(0x078d3925) /* 0.471978327 */, 18 }, +/* 6598 */ { MAD_F(0x078d9d2d) /* 0.472073722 */, 18 }, +/* 6599 */ { MAD_F(0x078e0135) /* 0.472169122 */, 18 }, +/* 6600 */ { MAD_F(0x078e653f) /* 0.472264527 */, 18 }, +/* 6601 */ { MAD_F(0x078ec94b) /* 0.472359936 */, 18 }, +/* 6602 */ { MAD_F(0x078f2d57) /* 0.472455350 */, 18 }, +/* 6603 */ { MAD_F(0x078f9165) /* 0.472550769 */, 18 }, +/* 6604 */ { MAD_F(0x078ff574) /* 0.472646193 */, 18 }, +/* 6605 */ { MAD_F(0x07905985) /* 0.472741622 */, 18 }, +/* 6606 */ { MAD_F(0x0790bd96) /* 0.472837055 */, 18 }, +/* 6607 */ { MAD_F(0x079121a9) /* 0.472932493 */, 18 }, + +/* 6608 */ { MAD_F(0x079185be) /* 0.473027937 */, 18 }, +/* 6609 */ { MAD_F(0x0791e9d3) /* 0.473123384 */, 18 }, +/* 6610 */ { MAD_F(0x07924dea) /* 0.473218837 */, 18 }, +/* 6611 */ { MAD_F(0x0792b202) /* 0.473314295 */, 18 }, +/* 6612 */ { MAD_F(0x0793161c) /* 0.473409757 */, 18 }, +/* 6613 */ { MAD_F(0x07937a37) /* 0.473505224 */, 18 }, +/* 6614 */ { MAD_F(0x0793de53) /* 0.473600696 */, 18 }, +/* 6615 */ { MAD_F(0x07944270) /* 0.473696173 */, 18 }, +/* 6616 */ { MAD_F(0x0794a68f) /* 0.473791655 */, 18 }, +/* 6617 */ { MAD_F(0x07950aaf) /* 0.473887141 */, 18 }, +/* 6618 */ { MAD_F(0x07956ed0) /* 0.473982632 */, 18 }, +/* 6619 */ { MAD_F(0x0795d2f2) /* 0.474078128 */, 18 }, +/* 6620 */ { MAD_F(0x07963716) /* 0.474173629 */, 18 }, +/* 6621 */ { MAD_F(0x07969b3b) /* 0.474269135 */, 18 }, +/* 6622 */ { MAD_F(0x0796ff62) /* 0.474364645 */, 18 }, +/* 6623 */ { MAD_F(0x07976389) /* 0.474460161 */, 18 }, + +/* 6624 */ { MAD_F(0x0797c7b2) /* 0.474555681 */, 18 }, +/* 6625 */ { MAD_F(0x07982bdd) /* 0.474651205 */, 18 }, +/* 6626 */ { MAD_F(0x07989008) /* 0.474746735 */, 18 }, +/* 6627 */ { MAD_F(0x0798f435) /* 0.474842270 */, 18 }, +/* 6628 */ { MAD_F(0x07995863) /* 0.474937809 */, 18 }, +/* 6629 */ { MAD_F(0x0799bc92) /* 0.475033353 */, 18 }, +/* 6630 */ { MAD_F(0x079a20c3) /* 0.475128902 */, 18 }, +/* 6631 */ { MAD_F(0x079a84f5) /* 0.475224456 */, 18 }, +/* 6632 */ { MAD_F(0x079ae929) /* 0.475320014 */, 18 }, +/* 6633 */ { MAD_F(0x079b4d5d) /* 0.475415578 */, 18 }, +/* 6634 */ { MAD_F(0x079bb193) /* 0.475511146 */, 18 }, +/* 6635 */ { MAD_F(0x079c15ca) /* 0.475606719 */, 18 }, +/* 6636 */ { MAD_F(0x079c7a03) /* 0.475702296 */, 18 }, +/* 6637 */ { MAD_F(0x079cde3c) /* 0.475797879 */, 18 }, +/* 6638 */ { MAD_F(0x079d4277) /* 0.475893466 */, 18 }, +/* 6639 */ { MAD_F(0x079da6b4) /* 0.475989058 */, 18 }, + +/* 6640 */ { MAD_F(0x079e0af1) /* 0.476084655 */, 18 }, +/* 6641 */ { MAD_F(0x079e6f30) /* 0.476180257 */, 18 }, +/* 6642 */ { MAD_F(0x079ed370) /* 0.476275863 */, 18 }, +/* 6643 */ { MAD_F(0x079f37b2) /* 0.476371475 */, 18 }, +/* 6644 */ { MAD_F(0x079f9bf5) /* 0.476467091 */, 18 }, +/* 6645 */ { MAD_F(0x07a00039) /* 0.476562712 */, 18 }, +/* 6646 */ { MAD_F(0x07a0647e) /* 0.476658338 */, 18 }, +/* 6647 */ { MAD_F(0x07a0c8c5) /* 0.476753968 */, 18 }, +/* 6648 */ { MAD_F(0x07a12d0c) /* 0.476849603 */, 18 }, +/* 6649 */ { MAD_F(0x07a19156) /* 0.476945243 */, 18 }, +/* 6650 */ { MAD_F(0x07a1f5a0) /* 0.477040888 */, 18 }, +/* 6651 */ { MAD_F(0x07a259ec) /* 0.477136538 */, 18 }, +/* 6652 */ { MAD_F(0x07a2be39) /* 0.477232193 */, 18 }, +/* 6653 */ { MAD_F(0x07a32287) /* 0.477327852 */, 18 }, +/* 6654 */ { MAD_F(0x07a386d7) /* 0.477423516 */, 18 }, +/* 6655 */ { MAD_F(0x07a3eb28) /* 0.477519185 */, 18 }, + +/* 6656 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 18 }, +/* 6657 */ { MAD_F(0x07a4b3ce) /* 0.477710537 */, 18 }, +/* 6658 */ { MAD_F(0x07a51822) /* 0.477806220 */, 18 }, +/* 6659 */ { MAD_F(0x07a57c78) /* 0.477901908 */, 18 }, +/* 6660 */ { MAD_F(0x07a5e0d0) /* 0.477997601 */, 18 }, +/* 6661 */ { MAD_F(0x07a64528) /* 0.478093299 */, 18 }, +/* 6662 */ { MAD_F(0x07a6a982) /* 0.478189001 */, 18 }, +/* 6663 */ { MAD_F(0x07a70ddd) /* 0.478284708 */, 18 }, +/* 6664 */ { MAD_F(0x07a7723a) /* 0.478380420 */, 18 }, +/* 6665 */ { MAD_F(0x07a7d698) /* 0.478476137 */, 18 }, +/* 6666 */ { MAD_F(0x07a83af7) /* 0.478571858 */, 18 }, +/* 6667 */ { MAD_F(0x07a89f57) /* 0.478667585 */, 18 }, +/* 6668 */ { MAD_F(0x07a903b9) /* 0.478763316 */, 18 }, +/* 6669 */ { MAD_F(0x07a9681c) /* 0.478859052 */, 18 }, +/* 6670 */ { MAD_F(0x07a9cc80) /* 0.478954793 */, 18 }, +/* 6671 */ { MAD_F(0x07aa30e5) /* 0.479050538 */, 18 }, + +/* 6672 */ { MAD_F(0x07aa954c) /* 0.479146288 */, 18 }, +/* 6673 */ { MAD_F(0x07aaf9b4) /* 0.479242043 */, 18 }, +/* 6674 */ { MAD_F(0x07ab5e1e) /* 0.479337803 */, 18 }, +/* 6675 */ { MAD_F(0x07abc288) /* 0.479433568 */, 18 }, +/* 6676 */ { MAD_F(0x07ac26f4) /* 0.479529337 */, 18 }, +/* 6677 */ { MAD_F(0x07ac8b61) /* 0.479625111 */, 18 }, +/* 6678 */ { MAD_F(0x07acefd0) /* 0.479720890 */, 18 }, +/* 6679 */ { MAD_F(0x07ad543f) /* 0.479816674 */, 18 }, +/* 6680 */ { MAD_F(0x07adb8b0) /* 0.479912463 */, 18 }, +/* 6681 */ { MAD_F(0x07ae1d23) /* 0.480008256 */, 18 }, +/* 6682 */ { MAD_F(0x07ae8196) /* 0.480104054 */, 18 }, +/* 6683 */ { MAD_F(0x07aee60b) /* 0.480199857 */, 18 }, +/* 6684 */ { MAD_F(0x07af4a81) /* 0.480295664 */, 18 }, +/* 6685 */ { MAD_F(0x07afaef9) /* 0.480391477 */, 18 }, +/* 6686 */ { MAD_F(0x07b01372) /* 0.480487294 */, 18 }, +/* 6687 */ { MAD_F(0x07b077ec) /* 0.480583116 */, 18 }, + +/* 6688 */ { MAD_F(0x07b0dc67) /* 0.480678943 */, 18 }, +/* 6689 */ { MAD_F(0x07b140e4) /* 0.480774774 */, 18 }, +/* 6690 */ { MAD_F(0x07b1a561) /* 0.480870611 */, 18 }, +/* 6691 */ { MAD_F(0x07b209e1) /* 0.480966452 */, 18 }, +/* 6692 */ { MAD_F(0x07b26e61) /* 0.481062298 */, 18 }, +/* 6693 */ { MAD_F(0x07b2d2e3) /* 0.481158148 */, 18 }, +/* 6694 */ { MAD_F(0x07b33766) /* 0.481254004 */, 18 }, +/* 6695 */ { MAD_F(0x07b39bea) /* 0.481349864 */, 18 }, +/* 6696 */ { MAD_F(0x07b4006f) /* 0.481445729 */, 18 }, +/* 6697 */ { MAD_F(0x07b464f6) /* 0.481541598 */, 18 }, +/* 6698 */ { MAD_F(0x07b4c97e) /* 0.481637473 */, 18 }, +/* 6699 */ { MAD_F(0x07b52e08) /* 0.481733352 */, 18 }, +/* 6700 */ { MAD_F(0x07b59292) /* 0.481829236 */, 18 }, +/* 6701 */ { MAD_F(0x07b5f71e) /* 0.481925125 */, 18 }, +/* 6702 */ { MAD_F(0x07b65bac) /* 0.482021019 */, 18 }, +/* 6703 */ { MAD_F(0x07b6c03a) /* 0.482116917 */, 18 }, + +/* 6704 */ { MAD_F(0x07b724ca) /* 0.482212820 */, 18 }, +/* 6705 */ { MAD_F(0x07b7895b) /* 0.482308728 */, 18 }, +/* 6706 */ { MAD_F(0x07b7eded) /* 0.482404640 */, 18 }, +/* 6707 */ { MAD_F(0x07b85281) /* 0.482500558 */, 18 }, +/* 6708 */ { MAD_F(0x07b8b716) /* 0.482596480 */, 18 }, +/* 6709 */ { MAD_F(0x07b91bac) /* 0.482692407 */, 18 }, +/* 6710 */ { MAD_F(0x07b98044) /* 0.482788339 */, 18 }, +/* 6711 */ { MAD_F(0x07b9e4dc) /* 0.482884275 */, 18 }, +/* 6712 */ { MAD_F(0x07ba4976) /* 0.482980216 */, 18 }, +/* 6713 */ { MAD_F(0x07baae12) /* 0.483076162 */, 18 }, +/* 6714 */ { MAD_F(0x07bb12ae) /* 0.483172113 */, 18 }, +/* 6715 */ { MAD_F(0x07bb774c) /* 0.483268069 */, 18 }, +/* 6716 */ { MAD_F(0x07bbdbeb) /* 0.483364029 */, 18 }, +/* 6717 */ { MAD_F(0x07bc408c) /* 0.483459994 */, 18 }, +/* 6718 */ { MAD_F(0x07bca52d) /* 0.483555964 */, 18 }, +/* 6719 */ { MAD_F(0x07bd09d0) /* 0.483651939 */, 18 }, + +/* 6720 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 18 }, +/* 6721 */ { MAD_F(0x07bdd31a) /* 0.483843902 */, 18 }, +/* 6722 */ { MAD_F(0x07be37c1) /* 0.483939891 */, 18 }, +/* 6723 */ { MAD_F(0x07be9c69) /* 0.484035885 */, 18 }, +/* 6724 */ { MAD_F(0x07bf0113) /* 0.484131883 */, 18 }, +/* 6725 */ { MAD_F(0x07bf65bd) /* 0.484227886 */, 18 }, +/* 6726 */ { MAD_F(0x07bfca69) /* 0.484323894 */, 18 }, +/* 6727 */ { MAD_F(0x07c02f16) /* 0.484419907 */, 18 }, +/* 6728 */ { MAD_F(0x07c093c5) /* 0.484515924 */, 18 }, +/* 6729 */ { MAD_F(0x07c0f875) /* 0.484611946 */, 18 }, +/* 6730 */ { MAD_F(0x07c15d26) /* 0.484707973 */, 18 }, +/* 6731 */ { MAD_F(0x07c1c1d8) /* 0.484804005 */, 18 }, +/* 6732 */ { MAD_F(0x07c2268b) /* 0.484900041 */, 18 }, +/* 6733 */ { MAD_F(0x07c28b40) /* 0.484996083 */, 18 }, +/* 6734 */ { MAD_F(0x07c2eff6) /* 0.485092128 */, 18 }, +/* 6735 */ { MAD_F(0x07c354ae) /* 0.485188179 */, 18 }, + +/* 6736 */ { MAD_F(0x07c3b967) /* 0.485284235 */, 18 }, +/* 6737 */ { MAD_F(0x07c41e21) /* 0.485380295 */, 18 }, +/* 6738 */ { MAD_F(0x07c482dc) /* 0.485476360 */, 18 }, +/* 6739 */ { MAD_F(0x07c4e798) /* 0.485572430 */, 18 }, +/* 6740 */ { MAD_F(0x07c54c56) /* 0.485668504 */, 18 }, +/* 6741 */ { MAD_F(0x07c5b115) /* 0.485764583 */, 18 }, +/* 6742 */ { MAD_F(0x07c615d6) /* 0.485860667 */, 18 }, +/* 6743 */ { MAD_F(0x07c67a97) /* 0.485956756 */, 18 }, +/* 6744 */ { MAD_F(0x07c6df5a) /* 0.486052849 */, 18 }, +/* 6745 */ { MAD_F(0x07c7441e) /* 0.486148948 */, 18 }, +/* 6746 */ { MAD_F(0x07c7a8e4) /* 0.486245051 */, 18 }, +/* 6747 */ { MAD_F(0x07c80daa) /* 0.486341158 */, 18 }, +/* 6748 */ { MAD_F(0x07c87272) /* 0.486437271 */, 18 }, +/* 6749 */ { MAD_F(0x07c8d73c) /* 0.486533388 */, 18 }, +/* 6750 */ { MAD_F(0x07c93c06) /* 0.486629510 */, 18 }, +/* 6751 */ { MAD_F(0x07c9a0d2) /* 0.486725637 */, 18 }, + +/* 6752 */ { MAD_F(0x07ca059f) /* 0.486821768 */, 18 }, +/* 6753 */ { MAD_F(0x07ca6a6d) /* 0.486917905 */, 18 }, +/* 6754 */ { MAD_F(0x07cacf3d) /* 0.487014045 */, 18 }, +/* 6755 */ { MAD_F(0x07cb340e) /* 0.487110191 */, 18 }, +/* 6756 */ { MAD_F(0x07cb98e0) /* 0.487206342 */, 18 }, +/* 6757 */ { MAD_F(0x07cbfdb4) /* 0.487302497 */, 18 }, +/* 6758 */ { MAD_F(0x07cc6288) /* 0.487398657 */, 18 }, +/* 6759 */ { MAD_F(0x07ccc75e) /* 0.487494821 */, 18 }, +/* 6760 */ { MAD_F(0x07cd2c36) /* 0.487590991 */, 18 }, +/* 6761 */ { MAD_F(0x07cd910e) /* 0.487687165 */, 18 }, +/* 6762 */ { MAD_F(0x07cdf5e8) /* 0.487783344 */, 18 }, +/* 6763 */ { MAD_F(0x07ce5ac3) /* 0.487879528 */, 18 }, +/* 6764 */ { MAD_F(0x07cebfa0) /* 0.487975716 */, 18 }, +/* 6765 */ { MAD_F(0x07cf247d) /* 0.488071909 */, 18 }, +/* 6766 */ { MAD_F(0x07cf895c) /* 0.488168107 */, 18 }, +/* 6767 */ { MAD_F(0x07cfee3c) /* 0.488264310 */, 18 }, + +/* 6768 */ { MAD_F(0x07d0531e) /* 0.488360517 */, 18 }, +/* 6769 */ { MAD_F(0x07d0b801) /* 0.488456729 */, 18 }, +/* 6770 */ { MAD_F(0x07d11ce5) /* 0.488552946 */, 18 }, +/* 6771 */ { MAD_F(0x07d181ca) /* 0.488649167 */, 18 }, +/* 6772 */ { MAD_F(0x07d1e6b0) /* 0.488745394 */, 18 }, +/* 6773 */ { MAD_F(0x07d24b98) /* 0.488841625 */, 18 }, +/* 6774 */ { MAD_F(0x07d2b081) /* 0.488937860 */, 18 }, +/* 6775 */ { MAD_F(0x07d3156c) /* 0.489034101 */, 18 }, +/* 6776 */ { MAD_F(0x07d37a57) /* 0.489130346 */, 18 }, +/* 6777 */ { MAD_F(0x07d3df44) /* 0.489226596 */, 18 }, +/* 6778 */ { MAD_F(0x07d44432) /* 0.489322851 */, 18 }, +/* 6779 */ { MAD_F(0x07d4a922) /* 0.489419110 */, 18 }, +/* 6780 */ { MAD_F(0x07d50e13) /* 0.489515375 */, 18 }, +/* 6781 */ { MAD_F(0x07d57305) /* 0.489611643 */, 18 }, +/* 6782 */ { MAD_F(0x07d5d7f8) /* 0.489707917 */, 18 }, +/* 6783 */ { MAD_F(0x07d63cec) /* 0.489804195 */, 18 }, + +/* 6784 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 18 }, +/* 6785 */ { MAD_F(0x07d706d9) /* 0.489996766 */, 18 }, +/* 6786 */ { MAD_F(0x07d76bd2) /* 0.490093059 */, 18 }, +/* 6787 */ { MAD_F(0x07d7d0cb) /* 0.490189356 */, 18 }, +/* 6788 */ { MAD_F(0x07d835c6) /* 0.490285658 */, 18 }, +/* 6789 */ { MAD_F(0x07d89ac2) /* 0.490381965 */, 18 }, +/* 6790 */ { MAD_F(0x07d8ffc0) /* 0.490478277 */, 18 }, +/* 6791 */ { MAD_F(0x07d964be) /* 0.490574593 */, 18 }, +/* 6792 */ { MAD_F(0x07d9c9be) /* 0.490670914 */, 18 }, +/* 6793 */ { MAD_F(0x07da2ebf) /* 0.490767239 */, 18 }, +/* 6794 */ { MAD_F(0x07da93c2) /* 0.490863570 */, 18 }, +/* 6795 */ { MAD_F(0x07daf8c6) /* 0.490959905 */, 18 }, +/* 6796 */ { MAD_F(0x07db5dcb) /* 0.491056245 */, 18 }, +/* 6797 */ { MAD_F(0x07dbc2d1) /* 0.491152589 */, 18 }, +/* 6798 */ { MAD_F(0x07dc27d9) /* 0.491248939 */, 18 }, +/* 6799 */ { MAD_F(0x07dc8ce1) /* 0.491345293 */, 18 }, + +/* 6800 */ { MAD_F(0x07dcf1ec) /* 0.491441651 */, 18 }, +/* 6801 */ { MAD_F(0x07dd56f7) /* 0.491538015 */, 18 }, +/* 6802 */ { MAD_F(0x07ddbc04) /* 0.491634383 */, 18 }, +/* 6803 */ { MAD_F(0x07de2111) /* 0.491730756 */, 18 }, +/* 6804 */ { MAD_F(0x07de8621) /* 0.491827134 */, 18 }, +/* 6805 */ { MAD_F(0x07deeb31) /* 0.491923516 */, 18 }, +/* 6806 */ { MAD_F(0x07df5043) /* 0.492019903 */, 18 }, +/* 6807 */ { MAD_F(0x07dfb556) /* 0.492116295 */, 18 }, +/* 6808 */ { MAD_F(0x07e01a6a) /* 0.492212691 */, 18 }, +/* 6809 */ { MAD_F(0x07e07f80) /* 0.492309093 */, 18 }, +/* 6810 */ { MAD_F(0x07e0e496) /* 0.492405499 */, 18 }, +/* 6811 */ { MAD_F(0x07e149ae) /* 0.492501909 */, 18 }, +/* 6812 */ { MAD_F(0x07e1aec8) /* 0.492598325 */, 18 }, +/* 6813 */ { MAD_F(0x07e213e2) /* 0.492694745 */, 18 }, +/* 6814 */ { MAD_F(0x07e278fe) /* 0.492791170 */, 18 }, +/* 6815 */ { MAD_F(0x07e2de1b) /* 0.492887599 */, 18 }, + +/* 6816 */ { MAD_F(0x07e3433a) /* 0.492984033 */, 18 }, +/* 6817 */ { MAD_F(0x07e3a859) /* 0.493080472 */, 18 }, +/* 6818 */ { MAD_F(0x07e40d7a) /* 0.493176916 */, 18 }, +/* 6819 */ { MAD_F(0x07e4729c) /* 0.493273365 */, 18 }, +/* 6820 */ { MAD_F(0x07e4d7c0) /* 0.493369818 */, 18 }, +/* 6821 */ { MAD_F(0x07e53ce4) /* 0.493466275 */, 18 }, +/* 6822 */ { MAD_F(0x07e5a20a) /* 0.493562738 */, 18 }, +/* 6823 */ { MAD_F(0x07e60732) /* 0.493659205 */, 18 }, +/* 6824 */ { MAD_F(0x07e66c5a) /* 0.493755677 */, 18 }, +/* 6825 */ { MAD_F(0x07e6d184) /* 0.493852154 */, 18 }, +/* 6826 */ { MAD_F(0x07e736af) /* 0.493948635 */, 18 }, +/* 6827 */ { MAD_F(0x07e79bdb) /* 0.494045122 */, 18 }, +/* 6828 */ { MAD_F(0x07e80109) /* 0.494141612 */, 18 }, +/* 6829 */ { MAD_F(0x07e86638) /* 0.494238108 */, 18 }, +/* 6830 */ { MAD_F(0x07e8cb68) /* 0.494334608 */, 18 }, +/* 6831 */ { MAD_F(0x07e93099) /* 0.494431113 */, 18 }, + +/* 6832 */ { MAD_F(0x07e995cc) /* 0.494527623 */, 18 }, +/* 6833 */ { MAD_F(0x07e9fb00) /* 0.494624137 */, 18 }, +/* 6834 */ { MAD_F(0x07ea6035) /* 0.494720656 */, 18 }, +/* 6835 */ { MAD_F(0x07eac56b) /* 0.494817180 */, 18 }, +/* 6836 */ { MAD_F(0x07eb2aa3) /* 0.494913709 */, 18 }, +/* 6837 */ { MAD_F(0x07eb8fdc) /* 0.495010242 */, 18 }, +/* 6838 */ { MAD_F(0x07ebf516) /* 0.495106780 */, 18 }, +/* 6839 */ { MAD_F(0x07ec5a51) /* 0.495203322 */, 18 }, +/* 6840 */ { MAD_F(0x07ecbf8e) /* 0.495299870 */, 18 }, +/* 6841 */ { MAD_F(0x07ed24cc) /* 0.495396422 */, 18 }, +/* 6842 */ { MAD_F(0x07ed8a0b) /* 0.495492978 */, 18 }, +/* 6843 */ { MAD_F(0x07edef4c) /* 0.495589540 */, 18 }, +/* 6844 */ { MAD_F(0x07ee548e) /* 0.495686106 */, 18 }, +/* 6845 */ { MAD_F(0x07eeb9d1) /* 0.495782677 */, 18 }, +/* 6846 */ { MAD_F(0x07ef1f15) /* 0.495879252 */, 18 }, +/* 6847 */ { MAD_F(0x07ef845b) /* 0.495975833 */, 18 }, + +/* 6848 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 18 }, +/* 6849 */ { MAD_F(0x07f04ee9) /* 0.496169007 */, 18 }, +/* 6850 */ { MAD_F(0x07f0b433) /* 0.496265602 */, 18 }, +/* 6851 */ { MAD_F(0x07f1197d) /* 0.496362201 */, 18 }, +/* 6852 */ { MAD_F(0x07f17ec9) /* 0.496458804 */, 18 }, +/* 6853 */ { MAD_F(0x07f1e416) /* 0.496555413 */, 18 }, +/* 6854 */ { MAD_F(0x07f24965) /* 0.496652026 */, 18 }, +/* 6855 */ { MAD_F(0x07f2aeb5) /* 0.496748644 */, 18 }, +/* 6856 */ { MAD_F(0x07f31405) /* 0.496845266 */, 18 }, +/* 6857 */ { MAD_F(0x07f37958) /* 0.496941894 */, 18 }, +/* 6858 */ { MAD_F(0x07f3deab) /* 0.497038526 */, 18 }, +/* 6859 */ { MAD_F(0x07f44400) /* 0.497135162 */, 18 }, +/* 6860 */ { MAD_F(0x07f4a956) /* 0.497231804 */, 18 }, +/* 6861 */ { MAD_F(0x07f50ead) /* 0.497328450 */, 18 }, +/* 6862 */ { MAD_F(0x07f57405) /* 0.497425100 */, 18 }, +/* 6863 */ { MAD_F(0x07f5d95f) /* 0.497521756 */, 18 }, + +/* 6864 */ { MAD_F(0x07f63eba) /* 0.497618416 */, 18 }, +/* 6865 */ { MAD_F(0x07f6a416) /* 0.497715081 */, 18 }, +/* 6866 */ { MAD_F(0x07f70974) /* 0.497811750 */, 18 }, +/* 6867 */ { MAD_F(0x07f76ed3) /* 0.497908425 */, 18 }, +/* 6868 */ { MAD_F(0x07f7d433) /* 0.498005103 */, 18 }, +/* 6869 */ { MAD_F(0x07f83994) /* 0.498101787 */, 18 }, +/* 6870 */ { MAD_F(0x07f89ef7) /* 0.498198475 */, 18 }, +/* 6871 */ { MAD_F(0x07f9045a) /* 0.498295168 */, 18 }, +/* 6872 */ { MAD_F(0x07f969c0) /* 0.498391866 */, 18 }, +/* 6873 */ { MAD_F(0x07f9cf26) /* 0.498488568 */, 18 }, +/* 6874 */ { MAD_F(0x07fa348e) /* 0.498585275 */, 18 }, +/* 6875 */ { MAD_F(0x07fa99f6) /* 0.498681987 */, 18 }, +/* 6876 */ { MAD_F(0x07faff60) /* 0.498778704 */, 18 }, +/* 6877 */ { MAD_F(0x07fb64cc) /* 0.498875425 */, 18 }, +/* 6878 */ { MAD_F(0x07fbca38) /* 0.498972150 */, 18 }, +/* 6879 */ { MAD_F(0x07fc2fa6) /* 0.499068881 */, 18 }, + +/* 6880 */ { MAD_F(0x07fc9516) /* 0.499165616 */, 18 }, +/* 6881 */ { MAD_F(0x07fcfa86) /* 0.499262356 */, 18 }, +/* 6882 */ { MAD_F(0x07fd5ff8) /* 0.499359101 */, 18 }, +/* 6883 */ { MAD_F(0x07fdc56b) /* 0.499455850 */, 18 }, +/* 6884 */ { MAD_F(0x07fe2adf) /* 0.499552604 */, 18 }, +/* 6885 */ { MAD_F(0x07fe9054) /* 0.499649362 */, 18 }, +/* 6886 */ { MAD_F(0x07fef5cb) /* 0.499746126 */, 18 }, +/* 6887 */ { MAD_F(0x07ff5b43) /* 0.499842894 */, 18 }, +/* 6888 */ { MAD_F(0x07ffc0bc) /* 0.499939666 */, 18 }, +/* 6889 */ { MAD_F(0x0400131b) /* 0.250018222 */, 19 }, +/* 6890 */ { MAD_F(0x040045d9) /* 0.250066613 */, 19 }, +/* 6891 */ { MAD_F(0x04007897) /* 0.250115006 */, 19 }, +/* 6892 */ { MAD_F(0x0400ab57) /* 0.250163402 */, 19 }, +/* 6893 */ { MAD_F(0x0400de16) /* 0.250211800 */, 19 }, +/* 6894 */ { MAD_F(0x040110d7) /* 0.250260200 */, 19 }, +/* 6895 */ { MAD_F(0x04014398) /* 0.250308603 */, 19 }, + +/* 6896 */ { MAD_F(0x04017659) /* 0.250357008 */, 19 }, +/* 6897 */ { MAD_F(0x0401a91c) /* 0.250405415 */, 19 }, +/* 6898 */ { MAD_F(0x0401dbdf) /* 0.250453825 */, 19 }, +/* 6899 */ { MAD_F(0x04020ea2) /* 0.250502237 */, 19 }, +/* 6900 */ { MAD_F(0x04024166) /* 0.250550652 */, 19 }, +/* 6901 */ { MAD_F(0x0402742b) /* 0.250599068 */, 19 }, +/* 6902 */ { MAD_F(0x0402a6f0) /* 0.250647488 */, 19 }, +/* 6903 */ { MAD_F(0x0402d9b6) /* 0.250695909 */, 19 }, +/* 6904 */ { MAD_F(0x04030c7d) /* 0.250744333 */, 19 }, +/* 6905 */ { MAD_F(0x04033f44) /* 0.250792759 */, 19 }, +/* 6906 */ { MAD_F(0x0403720c) /* 0.250841187 */, 19 }, +/* 6907 */ { MAD_F(0x0403a4d5) /* 0.250889618 */, 19 }, +/* 6908 */ { MAD_F(0x0403d79e) /* 0.250938051 */, 19 }, +/* 6909 */ { MAD_F(0x04040a68) /* 0.250986487 */, 19 }, +/* 6910 */ { MAD_F(0x04043d32) /* 0.251034924 */, 19 }, +/* 6911 */ { MAD_F(0x04046ffd) /* 0.251083365 */, 19 }, + +/* 6912 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 19 }, +/* 6913 */ { MAD_F(0x0404d595) /* 0.251180252 */, 19 }, +/* 6914 */ { MAD_F(0x04050862) /* 0.251228699 */, 19 }, +/* 6915 */ { MAD_F(0x04053b30) /* 0.251277148 */, 19 }, +/* 6916 */ { MAD_F(0x04056dfe) /* 0.251325600 */, 19 }, +/* 6917 */ { MAD_F(0x0405a0cd) /* 0.251374054 */, 19 }, +/* 6918 */ { MAD_F(0x0405d39c) /* 0.251422511 */, 19 }, +/* 6919 */ { MAD_F(0x0406066c) /* 0.251470970 */, 19 }, +/* 6920 */ { MAD_F(0x0406393d) /* 0.251519431 */, 19 }, +/* 6921 */ { MAD_F(0x04066c0e) /* 0.251567894 */, 19 }, +/* 6922 */ { MAD_F(0x04069ee0) /* 0.251616360 */, 19 }, +/* 6923 */ { MAD_F(0x0406d1b3) /* 0.251664828 */, 19 }, +/* 6924 */ { MAD_F(0x04070486) /* 0.251713299 */, 19 }, +/* 6925 */ { MAD_F(0x0407375a) /* 0.251761772 */, 19 }, +/* 6926 */ { MAD_F(0x04076a2e) /* 0.251810247 */, 19 }, +/* 6927 */ { MAD_F(0x04079d03) /* 0.251858724 */, 19 }, + +/* 6928 */ { MAD_F(0x0407cfd9) /* 0.251907204 */, 19 }, +/* 6929 */ { MAD_F(0x040802af) /* 0.251955686 */, 19 }, +/* 6930 */ { MAD_F(0x04083586) /* 0.252004171 */, 19 }, +/* 6931 */ { MAD_F(0x0408685e) /* 0.252052658 */, 19 }, +/* 6932 */ { MAD_F(0x04089b36) /* 0.252101147 */, 19 }, +/* 6933 */ { MAD_F(0x0408ce0f) /* 0.252149638 */, 19 }, +/* 6934 */ { MAD_F(0x040900e8) /* 0.252198132 */, 19 }, +/* 6935 */ { MAD_F(0x040933c2) /* 0.252246628 */, 19 }, +/* 6936 */ { MAD_F(0x0409669d) /* 0.252295127 */, 19 }, +/* 6937 */ { MAD_F(0x04099978) /* 0.252343627 */, 19 }, +/* 6938 */ { MAD_F(0x0409cc54) /* 0.252392131 */, 19 }, +/* 6939 */ { MAD_F(0x0409ff31) /* 0.252440636 */, 19 }, +/* 6940 */ { MAD_F(0x040a320e) /* 0.252489144 */, 19 }, +/* 6941 */ { MAD_F(0x040a64ec) /* 0.252537654 */, 19 }, +/* 6942 */ { MAD_F(0x040a97cb) /* 0.252586166 */, 19 }, +/* 6943 */ { MAD_F(0x040acaaa) /* 0.252634681 */, 19 }, + +/* 6944 */ { MAD_F(0x040afd89) /* 0.252683198 */, 19 }, +/* 6945 */ { MAD_F(0x040b306a) /* 0.252731718 */, 19 }, +/* 6946 */ { MAD_F(0x040b634b) /* 0.252780240 */, 19 }, +/* 6947 */ { MAD_F(0x040b962c) /* 0.252828764 */, 19 }, +/* 6948 */ { MAD_F(0x040bc90e) /* 0.252877290 */, 19 }, +/* 6949 */ { MAD_F(0x040bfbf1) /* 0.252925819 */, 19 }, +/* 6950 */ { MAD_F(0x040c2ed5) /* 0.252974350 */, 19 }, +/* 6951 */ { MAD_F(0x040c61b9) /* 0.253022883 */, 19 }, +/* 6952 */ { MAD_F(0x040c949e) /* 0.253071419 */, 19 }, +/* 6953 */ { MAD_F(0x040cc783) /* 0.253119957 */, 19 }, +/* 6954 */ { MAD_F(0x040cfa69) /* 0.253168498 */, 19 }, +/* 6955 */ { MAD_F(0x040d2d4f) /* 0.253217040 */, 19 }, +/* 6956 */ { MAD_F(0x040d6037) /* 0.253265585 */, 19 }, +/* 6957 */ { MAD_F(0x040d931e) /* 0.253314133 */, 19 }, +/* 6958 */ { MAD_F(0x040dc607) /* 0.253362682 */, 19 }, +/* 6959 */ { MAD_F(0x040df8f0) /* 0.253411234 */, 19 }, + +/* 6960 */ { MAD_F(0x040e2bda) /* 0.253459789 */, 19 }, +/* 6961 */ { MAD_F(0x040e5ec4) /* 0.253508345 */, 19 }, +/* 6962 */ { MAD_F(0x040e91af) /* 0.253556904 */, 19 }, +/* 6963 */ { MAD_F(0x040ec49b) /* 0.253605466 */, 19 }, +/* 6964 */ { MAD_F(0x040ef787) /* 0.253654029 */, 19 }, +/* 6965 */ { MAD_F(0x040f2a74) /* 0.253702595 */, 19 }, +/* 6966 */ { MAD_F(0x040f5d61) /* 0.253751164 */, 19 }, +/* 6967 */ { MAD_F(0x040f904f) /* 0.253799734 */, 19 }, +/* 6968 */ { MAD_F(0x040fc33e) /* 0.253848307 */, 19 }, +/* 6969 */ { MAD_F(0x040ff62d) /* 0.253896883 */, 19 }, +/* 6970 */ { MAD_F(0x0410291d) /* 0.253945460 */, 19 }, +/* 6971 */ { MAD_F(0x04105c0e) /* 0.253994040 */, 19 }, +/* 6972 */ { MAD_F(0x04108eff) /* 0.254042622 */, 19 }, +/* 6973 */ { MAD_F(0x0410c1f1) /* 0.254091207 */, 19 }, +/* 6974 */ { MAD_F(0x0410f4e3) /* 0.254139794 */, 19 }, +/* 6975 */ { MAD_F(0x041127d6) /* 0.254188383 */, 19 }, + +/* 6976 */ { MAD_F(0x04115aca) /* 0.254236974 */, 19 }, +/* 6977 */ { MAD_F(0x04118dbe) /* 0.254285568 */, 19 }, +/* 6978 */ { MAD_F(0x0411c0b3) /* 0.254334165 */, 19 }, +/* 6979 */ { MAD_F(0x0411f3a9) /* 0.254382763 */, 19 }, +/* 6980 */ { MAD_F(0x0412269f) /* 0.254431364 */, 19 }, +/* 6981 */ { MAD_F(0x04125996) /* 0.254479967 */, 19 }, +/* 6982 */ { MAD_F(0x04128c8d) /* 0.254528572 */, 19 }, +/* 6983 */ { MAD_F(0x0412bf85) /* 0.254577180 */, 19 }, +/* 6984 */ { MAD_F(0x0412f27e) /* 0.254625790 */, 19 }, +/* 6985 */ { MAD_F(0x04132577) /* 0.254674403 */, 19 }, +/* 6986 */ { MAD_F(0x04135871) /* 0.254723017 */, 19 }, +/* 6987 */ { MAD_F(0x04138b6c) /* 0.254771635 */, 19 }, +/* 6988 */ { MAD_F(0x0413be67) /* 0.254820254 */, 19 }, +/* 6989 */ { MAD_F(0x0413f163) /* 0.254868876 */, 19 }, +/* 6990 */ { MAD_F(0x0414245f) /* 0.254917500 */, 19 }, +/* 6991 */ { MAD_F(0x0414575c) /* 0.254966126 */, 19 }, + +/* 6992 */ { MAD_F(0x04148a5a) /* 0.255014755 */, 19 }, +/* 6993 */ { MAD_F(0x0414bd58) /* 0.255063386 */, 19 }, +/* 6994 */ { MAD_F(0x0414f057) /* 0.255112019 */, 19 }, +/* 6995 */ { MAD_F(0x04152356) /* 0.255160655 */, 19 }, +/* 6996 */ { MAD_F(0x04155657) /* 0.255209292 */, 19 }, +/* 6997 */ { MAD_F(0x04158957) /* 0.255257933 */, 19 }, +/* 6998 */ { MAD_F(0x0415bc59) /* 0.255306575 */, 19 }, +/* 6999 */ { MAD_F(0x0415ef5b) /* 0.255355220 */, 19 }, +/* 7000 */ { MAD_F(0x0416225d) /* 0.255403867 */, 19 }, +/* 7001 */ { MAD_F(0x04165561) /* 0.255452517 */, 19 }, +/* 7002 */ { MAD_F(0x04168864) /* 0.255501169 */, 19 }, +/* 7003 */ { MAD_F(0x0416bb69) /* 0.255549823 */, 19 }, +/* 7004 */ { MAD_F(0x0416ee6e) /* 0.255598479 */, 19 }, +/* 7005 */ { MAD_F(0x04172174) /* 0.255647138 */, 19 }, +/* 7006 */ { MAD_F(0x0417547a) /* 0.255695799 */, 19 }, +/* 7007 */ { MAD_F(0x04178781) /* 0.255744463 */, 19 }, + +/* 7008 */ { MAD_F(0x0417ba89) /* 0.255793128 */, 19 }, +/* 7009 */ { MAD_F(0x0417ed91) /* 0.255841796 */, 19 }, +/* 7010 */ { MAD_F(0x0418209a) /* 0.255890467 */, 19 }, +/* 7011 */ { MAD_F(0x041853a3) /* 0.255939139 */, 19 }, +/* 7012 */ { MAD_F(0x041886ad) /* 0.255987814 */, 19 }, +/* 7013 */ { MAD_F(0x0418b9b8) /* 0.256036492 */, 19 }, +/* 7014 */ { MAD_F(0x0418ecc3) /* 0.256085171 */, 19 }, +/* 7015 */ { MAD_F(0x04191fcf) /* 0.256133853 */, 19 }, +/* 7016 */ { MAD_F(0x041952dc) /* 0.256182537 */, 19 }, +/* 7017 */ { MAD_F(0x041985e9) /* 0.256231224 */, 19 }, +/* 7018 */ { MAD_F(0x0419b8f7) /* 0.256279913 */, 19 }, +/* 7019 */ { MAD_F(0x0419ec05) /* 0.256328604 */, 19 }, +/* 7020 */ { MAD_F(0x041a1f15) /* 0.256377297 */, 19 }, +/* 7021 */ { MAD_F(0x041a5224) /* 0.256425993 */, 19 }, +/* 7022 */ { MAD_F(0x041a8534) /* 0.256474691 */, 19 }, +/* 7023 */ { MAD_F(0x041ab845) /* 0.256523392 */, 19 }, + +/* 7024 */ { MAD_F(0x041aeb57) /* 0.256572095 */, 19 }, +/* 7025 */ { MAD_F(0x041b1e69) /* 0.256620800 */, 19 }, +/* 7026 */ { MAD_F(0x041b517c) /* 0.256669507 */, 19 }, +/* 7027 */ { MAD_F(0x041b848f) /* 0.256718217 */, 19 }, +/* 7028 */ { MAD_F(0x041bb7a3) /* 0.256766929 */, 19 }, +/* 7029 */ { MAD_F(0x041beab8) /* 0.256815643 */, 19 }, +/* 7030 */ { MAD_F(0x041c1dcd) /* 0.256864359 */, 19 }, +/* 7031 */ { MAD_F(0x041c50e3) /* 0.256913078 */, 19 }, +/* 7032 */ { MAD_F(0x041c83fa) /* 0.256961800 */, 19 }, +/* 7033 */ { MAD_F(0x041cb711) /* 0.257010523 */, 19 }, +/* 7034 */ { MAD_F(0x041cea28) /* 0.257059249 */, 19 }, +/* 7035 */ { MAD_F(0x041d1d41) /* 0.257107977 */, 19 }, +/* 7036 */ { MAD_F(0x041d505a) /* 0.257156708 */, 19 }, +/* 7037 */ { MAD_F(0x041d8373) /* 0.257205440 */, 19 }, +/* 7038 */ { MAD_F(0x041db68e) /* 0.257254175 */, 19 }, +/* 7039 */ { MAD_F(0x041de9a8) /* 0.257302913 */, 19 }, + +/* 7040 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 19 }, +/* 7041 */ { MAD_F(0x041e4fe0) /* 0.257400394 */, 19 }, +/* 7042 */ { MAD_F(0x041e82fd) /* 0.257449139 */, 19 }, +/* 7043 */ { MAD_F(0x041eb61a) /* 0.257497885 */, 19 }, +/* 7044 */ { MAD_F(0x041ee938) /* 0.257546634 */, 19 }, +/* 7045 */ { MAD_F(0x041f1c57) /* 0.257595386 */, 19 }, +/* 7046 */ { MAD_F(0x041f4f76) /* 0.257644139 */, 19 }, +/* 7047 */ { MAD_F(0x041f8296) /* 0.257692895 */, 19 }, +/* 7048 */ { MAD_F(0x041fb5b6) /* 0.257741653 */, 19 }, +/* 7049 */ { MAD_F(0x041fe8d7) /* 0.257790414 */, 19 }, +/* 7050 */ { MAD_F(0x04201bf9) /* 0.257839176 */, 19 }, +/* 7051 */ { MAD_F(0x04204f1b) /* 0.257887941 */, 19 }, +/* 7052 */ { MAD_F(0x0420823e) /* 0.257936709 */, 19 }, +/* 7053 */ { MAD_F(0x0420b561) /* 0.257985478 */, 19 }, +/* 7054 */ { MAD_F(0x0420e885) /* 0.258034250 */, 19 }, +/* 7055 */ { MAD_F(0x04211baa) /* 0.258083025 */, 19 }, + +/* 7056 */ { MAD_F(0x04214ed0) /* 0.258131801 */, 19 }, +/* 7057 */ { MAD_F(0x042181f6) /* 0.258180580 */, 19 }, +/* 7058 */ { MAD_F(0x0421b51c) /* 0.258229361 */, 19 }, +/* 7059 */ { MAD_F(0x0421e843) /* 0.258278145 */, 19 }, +/* 7060 */ { MAD_F(0x04221b6b) /* 0.258326931 */, 19 }, +/* 7061 */ { MAD_F(0x04224e94) /* 0.258375719 */, 19 }, +/* 7062 */ { MAD_F(0x042281bd) /* 0.258424509 */, 19 }, +/* 7063 */ { MAD_F(0x0422b4e6) /* 0.258473302 */, 19 }, +/* 7064 */ { MAD_F(0x0422e811) /* 0.258522097 */, 19 }, +/* 7065 */ { MAD_F(0x04231b3c) /* 0.258570894 */, 19 }, +/* 7066 */ { MAD_F(0x04234e67) /* 0.258619694 */, 19 }, +/* 7067 */ { MAD_F(0x04238193) /* 0.258668496 */, 19 }, +/* 7068 */ { MAD_F(0x0423b4c0) /* 0.258717300 */, 19 }, +/* 7069 */ { MAD_F(0x0423e7ee) /* 0.258766106 */, 19 }, +/* 7070 */ { MAD_F(0x04241b1c) /* 0.258814915 */, 19 }, +/* 7071 */ { MAD_F(0x04244e4a) /* 0.258863726 */, 19 }, + +/* 7072 */ { MAD_F(0x04248179) /* 0.258912540 */, 19 }, +/* 7073 */ { MAD_F(0x0424b4a9) /* 0.258961356 */, 19 }, +/* 7074 */ { MAD_F(0x0424e7da) /* 0.259010174 */, 19 }, +/* 7075 */ { MAD_F(0x04251b0b) /* 0.259058994 */, 19 }, +/* 7076 */ { MAD_F(0x04254e3d) /* 0.259107817 */, 19 }, +/* 7077 */ { MAD_F(0x0425816f) /* 0.259156642 */, 19 }, +/* 7078 */ { MAD_F(0x0425b4a2) /* 0.259205469 */, 19 }, +/* 7079 */ { MAD_F(0x0425e7d6) /* 0.259254298 */, 19 }, +/* 7080 */ { MAD_F(0x04261b0a) /* 0.259303130 */, 19 }, +/* 7081 */ { MAD_F(0x04264e3f) /* 0.259351964 */, 19 }, +/* 7082 */ { MAD_F(0x04268174) /* 0.259400801 */, 19 }, +/* 7083 */ { MAD_F(0x0426b4aa) /* 0.259449639 */, 19 }, +/* 7084 */ { MAD_F(0x0426e7e1) /* 0.259498480 */, 19 }, +/* 7085 */ { MAD_F(0x04271b18) /* 0.259547324 */, 19 }, +/* 7086 */ { MAD_F(0x04274e50) /* 0.259596169 */, 19 }, +/* 7087 */ { MAD_F(0x04278188) /* 0.259645017 */, 19 }, + +/* 7088 */ { MAD_F(0x0427b4c2) /* 0.259693868 */, 19 }, +/* 7089 */ { MAD_F(0x0427e7fb) /* 0.259742720 */, 19 }, +/* 7090 */ { MAD_F(0x04281b36) /* 0.259791575 */, 19 }, +/* 7091 */ { MAD_F(0x04284e71) /* 0.259840432 */, 19 }, +/* 7092 */ { MAD_F(0x042881ac) /* 0.259889291 */, 19 }, +/* 7093 */ { MAD_F(0x0428b4e8) /* 0.259938153 */, 19 }, +/* 7094 */ { MAD_F(0x0428e825) /* 0.259987017 */, 19 }, +/* 7095 */ { MAD_F(0x04291b63) /* 0.260035883 */, 19 }, +/* 7096 */ { MAD_F(0x04294ea1) /* 0.260084752 */, 19 }, +/* 7097 */ { MAD_F(0x042981df) /* 0.260133623 */, 19 }, +/* 7098 */ { MAD_F(0x0429b51f) /* 0.260182496 */, 19 }, +/* 7099 */ { MAD_F(0x0429e85f) /* 0.260231372 */, 19 }, +/* 7100 */ { MAD_F(0x042a1b9f) /* 0.260280249 */, 19 }, +/* 7101 */ { MAD_F(0x042a4ee0) /* 0.260329129 */, 19 }, +/* 7102 */ { MAD_F(0x042a8222) /* 0.260378012 */, 19 }, +/* 7103 */ { MAD_F(0x042ab564) /* 0.260426896 */, 19 }, + +/* 7104 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 19 }, +/* 7105 */ { MAD_F(0x042b1beb) /* 0.260524673 */, 19 }, +/* 7106 */ { MAD_F(0x042b4f2f) /* 0.260573564 */, 19 }, +/* 7107 */ { MAD_F(0x042b8274) /* 0.260622458 */, 19 }, +/* 7108 */ { MAD_F(0x042bb5ba) /* 0.260671354 */, 19 }, +/* 7109 */ { MAD_F(0x042be900) /* 0.260720252 */, 19 }, +/* 7110 */ { MAD_F(0x042c1c46) /* 0.260769153 */, 19 }, +/* 7111 */ { MAD_F(0x042c4f8e) /* 0.260818056 */, 19 }, +/* 7112 */ { MAD_F(0x042c82d6) /* 0.260866961 */, 19 }, +/* 7113 */ { MAD_F(0x042cb61e) /* 0.260915869 */, 19 }, +/* 7114 */ { MAD_F(0x042ce967) /* 0.260964779 */, 19 }, +/* 7115 */ { MAD_F(0x042d1cb1) /* 0.261013691 */, 19 }, +/* 7116 */ { MAD_F(0x042d4ffb) /* 0.261062606 */, 19 }, +/* 7117 */ { MAD_F(0x042d8346) /* 0.261111522 */, 19 }, +/* 7118 */ { MAD_F(0x042db692) /* 0.261160441 */, 19 }, +/* 7119 */ { MAD_F(0x042de9de) /* 0.261209363 */, 19 }, + +/* 7120 */ { MAD_F(0x042e1d2b) /* 0.261258286 */, 19 }, +/* 7121 */ { MAD_F(0x042e5078) /* 0.261307212 */, 19 }, +/* 7122 */ { MAD_F(0x042e83c6) /* 0.261356140 */, 19 }, +/* 7123 */ { MAD_F(0x042eb715) /* 0.261405071 */, 19 }, +/* 7124 */ { MAD_F(0x042eea64) /* 0.261454004 */, 19 }, +/* 7125 */ { MAD_F(0x042f1db4) /* 0.261502939 */, 19 }, +/* 7126 */ { MAD_F(0x042f5105) /* 0.261551876 */, 19 }, +/* 7127 */ { MAD_F(0x042f8456) /* 0.261600816 */, 19 }, +/* 7128 */ { MAD_F(0x042fb7a8) /* 0.261649758 */, 19 }, +/* 7129 */ { MAD_F(0x042feafa) /* 0.261698702 */, 19 }, +/* 7130 */ { MAD_F(0x04301e4d) /* 0.261747649 */, 19 }, +/* 7131 */ { MAD_F(0x043051a1) /* 0.261796597 */, 19 }, +/* 7132 */ { MAD_F(0x043084f5) /* 0.261845548 */, 19 }, +/* 7133 */ { MAD_F(0x0430b84a) /* 0.261894502 */, 19 }, +/* 7134 */ { MAD_F(0x0430eb9f) /* 0.261943458 */, 19 }, +/* 7135 */ { MAD_F(0x04311ef5) /* 0.261992416 */, 19 }, + +/* 7136 */ { MAD_F(0x0431524c) /* 0.262041376 */, 19 }, +/* 7137 */ { MAD_F(0x043185a3) /* 0.262090338 */, 19 }, +/* 7138 */ { MAD_F(0x0431b8fb) /* 0.262139303 */, 19 }, +/* 7139 */ { MAD_F(0x0431ec54) /* 0.262188270 */, 19 }, +/* 7140 */ { MAD_F(0x04321fad) /* 0.262237240 */, 19 }, +/* 7141 */ { MAD_F(0x04325306) /* 0.262286211 */, 19 }, +/* 7142 */ { MAD_F(0x04328661) /* 0.262335185 */, 19 }, +/* 7143 */ { MAD_F(0x0432b9bc) /* 0.262384162 */, 19 }, +/* 7144 */ { MAD_F(0x0432ed17) /* 0.262433140 */, 19 }, +/* 7145 */ { MAD_F(0x04332074) /* 0.262482121 */, 19 }, +/* 7146 */ { MAD_F(0x043353d0) /* 0.262531104 */, 19 }, +/* 7147 */ { MAD_F(0x0433872e) /* 0.262580089 */, 19 }, +/* 7148 */ { MAD_F(0x0433ba8c) /* 0.262629077 */, 19 }, +/* 7149 */ { MAD_F(0x0433edea) /* 0.262678067 */, 19 }, +/* 7150 */ { MAD_F(0x0434214a) /* 0.262727059 */, 19 }, +/* 7151 */ { MAD_F(0x043454aa) /* 0.262776054 */, 19 }, + +/* 7152 */ { MAD_F(0x0434880a) /* 0.262825051 */, 19 }, +/* 7153 */ { MAD_F(0x0434bb6b) /* 0.262874050 */, 19 }, +/* 7154 */ { MAD_F(0x0434eecd) /* 0.262923051 */, 19 }, +/* 7155 */ { MAD_F(0x0435222f) /* 0.262972055 */, 19 }, +/* 7156 */ { MAD_F(0x04355592) /* 0.263021061 */, 19 }, +/* 7157 */ { MAD_F(0x043588f6) /* 0.263070069 */, 19 }, +/* 7158 */ { MAD_F(0x0435bc5a) /* 0.263119079 */, 19 }, +/* 7159 */ { MAD_F(0x0435efbf) /* 0.263168092 */, 19 }, +/* 7160 */ { MAD_F(0x04362324) /* 0.263217107 */, 19 }, +/* 7161 */ { MAD_F(0x0436568a) /* 0.263266125 */, 19 }, +/* 7162 */ { MAD_F(0x043689f1) /* 0.263315144 */, 19 }, +/* 7163 */ { MAD_F(0x0436bd58) /* 0.263364166 */, 19 }, +/* 7164 */ { MAD_F(0x0436f0c0) /* 0.263413191 */, 19 }, +/* 7165 */ { MAD_F(0x04372428) /* 0.263462217 */, 19 }, +/* 7166 */ { MAD_F(0x04375791) /* 0.263511246 */, 19 }, +/* 7167 */ { MAD_F(0x04378afb) /* 0.263560277 */, 19 }, + +/* 7168 */ { MAD_F(0x0437be65) /* 0.263609310 */, 19 }, +/* 7169 */ { MAD_F(0x0437f1d0) /* 0.263658346 */, 19 }, +/* 7170 */ { MAD_F(0x0438253c) /* 0.263707384 */, 19 }, +/* 7171 */ { MAD_F(0x043858a8) /* 0.263756424 */, 19 }, +/* 7172 */ { MAD_F(0x04388c14) /* 0.263805466 */, 19 }, +/* 7173 */ { MAD_F(0x0438bf82) /* 0.263854511 */, 19 }, +/* 7174 */ { MAD_F(0x0438f2f0) /* 0.263903558 */, 19 }, +/* 7175 */ { MAD_F(0x0439265e) /* 0.263952607 */, 19 }, +/* 7176 */ { MAD_F(0x043959cd) /* 0.264001659 */, 19 }, +/* 7177 */ { MAD_F(0x04398d3d) /* 0.264050713 */, 19 }, +/* 7178 */ { MAD_F(0x0439c0ae) /* 0.264099769 */, 19 }, +/* 7179 */ { MAD_F(0x0439f41f) /* 0.264148827 */, 19 }, +/* 7180 */ { MAD_F(0x043a2790) /* 0.264197888 */, 19 }, +/* 7181 */ { MAD_F(0x043a5b02) /* 0.264246951 */, 19 }, +/* 7182 */ { MAD_F(0x043a8e75) /* 0.264296016 */, 19 }, +/* 7183 */ { MAD_F(0x043ac1e9) /* 0.264345084 */, 19 }, + +/* 7184 */ { MAD_F(0x043af55d) /* 0.264394153 */, 19 }, +/* 7185 */ { MAD_F(0x043b28d2) /* 0.264443225 */, 19 }, +/* 7186 */ { MAD_F(0x043b5c47) /* 0.264492300 */, 19 }, +/* 7187 */ { MAD_F(0x043b8fbd) /* 0.264541376 */, 19 }, +/* 7188 */ { MAD_F(0x043bc333) /* 0.264590455 */, 19 }, +/* 7189 */ { MAD_F(0x043bf6aa) /* 0.264639536 */, 19 }, +/* 7190 */ { MAD_F(0x043c2a22) /* 0.264688620 */, 19 }, +/* 7191 */ { MAD_F(0x043c5d9a) /* 0.264737706 */, 19 }, +/* 7192 */ { MAD_F(0x043c9113) /* 0.264786794 */, 19 }, +/* 7193 */ { MAD_F(0x043cc48d) /* 0.264835884 */, 19 }, +/* 7194 */ { MAD_F(0x043cf807) /* 0.264884976 */, 19 }, +/* 7195 */ { MAD_F(0x043d2b82) /* 0.264934071 */, 19 }, +/* 7196 */ { MAD_F(0x043d5efd) /* 0.264983168 */, 19 }, +/* 7197 */ { MAD_F(0x043d9279) /* 0.265032268 */, 19 }, +/* 7198 */ { MAD_F(0x043dc5f6) /* 0.265081369 */, 19 }, +/* 7199 */ { MAD_F(0x043df973) /* 0.265130473 */, 19 }, + +/* 7200 */ { MAD_F(0x043e2cf1) /* 0.265179580 */, 19 }, +/* 7201 */ { MAD_F(0x043e6070) /* 0.265228688 */, 19 }, +/* 7202 */ { MAD_F(0x043e93ef) /* 0.265277799 */, 19 }, +/* 7203 */ { MAD_F(0x043ec76e) /* 0.265326912 */, 19 }, +/* 7204 */ { MAD_F(0x043efaef) /* 0.265376027 */, 19 }, +/* 7205 */ { MAD_F(0x043f2e6f) /* 0.265425145 */, 19 }, +/* 7206 */ { MAD_F(0x043f61f1) /* 0.265474264 */, 19 }, +/* 7207 */ { MAD_F(0x043f9573) /* 0.265523387 */, 19 }, +/* 7208 */ { MAD_F(0x043fc8f6) /* 0.265572511 */, 19 }, +/* 7209 */ { MAD_F(0x043ffc79) /* 0.265621638 */, 19 }, +/* 7210 */ { MAD_F(0x04402ffd) /* 0.265670766 */, 19 }, +/* 7211 */ { MAD_F(0x04406382) /* 0.265719898 */, 19 }, +/* 7212 */ { MAD_F(0x04409707) /* 0.265769031 */, 19 }, +/* 7213 */ { MAD_F(0x0440ca8d) /* 0.265818167 */, 19 }, +/* 7214 */ { MAD_F(0x0440fe13) /* 0.265867305 */, 19 }, +/* 7215 */ { MAD_F(0x0441319a) /* 0.265916445 */, 19 }, + +/* 7216 */ { MAD_F(0x04416522) /* 0.265965588 */, 19 }, +/* 7217 */ { MAD_F(0x044198aa) /* 0.266014732 */, 19 }, +/* 7218 */ { MAD_F(0x0441cc33) /* 0.266063880 */, 19 }, +/* 7219 */ { MAD_F(0x0441ffbc) /* 0.266113029 */, 19 }, +/* 7220 */ { MAD_F(0x04423346) /* 0.266162181 */, 19 }, +/* 7221 */ { MAD_F(0x044266d1) /* 0.266211334 */, 19 }, +/* 7222 */ { MAD_F(0x04429a5c) /* 0.266260491 */, 19 }, +/* 7223 */ { MAD_F(0x0442cde8) /* 0.266309649 */, 19 }, +/* 7224 */ { MAD_F(0x04430174) /* 0.266358810 */, 19 }, +/* 7225 */ { MAD_F(0x04433501) /* 0.266407973 */, 19 }, +/* 7226 */ { MAD_F(0x0443688f) /* 0.266457138 */, 19 }, +/* 7227 */ { MAD_F(0x04439c1d) /* 0.266506305 */, 19 }, +/* 7228 */ { MAD_F(0x0443cfac) /* 0.266555475 */, 19 }, +/* 7229 */ { MAD_F(0x0444033c) /* 0.266604647 */, 19 }, +/* 7230 */ { MAD_F(0x044436cc) /* 0.266653822 */, 19 }, +/* 7231 */ { MAD_F(0x04446a5d) /* 0.266702998 */, 19 }, + +/* 7232 */ { MAD_F(0x04449dee) /* 0.266752177 */, 19 }, +/* 7233 */ { MAD_F(0x0444d180) /* 0.266801358 */, 19 }, +/* 7234 */ { MAD_F(0x04450513) /* 0.266850541 */, 19 }, +/* 7235 */ { MAD_F(0x044538a6) /* 0.266899727 */, 19 }, +/* 7236 */ { MAD_F(0x04456c39) /* 0.266948915 */, 19 }, +/* 7237 */ { MAD_F(0x04459fce) /* 0.266998105 */, 19 }, +/* 7238 */ { MAD_F(0x0445d363) /* 0.267047298 */, 19 }, +/* 7239 */ { MAD_F(0x044606f8) /* 0.267096492 */, 19 }, +/* 7240 */ { MAD_F(0x04463a8f) /* 0.267145689 */, 19 }, +/* 7241 */ { MAD_F(0x04466e25) /* 0.267194888 */, 19 }, +/* 7242 */ { MAD_F(0x0446a1bd) /* 0.267244090 */, 19 }, +/* 7243 */ { MAD_F(0x0446d555) /* 0.267293294 */, 19 }, +/* 7244 */ { MAD_F(0x044708ee) /* 0.267342500 */, 19 }, +/* 7245 */ { MAD_F(0x04473c87) /* 0.267391708 */, 19 }, +/* 7246 */ { MAD_F(0x04477021) /* 0.267440919 */, 19 }, +/* 7247 */ { MAD_F(0x0447a3bb) /* 0.267490131 */, 19 }, + +/* 7248 */ { MAD_F(0x0447d756) /* 0.267539347 */, 19 }, +/* 7249 */ { MAD_F(0x04480af2) /* 0.267588564 */, 19 }, +/* 7250 */ { MAD_F(0x04483e8e) /* 0.267637783 */, 19 }, +/* 7251 */ { MAD_F(0x0448722b) /* 0.267687005 */, 19 }, +/* 7252 */ { MAD_F(0x0448a5c9) /* 0.267736229 */, 19 }, +/* 7253 */ { MAD_F(0x0448d967) /* 0.267785456 */, 19 }, +/* 7254 */ { MAD_F(0x04490d05) /* 0.267834685 */, 19 }, +/* 7255 */ { MAD_F(0x044940a5) /* 0.267883915 */, 19 }, +/* 7256 */ { MAD_F(0x04497445) /* 0.267933149 */, 19 }, +/* 7257 */ { MAD_F(0x0449a7e5) /* 0.267982384 */, 19 }, +/* 7258 */ { MAD_F(0x0449db86) /* 0.268031622 */, 19 }, +/* 7259 */ { MAD_F(0x044a0f28) /* 0.268080862 */, 19 }, +/* 7260 */ { MAD_F(0x044a42ca) /* 0.268130104 */, 19 }, +/* 7261 */ { MAD_F(0x044a766d) /* 0.268179349 */, 19 }, +/* 7262 */ { MAD_F(0x044aaa11) /* 0.268228595 */, 19 }, +/* 7263 */ { MAD_F(0x044addb5) /* 0.268277844 */, 19 }, + +/* 7264 */ { MAD_F(0x044b115a) /* 0.268327096 */, 19 }, +/* 7265 */ { MAD_F(0x044b44ff) /* 0.268376349 */, 19 }, +/* 7266 */ { MAD_F(0x044b78a5) /* 0.268425605 */, 19 }, +/* 7267 */ { MAD_F(0x044bac4c) /* 0.268474863 */, 19 }, +/* 7268 */ { MAD_F(0x044bdff3) /* 0.268524123 */, 19 }, +/* 7269 */ { MAD_F(0x044c139b) /* 0.268573386 */, 19 }, +/* 7270 */ { MAD_F(0x044c4743) /* 0.268622651 */, 19 }, +/* 7271 */ { MAD_F(0x044c7aec) /* 0.268671918 */, 19 }, +/* 7272 */ { MAD_F(0x044cae96) /* 0.268721187 */, 19 }, +/* 7273 */ { MAD_F(0x044ce240) /* 0.268770459 */, 19 }, +/* 7274 */ { MAD_F(0x044d15eb) /* 0.268819733 */, 19 }, +/* 7275 */ { MAD_F(0x044d4997) /* 0.268869009 */, 19 }, +/* 7276 */ { MAD_F(0x044d7d43) /* 0.268918287 */, 19 }, +/* 7277 */ { MAD_F(0x044db0ef) /* 0.268967568 */, 19 }, +/* 7278 */ { MAD_F(0x044de49d) /* 0.269016851 */, 19 }, +/* 7279 */ { MAD_F(0x044e184b) /* 0.269066136 */, 19 }, + +/* 7280 */ { MAD_F(0x044e4bf9) /* 0.269115423 */, 19 }, +/* 7281 */ { MAD_F(0x044e7fa8) /* 0.269164713 */, 19 }, +/* 7282 */ { MAD_F(0x044eb358) /* 0.269214005 */, 19 }, +/* 7283 */ { MAD_F(0x044ee708) /* 0.269263299 */, 19 }, +/* 7284 */ { MAD_F(0x044f1ab9) /* 0.269312595 */, 19 }, +/* 7285 */ { MAD_F(0x044f4e6b) /* 0.269361894 */, 19 }, +/* 7286 */ { MAD_F(0x044f821d) /* 0.269411195 */, 19 }, +/* 7287 */ { MAD_F(0x044fb5cf) /* 0.269460498 */, 19 }, +/* 7288 */ { MAD_F(0x044fe983) /* 0.269509804 */, 19 }, +/* 7289 */ { MAD_F(0x04501d37) /* 0.269559111 */, 19 }, +/* 7290 */ { MAD_F(0x045050eb) /* 0.269608421 */, 19 }, +/* 7291 */ { MAD_F(0x045084a0) /* 0.269657734 */, 19 }, +/* 7292 */ { MAD_F(0x0450b856) /* 0.269707048 */, 19 }, +/* 7293 */ { MAD_F(0x0450ec0d) /* 0.269756365 */, 19 }, +/* 7294 */ { MAD_F(0x04511fc4) /* 0.269805684 */, 19 }, +/* 7295 */ { MAD_F(0x0451537b) /* 0.269855005 */, 19 }, + +/* 7296 */ { MAD_F(0x04518733) /* 0.269904329 */, 19 }, +/* 7297 */ { MAD_F(0x0451baec) /* 0.269953654 */, 19 }, +/* 7298 */ { MAD_F(0x0451eea5) /* 0.270002982 */, 19 }, +/* 7299 */ { MAD_F(0x0452225f) /* 0.270052313 */, 19 }, +/* 7300 */ { MAD_F(0x0452561a) /* 0.270101645 */, 19 }, +/* 7301 */ { MAD_F(0x045289d5) /* 0.270150980 */, 19 }, +/* 7302 */ { MAD_F(0x0452bd91) /* 0.270200317 */, 19 }, +/* 7303 */ { MAD_F(0x0452f14d) /* 0.270249656 */, 19 }, +/* 7304 */ { MAD_F(0x0453250a) /* 0.270298998 */, 19 }, +/* 7305 */ { MAD_F(0x045358c8) /* 0.270348341 */, 19 }, +/* 7306 */ { MAD_F(0x04538c86) /* 0.270397687 */, 19 }, +/* 7307 */ { MAD_F(0x0453c045) /* 0.270447036 */, 19 }, +/* 7308 */ { MAD_F(0x0453f405) /* 0.270496386 */, 19 }, +/* 7309 */ { MAD_F(0x045427c5) /* 0.270545739 */, 19 }, +/* 7310 */ { MAD_F(0x04545b85) /* 0.270595094 */, 19 }, +/* 7311 */ { MAD_F(0x04548f46) /* 0.270644451 */, 19 }, + +/* 7312 */ { MAD_F(0x0454c308) /* 0.270693811 */, 19 }, +/* 7313 */ { MAD_F(0x0454f6cb) /* 0.270743173 */, 19 }, +/* 7314 */ { MAD_F(0x04552a8e) /* 0.270792537 */, 19 }, +/* 7315 */ { MAD_F(0x04555e51) /* 0.270841903 */, 19 }, +/* 7316 */ { MAD_F(0x04559216) /* 0.270891271 */, 19 }, +/* 7317 */ { MAD_F(0x0455c5db) /* 0.270940642 */, 19 }, +/* 7318 */ { MAD_F(0x0455f9a0) /* 0.270990015 */, 19 }, +/* 7319 */ { MAD_F(0x04562d66) /* 0.271039390 */, 19 }, +/* 7320 */ { MAD_F(0x0456612d) /* 0.271088768 */, 19 }, +/* 7321 */ { MAD_F(0x045694f4) /* 0.271138148 */, 19 }, +/* 7322 */ { MAD_F(0x0456c8bc) /* 0.271187530 */, 19 }, +/* 7323 */ { MAD_F(0x0456fc84) /* 0.271236914 */, 19 }, +/* 7324 */ { MAD_F(0x0457304e) /* 0.271286301 */, 19 }, +/* 7325 */ { MAD_F(0x04576417) /* 0.271335689 */, 19 }, +/* 7326 */ { MAD_F(0x045797e2) /* 0.271385080 */, 19 }, +/* 7327 */ { MAD_F(0x0457cbac) /* 0.271434474 */, 19 }, + +/* 7328 */ { MAD_F(0x0457ff78) /* 0.271483869 */, 19 }, +/* 7329 */ { MAD_F(0x04583344) /* 0.271533267 */, 19 }, +/* 7330 */ { MAD_F(0x04586711) /* 0.271582667 */, 19 }, +/* 7331 */ { MAD_F(0x04589ade) /* 0.271632069 */, 19 }, +/* 7332 */ { MAD_F(0x0458ceac) /* 0.271681474 */, 19 }, +/* 7333 */ { MAD_F(0x0459027b) /* 0.271730880 */, 19 }, +/* 7334 */ { MAD_F(0x0459364a) /* 0.271780289 */, 19 }, +/* 7335 */ { MAD_F(0x04596a19) /* 0.271829701 */, 19 }, +/* 7336 */ { MAD_F(0x04599dea) /* 0.271879114 */, 19 }, +/* 7337 */ { MAD_F(0x0459d1bb) /* 0.271928530 */, 19 }, +/* 7338 */ { MAD_F(0x045a058c) /* 0.271977948 */, 19 }, +/* 7339 */ { MAD_F(0x045a395e) /* 0.272027368 */, 19 }, +/* 7340 */ { MAD_F(0x045a6d31) /* 0.272076790 */, 19 }, +/* 7341 */ { MAD_F(0x045aa104) /* 0.272126215 */, 19 }, +/* 7342 */ { MAD_F(0x045ad4d8) /* 0.272175642 */, 19 }, +/* 7343 */ { MAD_F(0x045b08ad) /* 0.272225071 */, 19 }, + +/* 7344 */ { MAD_F(0x045b3c82) /* 0.272274503 */, 19 }, +/* 7345 */ { MAD_F(0x045b7058) /* 0.272323936 */, 19 }, +/* 7346 */ { MAD_F(0x045ba42e) /* 0.272373372 */, 19 }, +/* 7347 */ { MAD_F(0x045bd805) /* 0.272422810 */, 19 }, +/* 7348 */ { MAD_F(0x045c0bdd) /* 0.272472251 */, 19 }, +/* 7349 */ { MAD_F(0x045c3fb5) /* 0.272521693 */, 19 }, +/* 7350 */ { MAD_F(0x045c738e) /* 0.272571138 */, 19 }, +/* 7351 */ { MAD_F(0x045ca767) /* 0.272620585 */, 19 }, +/* 7352 */ { MAD_F(0x045cdb41) /* 0.272670035 */, 19 }, +/* 7353 */ { MAD_F(0x045d0f1b) /* 0.272719486 */, 19 }, +/* 7354 */ { MAD_F(0x045d42f7) /* 0.272768940 */, 19 }, +/* 7355 */ { MAD_F(0x045d76d2) /* 0.272818396 */, 19 }, +/* 7356 */ { MAD_F(0x045daaaf) /* 0.272867855 */, 19 }, +/* 7357 */ { MAD_F(0x045dde8c) /* 0.272917315 */, 19 }, +/* 7358 */ { MAD_F(0x045e1269) /* 0.272966778 */, 19 }, +/* 7359 */ { MAD_F(0x045e4647) /* 0.273016243 */, 19 }, + +/* 7360 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 19 }, +/* 7361 */ { MAD_F(0x045eae06) /* 0.273115180 */, 19 }, +/* 7362 */ { MAD_F(0x045ee1e6) /* 0.273164652 */, 19 }, +/* 7363 */ { MAD_F(0x045f15c6) /* 0.273214126 */, 19 }, +/* 7364 */ { MAD_F(0x045f49a7) /* 0.273263602 */, 19 }, +/* 7365 */ { MAD_F(0x045f7d89) /* 0.273313081 */, 19 }, +/* 7366 */ { MAD_F(0x045fb16c) /* 0.273362561 */, 19 }, +/* 7367 */ { MAD_F(0x045fe54f) /* 0.273412044 */, 19 }, +/* 7368 */ { MAD_F(0x04601932) /* 0.273461530 */, 19 }, +/* 7369 */ { MAD_F(0x04604d16) /* 0.273511017 */, 19 }, +/* 7370 */ { MAD_F(0x046080fb) /* 0.273560507 */, 19 }, +/* 7371 */ { MAD_F(0x0460b4e1) /* 0.273609999 */, 19 }, +/* 7372 */ { MAD_F(0x0460e8c7) /* 0.273659493 */, 19 }, +/* 7373 */ { MAD_F(0x04611cad) /* 0.273708989 */, 19 }, +/* 7374 */ { MAD_F(0x04615094) /* 0.273758488 */, 19 }, +/* 7375 */ { MAD_F(0x0461847c) /* 0.273807989 */, 19 }, + +/* 7376 */ { MAD_F(0x0461b864) /* 0.273857492 */, 19 }, +/* 7377 */ { MAD_F(0x0461ec4d) /* 0.273906997 */, 19 }, +/* 7378 */ { MAD_F(0x04622037) /* 0.273956505 */, 19 }, +/* 7379 */ { MAD_F(0x04625421) /* 0.274006015 */, 19 }, +/* 7380 */ { MAD_F(0x0462880c) /* 0.274055527 */, 19 }, +/* 7381 */ { MAD_F(0x0462bbf7) /* 0.274105041 */, 19 }, +/* 7382 */ { MAD_F(0x0462efe3) /* 0.274154558 */, 19 }, +/* 7383 */ { MAD_F(0x046323d0) /* 0.274204076 */, 19 }, +/* 7384 */ { MAD_F(0x046357bd) /* 0.274253597 */, 19 }, +/* 7385 */ { MAD_F(0x04638bab) /* 0.274303121 */, 19 }, +/* 7386 */ { MAD_F(0x0463bf99) /* 0.274352646 */, 19 }, +/* 7387 */ { MAD_F(0x0463f388) /* 0.274402174 */, 19 }, +/* 7388 */ { MAD_F(0x04642778) /* 0.274451704 */, 19 }, +/* 7389 */ { MAD_F(0x04645b68) /* 0.274501236 */, 19 }, +/* 7390 */ { MAD_F(0x04648f59) /* 0.274550771 */, 19 }, +/* 7391 */ { MAD_F(0x0464c34a) /* 0.274600307 */, 19 }, + +/* 7392 */ { MAD_F(0x0464f73c) /* 0.274649846 */, 19 }, +/* 7393 */ { MAD_F(0x04652b2f) /* 0.274699387 */, 19 }, +/* 7394 */ { MAD_F(0x04655f22) /* 0.274748931 */, 19 }, +/* 7395 */ { MAD_F(0x04659316) /* 0.274798476 */, 19 }, +/* 7396 */ { MAD_F(0x0465c70a) /* 0.274848024 */, 19 }, +/* 7397 */ { MAD_F(0x0465faff) /* 0.274897574 */, 19 }, +/* 7398 */ { MAD_F(0x04662ef5) /* 0.274947126 */, 19 }, +/* 7399 */ { MAD_F(0x046662eb) /* 0.274996681 */, 19 }, +/* 7400 */ { MAD_F(0x046696e2) /* 0.275046238 */, 19 }, +/* 7401 */ { MAD_F(0x0466cad9) /* 0.275095797 */, 19 }, +/* 7402 */ { MAD_F(0x0466fed1) /* 0.275145358 */, 19 }, +/* 7403 */ { MAD_F(0x046732ca) /* 0.275194921 */, 19 }, +/* 7404 */ { MAD_F(0x046766c3) /* 0.275244487 */, 19 }, +/* 7405 */ { MAD_F(0x04679abd) /* 0.275294055 */, 19 }, +/* 7406 */ { MAD_F(0x0467ceb7) /* 0.275343625 */, 19 }, +/* 7407 */ { MAD_F(0x046802b2) /* 0.275393198 */, 19 }, + +/* 7408 */ { MAD_F(0x046836ae) /* 0.275442772 */, 19 }, +/* 7409 */ { MAD_F(0x04686aaa) /* 0.275492349 */, 19 }, +/* 7410 */ { MAD_F(0x04689ea7) /* 0.275541928 */, 19 }, +/* 7411 */ { MAD_F(0x0468d2a4) /* 0.275591509 */, 19 }, +/* 7412 */ { MAD_F(0x046906a2) /* 0.275641093 */, 19 }, +/* 7413 */ { MAD_F(0x04693aa1) /* 0.275690679 */, 19 }, +/* 7414 */ { MAD_F(0x04696ea0) /* 0.275740267 */, 19 }, +/* 7415 */ { MAD_F(0x0469a2a0) /* 0.275789857 */, 19 }, +/* 7416 */ { MAD_F(0x0469d6a0) /* 0.275839449 */, 19 }, +/* 7417 */ { MAD_F(0x046a0aa1) /* 0.275889044 */, 19 }, +/* 7418 */ { MAD_F(0x046a3ea3) /* 0.275938641 */, 19 }, +/* 7419 */ { MAD_F(0x046a72a5) /* 0.275988240 */, 19 }, +/* 7420 */ { MAD_F(0x046aa6a8) /* 0.276037842 */, 19 }, +/* 7421 */ { MAD_F(0x046adaab) /* 0.276087445 */, 19 }, +/* 7422 */ { MAD_F(0x046b0eaf) /* 0.276137051 */, 19 }, +/* 7423 */ { MAD_F(0x046b42b3) /* 0.276186659 */, 19 }, + +/* 7424 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 19 }, +/* 7425 */ { MAD_F(0x046baabe) /* 0.276285882 */, 19 }, +/* 7426 */ { MAD_F(0x046bdec5) /* 0.276335497 */, 19 }, +/* 7427 */ { MAD_F(0x046c12cc) /* 0.276385113 */, 19 }, +/* 7428 */ { MAD_F(0x046c46d3) /* 0.276434733 */, 19 }, +/* 7429 */ { MAD_F(0x046c7adb) /* 0.276484354 */, 19 }, +/* 7430 */ { MAD_F(0x046caee4) /* 0.276533978 */, 19 }, +/* 7431 */ { MAD_F(0x046ce2ee) /* 0.276583604 */, 19 }, +/* 7432 */ { MAD_F(0x046d16f7) /* 0.276633232 */, 19 }, +/* 7433 */ { MAD_F(0x046d4b02) /* 0.276682862 */, 19 }, +/* 7434 */ { MAD_F(0x046d7f0d) /* 0.276732495 */, 19 }, +/* 7435 */ { MAD_F(0x046db319) /* 0.276782129 */, 19 }, +/* 7436 */ { MAD_F(0x046de725) /* 0.276831766 */, 19 }, +/* 7437 */ { MAD_F(0x046e1b32) /* 0.276881406 */, 19 }, +/* 7438 */ { MAD_F(0x046e4f40) /* 0.276931047 */, 19 }, +/* 7439 */ { MAD_F(0x046e834e) /* 0.276980691 */, 19 }, + +/* 7440 */ { MAD_F(0x046eb75c) /* 0.277030337 */, 19 }, +/* 7441 */ { MAD_F(0x046eeb6c) /* 0.277079985 */, 19 }, +/* 7442 */ { MAD_F(0x046f1f7c) /* 0.277129635 */, 19 }, +/* 7443 */ { MAD_F(0x046f538c) /* 0.277179288 */, 19 }, +/* 7444 */ { MAD_F(0x046f879d) /* 0.277228942 */, 19 }, +/* 7445 */ { MAD_F(0x046fbbaf) /* 0.277278600 */, 19 }, +/* 7446 */ { MAD_F(0x046fefc1) /* 0.277328259 */, 19 }, +/* 7447 */ { MAD_F(0x047023d4) /* 0.277377920 */, 19 }, +/* 7448 */ { MAD_F(0x047057e8) /* 0.277427584 */, 19 }, +/* 7449 */ { MAD_F(0x04708bfc) /* 0.277477250 */, 19 }, +/* 7450 */ { MAD_F(0x0470c011) /* 0.277526918 */, 19 }, +/* 7451 */ { MAD_F(0x0470f426) /* 0.277576588 */, 19 }, +/* 7452 */ { MAD_F(0x0471283c) /* 0.277626261 */, 19 }, +/* 7453 */ { MAD_F(0x04715c52) /* 0.277675936 */, 19 }, +/* 7454 */ { MAD_F(0x04719069) /* 0.277725613 */, 19 }, +/* 7455 */ { MAD_F(0x0471c481) /* 0.277775292 */, 19 }, + +/* 7456 */ { MAD_F(0x0471f899) /* 0.277824973 */, 19 }, +/* 7457 */ { MAD_F(0x04722cb2) /* 0.277874657 */, 19 }, +/* 7458 */ { MAD_F(0x047260cc) /* 0.277924343 */, 19 }, +/* 7459 */ { MAD_F(0x047294e6) /* 0.277974031 */, 19 }, +/* 7460 */ { MAD_F(0x0472c900) /* 0.278023722 */, 19 }, +/* 7461 */ { MAD_F(0x0472fd1b) /* 0.278073414 */, 19 }, +/* 7462 */ { MAD_F(0x04733137) /* 0.278123109 */, 19 }, +/* 7463 */ { MAD_F(0x04736554) /* 0.278172806 */, 19 }, +/* 7464 */ { MAD_F(0x04739971) /* 0.278222505 */, 19 }, +/* 7465 */ { MAD_F(0x0473cd8e) /* 0.278272207 */, 19 }, +/* 7466 */ { MAD_F(0x047401ad) /* 0.278321910 */, 19 }, +/* 7467 */ { MAD_F(0x047435cb) /* 0.278371616 */, 19 }, +/* 7468 */ { MAD_F(0x047469eb) /* 0.278421324 */, 19 }, +/* 7469 */ { MAD_F(0x04749e0b) /* 0.278471035 */, 19 }, +/* 7470 */ { MAD_F(0x0474d22c) /* 0.278520747 */, 19 }, +/* 7471 */ { MAD_F(0x0475064d) /* 0.278570462 */, 19 }, + +/* 7472 */ { MAD_F(0x04753a6f) /* 0.278620179 */, 19 }, +/* 7473 */ { MAD_F(0x04756e91) /* 0.278669898 */, 19 }, +/* 7474 */ { MAD_F(0x0475a2b4) /* 0.278719619 */, 19 }, +/* 7475 */ { MAD_F(0x0475d6d7) /* 0.278769343 */, 19 }, +/* 7476 */ { MAD_F(0x04760afc) /* 0.278819069 */, 19 }, +/* 7477 */ { MAD_F(0x04763f20) /* 0.278868797 */, 19 }, +/* 7478 */ { MAD_F(0x04767346) /* 0.278918527 */, 19 }, +/* 7479 */ { MAD_F(0x0476a76c) /* 0.278968260 */, 19 }, +/* 7480 */ { MAD_F(0x0476db92) /* 0.279017995 */, 19 }, +/* 7481 */ { MAD_F(0x04770fba) /* 0.279067731 */, 19 }, +/* 7482 */ { MAD_F(0x047743e1) /* 0.279117471 */, 19 }, +/* 7483 */ { MAD_F(0x0477780a) /* 0.279167212 */, 19 }, +/* 7484 */ { MAD_F(0x0477ac33) /* 0.279216956 */, 19 }, +/* 7485 */ { MAD_F(0x0477e05c) /* 0.279266701 */, 19 }, +/* 7486 */ { MAD_F(0x04781486) /* 0.279316449 */, 19 }, +/* 7487 */ { MAD_F(0x047848b1) /* 0.279366200 */, 19 }, + +/* 7488 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 19 }, +/* 7489 */ { MAD_F(0x0478b108) /* 0.279465707 */, 19 }, +/* 7490 */ { MAD_F(0x0478e535) /* 0.279515464 */, 19 }, +/* 7491 */ { MAD_F(0x04791962) /* 0.279565223 */, 19 }, +/* 7492 */ { MAD_F(0x04794d8f) /* 0.279614984 */, 19 }, +/* 7493 */ { MAD_F(0x047981be) /* 0.279664748 */, 19 }, +/* 7494 */ { MAD_F(0x0479b5ed) /* 0.279714513 */, 19 }, +/* 7495 */ { MAD_F(0x0479ea1c) /* 0.279764281 */, 19 }, +/* 7496 */ { MAD_F(0x047a1e4c) /* 0.279814051 */, 19 }, +/* 7497 */ { MAD_F(0x047a527d) /* 0.279863824 */, 19 }, +/* 7498 */ { MAD_F(0x047a86ae) /* 0.279913598 */, 19 }, +/* 7499 */ { MAD_F(0x047abae0) /* 0.279963375 */, 19 }, +/* 7500 */ { MAD_F(0x047aef12) /* 0.280013154 */, 19 }, +/* 7501 */ { MAD_F(0x047b2346) /* 0.280062935 */, 19 }, +/* 7502 */ { MAD_F(0x047b5779) /* 0.280112719 */, 19 }, +/* 7503 */ { MAD_F(0x047b8bad) /* 0.280162504 */, 19 }, + +/* 7504 */ { MAD_F(0x047bbfe2) /* 0.280212292 */, 19 }, +/* 7505 */ { MAD_F(0x047bf418) /* 0.280262082 */, 19 }, +/* 7506 */ { MAD_F(0x047c284e) /* 0.280311875 */, 19 }, +/* 7507 */ { MAD_F(0x047c5c84) /* 0.280361669 */, 19 }, +/* 7508 */ { MAD_F(0x047c90bb) /* 0.280411466 */, 19 }, +/* 7509 */ { MAD_F(0x047cc4f3) /* 0.280461265 */, 19 }, +/* 7510 */ { MAD_F(0x047cf92c) /* 0.280511066 */, 19 }, +/* 7511 */ { MAD_F(0x047d2d65) /* 0.280560869 */, 19 }, +/* 7512 */ { MAD_F(0x047d619e) /* 0.280610675 */, 19 }, +/* 7513 */ { MAD_F(0x047d95d8) /* 0.280660483 */, 19 }, +/* 7514 */ { MAD_F(0x047dca13) /* 0.280710292 */, 19 }, +/* 7515 */ { MAD_F(0x047dfe4e) /* 0.280760105 */, 19 }, +/* 7516 */ { MAD_F(0x047e328a) /* 0.280809919 */, 19 }, +/* 7517 */ { MAD_F(0x047e66c7) /* 0.280859736 */, 19 }, +/* 7518 */ { MAD_F(0x047e9b04) /* 0.280909554 */, 19 }, +/* 7519 */ { MAD_F(0x047ecf42) /* 0.280959375 */, 19 }, + +/* 7520 */ { MAD_F(0x047f0380) /* 0.281009199 */, 19 }, +/* 7521 */ { MAD_F(0x047f37bf) /* 0.281059024 */, 19 }, +/* 7522 */ { MAD_F(0x047f6bff) /* 0.281108852 */, 19 }, +/* 7523 */ { MAD_F(0x047fa03f) /* 0.281158682 */, 19 }, +/* 7524 */ { MAD_F(0x047fd47f) /* 0.281208514 */, 19 }, +/* 7525 */ { MAD_F(0x048008c1) /* 0.281258348 */, 19 }, +/* 7526 */ { MAD_F(0x04803d02) /* 0.281308184 */, 19 }, +/* 7527 */ { MAD_F(0x04807145) /* 0.281358023 */, 19 }, +/* 7528 */ { MAD_F(0x0480a588) /* 0.281407864 */, 19 }, +/* 7529 */ { MAD_F(0x0480d9cc) /* 0.281457707 */, 19 }, +/* 7530 */ { MAD_F(0x04810e10) /* 0.281507552 */, 19 }, +/* 7531 */ { MAD_F(0x04814255) /* 0.281557400 */, 19 }, +/* 7532 */ { MAD_F(0x0481769a) /* 0.281607250 */, 19 }, +/* 7533 */ { MAD_F(0x0481aae0) /* 0.281657101 */, 19 }, +/* 7534 */ { MAD_F(0x0481df27) /* 0.281706956 */, 19 }, +/* 7535 */ { MAD_F(0x0482136e) /* 0.281756812 */, 19 }, + +/* 7536 */ { MAD_F(0x048247b6) /* 0.281806670 */, 19 }, +/* 7537 */ { MAD_F(0x04827bfe) /* 0.281856531 */, 19 }, +/* 7538 */ { MAD_F(0x0482b047) /* 0.281906394 */, 19 }, +/* 7539 */ { MAD_F(0x0482e491) /* 0.281956259 */, 19 }, +/* 7540 */ { MAD_F(0x048318db) /* 0.282006127 */, 19 }, +/* 7541 */ { MAD_F(0x04834d26) /* 0.282055996 */, 19 }, +/* 7542 */ { MAD_F(0x04838171) /* 0.282105868 */, 19 }, +/* 7543 */ { MAD_F(0x0483b5bd) /* 0.282155742 */, 19 }, +/* 7544 */ { MAD_F(0x0483ea0a) /* 0.282205618 */, 19 }, +/* 7545 */ { MAD_F(0x04841e57) /* 0.282255496 */, 19 }, +/* 7546 */ { MAD_F(0x048452a4) /* 0.282305377 */, 19 }, +/* 7547 */ { MAD_F(0x048486f3) /* 0.282355260 */, 19 }, +/* 7548 */ { MAD_F(0x0484bb42) /* 0.282405145 */, 19 }, +/* 7549 */ { MAD_F(0x0484ef91) /* 0.282455032 */, 19 }, +/* 7550 */ { MAD_F(0x048523e1) /* 0.282504921 */, 19 }, +/* 7551 */ { MAD_F(0x04855832) /* 0.282554813 */, 19 }, + +/* 7552 */ { MAD_F(0x04858c83) /* 0.282604707 */, 19 }, +/* 7553 */ { MAD_F(0x0485c0d5) /* 0.282654603 */, 19 }, +/* 7554 */ { MAD_F(0x0485f527) /* 0.282704501 */, 19 }, +/* 7555 */ { MAD_F(0x0486297a) /* 0.282754401 */, 19 }, +/* 7556 */ { MAD_F(0x04865dce) /* 0.282804304 */, 19 }, +/* 7557 */ { MAD_F(0x04869222) /* 0.282854209 */, 19 }, +/* 7558 */ { MAD_F(0x0486c677) /* 0.282904116 */, 19 }, +/* 7559 */ { MAD_F(0x0486facc) /* 0.282954025 */, 19 }, +/* 7560 */ { MAD_F(0x04872f22) /* 0.283003936 */, 19 }, +/* 7561 */ { MAD_F(0x04876379) /* 0.283053850 */, 19 }, +/* 7562 */ { MAD_F(0x048797d0) /* 0.283103766 */, 19 }, +/* 7563 */ { MAD_F(0x0487cc28) /* 0.283153684 */, 19 }, +/* 7564 */ { MAD_F(0x04880080) /* 0.283203604 */, 19 }, +/* 7565 */ { MAD_F(0x048834d9) /* 0.283253527 */, 19 }, +/* 7566 */ { MAD_F(0x04886933) /* 0.283303451 */, 19 }, +/* 7567 */ { MAD_F(0x04889d8d) /* 0.283353378 */, 19 }, + +/* 7568 */ { MAD_F(0x0488d1e8) /* 0.283403307 */, 19 }, +/* 7569 */ { MAD_F(0x04890643) /* 0.283453238 */, 19 }, +/* 7570 */ { MAD_F(0x04893a9f) /* 0.283503172 */, 19 }, +/* 7571 */ { MAD_F(0x04896efb) /* 0.283553107 */, 19 }, +/* 7572 */ { MAD_F(0x0489a358) /* 0.283603045 */, 19 }, +/* 7573 */ { MAD_F(0x0489d7b6) /* 0.283652985 */, 19 }, +/* 7574 */ { MAD_F(0x048a0c14) /* 0.283702927 */, 19 }, +/* 7575 */ { MAD_F(0x048a4073) /* 0.283752872 */, 19 }, +/* 7576 */ { MAD_F(0x048a74d3) /* 0.283802818 */, 19 }, +/* 7577 */ { MAD_F(0x048aa933) /* 0.283852767 */, 19 }, +/* 7578 */ { MAD_F(0x048add93) /* 0.283902718 */, 19 }, +/* 7579 */ { MAD_F(0x048b11f5) /* 0.283952671 */, 19 }, +/* 7580 */ { MAD_F(0x048b4656) /* 0.284002627 */, 19 }, +/* 7581 */ { MAD_F(0x048b7ab9) /* 0.284052584 */, 19 }, +/* 7582 */ { MAD_F(0x048baf1c) /* 0.284102544 */, 19 }, +/* 7583 */ { MAD_F(0x048be37f) /* 0.284152506 */, 19 }, + +/* 7584 */ { MAD_F(0x048c17e3) /* 0.284202470 */, 19 }, +/* 7585 */ { MAD_F(0x048c4c48) /* 0.284252436 */, 19 }, +/* 7586 */ { MAD_F(0x048c80ad) /* 0.284302405 */, 19 }, +/* 7587 */ { MAD_F(0x048cb513) /* 0.284352376 */, 19 }, +/* 7588 */ { MAD_F(0x048ce97a) /* 0.284402349 */, 19 }, +/* 7589 */ { MAD_F(0x048d1de1) /* 0.284452324 */, 19 }, +/* 7590 */ { MAD_F(0x048d5249) /* 0.284502301 */, 19 }, +/* 7591 */ { MAD_F(0x048d86b1) /* 0.284552281 */, 19 }, +/* 7592 */ { MAD_F(0x048dbb1a) /* 0.284602263 */, 19 }, +/* 7593 */ { MAD_F(0x048def83) /* 0.284652246 */, 19 }, +/* 7594 */ { MAD_F(0x048e23ed) /* 0.284702233 */, 19 }, +/* 7595 */ { MAD_F(0x048e5858) /* 0.284752221 */, 19 }, +/* 7596 */ { MAD_F(0x048e8cc3) /* 0.284802211 */, 19 }, +/* 7597 */ { MAD_F(0x048ec12f) /* 0.284852204 */, 19 }, +/* 7598 */ { MAD_F(0x048ef59b) /* 0.284902199 */, 19 }, +/* 7599 */ { MAD_F(0x048f2a08) /* 0.284952196 */, 19 }, + +/* 7600 */ { MAD_F(0x048f5e76) /* 0.285002195 */, 19 }, +/* 7601 */ { MAD_F(0x048f92e4) /* 0.285052197 */, 19 }, +/* 7602 */ { MAD_F(0x048fc753) /* 0.285102201 */, 19 }, +/* 7603 */ { MAD_F(0x048ffbc2) /* 0.285152206 */, 19 }, +/* 7604 */ { MAD_F(0x04903032) /* 0.285202214 */, 19 }, +/* 7605 */ { MAD_F(0x049064a3) /* 0.285252225 */, 19 }, +/* 7606 */ { MAD_F(0x04909914) /* 0.285302237 */, 19 }, +/* 7607 */ { MAD_F(0x0490cd86) /* 0.285352252 */, 19 }, +/* 7608 */ { MAD_F(0x049101f8) /* 0.285402269 */, 19 }, +/* 7609 */ { MAD_F(0x0491366b) /* 0.285452288 */, 19 }, +/* 7610 */ { MAD_F(0x04916ade) /* 0.285502309 */, 19 }, +/* 7611 */ { MAD_F(0x04919f52) /* 0.285552332 */, 19 }, +/* 7612 */ { MAD_F(0x0491d3c7) /* 0.285602358 */, 19 }, +/* 7613 */ { MAD_F(0x0492083c) /* 0.285652386 */, 19 }, +/* 7614 */ { MAD_F(0x04923cb2) /* 0.285702416 */, 19 }, +/* 7615 */ { MAD_F(0x04927128) /* 0.285752448 */, 19 }, + +/* 7616 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 19 }, +/* 7617 */ { MAD_F(0x0492da17) /* 0.285852519 */, 19 }, +/* 7618 */ { MAD_F(0x04930e8f) /* 0.285902557 */, 19 }, +/* 7619 */ { MAD_F(0x04934308) /* 0.285952598 */, 19 }, +/* 7620 */ { MAD_F(0x04937781) /* 0.286002641 */, 19 }, +/* 7621 */ { MAD_F(0x0493abfb) /* 0.286052687 */, 19 }, +/* 7622 */ { MAD_F(0x0493e076) /* 0.286102734 */, 19 }, +/* 7623 */ { MAD_F(0x049414f1) /* 0.286152784 */, 19 }, +/* 7624 */ { MAD_F(0x0494496c) /* 0.286202836 */, 19 }, +/* 7625 */ { MAD_F(0x04947de9) /* 0.286252890 */, 19 }, +/* 7626 */ { MAD_F(0x0494b266) /* 0.286302946 */, 19 }, +/* 7627 */ { MAD_F(0x0494e6e3) /* 0.286353005 */, 19 }, +/* 7628 */ { MAD_F(0x04951b61) /* 0.286403065 */, 19 }, +/* 7629 */ { MAD_F(0x04954fe0) /* 0.286453128 */, 19 }, +/* 7630 */ { MAD_F(0x0495845f) /* 0.286503193 */, 19 }, +/* 7631 */ { MAD_F(0x0495b8df) /* 0.286553260 */, 19 }, + +/* 7632 */ { MAD_F(0x0495ed5f) /* 0.286603329 */, 19 }, +/* 7633 */ { MAD_F(0x049621e0) /* 0.286653401 */, 19 }, +/* 7634 */ { MAD_F(0x04965662) /* 0.286703475 */, 19 }, +/* 7635 */ { MAD_F(0x04968ae4) /* 0.286753551 */, 19 }, +/* 7636 */ { MAD_F(0x0496bf67) /* 0.286803629 */, 19 }, +/* 7637 */ { MAD_F(0x0496f3ea) /* 0.286853709 */, 19 }, +/* 7638 */ { MAD_F(0x0497286e) /* 0.286903792 */, 19 }, +/* 7639 */ { MAD_F(0x04975cf2) /* 0.286953876 */, 19 }, +/* 7640 */ { MAD_F(0x04979177) /* 0.287003963 */, 19 }, +/* 7641 */ { MAD_F(0x0497c5fd) /* 0.287054052 */, 19 }, +/* 7642 */ { MAD_F(0x0497fa83) /* 0.287104143 */, 19 }, +/* 7643 */ { MAD_F(0x04982f0a) /* 0.287154237 */, 19 }, +/* 7644 */ { MAD_F(0x04986392) /* 0.287204332 */, 19 }, +/* 7645 */ { MAD_F(0x0498981a) /* 0.287254430 */, 19 }, +/* 7646 */ { MAD_F(0x0498cca2) /* 0.287304530 */, 19 }, +/* 7647 */ { MAD_F(0x0499012c) /* 0.287354632 */, 19 }, + +/* 7648 */ { MAD_F(0x049935b5) /* 0.287404737 */, 19 }, +/* 7649 */ { MAD_F(0x04996a40) /* 0.287454843 */, 19 }, +/* 7650 */ { MAD_F(0x04999ecb) /* 0.287504952 */, 19 }, +/* 7651 */ { MAD_F(0x0499d356) /* 0.287555063 */, 19 }, +/* 7652 */ { MAD_F(0x049a07e2) /* 0.287605176 */, 19 }, +/* 7653 */ { MAD_F(0x049a3c6f) /* 0.287655291 */, 19 }, +/* 7654 */ { MAD_F(0x049a70fc) /* 0.287705409 */, 19 }, +/* 7655 */ { MAD_F(0x049aa58a) /* 0.287755528 */, 19 }, +/* 7656 */ { MAD_F(0x049ada19) /* 0.287805650 */, 19 }, +/* 7657 */ { MAD_F(0x049b0ea8) /* 0.287855774 */, 19 }, +/* 7658 */ { MAD_F(0x049b4337) /* 0.287905900 */, 19 }, +/* 7659 */ { MAD_F(0x049b77c8) /* 0.287956028 */, 19 }, +/* 7660 */ { MAD_F(0x049bac58) /* 0.288006159 */, 19 }, +/* 7661 */ { MAD_F(0x049be0ea) /* 0.288056292 */, 19 }, +/* 7662 */ { MAD_F(0x049c157c) /* 0.288106427 */, 19 }, +/* 7663 */ { MAD_F(0x049c4a0e) /* 0.288156564 */, 19 }, + +/* 7664 */ { MAD_F(0x049c7ea1) /* 0.288206703 */, 19 }, +/* 7665 */ { MAD_F(0x049cb335) /* 0.288256844 */, 19 }, +/* 7666 */ { MAD_F(0x049ce7ca) /* 0.288306988 */, 19 }, +/* 7667 */ { MAD_F(0x049d1c5e) /* 0.288357134 */, 19 }, +/* 7668 */ { MAD_F(0x049d50f4) /* 0.288407282 */, 19 }, +/* 7669 */ { MAD_F(0x049d858a) /* 0.288457432 */, 19 }, +/* 7670 */ { MAD_F(0x049dba21) /* 0.288507584 */, 19 }, +/* 7671 */ { MAD_F(0x049deeb8) /* 0.288557739 */, 19 }, +/* 7672 */ { MAD_F(0x049e2350) /* 0.288607895 */, 19 }, +/* 7673 */ { MAD_F(0x049e57e8) /* 0.288658054 */, 19 }, +/* 7674 */ { MAD_F(0x049e8c81) /* 0.288708215 */, 19 }, +/* 7675 */ { MAD_F(0x049ec11b) /* 0.288758379 */, 19 }, +/* 7676 */ { MAD_F(0x049ef5b5) /* 0.288808544 */, 19 }, +/* 7677 */ { MAD_F(0x049f2a50) /* 0.288858712 */, 19 }, +/* 7678 */ { MAD_F(0x049f5eeb) /* 0.288908881 */, 19 }, +/* 7679 */ { MAD_F(0x049f9387) /* 0.288959053 */, 19 }, + +/* 7680 */ { MAD_F(0x049fc824) /* 0.289009227 */, 19 }, +/* 7681 */ { MAD_F(0x049ffcc1) /* 0.289059404 */, 19 }, +/* 7682 */ { MAD_F(0x04a0315e) /* 0.289109582 */, 19 }, +/* 7683 */ { MAD_F(0x04a065fd) /* 0.289159763 */, 19 }, +/* 7684 */ { MAD_F(0x04a09a9b) /* 0.289209946 */, 19 }, +/* 7685 */ { MAD_F(0x04a0cf3b) /* 0.289260131 */, 19 }, +/* 7686 */ { MAD_F(0x04a103db) /* 0.289310318 */, 19 }, +/* 7687 */ { MAD_F(0x04a1387b) /* 0.289360507 */, 19 }, +/* 7688 */ { MAD_F(0x04a16d1d) /* 0.289410699 */, 19 }, +/* 7689 */ { MAD_F(0x04a1a1be) /* 0.289460893 */, 19 }, +/* 7690 */ { MAD_F(0x04a1d661) /* 0.289511088 */, 19 }, +/* 7691 */ { MAD_F(0x04a20b04) /* 0.289561287 */, 19 }, +/* 7692 */ { MAD_F(0x04a23fa7) /* 0.289611487 */, 19 }, +/* 7693 */ { MAD_F(0x04a2744b) /* 0.289661689 */, 19 }, +/* 7694 */ { MAD_F(0x04a2a8f0) /* 0.289711894 */, 19 }, +/* 7695 */ { MAD_F(0x04a2dd95) /* 0.289762101 */, 19 }, + +/* 7696 */ { MAD_F(0x04a3123b) /* 0.289812309 */, 19 }, +/* 7697 */ { MAD_F(0x04a346e2) /* 0.289862521 */, 19 }, +/* 7698 */ { MAD_F(0x04a37b89) /* 0.289912734 */, 19 }, +/* 7699 */ { MAD_F(0x04a3b030) /* 0.289962949 */, 19 }, +/* 7700 */ { MAD_F(0x04a3e4d8) /* 0.290013167 */, 19 }, +/* 7701 */ { MAD_F(0x04a41981) /* 0.290063387 */, 19 }, +/* 7702 */ { MAD_F(0x04a44e2b) /* 0.290113609 */, 19 }, +/* 7703 */ { MAD_F(0x04a482d5) /* 0.290163833 */, 19 }, +/* 7704 */ { MAD_F(0x04a4b77f) /* 0.290214059 */, 19 }, +/* 7705 */ { MAD_F(0x04a4ec2a) /* 0.290264288 */, 19 }, +/* 7706 */ { MAD_F(0x04a520d6) /* 0.290314519 */, 19 }, +/* 7707 */ { MAD_F(0x04a55582) /* 0.290364751 */, 19 }, +/* 7708 */ { MAD_F(0x04a58a2f) /* 0.290414986 */, 19 }, +/* 7709 */ { MAD_F(0x04a5bedd) /* 0.290465224 */, 19 }, +/* 7710 */ { MAD_F(0x04a5f38b) /* 0.290515463 */, 19 }, +/* 7711 */ { MAD_F(0x04a62839) /* 0.290565705 */, 19 }, + +/* 7712 */ { MAD_F(0x04a65ce8) /* 0.290615948 */, 19 }, +/* 7713 */ { MAD_F(0x04a69198) /* 0.290666194 */, 19 }, +/* 7714 */ { MAD_F(0x04a6c648) /* 0.290716442 */, 19 }, +/* 7715 */ { MAD_F(0x04a6faf9) /* 0.290766692 */, 19 }, +/* 7716 */ { MAD_F(0x04a72fab) /* 0.290816945 */, 19 }, +/* 7717 */ { MAD_F(0x04a7645d) /* 0.290867199 */, 19 }, +/* 7718 */ { MAD_F(0x04a79910) /* 0.290917456 */, 19 }, +/* 7719 */ { MAD_F(0x04a7cdc3) /* 0.290967715 */, 19 }, +/* 7720 */ { MAD_F(0x04a80277) /* 0.291017976 */, 19 }, +/* 7721 */ { MAD_F(0x04a8372b) /* 0.291068239 */, 19 }, +/* 7722 */ { MAD_F(0x04a86be0) /* 0.291118505 */, 19 }, +/* 7723 */ { MAD_F(0x04a8a096) /* 0.291168772 */, 19 }, +/* 7724 */ { MAD_F(0x04a8d54c) /* 0.291219042 */, 19 }, +/* 7725 */ { MAD_F(0x04a90a03) /* 0.291269314 */, 19 }, +/* 7726 */ { MAD_F(0x04a93eba) /* 0.291319588 */, 19 }, +/* 7727 */ { MAD_F(0x04a97372) /* 0.291369865 */, 19 }, + +/* 7728 */ { MAD_F(0x04a9a82b) /* 0.291420143 */, 19 }, +/* 7729 */ { MAD_F(0x04a9dce4) /* 0.291470424 */, 19 }, +/* 7730 */ { MAD_F(0x04aa119d) /* 0.291520706 */, 19 }, +/* 7731 */ { MAD_F(0x04aa4658) /* 0.291570991 */, 19 }, +/* 7732 */ { MAD_F(0x04aa7b13) /* 0.291621278 */, 19 }, +/* 7733 */ { MAD_F(0x04aaafce) /* 0.291671568 */, 19 }, +/* 7734 */ { MAD_F(0x04aae48a) /* 0.291721859 */, 19 }, +/* 7735 */ { MAD_F(0x04ab1947) /* 0.291772153 */, 19 }, +/* 7736 */ { MAD_F(0x04ab4e04) /* 0.291822449 */, 19 }, +/* 7737 */ { MAD_F(0x04ab82c2) /* 0.291872747 */, 19 }, +/* 7738 */ { MAD_F(0x04abb780) /* 0.291923047 */, 19 }, +/* 7739 */ { MAD_F(0x04abec3f) /* 0.291973349 */, 19 }, +/* 7740 */ { MAD_F(0x04ac20fe) /* 0.292023653 */, 19 }, +/* 7741 */ { MAD_F(0x04ac55be) /* 0.292073960 */, 19 }, +/* 7742 */ { MAD_F(0x04ac8a7f) /* 0.292124269 */, 19 }, +/* 7743 */ { MAD_F(0x04acbf40) /* 0.292174580 */, 19 }, + +/* 7744 */ { MAD_F(0x04acf402) /* 0.292224893 */, 19 }, +/* 7745 */ { MAD_F(0x04ad28c5) /* 0.292275208 */, 19 }, +/* 7746 */ { MAD_F(0x04ad5d88) /* 0.292325526 */, 19 }, +/* 7747 */ { MAD_F(0x04ad924b) /* 0.292375845 */, 19 }, +/* 7748 */ { MAD_F(0x04adc70f) /* 0.292426167 */, 19 }, +/* 7749 */ { MAD_F(0x04adfbd4) /* 0.292476491 */, 19 }, +/* 7750 */ { MAD_F(0x04ae3099) /* 0.292526817 */, 19 }, +/* 7751 */ { MAD_F(0x04ae655f) /* 0.292577145 */, 19 }, +/* 7752 */ { MAD_F(0x04ae9a26) /* 0.292627476 */, 19 }, +/* 7753 */ { MAD_F(0x04aeceed) /* 0.292677808 */, 19 }, +/* 7754 */ { MAD_F(0x04af03b4) /* 0.292728143 */, 19 }, +/* 7755 */ { MAD_F(0x04af387d) /* 0.292778480 */, 19 }, +/* 7756 */ { MAD_F(0x04af6d45) /* 0.292828819 */, 19 }, +/* 7757 */ { MAD_F(0x04afa20f) /* 0.292879160 */, 19 }, +/* 7758 */ { MAD_F(0x04afd6d9) /* 0.292929504 */, 19 }, +/* 7759 */ { MAD_F(0x04b00ba3) /* 0.292979849 */, 19 }, + +/* 7760 */ { MAD_F(0x04b0406e) /* 0.293030197 */, 19 }, +/* 7761 */ { MAD_F(0x04b0753a) /* 0.293080547 */, 19 }, +/* 7762 */ { MAD_F(0x04b0aa06) /* 0.293130899 */, 19 }, +/* 7763 */ { MAD_F(0x04b0ded3) /* 0.293181253 */, 19 }, +/* 7764 */ { MAD_F(0x04b113a1) /* 0.293231610 */, 19 }, +/* 7765 */ { MAD_F(0x04b1486f) /* 0.293281968 */, 19 }, +/* 7766 */ { MAD_F(0x04b17d3d) /* 0.293332329 */, 19 }, +/* 7767 */ { MAD_F(0x04b1b20c) /* 0.293382692 */, 19 }, +/* 7768 */ { MAD_F(0x04b1e6dc) /* 0.293433057 */, 19 }, +/* 7769 */ { MAD_F(0x04b21bad) /* 0.293483424 */, 19 }, +/* 7770 */ { MAD_F(0x04b2507d) /* 0.293533794 */, 19 }, +/* 7771 */ { MAD_F(0x04b2854f) /* 0.293584165 */, 19 }, +/* 7772 */ { MAD_F(0x04b2ba21) /* 0.293634539 */, 19 }, +/* 7773 */ { MAD_F(0x04b2eef4) /* 0.293684915 */, 19 }, +/* 7774 */ { MAD_F(0x04b323c7) /* 0.293735293 */, 19 }, +/* 7775 */ { MAD_F(0x04b3589b) /* 0.293785673 */, 19 }, + +/* 7776 */ { MAD_F(0x04b38d6f) /* 0.293836055 */, 19 }, +/* 7777 */ { MAD_F(0x04b3c244) /* 0.293886440 */, 19 }, +/* 7778 */ { MAD_F(0x04b3f71a) /* 0.293936826 */, 19 }, +/* 7779 */ { MAD_F(0x04b42bf0) /* 0.293987215 */, 19 }, +/* 7780 */ { MAD_F(0x04b460c7) /* 0.294037606 */, 19 }, +/* 7781 */ { MAD_F(0x04b4959e) /* 0.294087999 */, 19 }, +/* 7782 */ { MAD_F(0x04b4ca76) /* 0.294138395 */, 19 }, +/* 7783 */ { MAD_F(0x04b4ff4e) /* 0.294188792 */, 19 }, +/* 7784 */ { MAD_F(0x04b53427) /* 0.294239192 */, 19 }, +/* 7785 */ { MAD_F(0x04b56901) /* 0.294289593 */, 19 }, +/* 7786 */ { MAD_F(0x04b59ddb) /* 0.294339997 */, 19 }, +/* 7787 */ { MAD_F(0x04b5d2b6) /* 0.294390403 */, 19 }, +/* 7788 */ { MAD_F(0x04b60791) /* 0.294440812 */, 19 }, +/* 7789 */ { MAD_F(0x04b63c6d) /* 0.294491222 */, 19 }, +/* 7790 */ { MAD_F(0x04b6714a) /* 0.294541635 */, 19 }, +/* 7791 */ { MAD_F(0x04b6a627) /* 0.294592049 */, 19 }, + +/* 7792 */ { MAD_F(0x04b6db05) /* 0.294642466 */, 19 }, +/* 7793 */ { MAD_F(0x04b70fe3) /* 0.294692885 */, 19 }, +/* 7794 */ { MAD_F(0x04b744c2) /* 0.294743306 */, 19 }, +/* 7795 */ { MAD_F(0x04b779a1) /* 0.294793730 */, 19 }, +/* 7796 */ { MAD_F(0x04b7ae81) /* 0.294844155 */, 19 }, +/* 7797 */ { MAD_F(0x04b7e362) /* 0.294894583 */, 19 }, +/* 7798 */ { MAD_F(0x04b81843) /* 0.294945013 */, 19 }, +/* 7799 */ { MAD_F(0x04b84d24) /* 0.294995445 */, 19 }, +/* 7800 */ { MAD_F(0x04b88207) /* 0.295045879 */, 19 }, +/* 7801 */ { MAD_F(0x04b8b6ea) /* 0.295096315 */, 19 }, +/* 7802 */ { MAD_F(0x04b8ebcd) /* 0.295146753 */, 19 }, +/* 7803 */ { MAD_F(0x04b920b1) /* 0.295197194 */, 19 }, +/* 7804 */ { MAD_F(0x04b95596) /* 0.295247637 */, 19 }, +/* 7805 */ { MAD_F(0x04b98a7b) /* 0.295298082 */, 19 }, +/* 7806 */ { MAD_F(0x04b9bf61) /* 0.295348529 */, 19 }, +/* 7807 */ { MAD_F(0x04b9f447) /* 0.295398978 */, 19 }, + +/* 7808 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 19 }, +/* 7809 */ { MAD_F(0x04ba5e16) /* 0.295499883 */, 19 }, +/* 7810 */ { MAD_F(0x04ba92fe) /* 0.295550338 */, 19 }, +/* 7811 */ { MAD_F(0x04bac7e6) /* 0.295600796 */, 19 }, +/* 7812 */ { MAD_F(0x04bafcd0) /* 0.295651256 */, 19 }, +/* 7813 */ { MAD_F(0x04bb31b9) /* 0.295701718 */, 19 }, +/* 7814 */ { MAD_F(0x04bb66a4) /* 0.295752183 */, 19 }, +/* 7815 */ { MAD_F(0x04bb9b8f) /* 0.295802649 */, 19 }, +/* 7816 */ { MAD_F(0x04bbd07a) /* 0.295853118 */, 19 }, +/* 7817 */ { MAD_F(0x04bc0566) /* 0.295903588 */, 19 }, +/* 7818 */ { MAD_F(0x04bc3a53) /* 0.295954061 */, 19 }, +/* 7819 */ { MAD_F(0x04bc6f40) /* 0.296004536 */, 19 }, +/* 7820 */ { MAD_F(0x04bca42e) /* 0.296055013 */, 19 }, +/* 7821 */ { MAD_F(0x04bcd91d) /* 0.296105493 */, 19 }, +/* 7822 */ { MAD_F(0x04bd0e0c) /* 0.296155974 */, 19 }, +/* 7823 */ { MAD_F(0x04bd42fb) /* 0.296206458 */, 19 }, + +/* 7824 */ { MAD_F(0x04bd77ec) /* 0.296256944 */, 19 }, +/* 7825 */ { MAD_F(0x04bdacdc) /* 0.296307432 */, 19 }, +/* 7826 */ { MAD_F(0x04bde1ce) /* 0.296357922 */, 19 }, +/* 7827 */ { MAD_F(0x04be16c0) /* 0.296408414 */, 19 }, +/* 7828 */ { MAD_F(0x04be4bb2) /* 0.296458908 */, 19 }, +/* 7829 */ { MAD_F(0x04be80a5) /* 0.296509405 */, 19 }, +/* 7830 */ { MAD_F(0x04beb599) /* 0.296559904 */, 19 }, +/* 7831 */ { MAD_F(0x04beea8d) /* 0.296610404 */, 19 }, +/* 7832 */ { MAD_F(0x04bf1f82) /* 0.296660907 */, 19 }, +/* 7833 */ { MAD_F(0x04bf5477) /* 0.296711413 */, 19 }, +/* 7834 */ { MAD_F(0x04bf896d) /* 0.296761920 */, 19 }, +/* 7835 */ { MAD_F(0x04bfbe64) /* 0.296812429 */, 19 }, +/* 7836 */ { MAD_F(0x04bff35b) /* 0.296862941 */, 19 }, +/* 7837 */ { MAD_F(0x04c02852) /* 0.296913455 */, 19 }, +/* 7838 */ { MAD_F(0x04c05d4b) /* 0.296963971 */, 19 }, +/* 7839 */ { MAD_F(0x04c09243) /* 0.297014489 */, 19 }, + +/* 7840 */ { MAD_F(0x04c0c73d) /* 0.297065009 */, 19 }, +/* 7841 */ { MAD_F(0x04c0fc37) /* 0.297115531 */, 19 }, +/* 7842 */ { MAD_F(0x04c13131) /* 0.297166056 */, 19 }, +/* 7843 */ { MAD_F(0x04c1662d) /* 0.297216582 */, 19 }, +/* 7844 */ { MAD_F(0x04c19b28) /* 0.297267111 */, 19 }, +/* 7845 */ { MAD_F(0x04c1d025) /* 0.297317642 */, 19 }, +/* 7846 */ { MAD_F(0x04c20521) /* 0.297368175 */, 19 }, +/* 7847 */ { MAD_F(0x04c23a1f) /* 0.297418710 */, 19 }, +/* 7848 */ { MAD_F(0x04c26f1d) /* 0.297469248 */, 19 }, +/* 7849 */ { MAD_F(0x04c2a41b) /* 0.297519787 */, 19 }, +/* 7850 */ { MAD_F(0x04c2d91b) /* 0.297570329 */, 19 }, +/* 7851 */ { MAD_F(0x04c30e1a) /* 0.297620873 */, 19 }, +/* 7852 */ { MAD_F(0x04c3431b) /* 0.297671418 */, 19 }, +/* 7853 */ { MAD_F(0x04c3781c) /* 0.297721967 */, 19 }, +/* 7854 */ { MAD_F(0x04c3ad1d) /* 0.297772517 */, 19 }, +/* 7855 */ { MAD_F(0x04c3e21f) /* 0.297823069 */, 19 }, + +/* 7856 */ { MAD_F(0x04c41722) /* 0.297873624 */, 19 }, +/* 7857 */ { MAD_F(0x04c44c25) /* 0.297924180 */, 19 }, +/* 7858 */ { MAD_F(0x04c48129) /* 0.297974739 */, 19 }, +/* 7859 */ { MAD_F(0x04c4b62d) /* 0.298025300 */, 19 }, +/* 7860 */ { MAD_F(0x04c4eb32) /* 0.298075863 */, 19 }, +/* 7861 */ { MAD_F(0x04c52038) /* 0.298126429 */, 19 }, +/* 7862 */ { MAD_F(0x04c5553e) /* 0.298176996 */, 19 }, +/* 7863 */ { MAD_F(0x04c58a44) /* 0.298227565 */, 19 }, +/* 7864 */ { MAD_F(0x04c5bf4c) /* 0.298278137 */, 19 }, +/* 7865 */ { MAD_F(0x04c5f453) /* 0.298328711 */, 19 }, +/* 7866 */ { MAD_F(0x04c6295c) /* 0.298379287 */, 19 }, +/* 7867 */ { MAD_F(0x04c65e65) /* 0.298429865 */, 19 }, +/* 7868 */ { MAD_F(0x04c6936e) /* 0.298480445 */, 19 }, +/* 7869 */ { MAD_F(0x04c6c878) /* 0.298531028 */, 19 }, +/* 7870 */ { MAD_F(0x04c6fd83) /* 0.298581612 */, 19 }, +/* 7871 */ { MAD_F(0x04c7328e) /* 0.298632199 */, 19 }, + +/* 7872 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 19 }, +/* 7873 */ { MAD_F(0x04c79ca7) /* 0.298733379 */, 19 }, +/* 7874 */ { MAD_F(0x04c7d1b4) /* 0.298783972 */, 19 }, +/* 7875 */ { MAD_F(0x04c806c1) /* 0.298834567 */, 19 }, +/* 7876 */ { MAD_F(0x04c83bcf) /* 0.298885165 */, 19 }, +/* 7877 */ { MAD_F(0x04c870de) /* 0.298935764 */, 19 }, +/* 7878 */ { MAD_F(0x04c8a5ed) /* 0.298986366 */, 19 }, +/* 7879 */ { MAD_F(0x04c8dafd) /* 0.299036970 */, 19 }, +/* 7880 */ { MAD_F(0x04c9100d) /* 0.299087576 */, 19 }, +/* 7881 */ { MAD_F(0x04c9451e) /* 0.299138184 */, 19 }, +/* 7882 */ { MAD_F(0x04c97a30) /* 0.299188794 */, 19 }, +/* 7883 */ { MAD_F(0x04c9af42) /* 0.299239406 */, 19 }, +/* 7884 */ { MAD_F(0x04c9e455) /* 0.299290021 */, 19 }, +/* 7885 */ { MAD_F(0x04ca1968) /* 0.299340638 */, 19 }, +/* 7886 */ { MAD_F(0x04ca4e7c) /* 0.299391256 */, 19 }, +/* 7887 */ { MAD_F(0x04ca8391) /* 0.299441877 */, 19 }, + +/* 7888 */ { MAD_F(0x04cab8a6) /* 0.299492500 */, 19 }, +/* 7889 */ { MAD_F(0x04caedbb) /* 0.299543126 */, 19 }, +/* 7890 */ { MAD_F(0x04cb22d1) /* 0.299593753 */, 19 }, +/* 7891 */ { MAD_F(0x04cb57e8) /* 0.299644382 */, 19 }, +/* 7892 */ { MAD_F(0x04cb8d00) /* 0.299695014 */, 19 }, +/* 7893 */ { MAD_F(0x04cbc217) /* 0.299745648 */, 19 }, +/* 7894 */ { MAD_F(0x04cbf730) /* 0.299796284 */, 19 }, +/* 7895 */ { MAD_F(0x04cc2c49) /* 0.299846922 */, 19 }, +/* 7896 */ { MAD_F(0x04cc6163) /* 0.299897562 */, 19 }, +/* 7897 */ { MAD_F(0x04cc967d) /* 0.299948204 */, 19 }, +/* 7898 */ { MAD_F(0x04cccb98) /* 0.299998849 */, 19 }, +/* 7899 */ { MAD_F(0x04cd00b3) /* 0.300049495 */, 19 }, +/* 7900 */ { MAD_F(0x04cd35cf) /* 0.300100144 */, 19 }, +/* 7901 */ { MAD_F(0x04cd6aeb) /* 0.300150795 */, 19 }, +/* 7902 */ { MAD_F(0x04cda008) /* 0.300201448 */, 19 }, +/* 7903 */ { MAD_F(0x04cdd526) /* 0.300252103 */, 19 }, + +/* 7904 */ { MAD_F(0x04ce0a44) /* 0.300302761 */, 19 }, +/* 7905 */ { MAD_F(0x04ce3f63) /* 0.300353420 */, 19 }, +/* 7906 */ { MAD_F(0x04ce7482) /* 0.300404082 */, 19 }, +/* 7907 */ { MAD_F(0x04cea9a2) /* 0.300454745 */, 19 }, +/* 7908 */ { MAD_F(0x04cedec3) /* 0.300505411 */, 19 }, +/* 7909 */ { MAD_F(0x04cf13e4) /* 0.300556079 */, 19 }, +/* 7910 */ { MAD_F(0x04cf4906) /* 0.300606749 */, 19 }, +/* 7911 */ { MAD_F(0x04cf7e28) /* 0.300657421 */, 19 }, +/* 7912 */ { MAD_F(0x04cfb34b) /* 0.300708096 */, 19 }, +/* 7913 */ { MAD_F(0x04cfe86e) /* 0.300758772 */, 19 }, +/* 7914 */ { MAD_F(0x04d01d92) /* 0.300809451 */, 19 }, +/* 7915 */ { MAD_F(0x04d052b6) /* 0.300860132 */, 19 }, +/* 7916 */ { MAD_F(0x04d087db) /* 0.300910815 */, 19 }, +/* 7917 */ { MAD_F(0x04d0bd01) /* 0.300961500 */, 19 }, +/* 7918 */ { MAD_F(0x04d0f227) /* 0.301012187 */, 19 }, +/* 7919 */ { MAD_F(0x04d1274e) /* 0.301062876 */, 19 }, + +/* 7920 */ { MAD_F(0x04d15c76) /* 0.301113568 */, 19 }, +/* 7921 */ { MAD_F(0x04d1919e) /* 0.301164261 */, 19 }, +/* 7922 */ { MAD_F(0x04d1c6c6) /* 0.301214957 */, 19 }, +/* 7923 */ { MAD_F(0x04d1fbef) /* 0.301265655 */, 19 }, +/* 7924 */ { MAD_F(0x04d23119) /* 0.301316355 */, 19 }, +/* 7925 */ { MAD_F(0x04d26643) /* 0.301367057 */, 19 }, +/* 7926 */ { MAD_F(0x04d29b6e) /* 0.301417761 */, 19 }, +/* 7927 */ { MAD_F(0x04d2d099) /* 0.301468468 */, 19 }, +/* 7928 */ { MAD_F(0x04d305c5) /* 0.301519176 */, 19 }, +/* 7929 */ { MAD_F(0x04d33af2) /* 0.301569887 */, 19 }, +/* 7930 */ { MAD_F(0x04d3701f) /* 0.301620599 */, 19 }, +/* 7931 */ { MAD_F(0x04d3a54d) /* 0.301671314 */, 19 }, +/* 7932 */ { MAD_F(0x04d3da7b) /* 0.301722031 */, 19 }, +/* 7933 */ { MAD_F(0x04d40faa) /* 0.301772751 */, 19 }, +/* 7934 */ { MAD_F(0x04d444d9) /* 0.301823472 */, 19 }, +/* 7935 */ { MAD_F(0x04d47a09) /* 0.301874195 */, 19 }, + +/* 7936 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 19 }, +/* 7937 */ { MAD_F(0x04d4e46b) /* 0.301975649 */, 19 }, +/* 7938 */ { MAD_F(0x04d5199c) /* 0.302026378 */, 19 }, +/* 7939 */ { MAD_F(0x04d54ecf) /* 0.302077110 */, 19 }, +/* 7940 */ { MAD_F(0x04d58401) /* 0.302127845 */, 19 }, +/* 7941 */ { MAD_F(0x04d5b935) /* 0.302178581 */, 19 }, +/* 7942 */ { MAD_F(0x04d5ee69) /* 0.302229319 */, 19 }, +/* 7943 */ { MAD_F(0x04d6239d) /* 0.302280060 */, 19 }, +/* 7944 */ { MAD_F(0x04d658d2) /* 0.302330802 */, 19 }, +/* 7945 */ { MAD_F(0x04d68e08) /* 0.302381547 */, 19 }, +/* 7946 */ { MAD_F(0x04d6c33e) /* 0.302432294 */, 19 }, +/* 7947 */ { MAD_F(0x04d6f875) /* 0.302483043 */, 19 }, +/* 7948 */ { MAD_F(0x04d72dad) /* 0.302533794 */, 19 }, +/* 7949 */ { MAD_F(0x04d762e5) /* 0.302584547 */, 19 }, +/* 7950 */ { MAD_F(0x04d7981d) /* 0.302635303 */, 19 }, +/* 7951 */ { MAD_F(0x04d7cd56) /* 0.302686060 */, 19 }, + +/* 7952 */ { MAD_F(0x04d80290) /* 0.302736820 */, 19 }, +/* 7953 */ { MAD_F(0x04d837ca) /* 0.302787581 */, 19 }, +/* 7954 */ { MAD_F(0x04d86d05) /* 0.302838345 */, 19 }, +/* 7955 */ { MAD_F(0x04d8a240) /* 0.302889111 */, 19 }, +/* 7956 */ { MAD_F(0x04d8d77c) /* 0.302939879 */, 19 }, +/* 7957 */ { MAD_F(0x04d90cb9) /* 0.302990650 */, 19 }, +/* 7958 */ { MAD_F(0x04d941f6) /* 0.303041422 */, 19 }, +/* 7959 */ { MAD_F(0x04d97734) /* 0.303092197 */, 19 }, +/* 7960 */ { MAD_F(0x04d9ac72) /* 0.303142973 */, 19 }, +/* 7961 */ { MAD_F(0x04d9e1b1) /* 0.303193752 */, 19 }, +/* 7962 */ { MAD_F(0x04da16f0) /* 0.303244533 */, 19 }, +/* 7963 */ { MAD_F(0x04da4c30) /* 0.303295316 */, 19 }, +/* 7964 */ { MAD_F(0x04da8171) /* 0.303346101 */, 19 }, +/* 7965 */ { MAD_F(0x04dab6b2) /* 0.303396889 */, 19 }, +/* 7966 */ { MAD_F(0x04daebf4) /* 0.303447678 */, 19 }, +/* 7967 */ { MAD_F(0x04db2136) /* 0.303498469 */, 19 }, + +/* 7968 */ { MAD_F(0x04db5679) /* 0.303549263 */, 19 }, +/* 7969 */ { MAD_F(0x04db8bbc) /* 0.303600059 */, 19 }, +/* 7970 */ { MAD_F(0x04dbc100) /* 0.303650857 */, 19 }, +/* 7971 */ { MAD_F(0x04dbf644) /* 0.303701657 */, 19 }, +/* 7972 */ { MAD_F(0x04dc2b8a) /* 0.303752459 */, 19 }, +/* 7973 */ { MAD_F(0x04dc60cf) /* 0.303803263 */, 19 }, +/* 7974 */ { MAD_F(0x04dc9616) /* 0.303854070 */, 19 }, +/* 7975 */ { MAD_F(0x04dccb5c) /* 0.303904878 */, 19 }, +/* 7976 */ { MAD_F(0x04dd00a4) /* 0.303955689 */, 19 }, +/* 7977 */ { MAD_F(0x04dd35ec) /* 0.304006502 */, 19 }, +/* 7978 */ { MAD_F(0x04dd6b34) /* 0.304057317 */, 19 }, +/* 7979 */ { MAD_F(0x04dda07d) /* 0.304108134 */, 19 }, +/* 7980 */ { MAD_F(0x04ddd5c7) /* 0.304158953 */, 19 }, +/* 7981 */ { MAD_F(0x04de0b11) /* 0.304209774 */, 19 }, +/* 7982 */ { MAD_F(0x04de405c) /* 0.304260597 */, 19 }, +/* 7983 */ { MAD_F(0x04de75a7) /* 0.304311423 */, 19 }, + +/* 7984 */ { MAD_F(0x04deaaf3) /* 0.304362251 */, 19 }, +/* 7985 */ { MAD_F(0x04dee040) /* 0.304413080 */, 19 }, +/* 7986 */ { MAD_F(0x04df158d) /* 0.304463912 */, 19 }, +/* 7987 */ { MAD_F(0x04df4adb) /* 0.304514746 */, 19 }, +/* 7988 */ { MAD_F(0x04df8029) /* 0.304565582 */, 19 }, +/* 7989 */ { MAD_F(0x04dfb578) /* 0.304616421 */, 19 }, +/* 7990 */ { MAD_F(0x04dfeac7) /* 0.304667261 */, 19 }, +/* 7991 */ { MAD_F(0x04e02017) /* 0.304718103 */, 19 }, +/* 7992 */ { MAD_F(0x04e05567) /* 0.304768948 */, 19 }, +/* 7993 */ { MAD_F(0x04e08ab8) /* 0.304819795 */, 19 }, +/* 7994 */ { MAD_F(0x04e0c00a) /* 0.304870644 */, 19 }, +/* 7995 */ { MAD_F(0x04e0f55c) /* 0.304921495 */, 19 }, +/* 7996 */ { MAD_F(0x04e12aaf) /* 0.304972348 */, 19 }, +/* 7997 */ { MAD_F(0x04e16002) /* 0.305023203 */, 19 }, +/* 7998 */ { MAD_F(0x04e19556) /* 0.305074060 */, 19 }, +/* 7999 */ { MAD_F(0x04e1caab) /* 0.305124920 */, 19 }, + +/* 8000 */ { MAD_F(0x04e20000) /* 0.305175781 */, 19 }, +/* 8001 */ { MAD_F(0x04e23555) /* 0.305226645 */, 19 }, +/* 8002 */ { MAD_F(0x04e26aac) /* 0.305277511 */, 19 }, +/* 8003 */ { MAD_F(0x04e2a002) /* 0.305328379 */, 19 }, +/* 8004 */ { MAD_F(0x04e2d55a) /* 0.305379249 */, 19 }, +/* 8005 */ { MAD_F(0x04e30ab2) /* 0.305430121 */, 19 }, +/* 8006 */ { MAD_F(0x04e3400a) /* 0.305480995 */, 19 }, +/* 8007 */ { MAD_F(0x04e37563) /* 0.305531872 */, 19 }, +/* 8008 */ { MAD_F(0x04e3aabd) /* 0.305582750 */, 19 }, +/* 8009 */ { MAD_F(0x04e3e017) /* 0.305633631 */, 19 }, +/* 8010 */ { MAD_F(0x04e41572) /* 0.305684513 */, 19 }, +/* 8011 */ { MAD_F(0x04e44acd) /* 0.305735398 */, 19 }, +/* 8012 */ { MAD_F(0x04e48029) /* 0.305786285 */, 19 }, +/* 8013 */ { MAD_F(0x04e4b585) /* 0.305837174 */, 19 }, +/* 8014 */ { MAD_F(0x04e4eae2) /* 0.305888066 */, 19 }, +/* 8015 */ { MAD_F(0x04e52040) /* 0.305938959 */, 19 }, + +/* 8016 */ { MAD_F(0x04e5559e) /* 0.305989854 */, 19 }, +/* 8017 */ { MAD_F(0x04e58afd) /* 0.306040752 */, 19 }, +/* 8018 */ { MAD_F(0x04e5c05c) /* 0.306091652 */, 19 }, +/* 8019 */ { MAD_F(0x04e5f5bc) /* 0.306142554 */, 19 }, +/* 8020 */ { MAD_F(0x04e62b1c) /* 0.306193457 */, 19 }, +/* 8021 */ { MAD_F(0x04e6607d) /* 0.306244364 */, 19 }, +/* 8022 */ { MAD_F(0x04e695df) /* 0.306295272 */, 19 }, +/* 8023 */ { MAD_F(0x04e6cb41) /* 0.306346182 */, 19 }, +/* 8024 */ { MAD_F(0x04e700a3) /* 0.306397094 */, 19 }, +/* 8025 */ { MAD_F(0x04e73607) /* 0.306448009 */, 19 }, +/* 8026 */ { MAD_F(0x04e76b6b) /* 0.306498925 */, 19 }, +/* 8027 */ { MAD_F(0x04e7a0cf) /* 0.306549844 */, 19 }, +/* 8028 */ { MAD_F(0x04e7d634) /* 0.306600765 */, 19 }, +/* 8029 */ { MAD_F(0x04e80b99) /* 0.306651688 */, 19 }, +/* 8030 */ { MAD_F(0x04e84100) /* 0.306702613 */, 19 }, +/* 8031 */ { MAD_F(0x04e87666) /* 0.306753540 */, 19 }, + +/* 8032 */ { MAD_F(0x04e8abcd) /* 0.306804470 */, 19 }, +/* 8033 */ { MAD_F(0x04e8e135) /* 0.306855401 */, 19 }, +/* 8034 */ { MAD_F(0x04e9169e) /* 0.306906334 */, 19 }, +/* 8035 */ { MAD_F(0x04e94c07) /* 0.306957270 */, 19 }, +/* 8036 */ { MAD_F(0x04e98170) /* 0.307008208 */, 19 }, +/* 8037 */ { MAD_F(0x04e9b6da) /* 0.307059148 */, 19 }, +/* 8038 */ { MAD_F(0x04e9ec45) /* 0.307110090 */, 19 }, +/* 8039 */ { MAD_F(0x04ea21b0) /* 0.307161034 */, 19 }, +/* 8040 */ { MAD_F(0x04ea571c) /* 0.307211980 */, 19 }, +/* 8041 */ { MAD_F(0x04ea8c88) /* 0.307262928 */, 19 }, +/* 8042 */ { MAD_F(0x04eac1f5) /* 0.307313879 */, 19 }, +/* 8043 */ { MAD_F(0x04eaf762) /* 0.307364831 */, 19 }, +/* 8044 */ { MAD_F(0x04eb2cd0) /* 0.307415786 */, 19 }, +/* 8045 */ { MAD_F(0x04eb623f) /* 0.307466743 */, 19 }, +/* 8046 */ { MAD_F(0x04eb97ae) /* 0.307517702 */, 19 }, +/* 8047 */ { MAD_F(0x04ebcd1e) /* 0.307568663 */, 19 }, + +/* 8048 */ { MAD_F(0x04ec028e) /* 0.307619626 */, 19 }, +/* 8049 */ { MAD_F(0x04ec37ff) /* 0.307670591 */, 19 }, +/* 8050 */ { MAD_F(0x04ec6d71) /* 0.307721558 */, 19 }, +/* 8051 */ { MAD_F(0x04eca2e3) /* 0.307772528 */, 19 }, +/* 8052 */ { MAD_F(0x04ecd855) /* 0.307823499 */, 19 }, +/* 8053 */ { MAD_F(0x04ed0dc8) /* 0.307874473 */, 19 }, +/* 8054 */ { MAD_F(0x04ed433c) /* 0.307925449 */, 19 }, +/* 8055 */ { MAD_F(0x04ed78b0) /* 0.307976426 */, 19 }, +/* 8056 */ { MAD_F(0x04edae25) /* 0.308027406 */, 19 }, +/* 8057 */ { MAD_F(0x04ede39a) /* 0.308078389 */, 19 }, +/* 8058 */ { MAD_F(0x04ee1910) /* 0.308129373 */, 19 }, +/* 8059 */ { MAD_F(0x04ee4e87) /* 0.308180359 */, 19 }, +/* 8060 */ { MAD_F(0x04ee83fe) /* 0.308231347 */, 19 }, +/* 8061 */ { MAD_F(0x04eeb976) /* 0.308282338 */, 19 }, +/* 8062 */ { MAD_F(0x04eeeeee) /* 0.308333331 */, 19 }, +/* 8063 */ { MAD_F(0x04ef2467) /* 0.308384325 */, 19 }, + +/* 8064 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 19 }, +/* 8065 */ { MAD_F(0x04ef8f5a) /* 0.308486321 */, 19 }, +/* 8066 */ { MAD_F(0x04efc4d5) /* 0.308537322 */, 19 }, +/* 8067 */ { MAD_F(0x04effa50) /* 0.308588325 */, 19 }, +/* 8068 */ { MAD_F(0x04f02fcb) /* 0.308639331 */, 19 }, +/* 8069 */ { MAD_F(0x04f06547) /* 0.308690338 */, 19 }, +/* 8070 */ { MAD_F(0x04f09ac4) /* 0.308741348 */, 19 }, +/* 8071 */ { MAD_F(0x04f0d041) /* 0.308792359 */, 19 }, +/* 8072 */ { MAD_F(0x04f105bf) /* 0.308843373 */, 19 }, +/* 8073 */ { MAD_F(0x04f13b3e) /* 0.308894389 */, 19 }, +/* 8074 */ { MAD_F(0x04f170bd) /* 0.308945407 */, 19 }, +/* 8075 */ { MAD_F(0x04f1a63c) /* 0.308996427 */, 19 }, +/* 8076 */ { MAD_F(0x04f1dbbd) /* 0.309047449 */, 19 }, +/* 8077 */ { MAD_F(0x04f2113d) /* 0.309098473 */, 19 }, +/* 8078 */ { MAD_F(0x04f246bf) /* 0.309149499 */, 19 }, +/* 8079 */ { MAD_F(0x04f27c40) /* 0.309200528 */, 19 }, + +/* 8080 */ { MAD_F(0x04f2b1c3) /* 0.309251558 */, 19 }, +/* 8081 */ { MAD_F(0x04f2e746) /* 0.309302591 */, 19 }, +/* 8082 */ { MAD_F(0x04f31cc9) /* 0.309353626 */, 19 }, +/* 8083 */ { MAD_F(0x04f3524d) /* 0.309404663 */, 19 }, +/* 8084 */ { MAD_F(0x04f387d2) /* 0.309455702 */, 19 }, +/* 8085 */ { MAD_F(0x04f3bd57) /* 0.309506743 */, 19 }, +/* 8086 */ { MAD_F(0x04f3f2dd) /* 0.309557786 */, 19 }, +/* 8087 */ { MAD_F(0x04f42864) /* 0.309608831 */, 19 }, +/* 8088 */ { MAD_F(0x04f45dea) /* 0.309659879 */, 19 }, +/* 8089 */ { MAD_F(0x04f49372) /* 0.309710928 */, 19 }, +/* 8090 */ { MAD_F(0x04f4c8fa) /* 0.309761980 */, 19 }, +/* 8091 */ { MAD_F(0x04f4fe83) /* 0.309813033 */, 19 }, +/* 8092 */ { MAD_F(0x04f5340c) /* 0.309864089 */, 19 }, +/* 8093 */ { MAD_F(0x04f56996) /* 0.309915147 */, 19 }, +/* 8094 */ { MAD_F(0x04f59f20) /* 0.309966207 */, 19 }, +/* 8095 */ { MAD_F(0x04f5d4ab) /* 0.310017269 */, 19 }, + +/* 8096 */ { MAD_F(0x04f60a36) /* 0.310068333 */, 19 }, +/* 8097 */ { MAD_F(0x04f63fc2) /* 0.310119400 */, 19 }, +/* 8098 */ { MAD_F(0x04f6754f) /* 0.310170468 */, 19 }, +/* 8099 */ { MAD_F(0x04f6aadc) /* 0.310221539 */, 19 }, +/* 8100 */ { MAD_F(0x04f6e06a) /* 0.310272611 */, 19 }, +/* 8101 */ { MAD_F(0x04f715f8) /* 0.310323686 */, 19 }, +/* 8102 */ { MAD_F(0x04f74b87) /* 0.310374763 */, 19 }, +/* 8103 */ { MAD_F(0x04f78116) /* 0.310425842 */, 19 }, +/* 8104 */ { MAD_F(0x04f7b6a6) /* 0.310476923 */, 19 }, +/* 8105 */ { MAD_F(0x04f7ec37) /* 0.310528006 */, 19 }, +/* 8106 */ { MAD_F(0x04f821c8) /* 0.310579091 */, 19 }, +/* 8107 */ { MAD_F(0x04f85759) /* 0.310630179 */, 19 }, +/* 8108 */ { MAD_F(0x04f88cec) /* 0.310681268 */, 19 }, +/* 8109 */ { MAD_F(0x04f8c27e) /* 0.310732360 */, 19 }, +/* 8110 */ { MAD_F(0x04f8f812) /* 0.310783453 */, 19 }, +/* 8111 */ { MAD_F(0x04f92da6) /* 0.310834549 */, 19 }, + +/* 8112 */ { MAD_F(0x04f9633a) /* 0.310885647 */, 19 }, +/* 8113 */ { MAD_F(0x04f998cf) /* 0.310936747 */, 19 }, +/* 8114 */ { MAD_F(0x04f9ce65) /* 0.310987849 */, 19 }, +/* 8115 */ { MAD_F(0x04fa03fb) /* 0.311038953 */, 19 }, +/* 8116 */ { MAD_F(0x04fa3992) /* 0.311090059 */, 19 }, +/* 8117 */ { MAD_F(0x04fa6f29) /* 0.311141168 */, 19 }, +/* 8118 */ { MAD_F(0x04faa4c1) /* 0.311192278 */, 19 }, +/* 8119 */ { MAD_F(0x04fada59) /* 0.311243390 */, 19 }, +/* 8120 */ { MAD_F(0x04fb0ff2) /* 0.311294505 */, 19 }, +/* 8121 */ { MAD_F(0x04fb458c) /* 0.311345622 */, 19 }, +/* 8122 */ { MAD_F(0x04fb7b26) /* 0.311396741 */, 19 }, +/* 8123 */ { MAD_F(0x04fbb0c1) /* 0.311447862 */, 19 }, +/* 8124 */ { MAD_F(0x04fbe65c) /* 0.311498985 */, 19 }, +/* 8125 */ { MAD_F(0x04fc1bf8) /* 0.311550110 */, 19 }, +/* 8126 */ { MAD_F(0x04fc5194) /* 0.311601237 */, 19 }, +/* 8127 */ { MAD_F(0x04fc8731) /* 0.311652366 */, 19 }, + +/* 8128 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 19 }, +/* 8129 */ { MAD_F(0x04fcf26c) /* 0.311754631 */, 19 }, +/* 8130 */ { MAD_F(0x04fd280b) /* 0.311805767 */, 19 }, +/* 8131 */ { MAD_F(0x04fd5daa) /* 0.311856905 */, 19 }, +/* 8132 */ { MAD_F(0x04fd934a) /* 0.311908044 */, 19 }, +/* 8133 */ { MAD_F(0x04fdc8ea) /* 0.311959186 */, 19 }, +/* 8134 */ { MAD_F(0x04fdfe8b) /* 0.312010330 */, 19 }, +/* 8135 */ { MAD_F(0x04fe342c) /* 0.312061476 */, 19 }, +/* 8136 */ { MAD_F(0x04fe69ce) /* 0.312112625 */, 19 }, +/* 8137 */ { MAD_F(0x04fe9f71) /* 0.312163775 */, 19 }, +/* 8138 */ { MAD_F(0x04fed514) /* 0.312214927 */, 19 }, +/* 8139 */ { MAD_F(0x04ff0ab8) /* 0.312266082 */, 19 }, +/* 8140 */ { MAD_F(0x04ff405c) /* 0.312317238 */, 19 }, +/* 8141 */ { MAD_F(0x04ff7601) /* 0.312368397 */, 19 }, +/* 8142 */ { MAD_F(0x04ffaba6) /* 0.312419558 */, 19 }, +/* 8143 */ { MAD_F(0x04ffe14c) /* 0.312470720 */, 19 }, + +/* 8144 */ { MAD_F(0x050016f3) /* 0.312521885 */, 19 }, +/* 8145 */ { MAD_F(0x05004c9a) /* 0.312573052 */, 19 }, +/* 8146 */ { MAD_F(0x05008241) /* 0.312624222 */, 19 }, +/* 8147 */ { MAD_F(0x0500b7e9) /* 0.312675393 */, 19 }, +/* 8148 */ { MAD_F(0x0500ed92) /* 0.312726566 */, 19 }, +/* 8149 */ { MAD_F(0x0501233b) /* 0.312777742 */, 19 }, +/* 8150 */ { MAD_F(0x050158e5) /* 0.312828919 */, 19 }, +/* 8151 */ { MAD_F(0x05018e90) /* 0.312880099 */, 19 }, +/* 8152 */ { MAD_F(0x0501c43b) /* 0.312931280 */, 19 }, +/* 8153 */ { MAD_F(0x0501f9e6) /* 0.312982464 */, 19 }, +/* 8154 */ { MAD_F(0x05022f92) /* 0.313033650 */, 19 }, +/* 8155 */ { MAD_F(0x0502653f) /* 0.313084838 */, 19 }, +/* 8156 */ { MAD_F(0x05029aec) /* 0.313136028 */, 19 }, +/* 8157 */ { MAD_F(0x0502d09a) /* 0.313187220 */, 19 }, +/* 8158 */ { MAD_F(0x05030648) /* 0.313238414 */, 19 }, +/* 8159 */ { MAD_F(0x05033bf7) /* 0.313289611 */, 19 }, + +/* 8160 */ { MAD_F(0x050371a7) /* 0.313340809 */, 19 }, +/* 8161 */ { MAD_F(0x0503a757) /* 0.313392010 */, 19 }, +/* 8162 */ { MAD_F(0x0503dd07) /* 0.313443212 */, 19 }, +/* 8163 */ { MAD_F(0x050412b9) /* 0.313494417 */, 19 }, +/* 8164 */ { MAD_F(0x0504486a) /* 0.313545624 */, 19 }, +/* 8165 */ { MAD_F(0x05047e1d) /* 0.313596833 */, 19 }, +/* 8166 */ { MAD_F(0x0504b3cf) /* 0.313648044 */, 19 }, +/* 8167 */ { MAD_F(0x0504e983) /* 0.313699257 */, 19 }, +/* 8168 */ { MAD_F(0x05051f37) /* 0.313750472 */, 19 }, +/* 8169 */ { MAD_F(0x050554eb) /* 0.313801689 */, 19 }, +/* 8170 */ { MAD_F(0x05058aa0) /* 0.313852909 */, 19 }, +/* 8171 */ { MAD_F(0x0505c056) /* 0.313904130 */, 19 }, +/* 8172 */ { MAD_F(0x0505f60c) /* 0.313955354 */, 19 }, +/* 8173 */ { MAD_F(0x05062bc3) /* 0.314006579 */, 19 }, +/* 8174 */ { MAD_F(0x0506617a) /* 0.314057807 */, 19 }, +/* 8175 */ { MAD_F(0x05069732) /* 0.314109037 */, 19 }, + +/* 8176 */ { MAD_F(0x0506cceb) /* 0.314160269 */, 19 }, +/* 8177 */ { MAD_F(0x050702a4) /* 0.314211502 */, 19 }, +/* 8178 */ { MAD_F(0x0507385d) /* 0.314262739 */, 19 }, +/* 8179 */ { MAD_F(0x05076e17) /* 0.314313977 */, 19 }, +/* 8180 */ { MAD_F(0x0507a3d2) /* 0.314365217 */, 19 }, +/* 8181 */ { MAD_F(0x0507d98d) /* 0.314416459 */, 19 }, +/* 8182 */ { MAD_F(0x05080f49) /* 0.314467704 */, 19 }, +/* 8183 */ { MAD_F(0x05084506) /* 0.314518950 */, 19 }, +/* 8184 */ { MAD_F(0x05087ac2) /* 0.314570199 */, 19 }, +/* 8185 */ { MAD_F(0x0508b080) /* 0.314621449 */, 19 }, +/* 8186 */ { MAD_F(0x0508e63e) /* 0.314672702 */, 19 }, +/* 8187 */ { MAD_F(0x05091bfd) /* 0.314723957 */, 19 }, +/* 8188 */ { MAD_F(0x050951bc) /* 0.314775214 */, 19 }, +/* 8189 */ { MAD_F(0x0509877c) /* 0.314826473 */, 19 }, +/* 8190 */ { MAD_F(0x0509bd3c) /* 0.314877734 */, 19 }, +/* 8191 */ { MAD_F(0x0509f2fd) /* 0.314928997 */, 19 }, + +/* 8192 */ { MAD_F(0x050a28be) /* 0.314980262 */, 19 }, +/* 8193 */ { MAD_F(0x050a5e80) /* 0.315031530 */, 19 }, +/* 8194 */ { MAD_F(0x050a9443) /* 0.315082799 */, 19 }, +/* 8195 */ { MAD_F(0x050aca06) /* 0.315134071 */, 19 }, +/* 8196 */ { MAD_F(0x050affc9) /* 0.315185344 */, 19 }, +/* 8197 */ { MAD_F(0x050b358e) /* 0.315236620 */, 19 }, +/* 8198 */ { MAD_F(0x050b6b52) /* 0.315287898 */, 19 }, +/* 8199 */ { MAD_F(0x050ba118) /* 0.315339178 */, 19 }, +/* 8200 */ { MAD_F(0x050bd6de) /* 0.315390460 */, 19 }, +/* 8201 */ { MAD_F(0x050c0ca4) /* 0.315441744 */, 19 }, +/* 8202 */ { MAD_F(0x050c426b) /* 0.315493030 */, 19 }, +/* 8203 */ { MAD_F(0x050c7833) /* 0.315544318 */, 19 }, +/* 8204 */ { MAD_F(0x050cadfb) /* 0.315595608 */, 19 }, +/* 8205 */ { MAD_F(0x050ce3c4) /* 0.315646901 */, 19 }, +/* 8206 */ { MAD_F(0x050d198d) /* 0.315698195 */, 19 } diff --git a/src/libmad/sf_table.dat.h b/src/libmad/sf_table.dat.h index db1484a0..5432d8d3 100644 --- a/src/libmad/sf_table.dat.h +++ b/src/libmad/sf_table.dat.h @@ -1,106 +1,106 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: sf_table.dat,v 1.7 2004/01/23 09:41:33 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: sf_table.dat,v 1.7 2004/01/23 09:41:33 rob Exp $ +*/ /* - * These are the scalefactor values for Layer I and Layer II. - * The values are from Table B.1 of ISO/IEC 11172-3. - * - * There is some error introduced by the 32-bit fixed-point representation; - * the amount of error is shown. For 16-bit PCM output, this shouldn't be - * too much of a problem. - * - * Strictly speaking, Table B.1 has only 63 entries (0-62), thus a strict - * interpretation of ISO/IEC 11172-3 would suggest that a scalefactor index of - * 63 is invalid. However, for better compatibility with current practices, we - * add a 64th entry. - */ + These are the scalefactor values for Layer I and Layer II. + The values are from Table B.1 of ISO/IEC 11172-3. + + There is some error introduced by the 32-bit fixed-point representation; + the amount of error is shown. For 16-bit PCM output, this shouldn't be + too much of a problem. + + Strictly speaking, Table B.1 has only 63 entries (0-62), thus a strict + interpretation of ISO/IEC 11172-3 would suggest that a scalefactor index of + 63 is invalid. However, for better compatibility with current practices, we + add a 64th entry. +*/ - MAD_F(0x20000000), /* 2.000000000000 => 2.000000000000, e 0.000000000000 */ - MAD_F(0x1965fea5), /* 1.587401051968 => 1.587401051074, e 0.000000000894 */ - MAD_F(0x1428a2fa), /* 1.259921049895 => 1.259921051562, e -0.000000001667 */ - MAD_F(0x10000000), /* 1.000000000000 => 1.000000000000, e 0.000000000000 */ - MAD_F(0x0cb2ff53), /* 0.793700525984 => 0.793700527400, e -0.000000001416 */ - MAD_F(0x0a14517d), /* 0.629960524947 => 0.629960525781, e -0.000000000833 */ - MAD_F(0x08000000), /* 0.500000000000 => 0.500000000000, e 0.000000000000 */ - MAD_F(0x06597fa9), /* 0.396850262992 => 0.396850261837, e 0.000000001155 */ +MAD_F(0x20000000), /* 2.000000000000 => 2.000000000000, e 0.000000000000 */ + MAD_F(0x1965fea5), /* 1.587401051968 => 1.587401051074, e 0.000000000894 */ + MAD_F(0x1428a2fa), /* 1.259921049895 => 1.259921051562, e -0.000000001667 */ + MAD_F(0x10000000), /* 1.000000000000 => 1.000000000000, e 0.000000000000 */ + MAD_F(0x0cb2ff53), /* 0.793700525984 => 0.793700527400, e -0.000000001416 */ + MAD_F(0x0a14517d), /* 0.629960524947 => 0.629960525781, e -0.000000000833 */ + MAD_F(0x08000000), /* 0.500000000000 => 0.500000000000, e 0.000000000000 */ + MAD_F(0x06597fa9), /* 0.396850262992 => 0.396850261837, e 0.000000001155 */ - MAD_F(0x050a28be), /* 0.314980262474 => 0.314980261028, e 0.000000001446 */ - MAD_F(0x04000000), /* 0.250000000000 => 0.250000000000, e 0.000000000000 */ - MAD_F(0x032cbfd5), /* 0.198425131496 => 0.198425132781, e -0.000000001285 */ - MAD_F(0x0285145f), /* 0.157490131237 => 0.157490130514, e 0.000000000723 */ - MAD_F(0x02000000), /* 0.125000000000 => 0.125000000000, e 0.000000000000 */ - MAD_F(0x01965fea), /* 0.099212565748 => 0.099212564528, e 0.000000001220 */ - MAD_F(0x01428a30), /* 0.078745065618 => 0.078745067120, e -0.000000001501 */ - MAD_F(0x01000000), /* 0.062500000000 => 0.062500000000, e 0.000000000000 */ + MAD_F(0x050a28be), /* 0.314980262474 => 0.314980261028, e 0.000000001446 */ + MAD_F(0x04000000), /* 0.250000000000 => 0.250000000000, e 0.000000000000 */ + MAD_F(0x032cbfd5), /* 0.198425131496 => 0.198425132781, e -0.000000001285 */ + MAD_F(0x0285145f), /* 0.157490131237 => 0.157490130514, e 0.000000000723 */ + MAD_F(0x02000000), /* 0.125000000000 => 0.125000000000, e 0.000000000000 */ + MAD_F(0x01965fea), /* 0.099212565748 => 0.099212564528, e 0.000000001220 */ + MAD_F(0x01428a30), /* 0.078745065618 => 0.078745067120, e -0.000000001501 */ + MAD_F(0x01000000), /* 0.062500000000 => 0.062500000000, e 0.000000000000 */ - MAD_F(0x00cb2ff5), /* 0.049606282874 => 0.049606282264, e 0.000000000610 */ - MAD_F(0x00a14518), /* 0.039372532809 => 0.039372533560, e -0.000000000751 */ - MAD_F(0x00800000), /* 0.031250000000 => 0.031250000000, e 0.000000000000 */ - MAD_F(0x006597fb), /* 0.024803141437 => 0.024803142995, e -0.000000001558 */ - MAD_F(0x0050a28c), /* 0.019686266405 => 0.019686266780, e -0.000000000375 */ - MAD_F(0x00400000), /* 0.015625000000 => 0.015625000000, e 0.000000000000 */ - MAD_F(0x0032cbfd), /* 0.012401570719 => 0.012401569635, e 0.000000001084 */ - MAD_F(0x00285146), /* 0.009843133202 => 0.009843133390, e -0.000000000188 */ + MAD_F(0x00cb2ff5), /* 0.049606282874 => 0.049606282264, e 0.000000000610 */ + MAD_F(0x00a14518), /* 0.039372532809 => 0.039372533560, e -0.000000000751 */ + MAD_F(0x00800000), /* 0.031250000000 => 0.031250000000, e 0.000000000000 */ + MAD_F(0x006597fb), /* 0.024803141437 => 0.024803142995, e -0.000000001558 */ + MAD_F(0x0050a28c), /* 0.019686266405 => 0.019686266780, e -0.000000000375 */ + MAD_F(0x00400000), /* 0.015625000000 => 0.015625000000, e 0.000000000000 */ + MAD_F(0x0032cbfd), /* 0.012401570719 => 0.012401569635, e 0.000000001084 */ + MAD_F(0x00285146), /* 0.009843133202 => 0.009843133390, e -0.000000000188 */ - MAD_F(0x00200000), /* 0.007812500000 => 0.007812500000, e 0.000000000000 */ - MAD_F(0x001965ff), /* 0.006200785359 => 0.006200786680, e -0.000000001321 */ - MAD_F(0x001428a3), /* 0.004921566601 => 0.004921566695, e -0.000000000094 */ - MAD_F(0x00100000), /* 0.003906250000 => 0.003906250000, e 0.000000000000 */ - MAD_F(0x000cb2ff), /* 0.003100392680 => 0.003100391477, e 0.000000001202 */ - MAD_F(0x000a1451), /* 0.002460783301 => 0.002460781485, e 0.000000001816 */ - MAD_F(0x00080000), /* 0.001953125000 => 0.001953125000, e 0.000000000000 */ - MAD_F(0x00065980), /* 0.001550196340 => 0.001550197601, e -0.000000001262 */ + MAD_F(0x00200000), /* 0.007812500000 => 0.007812500000, e 0.000000000000 */ + MAD_F(0x001965ff), /* 0.006200785359 => 0.006200786680, e -0.000000001321 */ + MAD_F(0x001428a3), /* 0.004921566601 => 0.004921566695, e -0.000000000094 */ + MAD_F(0x00100000), /* 0.003906250000 => 0.003906250000, e 0.000000000000 */ + MAD_F(0x000cb2ff), /* 0.003100392680 => 0.003100391477, e 0.000000001202 */ + MAD_F(0x000a1451), /* 0.002460783301 => 0.002460781485, e 0.000000001816 */ + MAD_F(0x00080000), /* 0.001953125000 => 0.001953125000, e 0.000000000000 */ + MAD_F(0x00065980), /* 0.001550196340 => 0.001550197601, e -0.000000001262 */ - MAD_F(0x00050a29), /* 0.001230391650 => 0.001230392605, e -0.000000000955 */ - MAD_F(0x00040000), /* 0.000976562500 => 0.000976562500, e 0.000000000000 */ - MAD_F(0x00032cc0), /* 0.000775098170 => 0.000775098801, e -0.000000000631 */ - MAD_F(0x00028514), /* 0.000615195825 => 0.000615194440, e 0.000000001385 */ - MAD_F(0x00020000), /* 0.000488281250 => 0.000488281250, e 0.000000000000 */ - MAD_F(0x00019660), /* 0.000387549085 => 0.000387549400, e -0.000000000315 */ - MAD_F(0x0001428a), /* 0.000307597913 => 0.000307597220, e 0.000000000693 */ - MAD_F(0x00010000), /* 0.000244140625 => 0.000244140625, e 0.000000000000 */ + MAD_F(0x00050a29), /* 0.001230391650 => 0.001230392605, e -0.000000000955 */ + MAD_F(0x00040000), /* 0.000976562500 => 0.000976562500, e 0.000000000000 */ + MAD_F(0x00032cc0), /* 0.000775098170 => 0.000775098801, e -0.000000000631 */ + MAD_F(0x00028514), /* 0.000615195825 => 0.000615194440, e 0.000000001385 */ + MAD_F(0x00020000), /* 0.000488281250 => 0.000488281250, e 0.000000000000 */ + MAD_F(0x00019660), /* 0.000387549085 => 0.000387549400, e -0.000000000315 */ + MAD_F(0x0001428a), /* 0.000307597913 => 0.000307597220, e 0.000000000693 */ + MAD_F(0x00010000), /* 0.000244140625 => 0.000244140625, e 0.000000000000 */ - MAD_F(0x0000cb30), /* 0.000193774542 => 0.000193774700, e -0.000000000158 */ - MAD_F(0x0000a145), /* 0.000153798956 => 0.000153798610, e 0.000000000346 */ - MAD_F(0x00008000), /* 0.000122070313 => 0.000122070313, e 0.000000000000 */ - MAD_F(0x00006598), /* 0.000096887271 => 0.000096887350, e -0.000000000079 */ - MAD_F(0x000050a3), /* 0.000076899478 => 0.000076901168, e -0.000000001689 */ - MAD_F(0x00004000), /* 0.000061035156 => 0.000061035156, e 0.000000000000 */ - MAD_F(0x000032cc), /* 0.000048443636 => 0.000048443675, e -0.000000000039 */ - MAD_F(0x00002851), /* 0.000038449739 => 0.000038448721, e 0.000000001018 */ + MAD_F(0x0000cb30), /* 0.000193774542 => 0.000193774700, e -0.000000000158 */ + MAD_F(0x0000a145), /* 0.000153798956 => 0.000153798610, e 0.000000000346 */ + MAD_F(0x00008000), /* 0.000122070313 => 0.000122070313, e 0.000000000000 */ + MAD_F(0x00006598), /* 0.000096887271 => 0.000096887350, e -0.000000000079 */ + MAD_F(0x000050a3), /* 0.000076899478 => 0.000076901168, e -0.000000001689 */ + MAD_F(0x00004000), /* 0.000061035156 => 0.000061035156, e 0.000000000000 */ + MAD_F(0x000032cc), /* 0.000048443636 => 0.000048443675, e -0.000000000039 */ + MAD_F(0x00002851), /* 0.000038449739 => 0.000038448721, e 0.000000001018 */ - MAD_F(0x00002000), /* 0.000030517578 => 0.000030517578, e 0.000000000000 */ - MAD_F(0x00001966), /* 0.000024221818 => 0.000024221838, e -0.000000000020 */ - MAD_F(0x00001429), /* 0.000019224870 => 0.000019226223, e -0.000000001354 */ - MAD_F(0x00001000), /* 0.000015258789 => 0.000015258789, e -0.000000000000 */ - MAD_F(0x00000cb3), /* 0.000012110909 => 0.000012110919, e -0.000000000010 */ - MAD_F(0x00000a14), /* 0.000009612435 => 0.000009611249, e 0.000000001186 */ - MAD_F(0x00000800), /* 0.000007629395 => 0.000007629395, e -0.000000000000 */ - MAD_F(0x00000659), /* 0.000006055454 => 0.000006053597, e 0.000000001858 */ + MAD_F(0x00002000), /* 0.000030517578 => 0.000030517578, e 0.000000000000 */ + MAD_F(0x00001966), /* 0.000024221818 => 0.000024221838, e -0.000000000020 */ + MAD_F(0x00001429), /* 0.000019224870 => 0.000019226223, e -0.000000001354 */ + MAD_F(0x00001000), /* 0.000015258789 => 0.000015258789, e -0.000000000000 */ + MAD_F(0x00000cb3), /* 0.000012110909 => 0.000012110919, e -0.000000000010 */ + MAD_F(0x00000a14), /* 0.000009612435 => 0.000009611249, e 0.000000001186 */ + MAD_F(0x00000800), /* 0.000007629395 => 0.000007629395, e -0.000000000000 */ + MAD_F(0x00000659), /* 0.000006055454 => 0.000006053597, e 0.000000001858 */ - MAD_F(0x0000050a), /* 0.000004806217 => 0.000004805624, e 0.000000000593 */ - MAD_F(0x00000400), /* 0.000003814697 => 0.000003814697, e 0.000000000000 */ - MAD_F(0x0000032d), /* 0.000003027727 => 0.000003028661, e -0.000000000934 */ - MAD_F(0x00000285), /* 0.000002403109 => 0.000002402812, e 0.000000000296 */ - MAD_F(0x00000200), /* 0.000001907349 => 0.000001907349, e -0.000000000000 */ - MAD_F(0x00000196), /* 0.000001513864 => 0.000001512468, e 0.000000001396 */ - MAD_F(0x00000143), /* 0.000001201554 => 0.000001203269, e -0.000000001714 */ - MAD_F(0x00000000) /* this compatibility entry is not part of Table B.1 */ + MAD_F(0x0000050a), /* 0.000004806217 => 0.000004805624, e 0.000000000593 */ + MAD_F(0x00000400), /* 0.000003814697 => 0.000003814697, e 0.000000000000 */ + MAD_F(0x0000032d), /* 0.000003027727 => 0.000003028661, e -0.000000000934 */ + MAD_F(0x00000285), /* 0.000002403109 => 0.000002402812, e 0.000000000296 */ + MAD_F(0x00000200), /* 0.000001907349 => 0.000001907349, e -0.000000000000 */ + MAD_F(0x00000196), /* 0.000001513864 => 0.000001512468, e 0.000000001396 */ + MAD_F(0x00000143), /* 0.000001201554 => 0.000001203269, e -0.000000001714 */ + MAD_F(0x00000000) /* this compatibility entry is not part of Table B.1 */ diff --git a/src/libmad/stream.c b/src/libmad/stream.c index 837cd9e7..c9d43b94 100644 --- a/src/libmad/stream.c +++ b/src/libmad/stream.c @@ -1,23 +1,23 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: stream.c,v 1.12 2004/02/05 09:02:39 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: stream.c,v 1.12 2004/02/05 09:02:39 rob Exp $ +*/ #pragma GCC optimize ("O3") @@ -32,133 +32,129 @@ # include "stream.h" /* - * NAME: stream->init() - * DESCRIPTION: initialize stream struct - */ -void mad_stream_init(struct mad_stream *stream) -{ -stack(__FUNCTION__, __FILE__, __LINE__); - stream->buffer = 0; - stream->bufend = 0; - stream->skiplen = 0; - - stream->sync = 0; - stream->freerate = 0; - - stream->this_frame = 0; - stream->next_frame = 0; - mad_bit_init(&stream->ptr, 0); - - mad_bit_init(&stream->anc_ptr, 0); - stream->anc_bitlen = 0; - - stream->md_len = 0; - - stream->options = 0; - stream->error = MAD_ERROR_NONE; + NAME: stream->init() + DESCRIPTION: initialize stream struct +*/ +void mad_stream_init(struct mad_stream *stream) { + stackenter(__FUNCTION__, __FILE__, __LINE__); + stream->buffer = 0; + stream->bufend = 0; + stream->skiplen = 0; + + stream->sync = 0; + stream->freerate = 0; + + stream->this_frame = 0; + stream->next_frame = 0; + mad_bit_init(&stream->ptr, 0); + + mad_bit_init(&stream->anc_ptr, 0); + stream->anc_bitlen = 0; + + stream->md_len = 0; + + stream->options = 0; + stream->error = MAD_ERROR_NONE; } /* - * NAME: stream->finish() - * DESCRIPTION: deallocate any dynamic memory associated with stream - */ -void mad_stream_finish(struct mad_stream *stream) -{ -stack(__FUNCTION__, __FILE__, __LINE__); - (void) stream; - - mad_bit_finish(&stream->anc_ptr); - mad_bit_finish(&stream->ptr); + NAME: stream->finish() + DESCRIPTION: deallocate any dynamic memory associated with stream +*/ +void mad_stream_finish(struct mad_stream *stream) { + stackenter(__FUNCTION__, __FILE__, __LINE__); + (void) stream; + + mad_bit_finish(&stream->anc_ptr); + mad_bit_finish(&stream->ptr); } /* - * NAME: stream->buffer() - * DESCRIPTION: set stream buffer pointers - */ + NAME: stream->buffer() + DESCRIPTION: set stream buffer pointers +*/ void mad_stream_buffer(struct mad_stream *stream, - unsigned char const *buffer, unsigned long length) -{ -stack(__FUNCTION__, __FILE__, __LINE__); - stream->buffer = buffer; - stream->bufend = buffer + length; + unsigned char const *buffer, unsigned long length) { + stackenter(__FUNCTION__, __FILE__, __LINE__); + stream->buffer = buffer; + stream->bufend = buffer + length; - stream->this_frame = buffer; - stream->next_frame = buffer; + stream->this_frame = buffer; + stream->next_frame = buffer; - stream->sync = 1; + stream->sync = 1; - mad_bit_init(&stream->ptr, buffer); + mad_bit_init(&stream->ptr, buffer); } /* - * NAME: stream->skip() - * DESCRIPTION: arrange to skip bytes before the next frame - */ -void mad_stream_skip(struct mad_stream *stream, unsigned long length) -{ -stack(__FUNCTION__, __FILE__, __LINE__); - stream->skiplen += length; + NAME: stream->skip() + DESCRIPTION: arrange to skip bytes before the next frame +*/ +void mad_stream_skip(struct mad_stream *stream, unsigned long length) { + stackenter(__FUNCTION__, __FILE__, __LINE__); + stream->skiplen += length; } /* - * NAME: stream->sync() - * DESCRIPTION: locate the next stream sync word - */ -int mad_stream_sync(struct mad_stream *stream) -{ - register unsigned char const *ptr, *end; -stack(__FUNCTION__, __FILE__, __LINE__); + NAME: stream->sync() + DESCRIPTION: locate the next stream sync word +*/ +int mad_stream_sync(struct mad_stream *stream) { + register unsigned char const *ptr, *end; + stackenter(__FUNCTION__, __FILE__, __LINE__); - ptr = mad_bit_nextbyte(&stream->ptr); - end = stream->bufend; + ptr = mad_bit_nextbyte(&stream->ptr); + end = stream->bufend; - while (ptr < end - 1 && - !(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) - ++ptr; + while (ptr < end - 1 && + !(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) { + ++ptr; + } - if (end - ptr < MAD_BUFFER_GUARD) - return -1; + if (end - ptr < MAD_BUFFER_GUARD) { + return -1; + } - mad_bit_init(&stream->ptr, ptr); + mad_bit_init(&stream->ptr, ptr); - return 0; + return 0; } /* - * NAME: stream->errorstr() - * DESCRIPTION: return a string description of the current error condition - */ -char const *mad_stream_errorstr(struct mad_stream const *stream) -{ -stack(__FUNCTION__, __FILE__, __LINE__); - switch (stream->error) { - case MAD_ERROR_NONE: return PSTR("no error"); - - case MAD_ERROR_BUFLEN: return PSTR("input buffer too small (or EOF)"); - case MAD_ERROR_BUFPTR: return PSTR("invalid (null) buffer pointer"); - - case MAD_ERROR_NOMEM: return PSTR("not enough memory"); - - case MAD_ERROR_LOSTSYNC: return PSTR("lost synchronization"); - case MAD_ERROR_BADLAYER: return PSTR("reserved header layer value"); - case MAD_ERROR_BADBITRATE: return PSTR("forbidden bitrate value"); - case MAD_ERROR_BADSAMPLERATE: return PSTR("reserved sample frequency value"); - case MAD_ERROR_BADEMPHASIS: return PSTR("reserved emphasis value"); - - case MAD_ERROR_BADCRC: return PSTR("CRC check failed"); - case MAD_ERROR_BADBITALLOC: return PSTR("forbidden bit allocation value"); - case MAD_ERROR_BADSCALEFACTOR: return PSTR("bad scalefactor index"); - case MAD_ERROR_BADMODE: return PSTR("bad bitrate/mode combination"); - case MAD_ERROR_BADFRAMELEN: return PSTR("bad frame length"); - case MAD_ERROR_BADBIGVALUES: return PSTR("bad big_values count"); - case MAD_ERROR_BADBLOCKTYPE: return PSTR("reserved block_type"); - case MAD_ERROR_BADSCFSI: return PSTR("bad scalefactor selection info"); - case MAD_ERROR_BADDATAPTR: return PSTR("bad main_data_begin pointer"); - case MAD_ERROR_BADPART3LEN: return PSTR("bad audio data length"); - case MAD_ERROR_BADHUFFTABLE: return PSTR("bad Huffman table select"); - case MAD_ERROR_BADHUFFDATA: return PSTR("Huffman data overrun"); - case MAD_ERROR_BADSTEREO: return PSTR("incompatible block_type for JS"); - } - - return 0; + NAME: stream->errorstr() + DESCRIPTION: return a string description of the current error condition +*/ +char const *mad_stream_errorstr(struct mad_stream const *stream) { + stackenter(__FUNCTION__, __FILE__, __LINE__); + switch (stream->error) { + case MAD_ERROR_NONE: return PSTR("no error"); + + case MAD_ERROR_BUFLEN: return PSTR("input buffer too small (or EOF)"); + case MAD_ERROR_BUFPTR: return PSTR("invalid (null) buffer pointer"); + + case MAD_ERROR_NOMEM: return PSTR("not enough memory"); + + case MAD_ERROR_LOSTSYNC: return PSTR("lost synchronization"); + case MAD_ERROR_BADLAYER: return PSTR("reserved header layer value"); + case MAD_ERROR_BADBITRATE: return PSTR("forbidden bitrate value"); + case MAD_ERROR_BADSAMPLERATE: return PSTR("reserved sample frequency value"); + case MAD_ERROR_BADEMPHASIS: return PSTR("reserved emphasis value"); + + case MAD_ERROR_BADCRC: return PSTR("CRC check failed"); + case MAD_ERROR_BADBITALLOC: return PSTR("forbidden bit allocation value"); + case MAD_ERROR_BADSCALEFACTOR: return PSTR("bad scalefactor index"); + case MAD_ERROR_BADMODE: return PSTR("bad bitrate/mode combination"); + case MAD_ERROR_BADFRAMELEN: return PSTR("bad frame length"); + case MAD_ERROR_BADBIGVALUES: return PSTR("bad big_values count"); + case MAD_ERROR_BADBLOCKTYPE: return PSTR("reserved block_type"); + case MAD_ERROR_BADSCFSI: return PSTR("bad scalefactor selection info"); + case MAD_ERROR_BADDATAPTR: return PSTR("bad main_data_begin pointer"); + case MAD_ERROR_BADPART3LEN: return PSTR("bad audio data length"); + case MAD_ERROR_BADHUFFTABLE: return PSTR("bad Huffman table select"); + case MAD_ERROR_BADHUFFDATA: return PSTR("Huffman data overrun"); + case MAD_ERROR_BADSTEREO: return PSTR("incompatible block_type for JS"); + } + + return 0; } diff --git a/src/libmad/stream.h b/src/libmad/stream.h index 8dc8ec12..7661ee8d 100644 --- a/src/libmad/stream.h +++ b/src/libmad/stream.h @@ -1,23 +1,23 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: stream.h,v 1.20 2004/02/05 09:02:39 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: stream.h,v 1.20 2004/02/05 09:02:39 rob Exp $ +*/ # ifndef LIBMAD_STREAM_H # define LIBMAD_STREAM_H @@ -28,66 +28,66 @@ # define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD) enum mad_error { - MAD_ERROR_NONE = 0x0000, /* no error */ - - MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */ - MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */ - - MAD_ERROR_NOMEM = 0x0031, /* not enough memory */ - - MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */ - MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */ - MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */ - MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */ - MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */ - - MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */ - MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */ - MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */ - MAD_ERROR_BADMODE = 0x0222, /* bad bitrate/mode combination */ - MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */ - MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */ - MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */ - MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */ - MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */ - MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */ - MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */ - MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */ - MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */ + MAD_ERROR_NONE = 0x0000, /* no error */ + + MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */ + MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */ + + MAD_ERROR_NOMEM = 0x0031, /* not enough memory */ + + MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */ + MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */ + MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */ + MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */ + MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */ + + MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */ + MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */ + MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */ + MAD_ERROR_BADMODE = 0x0222, /* bad bitrate/mode combination */ + MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */ + MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */ + MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */ + MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */ + MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */ + MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */ + MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */ + MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */ + MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */ }; # define MAD_RECOVERABLE(error) ((error) & 0xff00) struct mad_stream { - unsigned char const *buffer; /* input bitstream buffer */ - unsigned char const *bufend; /* end of buffer */ - unsigned long skiplen; /* bytes to skip before next frame */ + unsigned char const *buffer; /* input bitstream buffer */ + unsigned char const *bufend; /* end of buffer */ + unsigned long skiplen; /* bytes to skip before next frame */ - int sync; /* stream sync found */ - unsigned long freerate; /* free bitrate (fixed) */ + int sync; /* stream sync found */ + unsigned long freerate; /* free bitrate (fixed) */ - unsigned char const *this_frame; /* start of current frame */ - unsigned char const *next_frame; /* start of next frame */ - struct mad_bitptr ptr; /* current processing bit pointer */ + unsigned char const *this_frame; /* start of current frame */ + unsigned char const *next_frame; /* start of next frame */ + struct mad_bitptr ptr; /* current processing bit pointer */ - struct mad_bitptr anc_ptr; /* ancillary bits pointer */ - unsigned int anc_bitlen; /* number of ancillary bits */ + struct mad_bitptr anc_ptr; /* ancillary bits pointer */ + unsigned int anc_bitlen; /* number of ancillary bits */ - unsigned char main_data[MAD_BUFFER_MDLEN]; - /* Layer III main_data() */ - unsigned int md_len; /* bytes in main_data */ + unsigned char main_data[MAD_BUFFER_MDLEN]; + /* Layer III main_data() */ + unsigned int md_len; /* bytes in main_data */ - int options; /* decoding options (see below) */ - enum mad_error error; /* error code (see above) */ + int options; /* decoding options (see below) */ + enum mad_error error; /* error code (see above) */ }; enum { - MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */ - MAD_OPTION_HALFSAMPLERATE = 0x0002 /* generate PCM at 1/2 sample rate */ + MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */ + MAD_OPTION_HALFSAMPLERATE = 0x0002 /* generate PCM at 1/2 sample rate */ # if 0 /* not yet implemented */ - MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */ - MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */ - MAD_OPTION_SINGLECHANNEL = 0x0030 /* combine channels */ + MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */ + MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */ + MAD_OPTION_SINGLECHANNEL = 0x0030 /* combine channels */ # endif }; @@ -98,7 +98,7 @@ void mad_stream_finish(struct mad_stream *); ((void) ((stream)->options = (opts))) void mad_stream_buffer(struct mad_stream *, - unsigned char const *, unsigned long); + unsigned char const *, unsigned long); void mad_stream_skip(struct mad_stream *, unsigned long); int mad_stream_sync(struct mad_stream *); diff --git a/src/libmad/synth.c b/src/libmad/synth.c index d694b5c9..833d77a7 100644 --- a/src/libmad/synth.c +++ b/src/libmad/synth.c @@ -1,22 +1,22 @@ /* - libmad - MPEG audio decoder library - Copyright (C) 2000-2004 Underbit Technologies, Inc. + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - $Id: synth.c,v 1.25 2004/01/23 09:41:33 rob Exp $ + $Id: synth.c,v 1.25 2004/01/23 09:41:33 rob Exp $ */ #pragma GCC optimize ("O3") @@ -32,79 +32,77 @@ # include "synth.h" #include "decoder.h" -static int16_t scale(mad_fixed_t sample) -{ - /* round */ - sample += (1L << (MAD_F_FRACBITS - 16)); +static int16_t scale(mad_fixed_t sample) { + /* round */ + sample += (1L << (MAD_F_FRACBITS - 16)); - /* clip */ - if (sample >= MAD_F_ONE) - sample = MAD_F_ONE - 1; - else if (sample < -MAD_F_ONE) - sample = -MAD_F_ONE; + /* clip */ + if (sample >= MAD_F_ONE) { + sample = MAD_F_ONE - 1; + } else if (sample < -MAD_F_ONE) { + sample = -MAD_F_ONE; + } - /* quantize */ - return sample >> (MAD_F_FRACBITS + 1 - 16); + /* quantize */ + return sample >> (MAD_F_FRACBITS + 1 - 16); } /* - NAME: synth->init() - DESCRIPTION: initialize synth struct + NAME: synth->init() + DESCRIPTION: initialize synth struct */ -void mad_synth_init(struct mad_synth *synth) -{ - stack(__FUNCTION__,__FILE__,__LINE__); - mad_synth_mute(synth); +void mad_synth_init(struct mad_synth *synth) { + stackenter(__FUNCTION__, __FILE__, __LINE__); + mad_synth_mute(synth); - synth->phase = 0; + synth->phase = 0; - synth->pcm.samplerate = 0; - synth->pcm.channels = 0; - synth->pcm.length = 0; + synth->pcm.samplerate = 0; + synth->pcm.channels = 0; + synth->pcm.length = 0; } /* - NAME: synth->mute() - DESCRIPTION: zero all polyphase filterbank values, resetting synthesis + NAME: synth->mute() + DESCRIPTION: zero all polyphase filterbank values, resetting synthesis */ -void mad_synth_mute(struct mad_synth *synth) -{ - unsigned int ch, s, v; - stack(__FUNCTION__, __FILE__, __LINE__); - - for (ch = 0; ch < 2; ++ch) { - for (s = 0; s < 16; ++s) { - for (v = 0; v < 8; ++v) { - synth->filter[ch][0][0][s][v] = synth->filter[ch][0][1][s][v] = - synth->filter[ch][1][0][s][v] = synth->filter[ch][1][1][s][v] = 0; - } +void mad_synth_mute(struct mad_synth *synth) { + unsigned int ch, s, v; + stackenter(__FUNCTION__, __FILE__, __LINE__); + + for (ch = 0; ch < 2; ++ch) { + for (s = 0; s < 16; ++s) { + for (v = 0; v < 8; ++v) { + synth->filter[ch][0][0][s][v] = synth->filter[ch][0][1][s][v] = + synth->filter[ch][1][0][s][v] = synth->filter[ch][1][1][s][v] = 0; + } + } } - } } /* - An optional optimization called here the Subband Synthesis Optimization - (SSO) improves the performance of subband synthesis at the expense of - accuracy. - - The idea is to simplify 32x32->64-bit multiplication to 32x32->32 such - that extra scaling and rounding are not necessary. This often allows the - compiler to use faster 32-bit multiply-accumulate instructions instead of - explicit 64-bit multiply, shift, and add instructions. - - SSO works like this: a full 32x32->64-bit multiply of two mad_fixed_t - values requires the result to be right-shifted 28 bits to be properly - scaled to the same fixed-point format. Right shifts can be applied at any - time to either operand or to the result, so the optimization involves - careful placement of these shifts to minimize the loss of accuracy. - - First, a 14-bit shift is applied with rounding at compile-time to the D[] - table of coefficients for the subband synthesis window. This only loses 2 - bits of accuracy because the lower 12 bits are always zero. A second - 12-bit shift occurs after the DCT calculation. This loses 12 bits of - accuracy. Finally, a third 2-bit shift occurs just before the sample is - saved in the PCM buffer. 14 + 12 + 2 == 28 bits. + An optional optimization called here the Subband Synthesis Optimization + (SSO) improves the performance of subband synthesis at the expense of + accuracy. + + The idea is to simplify 32x32->64-bit multiplication to 32x32->32 such + that extra scaling and rounding are not necessary. This often allows the + compiler to use faster 32-bit multiply-accumulate instructions instead of + explicit 64-bit multiply, shift, and add instructions. + + SSO works like this: a full 32x32->64-bit multiply of two mad_fixed_t + values requires the result to be right-shifted 28 bits to be properly + scaled to the same fixed-point format. Right shifts can be applied at any + time to either operand or to the result, so the optimization involves + careful placement of these shifts to minimize the loss of accuracy. + + First, a 14-bit shift is applied with rounding at compile-time to the D[] + table of coefficients for the subband synthesis window. This only loses 2 + bits of accuracy because the lower 12 bits are always zero. A second + 12-bit shift occurs after the DCT calculation. This loses 12 bits of + accuracy. Finally, a third 2-bit shift occurs just before the sample is + saved in the PCM buffer. 14 + 12 + 2 == 28 bits. */ /* FPM_DEFAULT without OPT_SSO will actually lose accuracy and performance */ @@ -137,38 +135,37 @@ void mad_synth_mute(struct mad_synth *synth) # endif /* - NAME: dct32() - DESCRIPTION: perform fast in[32]->out[32] DCT + NAME: dct32() + DESCRIPTION: perform fast in[32]->out[32] DCT */ static void dct32(mad_fixed_t const in[32], unsigned int slot, - mad_fixed_t lo[16][8], mad_fixed_t hi[16][8]) -{ - mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7; - mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15; - mad_fixed_t t16, t17, t18, t19, t20, t21, t22, t23; - mad_fixed_t t24, t25, t26, t27, t28, t29, t30, t31; - mad_fixed_t t32, t33, t34, t35, t36, t37, t38, t39; - mad_fixed_t t40, t41, t42, t43, t44, t45, t46, t47; - mad_fixed_t t48, t49, t50, t51, t52, t53, t54, t55; - mad_fixed_t t56, t57, t58, t59, t60, t61, t62, t63; - mad_fixed_t t64, t65, t66, t67, t68, t69, t70, t71; - mad_fixed_t t72, t73, t74, t75, t76, t77, t78, t79; - mad_fixed_t t80, t81, t82, t83, t84, t85, t86, t87; - mad_fixed_t t88, t89, t90, t91, t92, t93, t94, t95; - mad_fixed_t t96, t97, t98, t99, t100, t101, t102, t103; - mad_fixed_t t104, t105, t106, t107, t108, t109, t110, t111; - mad_fixed_t t112, t113, t114, t115, t116, t117, t118, t119; - mad_fixed_t t120, t121, t122, t123, t124, t125, t126, t127; - mad_fixed_t t128, t129, t130, t131, t132, t133, t134, t135; - mad_fixed_t t136, t137, t138, t139, t140, t141, t142, t143; - mad_fixed_t t144, t145, t146, t147, t148, t149, t150, t151; - mad_fixed_t t152, t153, t154, t155, t156, t157, t158, t159; - mad_fixed_t t160, t161, t162, t163, t164, t165, t166, t167; - mad_fixed_t t168, t169, t170, t171, t172, t173, t174, t175; - mad_fixed_t t176; - stack(__FUNCTION__, __FILE__, __LINE__); - /* costab[i] = cos(PI / (2 * 32) * i) */ + mad_fixed_t lo[16][8], mad_fixed_t hi[16][8]) { + mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7; + mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15; + mad_fixed_t t16, t17, t18, t19, t20, t21, t22, t23; + mad_fixed_t t24, t25, t26, t27, t28, t29, t30, t31; + mad_fixed_t t32, t33, t34, t35, t36, t37, t38, t39; + mad_fixed_t t40, t41, t42, t43, t44, t45, t46, t47; + mad_fixed_t t48, t49, t50, t51, t52, t53, t54, t55; + mad_fixed_t t56, t57, t58, t59, t60, t61, t62, t63; + mad_fixed_t t64, t65, t66, t67, t68, t69, t70, t71; + mad_fixed_t t72, t73, t74, t75, t76, t77, t78, t79; + mad_fixed_t t80, t81, t82, t83, t84, t85, t86, t87; + mad_fixed_t t88, t89, t90, t91, t92, t93, t94, t95; + mad_fixed_t t96, t97, t98, t99, t100, t101, t102, t103; + mad_fixed_t t104, t105, t106, t107, t108, t109, t110, t111; + mad_fixed_t t112, t113, t114, t115, t116, t117, t118, t119; + mad_fixed_t t120, t121, t122, t123, t124, t125, t126, t127; + mad_fixed_t t128, t129, t130, t131, t132, t133, t134, t135; + mad_fixed_t t136, t137, t138, t139, t140, t141, t142, t143; + mad_fixed_t t144, t145, t146, t147, t148, t149, t150, t151; + mad_fixed_t t152, t153, t154, t155, t156, t157, t158, t159; + mad_fixed_t t160, t161, t162, t163, t164, t165, t166, t167; + mad_fixed_t t168, t169, t170, t171, t172, t173, t174, t175; + mad_fixed_t t176; + stackenter(__FUNCTION__, __FILE__, __LINE__); + /* costab[i] = cos(PI / (2 * 32) * i) */ # if defined(OPT_DCTO) # define costab1 MAD_F(0x7fd8878e) @@ -236,300 +233,300 @@ void dct32(mad_fixed_t const in[32], unsigned int slot, # define costab31 MAD_F(0x00c8fb30) /* 0.049067674 */ # endif - t0 = in[0] + in[31]; t16 = MUL(in[0] - in[31], costab1); - t1 = in[15] + in[16]; t17 = MUL(in[15] - in[16], costab31); + t0 = in[0] + in[31]; t16 = MUL(in[0] - in[31], costab1); + t1 = in[15] + in[16]; t17 = MUL(in[15] - in[16], costab31); - t41 = t16 + t17; - t59 = MUL(t16 - t17, costab2); - t33 = t0 + t1; - t50 = MUL(t0 - t1, costab2); + t41 = t16 + t17; + t59 = MUL(t16 - t17, costab2); + t33 = t0 + t1; + t50 = MUL(t0 - t1, costab2); - t2 = in[7] + in[24]; t18 = MUL(in[7] - in[24], costab15); - t3 = in[8] + in[23]; t19 = MUL(in[8] - in[23], costab17); + t2 = in[7] + in[24]; t18 = MUL(in[7] - in[24], costab15); + t3 = in[8] + in[23]; t19 = MUL(in[8] - in[23], costab17); - t42 = t18 + t19; - t60 = MUL(t18 - t19, costab30); - t34 = t2 + t3; - t51 = MUL(t2 - t3, costab30); + t42 = t18 + t19; + t60 = MUL(t18 - t19, costab30); + t34 = t2 + t3; + t51 = MUL(t2 - t3, costab30); - t4 = in[3] + in[28]; t20 = MUL(in[3] - in[28], costab7); - t5 = in[12] + in[19]; t21 = MUL(in[12] - in[19], costab25); + t4 = in[3] + in[28]; t20 = MUL(in[3] - in[28], costab7); + t5 = in[12] + in[19]; t21 = MUL(in[12] - in[19], costab25); - t43 = t20 + t21; - t61 = MUL(t20 - t21, costab14); - t35 = t4 + t5; - t52 = MUL(t4 - t5, costab14); + t43 = t20 + t21; + t61 = MUL(t20 - t21, costab14); + t35 = t4 + t5; + t52 = MUL(t4 - t5, costab14); - t6 = in[4] + in[27]; t22 = MUL(in[4] - in[27], costab9); - t7 = in[11] + in[20]; t23 = MUL(in[11] - in[20], costab23); + t6 = in[4] + in[27]; t22 = MUL(in[4] - in[27], costab9); + t7 = in[11] + in[20]; t23 = MUL(in[11] - in[20], costab23); - t44 = t22 + t23; - t62 = MUL(t22 - t23, costab18); - t36 = t6 + t7; - t53 = MUL(t6 - t7, costab18); + t44 = t22 + t23; + t62 = MUL(t22 - t23, costab18); + t36 = t6 + t7; + t53 = MUL(t6 - t7, costab18); - t8 = in[1] + in[30]; t24 = MUL(in[1] - in[30], costab3); - t9 = in[14] + in[17]; t25 = MUL(in[14] - in[17], costab29); + t8 = in[1] + in[30]; t24 = MUL(in[1] - in[30], costab3); + t9 = in[14] + in[17]; t25 = MUL(in[14] - in[17], costab29); - t45 = t24 + t25; - t63 = MUL(t24 - t25, costab6); - t37 = t8 + t9; - t54 = MUL(t8 - t9, costab6); + t45 = t24 + t25; + t63 = MUL(t24 - t25, costab6); + t37 = t8 + t9; + t54 = MUL(t8 - t9, costab6); - t10 = in[6] + in[25]; t26 = MUL(in[6] - in[25], costab13); - t11 = in[9] + in[22]; t27 = MUL(in[9] - in[22], costab19); + t10 = in[6] + in[25]; t26 = MUL(in[6] - in[25], costab13); + t11 = in[9] + in[22]; t27 = MUL(in[9] - in[22], costab19); - t46 = t26 + t27; - t64 = MUL(t26 - t27, costab26); - t38 = t10 + t11; - t55 = MUL(t10 - t11, costab26); + t46 = t26 + t27; + t64 = MUL(t26 - t27, costab26); + t38 = t10 + t11; + t55 = MUL(t10 - t11, costab26); - t12 = in[2] + in[29]; t28 = MUL(in[2] - in[29], costab5); - t13 = in[13] + in[18]; t29 = MUL(in[13] - in[18], costab27); + t12 = in[2] + in[29]; t28 = MUL(in[2] - in[29], costab5); + t13 = in[13] + in[18]; t29 = MUL(in[13] - in[18], costab27); - t47 = t28 + t29; - t65 = MUL(t28 - t29, costab10); - t39 = t12 + t13; - t56 = MUL(t12 - t13, costab10); + t47 = t28 + t29; + t65 = MUL(t28 - t29, costab10); + t39 = t12 + t13; + t56 = MUL(t12 - t13, costab10); - t14 = in[5] + in[26]; t30 = MUL(in[5] - in[26], costab11); - t15 = in[10] + in[21]; t31 = MUL(in[10] - in[21], costab21); + t14 = in[5] + in[26]; t30 = MUL(in[5] - in[26], costab11); + t15 = in[10] + in[21]; t31 = MUL(in[10] - in[21], costab21); - t48 = t30 + t31; - t66 = MUL(t30 - t31, costab22); - t40 = t14 + t15; - t57 = MUL(t14 - t15, costab22); + t48 = t30 + t31; + t66 = MUL(t30 - t31, costab22); + t40 = t14 + t15; + t57 = MUL(t14 - t15, costab22); - t69 = t33 + t34; t89 = MUL(t33 - t34, costab4); - t70 = t35 + t36; t90 = MUL(t35 - t36, costab28); - t71 = t37 + t38; t91 = MUL(t37 - t38, costab12); - t72 = t39 + t40; t92 = MUL(t39 - t40, costab20); - t73 = t41 + t42; t94 = MUL(t41 - t42, costab4); - t74 = t43 + t44; t95 = MUL(t43 - t44, costab28); - t75 = t45 + t46; t96 = MUL(t45 - t46, costab12); - t76 = t47 + t48; t97 = MUL(t47 - t48, costab20); + t69 = t33 + t34; t89 = MUL(t33 - t34, costab4); + t70 = t35 + t36; t90 = MUL(t35 - t36, costab28); + t71 = t37 + t38; t91 = MUL(t37 - t38, costab12); + t72 = t39 + t40; t92 = MUL(t39 - t40, costab20); + t73 = t41 + t42; t94 = MUL(t41 - t42, costab4); + t74 = t43 + t44; t95 = MUL(t43 - t44, costab28); + t75 = t45 + t46; t96 = MUL(t45 - t46, costab12); + t76 = t47 + t48; t97 = MUL(t47 - t48, costab20); - t78 = t50 + t51; t100 = MUL(t50 - t51, costab4); - t79 = t52 + t53; t101 = MUL(t52 - t53, costab28); - t80 = t54 + t55; t102 = MUL(t54 - t55, costab12); - t81 = t56 + t57; t103 = MUL(t56 - t57, costab20); + t78 = t50 + t51; t100 = MUL(t50 - t51, costab4); + t79 = t52 + t53; t101 = MUL(t52 - t53, costab28); + t80 = t54 + t55; t102 = MUL(t54 - t55, costab12); + t81 = t56 + t57; t103 = MUL(t56 - t57, costab20); - t83 = t59 + t60; t106 = MUL(t59 - t60, costab4); - t84 = t61 + t62; t107 = MUL(t61 - t62, costab28); - t85 = t63 + t64; t108 = MUL(t63 - t64, costab12); - t86 = t65 + t66; t109 = MUL(t65 - t66, costab20); + t83 = t59 + t60; t106 = MUL(t59 - t60, costab4); + t84 = t61 + t62; t107 = MUL(t61 - t62, costab28); + t85 = t63 + t64; t108 = MUL(t63 - t64, costab12); + t86 = t65 + t66; t109 = MUL(t65 - t66, costab20); - t113 = t69 + t70; - t114 = t71 + t72; + t113 = t69 + t70; + t114 = t71 + t72; - /* 0 */ hi[15][slot] = SHIFT(t113 + t114); - /* 16 */ lo[ 0][slot] = SHIFT(MUL(t113 - t114, costab16)); + /* 0 */ hi[15][slot] = SHIFT(t113 + t114); + /* 16 */ lo[ 0][slot] = SHIFT(MUL(t113 - t114, costab16)); - t115 = t73 + t74; - t116 = t75 + t76; + t115 = t73 + t74; + t116 = t75 + t76; - t32 = t115 + t116; + t32 = t115 + t116; - /* 1 */ hi[14][slot] = SHIFT(t32); + /* 1 */ hi[14][slot] = SHIFT(t32); - t118 = t78 + t79; - t119 = t80 + t81; + t118 = t78 + t79; + t119 = t80 + t81; - t58 = t118 + t119; + t58 = t118 + t119; - /* 2 */ hi[13][slot] = SHIFT(t58); + /* 2 */ hi[13][slot] = SHIFT(t58); - t121 = t83 + t84; - t122 = t85 + t86; + t121 = t83 + t84; + t122 = t85 + t86; - t67 = t121 + t122; + t67 = t121 + t122; - t49 = (t67 * 2) - t32; + t49 = (t67 * 2) - t32; - /* 3 */ hi[12][slot] = SHIFT(t49); + /* 3 */ hi[12][slot] = SHIFT(t49); - t125 = t89 + t90; - t126 = t91 + t92; + t125 = t89 + t90; + t126 = t91 + t92; - t93 = t125 + t126; + t93 = t125 + t126; - /* 4 */ hi[11][slot] = SHIFT(t93); + /* 4 */ hi[11][slot] = SHIFT(t93); - t128 = t94 + t95; - t129 = t96 + t97; + t128 = t94 + t95; + t129 = t96 + t97; - t98 = t128 + t129; + t98 = t128 + t129; - t68 = (t98 * 2) - t49; + t68 = (t98 * 2) - t49; - /* 5 */ hi[10][slot] = SHIFT(t68); + /* 5 */ hi[10][slot] = SHIFT(t68); - t132 = t100 + t101; - t133 = t102 + t103; + t132 = t100 + t101; + t133 = t102 + t103; - t104 = t132 + t133; + t104 = t132 + t133; - t82 = (t104 * 2) - t58; + t82 = (t104 * 2) - t58; - /* 6 */ hi[ 9][slot] = SHIFT(t82); + /* 6 */ hi[ 9][slot] = SHIFT(t82); - t136 = t106 + t107; - t137 = t108 + t109; + t136 = t106 + t107; + t137 = t108 + t109; - t110 = t136 + t137; + t110 = t136 + t137; - t87 = (t110 * 2) - t67; + t87 = (t110 * 2) - t67; - t77 = (t87 * 2) - t68; + t77 = (t87 * 2) - t68; - /* 7 */ hi[ 8][slot] = SHIFT(t77); + /* 7 */ hi[ 8][slot] = SHIFT(t77); - t141 = MUL(t69 - t70, costab8); - t142 = MUL(t71 - t72, costab24); - t143 = t141 + t142; + t141 = MUL(t69 - t70, costab8); + t142 = MUL(t71 - t72, costab24); + t143 = t141 + t142; - /* 8 */ hi[ 7][slot] = SHIFT(t143); - /* 24 */ lo[ 8][slot] = - SHIFT((MUL(t141 - t142, costab16) * 2) - t143); + /* 8 */ hi[ 7][slot] = SHIFT(t143); + /* 24 */ lo[ 8][slot] = + SHIFT((MUL(t141 - t142, costab16) * 2) - t143); - t144 = MUL(t73 - t74, costab8); - t145 = MUL(t75 - t76, costab24); - t146 = t144 + t145; + t144 = MUL(t73 - t74, costab8); + t145 = MUL(t75 - t76, costab24); + t146 = t144 + t145; - t88 = (t146 * 2) - t77; + t88 = (t146 * 2) - t77; - /* 9 */ hi[ 6][slot] = SHIFT(t88); + /* 9 */ hi[ 6][slot] = SHIFT(t88); - t148 = MUL(t78 - t79, costab8); - t149 = MUL(t80 - t81, costab24); - t150 = t148 + t149; + t148 = MUL(t78 - t79, costab8); + t149 = MUL(t80 - t81, costab24); + t150 = t148 + t149; - t105 = (t150 * 2) - t82; + t105 = (t150 * 2) - t82; - /* 10 */ hi[ 5][slot] = SHIFT(t105); + /* 10 */ hi[ 5][slot] = SHIFT(t105); - t152 = MUL(t83 - t84, costab8); - t153 = MUL(t85 - t86, costab24); - t154 = t152 + t153; + t152 = MUL(t83 - t84, costab8); + t153 = MUL(t85 - t86, costab24); + t154 = t152 + t153; - t111 = (t154 * 2) - t87; + t111 = (t154 * 2) - t87; - t99 = (t111 * 2) - t88; + t99 = (t111 * 2) - t88; - /* 11 */ hi[ 4][slot] = SHIFT(t99); + /* 11 */ hi[ 4][slot] = SHIFT(t99); - t157 = MUL(t89 - t90, costab8); - t158 = MUL(t91 - t92, costab24); - t159 = t157 + t158; + t157 = MUL(t89 - t90, costab8); + t158 = MUL(t91 - t92, costab24); + t159 = t157 + t158; - t127 = (t159 * 2) - t93; + t127 = (t159 * 2) - t93; - /* 12 */ hi[ 3][slot] = SHIFT(t127); + /* 12 */ hi[ 3][slot] = SHIFT(t127); - t160 = (MUL(t125 - t126, costab16) * 2) - t127; + t160 = (MUL(t125 - t126, costab16) * 2) - t127; - /* 20 */ lo[ 4][slot] = SHIFT(t160); - /* 28 */ lo[12][slot] = - SHIFT((((MUL(t157 - t158, costab16) * 2) - t159) * 2) - t160); + /* 20 */ lo[ 4][slot] = SHIFT(t160); + /* 28 */ lo[12][slot] = + SHIFT((((MUL(t157 - t158, costab16) * 2) - t159) * 2) - t160); - t161 = MUL(t94 - t95, costab8); - t162 = MUL(t96 - t97, costab24); - t163 = t161 + t162; + t161 = MUL(t94 - t95, costab8); + t162 = MUL(t96 - t97, costab24); + t163 = t161 + t162; - t130 = (t163 * 2) - t98; + t130 = (t163 * 2) - t98; - t112 = (t130 * 2) - t99; + t112 = (t130 * 2) - t99; - /* 13 */ hi[ 2][slot] = SHIFT(t112); + /* 13 */ hi[ 2][slot] = SHIFT(t112); - t164 = (MUL(t128 - t129, costab16) * 2) - t130; + t164 = (MUL(t128 - t129, costab16) * 2) - t130; - t166 = MUL(t100 - t101, costab8); - t167 = MUL(t102 - t103, costab24); - t168 = t166 + t167; + t166 = MUL(t100 - t101, costab8); + t167 = MUL(t102 - t103, costab24); + t168 = t166 + t167; - t134 = (t168 * 2) - t104; + t134 = (t168 * 2) - t104; - t120 = (t134 * 2) - t105; + t120 = (t134 * 2) - t105; - /* 14 */ hi[ 1][slot] = SHIFT(t120); + /* 14 */ hi[ 1][slot] = SHIFT(t120); - t135 = (MUL(t118 - t119, costab16) * 2) - t120; + t135 = (MUL(t118 - t119, costab16) * 2) - t120; - /* 18 */ lo[ 2][slot] = SHIFT(t135); + /* 18 */ lo[ 2][slot] = SHIFT(t135); - t169 = (MUL(t132 - t133, costab16) * 2) - t134; + t169 = (MUL(t132 - t133, costab16) * 2) - t134; - t151 = (t169 * 2) - t135; + t151 = (t169 * 2) - t135; - /* 22 */ lo[ 6][slot] = SHIFT(t151); + /* 22 */ lo[ 6][slot] = SHIFT(t151); - t170 = (((MUL(t148 - t149, costab16) * 2) - t150) * 2) - t151; + t170 = (((MUL(t148 - t149, costab16) * 2) - t150) * 2) - t151; - /* 26 */ lo[10][slot] = SHIFT(t170); - /* 30 */ lo[14][slot] = - SHIFT((((((MUL(t166 - t167, costab16) * 2) - - t168) * 2) - t169) * 2) - t170); + /* 26 */ lo[10][slot] = SHIFT(t170); + /* 30 */ lo[14][slot] = + SHIFT((((((MUL(t166 - t167, costab16) * 2) - + t168) * 2) - t169) * 2) - t170); - t171 = MUL(t106 - t107, costab8); - t172 = MUL(t108 - t109, costab24); - t173 = t171 + t172; + t171 = MUL(t106 - t107, costab8); + t172 = MUL(t108 - t109, costab24); + t173 = t171 + t172; - t138 = (t173 * 2) - t110; + t138 = (t173 * 2) - t110; - t123 = (t138 * 2) - t111; + t123 = (t138 * 2) - t111; - t139 = (MUL(t121 - t122, costab16) * 2) - t123; + t139 = (MUL(t121 - t122, costab16) * 2) - t123; - t117 = (t123 * 2) - t112; + t117 = (t123 * 2) - t112; - /* 15 */ hi[ 0][slot] = SHIFT(t117); + /* 15 */ hi[ 0][slot] = SHIFT(t117); - t124 = (MUL(t115 - t116, costab16) * 2) - t117; + t124 = (MUL(t115 - t116, costab16) * 2) - t117; - /* 17 */ lo[ 1][slot] = SHIFT(t124); + /* 17 */ lo[ 1][slot] = SHIFT(t124); - t131 = (t139 * 2) - t124; + t131 = (t139 * 2) - t124; - /* 19 */ lo[ 3][slot] = SHIFT(t131); + /* 19 */ lo[ 3][slot] = SHIFT(t131); - t140 = (t164 * 2) - t131; + t140 = (t164 * 2) - t131; - /* 21 */ lo[ 5][slot] = SHIFT(t140); + /* 21 */ lo[ 5][slot] = SHIFT(t140); - t174 = (MUL(t136 - t137, costab16) * 2) - t138; + t174 = (MUL(t136 - t137, costab16) * 2) - t138; - t155 = (t174 * 2) - t139; + t155 = (t174 * 2) - t139; - t147 = (t155 * 2) - t140; + t147 = (t155 * 2) - t140; - /* 23 */ lo[ 7][slot] = SHIFT(t147); + /* 23 */ lo[ 7][slot] = SHIFT(t147); - t156 = (((MUL(t144 - t145, costab16) * 2) - t146) * 2) - t147; + t156 = (((MUL(t144 - t145, costab16) * 2) - t146) * 2) - t147; - /* 25 */ lo[ 9][slot] = SHIFT(t156); + /* 25 */ lo[ 9][slot] = SHIFT(t156); - t175 = (((MUL(t152 - t153, costab16) * 2) - t154) * 2) - t155; + t175 = (((MUL(t152 - t153, costab16) * 2) - t154) * 2) - t155; - t165 = (t175 * 2) - t156; + t165 = (t175 * 2) - t156; - /* 27 */ lo[11][slot] = SHIFT(t165); + /* 27 */ lo[11][slot] = SHIFT(t165); - t176 = (((((MUL(t161 - t162, costab16) * 2) - - t163) * 2) - t164) * 2) - t165; + t176 = (((((MUL(t161 - t162, costab16) * 2) - + t163) * 2) - t164) * 2) - t165; - /* 29 */ lo[13][slot] = SHIFT(t176); - /* 31 */ lo[15][slot] = - SHIFT((((((((MUL(t171 - t172, costab16) * 2) - - t173) * 2) - t174) * 2) - t175) * 2) - t176); + /* 29 */ lo[13][slot] = SHIFT(t176); + /* 31 */ lo[15][slot] = + SHIFT((((((((MUL(t171 - t172, costab16) * 2) - + t173) * 2) - t174) * 2) - t175) * 2) - t176); - /* - Totals: - 80 multiplies - 80 additions - 119 subtractions - 49 shifts (not counting SSO) - */ + /* + Totals: + 80 multiplies + 80 additions + 119 subtractions + 49 shifts (not counting SSO) + */ } # undef MUL @@ -572,359 +569,361 @@ void synth_full(struct mad_synth *, struct mad_frame const *, unsigned int, unsigned int); # else /* - NAME: synth->full() - DESCRIPTION: perform full frequency PCM synthesis + NAME: synth->full() + DESCRIPTION: perform full frequency PCM synthesis */ static enum mad_flow synth_full(struct mad_synth *synth, struct mad_frame const *frame, - unsigned int nch, unsigned int startns, unsigned int endns, - enum mad_flow (*output_func)(void *s, struct mad_header const *, struct mad_pcm *), void *cbdata) -{ - unsigned int phase, ch, s, sb, pe, po; - int16_t *pcm1, *pcm2; - mad_fixed_t (*filter)[2][2][16][8]; - mad_fixed_t const (*sbsample)[36][32]; - register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8]; - register mad_fixed_t const (*Dptr)[32], *ptr; - register mad_fixed64hi_t hi; - register mad_fixed64lo_t lo; - stack(__FUNCTION__, __FILE__, __LINE__); - - for (unsigned int start = startns; start < endns; start ++) { - for (ch = 0; ch < nch; ++ch) { - sbsample = &frame->sbsample[ch]; - filter = &synth->filter[ch]; - phase = (synth->phase + start ) % 16; - pcm1 = synth->pcm.samples[ch];// + start * 32; - - for (s = start; s <= start; ++s) { - dct32((*sbsample)[s], phase >> 1, - (*filter)[0][phase & 1], (*filter)[1][phase & 1]); - - pe = phase & ~1; - po = ((phase - 1) & 0xf) | 1; - - /* calculate 32 samples */ - - fe = &(*filter)[0][ phase & 1][0]; - fx = &(*filter)[0][~phase & 1][0]; - fo = &(*filter)[1][~phase & 1][0]; - - Dptr = &D[0]; - - ptr = *Dptr + po; - ML0(hi, lo, (*fx)[0], ptr[ 0]); - MLA(hi, lo, (*fx)[1], ptr[14]); - MLA(hi, lo, (*fx)[2], ptr[12]); - MLA(hi, lo, (*fx)[3], ptr[10]); - MLA(hi, lo, (*fx)[4], ptr[ 8]); - MLA(hi, lo, (*fx)[5], ptr[ 6]); - MLA(hi, lo, (*fx)[6], ptr[ 4]); - MLA(hi, lo, (*fx)[7], ptr[ 2]); - MLN(hi, lo); - - ptr = *Dptr + pe; - MLA(hi, lo, (*fe)[0], ptr[ 0]); - MLA(hi, lo, (*fe)[1], ptr[14]); - MLA(hi, lo, (*fe)[2], ptr[12]); - MLA(hi, lo, (*fe)[3], ptr[10]); - MLA(hi, lo, (*fe)[4], ptr[ 8]); - MLA(hi, lo, (*fe)[5], ptr[ 6]); - MLA(hi, lo, (*fe)[6], ptr[ 4]); - MLA(hi, lo, (*fe)[7], ptr[ 2]); - - *pcm1++ = scale(SHIFT(MLZ(hi, lo))); - - pcm2 = pcm1 + 30; - - for (sb = 1; sb < 16; ++sb) { - ++fe; - ++Dptr; - - /* D[32 - sb][i] == -D[sb][31 - i] */ - - ptr = *Dptr + po; - ML0(hi, lo, (*fo)[0], ptr[ 0]); - MLA(hi, lo, (*fo)[1], ptr[14]); - MLA(hi, lo, (*fo)[2], ptr[12]); - MLA(hi, lo, (*fo)[3], ptr[10]); - MLA(hi, lo, (*fo)[4], ptr[ 8]); - MLA(hi, lo, (*fo)[5], ptr[ 6]); - MLA(hi, lo, (*fo)[6], ptr[ 4]); - MLA(hi, lo, (*fo)[7], ptr[ 2]); - MLN(hi, lo); - - ptr = *Dptr + pe; - MLA(hi, lo, (*fe)[7], ptr[ 2]); - MLA(hi, lo, (*fe)[6], ptr[ 4]); - MLA(hi, lo, (*fe)[5], ptr[ 6]); - MLA(hi, lo, (*fe)[4], ptr[ 8]); - MLA(hi, lo, (*fe)[3], ptr[10]); - MLA(hi, lo, (*fe)[2], ptr[12]); - MLA(hi, lo, (*fe)[1], ptr[14]); - MLA(hi, lo, (*fe)[0], ptr[ 0]); - - *pcm1++ = scale(SHIFT(MLZ(hi, lo))); - - ptr = *Dptr - pe; - ML0(hi, lo, (*fe)[0], ptr[31 - 16]); - MLA(hi, lo, (*fe)[1], ptr[31 - 14]); - MLA(hi, lo, (*fe)[2], ptr[31 - 12]); - MLA(hi, lo, (*fe)[3], ptr[31 - 10]); - MLA(hi, lo, (*fe)[4], ptr[31 - 8]); - MLA(hi, lo, (*fe)[5], ptr[31 - 6]); - MLA(hi, lo, (*fe)[6], ptr[31 - 4]); - MLA(hi, lo, (*fe)[7], ptr[31 - 2]); - - ptr = *Dptr - po; - MLA(hi, lo, (*fo)[7], ptr[31 - 2]); - MLA(hi, lo, (*fo)[6], ptr[31 - 4]); - MLA(hi, lo, (*fo)[5], ptr[31 - 6]); - MLA(hi, lo, (*fo)[4], ptr[31 - 8]); - MLA(hi, lo, (*fo)[3], ptr[31 - 10]); - MLA(hi, lo, (*fo)[2], ptr[31 - 12]); - MLA(hi, lo, (*fo)[1], ptr[31 - 14]); - MLA(hi, lo, (*fo)[0], ptr[31 - 16]); - - *pcm2-- = scale(SHIFT(MLZ(hi, lo))); - - ++fo; + unsigned int nch, unsigned int startns, unsigned int endns, + enum mad_flow(*output_func)(void *s, struct mad_header const *, struct mad_pcm *), void *cbdata) { + unsigned int phase, ch, s, sb, pe, po; + int16_t *pcm1, *pcm2; + mad_fixed_t (*filter)[2][2][16][8]; + mad_fixed_t const(*sbsample)[36][32]; + register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8]; + register mad_fixed_t const(*Dptr)[32], *ptr; + register mad_fixed64hi_t hi; + register mad_fixed64lo_t lo; + stackenter(__FUNCTION__, __FILE__, __LINE__); + + for (unsigned int start = startns; start < endns; start ++) { + for (ch = 0; ch < nch; ++ch) { + sbsample = &frame->sbsample[ch]; + filter = &synth->filter[ch]; + phase = (synth->phase + start) % 16; + pcm1 = synth->pcm.samples[ch];// + start * 32; + + for (s = start; s <= start; ++s) { + dct32((*sbsample)[s], phase >> 1, + (*filter)[0][phase & 1], (*filter)[1][phase & 1]); + + pe = phase & ~1; + po = ((phase - 1) & 0xf) | 1; + + /* calculate 32 samples */ + + fe = &(*filter)[0][ phase & 1][0]; + fx = &(*filter)[0][~phase & 1][0]; + fo = &(*filter)[1][~phase & 1][0]; + + Dptr = &D[0]; + + ptr = *Dptr + po; + ML0(hi, lo, (*fx)[0], ptr[ 0]); + MLA(hi, lo, (*fx)[1], ptr[14]); + MLA(hi, lo, (*fx)[2], ptr[12]); + MLA(hi, lo, (*fx)[3], ptr[10]); + MLA(hi, lo, (*fx)[4], ptr[ 8]); + MLA(hi, lo, (*fx)[5], ptr[ 6]); + MLA(hi, lo, (*fx)[6], ptr[ 4]); + MLA(hi, lo, (*fx)[7], ptr[ 2]); + MLN(hi, lo); + + ptr = *Dptr + pe; + MLA(hi, lo, (*fe)[0], ptr[ 0]); + MLA(hi, lo, (*fe)[1], ptr[14]); + MLA(hi, lo, (*fe)[2], ptr[12]); + MLA(hi, lo, (*fe)[3], ptr[10]); + MLA(hi, lo, (*fe)[4], ptr[ 8]); + MLA(hi, lo, (*fe)[5], ptr[ 6]); + MLA(hi, lo, (*fe)[6], ptr[ 4]); + MLA(hi, lo, (*fe)[7], ptr[ 2]); + + *pcm1++ = scale(SHIFT(MLZ(hi, lo))); + + pcm2 = pcm1 + 30; + + for (sb = 1; sb < 16; ++sb) { + ++fe; + ++Dptr; + + /* D[32 - sb][i] == -D[sb][31 - i] */ + + ptr = *Dptr + po; + ML0(hi, lo, (*fo)[0], ptr[ 0]); + MLA(hi, lo, (*fo)[1], ptr[14]); + MLA(hi, lo, (*fo)[2], ptr[12]); + MLA(hi, lo, (*fo)[3], ptr[10]); + MLA(hi, lo, (*fo)[4], ptr[ 8]); + MLA(hi, lo, (*fo)[5], ptr[ 6]); + MLA(hi, lo, (*fo)[6], ptr[ 4]); + MLA(hi, lo, (*fo)[7], ptr[ 2]); + MLN(hi, lo); + + ptr = *Dptr + pe; + MLA(hi, lo, (*fe)[7], ptr[ 2]); + MLA(hi, lo, (*fe)[6], ptr[ 4]); + MLA(hi, lo, (*fe)[5], ptr[ 6]); + MLA(hi, lo, (*fe)[4], ptr[ 8]); + MLA(hi, lo, (*fe)[3], ptr[10]); + MLA(hi, lo, (*fe)[2], ptr[12]); + MLA(hi, lo, (*fe)[1], ptr[14]); + MLA(hi, lo, (*fe)[0], ptr[ 0]); + + *pcm1++ = scale(SHIFT(MLZ(hi, lo))); + + ptr = *Dptr - pe; + ML0(hi, lo, (*fe)[0], ptr[31 - 16]); + MLA(hi, lo, (*fe)[1], ptr[31 - 14]); + MLA(hi, lo, (*fe)[2], ptr[31 - 12]); + MLA(hi, lo, (*fe)[3], ptr[31 - 10]); + MLA(hi, lo, (*fe)[4], ptr[31 - 8]); + MLA(hi, lo, (*fe)[5], ptr[31 - 6]); + MLA(hi, lo, (*fe)[6], ptr[31 - 4]); + MLA(hi, lo, (*fe)[7], ptr[31 - 2]); + + ptr = *Dptr - po; + MLA(hi, lo, (*fo)[7], ptr[31 - 2]); + MLA(hi, lo, (*fo)[6], ptr[31 - 4]); + MLA(hi, lo, (*fo)[5], ptr[31 - 6]); + MLA(hi, lo, (*fo)[4], ptr[31 - 8]); + MLA(hi, lo, (*fo)[3], ptr[31 - 10]); + MLA(hi, lo, (*fo)[2], ptr[31 - 12]); + MLA(hi, lo, (*fo)[1], ptr[31 - 14]); + MLA(hi, lo, (*fo)[0], ptr[31 - 16]); + + *pcm2-- = scale(SHIFT(MLZ(hi, lo))); + + ++fo; + } + + ++Dptr; + + ptr = *Dptr + po; + ML0(hi, lo, (*fo)[0], ptr[ 0]); + MLA(hi, lo, (*fo)[1], ptr[14]); + MLA(hi, lo, (*fo)[2], ptr[12]); + MLA(hi, lo, (*fo)[3], ptr[10]); + MLA(hi, lo, (*fo)[4], ptr[ 8]); + MLA(hi, lo, (*fo)[5], ptr[ 6]); + MLA(hi, lo, (*fo)[6], ptr[ 4]); + MLA(hi, lo, (*fo)[7], ptr[ 2]); + + *pcm1 = scale(SHIFT(-MLZ(hi, lo))); + pcm1 += 16; + + phase = (phase + 1) % 16; + } + } + if (output_func) { + enum mad_flow ret = output_func(cbdata, &frame->header, &synth->pcm); + if (ret != MAD_FLOW_CONTINUE) { + return ret; + } } - - ++Dptr; - - ptr = *Dptr + po; - ML0(hi, lo, (*fo)[0], ptr[ 0]); - MLA(hi, lo, (*fo)[1], ptr[14]); - MLA(hi, lo, (*fo)[2], ptr[12]); - MLA(hi, lo, (*fo)[3], ptr[10]); - MLA(hi, lo, (*fo)[4], ptr[ 8]); - MLA(hi, lo, (*fo)[5], ptr[ 6]); - MLA(hi, lo, (*fo)[6], ptr[ 4]); - MLA(hi, lo, (*fo)[7], ptr[ 2]); - - *pcm1 = scale(SHIFT(-MLZ(hi, lo))); - pcm1 += 16; - - phase = (phase + 1) % 16; - } - } - if (output_func) { - enum mad_flow ret = output_func(cbdata, &frame->header, &synth->pcm); - if (ret != MAD_FLOW_CONTINUE) return ret; } - } - return MAD_FLOW_CONTINUE; + return MAD_FLOW_CONTINUE; } # endif /* - NAME: synth->half() - DESCRIPTION: perform half frequency PCM synthesis + NAME: synth->half() + DESCRIPTION: perform half frequency PCM synthesis */ static enum mad_flow synth_half(struct mad_synth *synth, struct mad_frame const *frame, - unsigned int nch, unsigned int startns, unsigned int endns, - enum mad_flow (*output_func)(void *s, struct mad_header const *, struct mad_pcm *), void *cbdata ) -{ - unsigned int phase, ch, s, sb, pe, po; - int16_t *pcm1, *pcm2; - mad_fixed_t (*filter)[2][2][16][8]; - mad_fixed_t const (*sbsample)[36][32]; - register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8]; - register mad_fixed_t const (*Dptr)[32], *ptr; - register mad_fixed64hi_t hi; - register mad_fixed64lo_t lo; - stack(__FUNCTION__, __FILE__, __LINE__); - for (unsigned int start = startns; start < endns; start ++) { - for (ch = 0; ch < nch; ++ch) { - sbsample = &frame->sbsample[ch]; - filter = &synth->filter[ch]; - phase = (synth->phase + start) % 16; - pcm1 = synth->pcm.samples[ch];// + start * 32; - - for (s = start; s <= start; ++s) { - dct32((*sbsample)[s], phase >> 1, - (*filter)[0][phase & 1], (*filter)[1][phase & 1]); - - pe = phase & ~1; - po = ((phase - 1) & 0xf) | 1; - - /* calculate 16 samples */ - - fe = &(*filter)[0][ phase & 1][0]; - fx = &(*filter)[0][~phase & 1][0]; - fo = &(*filter)[1][~phase & 1][0]; - - Dptr = &D[0]; - - ptr = *Dptr + po; - ML0(hi, lo, (*fx)[0], ptr[ 0]); - MLA(hi, lo, (*fx)[1], ptr[14]); - MLA(hi, lo, (*fx)[2], ptr[12]); - MLA(hi, lo, (*fx)[3], ptr[10]); - MLA(hi, lo, (*fx)[4], ptr[ 8]); - MLA(hi, lo, (*fx)[5], ptr[ 6]); - MLA(hi, lo, (*fx)[6], ptr[ 4]); - MLA(hi, lo, (*fx)[7], ptr[ 2]); - MLN(hi, lo); - - ptr = *Dptr + pe; - MLA(hi, lo, (*fe)[0], ptr[ 0]); - MLA(hi, lo, (*fe)[1], ptr[14]); - MLA(hi, lo, (*fe)[2], ptr[12]); - MLA(hi, lo, (*fe)[3], ptr[10]); - MLA(hi, lo, (*fe)[4], ptr[ 8]); - MLA(hi, lo, (*fe)[5], ptr[ 6]); - MLA(hi, lo, (*fe)[6], ptr[ 4]); - MLA(hi, lo, (*fe)[7], ptr[ 2]); - - *pcm1++ = scale(SHIFT(MLZ(hi, lo))); - - pcm2 = pcm1 + 14; - - for (sb = 1; sb < 16; ++sb) { - ++fe; - ++Dptr; - - /* D[32 - sb][i] == -D[sb][31 - i] */ - - if (!(sb & 1)) { - ptr = *Dptr + po; - ML0(hi, lo, (*fo)[0], ptr[ 0]); - MLA(hi, lo, (*fo)[1], ptr[14]); - MLA(hi, lo, (*fo)[2], ptr[12]); - MLA(hi, lo, (*fo)[3], ptr[10]); - MLA(hi, lo, (*fo)[4], ptr[ 8]); - MLA(hi, lo, (*fo)[5], ptr[ 6]); - MLA(hi, lo, (*fo)[6], ptr[ 4]); - MLA(hi, lo, (*fo)[7], ptr[ 2]); - MLN(hi, lo); - - ptr = *Dptr + pe; - MLA(hi, lo, (*fe)[7], ptr[ 2]); - MLA(hi, lo, (*fe)[6], ptr[ 4]); - MLA(hi, lo, (*fe)[5], ptr[ 6]); - MLA(hi, lo, (*fe)[4], ptr[ 8]); - MLA(hi, lo, (*fe)[3], ptr[10]); - MLA(hi, lo, (*fe)[2], ptr[12]); - MLA(hi, lo, (*fe)[1], ptr[14]); - MLA(hi, lo, (*fe)[0], ptr[ 0]); - - *pcm1++ = scale(SHIFT(MLZ(hi, lo))); - - ptr = *Dptr - po; - ML0(hi, lo, (*fo)[7], ptr[31 - 2]); - MLA(hi, lo, (*fo)[6], ptr[31 - 4]); - MLA(hi, lo, (*fo)[5], ptr[31 - 6]); - MLA(hi, lo, (*fo)[4], ptr[31 - 8]); - MLA(hi, lo, (*fo)[3], ptr[31 - 10]); - MLA(hi, lo, (*fo)[2], ptr[31 - 12]); - MLA(hi, lo, (*fo)[1], ptr[31 - 14]); - MLA(hi, lo, (*fo)[0], ptr[31 - 16]); - - ptr = *Dptr - pe; - MLA(hi, lo, (*fe)[0], ptr[31 - 16]); - MLA(hi, lo, (*fe)[1], ptr[31 - 14]); - MLA(hi, lo, (*fe)[2], ptr[31 - 12]); - MLA(hi, lo, (*fe)[3], ptr[31 - 10]); - MLA(hi, lo, (*fe)[4], ptr[31 - 8]); - MLA(hi, lo, (*fe)[5], ptr[31 - 6]); - MLA(hi, lo, (*fe)[6], ptr[31 - 4]); - MLA(hi, lo, (*fe)[7], ptr[31 - 2]); - - *pcm2-- = scale(SHIFT(MLZ(hi, lo))); - } - - ++fo; + unsigned int nch, unsigned int startns, unsigned int endns, + enum mad_flow(*output_func)(void *s, struct mad_header const *, struct mad_pcm *), void *cbdata) { + unsigned int phase, ch, s, sb, pe, po; + int16_t *pcm1, *pcm2; + mad_fixed_t (*filter)[2][2][16][8]; + mad_fixed_t const(*sbsample)[36][32]; + register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8]; + register mad_fixed_t const(*Dptr)[32], *ptr; + register mad_fixed64hi_t hi; + register mad_fixed64lo_t lo; + stackenter(__FUNCTION__, __FILE__, __LINE__); + for (unsigned int start = startns; start < endns; start ++) { + for (ch = 0; ch < nch; ++ch) { + sbsample = &frame->sbsample[ch]; + filter = &synth->filter[ch]; + phase = (synth->phase + start) % 16; + pcm1 = synth->pcm.samples[ch];// + start * 32; + + for (s = start; s <= start; ++s) { + dct32((*sbsample)[s], phase >> 1, + (*filter)[0][phase & 1], (*filter)[1][phase & 1]); + + pe = phase & ~1; + po = ((phase - 1) & 0xf) | 1; + + /* calculate 16 samples */ + + fe = &(*filter)[0][ phase & 1][0]; + fx = &(*filter)[0][~phase & 1][0]; + fo = &(*filter)[1][~phase & 1][0]; + + Dptr = &D[0]; + + ptr = *Dptr + po; + ML0(hi, lo, (*fx)[0], ptr[ 0]); + MLA(hi, lo, (*fx)[1], ptr[14]); + MLA(hi, lo, (*fx)[2], ptr[12]); + MLA(hi, lo, (*fx)[3], ptr[10]); + MLA(hi, lo, (*fx)[4], ptr[ 8]); + MLA(hi, lo, (*fx)[5], ptr[ 6]); + MLA(hi, lo, (*fx)[6], ptr[ 4]); + MLA(hi, lo, (*fx)[7], ptr[ 2]); + MLN(hi, lo); + + ptr = *Dptr + pe; + MLA(hi, lo, (*fe)[0], ptr[ 0]); + MLA(hi, lo, (*fe)[1], ptr[14]); + MLA(hi, lo, (*fe)[2], ptr[12]); + MLA(hi, lo, (*fe)[3], ptr[10]); + MLA(hi, lo, (*fe)[4], ptr[ 8]); + MLA(hi, lo, (*fe)[5], ptr[ 6]); + MLA(hi, lo, (*fe)[6], ptr[ 4]); + MLA(hi, lo, (*fe)[7], ptr[ 2]); + + *pcm1++ = scale(SHIFT(MLZ(hi, lo))); + + pcm2 = pcm1 + 14; + + for (sb = 1; sb < 16; ++sb) { + ++fe; + ++Dptr; + + /* D[32 - sb][i] == -D[sb][31 - i] */ + + if (!(sb & 1)) { + ptr = *Dptr + po; + ML0(hi, lo, (*fo)[0], ptr[ 0]); + MLA(hi, lo, (*fo)[1], ptr[14]); + MLA(hi, lo, (*fo)[2], ptr[12]); + MLA(hi, lo, (*fo)[3], ptr[10]); + MLA(hi, lo, (*fo)[4], ptr[ 8]); + MLA(hi, lo, (*fo)[5], ptr[ 6]); + MLA(hi, lo, (*fo)[6], ptr[ 4]); + MLA(hi, lo, (*fo)[7], ptr[ 2]); + MLN(hi, lo); + + ptr = *Dptr + pe; + MLA(hi, lo, (*fe)[7], ptr[ 2]); + MLA(hi, lo, (*fe)[6], ptr[ 4]); + MLA(hi, lo, (*fe)[5], ptr[ 6]); + MLA(hi, lo, (*fe)[4], ptr[ 8]); + MLA(hi, lo, (*fe)[3], ptr[10]); + MLA(hi, lo, (*fe)[2], ptr[12]); + MLA(hi, lo, (*fe)[1], ptr[14]); + MLA(hi, lo, (*fe)[0], ptr[ 0]); + + *pcm1++ = scale(SHIFT(MLZ(hi, lo))); + + ptr = *Dptr - po; + ML0(hi, lo, (*fo)[7], ptr[31 - 2]); + MLA(hi, lo, (*fo)[6], ptr[31 - 4]); + MLA(hi, lo, (*fo)[5], ptr[31 - 6]); + MLA(hi, lo, (*fo)[4], ptr[31 - 8]); + MLA(hi, lo, (*fo)[3], ptr[31 - 10]); + MLA(hi, lo, (*fo)[2], ptr[31 - 12]); + MLA(hi, lo, (*fo)[1], ptr[31 - 14]); + MLA(hi, lo, (*fo)[0], ptr[31 - 16]); + + ptr = *Dptr - pe; + MLA(hi, lo, (*fe)[0], ptr[31 - 16]); + MLA(hi, lo, (*fe)[1], ptr[31 - 14]); + MLA(hi, lo, (*fe)[2], ptr[31 - 12]); + MLA(hi, lo, (*fe)[3], ptr[31 - 10]); + MLA(hi, lo, (*fe)[4], ptr[31 - 8]); + MLA(hi, lo, (*fe)[5], ptr[31 - 6]); + MLA(hi, lo, (*fe)[6], ptr[31 - 4]); + MLA(hi, lo, (*fe)[7], ptr[31 - 2]); + + *pcm2-- = scale(SHIFT(MLZ(hi, lo))); + } + + ++fo; + } + + ++Dptr; + + ptr = *Dptr + po; + ML0(hi, lo, (*fo)[0], ptr[ 0]); + MLA(hi, lo, (*fo)[1], ptr[14]); + MLA(hi, lo, (*fo)[2], ptr[12]); + MLA(hi, lo, (*fo)[3], ptr[10]); + MLA(hi, lo, (*fo)[4], ptr[ 8]); + MLA(hi, lo, (*fo)[5], ptr[ 6]); + MLA(hi, lo, (*fo)[6], ptr[ 4]); + MLA(hi, lo, (*fo)[7], ptr[ 2]); + + *pcm1 = scale(SHIFT(-MLZ(hi, lo))); + pcm1 += 8; + + phase = (phase + 1) % 16; + + } + } + if (output_func) { + enum mad_flow ret = output_func(cbdata, &frame->header, &synth->pcm); + if (ret != MAD_FLOW_CONTINUE) { + return ret; + } } - - ++Dptr; - - ptr = *Dptr + po; - ML0(hi, lo, (*fo)[0], ptr[ 0]); - MLA(hi, lo, (*fo)[1], ptr[14]); - MLA(hi, lo, (*fo)[2], ptr[12]); - MLA(hi, lo, (*fo)[3], ptr[10]); - MLA(hi, lo, (*fo)[4], ptr[ 8]); - MLA(hi, lo, (*fo)[5], ptr[ 6]); - MLA(hi, lo, (*fo)[6], ptr[ 4]); - MLA(hi, lo, (*fo)[7], ptr[ 2]); - - *pcm1 = scale(SHIFT(-MLZ(hi, lo))); - pcm1 += 8; - - phase = (phase + 1) % 16; - - } - } - if (output_func) { - enum mad_flow ret = output_func(cbdata, &frame->header, &synth->pcm); - if (ret != MAD_FLOW_CONTINUE) return ret; } - } - return MAD_FLOW_CONTINUE; + return MAD_FLOW_CONTINUE; } /* - NAME: synth->frame() - DESCRIPTION: perform PCM synthesis of frame subband samples + NAME: synth->frame() + DESCRIPTION: perform PCM synthesis of frame subband samples */ -enum mad_flow mad_synth_frame(struct mad_synth *synth, struct mad_frame const *frame, enum mad_flow (*output_func)(void *s, struct mad_header const *, struct mad_pcm *), void *cbdata) +enum mad_flow mad_synth_frame(struct mad_synth *synth, struct mad_frame const *frame, enum mad_flow(*output_func)(void *s, struct mad_header const *, struct mad_pcm *), void *cbdata) //void mad_synth_frame(struct mad_synth *synth, struct mad_frame const *frame) { - unsigned int nch, ns; - enum mad_flow (*synth_frame)(struct mad_synth *, struct mad_frame const *, unsigned int, unsigned int, unsigned int, enum mad_flow (*output_func)(), void *); + unsigned int nch, ns; + enum mad_flow(*synth_frame)(struct mad_synth *, struct mad_frame const *, unsigned int, unsigned int, unsigned int, enum mad_flow(*output_func)(), void *); - nch = MAD_NCHANNELS(&frame->header); - ns = MAD_NSBSAMPLES(&frame->header); + nch = MAD_NCHANNELS(&frame->header); + ns = MAD_NSBSAMPLES(&frame->header); - synth->pcm.samplerate = frame->header.samplerate; - synth->pcm.channels = nch; - synth->pcm.length = 32;// * ns; + synth->pcm.samplerate = frame->header.samplerate; + synth->pcm.channels = nch; + synth->pcm.length = 32;// * ns; - synth_frame = synth_full; + synth_frame = synth_full; - if (frame->options & MAD_OPTION_HALFSAMPLERATE) { - synth->pcm.samplerate /= 2; - synth->pcm.length /= 2; + if (frame->options & MAD_OPTION_HALFSAMPLERATE) { + synth->pcm.samplerate /= 2; + synth->pcm.length /= 2; - synth_frame = synth_half; - } + synth_frame = synth_half; + } - enum mad_flow ret = synth_frame(synth, frame, nch, 0, ns, output_func, cbdata); + enum mad_flow ret = synth_frame(synth, frame, nch, 0, ns, output_func, cbdata); - synth->phase = (synth->phase + ns) % 16; + synth->phase = (synth->phase + ns) % 16; - return ret; + return ret; } // Synthesize a single NS of the frame, return in the synth->pcm.samples // Up to caller to increment synth->phase, only call proper # of ns -enum mad_flow mad_synth_frame_onens(struct mad_synth *synth, struct mad_frame const *frame, unsigned int ns) -{ - unsigned int nch; //, ns; - enum mad_flow (*synth_frame)(struct mad_synth *, struct mad_frame const *, unsigned int, unsigned int, unsigned int, enum mad_flow (*output_func)(), void *); +enum mad_flow mad_synth_frame_onens(struct mad_synth *synth, struct mad_frame const *frame, unsigned int ns) { + unsigned int nch; //, ns; + enum mad_flow(*synth_frame)(struct mad_synth *, struct mad_frame const *, unsigned int, unsigned int, unsigned int, enum mad_flow(*output_func)(), void *); - nch = MAD_NCHANNELS(&frame->header); -// ns = MAD_NSBSAMPLES(&frame->header); + nch = MAD_NCHANNELS(&frame->header); + // ns = MAD_NSBSAMPLES(&frame->header); - synth->pcm.samplerate = frame->header.samplerate; - synth->pcm.channels = nch; - synth->pcm.length = 32;// * ns; + synth->pcm.samplerate = frame->header.samplerate; + synth->pcm.channels = nch; + synth->pcm.length = 32;// * ns; - synth_frame = synth_full; + synth_frame = synth_full; - if (frame->options & MAD_OPTION_HALFSAMPLERATE) { - synth->pcm.samplerate /= 2; - synth->pcm.length /= 2; + if (frame->options & MAD_OPTION_HALFSAMPLERATE) { + synth->pcm.samplerate /= 2; + synth->pcm.length /= 2; - synth_frame = synth_half; - } - enum mad_flow ret = synth_frame(synth, frame, nch, ns, ns+1, NULL, NULL); + synth_frame = synth_half; + } + enum mad_flow ret = synth_frame(synth, frame, nch, ns, ns + 1, NULL, NULL); - if (ns==MAD_NSBSAMPLES(&frame->header)-1) - synth->phase = (synth->phase + MAD_NSBSAMPLES(&frame->header)) % 16; + if (ns == MAD_NSBSAMPLES(&frame->header) - 1) { + synth->phase = (synth->phase + MAD_NSBSAMPLES(&frame->header)) % 16; + } - return ret; + return ret; } diff --git a/src/libmad/synth.h b/src/libmad/synth.h index 3cdf9220..0f52349c 100644 --- a/src/libmad/synth.h +++ b/src/libmad/synth.h @@ -1,23 +1,23 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: synth.h,v 1.15 2004/01/23 09:41:33 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: synth.h,v 1.15 2004/01/23 09:41:33 rob Exp $ +*/ # ifndef LIBMAD_SYNTH_H # define LIBMAD_SYNTH_H @@ -27,36 +27,36 @@ #include struct mad_pcm { - unsigned int samplerate; /* sampling frequency (Hz) */ - unsigned short channels; /* number of channels */ - unsigned short length; /* number of samples per channel */ - int16_t samples[2][32]; //1152]; /* PCM output samples [ch][sample] */ + unsigned int samplerate; /* sampling frequency (Hz) */ + unsigned short channels; /* number of channels */ + unsigned short length; /* number of samples per channel */ + int16_t samples[2][32]; //1152]; /* PCM output samples [ch][sample] */ }; struct mad_synth { - mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */ - /* [ch][eo][peo][s][v] */ + mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */ + /* [ch][eo][peo][s][v] */ - unsigned int phase; /* current processing phase */ + unsigned int phase; /* current processing phase */ - struct mad_pcm pcm; /* PCM output */ + struct mad_pcm pcm; /* PCM output */ }; /* single channel PCM selector */ enum { - MAD_PCM_CHANNEL_SINGLE = 0 + MAD_PCM_CHANNEL_SINGLE = 0 }; /* dual channel PCM selector */ enum { - MAD_PCM_CHANNEL_DUAL_1 = 0, - MAD_PCM_CHANNEL_DUAL_2 = 1 + MAD_PCM_CHANNEL_DUAL_1 = 0, + MAD_PCM_CHANNEL_DUAL_2 = 1 }; /* stereo PCM selector */ enum { - MAD_PCM_CHANNEL_STEREO_LEFT = 0, - MAD_PCM_CHANNEL_STEREO_RIGHT = 1 + MAD_PCM_CHANNEL_STEREO_LEFT = 0, + MAD_PCM_CHANNEL_STEREO_RIGHT = 1 }; void mad_synth_init(struct mad_synth *); @@ -65,7 +65,7 @@ void mad_synth_init(struct mad_synth *); void mad_synth_mute(struct mad_synth *); -enum mad_flow mad_synth_frame(struct mad_synth *, struct mad_frame const *, enum mad_flow (*output_func)(void *s, struct mad_header const *, struct mad_pcm *), void *cbdata ); +enum mad_flow mad_synth_frame(struct mad_synth *, struct mad_frame const *, enum mad_flow(*output_func)(void *s, struct mad_header const *, struct mad_pcm *), void *cbdata); enum mad_flow mad_synth_frame_onens(struct mad_synth *synth, struct mad_frame const *frame, unsigned int ns); # endif diff --git a/src/libmad/timer.c b/src/libmad/timer.c index 6b434c9c..7bf777c7 100644 --- a/src/libmad/timer.c +++ b/src/libmad/timer.c @@ -1,23 +1,23 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: timer.c,v 1.18 2004/01/23 09:41:33 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: timer.c,v 1.18 2004/01/23 09:41:33 rob Exp $ +*/ #pragma GCC optimize ("O3") @@ -36,450 +36,445 @@ mad_timer_t const mad_timer_zero = { 0, 0 }; /* - * NAME: timer->compare() - * DESCRIPTION: indicate relative order of two timers - */ -int mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2) -{ - signed long diff; - - diff = timer1.seconds - timer2.seconds; - if (diff < 0) - return -1; - else if (diff > 0) - return +1; - - diff = timer1.fraction - timer2.fraction; - if (diff < 0) - return -1; - else if (diff > 0) - return +1; - - return 0; + NAME: timer->compare() + DESCRIPTION: indicate relative order of two timers +*/ +int mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2) { + signed long diff; + + diff = timer1.seconds - timer2.seconds; + if (diff < 0) { + return -1; + } else if (diff > 0) { + return +1; + } + + diff = timer1.fraction - timer2.fraction; + if (diff < 0) { + return -1; + } else if (diff > 0) { + return +1; + } + + return 0; } /* - * NAME: timer->negate() - * DESCRIPTION: invert the sign of a timer - */ -void mad_timer_negate(mad_timer_t *timer) -{ - timer->seconds = -timer->seconds; - - if (timer->fraction) { - timer->seconds -= 1; - timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction; - } + NAME: timer->negate() + DESCRIPTION: invert the sign of a timer +*/ +void mad_timer_negate(mad_timer_t *timer) { + timer->seconds = -timer->seconds; + + if (timer->fraction) { + timer->seconds -= 1; + timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction; + } } /* - * NAME: timer->abs() - * DESCRIPTION: return the absolute value of a timer - */ -mad_timer_t mad_timer_abs(mad_timer_t timer) -{ - if (timer.seconds < 0) - mad_timer_negate(&timer); - - return timer; + NAME: timer->abs() + DESCRIPTION: return the absolute value of a timer +*/ +mad_timer_t mad_timer_abs(mad_timer_t timer) { + if (timer.seconds < 0) { + mad_timer_negate(&timer); + } + + return timer; } /* - * NAME: reduce_timer() - * DESCRIPTION: carry timer fraction into seconds - */ + NAME: reduce_timer() + DESCRIPTION: carry timer fraction into seconds +*/ static -void reduce_timer(mad_timer_t *timer) -{ - timer->seconds += timer->fraction / MAD_TIMER_RESOLUTION; - timer->fraction %= MAD_TIMER_RESOLUTION; +void reduce_timer(mad_timer_t *timer) { + timer->seconds += timer->fraction / MAD_TIMER_RESOLUTION; + timer->fraction %= MAD_TIMER_RESOLUTION; } /* - * NAME: gcd() - * DESCRIPTION: compute greatest common denominator - */ + NAME: gcd() + DESCRIPTION: compute greatest common denominator +*/ static -unsigned long gcd(unsigned long num1, unsigned long num2) -{ - unsigned long tmp; +unsigned long gcd(unsigned long num1, unsigned long num2) { + unsigned long tmp; - while (num2) { - tmp = num2; - num2 = num1 % num2; - num1 = tmp; - } + while (num2) { + tmp = num2; + num2 = num1 % num2; + num1 = tmp; + } - return num1; + return num1; } /* - * NAME: reduce_rational() - * DESCRIPTION: convert rational expression to lowest terms - */ + NAME: reduce_rational() + DESCRIPTION: convert rational expression to lowest terms +*/ static -void reduce_rational(unsigned long *numer, unsigned long *denom) -{ - unsigned long factor; +void reduce_rational(unsigned long *numer, unsigned long *denom) { + unsigned long factor; - factor = gcd(*numer, *denom); + factor = gcd(*numer, *denom); - assert(factor != 0); + assert(factor != 0); - *numer /= factor; - *denom /= factor; + *numer /= factor; + *denom /= factor; } /* - * NAME: scale_rational() - * DESCRIPTION: solve numer/denom == ?/scale avoiding overflowing - */ + NAME: scale_rational() + DESCRIPTION: solve numer/denom == ?/scale avoiding overflowing +*/ static unsigned long scale_rational(unsigned long numer, unsigned long denom, - unsigned long scale) -{ - reduce_rational(&numer, &denom); - reduce_rational(&scale, &denom); + unsigned long scale) { + reduce_rational(&numer, &denom); + reduce_rational(&scale, &denom); - assert(denom != 0); + assert(denom != 0); - if (denom < scale) - return numer * (scale / denom) + numer * (scale % denom) / denom; - if (denom < numer) - return scale * (numer / denom) + scale * (numer % denom) / denom; + if (denom < scale) { + return numer * (scale / denom) + numer * (scale % denom) / denom; + } + if (denom < numer) { + return scale * (numer / denom) + scale * (numer % denom) / denom; + } - return numer * scale / denom; + return numer * scale / denom; } /* - * NAME: timer->set() - * DESCRIPTION: set timer to specific (positive) value - */ + NAME: timer->set() + DESCRIPTION: set timer to specific (positive) value +*/ void mad_timer_set(mad_timer_t *timer, unsigned long seconds, - unsigned long numer, unsigned long denom) -{ - timer->seconds = seconds; - if (numer >= denom && denom > 0) { - timer->seconds += numer / denom; - numer %= denom; - } - - switch (denom) { - case 0: - case 1: - timer->fraction = 0; - break; + unsigned long numer, unsigned long denom) { + timer->seconds = seconds; + if (numer >= denom && denom > 0) { + timer->seconds += numer / denom; + numer %= denom; + } - case MAD_TIMER_RESOLUTION: - timer->fraction = numer; - break; + switch (denom) { + case 0: + case 1: + timer->fraction = 0; + break; - case 1000: - timer->fraction = numer * (MAD_TIMER_RESOLUTION / 1000); - break; + case MAD_TIMER_RESOLUTION: + timer->fraction = numer; + break; - case 8000: - timer->fraction = numer * (MAD_TIMER_RESOLUTION / 8000); - break; + case 1000: + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 1000); + break; - case 11025: - timer->fraction = numer * (MAD_TIMER_RESOLUTION / 11025); - break; + case 8000: + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 8000); + break; - case 12000: - timer->fraction = numer * (MAD_TIMER_RESOLUTION / 12000); - break; + case 11025: + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 11025); + break; - case 16000: - timer->fraction = numer * (MAD_TIMER_RESOLUTION / 16000); - break; + case 12000: + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 12000); + break; - case 22050: - timer->fraction = numer * (MAD_TIMER_RESOLUTION / 22050); - break; + case 16000: + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 16000); + break; - case 24000: - timer->fraction = numer * (MAD_TIMER_RESOLUTION / 24000); - break; + case 22050: + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 22050); + break; - case 32000: - timer->fraction = numer * (MAD_TIMER_RESOLUTION / 32000); - break; + case 24000: + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 24000); + break; - case 44100: - timer->fraction = numer * (MAD_TIMER_RESOLUTION / 44100); - break; + case 32000: + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 32000); + break; - case 48000: - timer->fraction = numer * (MAD_TIMER_RESOLUTION / 48000); - break; + case 44100: + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 44100); + break; - default: - timer->fraction = scale_rational(numer, denom, MAD_TIMER_RESOLUTION); - break; - } + case 48000: + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 48000); + break; + + default: + timer->fraction = scale_rational(numer, denom, MAD_TIMER_RESOLUTION); + break; + } - if (timer->fraction >= MAD_TIMER_RESOLUTION) - reduce_timer(timer); + if (timer->fraction >= MAD_TIMER_RESOLUTION) { + reduce_timer(timer); + } } /* - * NAME: timer->add() - * DESCRIPTION: add one timer to another - */ -void mad_timer_add(mad_timer_t *timer, mad_timer_t incr) -{ - timer->seconds += incr.seconds; - timer->fraction += incr.fraction; - - if (timer->fraction >= MAD_TIMER_RESOLUTION) - reduce_timer(timer); + NAME: timer->add() + DESCRIPTION: add one timer to another +*/ +void mad_timer_add(mad_timer_t *timer, mad_timer_t incr) { + timer->seconds += incr.seconds; + timer->fraction += incr.fraction; + + if (timer->fraction >= MAD_TIMER_RESOLUTION) { + reduce_timer(timer); + } } /* - * NAME: timer->multiply() - * DESCRIPTION: multiply a timer by a scalar value - */ -void mad_timer_multiply(mad_timer_t *timer, signed long scalar) -{ - mad_timer_t addend; - unsigned long factor; - - factor = scalar; - if (scalar < 0) { - factor = -scalar; - mad_timer_negate(timer); - } - - addend = *timer; - *timer = mad_timer_zero; - - while (factor) { - if (factor & 1) - mad_timer_add(timer, addend); - - mad_timer_add(&addend, addend); - factor >>= 1; - } + NAME: timer->multiply() + DESCRIPTION: multiply a timer by a scalar value +*/ +void mad_timer_multiply(mad_timer_t *timer, signed long scalar) { + mad_timer_t addend; + unsigned long factor; + + factor = scalar; + if (scalar < 0) { + factor = -scalar; + mad_timer_negate(timer); + } + + addend = *timer; + *timer = mad_timer_zero; + + while (factor) { + if (factor & 1) { + mad_timer_add(timer, addend); + } + + mad_timer_add(&addend, addend); + factor >>= 1; + } } /* - * NAME: timer->count() - * DESCRIPTION: return timer value in selected units - */ -signed long mad_timer_count(mad_timer_t timer, enum mad_units units) -{ - switch (units) { - case MAD_UNITS_HOURS: - return timer.seconds / 60 / 60; - - case MAD_UNITS_MINUTES: - return timer.seconds / 60; - - case MAD_UNITS_SECONDS: - return timer.seconds; - - case MAD_UNITS_DECISECONDS: - case MAD_UNITS_CENTISECONDS: - case MAD_UNITS_MILLISECONDS: - - case MAD_UNITS_8000_HZ: - case MAD_UNITS_11025_HZ: - case MAD_UNITS_12000_HZ: - case MAD_UNITS_16000_HZ: - case MAD_UNITS_22050_HZ: - case MAD_UNITS_24000_HZ: - case MAD_UNITS_32000_HZ: - case MAD_UNITS_44100_HZ: - case MAD_UNITS_48000_HZ: - - case MAD_UNITS_24_FPS: - case MAD_UNITS_25_FPS: - case MAD_UNITS_30_FPS: - case MAD_UNITS_48_FPS: - case MAD_UNITS_50_FPS: - case MAD_UNITS_60_FPS: - case MAD_UNITS_75_FPS: - return timer.seconds * (signed long) units + - (signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, - units); - - case MAD_UNITS_23_976_FPS: - case MAD_UNITS_24_975_FPS: - case MAD_UNITS_29_97_FPS: - case MAD_UNITS_47_952_FPS: - case MAD_UNITS_49_95_FPS: - case MAD_UNITS_59_94_FPS: - return (mad_timer_count(timer, -units) + 1) * 1000 / 1001; - } - - /* unsupported units */ - return 0; + NAME: timer->count() + DESCRIPTION: return timer value in selected units +*/ +signed long mad_timer_count(mad_timer_t timer, enum mad_units units) { + switch (units) { + case MAD_UNITS_HOURS: + return timer.seconds / 60 / 60; + + case MAD_UNITS_MINUTES: + return timer.seconds / 60; + + case MAD_UNITS_SECONDS: + return timer.seconds; + + case MAD_UNITS_DECISECONDS: + case MAD_UNITS_CENTISECONDS: + case MAD_UNITS_MILLISECONDS: + + case MAD_UNITS_8000_HZ: + case MAD_UNITS_11025_HZ: + case MAD_UNITS_12000_HZ: + case MAD_UNITS_16000_HZ: + case MAD_UNITS_22050_HZ: + case MAD_UNITS_24000_HZ: + case MAD_UNITS_32000_HZ: + case MAD_UNITS_44100_HZ: + case MAD_UNITS_48000_HZ: + + case MAD_UNITS_24_FPS: + case MAD_UNITS_25_FPS: + case MAD_UNITS_30_FPS: + case MAD_UNITS_48_FPS: + case MAD_UNITS_50_FPS: + case MAD_UNITS_60_FPS: + case MAD_UNITS_75_FPS: + return timer.seconds * (signed long) units + + (signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, + units); + + case MAD_UNITS_23_976_FPS: + case MAD_UNITS_24_975_FPS: + case MAD_UNITS_29_97_FPS: + case MAD_UNITS_47_952_FPS: + case MAD_UNITS_49_95_FPS: + case MAD_UNITS_59_94_FPS: + return (mad_timer_count(timer, -units) + 1) * 1000 / 1001; + } + + /* unsupported units */ + return 0; } /* - * NAME: timer->fraction() - * DESCRIPTION: return fractional part of timer in arbitrary terms - */ -unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long denom) -{ - timer = mad_timer_abs(timer); - - switch (denom) { - case 0: - return timer.fraction ? - MAD_TIMER_RESOLUTION / timer.fraction : MAD_TIMER_RESOLUTION + 1; - - case MAD_TIMER_RESOLUTION: - return timer.fraction; - - default: - return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, denom); - } + NAME: timer->fraction() + DESCRIPTION: return fractional part of timer in arbitrary terms +*/ +unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long denom) { + timer = mad_timer_abs(timer); + + switch (denom) { + case 0: + return timer.fraction ? + MAD_TIMER_RESOLUTION / timer.fraction : MAD_TIMER_RESOLUTION + 1; + + case MAD_TIMER_RESOLUTION: + return timer.fraction; + + default: + return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, denom); + } } /* - * NAME: timer->string() - * DESCRIPTION: write a string representation of a timer using a template - */ + NAME: timer->string() + DESCRIPTION: write a string representation of a timer using a template +*/ void mad_timer_string(mad_timer_t timer, - char *dest, char const *format, enum mad_units units, - enum mad_units fracunits, unsigned long subparts) -{ - unsigned long hours, minutes, seconds, sub; - unsigned int frac; - - timer = mad_timer_abs(timer); - - seconds = timer.seconds; - frac = sub = 0; - - switch (fracunits) { - case MAD_UNITS_HOURS: - case MAD_UNITS_MINUTES: - case MAD_UNITS_SECONDS: - break; - - case MAD_UNITS_DECISECONDS: - case MAD_UNITS_CENTISECONDS: - case MAD_UNITS_MILLISECONDS: - - case MAD_UNITS_8000_HZ: - case MAD_UNITS_11025_HZ: - case MAD_UNITS_12000_HZ: - case MAD_UNITS_16000_HZ: - case MAD_UNITS_22050_HZ: - case MAD_UNITS_24000_HZ: - case MAD_UNITS_32000_HZ: - case MAD_UNITS_44100_HZ: - case MAD_UNITS_48000_HZ: - - case MAD_UNITS_24_FPS: - case MAD_UNITS_25_FPS: - case MAD_UNITS_30_FPS: - case MAD_UNITS_48_FPS: - case MAD_UNITS_50_FPS: - case MAD_UNITS_60_FPS: - case MAD_UNITS_75_FPS: - { - unsigned long denom; - - denom = MAD_TIMER_RESOLUTION / fracunits; - - frac = timer.fraction / denom; - sub = scale_rational(timer.fraction % denom, denom, subparts); + char *dest, char const *format, enum mad_units units, + enum mad_units fracunits, unsigned long subparts) { + unsigned long hours, minutes, seconds, sub; + unsigned int frac; + + timer = mad_timer_abs(timer); + + seconds = timer.seconds; + frac = sub = 0; + + switch (fracunits) { + case MAD_UNITS_HOURS: + case MAD_UNITS_MINUTES: + case MAD_UNITS_SECONDS: + break; + + case MAD_UNITS_DECISECONDS: + case MAD_UNITS_CENTISECONDS: + case MAD_UNITS_MILLISECONDS: + + case MAD_UNITS_8000_HZ: + case MAD_UNITS_11025_HZ: + case MAD_UNITS_12000_HZ: + case MAD_UNITS_16000_HZ: + case MAD_UNITS_22050_HZ: + case MAD_UNITS_24000_HZ: + case MAD_UNITS_32000_HZ: + case MAD_UNITS_44100_HZ: + case MAD_UNITS_48000_HZ: + + case MAD_UNITS_24_FPS: + case MAD_UNITS_25_FPS: + case MAD_UNITS_30_FPS: + case MAD_UNITS_48_FPS: + case MAD_UNITS_50_FPS: + case MAD_UNITS_60_FPS: + case MAD_UNITS_75_FPS: { + unsigned long denom; + + denom = MAD_TIMER_RESOLUTION / fracunits; + + frac = timer.fraction / denom; + sub = scale_rational(timer.fraction % denom, denom, subparts); } break; - case MAD_UNITS_23_976_FPS: - case MAD_UNITS_24_975_FPS: - case MAD_UNITS_29_97_FPS: - case MAD_UNITS_47_952_FPS: - case MAD_UNITS_49_95_FPS: - case MAD_UNITS_59_94_FPS: - /* drop-frame encoding */ - /* N.B. this is only well-defined for MAD_UNITS_29_97_FPS */ + case MAD_UNITS_23_976_FPS: + case MAD_UNITS_24_975_FPS: + case MAD_UNITS_29_97_FPS: + case MAD_UNITS_47_952_FPS: + case MAD_UNITS_49_95_FPS: + case MAD_UNITS_59_94_FPS: + /* drop-frame encoding */ + /* N.B. this is only well-defined for MAD_UNITS_29_97_FPS */ { - unsigned long frame, cycle, d, m; + unsigned long frame, cycle, d, m; - frame = mad_timer_count(timer, fracunits); + frame = mad_timer_count(timer, fracunits); - cycle = -fracunits * 60 * 10 - (10 - 1) * 2; + cycle = -fracunits * 60 * 10 - (10 - 1) * 2; - d = frame / cycle; - m = frame % cycle; - frame += (10 - 1) * 2 * d; - if (m > 2) - frame += 2 * ((m - 2) / (cycle / 10)); + d = frame / cycle; + m = frame % cycle; + frame += (10 - 1) * 2 * d; + if (m > 2) { + frame += 2 * ((m - 2) / (cycle / 10)); + } - frac = frame % -fracunits; - seconds = frame / -fracunits; + frac = frame % -fracunits; + seconds = frame / -fracunits; } break; - } - - switch (units) { - case MAD_UNITS_HOURS: - minutes = seconds / 60; - hours = minutes / 60; - - sprintf(dest, format, - hours, - (unsigned int) (minutes % 60), - (unsigned int) (seconds % 60), - frac, sub); - break; - - case MAD_UNITS_MINUTES: - minutes = seconds / 60; - - sprintf(dest, format, - minutes, - (unsigned int) (seconds % 60), - frac, sub); - break; - - case MAD_UNITS_SECONDS: - sprintf(dest, format, - seconds, - frac, sub); - break; - - case MAD_UNITS_23_976_FPS: - case MAD_UNITS_24_975_FPS: - case MAD_UNITS_29_97_FPS: - case MAD_UNITS_47_952_FPS: - case MAD_UNITS_49_95_FPS: - case MAD_UNITS_59_94_FPS: - if (fracunits < 0) { - /* not yet implemented */ - sub = 0; } + switch (units) { + case MAD_UNITS_HOURS: + minutes = seconds / 60; + hours = minutes / 60; + + sprintf(dest, format, + hours, + (unsigned int)(minutes % 60), + (unsigned int)(seconds % 60), + frac, sub); + break; + + case MAD_UNITS_MINUTES: + minutes = seconds / 60; + + sprintf(dest, format, + minutes, + (unsigned int)(seconds % 60), + frac, sub); + break; + + case MAD_UNITS_SECONDS: + sprintf(dest, format, + seconds, + frac, sub); + break; + + case MAD_UNITS_23_976_FPS: + case MAD_UNITS_24_975_FPS: + case MAD_UNITS_29_97_FPS: + case MAD_UNITS_47_952_FPS: + case MAD_UNITS_49_95_FPS: + case MAD_UNITS_59_94_FPS: + if (fracunits < 0) { + /* not yet implemented */ + sub = 0; + } + /* fall through */ - case MAD_UNITS_DECISECONDS: - case MAD_UNITS_CENTISECONDS: - case MAD_UNITS_MILLISECONDS: - - case MAD_UNITS_8000_HZ: - case MAD_UNITS_11025_HZ: - case MAD_UNITS_12000_HZ: - case MAD_UNITS_16000_HZ: - case MAD_UNITS_22050_HZ: - case MAD_UNITS_24000_HZ: - case MAD_UNITS_32000_HZ: - case MAD_UNITS_44100_HZ: - case MAD_UNITS_48000_HZ: - - case MAD_UNITS_24_FPS: - case MAD_UNITS_25_FPS: - case MAD_UNITS_30_FPS: - case MAD_UNITS_48_FPS: - case MAD_UNITS_50_FPS: - case MAD_UNITS_60_FPS: - case MAD_UNITS_75_FPS: - sprintf(dest, format, mad_timer_count(timer, units), sub); - break; - } + case MAD_UNITS_DECISECONDS: + case MAD_UNITS_CENTISECONDS: + case MAD_UNITS_MILLISECONDS: + + case MAD_UNITS_8000_HZ: + case MAD_UNITS_11025_HZ: + case MAD_UNITS_12000_HZ: + case MAD_UNITS_16000_HZ: + case MAD_UNITS_22050_HZ: + case MAD_UNITS_24000_HZ: + case MAD_UNITS_32000_HZ: + case MAD_UNITS_44100_HZ: + case MAD_UNITS_48000_HZ: + + case MAD_UNITS_24_FPS: + case MAD_UNITS_25_FPS: + case MAD_UNITS_30_FPS: + case MAD_UNITS_48_FPS: + case MAD_UNITS_50_FPS: + case MAD_UNITS_60_FPS: + case MAD_UNITS_75_FPS: + sprintf(dest, format, mad_timer_count(timer, units), sub); + break; + } } diff --git a/src/libmad/timer.h b/src/libmad/timer.h index eb4542bb..64afdd5f 100644 --- a/src/libmad/timer.h +++ b/src/libmad/timer.h @@ -1,30 +1,30 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: timer.h,v 1.16 2004/01/23 09:41:33 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: timer.h,v 1.16 2004/01/23 09:41:33 rob Exp $ +*/ # ifndef LIBMAD_TIMER_H # define LIBMAD_TIMER_H typedef struct { - signed long seconds; /* whole seconds */ - unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */ + signed long seconds; /* whole seconds */ + unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */ } mad_timer_t; extern mad_timer_t const mad_timer_zero; @@ -32,51 +32,51 @@ extern mad_timer_t const mad_timer_zero; # define MAD_TIMER_RESOLUTION 352800000UL enum mad_units { - MAD_UNITS_HOURS = -2, - MAD_UNITS_MINUTES = -1, - MAD_UNITS_SECONDS = 0, + MAD_UNITS_HOURS = -2, + MAD_UNITS_MINUTES = -1, + MAD_UNITS_SECONDS = 0, - /* metric units */ + /* metric units */ - MAD_UNITS_DECISECONDS = 10, - MAD_UNITS_CENTISECONDS = 100, - MAD_UNITS_MILLISECONDS = 1000, + MAD_UNITS_DECISECONDS = 10, + MAD_UNITS_CENTISECONDS = 100, + MAD_UNITS_MILLISECONDS = 1000, - /* audio sample units */ + /* audio sample units */ - MAD_UNITS_8000_HZ = 8000, - MAD_UNITS_11025_HZ = 11025, - MAD_UNITS_12000_HZ = 12000, + MAD_UNITS_8000_HZ = 8000, + MAD_UNITS_11025_HZ = 11025, + MAD_UNITS_12000_HZ = 12000, - MAD_UNITS_16000_HZ = 16000, - MAD_UNITS_22050_HZ = 22050, - MAD_UNITS_24000_HZ = 24000, + MAD_UNITS_16000_HZ = 16000, + MAD_UNITS_22050_HZ = 22050, + MAD_UNITS_24000_HZ = 24000, - MAD_UNITS_32000_HZ = 32000, - MAD_UNITS_44100_HZ = 44100, - MAD_UNITS_48000_HZ = 48000, + MAD_UNITS_32000_HZ = 32000, + MAD_UNITS_44100_HZ = 44100, + MAD_UNITS_48000_HZ = 48000, - /* video frame/field units */ + /* video frame/field units */ - MAD_UNITS_24_FPS = 24, - MAD_UNITS_25_FPS = 25, - MAD_UNITS_30_FPS = 30, - MAD_UNITS_48_FPS = 48, - MAD_UNITS_50_FPS = 50, - MAD_UNITS_60_FPS = 60, + MAD_UNITS_24_FPS = 24, + MAD_UNITS_25_FPS = 25, + MAD_UNITS_30_FPS = 30, + MAD_UNITS_48_FPS = 48, + MAD_UNITS_50_FPS = 50, + MAD_UNITS_60_FPS = 60, - /* CD audio frames */ + /* CD audio frames */ - MAD_UNITS_75_FPS = 75, + MAD_UNITS_75_FPS = 75, - /* video drop-frame units */ + /* video drop-frame units */ - MAD_UNITS_23_976_FPS = -24, - MAD_UNITS_24_975_FPS = -25, - MAD_UNITS_29_97_FPS = -30, - MAD_UNITS_47_952_FPS = -48, - MAD_UNITS_49_95_FPS = -50, - MAD_UNITS_59_94_FPS = -60 + MAD_UNITS_23_976_FPS = -24, + MAD_UNITS_24_975_FPS = -25, + MAD_UNITS_29_97_FPS = -30, + MAD_UNITS_47_952_FPS = -48, + MAD_UNITS_49_95_FPS = -50, + MAD_UNITS_59_94_FPS = -60 }; # define mad_timer_reset(timer) ((void) (*(timer) = mad_timer_zero)) @@ -95,6 +95,6 @@ void mad_timer_multiply(mad_timer_t *, signed long); signed long mad_timer_count(mad_timer_t, enum mad_units); unsigned long mad_timer_fraction(mad_timer_t, unsigned long); void mad_timer_string(mad_timer_t, char *, char const *, - enum mad_units, enum mad_units, unsigned long); + enum mad_units, enum mad_units, unsigned long); # endif diff --git a/src/libmad/version.c b/src/libmad/version.c index b1cf1d34..bb54e044 100644 --- a/src/libmad/version.c +++ b/src/libmad/version.c @@ -1,23 +1,23 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: version.c,v 1.15 2004/01/23 09:41:33 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: version.c,v 1.15 2004/01/23 09:41:33 rob Exp $ +*/ #pragma GCC optimize ("O3") @@ -33,59 +33,59 @@ char const mad_author[] = MAD_AUTHOR " <" MAD_EMAIL ">"; char const mad_build[] = "" # if defined(DEBUG) - "DEBUG " + "DEBUG " # elif defined(NDEBUG) - "NDEBUG " + "NDEBUG " # endif # if defined(EXPERIMENTAL) - "EXPERIMENTAL " + "EXPERIMENTAL " # endif # if defined(FPM_64BIT) - "FPM_64BIT " + "FPM_64BIT " # elif defined(FPM_INTEL) - "FPM_INTEL " + "FPM_INTEL " # elif defined(FPM_ARM) - "FPM_ARM " + "FPM_ARM " # elif defined(FPM_MIPS) - "FPM_MIPS " + "FPM_MIPS " # elif defined(FPM_SPARC) - "FPM_SPARC " + "FPM_SPARC " # elif defined(FPM_PPC) - "FPM_PPC " + "FPM_PPC " # elif defined(FPM_DEFAULT) - "FPM_DEFAULT " + "FPM_DEFAULT " # endif # if defined(ASO_IMDCT) - "ASO_IMDCT " + "ASO_IMDCT " # endif # if defined(ASO_INTERLEAVE1) - "ASO_INTERLEAVE1 " + "ASO_INTERLEAVE1 " # endif # if defined(ASO_INTERLEAVE2) - "ASO_INTERLEAVE2 " + "ASO_INTERLEAVE2 " # endif # if defined(ASO_ZEROCHECK) - "ASO_ZEROCHECK " + "ASO_ZEROCHECK " # endif # if defined(OPT_SPEED) - "OPT_SPEED " + "OPT_SPEED " # elif defined(OPT_ACCURACY) - "OPT_ACCURACY " + "OPT_ACCURACY " # endif # if defined(OPT_SSO) - "OPT_SSO " + "OPT_SSO " # endif # if defined(OPT_DCTO) /* never defined here */ - "OPT_DCTO " + "OPT_DCTO " # endif # if defined(OPT_STRICT) - "OPT_STRICT " + "OPT_STRICT " # endif -; + ; diff --git a/src/libmad/version.h b/src/libmad/version.h index d215d4c1..8774f680 100644 --- a/src/libmad/version.h +++ b/src/libmad/version.h @@ -1,23 +1,23 @@ /* - * libmad - MPEG audio decoder library - * Copyright (C) 2000-2004 Underbit Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id: version.h,v 1.26 2004/01/23 09:41:33 rob Exp $ - */ + libmad - MPEG audio decoder library + Copyright (C) 2000-2004 Underbit Technologies, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id: version.h,v 1.26 2004/01/23 09:41:33 rob Exp $ +*/ # ifndef LIBMAD_VERSION_H # define LIBMAD_VERSION_H diff --git a/src/libogg/AUTHORS b/src/libogg/AUTHORS deleted file mode 100644 index a0023f2c..00000000 --- a/src/libogg/AUTHORS +++ /dev/null @@ -1,7 +0,0 @@ -Monty -Greg Maxwell -Ralph Giles -Cristian Adam -Tim Terriberry - -and the rest of the Xiph.Org Foundation. diff --git a/src/libogg/CHANGES b/src/libogg/CHANGES deleted file mode 100644 index 855b0b16..00000000 --- a/src/libogg/CHANGES +++ /dev/null @@ -1,104 +0,0 @@ -Version 1.3.4 (2019 August 30) - -* Faster slice-by-8 CRC32 implementation. - see https://lwn.net/Articles/453931/ for motivation. -* Add CMake build. -* Deprecate Visual Studio project files in favor of CMake. -* configure --disable-crc option for fuzzing. -* Various build fixes. -* Documentation and example code fixes. - -Version 1.3.3 (2017 November 7) - - * Fix an issue with corrupt continued packet handling. - * Update Windows projects and build settings. - * Remove Mac OS 9 build support. - -Version 1.3.2 (2014 May 27) - - * Fix an bug in oggpack_writecopy(). - -Version 1.3.1 (2013 May 12) - -* Guard against very large packets. -* Respect the configure --docdir override. -* Documentation fixes. -* More Windows build fixes. - -Version 1.3.0 (2011 August 4) - -* Add ogg_stream_flush_fill() call - This produces longer packets on flush, similar to - what ogg_stream_pageout_fill() does for single pages. -* Windows build fixes - -Version 1.2.2 (2010 December 07) - -* Build fix (types correction) for Mac OS X -* Update win32 project files to Visual Studio 2008 -* ogg_stream_pageout_fill documentation fix - -Version 1.2.1 (2010 November 01) - -* Various build updates (see SVN) -* Add ogg_stream_pageout_fill() to API to allow applications - greater explicit flexibility in page sizing. -* Documentation updates including multiplexing description, - terminology and API (incl. ogg_packet_clear(), - ogg_stream_pageout_fill()) -* Correct possible buffer overwrite in stream encoding on 32 bit - when a single packet exceed 250MB. -* Correct read-buffer overrun [without side effects] under - similar circumstances. -* Update unit testing to work properly with new page spill - heuristic. - -Version 1.2.0 (2010 March 25) - -* Alter default flushing behavior to span less often and use larger page - sizes when packet sizes are large. -* Build fixes for additional compilers -* Documentation updates - -Version 1.1.4 (2009 June 24) - -* New async error reporting mechanism. Calls made after a fatal error are - now safely handled in the event an error code is ignored -* Added allocation checks useful to some embedded applications -* fix possible read past end of buffer when reading 0 bits -* Updates to API documentation -* Build fixes - -Version 1.1.3 (2005 November 27) - - * Correct a bug in the granulepos field of pages where no packet ends - * New VS2003 and XCode builds, minor fixes to other builds - * documentation fixes and cleanup - -Version 1.1.2 (2004 September 23) - - * fix a bug with multipage packet assembly after seek - -Version 1.1.1 (2004 September 12) - - * various bugfixes - * important bugfix for 64-bit platforms - * various portability fixes - * autotools cleanup from Thomas Vander Stichele - * Symbian OS build support from Colin Ward at CSIRO - * new multiplexed Ogg stream documentation - -Version 1.1 (2003 November 17) - - * big-endian bitpacker routines for Theora - * various portability fixes - * improved API documentation - * RFC 3533 documentation of the format by Silvia Pfeiffer at CSIRO - * RFC 3534 documentation of the application/ogg mime-type by Linus Walleij - -Version 1.0 (2002 July 19) - - * First stable release - * little-endian bitpacker routines for Vorbis - * basic Ogg bitstream sync and coding support - diff --git a/src/libogg/COPYING b/src/libogg/COPYING deleted file mode 100644 index 6111c6c5..00000000 --- a/src/libogg/COPYING +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2002, Xiph.org Foundation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -- Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -- Neither the name of the Xiph.org Foundation nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/libogg/README.esp8266.md b/src/libogg/README.esp8266.md deleted file mode 100644 index f63d68f5..00000000 --- a/src/libogg/README.esp8266.md +++ /dev/null @@ -1,3 +0,0 @@ -This is libogg from Xiph, modified to build under Arduino by . - -OGG license/etc. unchanged. diff --git a/src/libogg/README.md b/src/libogg/README.md deleted file mode 100644 index 63545e28..00000000 --- a/src/libogg/README.md +++ /dev/null @@ -1,133 +0,0 @@ -# Ogg - -[![Travis Build Status](https://travis-ci.org/xiph/ogg.svg?branch=master)](https://travis-ci.org/xiph/ogg) -[![Jenkins Build Status](https://mf4.xiph.org/jenkins/job/libogg/badge/icon)](https://mf4.xiph.org/jenkins/job/libogg/) -[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/xiph/ogg?branch=master&svg=true)](https://ci.appveyor.com/project/rillian/ogg) - -Ogg project codecs use the Ogg bitstream format to arrange the raw, -compressed bitstream into a more robust, useful form. For example, -the Ogg bitstream makes seeking, time stamping and error recovery -possible, as well as mixing several sepearate, concurrent media -streams into a single physical bitstream. - -## What's here ## -This source distribution includes libogg and nothing else. Other modules -(eg, the modules libvorbis, vorbis-tools for the Vorbis music codec, -libtheora for the Theora video codec) contain the codec libraries for -use with Ogg bitstreams. - -Directory: - -- `src` The source for libogg, a BSD-license inplementation of the public domain Ogg bitstream format - -- `include` Library API headers - -- `doc` Ogg specification and libogg API documents - -- `win32` Win32 projects and build automation - -- `macosx` Mac OS X project and build files - -## Contact ## - -The Ogg homepage is located at https://www.xiph.org/ogg/ . -Up to date technical documents, contact information, source code and -pre-built utilities may be found there. - -## Building ## - -#### Building from tarball distributions #### - - ./configure - make - -and optionally (as root): - - make install - -This will install the Ogg libraries (static and shared) into -/usr/local/lib, includes into /usr/local/include and API -documentation into /usr/local/share/doc. - -#### Building from repository source #### - -A standard svn build should consist of nothing more than: - - ./autogen.sh - ./configure - make - -and as root if desired : - - make install - -#### Building on Windows #### - -Use the project file in the win32 directory. It should compile out of the box. - -#### Cross-compiling from Linux to Windows #### - -It is also possible to cross compile from Linux to windows using the MinGW -cross tools and even to run the test suite under Wine, the Linux/*nix -windows emulator. - -On Debian and Ubuntu systems, these cross compiler tools can be installed -by doing: - - sudo apt-get mingw32 mingw32-binutils mingw32-runtime wine - -Once these tools are installed its possible to compile and test by -executing the following commands, or something similar depending on -your system: - - ./configure --host=i586-mingw32msvc --target=i586-mingw32msvc --build=i586-linux - make - make check - -(Build instructions for Ogg codecs such as vorbis are similar and may -be found in those source modules' README files) - -## Building with CMake ## - -Ogg supports building using [CMake](http://www.cmake.org/). CMake is a meta build system that generates native projects for each platform. -To generate projects just run cmake replacing `YOUR-PROJECT-GENERATOR` with a proper generator from a list [here](http://www.cmake.org/cmake/help/v3.2/manual/cmake-generators.7.html): - - mkdir build - cd build - cmake -G YOUR-PROJECT-GENERATOR .. - -Note that by default cmake generates projects that will build static libraries. -To generate projects that will build dynamic library use `BUILD_SHARED_LIBS` option like this: - - cmake -G YOUR-PROJECT-GENERATOR -DBUILD_SHARED_LIBS=1 .. - -After projects are generated use them as usual - -#### Building on Windows #### - -Use proper generator for your Visual Studio version like: - - cmake -G "Visual Studio 12 2013" .. - -#### Building on Mac OS X #### - -Use Xcode generator. To build framework run: - - cmake -G Xcode -DBUILD_FRAMEWORK=1 .. - -#### Building on Linux #### - -Use Makefile generator which is default one. - - cmake .. - make - -## License ## - -THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. -USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS -GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE -IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. - -THE OggVorbis SOURCE CODE IS COPYRIGHT (C) 1994-2019 -by the Xiph.Org Foundation https://www.xiph.org/ diff --git a/src/libogg/bitwise.c b/src/libogg/bitwise.c deleted file mode 100644 index f977d5a0..00000000 --- a/src/libogg/bitwise.c +++ /dev/null @@ -1,1087 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2014 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: packing variable sized words into an octet stream - - ********************************************************************/ - -/* We're 'LSb' endian; if we write a word but read individual bits, - then we'll read the lsb first */ - -#include -#include -#include -#include "ogg/ogg.h" - -#define BUFFER_INCREMENT 256 - -static const unsigned long mask[]= -{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f, - 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff, - 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff, - 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff, - 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff, - 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff, - 0x3fffffff,0x7fffffff,0xffffffff }; - -static const unsigned int mask8B[]= -{0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; - -void oggpack_writeinit(oggpack_buffer *b){ - memset(b,0,sizeof(*b)); - b->ptr=b->buffer=_ogg_malloc(BUFFER_INCREMENT); - b->buffer[0]='\0'; - b->storage=BUFFER_INCREMENT; -} - -void oggpackB_writeinit(oggpack_buffer *b){ - oggpack_writeinit(b); -} - -int oggpack_writecheck(oggpack_buffer *b){ - if(!b->ptr || !b->storage)return -1; - return 0; -} - -int oggpackB_writecheck(oggpack_buffer *b){ - return oggpack_writecheck(b); -} - -void oggpack_writetrunc(oggpack_buffer *b,long bits){ - long bytes=bits>>3; - if(b->ptr){ - bits-=bytes*8; - b->ptr=b->buffer+bytes; - b->endbit=bits; - b->endbyte=bytes; - *b->ptr&=mask[bits]; - } -} - -void oggpackB_writetrunc(oggpack_buffer *b,long bits){ - long bytes=bits>>3; - if(b->ptr){ - bits-=bytes*8; - b->ptr=b->buffer+bytes; - b->endbit=bits; - b->endbyte=bytes; - *b->ptr&=mask8B[bits]; - } -} - -/* Takes only up to 32 bits. */ -void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){ - if(bits<0 || bits>32) goto err; - if(b->endbyte>=b->storage-4){ - void *ret; - if(!b->ptr)return; - if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err; - ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); - if(!ret) goto err; - b->buffer=ret; - b->storage+=BUFFER_INCREMENT; - b->ptr=b->buffer+b->endbyte; - } - - value&=mask[bits]; - bits+=b->endbit; - - b->ptr[0]|=value<endbit; - - if(bits>=8){ - b->ptr[1]=(unsigned char)(value>>(8-b->endbit)); - if(bits>=16){ - b->ptr[2]=(unsigned char)(value>>(16-b->endbit)); - if(bits>=24){ - b->ptr[3]=(unsigned char)(value>>(24-b->endbit)); - if(bits>=32){ - if(b->endbit) - b->ptr[4]=(unsigned char)(value>>(32-b->endbit)); - else - b->ptr[4]=0; - } - } - } - } - - b->endbyte+=bits/8; - b->ptr+=bits/8; - b->endbit=bits&7; - return; - err: - oggpack_writeclear(b); -} - -/* Takes only up to 32 bits. */ -void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){ - if(bits<0 || bits>32) goto err; - if(b->endbyte>=b->storage-4){ - void *ret; - if(!b->ptr)return; - if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err; - ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); - if(!ret) goto err; - b->buffer=ret; - b->storage+=BUFFER_INCREMENT; - b->ptr=b->buffer+b->endbyte; - } - - value=(value&mask[bits])<<(32-bits); - bits+=b->endbit; - - b->ptr[0]|=value>>(24+b->endbit); - - if(bits>=8){ - b->ptr[1]=(unsigned char)(value>>(16+b->endbit)); - if(bits>=16){ - b->ptr[2]=(unsigned char)(value>>(8+b->endbit)); - if(bits>=24){ - b->ptr[3]=(unsigned char)(value>>(b->endbit)); - if(bits>=32){ - if(b->endbit) - b->ptr[4]=(unsigned char)(value<<(8-b->endbit)); - else - b->ptr[4]=0; - } - } - } - } - - b->endbyte+=bits/8; - b->ptr+=bits/8; - b->endbit=bits&7; - return; - err: - oggpack_writeclear(b); -} - -void oggpack_writealign(oggpack_buffer *b){ - int bits=8-b->endbit; - if(bits<8) - oggpack_write(b,0,bits); -} - -void oggpackB_writealign(oggpack_buffer *b){ - int bits=8-b->endbit; - if(bits<8) - oggpackB_write(b,0,bits); -} - -static void oggpack_writecopy_helper(oggpack_buffer *b, - void *source, - long bits, - void (*w)(oggpack_buffer *, - unsigned long, - int), - int msb){ - unsigned char *ptr=(unsigned char *)source; - - long bytes=bits/8; - long pbytes=(b->endbit+bits)/8; - bits-=bytes*8; - - /* expand storage up-front */ - if(b->endbyte+pbytes>=b->storage){ - void *ret; - if(!b->ptr) goto err; - if(b->storage>b->endbyte+pbytes+BUFFER_INCREMENT) goto err; - b->storage=b->endbyte+pbytes+BUFFER_INCREMENT; - ret=_ogg_realloc(b->buffer,b->storage); - if(!ret) goto err; - b->buffer=ret; - b->ptr=b->buffer+b->endbyte; - } - - /* copy whole octets */ - if(b->endbit){ - int i; - /* unaligned copy. Do it the hard way. */ - for(i=0;iptr,source,bytes); - b->ptr+=bytes; - b->endbyte+=bytes; - *b->ptr=0; - } - - /* copy trailing bits */ - if(bits){ - if(msb) - w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits); - else - w(b,(unsigned long)(ptr[bytes]),bits); - } - return; - err: - oggpack_writeclear(b); -} - -void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){ - oggpack_writecopy_helper(b,source,bits,oggpack_write,0); -} - -void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){ - oggpack_writecopy_helper(b,source,bits,oggpackB_write,1); -} - -void oggpack_reset(oggpack_buffer *b){ - if(!b->ptr)return; - b->ptr=b->buffer; - b->buffer[0]=0; - b->endbit=b->endbyte=0; -} - -void oggpackB_reset(oggpack_buffer *b){ - oggpack_reset(b); -} - -void oggpack_writeclear(oggpack_buffer *b){ - if(b->buffer)_ogg_free(b->buffer); - memset(b,0,sizeof(*b)); -} - -void oggpackB_writeclear(oggpack_buffer *b){ - oggpack_writeclear(b); -} - -void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ - memset(b,0,sizeof(*b)); - b->buffer=b->ptr=buf; - b->storage=bytes; -} - -void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ - oggpack_readinit(b,buf,bytes); -} - -/* Read in bits without advancing the bitptr; bits <= 32 */ -long oggpack_look(oggpack_buffer *b,int bits){ - unsigned long ret; - unsigned long m; - - if(bits<0 || bits>32) return -1; - m=mask[bits]; - bits+=b->endbit; - - if(b->endbyte >= b->storage-4){ - /* not the main path */ - if(b->endbyte > b->storage-((bits+7)>>3)) return -1; - /* special case to avoid reading b->ptr[0], which might be past the end of - the buffer; also skips some useless accounting */ - else if(!bits)return(0L); - } - - ret=b->ptr[0]>>b->endbit; - if(bits>8){ - ret|=b->ptr[1]<<(8-b->endbit); - if(bits>16){ - ret|=b->ptr[2]<<(16-b->endbit); - if(bits>24){ - ret|=b->ptr[3]<<(24-b->endbit); - if(bits>32 && b->endbit) - ret|=b->ptr[4]<<(32-b->endbit); - } - } - } - return(m&ret); -} - -/* Read in bits without advancing the bitptr; bits <= 32 */ -long oggpackB_look(oggpack_buffer *b,int bits){ - unsigned long ret; - int m=32-bits; - - if(m<0 || m>32) return -1; - bits+=b->endbit; - - if(b->endbyte >= b->storage-4){ - /* not the main path */ - if(b->endbyte > b->storage-((bits+7)>>3)) return -1; - /* special case to avoid reading b->ptr[0], which might be past the end of - the buffer; also skips some useless accounting */ - else if(!bits)return(0L); - } - - ret=b->ptr[0]<<(24+b->endbit); - if(bits>8){ - ret|=b->ptr[1]<<(16+b->endbit); - if(bits>16){ - ret|=b->ptr[2]<<(8+b->endbit); - if(bits>24){ - ret|=b->ptr[3]<<(b->endbit); - if(bits>32 && b->endbit) - ret|=b->ptr[4]>>(8-b->endbit); - } - } - } - return ((ret&0xffffffff)>>(m>>1))>>((m+1)>>1); -} - -long oggpack_look1(oggpack_buffer *b){ - if(b->endbyte>=b->storage)return(-1); - return((b->ptr[0]>>b->endbit)&1); -} - -long oggpackB_look1(oggpack_buffer *b){ - if(b->endbyte>=b->storage)return(-1); - return((b->ptr[0]>>(7-b->endbit))&1); -} - -void oggpack_adv(oggpack_buffer *b,int bits){ - bits+=b->endbit; - - if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; - - b->ptr+=bits/8; - b->endbyte+=bits/8; - b->endbit=bits&7; - return; - - overflow: - b->ptr=NULL; - b->endbyte=b->storage; - b->endbit=1; -} - -void oggpackB_adv(oggpack_buffer *b,int bits){ - oggpack_adv(b,bits); -} - -void oggpack_adv1(oggpack_buffer *b){ - if(++(b->endbit)>7){ - b->endbit=0; - b->ptr++; - b->endbyte++; - } -} - -void oggpackB_adv1(oggpack_buffer *b){ - oggpack_adv1(b); -} - -/* bits <= 32 */ -long oggpack_read(oggpack_buffer *b,int bits){ - long ret; - unsigned long m; - - if(bits<0 || bits>32) goto err; - m=mask[bits]; - bits+=b->endbit; - - if(b->endbyte >= b->storage-4){ - /* not the main path */ - if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; - /* special case to avoid reading b->ptr[0], which might be past the end of - the buffer; also skips some useless accounting */ - else if(!bits)return(0L); - } - - ret=b->ptr[0]>>b->endbit; - if(bits>8){ - ret|=b->ptr[1]<<(8-b->endbit); - if(bits>16){ - ret|=b->ptr[2]<<(16-b->endbit); - if(bits>24){ - ret|=b->ptr[3]<<(24-b->endbit); - if(bits>32 && b->endbit){ - ret|=b->ptr[4]<<(32-b->endbit); - } - } - } - } - ret&=m; - b->ptr+=bits/8; - b->endbyte+=bits/8; - b->endbit=bits&7; - return ret; - - overflow: - err: - b->ptr=NULL; - b->endbyte=b->storage; - b->endbit=1; - return -1L; -} - -/* bits <= 32 */ -long oggpackB_read(oggpack_buffer *b,int bits){ - long ret; - long m=32-bits; - - if(m<0 || m>32) goto err; - bits+=b->endbit; - - if(b->endbyte+4>=b->storage){ - /* not the main path */ - if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; - /* special case to avoid reading b->ptr[0], which might be past the end of - the buffer; also skips some useless accounting */ - else if(!bits)return(0L); - } - - ret=b->ptr[0]<<(24+b->endbit); - if(bits>8){ - ret|=b->ptr[1]<<(16+b->endbit); - if(bits>16){ - ret|=b->ptr[2]<<(8+b->endbit); - if(bits>24){ - ret|=b->ptr[3]<<(b->endbit); - if(bits>32 && b->endbit) - ret|=b->ptr[4]>>(8-b->endbit); - } - } - } - ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1); - - b->ptr+=bits/8; - b->endbyte+=bits/8; - b->endbit=bits&7; - return ret; - - overflow: - err: - b->ptr=NULL; - b->endbyte=b->storage; - b->endbit=1; - return -1L; -} - -long oggpack_read1(oggpack_buffer *b){ - long ret; - - if(b->endbyte >= b->storage) goto overflow; - ret=(b->ptr[0]>>b->endbit)&1; - - b->endbit++; - if(b->endbit>7){ - b->endbit=0; - b->ptr++; - b->endbyte++; - } - return ret; - - overflow: - b->ptr=NULL; - b->endbyte=b->storage; - b->endbit=1; - return -1L; -} - -long oggpackB_read1(oggpack_buffer *b){ - long ret; - - if(b->endbyte >= b->storage) goto overflow; - ret=(b->ptr[0]>>(7-b->endbit))&1; - - b->endbit++; - if(b->endbit>7){ - b->endbit=0; - b->ptr++; - b->endbyte++; - } - return ret; - - overflow: - b->ptr=NULL; - b->endbyte=b->storage; - b->endbit=1; - return -1L; -} - -long oggpack_bytes(oggpack_buffer *b){ - return(b->endbyte+(b->endbit+7)/8); -} - -long oggpack_bits(oggpack_buffer *b){ - return(b->endbyte*8+b->endbit); -} - -long oggpackB_bytes(oggpack_buffer *b){ - return oggpack_bytes(b); -} - -long oggpackB_bits(oggpack_buffer *b){ - return oggpack_bits(b); -} - -unsigned char *oggpack_get_buffer(oggpack_buffer *b){ - return(b->buffer); -} - -unsigned char *oggpackB_get_buffer(oggpack_buffer *b){ - return oggpack_get_buffer(b); -} - -/* Self test of the bitwise routines; everything else is based on - them, so they damned well better be solid. */ - -#ifdef _V_SELFTEST -#include - -static int ilog(unsigned int v){ - int ret=0; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - -oggpack_buffer o; -oggpack_buffer r; - -void report(char *in){ - fprintf(stderr,"%s",in); - exit(1); -} - -void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){ - long bytes,i; - unsigned char *buffer; - - oggpack_reset(&o); - for(i=0;i header file. */ -#define HAVE_DLFCN_H 0 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 0 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 0 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 0 - -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -#define LT_OBJDIR ".libs/" - -/* Name of package */ -#define PACKAGE "libogg" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "ogg-dev@xiph.org" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "libogg" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "libogg 1.3.4" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "libogg" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "1.3.4" - -/* The size of `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* The size of `int16_t', as computed by sizeof. */ -#define SIZEOF_INT16_T 2 - -/* The size of `int32_t', as computed by sizeof. */ -#define SIZEOF_INT32_T 4 - -/* The size of `int64_t', as computed by sizeof. */ -#define SIZEOF_INT64_T 8 - -/* The size of `long', as computed by sizeof. */ -#define SIZEOF_LONG 4 - -/* The size of `long long', as computed by sizeof. */ -#define SIZEOF_LONG_LONG 8 - -/* The size of `short', as computed by sizeof. */ -#define SIZEOF_SHORT 2 - -/* The size of `uint16_t', as computed by sizeof. */ -#define SIZEOF_UINT16_T 2 - -/* The size of `uint32_t', as computed by sizeof. */ -#define SIZEOF_UINT32_T 4 - -/* The size of `uint64_t', as computed by sizeof. */ -#define SIZEOF_UINT64_T 8 - -/* The size of `u_int16_t', as computed by sizeof. */ -#define SIZEOF_U_INT16_T 2 - -/* The size of `u_int32_t', as computed by sizeof. */ -#define SIZEOF_U_INT32_T 4 - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "1.3.4" - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ diff --git a/src/libogg/crctable.h b/src/libogg/crctable.h deleted file mode 100644 index bf0ff4a3..00000000 --- a/src/libogg/crctable.h +++ /dev/null @@ -1,279 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2018 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ********************************************************************/ - -#include "ogg/os_types.h" -#include - -static const ogg_uint32_t crc_lookup[8][256] PROGMEM ={ -{0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005, - 0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd, - 0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75, - 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd, - 0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5, - 0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d, - 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95, - 0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d, - 0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072, - 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca, - 0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02, - 0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba, - 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692, - 0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a, - 0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2, - 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a, - 0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb, - 0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53, - 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b, - 0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623, - 0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b, - 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3, - 0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b, - 0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3, - 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c, - 0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,0x68860bfd,0x6c47164a,0x61043093,0x65c52d24, - 0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec, - 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654, - 0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c, - 0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4, - 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c, - 0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4}, - -{0x00000000,0xd219c1dc,0xa0f29e0f,0x72eb5fd3,0x452421a9,0x973de075,0xe5d6bfa6,0x37cf7e7a, - 0x8a484352,0x5851828e,0x2abadd5d,0xf8a31c81,0xcf6c62fb,0x1d75a327,0x6f9efcf4,0xbd873d28, - 0x10519b13,0xc2485acf,0xb0a3051c,0x62bac4c0,0x5575baba,0x876c7b66,0xf58724b5,0x279ee569, - 0x9a19d841,0x4800199d,0x3aeb464e,0xe8f28792,0xdf3df9e8,0x0d243834,0x7fcf67e7,0xadd6a63b, - 0x20a33626,0xf2baf7fa,0x8051a829,0x524869f5,0x6587178f,0xb79ed653,0xc5758980,0x176c485c, - 0xaaeb7574,0x78f2b4a8,0x0a19eb7b,0xd8002aa7,0xefcf54dd,0x3dd69501,0x4f3dcad2,0x9d240b0e, - 0x30f2ad35,0xe2eb6ce9,0x9000333a,0x4219f2e6,0x75d68c9c,0xa7cf4d40,0xd5241293,0x073dd34f, - 0xbabaee67,0x68a32fbb,0x1a487068,0xc851b1b4,0xff9ecfce,0x2d870e12,0x5f6c51c1,0x8d75901d, - 0x41466c4c,0x935fad90,0xe1b4f243,0x33ad339f,0x04624de5,0xd67b8c39,0xa490d3ea,0x76891236, - 0xcb0e2f1e,0x1917eec2,0x6bfcb111,0xb9e570cd,0x8e2a0eb7,0x5c33cf6b,0x2ed890b8,0xfcc15164, - 0x5117f75f,0x830e3683,0xf1e56950,0x23fca88c,0x1433d6f6,0xc62a172a,0xb4c148f9,0x66d88925, - 0xdb5fb40d,0x094675d1,0x7bad2a02,0xa9b4ebde,0x9e7b95a4,0x4c625478,0x3e890bab,0xec90ca77, - 0x61e55a6a,0xb3fc9bb6,0xc117c465,0x130e05b9,0x24c17bc3,0xf6d8ba1f,0x8433e5cc,0x562a2410, - 0xebad1938,0x39b4d8e4,0x4b5f8737,0x994646eb,0xae893891,0x7c90f94d,0x0e7ba69e,0xdc626742, - 0x71b4c179,0xa3ad00a5,0xd1465f76,0x035f9eaa,0x3490e0d0,0xe689210c,0x94627edf,0x467bbf03, - 0xfbfc822b,0x29e543f7,0x5b0e1c24,0x8917ddf8,0xbed8a382,0x6cc1625e,0x1e2a3d8d,0xcc33fc51, - 0x828cd898,0x50951944,0x227e4697,0xf067874b,0xc7a8f931,0x15b138ed,0x675a673e,0xb543a6e2, - 0x08c49bca,0xdadd5a16,0xa83605c5,0x7a2fc419,0x4de0ba63,0x9ff97bbf,0xed12246c,0x3f0be5b0, - 0x92dd438b,0x40c48257,0x322fdd84,0xe0361c58,0xd7f96222,0x05e0a3fe,0x770bfc2d,0xa5123df1, - 0x189500d9,0xca8cc105,0xb8679ed6,0x6a7e5f0a,0x5db12170,0x8fa8e0ac,0xfd43bf7f,0x2f5a7ea3, - 0xa22feebe,0x70362f62,0x02dd70b1,0xd0c4b16d,0xe70bcf17,0x35120ecb,0x47f95118,0x95e090c4, - 0x2867adec,0xfa7e6c30,0x889533e3,0x5a8cf23f,0x6d438c45,0xbf5a4d99,0xcdb1124a,0x1fa8d396, - 0xb27e75ad,0x6067b471,0x128ceba2,0xc0952a7e,0xf75a5404,0x254395d8,0x57a8ca0b,0x85b10bd7, - 0x383636ff,0xea2ff723,0x98c4a8f0,0x4add692c,0x7d121756,0xaf0bd68a,0xdde08959,0x0ff94885, - 0xc3cab4d4,0x11d37508,0x63382adb,0xb121eb07,0x86ee957d,0x54f754a1,0x261c0b72,0xf405caae, - 0x4982f786,0x9b9b365a,0xe9706989,0x3b69a855,0x0ca6d62f,0xdebf17f3,0xac544820,0x7e4d89fc, - 0xd39b2fc7,0x0182ee1b,0x7369b1c8,0xa1707014,0x96bf0e6e,0x44a6cfb2,0x364d9061,0xe45451bd, - 0x59d36c95,0x8bcaad49,0xf921f29a,0x2b383346,0x1cf74d3c,0xceee8ce0,0xbc05d333,0x6e1c12ef, - 0xe36982f2,0x3170432e,0x439b1cfd,0x9182dd21,0xa64da35b,0x74546287,0x06bf3d54,0xd4a6fc88, - 0x6921c1a0,0xbb38007c,0xc9d35faf,0x1bca9e73,0x2c05e009,0xfe1c21d5,0x8cf77e06,0x5eeebfda, - 0xf33819e1,0x2121d83d,0x53ca87ee,0x81d34632,0xb61c3848,0x6405f994,0x16eea647,0xc4f7679b, - 0x79705ab3,0xab699b6f,0xd982c4bc,0x0b9b0560,0x3c547b1a,0xee4dbac6,0x9ca6e515,0x4ebf24c9}, - -{0x00000000,0x01d8ac87,0x03b1590e,0x0269f589,0x0762b21c,0x06ba1e9b,0x04d3eb12,0x050b4795, - 0x0ec56438,0x0f1dc8bf,0x0d743d36,0x0cac91b1,0x09a7d624,0x087f7aa3,0x0a168f2a,0x0bce23ad, - 0x1d8ac870,0x1c5264f7,0x1e3b917e,0x1fe33df9,0x1ae87a6c,0x1b30d6eb,0x19592362,0x18818fe5, - 0x134fac48,0x129700cf,0x10fef546,0x112659c1,0x142d1e54,0x15f5b2d3,0x179c475a,0x1644ebdd, - 0x3b1590e0,0x3acd3c67,0x38a4c9ee,0x397c6569,0x3c7722fc,0x3daf8e7b,0x3fc67bf2,0x3e1ed775, - 0x35d0f4d8,0x3408585f,0x3661add6,0x37b90151,0x32b246c4,0x336aea43,0x31031fca,0x30dbb34d, - 0x269f5890,0x2747f417,0x252e019e,0x24f6ad19,0x21fdea8c,0x2025460b,0x224cb382,0x23941f05, - 0x285a3ca8,0x2982902f,0x2beb65a6,0x2a33c921,0x2f388eb4,0x2ee02233,0x2c89d7ba,0x2d517b3d, - 0x762b21c0,0x77f38d47,0x759a78ce,0x7442d449,0x714993dc,0x70913f5b,0x72f8cad2,0x73206655, - 0x78ee45f8,0x7936e97f,0x7b5f1cf6,0x7a87b071,0x7f8cf7e4,0x7e545b63,0x7c3daeea,0x7de5026d, - 0x6ba1e9b0,0x6a794537,0x6810b0be,0x69c81c39,0x6cc35bac,0x6d1bf72b,0x6f7202a2,0x6eaaae25, - 0x65648d88,0x64bc210f,0x66d5d486,0x670d7801,0x62063f94,0x63de9313,0x61b7669a,0x606fca1d, - 0x4d3eb120,0x4ce61da7,0x4e8fe82e,0x4f5744a9,0x4a5c033c,0x4b84afbb,0x49ed5a32,0x4835f6b5, - 0x43fbd518,0x4223799f,0x404a8c16,0x41922091,0x44996704,0x4541cb83,0x47283e0a,0x46f0928d, - 0x50b47950,0x516cd5d7,0x5305205e,0x52dd8cd9,0x57d6cb4c,0x560e67cb,0x54679242,0x55bf3ec5, - 0x5e711d68,0x5fa9b1ef,0x5dc04466,0x5c18e8e1,0x5913af74,0x58cb03f3,0x5aa2f67a,0x5b7a5afd, - 0xec564380,0xed8eef07,0xefe71a8e,0xee3fb609,0xeb34f19c,0xeaec5d1b,0xe885a892,0xe95d0415, - 0xe29327b8,0xe34b8b3f,0xe1227eb6,0xe0fad231,0xe5f195a4,0xe4293923,0xe640ccaa,0xe798602d, - 0xf1dc8bf0,0xf0042777,0xf26dd2fe,0xf3b57e79,0xf6be39ec,0xf766956b,0xf50f60e2,0xf4d7cc65, - 0xff19efc8,0xfec1434f,0xfca8b6c6,0xfd701a41,0xf87b5dd4,0xf9a3f153,0xfbca04da,0xfa12a85d, - 0xd743d360,0xd69b7fe7,0xd4f28a6e,0xd52a26e9,0xd021617c,0xd1f9cdfb,0xd3903872,0xd24894f5, - 0xd986b758,0xd85e1bdf,0xda37ee56,0xdbef42d1,0xdee40544,0xdf3ca9c3,0xdd555c4a,0xdc8df0cd, - 0xcac91b10,0xcb11b797,0xc978421e,0xc8a0ee99,0xcdaba90c,0xcc73058b,0xce1af002,0xcfc25c85, - 0xc40c7f28,0xc5d4d3af,0xc7bd2626,0xc6658aa1,0xc36ecd34,0xc2b661b3,0xc0df943a,0xc10738bd, - 0x9a7d6240,0x9ba5cec7,0x99cc3b4e,0x981497c9,0x9d1fd05c,0x9cc77cdb,0x9eae8952,0x9f7625d5, - 0x94b80678,0x9560aaff,0x97095f76,0x96d1f3f1,0x93dab464,0x920218e3,0x906bed6a,0x91b341ed, - 0x87f7aa30,0x862f06b7,0x8446f33e,0x859e5fb9,0x8095182c,0x814db4ab,0x83244122,0x82fceda5, - 0x8932ce08,0x88ea628f,0x8a839706,0x8b5b3b81,0x8e507c14,0x8f88d093,0x8de1251a,0x8c39899d, - 0xa168f2a0,0xa0b05e27,0xa2d9abae,0xa3010729,0xa60a40bc,0xa7d2ec3b,0xa5bb19b2,0xa463b535, - 0xafad9698,0xae753a1f,0xac1ccf96,0xadc46311,0xa8cf2484,0xa9178803,0xab7e7d8a,0xaaa6d10d, - 0xbce23ad0,0xbd3a9657,0xbf5363de,0xbe8bcf59,0xbb8088cc,0xba58244b,0xb831d1c2,0xb9e97d45, - 0xb2275ee8,0xb3fff26f,0xb19607e6,0xb04eab61,0xb545ecf4,0xb49d4073,0xb6f4b5fa,0xb72c197d}, - -{0x00000000,0xdc6d9ab7,0xbc1a28d9,0x6077b26e,0x7cf54c05,0xa098d6b2,0xc0ef64dc,0x1c82fe6b, - 0xf9ea980a,0x258702bd,0x45f0b0d3,0x999d2a64,0x851fd40f,0x59724eb8,0x3905fcd6,0xe5686661, - 0xf7142da3,0x2b79b714,0x4b0e057a,0x97639fcd,0x8be161a6,0x578cfb11,0x37fb497f,0xeb96d3c8, - 0x0efeb5a9,0xd2932f1e,0xb2e49d70,0x6e8907c7,0x720bf9ac,0xae66631b,0xce11d175,0x127c4bc2, - 0xeae946f1,0x3684dc46,0x56f36e28,0x8a9ef49f,0x961c0af4,0x4a719043,0x2a06222d,0xf66bb89a, - 0x1303defb,0xcf6e444c,0xaf19f622,0x73746c95,0x6ff692fe,0xb39b0849,0xd3ecba27,0x0f812090, - 0x1dfd6b52,0xc190f1e5,0xa1e7438b,0x7d8ad93c,0x61082757,0xbd65bde0,0xdd120f8e,0x017f9539, - 0xe417f358,0x387a69ef,0x580ddb81,0x84604136,0x98e2bf5d,0x448f25ea,0x24f89784,0xf8950d33, - 0xd1139055,0x0d7e0ae2,0x6d09b88c,0xb164223b,0xade6dc50,0x718b46e7,0x11fcf489,0xcd916e3e, - 0x28f9085f,0xf49492e8,0x94e32086,0x488eba31,0x540c445a,0x8861deed,0xe8166c83,0x347bf634, - 0x2607bdf6,0xfa6a2741,0x9a1d952f,0x46700f98,0x5af2f1f3,0x869f6b44,0xe6e8d92a,0x3a85439d, - 0xdfed25fc,0x0380bf4b,0x63f70d25,0xbf9a9792,0xa31869f9,0x7f75f34e,0x1f024120,0xc36fdb97, - 0x3bfad6a4,0xe7974c13,0x87e0fe7d,0x5b8d64ca,0x470f9aa1,0x9b620016,0xfb15b278,0x277828cf, - 0xc2104eae,0x1e7dd419,0x7e0a6677,0xa267fcc0,0xbee502ab,0x6288981c,0x02ff2a72,0xde92b0c5, - 0xcceefb07,0x108361b0,0x70f4d3de,0xac994969,0xb01bb702,0x6c762db5,0x0c019fdb,0xd06c056c, - 0x3504630d,0xe969f9ba,0x891e4bd4,0x5573d163,0x49f12f08,0x959cb5bf,0xf5eb07d1,0x29869d66, - 0xa6e63d1d,0x7a8ba7aa,0x1afc15c4,0xc6918f73,0xda137118,0x067eebaf,0x660959c1,0xba64c376, - 0x5f0ca517,0x83613fa0,0xe3168dce,0x3f7b1779,0x23f9e912,0xff9473a5,0x9fe3c1cb,0x438e5b7c, - 0x51f210be,0x8d9f8a09,0xede83867,0x3185a2d0,0x2d075cbb,0xf16ac60c,0x911d7462,0x4d70eed5, - 0xa81888b4,0x74751203,0x1402a06d,0xc86f3ada,0xd4edc4b1,0x08805e06,0x68f7ec68,0xb49a76df, - 0x4c0f7bec,0x9062e15b,0xf0155335,0x2c78c982,0x30fa37e9,0xec97ad5e,0x8ce01f30,0x508d8587, - 0xb5e5e3e6,0x69887951,0x09ffcb3f,0xd5925188,0xc910afe3,0x157d3554,0x750a873a,0xa9671d8d, - 0xbb1b564f,0x6776ccf8,0x07017e96,0xdb6ce421,0xc7ee1a4a,0x1b8380fd,0x7bf43293,0xa799a824, - 0x42f1ce45,0x9e9c54f2,0xfeebe69c,0x22867c2b,0x3e048240,0xe26918f7,0x821eaa99,0x5e73302e, - 0x77f5ad48,0xab9837ff,0xcbef8591,0x17821f26,0x0b00e14d,0xd76d7bfa,0xb71ac994,0x6b775323, - 0x8e1f3542,0x5272aff5,0x32051d9b,0xee68872c,0xf2ea7947,0x2e87e3f0,0x4ef0519e,0x929dcb29, - 0x80e180eb,0x5c8c1a5c,0x3cfba832,0xe0963285,0xfc14ccee,0x20795659,0x400ee437,0x9c637e80, - 0x790b18e1,0xa5668256,0xc5113038,0x197caa8f,0x05fe54e4,0xd993ce53,0xb9e47c3d,0x6589e68a, - 0x9d1cebb9,0x4171710e,0x2106c360,0xfd6b59d7,0xe1e9a7bc,0x3d843d0b,0x5df38f65,0x819e15d2, - 0x64f673b3,0xb89be904,0xd8ec5b6a,0x0481c1dd,0x18033fb6,0xc46ea501,0xa419176f,0x78748dd8, - 0x6a08c61a,0xb6655cad,0xd612eec3,0x0a7f7474,0x16fd8a1f,0xca9010a8,0xaae7a2c6,0x768a3871, - 0x93e25e10,0x4f8fc4a7,0x2ff876c9,0xf395ec7e,0xef171215,0x337a88a2,0x530d3acc,0x8f60a07b}, - -{0x00000000,0x490d678d,0x921acf1a,0xdb17a897,0x20f48383,0x69f9e40e,0xb2ee4c99,0xfbe32b14, - 0x41e90706,0x08e4608b,0xd3f3c81c,0x9afeaf91,0x611d8485,0x2810e308,0xf3074b9f,0xba0a2c12, - 0x83d20e0c,0xcadf6981,0x11c8c116,0x58c5a69b,0xa3268d8f,0xea2bea02,0x313c4295,0x78312518, - 0xc23b090a,0x8b366e87,0x5021c610,0x192ca19d,0xe2cf8a89,0xabc2ed04,0x70d54593,0x39d8221e, - 0x036501af,0x4a686622,0x917fceb5,0xd872a938,0x2391822c,0x6a9ce5a1,0xb18b4d36,0xf8862abb, - 0x428c06a9,0x0b816124,0xd096c9b3,0x999bae3e,0x6278852a,0x2b75e2a7,0xf0624a30,0xb96f2dbd, - 0x80b70fa3,0xc9ba682e,0x12adc0b9,0x5ba0a734,0xa0438c20,0xe94eebad,0x3259433a,0x7b5424b7, - 0xc15e08a5,0x88536f28,0x5344c7bf,0x1a49a032,0xe1aa8b26,0xa8a7ecab,0x73b0443c,0x3abd23b1, - 0x06ca035e,0x4fc764d3,0x94d0cc44,0xddddabc9,0x263e80dd,0x6f33e750,0xb4244fc7,0xfd29284a, - 0x47230458,0x0e2e63d5,0xd539cb42,0x9c34accf,0x67d787db,0x2edae056,0xf5cd48c1,0xbcc02f4c, - 0x85180d52,0xcc156adf,0x1702c248,0x5e0fa5c5,0xa5ec8ed1,0xece1e95c,0x37f641cb,0x7efb2646, - 0xc4f10a54,0x8dfc6dd9,0x56ebc54e,0x1fe6a2c3,0xe40589d7,0xad08ee5a,0x761f46cd,0x3f122140, - 0x05af02f1,0x4ca2657c,0x97b5cdeb,0xdeb8aa66,0x255b8172,0x6c56e6ff,0xb7414e68,0xfe4c29e5, - 0x444605f7,0x0d4b627a,0xd65ccaed,0x9f51ad60,0x64b28674,0x2dbfe1f9,0xf6a8496e,0xbfa52ee3, - 0x867d0cfd,0xcf706b70,0x1467c3e7,0x5d6aa46a,0xa6898f7e,0xef84e8f3,0x34934064,0x7d9e27e9, - 0xc7940bfb,0x8e996c76,0x558ec4e1,0x1c83a36c,0xe7608878,0xae6deff5,0x757a4762,0x3c7720ef, - 0x0d9406bc,0x44996131,0x9f8ec9a6,0xd683ae2b,0x2d60853f,0x646de2b2,0xbf7a4a25,0xf6772da8, - 0x4c7d01ba,0x05706637,0xde67cea0,0x976aa92d,0x6c898239,0x2584e5b4,0xfe934d23,0xb79e2aae, - 0x8e4608b0,0xc74b6f3d,0x1c5cc7aa,0x5551a027,0xaeb28b33,0xe7bfecbe,0x3ca84429,0x75a523a4, - 0xcfaf0fb6,0x86a2683b,0x5db5c0ac,0x14b8a721,0xef5b8c35,0xa656ebb8,0x7d41432f,0x344c24a2, - 0x0ef10713,0x47fc609e,0x9cebc809,0xd5e6af84,0x2e058490,0x6708e31d,0xbc1f4b8a,0xf5122c07, - 0x4f180015,0x06156798,0xdd02cf0f,0x940fa882,0x6fec8396,0x26e1e41b,0xfdf64c8c,0xb4fb2b01, - 0x8d23091f,0xc42e6e92,0x1f39c605,0x5634a188,0xadd78a9c,0xe4daed11,0x3fcd4586,0x76c0220b, - 0xccca0e19,0x85c76994,0x5ed0c103,0x17dda68e,0xec3e8d9a,0xa533ea17,0x7e244280,0x3729250d, - 0x0b5e05e2,0x4253626f,0x9944caf8,0xd049ad75,0x2baa8661,0x62a7e1ec,0xb9b0497b,0xf0bd2ef6, - 0x4ab702e4,0x03ba6569,0xd8adcdfe,0x91a0aa73,0x6a438167,0x234ee6ea,0xf8594e7d,0xb15429f0, - 0x888c0bee,0xc1816c63,0x1a96c4f4,0x539ba379,0xa878886d,0xe175efe0,0x3a624777,0x736f20fa, - 0xc9650ce8,0x80686b65,0x5b7fc3f2,0x1272a47f,0xe9918f6b,0xa09ce8e6,0x7b8b4071,0x328627fc, - 0x083b044d,0x413663c0,0x9a21cb57,0xd32cacda,0x28cf87ce,0x61c2e043,0xbad548d4,0xf3d82f59, - 0x49d2034b,0x00df64c6,0xdbc8cc51,0x92c5abdc,0x692680c8,0x202be745,0xfb3c4fd2,0xb231285f, - 0x8be90a41,0xc2e46dcc,0x19f3c55b,0x50fea2d6,0xab1d89c2,0xe210ee4f,0x390746d8,0x700a2155, - 0xca000d47,0x830d6aca,0x581ac25d,0x1117a5d0,0xeaf48ec4,0xa3f9e949,0x78ee41de,0x31e32653}, - -{0x00000000,0x1b280d78,0x36501af0,0x2d781788,0x6ca035e0,0x77883898,0x5af02f10,0x41d82268, - 0xd9406bc0,0xc26866b8,0xef107130,0xf4387c48,0xb5e05e20,0xaec85358,0x83b044d0,0x989849a8, - 0xb641ca37,0xad69c74f,0x8011d0c7,0x9b39ddbf,0xdae1ffd7,0xc1c9f2af,0xecb1e527,0xf799e85f, - 0x6f01a1f7,0x7429ac8f,0x5951bb07,0x4279b67f,0x03a19417,0x1889996f,0x35f18ee7,0x2ed9839f, - 0x684289d9,0x736a84a1,0x5e129329,0x453a9e51,0x04e2bc39,0x1fcab141,0x32b2a6c9,0x299aabb1, - 0xb102e219,0xaa2aef61,0x8752f8e9,0x9c7af591,0xdda2d7f9,0xc68ada81,0xebf2cd09,0xf0dac071, - 0xde0343ee,0xc52b4e96,0xe853591e,0xf37b5466,0xb2a3760e,0xa98b7b76,0x84f36cfe,0x9fdb6186, - 0x0743282e,0x1c6b2556,0x311332de,0x2a3b3fa6,0x6be31dce,0x70cb10b6,0x5db3073e,0x469b0a46, - 0xd08513b2,0xcbad1eca,0xe6d50942,0xfdfd043a,0xbc252652,0xa70d2b2a,0x8a753ca2,0x915d31da, - 0x09c57872,0x12ed750a,0x3f956282,0x24bd6ffa,0x65654d92,0x7e4d40ea,0x53355762,0x481d5a1a, - 0x66c4d985,0x7decd4fd,0x5094c375,0x4bbcce0d,0x0a64ec65,0x114ce11d,0x3c34f695,0x271cfbed, - 0xbf84b245,0xa4acbf3d,0x89d4a8b5,0x92fca5cd,0xd32487a5,0xc80c8add,0xe5749d55,0xfe5c902d, - 0xb8c79a6b,0xa3ef9713,0x8e97809b,0x95bf8de3,0xd467af8b,0xcf4fa2f3,0xe237b57b,0xf91fb803, - 0x6187f1ab,0x7aaffcd3,0x57d7eb5b,0x4cffe623,0x0d27c44b,0x160fc933,0x3b77debb,0x205fd3c3, - 0x0e86505c,0x15ae5d24,0x38d64aac,0x23fe47d4,0x622665bc,0x790e68c4,0x54767f4c,0x4f5e7234, - 0xd7c63b9c,0xccee36e4,0xe196216c,0xfabe2c14,0xbb660e7c,0xa04e0304,0x8d36148c,0x961e19f4, - 0xa5cb3ad3,0xbee337ab,0x939b2023,0x88b32d5b,0xc96b0f33,0xd243024b,0xff3b15c3,0xe41318bb, - 0x7c8b5113,0x67a35c6b,0x4adb4be3,0x51f3469b,0x102b64f3,0x0b03698b,0x267b7e03,0x3d53737b, - 0x138af0e4,0x08a2fd9c,0x25daea14,0x3ef2e76c,0x7f2ac504,0x6402c87c,0x497adff4,0x5252d28c, - 0xcaca9b24,0xd1e2965c,0xfc9a81d4,0xe7b28cac,0xa66aaec4,0xbd42a3bc,0x903ab434,0x8b12b94c, - 0xcd89b30a,0xd6a1be72,0xfbd9a9fa,0xe0f1a482,0xa12986ea,0xba018b92,0x97799c1a,0x8c519162, - 0x14c9d8ca,0x0fe1d5b2,0x2299c23a,0x39b1cf42,0x7869ed2a,0x6341e052,0x4e39f7da,0x5511faa2, - 0x7bc8793d,0x60e07445,0x4d9863cd,0x56b06eb5,0x17684cdd,0x0c4041a5,0x2138562d,0x3a105b55, - 0xa28812fd,0xb9a01f85,0x94d8080d,0x8ff00575,0xce28271d,0xd5002a65,0xf8783ded,0xe3503095, - 0x754e2961,0x6e662419,0x431e3391,0x58363ee9,0x19ee1c81,0x02c611f9,0x2fbe0671,0x34960b09, - 0xac0e42a1,0xb7264fd9,0x9a5e5851,0x81765529,0xc0ae7741,0xdb867a39,0xf6fe6db1,0xedd660c9, - 0xc30fe356,0xd827ee2e,0xf55ff9a6,0xee77f4de,0xafafd6b6,0xb487dbce,0x99ffcc46,0x82d7c13e, - 0x1a4f8896,0x016785ee,0x2c1f9266,0x37379f1e,0x76efbd76,0x6dc7b00e,0x40bfa786,0x5b97aafe, - 0x1d0ca0b8,0x0624adc0,0x2b5cba48,0x3074b730,0x71ac9558,0x6a849820,0x47fc8fa8,0x5cd482d0, - 0xc44ccb78,0xdf64c600,0xf21cd188,0xe934dcf0,0xa8ecfe98,0xb3c4f3e0,0x9ebce468,0x8594e910, - 0xab4d6a8f,0xb06567f7,0x9d1d707f,0x86357d07,0xc7ed5f6f,0xdcc55217,0xf1bd459f,0xea9548e7, - 0x720d014f,0x69250c37,0x445d1bbf,0x5f7516c7,0x1ead34af,0x058539d7,0x28fd2e5f,0x33d52327}, - -{0x00000000,0x4f576811,0x9eaed022,0xd1f9b833,0x399cbdf3,0x76cbd5e2,0xa7326dd1,0xe86505c0, - 0x73397be6,0x3c6e13f7,0xed97abc4,0xa2c0c3d5,0x4aa5c615,0x05f2ae04,0xd40b1637,0x9b5c7e26, - 0xe672f7cc,0xa9259fdd,0x78dc27ee,0x378b4fff,0xdfee4a3f,0x90b9222e,0x41409a1d,0x0e17f20c, - 0x954b8c2a,0xda1ce43b,0x0be55c08,0x44b23419,0xacd731d9,0xe38059c8,0x3279e1fb,0x7d2e89ea, - 0xc824f22f,0x87739a3e,0x568a220d,0x19dd4a1c,0xf1b84fdc,0xbeef27cd,0x6f169ffe,0x2041f7ef, - 0xbb1d89c9,0xf44ae1d8,0x25b359eb,0x6ae431fa,0x8281343a,0xcdd65c2b,0x1c2fe418,0x53788c09, - 0x2e5605e3,0x61016df2,0xb0f8d5c1,0xffafbdd0,0x17cab810,0x589dd001,0x89646832,0xc6330023, - 0x5d6f7e05,0x12381614,0xc3c1ae27,0x8c96c636,0x64f3c3f6,0x2ba4abe7,0xfa5d13d4,0xb50a7bc5, - 0x9488f9e9,0xdbdf91f8,0x0a2629cb,0x457141da,0xad14441a,0xe2432c0b,0x33ba9438,0x7cedfc29, - 0xe7b1820f,0xa8e6ea1e,0x791f522d,0x36483a3c,0xde2d3ffc,0x917a57ed,0x4083efde,0x0fd487cf, - 0x72fa0e25,0x3dad6634,0xec54de07,0xa303b616,0x4b66b3d6,0x0431dbc7,0xd5c863f4,0x9a9f0be5, - 0x01c375c3,0x4e941dd2,0x9f6da5e1,0xd03acdf0,0x385fc830,0x7708a021,0xa6f11812,0xe9a67003, - 0x5cac0bc6,0x13fb63d7,0xc202dbe4,0x8d55b3f5,0x6530b635,0x2a67de24,0xfb9e6617,0xb4c90e06, - 0x2f957020,0x60c21831,0xb13ba002,0xfe6cc813,0x1609cdd3,0x595ea5c2,0x88a71df1,0xc7f075e0, - 0xbadefc0a,0xf589941b,0x24702c28,0x6b274439,0x834241f9,0xcc1529e8,0x1dec91db,0x52bbf9ca, - 0xc9e787ec,0x86b0effd,0x574957ce,0x181e3fdf,0xf07b3a1f,0xbf2c520e,0x6ed5ea3d,0x2182822c, - 0x2dd0ee65,0x62878674,0xb37e3e47,0xfc295656,0x144c5396,0x5b1b3b87,0x8ae283b4,0xc5b5eba5, - 0x5ee99583,0x11befd92,0xc04745a1,0x8f102db0,0x67752870,0x28224061,0xf9dbf852,0xb68c9043, - 0xcba219a9,0x84f571b8,0x550cc98b,0x1a5ba19a,0xf23ea45a,0xbd69cc4b,0x6c907478,0x23c71c69, - 0xb89b624f,0xf7cc0a5e,0x2635b26d,0x6962da7c,0x8107dfbc,0xce50b7ad,0x1fa90f9e,0x50fe678f, - 0xe5f41c4a,0xaaa3745b,0x7b5acc68,0x340da479,0xdc68a1b9,0x933fc9a8,0x42c6719b,0x0d91198a, - 0x96cd67ac,0xd99a0fbd,0x0863b78e,0x4734df9f,0xaf51da5f,0xe006b24e,0x31ff0a7d,0x7ea8626c, - 0x0386eb86,0x4cd18397,0x9d283ba4,0xd27f53b5,0x3a1a5675,0x754d3e64,0xa4b48657,0xebe3ee46, - 0x70bf9060,0x3fe8f871,0xee114042,0xa1462853,0x49232d93,0x06744582,0xd78dfdb1,0x98da95a0, - 0xb958178c,0xf60f7f9d,0x27f6c7ae,0x68a1afbf,0x80c4aa7f,0xcf93c26e,0x1e6a7a5d,0x513d124c, - 0xca616c6a,0x8536047b,0x54cfbc48,0x1b98d459,0xf3fdd199,0xbcaab988,0x6d5301bb,0x220469aa, - 0x5f2ae040,0x107d8851,0xc1843062,0x8ed35873,0x66b65db3,0x29e135a2,0xf8188d91,0xb74fe580, - 0x2c139ba6,0x6344f3b7,0xb2bd4b84,0xfdea2395,0x158f2655,0x5ad84e44,0x8b21f677,0xc4769e66, - 0x717ce5a3,0x3e2b8db2,0xefd23581,0xa0855d90,0x48e05850,0x07b73041,0xd64e8872,0x9919e063, - 0x02459e45,0x4d12f654,0x9ceb4e67,0xd3bc2676,0x3bd923b6,0x748e4ba7,0xa577f394,0xea209b85, - 0x970e126f,0xd8597a7e,0x09a0c24d,0x46f7aa5c,0xae92af9c,0xe1c5c78d,0x303c7fbe,0x7f6b17af, - 0xe4376989,0xab600198,0x7a99b9ab,0x35ced1ba,0xddabd47a,0x92fcbc6b,0x43050458,0x0c526c49}, - -{0x00000000,0x5ba1dcca,0xb743b994,0xece2655e,0x6a466e9f,0x31e7b255,0xdd05d70b,0x86a40bc1, - 0xd48cdd3e,0x8f2d01f4,0x63cf64aa,0x386eb860,0xbecab3a1,0xe56b6f6b,0x09890a35,0x5228d6ff, - 0xadd8a7cb,0xf6797b01,0x1a9b1e5f,0x413ac295,0xc79ec954,0x9c3f159e,0x70dd70c0,0x2b7cac0a, - 0x79547af5,0x22f5a63f,0xce17c361,0x95b61fab,0x1312146a,0x48b3c8a0,0xa451adfe,0xfff07134, - 0x5f705221,0x04d18eeb,0xe833ebb5,0xb392377f,0x35363cbe,0x6e97e074,0x8275852a,0xd9d459e0, - 0x8bfc8f1f,0xd05d53d5,0x3cbf368b,0x671eea41,0xe1bae180,0xba1b3d4a,0x56f95814,0x0d5884de, - 0xf2a8f5ea,0xa9092920,0x45eb4c7e,0x1e4a90b4,0x98ee9b75,0xc34f47bf,0x2fad22e1,0x740cfe2b, - 0x262428d4,0x7d85f41e,0x91679140,0xcac64d8a,0x4c62464b,0x17c39a81,0xfb21ffdf,0xa0802315, - 0xbee0a442,0xe5417888,0x09a31dd6,0x5202c11c,0xd4a6cadd,0x8f071617,0x63e57349,0x3844af83, - 0x6a6c797c,0x31cda5b6,0xdd2fc0e8,0x868e1c22,0x002a17e3,0x5b8bcb29,0xb769ae77,0xecc872bd, - 0x13380389,0x4899df43,0xa47bba1d,0xffda66d7,0x797e6d16,0x22dfb1dc,0xce3dd482,0x959c0848, - 0xc7b4deb7,0x9c15027d,0x70f76723,0x2b56bbe9,0xadf2b028,0xf6536ce2,0x1ab109bc,0x4110d576, - 0xe190f663,0xba312aa9,0x56d34ff7,0x0d72933d,0x8bd698fc,0xd0774436,0x3c952168,0x6734fda2, - 0x351c2b5d,0x6ebdf797,0x825f92c9,0xd9fe4e03,0x5f5a45c2,0x04fb9908,0xe819fc56,0xb3b8209c, - 0x4c4851a8,0x17e98d62,0xfb0be83c,0xa0aa34f6,0x260e3f37,0x7dafe3fd,0x914d86a3,0xcaec5a69, - 0x98c48c96,0xc365505c,0x2f873502,0x7426e9c8,0xf282e209,0xa9233ec3,0x45c15b9d,0x1e608757, - 0x79005533,0x22a189f9,0xce43eca7,0x95e2306d,0x13463bac,0x48e7e766,0xa4058238,0xffa45ef2, - 0xad8c880d,0xf62d54c7,0x1acf3199,0x416eed53,0xc7cae692,0x9c6b3a58,0x70895f06,0x2b2883cc, - 0xd4d8f2f8,0x8f792e32,0x639b4b6c,0x383a97a6,0xbe9e9c67,0xe53f40ad,0x09dd25f3,0x527cf939, - 0x00542fc6,0x5bf5f30c,0xb7179652,0xecb64a98,0x6a124159,0x31b39d93,0xdd51f8cd,0x86f02407, - 0x26700712,0x7dd1dbd8,0x9133be86,0xca92624c,0x4c36698d,0x1797b547,0xfb75d019,0xa0d40cd3, - 0xf2fcda2c,0xa95d06e6,0x45bf63b8,0x1e1ebf72,0x98bab4b3,0xc31b6879,0x2ff90d27,0x7458d1ed, - 0x8ba8a0d9,0xd0097c13,0x3ceb194d,0x674ac587,0xe1eece46,0xba4f128c,0x56ad77d2,0x0d0cab18, - 0x5f247de7,0x0485a12d,0xe867c473,0xb3c618b9,0x35621378,0x6ec3cfb2,0x8221aaec,0xd9807626, - 0xc7e0f171,0x9c412dbb,0x70a348e5,0x2b02942f,0xada69fee,0xf6074324,0x1ae5267a,0x4144fab0, - 0x136c2c4f,0x48cdf085,0xa42f95db,0xff8e4911,0x792a42d0,0x228b9e1a,0xce69fb44,0x95c8278e, - 0x6a3856ba,0x31998a70,0xdd7bef2e,0x86da33e4,0x007e3825,0x5bdfe4ef,0xb73d81b1,0xec9c5d7b, - 0xbeb48b84,0xe515574e,0x09f73210,0x5256eeda,0xd4f2e51b,0x8f5339d1,0x63b15c8f,0x38108045, - 0x9890a350,0xc3317f9a,0x2fd31ac4,0x7472c60e,0xf2d6cdcf,0xa9771105,0x4595745b,0x1e34a891, - 0x4c1c7e6e,0x17bda2a4,0xfb5fc7fa,0xa0fe1b30,0x265a10f1,0x7dfbcc3b,0x9119a965,0xcab875af, - 0x3548049b,0x6ee9d851,0x820bbd0f,0xd9aa61c5,0x5f0e6a04,0x04afb6ce,0xe84dd390,0xb3ec0f5a, - 0xe1c4d9a5,0xba65056f,0x56876031,0x0d26bcfb,0x8b82b73a,0xd0236bf0,0x3cc10eae,0x6760d264}}; diff --git a/src/libogg/framing.c b/src/libogg/framing.c deleted file mode 100644 index 378698f5..00000000 --- a/src/libogg/framing.c +++ /dev/null @@ -1,2111 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2018 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: code raw packets into framed OggSquish stream and - decode Ogg streams back into raw packets - - note: The CRC code is directly derived from public domain code by - Ross Williams (ross@guest.adelaide.edu.au). See docs/framing.html - for details. - - ********************************************************************/ - -//#ifdef HAVE_CONFIG_H -#include "config.h" -//#endif - -#include -#include -#include -#include "ogg/ogg.h" - -#include - -/* A complete description of Ogg framing exists in docs/framing.html */ - -int ogg_page_version(const ogg_page *og){ - return((int)(og->header[4])); -} - -int ogg_page_continued(const ogg_page *og){ - return((int)(og->header[5]&0x01)); -} - -int ogg_page_bos(const ogg_page *og){ - return((int)(og->header[5]&0x02)); -} - -int ogg_page_eos(const ogg_page *og){ - return((int)(og->header[5]&0x04)); -} - -ogg_int64_t ogg_page_granulepos(const ogg_page *og){ - unsigned char *page=og->header; - ogg_uint64_t granulepos=page[13]&(0xff); - granulepos= (granulepos<<8)|(page[12]&0xff); - granulepos= (granulepos<<8)|(page[11]&0xff); - granulepos= (granulepos<<8)|(page[10]&0xff); - granulepos= (granulepos<<8)|(page[9]&0xff); - granulepos= (granulepos<<8)|(page[8]&0xff); - granulepos= (granulepos<<8)|(page[7]&0xff); - granulepos= (granulepos<<8)|(page[6]&0xff); - return((ogg_int64_t)granulepos); -} - -int ogg_page_serialno(const ogg_page *og){ - return((int)((ogg_uint32_t)og->header[14]) | - ((ogg_uint32_t)og->header[15]<<8) | - ((ogg_uint32_t)og->header[16]<<16) | - ((ogg_uint32_t)og->header[17]<<24)); -} - -long ogg_page_pageno(const ogg_page *og){ - return((long)((ogg_uint32_t)og->header[18]) | - ((ogg_uint32_t)og->header[19]<<8) | - ((ogg_uint32_t)og->header[20]<<16) | - ((ogg_uint32_t)og->header[21]<<24)); -} - - - -/* returns the number of packets that are completed on this page (if - the leading packet is begun on a previous page, but ends on this - page, it's counted */ - -/* NOTE: - If a page consists of a packet begun on a previous page, and a new - packet begun (but not completed) on this page, the return will be: - ogg_page_packets(page) ==1, - ogg_page_continued(page) !=0 - - If a page happens to be a single packet that was begun on a - previous page, and spans to the next page (in the case of a three or - more page packet), the return will be: - ogg_page_packets(page) ==0, - ogg_page_continued(page) !=0 -*/ - -int ogg_page_packets(const ogg_page *og){ - int i,n=og->header[26],count=0; - for(i=0;iheader[27+i]<255)count++; - return(count); -} - - -#if 0 -/* helper to initialize lookup for direct-table CRC (illustrative; we - use the static init in crctable.h) */ - -static void _ogg_crc_init(){ - int i, j; - ogg_uint32_t polynomial, crc; - polynomial = 0x04c11db7; /* The same as the ethernet generator - polynomial, although we use an - unreflected alg and an init/final - of 0, not 0xffffffff */ - for (i = 0; i <= 0xFF; i++){ - crc = i << 24; - - for (j = 0; j < 8; j++) - crc = (crc << 1) ^ (crc & (1 << 31) ? polynomial : 0); - - crc_lookup[0][i] = crc; - } - - for (i = 0; i <= 0xFF; i++) - for (j = 1; j < 8; j++) - crc_lookup[j][i] = crc_lookup[0][(crc_lookup[j - 1][i] >> 24) & 0xFF] ^ (crc_lookup[j - 1][i] << 8); -} -#endif - -#include "crctable.h" - -/* init the encode/decode logical stream state */ - -int ogg_stream_init(ogg_stream_state *os,int serialno){ - if(os){ - memset(os,0,sizeof(*os)); - os->body_storage=16*1024; - os->lacing_storage=1024; - - os->body_data=_ogg_malloc(os->body_storage*sizeof(*os->body_data)); - os->lacing_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->lacing_vals)); - os->granule_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->granule_vals)); - - if(!os->body_data || !os->lacing_vals || !os->granule_vals){ - ogg_stream_clear(os); - return -1; - } - - os->serialno=serialno; - - return(0); - } - return(-1); -} - -/* async/delayed error detection for the ogg_stream_state */ -int ogg_stream_check(ogg_stream_state *os){ - if(!os || !os->body_data) return -1; - return 0; -} - -/* _clear does not free os, only the non-flat storage within */ -int ogg_stream_clear(ogg_stream_state *os){ - if(os){ - if(os->body_data)_ogg_free(os->body_data); - if(os->lacing_vals)_ogg_free(os->lacing_vals); - if(os->granule_vals)_ogg_free(os->granule_vals); - - memset(os,0,sizeof(*os)); - } - return(0); -} - -int ogg_stream_destroy(ogg_stream_state *os){ - if(os){ - ogg_stream_clear(os); - _ogg_free(os); - } - return(0); -} - -/* Helpers for ogg_stream_encode; this keeps the structure and - what's happening fairly clear */ - -static int _os_body_expand(ogg_stream_state *os,long needed){ - if(os->body_storage-needed<=os->body_fill){ - long body_storage; - void *ret; - if(os->body_storage>LONG_MAX-needed){ - ogg_stream_clear(os); - return -1; - } - body_storage=os->body_storage+needed; - if(body_storagebody_data,body_storage*sizeof(*os->body_data)); - if(!ret){ - ogg_stream_clear(os); - return -1; - } - os->body_storage=body_storage; - os->body_data=ret; - } - return 0; -} - -static int _os_lacing_expand(ogg_stream_state *os,long needed){ - if(os->lacing_storage-needed<=os->lacing_fill){ - long lacing_storage; - void *ret; - if(os->lacing_storage>LONG_MAX-needed){ - ogg_stream_clear(os); - return -1; - } - lacing_storage=os->lacing_storage+needed; - if(lacing_storagelacing_vals,lacing_storage*sizeof(*os->lacing_vals)); - if(!ret){ - ogg_stream_clear(os); - return -1; - } - os->lacing_vals=ret; - ret=_ogg_realloc(os->granule_vals,lacing_storage* - sizeof(*os->granule_vals)); - if(!ret){ - ogg_stream_clear(os); - return -1; - } - os->granule_vals=ret; - os->lacing_storage=lacing_storage; - } - return 0; -} - -/* checksum the page */ -/* Direct table CRC; note that this will be faster in the future if we - perform the checksum simultaneously with other copies */ - -static ogg_uint32_t _os_update_crc(ogg_uint32_t crc, unsigned char *buffer, int size){ - while (size>=8){ - crc^=((ogg_uint32_t)buffer[0]<<24)|((ogg_uint32_t)buffer[1]<<16)|((ogg_uint32_t)buffer[2]<<8)|((ogg_uint32_t)buffer[3]); - - crc=crc_lookup[7][ crc>>24 ]^crc_lookup[6][(crc>>16)&0xFF]^ - crc_lookup[5][(crc>> 8)&0xFF]^crc_lookup[4][ crc &0xFF]^ - crc_lookup[3][buffer[4] ]^crc_lookup[2][buffer[5] ]^ - crc_lookup[1][buffer[6] ]^crc_lookup[0][buffer[7] ]; - - buffer+=8; - size-=8; - } - - while (size--) - crc=(crc<<8)^crc_lookup[0][((crc >> 24)&0xff)^*buffer++]; - return crc; -} - -void ogg_page_checksum_set(ogg_page *og){ - if(og){ - ogg_uint32_t crc_reg=0; - - /* safety; needed for API behavior, but not framing code */ - og->header[22]=0; - og->header[23]=0; - og->header[24]=0; - og->header[25]=0; - - crc_reg=_os_update_crc(crc_reg,og->header,og->header_len); - crc_reg=_os_update_crc(crc_reg,og->body,og->body_len); - - og->header[22]=(unsigned char)(crc_reg&0xff); - og->header[23]=(unsigned char)((crc_reg>>8)&0xff); - og->header[24]=(unsigned char)((crc_reg>>16)&0xff); - og->header[25]=(unsigned char)((crc_reg>>24)&0xff); - } -} - -/* submit data to the internal buffer of the framing engine */ -int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, int count, - long e_o_s, ogg_int64_t granulepos){ - - long bytes = 0, lacing_vals; - int i; - - if(ogg_stream_check(os)) return -1; - if(!iov) return 0; - - for (i = 0; i < count; ++i){ - if(iov[i].iov_len>LONG_MAX) return -1; - if(bytes>LONG_MAX-(long)iov[i].iov_len) return -1; - bytes += (long)iov[i].iov_len; - } - lacing_vals=bytes/255+1; - - if(os->body_returned){ - /* advance packet data according to the body_returned pointer. We - had to keep it around to return a pointer into the buffer last - call */ - - os->body_fill-=os->body_returned; - if(os->body_fill) - memmove(os->body_data,os->body_data+os->body_returned, - os->body_fill); - os->body_returned=0; - } - - /* make sure we have the buffer storage */ - if(_os_body_expand(os,bytes) || _os_lacing_expand(os,lacing_vals)) - return -1; - - /* Copy in the submitted packet. Yes, the copy is a waste; this is - the liability of overly clean abstraction for the time being. It - will actually be fairly easy to eliminate the extra copy in the - future */ - - for (i = 0; i < count; ++i) { - memcpy(os->body_data+os->body_fill, iov[i].iov_base, iov[i].iov_len); - os->body_fill += (int)iov[i].iov_len; - } - - /* Store lacing vals for this packet */ - for(i=0;ilacing_vals[os->lacing_fill+i]=255; - os->granule_vals[os->lacing_fill+i]=os->granulepos; - } - os->lacing_vals[os->lacing_fill+i]=bytes%255; - os->granulepos=os->granule_vals[os->lacing_fill+i]=granulepos; - - /* flag the first segment as the beginning of the packet */ - os->lacing_vals[os->lacing_fill]|= 0x100; - - os->lacing_fill+=lacing_vals; - - /* for the sake of completeness */ - os->packetno++; - - if(e_o_s)os->e_o_s=1; - - return(0); -} - -int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){ - ogg_iovec_t iov; - iov.iov_base = op->packet; - iov.iov_len = op->bytes; - return ogg_stream_iovecin(os, &iov, 1, op->e_o_s, op->granulepos); -} - -/* Conditionally flush a page; force==0 will only flush nominal-size - pages, force==1 forces us to flush a page regardless of page size - so long as there's any data available at all. */ -static int ogg_stream_flush_i(ogg_stream_state *os,ogg_page *og, int force, int nfill){ - int i; - int vals=0; - int maxvals=(os->lacing_fill>255?255:os->lacing_fill); - int bytes=0; - long acc=0; - ogg_int64_t granule_pos=-1; - - if(ogg_stream_check(os)) return(0); - if(maxvals==0) return(0); - - /* construct a page */ - /* decide how many segments to include */ - - /* If this is the initial header case, the first page must only include - the initial header packet */ - if(os->b_o_s==0){ /* 'initial header page' case */ - granule_pos=0; - for(vals=0;valslacing_vals[vals]&0x0ff)<255){ - vals++; - break; - } - } - }else{ - - /* The extra packets_done, packet_just_done logic here attempts to do two things: - 1) Don't unnecessarily span pages. - 2) Unless necessary, don't flush pages if there are less than four packets on - them; this expands page size to reduce unnecessary overhead if incoming packets - are large. - These are not necessary behaviors, just 'always better than naive flushing' - without requiring an application to explicitly request a specific optimized - behavior. We'll want an explicit behavior setup pathway eventually as well. */ - - int packets_done=0; - int packet_just_done=0; - for(vals=0;valsnfill && packet_just_done>=4){ - force=1; - break; - } - acc+=os->lacing_vals[vals]&0x0ff; - if((os->lacing_vals[vals]&0xff)<255){ - granule_pos=os->granule_vals[vals]; - packet_just_done=++packets_done; - }else - packet_just_done=0; - } - if(vals==255)force=1; - } - - if(!force) return(0); - - /* construct the header in temp storage */ - memcpy(os->header,"OggS",4); - - /* stream structure version */ - os->header[4]=0x00; - - /* continued packet flag? */ - os->header[5]=0x00; - if((os->lacing_vals[0]&0x100)==0)os->header[5]|=0x01; - /* first page flag? */ - if(os->b_o_s==0)os->header[5]|=0x02; - /* last page flag? */ - if(os->e_o_s && os->lacing_fill==vals)os->header[5]|=0x04; - os->b_o_s=1; - - /* 64 bits of PCM position */ - for(i=6;i<14;i++){ - os->header[i]=(unsigned char)(granule_pos&0xff); - granule_pos>>=8; - } - - /* 32 bits of stream serial number */ - { - long serialno=os->serialno; - for(i=14;i<18;i++){ - os->header[i]=(unsigned char)(serialno&0xff); - serialno>>=8; - } - } - - /* 32 bits of page counter (we have both counter and page header - because this val can roll over) */ - if(os->pageno==-1)os->pageno=0; /* because someone called - stream_reset; this would be a - strange thing to do in an - encode stream, but it has - plausible uses */ - { - long pageno=os->pageno++; - for(i=18;i<22;i++){ - os->header[i]=(unsigned char)(pageno&0xff); - pageno>>=8; - } - } - - /* zero for computation; filled in later */ - os->header[22]=0; - os->header[23]=0; - os->header[24]=0; - os->header[25]=0; - - /* segment table */ - os->header[26]=(unsigned char)(vals&0xff); - for(i=0;iheader[i+27]=(unsigned char)(os->lacing_vals[i]&0xff); - - /* set pointers in the ogg_page struct */ - og->header=os->header; - og->header_len=os->header_fill=vals+27; - og->body=os->body_data+os->body_returned; - og->body_len=bytes; - - /* advance the lacing data and set the body_returned pointer */ - - os->lacing_fill-=vals; - memmove(os->lacing_vals,os->lacing_vals+vals,os->lacing_fill*sizeof(*os->lacing_vals)); - memmove(os->granule_vals,os->granule_vals+vals,os->lacing_fill*sizeof(*os->granule_vals)); - os->body_returned+=bytes; - - /* calculate the checksum */ - - ogg_page_checksum_set(og); - - /* done */ - return(1); -} - -/* This will flush remaining packets into a page (returning nonzero), - even if there is not enough data to trigger a flush normally - (undersized page). If there are no packets or partial packets to - flush, ogg_stream_flush returns 0. Note that ogg_stream_flush will - try to flush a normal sized page like ogg_stream_pageout; a call to - ogg_stream_flush does not guarantee that all packets have flushed. - Only a return value of 0 from ogg_stream_flush indicates all packet - data is flushed into pages. - - since ogg_stream_flush will flush the last page in a stream even if - it's undersized, you almost certainly want to use ogg_stream_pageout - (and *not* ogg_stream_flush) unless you specifically need to flush - a page regardless of size in the middle of a stream. */ - -int ogg_stream_flush(ogg_stream_state *os,ogg_page *og){ - return ogg_stream_flush_i(os,og,1,4096); -} - -/* Like the above, but an argument is provided to adjust the nominal - page size for applications which are smart enough to provide their - own delay based flushing */ - -int ogg_stream_flush_fill(ogg_stream_state *os,ogg_page *og, int nfill){ - return ogg_stream_flush_i(os,og,1,nfill); -} - -/* This constructs pages from buffered packet segments. The pointers -returned are to static buffers; do not free. The returned buffers are -good only until the next call (using the same ogg_stream_state) */ - -int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){ - int force=0; - if(ogg_stream_check(os)) return 0; - - if((os->e_o_s&&os->lacing_fill) || /* 'were done, now flush' case */ - (os->lacing_fill&&!os->b_o_s)) /* 'initial header page' case */ - force=1; - - return(ogg_stream_flush_i(os,og,force,4096)); -} - -/* Like the above, but an argument is provided to adjust the nominal -page size for applications which are smart enough to provide their -own delay based flushing */ - -int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill){ - int force=0; - if(ogg_stream_check(os)) return 0; - - if((os->e_o_s&&os->lacing_fill) || /* 'were done, now flush' case */ - (os->lacing_fill&&!os->b_o_s)) /* 'initial header page' case */ - force=1; - - return(ogg_stream_flush_i(os,og,force,nfill)); -} - -int ogg_stream_eos(ogg_stream_state *os){ - if(ogg_stream_check(os)) return 1; - return os->e_o_s; -} - -/* DECODING PRIMITIVES: packet streaming layer **********************/ - -/* This has two layers to place more of the multi-serialno and paging - control in the application's hands. First, we expose a data buffer - using ogg_sync_buffer(). The app either copies into the - buffer, or passes it directly to read(), etc. We then call - ogg_sync_wrote() to tell how many bytes we just added. - - Pages are returned (pointers into the buffer in ogg_sync_state) - by ogg_sync_pageout(). The page is then submitted to - ogg_stream_pagein() along with the appropriate - ogg_stream_state* (ie, matching serialno). We then get raw - packets out calling ogg_stream_packetout() with a - ogg_stream_state. */ - -/* initialize the struct to a known state */ -int ogg_sync_init(ogg_sync_state *oy){ - if(oy){ - oy->storage = -1; /* used as a readiness flag */ - memset(oy,0,sizeof(*oy)); - } - return(0); -} - -/* clear non-flat storage within */ -int ogg_sync_clear(ogg_sync_state *oy){ - if(oy){ - if(oy->data)_ogg_free(oy->data); - memset(oy,0,sizeof(*oy)); - } - return(0); -} - -int ogg_sync_destroy(ogg_sync_state *oy){ - if(oy){ - ogg_sync_clear(oy); - _ogg_free(oy); - } - return(0); -} - -int ogg_sync_check(ogg_sync_state *oy){ - if(oy->storage<0) return -1; - return 0; -} - -char *ogg_sync_buffer(ogg_sync_state *oy, long size){ - if(ogg_sync_check(oy)) return NULL; - - /* first, clear out any space that has been previously returned */ - if(oy->returned){ - oy->fill-=oy->returned; - if(oy->fill>0) - memmove(oy->data,oy->data+oy->returned,oy->fill); - oy->returned=0; - } - - if(size>oy->storage-oy->fill){ - /* We need to extend the internal buffer */ - long newsize=size+oy->fill+4096; /* an extra page to be nice */ - void *ret; - - if(oy->data) - ret=_ogg_realloc(oy->data,newsize); - else - ret=_ogg_malloc(newsize); - if(!ret){ - ogg_sync_clear(oy); - return NULL; - } - oy->data=ret; - oy->storage=newsize; - } - - /* expose a segment at least as large as requested at the fill mark */ - return((char *)oy->data+oy->fill); -} - -int ogg_sync_wrote(ogg_sync_state *oy, long bytes){ - if(ogg_sync_check(oy))return -1; - if(oy->fill+bytes>oy->storage)return -1; - oy->fill+=bytes; - return(0); -} - -/* sync the stream. This is meant to be useful for finding page - boundaries. - - return values for this: - -n) skipped n bytes - 0) page not ready; more data (no bytes skipped) - n) page synced at current location; page length n bytes - -*/ - -long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){ - unsigned char *page=oy->data+oy->returned; - unsigned char *next; - long bytes=oy->fill-oy->returned; - - if(ogg_sync_check(oy))return 0; - - if(oy->headerbytes==0){ - int headerbytes,i; - if(bytes<27)return(0); /* not enough for a header */ - - /* verify capture pattern */ - if(memcmp(page,"OggS",4))goto sync_fail; - - headerbytes=page[26]+27; - if(bytesbodybytes+=page[27+i]; - oy->headerbytes=headerbytes; - } - - if(oy->bodybytes+oy->headerbytes>bytes)return(0); - - /* The whole test page is buffered. Verify the checksum */ - { - /* Grab the checksum bytes, set the header field to zero */ - char chksum[4]; - ogg_page log; - - memcpy(chksum,page+22,4); - memset(page+22,0,4); - - /* set up a temp page struct and recompute the checksum */ - log.header=page; - log.header_len=oy->headerbytes; - log.body=page+oy->headerbytes; - log.body_len=oy->bodybytes; - ogg_page_checksum_set(&log); - - /* Compare */ - if(memcmp(chksum,page+22,4)){ - /* D'oh. Mismatch! Corrupt page (or miscapture and not a page - at all) */ - /* replace the computed checksum with the one actually read in */ - memcpy(page+22,chksum,4); - -#ifndef DISABLE_CRC - /* Bad checksum. Lose sync */ - goto sync_fail; -#endif - } - } - - /* yes, have a whole page all ready to go */ - { - if(og){ - og->header=page; - og->header_len=oy->headerbytes; - og->body=page+oy->headerbytes; - og->body_len=oy->bodybytes; - } - - oy->unsynced=0; - oy->returned+=(bytes=oy->headerbytes+oy->bodybytes); - oy->headerbytes=0; - oy->bodybytes=0; - return(bytes); - } - - sync_fail: - - oy->headerbytes=0; - oy->bodybytes=0; - - /* search for possible capture */ - next=memchr(page+1,'O',bytes-1); - if(!next) - next=oy->data+oy->fill; - - oy->returned=(int)(next-oy->data); - return((long)-(next-page)); -} - -/* sync the stream and get a page. Keep trying until we find a page. - Suppress 'sync errors' after reporting the first. - - return values: - -1) recapture (hole in data) - 0) need more data - 1) page returned - - Returns pointers into buffered data; invalidated by next call to - _stream, _clear, _init, or _buffer */ - -int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){ - - if(ogg_sync_check(oy))return 0; - - /* all we need to do is verify a page at the head of the stream - buffer. If it doesn't verify, we look for the next potential - frame */ - - for(;;){ - long ret=ogg_sync_pageseek(oy,og); - if(ret>0){ - /* have a page */ - return(1); - } - if(ret==0){ - /* need more data */ - return(0); - } - - /* head did not start a synced page... skipped some bytes */ - if(!oy->unsynced){ - oy->unsynced=1; - return(-1); - } - - /* loop. keep looking */ - - } -} - -/* add the incoming page to the stream state; we decompose the page - into packet segments here as well. */ - -int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){ - unsigned char *header=og->header; - unsigned char *body=og->body; - long bodysize=og->body_len; - int segptr=0; - - int version=ogg_page_version(og); - int continued=ogg_page_continued(og); - int bos=ogg_page_bos(og); - int eos=ogg_page_eos(og); - ogg_int64_t granulepos=ogg_page_granulepos(og); - int serialno=ogg_page_serialno(og); - long pageno=ogg_page_pageno(og); - int segments=header[26]; - - if(ogg_stream_check(os)) return -1; - - /* clean up 'returned data' */ - { - long lr=os->lacing_returned; - long br=os->body_returned; - - /* body data */ - if(br){ - os->body_fill-=br; - if(os->body_fill) - memmove(os->body_data,os->body_data+br,os->body_fill); - os->body_returned=0; - } - - if(lr){ - /* segment table */ - if(os->lacing_fill-lr){ - memmove(os->lacing_vals,os->lacing_vals+lr, - (os->lacing_fill-lr)*sizeof(*os->lacing_vals)); - memmove(os->granule_vals,os->granule_vals+lr, - (os->lacing_fill-lr)*sizeof(*os->granule_vals)); - } - os->lacing_fill-=lr; - os->lacing_packet-=lr; - os->lacing_returned=0; - } - } - - /* check the serial number */ - if(serialno!=os->serialno)return(-1); - if(version>0)return(-1); - - if(_os_lacing_expand(os,segments+1)) return -1; - - /* are we in sequence? */ - if(pageno!=os->pageno){ - int i; - - /* unroll previous partial packet (if any) */ - for(i=os->lacing_packet;ilacing_fill;i++) - os->body_fill-=os->lacing_vals[i]&0xff; - os->lacing_fill=os->lacing_packet; - - /* make a note of dropped data in segment table */ - if(os->pageno!=-1){ - os->lacing_vals[os->lacing_fill++]=0x400; - os->lacing_packet++; - } - } - - /* are we a 'continued packet' page? If so, we may need to skip - some segments */ - if(continued){ - if(os->lacing_fill<1 || - (os->lacing_vals[os->lacing_fill-1]&0xff)<255 || - os->lacing_vals[os->lacing_fill-1]==0x400){ - bos=0; - for(;segptrbody_data+os->body_fill,body,bodysize); - os->body_fill+=bodysize; - } - - { - int saved=-1; - while(segptrlacing_vals[os->lacing_fill]=val; - os->granule_vals[os->lacing_fill]=-1; - - if(bos){ - os->lacing_vals[os->lacing_fill]|=0x100; - bos=0; - } - - if(val<255)saved=os->lacing_fill; - - os->lacing_fill++; - segptr++; - - if(val<255)os->lacing_packet=os->lacing_fill; - } - - /* set the granulepos on the last granuleval of the last full packet */ - if(saved!=-1){ - os->granule_vals[saved]=granulepos; - } - - } - - if(eos){ - os->e_o_s=1; - if(os->lacing_fill>0) - os->lacing_vals[os->lacing_fill-1]|=0x200; - } - - os->pageno=pageno+1; - - return(0); -} - -/* clear things to an initial state. Good to call, eg, before seeking */ -int ogg_sync_reset(ogg_sync_state *oy){ - if(ogg_sync_check(oy))return -1; - - oy->fill=0; - oy->returned=0; - oy->unsynced=0; - oy->headerbytes=0; - oy->bodybytes=0; - return(0); -} - -int ogg_stream_reset(ogg_stream_state *os){ - if(ogg_stream_check(os)) return -1; - - os->body_fill=0; - os->body_returned=0; - - os->lacing_fill=0; - os->lacing_packet=0; - os->lacing_returned=0; - - os->header_fill=0; - - os->e_o_s=0; - os->b_o_s=0; - os->pageno=-1; - os->packetno=0; - os->granulepos=0; - - return(0); -} - -int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno){ - if(ogg_stream_check(os)) return -1; - ogg_stream_reset(os); - os->serialno=serialno; - return(0); -} - -static int _packetout(ogg_stream_state *os,ogg_packet *op,int adv){ - - /* The last part of decode. We have the stream broken into packet - segments. Now we need to group them into packets (or return the - out of sync markers) */ - - int ptr=os->lacing_returned; - - if(os->lacing_packet<=ptr)return(0); - - if(os->lacing_vals[ptr]&0x400){ - /* we need to tell the codec there's a gap; it might need to - handle previous packet dependencies. */ - os->lacing_returned++; - os->packetno++; - return(-1); - } - - if(!op && !adv)return(1); /* just using peek as an inexpensive way - to ask if there's a whole packet - waiting */ - - /* Gather the whole packet. We'll have no holes or a partial packet */ - { - int size=os->lacing_vals[ptr]&0xff; - long bytes=size; - int eos=os->lacing_vals[ptr]&0x200; /* last packet of the stream? */ - int bos=os->lacing_vals[ptr]&0x100; /* first packet of the stream? */ - - while(size==255){ - int val=os->lacing_vals[++ptr]; - size=val&0xff; - if(val&0x200)eos=0x200; - bytes+=size; - } - - if(op){ - op->e_o_s=eos; - op->b_o_s=bos; - op->packet=os->body_data+os->body_returned; - op->packetno=os->packetno; - op->granulepos=os->granule_vals[ptr]; - op->bytes=bytes; - } - - if(adv){ - os->body_returned+=bytes; - os->lacing_returned=ptr+1; - os->packetno++; - } - } - return(1); -} - -int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op){ - if(ogg_stream_check(os)) return 0; - return _packetout(os,op,1); -} - -int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op){ - if(ogg_stream_check(os)) return 0; - return _packetout(os,op,0); -} - -void ogg_packet_clear(ogg_packet *op) { - _ogg_free(op->packet); - memset(op, 0, sizeof(*op)); -} - -#ifdef _V_SELFTEST -#include - -ogg_stream_state os_en, os_de; -ogg_sync_state oy; - -void checkpacket(ogg_packet *op,long len, int no, long pos){ - long j; - static int sequence=0; - static int lastno=0; - - if(op->bytes!=len){ - fprintf(stderr,"incorrect packet length (%ld != %ld)!\n",op->bytes,len); - exit(1); - } - if(op->granulepos!=pos){ - fprintf(stderr,"incorrect packet granpos (%ld != %ld)!\n",(long)op->granulepos,pos); - exit(1); - } - - /* packet number just follows sequence/gap; adjust the input number - for that */ - if(no==0){ - sequence=0; - }else{ - sequence++; - if(no>lastno+1) - sequence++; - } - lastno=no; - if(op->packetno!=sequence){ - fprintf(stderr,"incorrect packet sequence %ld != %d\n", - (long)(op->packetno),sequence); - exit(1); - } - - /* Test data */ - for(j=0;jbytes;j++) - if(op->packet[j]!=((j+no)&0xff)){ - fprintf(stderr,"body data mismatch (1) at pos %ld: %x!=%lx!\n\n", - j,op->packet[j],(j+no)&0xff); - exit(1); - } -} - -void check_page(unsigned char *data,const int *header,ogg_page *og){ - long j; - /* Test data */ - for(j=0;jbody_len;j++) - if(og->body[j]!=data[j]){ - fprintf(stderr,"body data mismatch (2) at pos %ld: %x!=%x!\n\n", - j,data[j],og->body[j]); - exit(1); - } - - /* Test header */ - for(j=0;jheader_len;j++){ - if(og->header[j]!=header[j]){ - fprintf(stderr,"header content mismatch at pos %ld:\n",j); - for(j=0;jheader[j]); - fprintf(stderr,"\n"); - exit(1); - } - } - if(og->header_len!=header[26]+27){ - fprintf(stderr,"header length incorrect! (%ld!=%d)\n", - og->header_len,header[26]+27); - exit(1); - } -} - -void print_header(ogg_page *og){ - int j; - fprintf(stderr,"\nHEADER:\n"); - fprintf(stderr," capture: %c %c %c %c version: %d flags: %x\n", - og->header[0],og->header[1],og->header[2],og->header[3], - (int)og->header[4],(int)og->header[5]); - - fprintf(stderr," granulepos: %d serialno: %d pageno: %ld\n", - (og->header[9]<<24)|(og->header[8]<<16)| - (og->header[7]<<8)|og->header[6], - (og->header[17]<<24)|(og->header[16]<<16)| - (og->header[15]<<8)|og->header[14], - ((long)(og->header[21])<<24)|(og->header[20]<<16)| - (og->header[19]<<8)|og->header[18]); - - fprintf(stderr," checksum: %02x:%02x:%02x:%02x\n segments: %d (", - (int)og->header[22],(int)og->header[23], - (int)og->header[24],(int)og->header[25], - (int)og->header[26]); - - for(j=27;jheader_len;j++) - fprintf(stderr,"%d ",(int)og->header[j]); - fprintf(stderr,")\n\n"); -} - -void copy_page(ogg_page *og){ - unsigned char *temp=_ogg_malloc(og->header_len); - memcpy(temp,og->header,og->header_len); - og->header=temp; - - temp=_ogg_malloc(og->body_len); - memcpy(temp,og->body,og->body_len); - og->body=temp; -} - -void free_page(ogg_page *og){ - _ogg_free (og->header); - _ogg_free (og->body); -} - -void error(void){ - fprintf(stderr,"error!\n"); - exit(1); -} - -/* 17 only */ -const int head1_0[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x06, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0,0,0,0, - 0x15,0xed,0xec,0x91, - 1, - 17}; - -/* 17, 254, 255, 256, 500, 510, 600 byte, pad */ -const int head1_1[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x02, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0,0,0,0, - 0x59,0x10,0x6c,0x2c, - 1, - 17}; -const int head2_1[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x04, - 0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,1,0,0,0, - 0x89,0x33,0x85,0xce, - 13, - 254,255,0,255,1,255,245,255,255,0, - 255,255,90}; - -/* nil packets; beginning,middle,end */ -const int head1_2[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x02, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0,0,0,0, - 0xff,0x7b,0x23,0x17, - 1, - 0}; -const int head2_2[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x04, - 0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,1,0,0,0, - 0x5c,0x3f,0x66,0xcb, - 17, - 17,254,255,0,0,255,1,0,255,245,255,255,0, - 255,255,90,0}; - -/* large initial packet */ -const int head1_3[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x02, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0,0,0,0, - 0x01,0x27,0x31,0xaa, - 18, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,10}; - -const int head2_3[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x04, - 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,1,0,0,0, - 0x7f,0x4e,0x8a,0xd2, - 4, - 255,4,255,0}; - - -/* continuing packet test */ -const int head1_4[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x02, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0,0,0,0, - 0xff,0x7b,0x23,0x17, - 1, - 0}; - -const int head2_4[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x00, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0x01,0x02,0x03,0x04,1,0,0,0, - 0xf8,0x3c,0x19,0x79, - 255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255}; - -const int head3_4[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x05, - 0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,2,0,0,0, - 0x38,0xe6,0xb6,0x28, - 6, - 255,220,255,4,255,0}; - - -/* spill expansion test */ -const int head1_4b[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x02, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0,0,0,0, - 0xff,0x7b,0x23,0x17, - 1, - 0}; - -const int head2_4b[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x00, - 0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,1,0,0,0, - 0xce,0x8f,0x17,0x1a, - 23, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,10,255,4,255,0,0}; - - -const int head3_4b[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x04, - 0x07,0x14,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,2,0,0,0, - 0x9b,0xb2,0x50,0xa1, - 1, - 0}; - -/* page with the 255 segment limit */ -const int head1_5[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x02, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0,0,0,0, - 0xff,0x7b,0x23,0x17, - 1, - 0}; - -const int head2_5[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x00, - 0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,1,0,0,0, - 0xed,0x2a,0x2e,0xa7, - 255, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10}; - -const int head3_5[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x04, - 0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,2,0,0,0, - 0x6c,0x3b,0x82,0x3d, - 1, - 50}; - - -/* packet that overspans over an entire page */ -const int head1_6[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x02, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0,0,0,0, - 0xff,0x7b,0x23,0x17, - 1, - 0}; - -const int head2_6[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x00, - 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,1,0,0,0, - 0x68,0x22,0x7c,0x3d, - 255, - 100, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255}; - -const int head3_6[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x01, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0x01,0x02,0x03,0x04,2,0,0,0, - 0xf4,0x87,0xba,0xf3, - 255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255}; - -const int head4_6[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x05, - 0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,3,0,0,0, - 0xf7,0x2f,0x6c,0x60, - 5, - 254,255,4,255,0}; - -/* packet that overspans over an entire page */ -const int head1_7[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x02, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0,0,0,0, - 0xff,0x7b,0x23,0x17, - 1, - 0}; - -const int head2_7[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x00, - 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,1,0,0,0, - 0x68,0x22,0x7c,0x3d, - 255, - 100, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255}; - -const int head3_7[] PROGMEM = {0x4f,0x67,0x67,0x53,0,0x05, - 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,2,0,0,0, - 0xd4,0xe0,0x60,0xe5, - 1, - 0}; - -int compare_packet(const ogg_packet *op1, const ogg_packet *op2){ - if(op1->packet!=op2->packet){ - fprintf(stderr,"op1->packet != op2->packet\n"); - return(1); - } - if(op1->bytes!=op2->bytes){ - fprintf(stderr,"op1->bytes != op2->bytes\n"); - return(1); - } - if(op1->b_o_s!=op2->b_o_s){ - fprintf(stderr,"op1->b_o_s != op2->b_o_s\n"); - return(1); - } - if(op1->e_o_s!=op2->e_o_s){ - fprintf(stderr,"op1->e_o_s != op2->e_o_s\n"); - return(1); - } - if(op1->granulepos!=op2->granulepos){ - fprintf(stderr,"op1->granulepos != op2->granulepos\n"); - return(1); - } - if(op1->packetno!=op2->packetno){ - fprintf(stderr,"op1->packetno != op2->packetno\n"); - return(1); - } - return(0); -} - -void test_pack(const int *pl, const int **headers, int byteskip, - int pageskip, int packetskip){ - unsigned char *data=_ogg_malloc(1024*1024); /* for scripted test cases only */ - long inptr=0; - long outptr=0; - long deptr=0; - long depacket=0; - long granule_pos=7,pageno=0; - int i,j,packets,pageout=pageskip; - int eosflag=0; - int bosflag=0; - - int byteskipcount=0; - - ogg_stream_reset(&os_en); - ogg_stream_reset(&os_de); - ogg_sync_reset(&oy); - - for(packets=0;packetsbyteskip){ - memcpy(next,og.header,byteskipcount-byteskip); - next+=byteskipcount-byteskip; - byteskipcount=byteskip; - } - - byteskipcount+=og.body_len; - if(byteskipcount>byteskip){ - memcpy(next,og.body,byteskipcount-byteskip); - next+=byteskipcount-byteskip; - byteskipcount=byteskip; - } - - ogg_sync_wrote(&oy,next-buf); - - while(1){ - int ret=ogg_sync_pageout(&oy,&og_de); - if(ret==0)break; - if(ret<0)continue; - /* got a page. Happy happy. Verify that it's good. */ - - fprintf(stderr,"(%d), ",pageout); - - check_page(data+deptr,headers[pageout],&og_de); - deptr+=og_de.body_len; - pageout++; - - /* submit it to deconstitution */ - ogg_stream_pagein(&os_de,&og_de); - - /* packets out? */ - while(ogg_stream_packetpeek(&os_de,&op_de2)>0){ - ogg_stream_packetpeek(&os_de,NULL); - ogg_stream_packetout(&os_de,&op_de); /* just catching them all */ - - /* verify peek and out match */ - if(compare_packet(&op_de,&op_de2)){ - fprintf(stderr,"packetout != packetpeek! pos=%ld\n", - depacket); - exit(1); - } - - /* verify the packet! */ - /* check data */ - if(memcmp(data+depacket,op_de.packet,op_de.bytes)){ - fprintf(stderr,"packet data mismatch in decode! pos=%ld\n", - depacket); - exit(1); - } - /* check bos flag */ - if(bosflag==0 && op_de.b_o_s==0){ - fprintf(stderr,"b_o_s flag not set on packet!\n"); - exit(1); - } - if(bosflag && op_de.b_o_s){ - fprintf(stderr,"b_o_s flag incorrectly set on packet!\n"); - exit(1); - } - bosflag=1; - depacket+=op_de.bytes; - - /* check eos flag */ - if(eosflag){ - fprintf(stderr,"Multiple decoded packets with eos flag!\n"); - exit(1); - } - - if(op_de.e_o_s)eosflag=1; - - /* check granulepos flag */ - if(op_de.granulepos!=-1){ - fprintf(stderr," granule:%ld ",(long)op_de.granulepos); - } - } - } - } - } - } - } - _ogg_free(data); - if(headers[pageno]!=NULL){ - fprintf(stderr,"did not write last page!\n"); - exit(1); - } - if(headers[pageout]!=NULL){ - fprintf(stderr,"did not decode last page!\n"); - exit(1); - } - if(inptr!=outptr){ - fprintf(stderr,"encoded page data incomplete!\n"); - exit(1); - } - if(inptr!=deptr){ - fprintf(stderr,"decoded page data incomplete!\n"); - exit(1); - } - if(inptr!=depacket){ - fprintf(stderr,"decoded packet data incomplete!\n"); - exit(1); - } - if(!eosflag){ - fprintf(stderr,"Never got a packet with EOS set!\n"); - exit(1); - } - fprintf(stderr,"ok.\n"); -} - -int main(void){ - - ogg_stream_init(&os_en,0x04030201); - ogg_stream_init(&os_de,0x04030201); - ogg_sync_init(&oy); - - /* Exercise each code path in the framing code. Also verify that - the checksums are working. */ - - { - /* 17 only */ - const int packets[]={17, -1}; - const int *headret[]={head1_0,NULL}; - - fprintf(stderr,"testing single page encoding... "); - test_pack(packets,headret,0,0,0); - } - - { - /* 17, 254, 255, 256, 500, 510, 600 byte, pad */ - const int packets[]={17, 254, 255, 256, 500, 510, 600, -1}; - const int *headret[]={head1_1,head2_1,NULL}; - - fprintf(stderr,"testing basic page encoding... "); - test_pack(packets,headret,0,0,0); - } - - { - /* nil packets; beginning,middle,end */ - const int packets[]={0,17, 254, 255, 0, 256, 0, 500, 510, 600, 0, -1}; - const int *headret[]={head1_2,head2_2,NULL}; - - fprintf(stderr,"testing basic nil packets... "); - test_pack(packets,headret,0,0,0); - } - - { - /* large initial packet */ - const int packets[]={4345,259,255,-1}; - const int *headret[]={head1_3,head2_3,NULL}; - - fprintf(stderr,"testing initial-packet lacing > 4k... "); - test_pack(packets,headret,0,0,0); - } - - { - /* continuing packet test; with page spill expansion, we have to - overflow the lacing table. */ - const int packets[]={0,65500,259,255,-1}; - const int *headret[]={head1_4,head2_4,head3_4,NULL}; - - fprintf(stderr,"testing single packet page span... "); - test_pack(packets,headret,0,0,0); - } - - { - /* spill expand packet test */ - const int packets[]={0,4345,259,255,0,0,-1}; - const int *headret[]={head1_4b,head2_4b,head3_4b,NULL}; - - fprintf(stderr,"testing page spill expansion... "); - test_pack(packets,headret,0,0,0); - } - - /* page with the 255 segment limit */ - { - - const int packets[] PROGMEM ={0,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,50,-1}; - const int *headret[] PROGMEM ={head1_5,head2_5,head3_5,NULL}; - - fprintf(stderr,"testing max packet segments... "); - test_pack(packets,headret,0,0,0); - } - - { - /* packet that overspans over an entire page */ - const int packets[]={0,100,130049,259,255,-1}; - const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL}; - - fprintf(stderr,"testing very large packets... "); - test_pack(packets,headret,0,0,0); - } - -#ifndef DISABLE_CRC - { - /* test for the libogg 1.1.1 resync in large continuation bug - found by Josh Coalson) */ - const int packets[]={0,100,130049,259,255,-1}; - const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL}; - - fprintf(stderr,"testing continuation resync in very large packets... "); - test_pack(packets,headret,100,2,3); - } -#else - fprintf(stderr,"Skipping continuation resync test due to --disable-crc\n"); -#endif - - { - /* term only page. why not? */ - const int packets[]={0,100,64770,-1}; - const int *headret[]={head1_7,head2_7,head3_7,NULL}; - - fprintf(stderr,"testing zero data page (1 nil packet)... "); - test_pack(packets,headret,0,0,0); - } - - - - { - /* build a bunch of pages for testing */ - unsigned char *data=_ogg_malloc(1024*1024); - int pl[]={0, 1,1,98,4079, 1,1,2954,2057, 76,34,912,0,234,1000,1000, 1000,300,-1}; - int inptr=0,i,j; - ogg_page og[5]; - - ogg_stream_reset(&os_en); - - for(i=0;pl[i]!=-1;i++){ - ogg_packet op; - int len=pl[i]; - - op.packet=data+inptr; - op.bytes=len; - op.e_o_s=(pl[i+1]<0?1:0); - op.granulepos=(i+1)*1000; - - for(j=0;j0)error(); - - /* Test fractional page inputs: incomplete fixed header */ - memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+3, - 20); - ogg_sync_wrote(&oy,20); - if(ogg_sync_pageout(&oy,&og_de)>0)error(); - - /* Test fractional page inputs: incomplete header */ - memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+23, - 5); - ogg_sync_wrote(&oy,5); - if(ogg_sync_pageout(&oy,&og_de)>0)error(); - - /* Test fractional page inputs: incomplete body */ - - memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+28, - og[1].header_len-28); - ogg_sync_wrote(&oy,og[1].header_len-28); - if(ogg_sync_pageout(&oy,&og_de)>0)error(); - - memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,1000); - ogg_sync_wrote(&oy,1000); - if(ogg_sync_pageout(&oy,&og_de)>0)error(); - - memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body+1000, - og[1].body_len-1000); - ogg_sync_wrote(&oy,og[1].body_len-1000); - if(ogg_sync_pageout(&oy,&og_de)<=0)error(); - - fprintf(stderr,"ok.\n"); - } - - /* Test fractional page inputs: page + incomplete capture */ - { - ogg_page og_de; - fprintf(stderr,"Testing sync on 1+partial inputs... "); - ogg_sync_reset(&oy); - - memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, - og[1].header_len); - ogg_sync_wrote(&oy,og[1].header_len); - - memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, - og[1].body_len); - ogg_sync_wrote(&oy,og[1].body_len); - - memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, - 20); - ogg_sync_wrote(&oy,20); - if(ogg_sync_pageout(&oy,&og_de)<=0)error(); - if(ogg_sync_pageout(&oy,&og_de)>0)error(); - - memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+20, - og[1].header_len-20); - ogg_sync_wrote(&oy,og[1].header_len-20); - memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, - og[1].body_len); - ogg_sync_wrote(&oy,og[1].body_len); - if(ogg_sync_pageout(&oy,&og_de)<=0)error(); - - fprintf(stderr,"ok.\n"); - } - - /* Test recapture: garbage + page */ - { - ogg_page og_de; - fprintf(stderr,"Testing search for capture... "); - ogg_sync_reset(&oy); - - /* 'garbage' */ - memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, - og[1].body_len); - ogg_sync_wrote(&oy,og[1].body_len); - - memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, - og[1].header_len); - ogg_sync_wrote(&oy,og[1].header_len); - - memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, - og[1].body_len); - ogg_sync_wrote(&oy,og[1].body_len); - - memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header, - 20); - ogg_sync_wrote(&oy,20); - if(ogg_sync_pageout(&oy,&og_de)>0)error(); - if(ogg_sync_pageout(&oy,&og_de)<=0)error(); - if(ogg_sync_pageout(&oy,&og_de)>0)error(); - - memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header+20, - og[2].header_len-20); - ogg_sync_wrote(&oy,og[2].header_len-20); - memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body, - og[2].body_len); - ogg_sync_wrote(&oy,og[2].body_len); - if(ogg_sync_pageout(&oy,&og_de)<=0)error(); - - fprintf(stderr,"ok.\n"); - } - -#ifndef DISABLE_CRC - /* Test recapture: page + garbage + page */ - { - ogg_page og_de; - fprintf(stderr,"Testing recapture... "); - ogg_sync_reset(&oy); - - memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, - og[1].header_len); - ogg_sync_wrote(&oy,og[1].header_len); - - memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, - og[1].body_len); - ogg_sync_wrote(&oy,og[1].body_len); - - memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header, - og[2].header_len); - ogg_sync_wrote(&oy,og[2].header_len); - - memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header, - og[2].header_len); - ogg_sync_wrote(&oy,og[2].header_len); - - if(ogg_sync_pageout(&oy,&og_de)<=0)error(); - - memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body, - og[2].body_len-5); - ogg_sync_wrote(&oy,og[2].body_len-5); - - memcpy(ogg_sync_buffer(&oy,og[3].header_len),og[3].header, - og[3].header_len); - ogg_sync_wrote(&oy,og[3].header_len); - - memcpy(ogg_sync_buffer(&oy,og[3].body_len),og[3].body, - og[3].body_len); - ogg_sync_wrote(&oy,og[3].body_len); - - if(ogg_sync_pageout(&oy,&og_de)>0)error(); - if(ogg_sync_pageout(&oy,&og_de)<=0)error(); - - fprintf(stderr,"ok.\n"); - } -#else - fprintf(stderr,"Skipping recapture test due to --disable-crc\n"); -#endif - - /* Free page data that was previously copied */ - { - for(i=0;i<5;i++){ - free_page(&og[i]); - } - } - } - ogg_sync_clear(&oy); - ogg_stream_clear(&os_en); - ogg_stream_clear(&os_de); - - return(0); -} - -#endif diff --git a/src/libogg/ogg.pc b/src/libogg/ogg.pc deleted file mode 100644 index 78755cec..00000000 --- a/src/libogg/ogg.pc +++ /dev/null @@ -1,14 +0,0 @@ -# ogg pkg-config file - -prefix=/usr/local -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -includedir=${prefix}/include - -Name: ogg -Description: ogg is a library for manipulating ogg bitstreams -Version: 1.3.4 -Requires: -Conflicts: -Libs: -L${libdir} -logg -Cflags: -I${includedir} diff --git a/src/libogg/ogg/config_types.h b/src/libogg/ogg/config_types.h deleted file mode 100644 index 1a87df64..00000000 --- a/src/libogg/ogg/config_types.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __CONFIG_TYPES_H__ -#define __CONFIG_TYPES_H__ - -/* these are filled in by configure or cmake*/ -#define INCLUDE_INTTYPES_H 1 -#define INCLUDE_STDINT_H 1 -#define INCLUDE_SYS_TYPES_H 1 - -#if INCLUDE_INTTYPES_H -# include -#endif -#if INCLUDE_STDINT_H -# include -#endif -#if INCLUDE_SYS_TYPES_H -# include -#endif - -typedef int16_t ogg_int16_t; -typedef uint16_t ogg_uint16_t; -typedef int32_t ogg_int32_t; -typedef uint32_t ogg_uint32_t; -typedef int64_t ogg_int64_t; -typedef uint64_t ogg_uint64_t; - -#endif diff --git a/src/libogg/ogg/ogg.h b/src/libogg/ogg/ogg.h deleted file mode 100644 index 330ea3c6..00000000 --- a/src/libogg/ogg/ogg.h +++ /dev/null @@ -1,209 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: toplevel libogg include - - ********************************************************************/ -#ifndef _OGG_H -#define _OGG_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "os_types.h" - -typedef struct { - void *iov_base; - size_t iov_len; -} ogg_iovec_t; - -typedef struct { - long endbyte; - int endbit; - - unsigned char *buffer; - unsigned char *ptr; - long storage; -} oggpack_buffer; - -/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/ - -typedef struct { - unsigned char *header; - long header_len; - unsigned char *body; - long body_len; -} ogg_page; - -/* ogg_stream_state contains the current encode/decode state of a logical - Ogg bitstream **********************************************************/ - -typedef struct { - unsigned char *body_data; /* bytes from packet bodies */ - long body_storage; /* storage elements allocated */ - long body_fill; /* elements stored; fill mark */ - long body_returned; /* elements of fill returned */ - - - int *lacing_vals; /* The values that will go to the segment table */ - ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact - this way, but it is simple coupled to the - lacing fifo */ - long lacing_storage; - long lacing_fill; - long lacing_packet; - long lacing_returned; - - unsigned char header[282]; /* working space for header encode */ - int header_fill; - - int e_o_s; /* set when we have buffered the last packet in the - logical bitstream */ - int b_o_s; /* set after we've written the initial page - of a logical bitstream */ - long serialno; - long pageno; - ogg_int64_t packetno; /* sequence number for decode; the framing - knows where there's a hole in the data, - but we need coupling so that the codec - (which is in a separate abstraction - layer) also knows about the gap */ - ogg_int64_t granulepos; - -} ogg_stream_state; - -/* ogg_packet is used to encapsulate the data and metadata belonging - to a single raw Ogg/Vorbis packet *************************************/ - -typedef struct { - unsigned char *packet; - long bytes; - long b_o_s; - long e_o_s; - - ogg_int64_t granulepos; - - ogg_int64_t packetno; /* sequence number for decode; the framing - knows where there's a hole in the data, - but we need coupling so that the codec - (which is in a separate abstraction - layer) also knows about the gap */ -} ogg_packet; - -typedef struct { - unsigned char *data; - int storage; - int fill; - int returned; - - int unsynced; - int headerbytes; - int bodybytes; -} ogg_sync_state; - -/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/ - -extern void oggpack_writeinit(oggpack_buffer *b); -extern int oggpack_writecheck(oggpack_buffer *b); -extern void oggpack_writetrunc(oggpack_buffer *b,long bits); -extern void oggpack_writealign(oggpack_buffer *b); -extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits); -extern void oggpack_reset(oggpack_buffer *b); -extern void oggpack_writeclear(oggpack_buffer *b); -extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); -extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits); -extern long oggpack_look(oggpack_buffer *b,int bits); -extern long oggpack_look1(oggpack_buffer *b); -extern void oggpack_adv(oggpack_buffer *b,int bits); -extern void oggpack_adv1(oggpack_buffer *b); -extern long oggpack_read(oggpack_buffer *b,int bits); -extern long oggpack_read1(oggpack_buffer *b); -extern long oggpack_bytes(oggpack_buffer *b); -extern long oggpack_bits(oggpack_buffer *b); -extern unsigned char *oggpack_get_buffer(oggpack_buffer *b); - -extern void oggpackB_writeinit(oggpack_buffer *b); -extern int oggpackB_writecheck(oggpack_buffer *b); -extern void oggpackB_writetrunc(oggpack_buffer *b,long bits); -extern void oggpackB_writealign(oggpack_buffer *b); -extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits); -extern void oggpackB_reset(oggpack_buffer *b); -extern void oggpackB_writeclear(oggpack_buffer *b); -extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); -extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits); -extern long oggpackB_look(oggpack_buffer *b,int bits); -extern long oggpackB_look1(oggpack_buffer *b); -extern void oggpackB_adv(oggpack_buffer *b,int bits); -extern void oggpackB_adv1(oggpack_buffer *b); -extern long oggpackB_read(oggpack_buffer *b,int bits); -extern long oggpackB_read1(oggpack_buffer *b); -extern long oggpackB_bytes(oggpack_buffer *b); -extern long oggpackB_bits(oggpack_buffer *b); -extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b); - -/* Ogg BITSTREAM PRIMITIVES: encoding **************************/ - -extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); -extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, - int count, long e_o_s, ogg_int64_t granulepos); -extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); -extern int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill); -extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); -extern int ogg_stream_flush_fill(ogg_stream_state *os, ogg_page *og, int nfill); - -/* Ogg BITSTREAM PRIMITIVES: decoding **************************/ - -extern int ogg_sync_init(ogg_sync_state *oy); -extern int ogg_sync_clear(ogg_sync_state *oy); -extern int ogg_sync_reset(ogg_sync_state *oy); -extern int ogg_sync_destroy(ogg_sync_state *oy); -extern int ogg_sync_check(ogg_sync_state *oy); - -extern char *ogg_sync_buffer(ogg_sync_state *oy, long size); -extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes); -extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og); -extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); -extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); -extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); -extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op); - -/* Ogg BITSTREAM PRIMITIVES: general ***************************/ - -extern int ogg_stream_init(ogg_stream_state *os,int serialno); -extern int ogg_stream_clear(ogg_stream_state *os); -extern int ogg_stream_reset(ogg_stream_state *os); -extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno); -extern int ogg_stream_destroy(ogg_stream_state *os); -extern int ogg_stream_check(ogg_stream_state *os); -extern int ogg_stream_eos(ogg_stream_state *os); - -extern void ogg_page_checksum_set(ogg_page *og); - -extern int ogg_page_version(const ogg_page *og); -extern int ogg_page_continued(const ogg_page *og); -extern int ogg_page_bos(const ogg_page *og); -extern int ogg_page_eos(const ogg_page *og); -extern ogg_int64_t ogg_page_granulepos(const ogg_page *og); -extern int ogg_page_serialno(const ogg_page *og); -extern long ogg_page_pageno(const ogg_page *og); -extern int ogg_page_packets(const ogg_page *og); - -extern void ogg_packet_clear(ogg_packet *op); - - -#ifdef __cplusplus -} -#endif - -#endif /* _OGG_H */ diff --git a/src/libogg/ogg/os_types.h b/src/libogg/ogg/os_types.h deleted file mode 100644 index 644e3750..00000000 --- a/src/libogg/ogg/os_types.h +++ /dev/null @@ -1,158 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: Define a consistent set of types on each platform. - - ********************************************************************/ -#ifndef _OS_TYPES_H -#define _OS_TYPES_H - -/* make it easy on the folks that want to compile the libs with a - different malloc than stdlib */ -#define _ogg_malloc malloc -#define _ogg_calloc calloc -#define _ogg_realloc realloc -#define _ogg_free free - -#if defined(_WIN32) - -# if defined(__CYGWIN__) -# include - typedef int16_t ogg_int16_t; - typedef uint16_t ogg_uint16_t; - typedef int32_t ogg_int32_t; - typedef uint32_t ogg_uint32_t; - typedef int64_t ogg_int64_t; - typedef uint64_t ogg_uint64_t; -# elif defined(__MINGW32__) -# include - typedef short ogg_int16_t; - typedef unsigned short ogg_uint16_t; - typedef int ogg_int32_t; - typedef unsigned int ogg_uint32_t; - typedef long long ogg_int64_t; - typedef unsigned long long ogg_uint64_t; -# elif defined(__MWERKS__) - typedef long long ogg_int64_t; - typedef unsigned long long ogg_uint64_t; - typedef int ogg_int32_t; - typedef unsigned int ogg_uint32_t; - typedef short ogg_int16_t; - typedef unsigned short ogg_uint16_t; -# else -# if defined(_MSC_VER) && (_MSC_VER >= 1800) /* MSVC 2013 and newer */ -# include - typedef int16_t ogg_int16_t; - typedef uint16_t ogg_uint16_t; - typedef int32_t ogg_int32_t; - typedef uint32_t ogg_uint32_t; - typedef int64_t ogg_int64_t; - typedef uint64_t ogg_uint64_t; -# else - /* MSVC/Borland */ - typedef __int64 ogg_int64_t; - typedef __int32 ogg_int32_t; - typedef unsigned __int32 ogg_uint32_t; - typedef unsigned __int64 ogg_uint64_t; - typedef __int16 ogg_int16_t; - typedef unsigned __int16 ogg_uint16_t; -# endif -# endif - -#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ - -# include - typedef int16_t ogg_int16_t; - typedef uint16_t ogg_uint16_t; - typedef int32_t ogg_int32_t; - typedef uint32_t ogg_uint32_t; - typedef int64_t ogg_int64_t; - typedef uint64_t ogg_uint64_t; - -#elif defined(__HAIKU__) - - /* Haiku */ -# include - typedef short ogg_int16_t; - typedef unsigned short ogg_uint16_t; - typedef int ogg_int32_t; - typedef unsigned int ogg_uint32_t; - typedef long long ogg_int64_t; - typedef unsigned long long ogg_uint64_t; - -#elif defined(__BEOS__) - - /* Be */ -# include - typedef int16_t ogg_int16_t; - typedef uint16_t ogg_uint16_t; - typedef int32_t ogg_int32_t; - typedef uint32_t ogg_uint32_t; - typedef int64_t ogg_int64_t; - typedef uint64_t ogg_uint64_t; - -#elif defined (__EMX__) - - /* OS/2 GCC */ - typedef short ogg_int16_t; - typedef unsigned short ogg_uint16_t; - typedef int ogg_int32_t; - typedef unsigned int ogg_uint32_t; - typedef long long ogg_int64_t; - typedef unsigned long long ogg_uint64_t; - - -#elif defined (DJGPP) - - /* DJGPP */ - typedef short ogg_int16_t; - typedef int ogg_int32_t; - typedef unsigned int ogg_uint32_t; - typedef long long ogg_int64_t; - typedef unsigned long long ogg_uint64_t; - -#elif defined(R5900) - - /* PS2 EE */ - typedef long ogg_int64_t; - typedef unsigned long ogg_uint64_t; - typedef int ogg_int32_t; - typedef unsigned ogg_uint32_t; - typedef short ogg_int16_t; - -#elif defined(__SYMBIAN32__) - - /* Symbian GCC */ - typedef signed short ogg_int16_t; - typedef unsigned short ogg_uint16_t; - typedef signed int ogg_int32_t; - typedef unsigned int ogg_uint32_t; - typedef long long int ogg_int64_t; - typedef unsigned long long int ogg_uint64_t; - -#elif defined(__TMS320C6X__) - - /* TI C64x compiler */ - typedef signed short ogg_int16_t; - typedef unsigned short ogg_uint16_t; - typedef signed int ogg_int32_t; - typedef unsigned int ogg_uint32_t; - typedef long long int ogg_int64_t; - typedef unsigned long long int ogg_uint64_t; - -#else - -# include "config_types.h" - -#endif - -#endif /* _OS_TYPES_H */ diff --git a/src/libopus/COPYING b/src/libopus/COPYING index 9c739c34..75711467 100644 --- a/src/libopus/COPYING +++ b/src/libopus/COPYING @@ -1,7 +1,7 @@ -Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic, +Copyright 2001-2023 Xiph.Org, Skype Limited, Octasic, Jean-Marc Valin, Timothy B. Terriberry, CSIRO, Gregory Maxwell, Mark Borgerding, - Erik de Castro Lopo + Erik de Castro Lopo, Mozilla, Amazon Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/src/libopus/ChangeLog b/src/libopus/ChangeLog deleted file mode 100644 index e69de29b..00000000 diff --git a/src/libopus/INSTALL b/src/libopus/INSTALL deleted file mode 100644 index 8865734f..00000000 --- a/src/libopus/INSTALL +++ /dev/null @@ -1,368 +0,0 @@ -Installation Instructions -************************* - - Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software -Foundation, Inc. - - Copying and distribution of this file, with or without modification, -are permitted in any medium without royalty provided the copyright -notice and this notice are preserved. This file is offered as-is, -without warranty of any kind. - -Basic Installation -================== - - Briefly, the shell command './configure && make && make install' -should configure, build, and install this package. The following -more-detailed instructions are generic; see the 'README' file for -instructions specific to this package. Some packages provide this -'INSTALL' file but do not implement all of the features documented -below. The lack of an optional feature in a given package is not -necessarily a bug. More recommendations for GNU packages can be found -in *note Makefile Conventions: (standards)Makefile Conventions. - - The 'configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a 'Makefile' in each directory of the package. -It may also create one or more '.h' files containing system-dependent -definitions. Finally, it creates a shell script 'config.status' that -you can run in the future to recreate the current configuration, and a -file 'config.log' containing compiler output (useful mainly for -debugging 'configure'). - - It can also use an optional file (typically called 'config.cache' and -enabled with '--cache-file=config.cache' or simply '-C') that saves the -results of its tests to speed up reconfiguring. Caching is disabled by -default to prevent problems with accidental use of stale cache files. - - If you need to do unusual things to compile the package, please try -to figure out how 'configure' could check whether to do them, and mail -diffs or instructions to the address given in the 'README' so they can -be considered for the next release. If you are using the cache, and at -some point 'config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file 'configure.ac' (or 'configure.in') is used to create -'configure' by a program called 'autoconf'. You need 'configure.ac' if -you want to change it or regenerate 'configure' using a newer version of -'autoconf'. - - The simplest way to compile this package is: - - 1. 'cd' to the directory containing the package's source code and type - './configure' to configure the package for your system. - - Running 'configure' might take a while. While running, it prints - some messages telling which features it is checking for. - - 2. Type 'make' to compile the package. - - 3. Optionally, type 'make check' to run any self-tests that come with - the package, generally using the just-built uninstalled binaries. - - 4. Type 'make install' to install the programs and any data files and - documentation. When installing into a prefix owned by root, it is - recommended that the package be configured and built as a regular - user, and only the 'make install' phase executed with root - privileges. - - 5. Optionally, type 'make installcheck' to repeat any self-tests, but - this time using the binaries in their final installed location. - This target does not install anything. Running this target as a - regular user, particularly if the prior 'make install' required - root privileges, verifies that the installation completed - correctly. - - 6. You can remove the program binaries and object files from the - source code directory by typing 'make clean'. To also remove the - files that 'configure' created (so you can compile the package for - a different kind of computer), type 'make distclean'. There is - also a 'make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - - 7. Often, you can also type 'make uninstall' to remove the installed - files again. In practice, not all packages have tested that - uninstallation works correctly, even though it is required by the - GNU Coding Standards. - - 8. Some packages, particularly those that use Automake, provide 'make - distcheck', which can by used by developers to test that all other - targets like 'make install' and 'make uninstall' work correctly. - This target is generally not run by end users. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the 'configure' script does not know about. Run './configure --help' -for details on some of the pertinent environment variables. - - You can give 'configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here is -an example: - - ./configure CC=c99 CFLAGS=-g LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you can use GNU 'make'. 'cd' to the -directory where you want the object files and executables to go and run -the 'configure' script. 'configure' automatically checks for the source -code in the directory that 'configure' is in and in '..'. This is known -as a "VPATH" build. - - With a non-GNU 'make', it is safer to compile the package for one -architecture at a time in the source code directory. After you have -installed the package for one architecture, use 'make distclean' before -reconfiguring for another architecture. - - On MacOS X 10.5 and later systems, you can create libraries and -executables that work on multiple system types--known as "fat" or -"universal" binaries--by specifying multiple '-arch' options to the -compiler but only a single '-arch' option to the preprocessor. Like -this: - - ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CPP="gcc -E" CXXCPP="g++ -E" - - This is not guaranteed to produce working output in all cases, you -may have to build one architecture at a time and combine the results -using the 'lipo' tool if you have problems. - -Installation Names -================== - - By default, 'make install' installs the package's commands under -'/usr/local/bin', include files under '/usr/local/include', etc. You -can specify an installation prefix other than '/usr/local' by giving -'configure' the option '--prefix=PREFIX', where PREFIX must be an -absolute file name. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option '--exec-prefix=PREFIX' to 'configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like '--bindir=DIR' to specify different values for particular -kinds of files. Run 'configure --help' for a list of the directories -you can set and what kinds of files go in them. In general, the default -for these options is expressed in terms of '${prefix}', so that -specifying just '--prefix' will affect all of the other directory -specifications that were not explicitly provided. - - The most portable way to affect installation locations is to pass the -correct locations to 'configure'; however, many packages provide one or -both of the following shortcuts of passing variable assignments to the -'make install' command line to change installation locations without -having to reconfigure or recompile. - - The first method involves providing an override variable for each -affected directory. For example, 'make install -prefix=/alternate/directory' will choose an alternate location for all -directory configuration variables that were expressed in terms of -'${prefix}'. Any directories that were specified during 'configure', -but not in terms of '${prefix}', must each be overridden at install time -for the entire installation to be relocated. The approach of makefile -variable overrides for each directory variable is required by the GNU -Coding Standards, and ideally causes no recompilation. However, some -platforms have known limitations with the semantics of shared libraries -that end up requiring recompilation when using this method, particularly -noticeable in packages that use GNU Libtool. - - The second method involves providing the 'DESTDIR' variable. For -example, 'make install DESTDIR=/alternate/directory' will prepend -'/alternate/directory' before all installation names. The approach of -'DESTDIR' overrides is not required by the GNU Coding Standards, and -does not work on platforms that have drive letters. On the other hand, -it does better at avoiding recompilation issues, and works well even -when some directory options were not specified in terms of '${prefix}' -at 'configure' time. - -Optional Features -================= - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving 'configure' the -option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. - - Some packages pay attention to '--enable-FEATURE' options to -'configure', where FEATURE indicates an optional part of the package. -They may also pay attention to '--with-PACKAGE' options, where PACKAGE -is something like 'gnu-as' or 'x' (for the X Window System). The -'README' should mention any '--enable-' and '--with-' options that the -package recognizes. - - For packages that use the X Window System, 'configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the 'configure' options '--x-includes=DIR' and -'--x-libraries=DIR' to specify their locations. - - Some packages offer the ability to configure how verbose the -execution of 'make' will be. For these packages, running './configure ---enable-silent-rules' sets the default to minimal output, which can be -overridden with 'make V=1'; while running './configure ---disable-silent-rules' sets the default to verbose, which can be -overridden with 'make V=0'. - -Particular systems -================== - - On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC -is not installed, it is recommended to use the following options in -order to use an ANSI C compiler: - - ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" - -and if that doesn't work, install pre-built binaries of GCC for HP-UX. - - HP-UX 'make' updates targets which have the same time stamps as their -prerequisites, which makes it generally unusable when shipped generated -files such as 'configure' are involved. Use GNU 'make' instead. - - On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot -parse its '' header file. The option '-nodtk' can be used as a -workaround. If GNU CC is not installed, it is therefore recommended to -try - - ./configure CC="cc" - -and if that doesn't work, try - - ./configure CC="cc -nodtk" - - On Solaris, don't put '/usr/ucb' early in your 'PATH'. This -directory contains several dysfunctional programs; working variants of -these programs are available in '/usr/bin'. So, if you need '/usr/ucb' -in your 'PATH', put it _after_ '/usr/bin'. - - On Haiku, software installed for all users goes in '/boot/common', -not '/usr/local'. It is recommended to use the following options: - - ./configure --prefix=/boot/common - -Specifying the System Type -========================== - - There may be some features 'configure' cannot figure out -automatically, but needs to determine by the type of machine the package -will run on. Usually, assuming the package is built to be run on the -_same_ architectures, 'configure' can figure that out, but if it prints -a message saying it cannot guess the machine type, give it the -'--build=TYPE' option. TYPE can either be a short name for the system -type, such as 'sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS - KERNEL-OS - - See the file 'config.sub' for the possible values of each field. If -'config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option '--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with '--host=TYPE'. - -Sharing Defaults -================ - - If you want to set default values for 'configure' scripts to share, -you can create a site shell script called 'config.site' that gives -default values for variables like 'CC', 'cache_file', and 'prefix'. -'configure' looks for 'PREFIX/share/config.site' if it exists, then -'PREFIX/etc/config.site' if it exists. Or, you can set the -'CONFIG_SITE' environment variable to the location of the site script. -A warning: not all 'configure' scripts look for a site script. - -Defining Variables -================== - - Variables not defined in a site shell script can be set in the -environment passed to 'configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the 'configure' command line, using 'VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified 'gcc' to be used as the C compiler (unless it is -overridden in the site shell script). - -Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an -Autoconf limitation. Until the limitation is lifted, you can use this -workaround: - - CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash - -'configure' Invocation -====================== - - 'configure' recognizes the following options to control how it -operates. - -'--help' -'-h' - Print a summary of all of the options to 'configure', and exit. - -'--help=short' -'--help=recursive' - Print a summary of the options unique to this package's - 'configure', and exit. The 'short' variant lists options used only - in the top level, while the 'recursive' variant lists options also - present in any nested packages. - -'--version' -'-V' - Print the version of Autoconf used to generate the 'configure' - script, and exit. - -'--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally 'config.cache'. FILE defaults to '/dev/null' to - disable caching. - -'--config-cache' -'-C' - Alias for '--cache-file=config.cache'. - -'--quiet' -'--silent' -'-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to '/dev/null' (any error - messages will still be shown). - -'--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - 'configure' can determine that directory automatically. - -'--prefix=DIR' - Use DIR as the installation prefix. *note Installation Names:: for - more details, including other options available for fine-tuning the - installation locations. - -'--no-create' -'-n' - Run the configure checks, but stop before creating any output - files. - -'configure' also accepts some other, not widely useful, options. Run -'configure --help' for more details. diff --git a/src/libopus/LICENSE_PLEASE_READ.txt b/src/libopus/LICENSE_PLEASE_READ.txt new file mode 100644 index 00000000..bc88efa6 --- /dev/null +++ b/src/libopus/LICENSE_PLEASE_READ.txt @@ -0,0 +1,22 @@ +Contributions to the collaboration shall not be considered confidential. + +Each contributor represents and warrants that it has the right and +authority to license copyright in its contributions to the collaboration. + +Each contributor agrees to license the copyright in the contributions +under the Modified (2-clause or 3-clause) BSD License or the Clear BSD License. + +Please see the IPR statements submitted to the IETF for the complete +patent licensing details: + +Xiph.Org Foundation: +https://datatracker.ietf.org/ipr/1524/ + +Microsoft Corporation: +https://datatracker.ietf.org/ipr/1914/ + +Skype Limited: +https://datatracker.ietf.org/ipr/1602/ + +Broadcom Corporation: +https://datatracker.ietf.org/ipr/1526/ diff --git a/src/libopus/NEWS b/src/libopus/NEWS deleted file mode 100644 index e69de29b..00000000 diff --git a/src/libopus/README b/src/libopus/README index 27fddf96..bcf2376d 100644 --- a/src/libopus/README +++ b/src/libopus/README @@ -22,7 +22,7 @@ This package implements a shared library for encoding and decoding raw Opus bitstreams. Raw Opus bitstreams should be used over RTP according to https://tools.ietf.org/html/rfc7587 -The package also includes a number of test tools used for testing the +The package also includes a number of test tools used for testing the correct operation of the library. The bitstreams read/written by these tools should not be used for Opus file distribution: They include additional debugging data and cannot support seeking. @@ -35,10 +35,32 @@ An opus-tools package is available which provides encoding and decoding of Ogg encapsulated Opus files and includes a number of useful features. Opus-tools can be found at: - https://git.xiph.org/?p=opus-tools.git + https://gitlab.xiph.org/xiph/opus-tools.git or on the main Opus website: https://opus-codec.org/ +== Deep Learning and Opus == + +Lossy networks continue to be a challenge for real-time communications. +While the original implementation of Opus provides an excellent packet loss +concealment mechanism, the team has continued to advance the methodology used +to improve audio quality in challenge network environments. + +In Opus 1.5, we added a deep learning based redundancy encoder that enhances +audio in lossy networks by embedding one second of recovery data in the padding +data of each packet. The underlying algorithm behind encoding and decoding the +recovery data is called the deep redundancy (DRED) algorithm. By leveraging +the padding data within the packet, Opus 1.5 is fully backward compatible with +prior revisions of Opus. Please see the README under the "dnn" subdirectory to +understand DRED. + +DRED was developed by a team that Amazon Web Services initially sponsored, +who open-sourced the implementation as well as began the +standardization process at the IETF: + https://datatracker.ietf.org/doc/draft-ietf-mlcodec-opus-extension/ +The license behind Opus or the intellectual property position of Opus does +not change with Opus 1.5. + == Compiling libopus == To build from a distribution tarball, you only need to do the following: @@ -68,7 +90,7 @@ On Apple macOS, install Xcode and brew.sh, then in the Terminal enter: 1) Clone the repository: - % git clone https://git.xiph.org/opus.git + % git clone https://gitlab.xiph.org/xiph/opus.git % cd opus 2) Compiling the source @@ -77,6 +99,8 @@ On Apple macOS, install Xcode and brew.sh, then in the Terminal enter: % ./configure % make +On x86, it's a good idea to use a -march= option that allows the use of AVX2. + 3) Install the codec libraries (optional) % sudo make install @@ -133,6 +157,10 @@ To run compare the code to these test vectors: % tar -zxf opus_testvectors-rfc8251.tar.gz % ./tests/run_vectors.sh ./ opus_newvectors 48000 +== Compiling libopus for Windows and alternative build systems == + +See cmake/README.md or meson/README.md. + == Portability notes == This implementation uses floating-point by default but can be compiled to diff --git a/src/libopus/analysis.h b/src/libopus/analysis.h deleted file mode 100644 index 553c0e7c..00000000 --- a/src/libopus/analysis.h +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright (c) 2011 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef ANALYSIS_H -#define ANALYSIS_H - -#include "celt/celt.h" -#include "opus_private.h" -#include "mlp.h" - -#define NB_FRAMES 8 -#define NB_TBANDS 18 -#define ANALYSIS_BUF_SIZE 720 /* 30 ms at 24 kHz */ - -/* At that point we can stop counting frames because it no longer matters. */ -#define ANALYSIS_COUNT_MAX 10000 - -#define DETECT_SIZE 100 - -/* Uncomment this to print the MLP features on stdout. */ -/*#define MLP_TRAINING*/ - -typedef struct { - int arch; - int application; - opus_int32 Fs; -#define TONALITY_ANALYSIS_RESET_START angle - float angle[240]; - float d_angle[240]; - float d2_angle[240]; - opus_val32 inmem[ANALYSIS_BUF_SIZE]; - int mem_fill; /* number of usable samples in the buffer */ - float prev_band_tonality[NB_TBANDS]; - float prev_tonality; - int prev_bandwidth; - float E[NB_FRAMES][NB_TBANDS]; - float logE[NB_FRAMES][NB_TBANDS]; - float lowE[NB_TBANDS]; - float highE[NB_TBANDS]; - float meanE[NB_TBANDS+1]; - float mem[32]; - float cmean[8]; - float std[9]; - float Etracker; - float lowECount; - int E_count; - int count; - int analysis_offset; - int write_pos; - int read_pos; - int read_subframe; - float hp_ener_accum; - int initialized; - float rnn_state[MAX_NEURONS]; - opus_val32 downmix_state[3]; - AnalysisInfo info[DETECT_SIZE]; -} TonalityAnalysisState; - -/** Initialize a TonalityAnalysisState struct. - * - * This performs some possibly slow initialization steps which should - * not be repeated every analysis step. No allocated memory is retained - * by the state struct, so no cleanup call is required. - */ -void tonality_analysis_init(TonalityAnalysisState *analysis, opus_int32 Fs); - -/** Reset a TonalityAnalysisState stuct. - * - * Call this when there's a discontinuity in the data. - */ -void tonality_analysis_reset(TonalityAnalysisState *analysis); - -void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len); - -void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *analysis_pcm, - int analysis_frame_size, int frame_size, int c1, int c2, int C, opus_int32 Fs, - int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info); - -#endif diff --git a/src/libopus/celt/arch.h b/src/libopus/celt/arch.h index 0db602d4..3845c3a0 100644 --- a/src/libopus/celt/arch.h +++ b/src/libopus/celt/arch.h @@ -34,8 +34,8 @@ #ifndef ARCH_H #define ARCH_H -#include "../opus_types.h" -#include "../opus_defines.h" +#include "opus_types.h" +#include "opus_defines.h" # if !defined(__GNUC_PREREQ) # if defined(__GNUC__)&&defined(__GNUC_MINOR__) @@ -73,6 +73,9 @@ __attribute__((noreturn)) void celt_fatal(const char *str, const char *file, int line) { fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str); +#if defined(_MSC_VER) + _set_abort_behavior( 0, _WRITE_ABORT_MSG); +#endif abort(); } #endif diff --git a/src/libopus/celt/bands.c b/src/libopus/celt/bands.c index ea5c4a3f..979a13b7 100644 --- a/src/libopus/celt/bands.c +++ b/src/libopus/celt/bands.c @@ -27,9 +27,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include #include "bands.h" @@ -901,7 +901,7 @@ static void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx, sctx->itheta = itheta; sctx->qalloc = qalloc; } -static unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, int b, +static unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, celt_norm *lowband_out) { int c; @@ -926,7 +926,6 @@ static unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, sign = ec_dec_bits(ec, 1); } ctx->remaining_bits -= 1<resynth) x[0] = sign ? -NORM_SCALING : NORM_SCALING; @@ -1134,7 +1133,7 @@ static unsigned quant_band(struct band_ctx *ctx, celt_norm *X, /* Special case for one sample */ if (N==1) { - return quant_band_n1(ctx, X, NULL, b, lowband_out); + return quant_band_n1(ctx, X, NULL, lowband_out); } if (tf_change>0) @@ -1256,7 +1255,7 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm /* Special case for one sample */ if (N==1) { - return quant_band_n1(ctx, X, Y, b, lowband_out); + return quant_band_n1(ctx, X, Y, lowband_out); } orig_fill = fill; @@ -1381,6 +1380,7 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm return cm; } +#ifndef DISABLE_UPDATE_DRAFT static void special_hybrid_folding(const CELTMode *m, celt_norm *norm, celt_norm *norm2, int start, int M, int dual_stereo) { int n1, n2; @@ -1393,6 +1393,7 @@ static void special_hybrid_folding(const CELTMode *m, celt_norm *norm, celt_norm if (dual_stereo) OPUS_COPY(&norm2[n1], &norm2[2*n1 - n2], n2-n1); } +#endif void quant_all_bands(int encode, const CELTMode *m, int start, int end, celt_norm *X_, celt_norm *Y_, unsigned char *collapse_masks, @@ -1449,7 +1450,7 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end, if (encode && resynth) lowband_scratch = _lowband_scratch; else - lowband_scratch = X_+M*eBands[m->nbEBands-1]; + lowband_scratch = X_+M*eBands[m->effEBands-1]; ALLOC(X_save, resynth_alloc, celt_norm); ALLOC(Y_save, resynth_alloc, celt_norm); ALLOC(X_save2, resynth_alloc, celt_norm); diff --git a/src/libopus/celt/celt.c b/src/libopus/celt/celt.c index bbe4a7f6..6af2f918 100644 --- a/src/libopus/celt/celt.c +++ b/src/libopus/celt/celt.c @@ -27,9 +27,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #define CELT_C diff --git a/src/libopus/celt/celt.h b/src/libopus/celt/celt.h index 34549521..2f501951 100644 --- a/src/libopus/celt/celt.h +++ b/src/libopus/celt/celt.h @@ -35,13 +35,17 @@ #ifndef CELT_H #define CELT_H -#include "../opus_types.h" -#include "../opus_defines.h" -#include "../opus_custom.h" +#include "opus_types.h" +#include "opus_defines.h" +#include "opus_custom.h" #include "entenc.h" #include "entdec.h" #include "arch.h" +#ifdef ENABLE_DEEP_PLC +#include "lpcnet.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -149,6 +153,13 @@ int celt_decoder_get_size(int channels); int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels); +int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, + int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum +#ifdef ENABLE_DEEP_PLC + ,LPCNetPLCState *lpcnet +#endif + ); + int celt_decode_with_ec(OpusCustomDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum); @@ -225,23 +236,13 @@ void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N, opus_val16 g0, opus_val16 g1, int tapset0, int tapset1, const opus_val16 *window, int overlap, int arch); -#ifdef NON_STATIC_COMB_FILTER_CONST_C -void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N, - opus_val16 g10, opus_val16 g11, opus_val16 g12); -#endif - -#ifndef OVERRIDE_COMB_FILTER_CONST -# define comb_filter_const(y, x, T, N, g10, g11, g12, arch) \ - ((void)(arch),comb_filter_const_c(y, x, T, N, g10, g11, g12)) -#endif - void init_caps(const CELTMode *m,int *cap,int LM,int C); #ifdef RESYNTH -void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef, celt_sig *mem); +void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef, celt_sig *mem, int accum); void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[], opus_val16 *oldBandE, int start, int effEnd, int C, int CC, int isTransient, - int LM, int downsample, int silence); + int LM, int downsample, int silence, int arch); #endif #ifdef __cplusplus diff --git a/src/libopus/celt/celt_decoder.c b/src/libopus/celt/celt_decoder.c index 329b6f6c..3e50eb2e 100644 --- a/src/libopus/celt/celt_decoder.c +++ b/src/libopus/celt/celt_decoder.c @@ -27,9 +27,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #define CELT_DECODER_C @@ -51,6 +51,11 @@ #include "celt_lpc.h" #include "vq.h" +#ifdef ENABLE_DEEP_PLC +#include "lpcnet.h" +#include "lpcnet_private.h" +#endif + /* The maximum pitch lag to allow in the pitch-based PLC. It's possible to save CPU time in the PLC pitch search by making this smaller than MAX_PERIOD. The current value corresponds to a pitch of 66.67 Hz. */ @@ -59,9 +64,6 @@ pitch of 480 Hz. */ #define PLC_PITCH_LAG_MIN (100) -#if defined(SMALL_FOOTPRINT) && defined(FIXED_POINT) -#define NORM_ALIASING_HACK -#endif /**********************************************************************/ /* */ /* DECODER */ @@ -69,6 +71,9 @@ /**********************************************************************/ #define DECODE_BUFFER_SIZE 2048 +#define PLC_UPDATE_FRAMES 4 +#define PLC_UPDATE_SAMPLES (PLC_UPDATE_FRAMES*FRAME_SIZE) + /** Decoder state @brief Decoder state */ @@ -82,6 +87,7 @@ struct OpusCustomDecoder { int start, end; int signalling; int disable_inv; + int complexity; int arch; /* Everything beyond this point gets cleared on a reset */ @@ -90,7 +96,7 @@ struct OpusCustomDecoder { opus_uint32 rng; int error; int last_pitch_index; - int loss_count; + int loss_duration; int skip_plc; int postfilter_period; int postfilter_period_old; @@ -98,11 +104,18 @@ struct OpusCustomDecoder { opus_val16 postfilter_gain_old; int postfilter_tapset; int postfilter_tapset_old; + int prefilter_and_fold; celt_sig preemph_memD[2]; +#ifdef ENABLE_DEEP_PLC + opus_int16 plc_pcm[PLC_UPDATE_SAMPLES]; + int plc_fill; + float plc_preemphasis_mem; +#endif + celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */ - /* opus_val16 lpc[], Size = channels*LPC_ORDER */ + /* opus_val16 lpc[], Size = channels*CELT_LPC_ORDER */ /* opus_val16 oldEBands[], Size = 2*mode->nbEBands */ /* opus_val16 oldLogE[], Size = 2*mode->nbEBands */ /* opus_val16 oldLogE2[], Size = 2*mode->nbEBands */ @@ -117,13 +130,19 @@ void validate_celt_decoder(CELTDecoder *st) #ifndef CUSTOM_MODES celt_assert(st->mode == opus_custom_mode_create(48000, 960, NULL)); celt_assert(st->overlap == 120); + celt_assert(st->end <= 21); +#else +/* From Section 4.3 in the spec: "The normal CELT layer uses 21 of those bands, + though Opus Custom (see Section 6.2) may use a different number of bands" + + Check if it's within the maximum number of Bark frequency bands instead */ + celt_assert(st->end <= 25); #endif celt_assert(st->channels == 1 || st->channels == 2); celt_assert(st->stream_channels == 1 || st->stream_channels == 2); celt_assert(st->downsample > 0); celt_assert(st->start == 0 || st->start == 17); celt_assert(st->start < st->end); - celt_assert(st->end <= 21); #ifdef OPUS_ARCHMASK celt_assert(st->arch >= 0); celt_assert(st->arch <= OPUS_ARCHMASK); @@ -151,7 +170,7 @@ OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_get_size(const CELTMode *mode, int { int size = sizeof(struct CELTDecoder) + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig) - + channels*LPC_ORDER*sizeof(opus_val16) + + channels*CELT_LPC_ORDER*sizeof(opus_val16) + 4*2*mode->nbEBands*sizeof(opus_val16); return size; } @@ -493,7 +512,100 @@ static int celt_plc_pitch_search(celt_sig *decode_mem[2], int C, int arch) return pitch_index; } -static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) +static void prefilter_and_fold(CELTDecoder * OPUS_RESTRICT st, int N) +{ + int c; + int CC; + int i; + int overlap; + celt_sig *decode_mem[2]; + const OpusCustomMode *mode; + VARDECL(opus_val32, etmp); + mode = st->mode; + overlap = st->overlap; + CC = st->channels; + ALLOC(etmp, overlap, opus_val32); + c=0; do { + decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap); + } while (++cpostfilter_period_old, st->postfilter_period, overlap, + -st->postfilter_gain_old, -st->postfilter_gain, + st->postfilter_tapset_old, st->postfilter_tapset, NULL, 0, st->arch); + + /* Simulate TDAC on the concealed audio so that it blends with the + MDCT of the next frame. */ + for (i=0;iwindow[i], etmp[overlap-1-i]) + + MULT16_32_Q15(mode->window[overlap-i-1], etmp[i]); + } + } while (++cfec_read_pos; + tmp_fec_skip = lpcnet->fec_skip; + for (i=0;ifec_read_pos = tmp_read_post; + lpcnet->fec_skip = tmp_fec_skip; +} +#endif + +static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM +#ifdef ENABLE_DEEP_PLC + ,LPCNetPLCState *lpcnet +#endif + ) { int c; int i; @@ -506,7 +618,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) int nbEBands; int overlap; int start; - int loss_count; + int loss_duration; int noise_based; const opus_int16 *eBands; SAVE_STACK; @@ -521,22 +633,22 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) out_syn[c] = decode_mem[c]+DECODE_BUFFER_SIZE-N; } while (++c_decode_mem+(DECODE_BUFFER_SIZE+overlap)*C); - oldBandE = lpc+C*LPC_ORDER; + oldBandE = lpc+C*CELT_LPC_ORDER; oldLogE = oldBandE + 2*nbEBands; oldLogE2 = oldLogE + 2*nbEBands; backgroundLogE = oldLogE2 + 2*nbEBands; - loss_count = st->loss_count; + loss_duration = st->loss_duration; start = st->start; - noise_based = loss_count >= 5 || start != 0 || st->skip_plc; +#ifdef ENABLE_DEEP_PLC + noise_based = start != 0 || (lpcnet->fec_fill_pos == 0 && (st->skip_plc || loss_duration >= 80)); +#else + noise_based = loss_duration >= 40 || start != 0 || st->skip_plc; +#endif if (noise_based) { /* Noise-based PLC/CNG */ -#ifdef NORM_ALIASING_HACK - celt_norm *X; -#else VARDECL(celt_norm, X); -#endif opus_uint32 seed; int end; int effEnd; @@ -544,16 +656,18 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) end = st->end; effEnd = IMAX(start, IMIN(end, mode->effEBands)); -#ifdef NORM_ALIASING_HACK - /* This is an ugly hack that breaks aliasing rules and would be easily broken, - but it saves almost 4kB of stack. */ - X = (celt_norm*)(out_syn[C-1]+overlap/2); -#else ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ -#endif + c=0; do { + OPUS_MOVE(decode_mem[c], decode_mem[c]+N, + DECODE_BUFFER_SIZE-N+overlap); + } while (++cprefilter_and_fold) { + prefilter_and_fold(st, N); + } /* Energy decay */ - decay = loss_count==0 ? QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT); + decay = loss_duration==0 ? QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT); c=0; do { for (i=start;irng = seed; - c=0; do { - OPUS_MOVE(decode_mem[c], decode_mem[c]+N, - DECODE_BUFFER_SIZE-N+(overlap>>1)); - } while (++cdownsample, 0, st->arch); + st->prefilter_and_fold = 0; + /* Skip regular PLC until we get two consecutive packets. */ + st->skip_plc = 1; } else { int exc_length; /* Pitch-based PLC */ @@ -592,12 +704,14 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) opus_val16 *exc; opus_val16 fade = Q15ONE; int pitch_index; - VARDECL(opus_val32, etmp); VARDECL(opus_val16, _exc); VARDECL(opus_val16, fir_tmp); - if (loss_count == 0) + if (loss_duration == 0) { +#ifdef ENABLE_DEEP_PLC + if (lpcnet->loaded) update_plc_state(lpcnet, decode_mem, &st->plc_preemphasis_mem, C); +#endif st->last_pitch_index = pitch_index = celt_plc_pitch_search(decode_mem, C, st->arch); } else { pitch_index = st->last_pitch_index; @@ -608,10 +722,9 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) decaying signal, but we can't get more than MAX_PERIOD. */ exc_length = IMIN(2*pitch_index, MAX_PERIOD); - ALLOC(etmp, overlap, opus_val32); - ALLOC(_exc, MAX_PERIOD+LPC_ORDER, opus_val16); + ALLOC(_exc, MAX_PERIOD+CELT_LPC_ORDER, opus_val16); ALLOC(fir_tmp, exc_length, opus_val16); - exc = _exc+LPC_ORDER; + exc = _exc+CELT_LPC_ORDER; window = mode->window; c=0; do { opus_val16 decay; @@ -623,16 +736,16 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) int j; buf = decode_mem[c]; - for (i=0;iarch); + CELT_LPC_ORDER, MAX_PERIOD, st->arch); /* Add a noise floor of -40 dB. */ #ifdef FIXED_POINT ac[0] += SHR32(ac[0],13); @@ -640,7 +753,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) ac[0] *= 1.0001f; #endif /* Use lag windowing to stabilize the Levinson-Durbin recursion. */ - for (i=1;i<=LPC_ORDER;i++) + for (i=1;i<=CELT_LPC_ORDER;i++) { /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/ #ifdef FIXED_POINT @@ -649,7 +762,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) ac[i] -= ac[i]*(0.008f*0.008f)*i*i; #endif } - _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER); + _celt_lpc(lpc+c*CELT_LPC_ORDER, ac, CELT_LPC_ORDER); #ifdef FIXED_POINT /* For fixed-point, apply bandwidth expansion until we can guarantee that no overflow can happen in the IIR filter. This means: @@ -657,13 +770,13 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) while (1) { opus_val16 tmp=Q15ONE; opus_val32 sum=QCONST16(1., SIG_SHIFT); - for (i=0;iarch); + celt_fir(exc+MAX_PERIOD-exc_length, lpc+c*CELT_LPC_ORDER, + fir_tmp, exc_length, CELT_LPC_ORDER, st->arch); OPUS_COPY(exc+MAX_PERIOD-exc_length, fir_tmp, exc_length); } @@ -726,21 +839,21 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) exc[extrapolation_offset+j])), SIG_SHIFT); /* Compute the energy of the previously decoded signal whose excitation we're copying. */ - tmp = ROUND16( + tmp = SROUND16( buf[DECODE_BUFFER_SIZE-MAX_PERIOD-N+extrapolation_offset+j], SIG_SHIFT); S1 += SHR32(MULT16_16(tmp, tmp), 10); } { - opus_val16 lpc_mem[LPC_ORDER]; + opus_val16 lpc_mem[CELT_LPC_ORDER]; /* Copy the last decoded samples (prior to the overlap region) to synthesis filter memory so we can have a continuous signal. */ - for (i=0;iarch); #ifdef FIXED_POINT for (i=0; i < extrapolation_len; i++) @@ -755,7 +868,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) opus_val32 S2=0; for (i=0;ipostfilter_period, st->postfilter_period, overlap, - -st->postfilter_gain, -st->postfilter_gain, - st->postfilter_tapset, st->postfilter_tapset, NULL, 0, st->arch); - - /* Simulate TDAC on the concealed audio so that it blends with the - MDCT of the next frame. */ - for (i=0;iloaded && (st->complexity >= 5 || lpcnet->fec_fill_pos > 0)) { + float overlap_mem; + int samples_needed16k; + celt_sig *buf; + VARDECL(float, buf_copy); + buf = decode_mem[0]; + ALLOC(buf_copy, C*overlap, float); + c=0; do { + OPUS_COPY(buf_copy+c*overlap, &decode_mem[c][DECODE_BUFFER_SIZE-N], overlap); + } while (++cplc_fill = 0; + } + while (st->plc_fill < samples_needed16k) { + lpcnet_plc_conceal(lpcnet, &st->plc_pcm[st->plc_fill]); + st->plc_fill += FRAME_SIZE; + } + /* Resample to 48 kHz. */ + for (i=0;i<(N+overlap)/3;i++) { + int j; + float sum; + for (sum=0, j=0;j<17;j++) sum += 3*st->plc_pcm[i+j]*sinc_filter[3*j]; + buf[DECODE_BUFFER_SIZE-N+3*i] = sum; + for (sum=0, j=0;j<16;j++) sum += 3*st->plc_pcm[i+j+1]*sinc_filter[3*j+2]; + buf[DECODE_BUFFER_SIZE-N+3*i+1] = sum; + for (sum=0, j=0;j<16;j++) sum += 3*st->plc_pcm[i+j+1]*sinc_filter[3*j+1]; + buf[DECODE_BUFFER_SIZE-N+3*i+2] = sum; + } + OPUS_MOVE(st->plc_pcm, &st->plc_pcm[N/3], st->plc_fill-N/3); + st->plc_fill -= N/3; + for (i=0;iplc_preemphasis_mem; + st->plc_preemphasis_mem = tmp; + } + overlap_mem = st->plc_preemphasis_mem; + for (i=0;iprefilter_and_fold = 1; } - st->loss_count = loss_count+1; + /* Saturate to soemthing large to avoid wrap-around. */ + st->loss_duration = IMIN(10000, loss_duration+(1<downsample; lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+overlap)*CC); - oldBandE = lpc+CC*LPC_ORDER; + oldBandE = lpc+CC*CELT_LPC_ORDER; oldLogE = oldBandE + 2*nbEBands; oldLogE2 = oldLogE + 2*nbEBands; backgroundLogE = oldLogE2 + 2*nbEBands; @@ -928,15 +1085,25 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat if (data == NULL || len<=1) { - celt_decode_lost(st, N, LM); + celt_decode_lost(st, N, LM +#ifdef ENABLE_DEEP_PLC + , lpcnet +#endif + ); deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, accum); RESTORE_STACK; return frame_size/st->downsample; } +#ifdef ENABLE_DEEP_PLC + else { + /* FIXME: This is a bit of a hack just to make sure opus_decode_native() knows we're no longer in PLC. */ + if (lpcnet) lpcnet->blend = 0; + } +#endif /* Check if there are at least two packets received consecutively before * turning on the pitch-based PLC */ - st->skip_plc = st->loss_count != 0; + if (st->loss_duration == 0) st->skip_plc = 0; if (dec == NULL) { @@ -999,6 +1166,36 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat /* Decode the global flags (first symbols in the stream) */ intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0; + /* If recovering from packet loss, make sure we make the energy prediction safe to reduce the + risk of getting loud artifacts. */ + if (!intra_ener && st->loss_duration != 0) { + c=0; do + { + opus_val16 safety = 0; + int missing = IMIN(10, st->loss_duration>>LM); + if (LM==0) safety = QCONST16(1.5f,DB_SHIFT); + else if (LM==1) safety = QCONST16(.5f,DB_SHIFT); + for (i=start;iprefilter_and_fold) { + prefilter_and_fold(st, N); + } celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd, C, CC, isTransient, LM, st->downsample, silence, st->arch); @@ -1134,25 +1327,21 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat if (C==1) OPUS_COPY(&oldBandE[nbEBands], oldBandE, nbEBands); - /* In case start or end were to change */ if (!isTransient) { - opus_val16 max_background_increase; OPUS_COPY(oldLogE2, oldLogE, 2*nbEBands); OPUS_COPY(oldLogE, oldBandE, 2*nbEBands); - /* In normal circumstances, we only allow the noise floor to increase by - up to 2.4 dB/second, but when we're in DTX, we allow up to 6 dB - increase for each update.*/ - if (st->loss_count < 10) - max_background_increase = M*QCONST16(0.001f,DB_SHIFT); - else - max_background_increase = QCONST16(1.f,DB_SHIFT); - for (i=0;i<2*nbEBands;i++) - backgroundLogE[i] = MIN16(backgroundLogE[i] + max_background_increase, oldBandE[i]); } else { for (i=0;i<2*nbEBands;i++) oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]); } + /* In normal circumstances, we only allow the noise floor to increase by + up to 2.4 dB/second, but when we're in DTX we give the weight of + all missing packets to the update packet. */ + max_background_increase = IMIN(160, st->loss_duration+M)*QCONST16(0.001f,DB_SHIFT); + for (i=0;i<2*nbEBands;i++) + backgroundLogE[i] = MIN16(backgroundLogE[i] + max_background_increase, oldBandE[i]); + /* In case start or end were to change */ c=0; do { for (i=0;irng = dec->rng; deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, accum); - st->loss_count = 0; + st->loss_duration = 0; + st->prefilter_and_fold = 0; RESTORE_STACK; if (ec_tell(dec) > 8*len) return OPUS_INTERNAL_ERROR; @@ -1178,6 +1368,15 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat return frame_size/st->downsample; } +int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, + int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum) +{ + return celt_decode_with_ec_dred(st, data, len, pcm, frame_size, dec, accum +#ifdef ENABLE_DEEP_PLC + , NULL +#endif + ); +} #ifdef CUSTOM_MODES @@ -1251,6 +1450,26 @@ int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...) va_start(ap, request); switch (request) { + case OPUS_SET_COMPLEXITY_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if(value<0 || value>10) + { + goto bad_arg; + } + st->complexity = value; + } + break; + case OPUS_GET_COMPLEXITY_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->complexity; + } + break; case CELT_SET_START_BAND_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); @@ -1297,7 +1516,7 @@ int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...) int i; opus_val16 *lpc, *oldBandE, *oldLogE, *oldLogE2; lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*st->channels); - oldBandE = lpc+st->channels*LPC_ORDER; + oldBandE = lpc+st->channels*CELT_LPC_ORDER; oldLogE = oldBandE + 2*st->mode->nbEBands; oldLogE2 = oldLogE + 2*st->mode->nbEBands; OPUS_CLEAR((char*)&st->DECODER_RESET_START, diff --git a/src/libopus/celt/celt_encoder.c b/src/libopus/celt/celt_encoder.c deleted file mode 100644 index 1fcb6a81..00000000 --- a/src/libopus/celt/celt_encoder.c +++ /dev/null @@ -1,2607 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2010 Xiph.Org Foundation - Copyright (c) 2008 Gregory Maxwell - Written by Jean-Marc Valin and Gregory Maxwell */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif - -#define CELT_ENCODER_C - -#include "cpu_support.h" -#include "os_support.h" -#include "mdct.h" -#include -#include "celt.h" -#include "pitch.h" -#include "bands.h" -#include "modes.h" -#include "entcode.h" -#include "quant_bands.h" -#include "rate.h" -#include "stack_alloc.h" -#include "mathops.h" -#include "float_cast.h" -#include -#include "celt_lpc.h" -#include "vq.h" - - -/** Encoder state - @brief Encoder state - */ -struct OpusCustomEncoder { - const OpusCustomMode *mode; /**< Mode used by the encoder */ - int channels; - int stream_channels; - - int force_intra; - int clip; - int disable_pf; - int complexity; - int upsample; - int start, end; - - opus_int32 bitrate; - int vbr; - int signalling; - int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */ - int loss_rate; - int lsb_depth; - int lfe; - int disable_inv; - int arch; - - /* Everything beyond this point gets cleared on a reset */ -#define ENCODER_RESET_START rng - - opus_uint32 rng; - int spread_decision; - opus_val32 delayedIntra; - int tonal_average; - int lastCodedBands; - int hf_average; - int tapset_decision; - - int prefilter_period; - opus_val16 prefilter_gain; - int prefilter_tapset; -#ifdef RESYNTH - int prefilter_period_old; - opus_val16 prefilter_gain_old; - int prefilter_tapset_old; -#endif - int consec_transient; - AnalysisInfo analysis; - SILKInfo silk_info; - - opus_val32 preemph_memE[2]; - opus_val32 preemph_memD[2]; - - /* VBR-related parameters */ - opus_int32 vbr_reservoir; - opus_int32 vbr_drift; - opus_int32 vbr_offset; - opus_int32 vbr_count; - opus_val32 overlap_max; - opus_val16 stereo_saving; - int intensity; - opus_val16 *energy_mask; - opus_val16 spec_avg; - -#ifdef RESYNTH - /* +MAX_PERIOD/2 to make space for overlap */ - celt_sig syn_mem[2][2*MAX_PERIOD+MAX_PERIOD/2]; -#endif - - celt_sig in_mem[1]; /* Size = channels*mode->overlap */ - /* celt_sig prefilter_mem[], Size = channels*COMBFILTER_MAXPERIOD */ - /* opus_val16 oldBandE[], Size = channels*mode->nbEBands */ - /* opus_val16 oldLogE[], Size = channels*mode->nbEBands */ - /* opus_val16 oldLogE2[], Size = channels*mode->nbEBands */ - /* opus_val16 energyError[], Size = channels*mode->nbEBands */ -}; - -int celt_encoder_get_size(int channels) -{ - CELTMode *mode = opus_custom_mode_create(48000, 960, NULL); - return opus_custom_encoder_get_size(mode, channels); -} - -OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_get_size(const CELTMode *mode, int channels) -{ - int size = sizeof(struct CELTEncoder) - + (channels*mode->overlap-1)*sizeof(celt_sig) /* celt_sig in_mem[channels*mode->overlap]; */ - + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig) /* celt_sig prefilter_mem[channels*COMBFILTER_MAXPERIOD]; */ - + 4*channels*mode->nbEBands*sizeof(opus_val16); /* opus_val16 oldBandE[channels*mode->nbEBands]; */ - /* opus_val16 oldLogE[channels*mode->nbEBands]; */ - /* opus_val16 oldLogE2[channels*mode->nbEBands]; */ - /* opus_val16 energyError[channels*mode->nbEBands]; */ - return size; -} - -#ifdef CUSTOM_MODES -CELTEncoder *opus_custom_encoder_create(const CELTMode *mode, int channels, int *error) -{ - int ret; - CELTEncoder *st = (CELTEncoder *)opus_alloc(opus_custom_encoder_get_size(mode, channels)); - /* init will handle the NULL case */ - ret = opus_custom_encoder_init(st, mode, channels); - if (ret != OPUS_OK) - { - opus_custom_encoder_destroy(st); - st = NULL; - } - if (error) - *error = ret; - return st; -} -#endif /* CUSTOM_MODES */ - -static int opus_custom_encoder_init_arch(CELTEncoder *st, const CELTMode *mode, - int channels, int arch) -{ - if (channels < 0 || channels > 2) - return OPUS_BAD_ARG; - - if (st==NULL || mode==NULL) - return OPUS_ALLOC_FAIL; - - OPUS_CLEAR((char*)st, opus_custom_encoder_get_size(mode, channels)); - - st->mode = mode; - st->stream_channels = st->channels = channels; - - st->upsample = 1; - st->start = 0; - st->end = st->mode->effEBands; - st->signalling = 1; - st->arch = arch; - - st->constrained_vbr = 1; - st->clip = 1; - - st->bitrate = OPUS_BITRATE_MAX; - st->vbr = 0; - st->force_intra = 0; - st->complexity = 5; - st->lsb_depth=24; - - opus_custom_encoder_ctl(st, OPUS_RESET_STATE); - - return OPUS_OK; -} - -#ifdef CUSTOM_MODES -int opus_custom_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels) -{ - return opus_custom_encoder_init_arch(st, mode, channels, opus_select_arch()); -} -#endif - -int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels, - int arch) -{ - int ret; - ret = opus_custom_encoder_init_arch(st, - opus_custom_mode_create(48000, 960, NULL), channels, arch); - if (ret != OPUS_OK) - return ret; - st->upsample = resampling_factor(sampling_rate); - return OPUS_OK; -} - -#ifdef CUSTOM_MODES -void opus_custom_encoder_destroy(CELTEncoder *st) -{ - opus_free(st); -} -#endif /* CUSTOM_MODES */ - - -static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int C, - opus_val16 *tf_estimate, int *tf_chan, int allow_weak_transients, - int *weak_transient) -{ - int i; - VARDECL(opus_val16, tmp); - opus_val32 mem0,mem1; - int is_transient = 0; - opus_int32 mask_metric = 0; - int c; - opus_val16 tf_max; - int len2; - /* Forward masking: 6.7 dB/ms. */ -#ifdef FIXED_POINT - int forward_shift = 4; -#else - opus_val16 forward_decay = QCONST16(.0625f,15); -#endif - /* Table of 6*64/x, trained on real data to minimize the average error */ - static const unsigned char inv_table[128] = { - 255,255,156,110, 86, 70, 59, 51, 45, 40, 37, 33, 31, 28, 26, 25, - 23, 22, 21, 20, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12, - 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, - 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, - }; - SAVE_STACK; - ALLOC(tmp, len, opus_val16); - - *weak_transient = 0; - /* For lower bitrates, let's be more conservative and have a forward masking - decay of 3.3 dB/ms. This avoids having to code transients at very low - bitrate (mostly for hybrid), which can result in unstable energy and/or - partial collapse. */ - if (allow_weak_transients) - { -#ifdef FIXED_POINT - forward_shift = 5; -#else - forward_decay = QCONST16(.03125f,15); -#endif - } - len2=len/2; - for (c=0;c=0;i--) - { - /* Backward masking: 13.9 dB/ms. */ -#ifdef FIXED_POINT - /* FIXME: Use PSHR16() instead */ - tmp[i] = mem0 + PSHR32(tmp[i]-mem0,3); -#else - tmp[i] = mem0 + MULT16_16_P15(QCONST16(0.125f,15),tmp[i]-mem0); -#endif - mem0 = tmp[i]; - maxE = MAX16(maxE, mem0); - } - /*for (i=0;i>1))); -#else - mean = celt_sqrt(mean * maxE*.5*len2); -#endif - /* Inverse of the mean energy in Q15+6 */ - norm = SHL32(EXTEND32(len2),6+14)/ADD32(EPSILON,SHR32(mean,1)); - /* Compute harmonic mean discarding the unreliable boundaries - The data is smooth, so we only take 1/4th of the samples */ - unmask=0; - /* We should never see NaNs here. If we find any, then something really bad happened and we better abort - before it does any damage later on. If these asserts are disabled (no hardening), then the table - lookup a few lines below (id = ...) is likely to crash dur to an out-of-bounds read. DO NOT FIX - that crash on NaN since it could result in a worse issue later on. */ - celt_assert(!celt_isnan(tmp[0])); - celt_assert(!celt_isnan(norm)); - for (i=12;imask_metric) - { - *tf_chan = c; - mask_metric = unmask; - } - } - is_transient = mask_metric>200; - /* For low bitrates, define "weak transients" that need to be - handled differently to avoid partial collapse. */ - if (allow_weak_transients && is_transient && mask_metric<600) { - is_transient = 0; - *weak_transient = 1; - } - /* Arbitrary metric for VBR boost */ - tf_max = MAX16(0,celt_sqrt(27*mask_metric)-42); - /* *tf_estimate = 1 + MIN16(1, sqrt(MAX16(0, tf_max-30))/20); */ - *tf_estimate = celt_sqrt(MAX32(0, SHL32(MULT16_16(QCONST16(0.0069,14),MIN16(163,tf_max)),14)-QCONST32(0.139,28))); - /*printf("%d %f\n", tf_max, mask_metric);*/ - RESTORE_STACK; -#ifdef FUZZING - is_transient = rand()&0x1; -#endif - /*printf("%d %f %d\n", is_transient, (float)*tf_estimate, tf_max);*/ - return is_transient; -} - -/* Looks for sudden increases of energy to decide whether we need to patch - the transient decision */ -static int patch_transient_decision(opus_val16 *newE, opus_val16 *oldE, int nbEBands, - int start, int end, int C) -{ - int i, c; - opus_val32 mean_diff=0; - opus_val16 spread_old[26]; - /* Apply an aggressive (-6 dB/Bark) spreading function to the old frame to - avoid false detection caused by irrelevant bands */ - if (C==1) - { - spread_old[start] = oldE[start]; - for (i=start+1;i=start;i--) - spread_old[i] = MAX16(spread_old[i], spread_old[i+1]-QCONST16(1.0f, DB_SHIFT)); - /* Compute mean increase */ - c=0; do { - for (i=IMAX(2,start);i QCONST16(1.f, DB_SHIFT); -} - -/** Apply window and compute the MDCT for all sub-frames and - all channels in a frame */ -static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig * OPUS_RESTRICT in, - celt_sig * OPUS_RESTRICT out, int C, int CC, int LM, int upsample, - int arch) -{ - const int overlap = mode->overlap; - int N; - int B; - int shift; - int i, b, c; - if (shortBlocks) - { - B = shortBlocks; - N = mode->shortMdctSize; - shift = mode->maxLM; - } else { - B = 1; - N = mode->shortMdctSize<maxLM-LM; - } - c=0; do { - for (b=0;bmdct, in+c*(B*N+overlap)+b*N, - &out[b+c*N*B], mode->window, overlap, shift, B, - arch); - } - } while (++ceBands[len]-m->eBands[len-1])<eBands[len]-m->eBands[len-1])<eBands[i+1]-m->eBands[i])<eBands[i+1]-m->eBands[i])==1; - OPUS_COPY(tmp, &X[tf_chan*N0 + (m->eBands[i]<eBands[i]<>LM, 1<>k, 1<=0;i--) - { - if (tf_res[i+1] == 1) - tf_res[i] = path1[i+1]; - else - tf_res[i] = path0[i+1]; - } - /*printf("%d %f\n", *tf_sum, tf_estimate);*/ - RESTORE_STACK; -#ifdef FUZZING - tf_select = rand()&0x1; - tf_res[0] = rand()&0x1; - for (i=1;istorage*8; - tell = ec_tell(enc); - logp = isTransient ? 2 : 4; - /* Reserve space to code the tf_select decision. */ - tf_select_rsv = LM>0 && tell+logp+1 <= budget; - budget -= tf_select_rsv; - curr = tf_changed = 0; - for (i=start;i> 10; - trim = QCONST16(4.f, 8) + QCONST16(1.f/16.f, 8)*frac; - } - if (C==2) - { - opus_val16 sum = 0; /* Q10 */ - opus_val16 minXC; /* Q10 */ - /* Compute inter-channel correlation for low frequencies */ - for (i=0;i<8;i++) - { - opus_val32 partial; - partial = celt_inner_prod(&X[m->eBands[i]<eBands[i]<eBands[i+1]-m->eBands[i])<eBands[i]<eBands[i]<eBands[i+1]-m->eBands[i])<nbEBands]*(opus_int32)(2+2*i-end); - } - } while (++cvalid) - { - trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8), - (opus_val16)(QCONST16(2.f, 8)*(analysis->tonality_slope+.05f)))); - } -#else - (void)analysis; -#endif - -#ifdef FIXED_POINT - trim_index = PSHR32(trim, 8); -#else - trim_index = (int)floor(.5f+trim); -#endif - trim_index = IMAX(0, IMIN(10, trim_index)); - /*printf("%d\n", trim_index);*/ -#ifdef FUZZING - trim_index = rand()%11; -#endif - return trim_index; -} - -static int stereo_analysis(const CELTMode *m, const celt_norm *X, - int LM, int N0) -{ - int i; - int thetas; - opus_val32 sumLR = EPSILON, sumMS = EPSILON; - - /* Use the L1 norm to model the entropy of the L/R signal vs the M/S signal */ - for (i=0;i<13;i++) - { - int j; - for (j=m->eBands[i]<eBands[i+1]<eBands[13]<<(LM+1))+thetas, sumMS) - > MULT16_32_Q15(m->eBands[13]<<(LM+1), sumLR); -} - -#define MSWAP(a,b) do {opus_val16 tmp = a;a=b;b=tmp;} while(0) -static opus_val16 median_of_5(const opus_val16 *x) -{ - opus_val16 t0, t1, t2, t3, t4; - t2 = x[2]; - if (x[0] > x[1]) - { - t0 = x[1]; - t1 = x[0]; - } else { - t0 = x[0]; - t1 = x[1]; - } - if (x[3] > x[4]) - { - t3 = x[4]; - t4 = x[3]; - } else { - t3 = x[3]; - t4 = x[4]; - } - if (t0 > t3) - { - MSWAP(t0, t3); - MSWAP(t1, t4); - } - if (t2 > t1) - { - if (t1 < t3) - return MIN16(t2, t3); - else - return MIN16(t4, t1); - } else { - if (t2 < t3) - return MIN16(t1, t3); - else - return MIN16(t2, t4); - } -} - -static opus_val16 median_of_3(const opus_val16 *x) -{ - opus_val16 t0, t1, t2; - if (x[0] > x[1]) - { - t0 = x[1]; - t1 = x[0]; - } else { - t0 = x[0]; - t1 = x[1]; - } - t2 = x[2]; - if (t1 < t2) - return t1; - else if (t0 < t2) - return t2; - else - return t0; -} - -static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16 *bandLogE2, - int nbEBands, int start, int end, int C, int *offsets, int lsb_depth, const opus_int16 *logN, - int isTransient, int vbr, int constrained_vbr, const opus_int16 *eBands, int LM, - int effectiveBytes, opus_int32 *tot_boost_, int lfe, opus_val16 *surround_dynalloc, - AnalysisInfo *analysis, int *importance, int *spread_weight) -{ - int i, c; - opus_int32 tot_boost=0; - opus_val16 maxDepth; - VARDECL(opus_val16, follower); - VARDECL(opus_val16, noise_floor); - SAVE_STACK; - ALLOC(follower, C*nbEBands, opus_val16); - ALLOC(noise_floor, C*nbEBands, opus_val16); - OPUS_CLEAR(offsets, nbEBands); - /* Dynamic allocation code */ - maxDepth=-QCONST16(31.9f, DB_SHIFT); - for (i=0;i=0;i--) - mask[i] = MAX16(mask[i], mask[i+1] - QCONST16(3.f, DB_SHIFT)); - for (i=0;i> shift; - } - /*for (i=0;i 50 && LM>=1 && !lfe) - { - int last=0; - c=0;do - { - opus_val16 offset; - opus_val16 tmp; - opus_val16 *f; - f = &follower[c*nbEBands]; - f[0] = bandLogE2[c*nbEBands]; - for (i=1;i bandLogE2[c*nbEBands+i-1]+QCONST16(.5f,DB_SHIFT)) - last=i; - f[i] = MIN16(f[i-1]+QCONST16(1.5f,DB_SHIFT), bandLogE2[c*nbEBands+i]); - } - for (i=last-1;i>=0;i--) - f[i] = MIN16(f[i], MIN16(f[i+1]+QCONST16(2.f,DB_SHIFT), bandLogE2[c*nbEBands+i])); - - /* Combine with a median filter to avoid dynalloc triggering unnecessarily. - The "offset" value controls how conservative we are -- a higher offset - reduces the impact of the median filter and makes dynalloc use more bits. */ - offset = QCONST16(1.f, DB_SHIFT); - for (i=2;i=12) - follower[i] = HALF16(follower[i]); - } -#ifdef DISABLE_FLOAT_API - (void)analysis; -#else - if (analysis->valid) - { - for (i=start;ileak_boost[i]; - } -#endif - for (i=start;i 48) { - boost = (int)SHR32(EXTEND32(follower[i])*8,DB_SHIFT); - boost_bits = (boost*width<>BITRES>>3 > 2*effectiveBytes/3) - { - opus_int32 cap = ((2*effectiveBytes/3)<mode; - overlap = mode->overlap; - ALLOC(_pre, CC*(N+COMBFILTER_MAXPERIOD), celt_sig); - - pre[0] = _pre; - pre[1] = _pre + (N+COMBFILTER_MAXPERIOD); - - - c=0; do { - OPUS_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD); - OPUS_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+overlap)+overlap, N); - } while (++c>1, opus_val16); - - pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, CC, st->arch); - /* Don't search for the fir last 1.5 octave of the range because - there's too many false-positives due to short-term correlation */ - pitch_search(pitch_buf+(COMBFILTER_MAXPERIOD>>1), pitch_buf, N, - COMBFILTER_MAXPERIOD-3*COMBFILTER_MINPERIOD, &pitch_index, - st->arch); - pitch_index = COMBFILTER_MAXPERIOD-pitch_index; - - gain1 = remove_doubling(pitch_buf, COMBFILTER_MAXPERIOD, COMBFILTER_MINPERIOD, - N, &pitch_index, st->prefilter_period, st->prefilter_gain, st->arch); - if (pitch_index > COMBFILTER_MAXPERIOD-2) - pitch_index = COMBFILTER_MAXPERIOD-2; - gain1 = MULT16_16_Q15(QCONST16(.7f,15),gain1); - /*printf("%d %d %f %f\n", pitch_change, pitch_index, gain1, st->analysis.tonality);*/ - if (st->loss_rate>2) - gain1 = HALF32(gain1); - if (st->loss_rate>4) - gain1 = HALF32(gain1); - if (st->loss_rate>8) - gain1 = 0; - } else { - gain1 = 0; - pitch_index = COMBFILTER_MINPERIOD; - } -#ifndef DISABLE_FLOAT_API - if (analysis->valid) - gain1 = (opus_val16)(gain1 * analysis->max_pitch_ratio); -#else - (void)analysis; -#endif - /* Gain threshold for enabling the prefilter/postfilter */ - pf_threshold = QCONST16(.2f,15); - - /* Adjusting the threshold based on rate and continuity */ - if (abs(pitch_index-st->prefilter_period)*10>pitch_index) - pf_threshold += QCONST16(.2f,15); - if (nbAvailableBytes<25) - pf_threshold += QCONST16(.1f,15); - if (nbAvailableBytes<35) - pf_threshold += QCONST16(.1f,15); - if (st->prefilter_gain > QCONST16(.4f,15)) - pf_threshold -= QCONST16(.1f,15); - if (st->prefilter_gain > QCONST16(.55f,15)) - pf_threshold -= QCONST16(.1f,15); - - /* Hard threshold at 0.2 */ - pf_threshold = MAX16(pf_threshold, QCONST16(.2f,15)); - if (gain1prefilter_gain)prefilter_gain; - -#ifdef FIXED_POINT - qg = ((gain1+1536)>>10)/3-1; -#else - qg = (int)floor(.5f+gain1*32/3)-1; -#endif - qg = IMAX(0, IMIN(7, qg)); - gain1 = QCONST16(0.09375f,15)*(qg+1); - pf_on = 1; - } - /*printf("%d %f\n", pitch_index, gain1);*/ - - c=0; do { - int offset = mode->shortMdctSize-overlap; - st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD); - OPUS_COPY(in+c*(N+overlap), st->in_mem+c*(overlap), overlap); - if (offset) - comb_filter(in+c*(N+overlap)+overlap, pre[c]+COMBFILTER_MAXPERIOD, - st->prefilter_period, st->prefilter_period, offset, -st->prefilter_gain, -st->prefilter_gain, - st->prefilter_tapset, st->prefilter_tapset, NULL, 0, st->arch); - - comb_filter(in+c*(N+overlap)+overlap+offset, pre[c]+COMBFILTER_MAXPERIOD+offset, - st->prefilter_period, pitch_index, N-offset, -st->prefilter_gain, -gain1, - st->prefilter_tapset, prefilter_tapset, mode->window, overlap, st->arch); - OPUS_COPY(st->in_mem+c*(overlap), in+c*(N+overlap)+N, overlap); - - if (N>COMBFILTER_MAXPERIOD) - { - OPUS_COPY(prefilter_mem+c*COMBFILTER_MAXPERIOD, pre[c]+N, COMBFILTER_MAXPERIOD); - } else { - OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, prefilter_mem+c*COMBFILTER_MAXPERIOD+N, COMBFILTER_MAXPERIOD-N); - OPUS_COPY(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N); - } - } while (++cnbEBands; - eBands = mode->eBands; - - coded_bands = lastCodedBands ? lastCodedBands : nbEBands; - coded_bins = eBands[coded_bands]<analysis.activity, st->analysis.tonality, tf_estimate, st->stereo_saving, tot_boost, coded_bands);*/ -#ifndef DISABLE_FLOAT_API - if (analysis->valid && analysis->activity<.4) - target -= (opus_int32)((coded_bins<activity)); -#endif - /* Stereo savings */ - if (C==2) - { - int coded_stereo_bands; - int coded_stereo_dof; - opus_val16 max_frac; - coded_stereo_bands = IMIN(intensity, coded_bands); - coded_stereo_dof = (eBands[coded_stereo_bands]<valid && !lfe) - { - opus_int32 tonal_target; - float tonal; - - /* Tonality boost (compensating for the average). */ - tonal = MAX16(0.f,analysis->tonality-.15f)-0.12f; - tonal_target = target + (opus_int32)((coded_bins<tonality, tonal);*/ - target = tonal_target; - } -#else - (void)analysis; - (void)pitch_change; -#endif - - if (has_surround_mask&&!lfe) - { - opus_int32 surround_target = target + (opus_int32)SHR32(MULT16_16(surround_masking,coded_bins<end, st->intensity, surround_target, target, st->bitrate);*/ - target = IMAX(target/4, surround_target); - } - - { - opus_int32 floor_depth; - int bins; - bins = eBands[nbEBands-2]<>2); - target = IMIN(target, floor_depth); - /*printf("%f %d\n", maxDepth, floor_depth);*/ - } - - /* Make VBR less aggressive for constrained VBR because we can't keep a higher bitrate - for long. Needs tuning. */ - if ((!has_surround_mask||lfe) && constrained_vbr) - { - target = base_target + (opus_int32)MULT16_32_Q15(QCONST16(0.67f, 15), target-base_target); - } - - if (!has_surround_mask && tf_estimate < QCONST16(.2f, 14)) - { - opus_val16 amount; - opus_val16 tvbr_factor; - amount = MULT16_16_Q15(QCONST16(.0000031f, 30), IMAX(0, IMIN(32000, 96000-bitrate))); - tvbr_factor = SHR32(MULT16_16(temporal_vbr, amount), DB_SHIFT); - target += (opus_int32)MULT16_32_Q15(tvbr_factor, target); - } - - /* Don't allow more than doubling the rate */ - target = IMIN(2*base_target, target); - - return target; -} - -int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc) -{ - int i, c, N; - opus_int32 bits; - ec_enc _enc; - VARDECL(celt_sig, in); - VARDECL(celt_sig, freq); - VARDECL(celt_norm, X); - VARDECL(celt_ener, bandE); - VARDECL(opus_val16, bandLogE); - VARDECL(opus_val16, bandLogE2); - VARDECL(int, fine_quant); - VARDECL(opus_val16, error); - VARDECL(int, pulses); - VARDECL(int, cap); - VARDECL(int, offsets); - VARDECL(int, importance); - VARDECL(int, spread_weight); - VARDECL(int, fine_priority); - VARDECL(int, tf_res); - VARDECL(unsigned char, collapse_masks); - celt_sig *prefilter_mem; - opus_val16 *oldBandE, *oldLogE, *oldLogE2, *energyError; - int shortBlocks=0; - int isTransient=0; - const int CC = st->channels; - const int C = st->stream_channels; - int LM, M; - int tf_select; - int nbFilledBytes, nbAvailableBytes; - int start; - int end; - int effEnd; - int codedBands; - int alloc_trim; - int pitch_index=COMBFILTER_MINPERIOD; - opus_val16 gain1 = 0; - int dual_stereo=0; - int effectiveBytes; - int dynalloc_logp; - opus_int32 vbr_rate; - opus_int32 total_bits; - opus_int32 total_boost; - opus_int32 balance; - opus_int32 tell; - opus_int32 tell0_frac; - int prefilter_tapset=0; - int pf_on; - int anti_collapse_rsv; - int anti_collapse_on=0; - int silence=0; - int tf_chan = 0; - opus_val16 tf_estimate; - int pitch_change=0; - opus_int32 tot_boost; - opus_val32 sample_max; - opus_val16 maxDepth; - const OpusCustomMode *mode; - int nbEBands; - int overlap; - const opus_int16 *eBands; - int secondMdct; - int signalBandwidth; - int transient_got_disabled=0; - opus_val16 surround_masking=0; - opus_val16 temporal_vbr=0; - opus_val16 surround_trim = 0; - opus_int32 equiv_rate; - int hybrid; - int weak_transient = 0; - int enable_tf_analysis; - VARDECL(opus_val16, surround_dynalloc); - ALLOC_STACK; - - mode = st->mode; - nbEBands = mode->nbEBands; - overlap = mode->overlap; - eBands = mode->eBands; - start = st->start; - end = st->end; - hybrid = start != 0; - tf_estimate = 0; - if (nbCompressedBytes<2 || pcm==NULL) - { - RESTORE_STACK; - return OPUS_BAD_ARG; - } - - frame_size *= st->upsample; - for (LM=0;LM<=mode->maxLM;LM++) - if (mode->shortMdctSize<mode->maxLM) - { - RESTORE_STACK; - return OPUS_BAD_ARG; - } - M=1<shortMdctSize; - - prefilter_mem = st->in_mem+CC*(overlap); - oldBandE = (opus_val16*)(st->in_mem+CC*(overlap+COMBFILTER_MAXPERIOD)); - oldLogE = oldBandE + CC*nbEBands; - oldLogE2 = oldLogE + CC*nbEBands; - energyError = oldLogE2 + CC*nbEBands; - - if (enc==NULL) - { - tell0_frac=tell=1; - nbFilledBytes=0; - } else { - tell0_frac=ec_tell_frac(enc); - tell=ec_tell(enc); - nbFilledBytes=(tell+4)>>3; - } - -#ifdef CUSTOM_MODES - if (st->signalling && enc==NULL) - { - int tmp = (mode->effEBands-end)>>1; - end = st->end = IMAX(1, mode->effEBands-tmp); - compressed[0] = tmp<<5; - compressed[0] |= LM<<3; - compressed[0] |= (C==2)<<2; - /* Convert "standard mode" to Opus header */ - if (mode->Fs==48000 && mode->shortMdctSize==120) - { - int c0 = toOpus(compressed[0]); - if (c0<0) - { - RESTORE_STACK; - return OPUS_BAD_ARG; - } - compressed[0] = c0; - } - compressed++; - nbCompressedBytes--; - } -#else - celt_assert(st->signalling==0); -#endif - - /* Can't produce more than 1275 output bytes */ - nbCompressedBytes = IMIN(nbCompressedBytes,1275); - nbAvailableBytes = nbCompressedBytes - nbFilledBytes; - - if (st->vbr && st->bitrate!=OPUS_BITRATE_MAX) - { - opus_int32 den=mode->Fs>>BITRES; - vbr_rate=(st->bitrate*frame_size+(den>>1))/den; -#ifdef CUSTOM_MODES - if (st->signalling) - vbr_rate -= 8<>(3+BITRES); - } else { - opus_int32 tmp; - vbr_rate = 0; - tmp = st->bitrate*frame_size; - if (tell>1) - tmp += tell; - if (st->bitrate!=OPUS_BITRATE_MAX) - nbCompressedBytes = IMAX(2, IMIN(nbCompressedBytes, - (tmp+4*mode->Fs)/(8*mode->Fs)-!!st->signalling)); - effectiveBytes = nbCompressedBytes - nbFilledBytes; - } - equiv_rate = ((opus_int32)nbCompressedBytes*8*50 >> (3-LM)) - (40*C+20)*((400>>LM) - 50); - if (st->bitrate != OPUS_BITRATE_MAX) - equiv_rate = IMIN(equiv_rate, st->bitrate - (40*C+20)*((400>>LM) - 50)); - - if (enc==NULL) - { - ec_enc_init(&_enc, compressed, nbCompressedBytes); - enc = &_enc; - } - - if (vbr_rate>0) - { - /* Computes the max bit-rate allowed in VBR mode to avoid violating the - target rate and buffering. - We must do this up front so that bust-prevention logic triggers - correctly if we don't have enough bits. */ - if (st->constrained_vbr) - { - opus_int32 vbr_bound; - opus_int32 max_allowed; - /* We could use any multiple of vbr_rate as bound (depending on the - delay). - This is clamped to ensure we use at least two bytes if the encoder - was entirely empty, but to allow 0 in hybrid mode. */ - vbr_bound = vbr_rate; - max_allowed = IMIN(IMAX(tell==1?2:0, - (vbr_rate+vbr_bound-st->vbr_reservoir)>>(BITRES+3)), - nbAvailableBytes); - if(max_allowed < nbAvailableBytes) - { - nbCompressedBytes = nbFilledBytes+max_allowed; - nbAvailableBytes = max_allowed; - ec_enc_shrink(enc, nbCompressedBytes); - } - } - } - total_bits = nbCompressedBytes*8; - - effEnd = end; - if (effEnd > mode->effEBands) - effEnd = mode->effEBands; - - ALLOC(in, CC*(N+overlap), celt_sig); - - sample_max=MAX32(st->overlap_max, celt_maxabs16(pcm, C*(N-overlap)/st->upsample)); - st->overlap_max=celt_maxabs16(pcm+C*(N-overlap)/st->upsample, C*overlap/st->upsample); - sample_max=MAX32(sample_max, st->overlap_max); -#ifdef FIXED_POINT - silence = (sample_max==0); -#else - silence = (sample_max <= (opus_val16)1/(1<lsb_depth)); -#endif -#ifdef FUZZING - if ((rand()&0x3F)==0) - silence = 1; -#endif - if (tell==1) - ec_enc_bit_logp(enc, silence, 15); - else - silence=0; - if (silence) - { - /*In VBR mode there is no need to send more than the minimum. */ - if (vbr_rate>0) - { - effectiveBytes=nbCompressedBytes=IMIN(nbCompressedBytes, nbFilledBytes+2); - total_bits=nbCompressedBytes*8; - nbAvailableBytes=2; - ec_enc_shrink(enc, nbCompressedBytes); - } - /* Pretend we've filled all the remaining bits with zeros - (that's what the initialiser did anyway) */ - tell = nbCompressedBytes*8; - enc->nbits_total+=tell-ec_tell(enc); - } - c=0; do { - int need_clip=0; -#ifndef FIXED_POINT - need_clip = st->clip && sample_max>65536.f; -#endif - celt_preemphasis(pcm+c, in+c*(N+overlap)+overlap, N, CC, st->upsample, - mode->preemph, st->preemph_memE+c, need_clip); - } while (++clfe&&nbAvailableBytes>3) || nbAvailableBytes>12*C) && !hybrid && !silence && !st->disable_pf - && st->complexity >= 5; - - prefilter_tapset = st->tapset_decision; - pf_on = run_prefilter(st, in, prefilter_mem, CC, N, prefilter_tapset, &pitch_index, &gain1, &qg, enabled, nbAvailableBytes, &st->analysis); - if ((gain1 > QCONST16(.4f,15) || st->prefilter_gain > QCONST16(.4f,15)) && (!st->analysis.valid || st->analysis.tonality > .3) - && (pitch_index > 1.26*st->prefilter_period || pitch_index < .79*st->prefilter_period)) - pitch_change = 1; - if (pf_on==0) - { - if(!hybrid && tell+16<=total_bits) - ec_enc_bit_logp(enc, 0, 1); - } else { - /*This block is not gated by a total bits check only because - of the nbAvailableBytes check above.*/ - int octave; - ec_enc_bit_logp(enc, 1, 1); - pitch_index += 1; - octave = EC_ILOG(pitch_index)-5; - ec_enc_uint(enc, octave, 6); - ec_enc_bits(enc, pitch_index-(16<complexity >= 1 && !st->lfe) - { - /* Reduces the likelihood of energy instability on fricatives at low bitrate - in hybrid mode. It seems like we still want to have real transients on vowels - though (small SILK quantization offset value). */ - int allow_weak_transients = hybrid && effectiveBytes<15 && st->silk_info.signalType != 2; - isTransient = transient_analysis(in, N+overlap, CC, - &tf_estimate, &tf_chan, allow_weak_transients, &weak_transient); - } - if (LM>0 && ec_tell(enc)+3<=total_bits) - { - if (isTransient) - shortBlocks = M; - } else { - isTransient = 0; - transient_got_disabled=1; - } - - ALLOC(freq, CC*N, celt_sig); /**< Interleaved signal MDCTs */ - ALLOC(bandE,nbEBands*CC, celt_ener); - ALLOC(bandLogE,nbEBands*CC, opus_val16); - - secondMdct = shortBlocks && st->complexity>=8; - ALLOC(bandLogE2, C*nbEBands, opus_val16); - if (secondMdct) - { - compute_mdcts(mode, 0, in, freq, C, CC, LM, st->upsample, st->arch); - compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch); - amp2Log2(mode, effEnd, end, bandE, bandLogE2, C); - for (i=0;iupsample, st->arch); - /* This should catch any NaN in the CELT input. Since we're not supposed to see any (they're filtered - at the Opus layer), just abort. */ - celt_assert(!celt_isnan(freq[0]) && (C==1 || !celt_isnan(freq[N]))); - if (CC==2&&C==1) - tf_chan = 0; - compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch); - - if (st->lfe) - { - for (i=2;ienergy_mask&&!st->lfe) - { - int mask_end; - int midband; - int count_dynalloc; - opus_val32 mask_avg=0; - opus_val32 diff=0; - int count=0; - mask_end = IMAX(2,st->lastCodedBands); - for (c=0;cenergy_mask[nbEBands*c+i], - QCONST16(.25f, DB_SHIFT)), -QCONST16(2.0f, DB_SHIFT)); - if (mask > 0) - mask = HALF16(mask); - mask_avg += MULT16_16(mask, eBands[i+1]-eBands[i]); - count += eBands[i+1]-eBands[i]; - diff += MULT16_16(mask, 1+2*i-mask_end); - } - } - celt_assert(count>0); - mask_avg = DIV32_16(mask_avg,count); - mask_avg += QCONST16(.2f, DB_SHIFT); - diff = diff*6/(C*(mask_end-1)*(mask_end+1)*mask_end); - /* Again, being conservative */ - diff = HALF32(diff); - diff = MAX32(MIN32(diff, QCONST32(.031f, DB_SHIFT)), -QCONST32(.031f, DB_SHIFT)); - /* Find the band that's in the middle of the coded spectrum */ - for (midband=0;eBands[midband+1] < eBands[mask_end]/2;midband++); - count_dynalloc=0; - for(i=0;ienergy_mask[i], st->energy_mask[nbEBands+i]); - else - unmask = st->energy_mask[i]; - unmask = MIN16(unmask, QCONST16(.0f, DB_SHIFT)); - unmask -= lin; - if (unmask > QCONST16(.25f, DB_SHIFT)) - { - surround_dynalloc[i] = unmask - QCONST16(.25f, DB_SHIFT); - count_dynalloc++; - } - } - if (count_dynalloc>=3) - { - /* If we need dynalloc in many bands, it's probably because our - initial masking rate was too low. */ - mask_avg += QCONST16(.25f, DB_SHIFT); - if (mask_avg>0) - { - /* Something went really wrong in the original calculations, - disabling masking. */ - mask_avg = 0; - diff = 0; - OPUS_CLEAR(surround_dynalloc, mask_end); - } else { - for(i=0;ilfe) - { - opus_val16 follow=-QCONST16(10.0f,DB_SHIFT); - opus_val32 frame_avg=0; - opus_val16 offset = shortBlocks?HALF16(SHL16(LM, DB_SHIFT)):0; - for(i=start;ispec_avg); - temporal_vbr = MIN16(QCONST16(3.f, DB_SHIFT), MAX16(-QCONST16(1.5f, DB_SHIFT), temporal_vbr)); - st->spec_avg += MULT16_16_Q15(QCONST16(.02f, 15), temporal_vbr); - } - /*for (i=0;i<21;i++) - printf("%f ", bandLogE[i]); - printf("\n");*/ - - if (!secondMdct) - { - OPUS_COPY(bandLogE2, bandLogE, C*nbEBands); - } - - /* Last chance to catch any transient we might have missed in the - time-domain analysis */ - if (LM>0 && ec_tell(enc)+3<=total_bits && !isTransient && st->complexity>=5 && !st->lfe && !hybrid) - { - if (patch_transient_decision(bandLogE, oldBandE, nbEBands, start, end, C)) - { - isTransient = 1; - shortBlocks = M; - compute_mdcts(mode, shortBlocks, in, freq, C, CC, LM, st->upsample, st->arch); - compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch); - amp2Log2(mode, effEnd, end, bandE, bandLogE, C); - /* Compensate for the scaling of short vs long mdcts */ - for (i=0;i0 && ec_tell(enc)+3<=total_bits) - ec_enc_bit_logp(enc, isTransient, 3); - - ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ - - /* Band normalisation */ - normalise_bands(mode, freq, X, bandE, effEnd, C, M); - - enable_tf_analysis = effectiveBytes>=15*C && !hybrid && st->complexity>=2 && !st->lfe; - - ALLOC(offsets, nbEBands, int); - ALLOC(importance, nbEBands, int); - ALLOC(spread_weight, nbEBands, int); - - maxDepth = dynalloc_analysis(bandLogE, bandLogE2, nbEBands, start, end, C, offsets, - st->lsb_depth, mode->logN, isTransient, st->vbr, st->constrained_vbr, - eBands, LM, effectiveBytes, &tot_boost, st->lfe, surround_dynalloc, &st->analysis, importance, spread_weight); - - ALLOC(tf_res, nbEBands, int); - /* Disable variable tf resolution for hybrid and at very low bitrate */ - if (enable_tf_analysis) - { - int lambda; - lambda = IMAX(80, 20480/effectiveBytes + 2); - tf_select = tf_analysis(mode, effEnd, isTransient, tf_res, lambda, X, N, LM, tf_estimate, tf_chan, importance); - for (i=effEnd;isilk_info.signalType != 2) - { - /* For low bitrate hybrid, we force temporal resolution to 5 ms rather than 2.5 ms. */ - for (i=0;iforce_intra, - &st->delayedIntra, st->complexity >= 4, st->loss_rate, st->lfe); - - tf_encode(start, end, isTransient, tf_res, LM, tf_select, enc); - - if (ec_tell(enc)+4<=total_bits) - { - if (st->lfe) - { - st->tapset_decision = 0; - st->spread_decision = SPREAD_NORMAL; - } else if (hybrid) - { - if (st->complexity == 0) - st->spread_decision = SPREAD_NONE; - else if (isTransient) - st->spread_decision = SPREAD_NORMAL; - else - st->spread_decision = SPREAD_AGGRESSIVE; - } else if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C) - { - if (st->complexity == 0) - st->spread_decision = SPREAD_NONE; - else - st->spread_decision = SPREAD_NORMAL; - } else { - /* Disable new spreading+tapset estimator until we can show it works - better than the old one. So far it seems like spreading_decision() - works best. */ -#if 0 - if (st->analysis.valid) - { - static const opus_val16 spread_thresholds[3] = {-QCONST16(.6f, 15), -QCONST16(.2f, 15), -QCONST16(.07f, 15)}; - static const opus_val16 spread_histeresis[3] = {QCONST16(.15f, 15), QCONST16(.07f, 15), QCONST16(.02f, 15)}; - static const opus_val16 tapset_thresholds[2] = {QCONST16(.0f, 15), QCONST16(.15f, 15)}; - static const opus_val16 tapset_histeresis[2] = {QCONST16(.1f, 15), QCONST16(.05f, 15)}; - st->spread_decision = hysteresis_decision(-st->analysis.tonality, spread_thresholds, spread_histeresis, 3, st->spread_decision); - st->tapset_decision = hysteresis_decision(st->analysis.tonality_slope, tapset_thresholds, tapset_histeresis, 2, st->tapset_decision); - } else -#endif - { - st->spread_decision = spreading_decision(mode, X, - &st->tonal_average, st->spread_decision, &st->hf_average, - &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M, spread_weight); - } - /*printf("%d %d\n", st->tapset_decision, st->spread_decision);*/ - /*printf("%f %d %f %d\n\n", st->analysis.tonality, st->spread_decision, st->analysis.tonality_slope, st->tapset_decision);*/ - } - ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5); - } - - /* For LFE, everything interesting is in the first band */ - if (st->lfe) - offsets[0] = IMIN(8, effectiveBytes/3); - ALLOC(cap, nbEBands, int); - init_caps(mode,cap,LM,C); - - dynalloc_logp = 6; - total_bits<<=BITRES; - total_boost = 0; - tell = ec_tell_frac(enc); - for (i=start;iintensity = hysteresis_decision((opus_val16)(equiv_rate/1000), - intensity_thresholds, intensity_histeresis, 21, st->intensity); - st->intensity = IMIN(end,IMAX(start, st->intensity)); - } - - alloc_trim = 5; - if (tell+(6< 0 || st->lfe) - { - st->stereo_saving = 0; - alloc_trim = 5; - } else { - alloc_trim = alloc_trim_analysis(mode, X, bandLogE, - end, LM, C, N, &st->analysis, &st->stereo_saving, tf_estimate, - st->intensity, surround_trim, equiv_rate, st->arch); - } - ec_enc_icdf(enc, alloc_trim, trim_icdf, 7); - tell = ec_tell_frac(enc); - } - - /* Variable bitrate */ - if (vbr_rate>0) - { - opus_val16 alpha; - opus_int32 delta; - /* The target rate in 8th bits per frame */ - opus_int32 target, base_target; - opus_int32 min_allowed; - int lm_diff = mode->maxLM - LM; - - /* Don't attempt to use more than 510 kb/s, even for frames smaller than 20 ms. - The CELT allocator will just not be able to use more than that anyway. */ - nbCompressedBytes = IMIN(nbCompressedBytes,1275>>(3-LM)); - if (!hybrid) - { - base_target = vbr_rate - ((40*C+20)<constrained_vbr) - base_target += (st->vbr_offset>>lm_diff); - - if (!hybrid) - { - target = compute_vbr(mode, &st->analysis, base_target, LM, equiv_rate, - st->lastCodedBands, C, st->intensity, st->constrained_vbr, - st->stereo_saving, tot_boost, tf_estimate, pitch_change, maxDepth, - st->lfe, st->energy_mask!=NULL, surround_masking, - temporal_vbr); - } else { - target = base_target; - /* Tonal frames (offset<100) need more bits than noisy (offset>100) ones. */ - if (st->silk_info.offset < 100) target += 12 << BITRES >> (3-LM); - if (st->silk_info.offset > 100) target -= 18 << BITRES >> (3-LM); - /* Boosting bitrate on transients and vowels with significant temporal - spikes. */ - target += (opus_int32)MULT16_16_Q14(tf_estimate-QCONST16(.25f,14), (50< QCONST16(.7f,14)) - target = IMAX(target, 50<>(BITRES+3)) + 2; - /* Take into account the 37 bits we need to have left in the packet to - signal a redundant frame in hybrid mode. Creating a shorter packet would - create an entropy coder desync. */ - if (hybrid) - min_allowed = IMAX(min_allowed, (tell0_frac+(37<>(BITRES+3)); - - nbAvailableBytes = (target+(1<<(BITRES+2)))>>(BITRES+3); - nbAvailableBytes = IMAX(min_allowed,nbAvailableBytes); - nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes); - - /* By how much did we "miss" the target on that frame */ - delta = target - vbr_rate; - - target=nbAvailableBytes<<(BITRES+3); - - /*If the frame is silent we don't adjust our drift, otherwise - the encoder will shoot to very high rates after hitting a - span of silence, but we do allow the bitres to refill. - This means that we'll undershoot our target in CVBR/VBR modes - on files with lots of silence. */ - if(silence) - { - nbAvailableBytes = 2; - target = 2*8<vbr_count < 970) - { - st->vbr_count++; - alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+20),16)); - } else - alpha = QCONST16(.001f,15); - /* How many bits have we used in excess of what we're allowed */ - if (st->constrained_vbr) - st->vbr_reservoir += target - vbr_rate; - /*printf ("%d\n", st->vbr_reservoir);*/ - - /* Compute the offset we need to apply in order to reach the target */ - if (st->constrained_vbr) - { - st->vbr_drift += (opus_int32)MULT16_32_Q15(alpha,(delta*(1<vbr_offset-st->vbr_drift); - st->vbr_offset = -st->vbr_drift; - } - /*printf ("%d\n", st->vbr_drift);*/ - - if (st->constrained_vbr && st->vbr_reservoir < 0) - { - /* We're under the min value -- increase rate */ - int adjust = (-st->vbr_reservoir)/(8<vbr_reservoir = 0; - /*printf ("+%d\n", adjust);*/ - } - nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes); - /*printf("%d\n", nbCompressedBytes*50*8);*/ - /* This moves the raw bits to take into account the new compressed size */ - ec_enc_shrink(enc, nbCompressedBytes); - } - - /* Bit allocation */ - ALLOC(fine_quant, nbEBands, int); - ALLOC(pulses, nbEBands, int); - ALLOC(fine_priority, nbEBands, int); - - /* bits = packet size - where we are - safety*/ - bits = (((opus_int32)nbCompressedBytes*8)<=2&&bits>=((LM+2)<analysis.valid) - { - int min_bandwidth; - if (equiv_rate < (opus_int32)32000*C) - min_bandwidth = 13; - else if (equiv_rate < (opus_int32)48000*C) - min_bandwidth = 16; - else if (equiv_rate < (opus_int32)60000*C) - min_bandwidth = 18; - else if (equiv_rate < (opus_int32)80000*C) - min_bandwidth = 19; - else - min_bandwidth = 20; - signalBandwidth = IMAX(st->analysis.bandwidth, min_bandwidth); - } -#endif - if (st->lfe) - signalBandwidth = 1; - codedBands = clt_compute_allocation(mode, start, end, offsets, cap, - alloc_trim, &st->intensity, &dual_stereo, bits, &balance, pulses, - fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands, signalBandwidth); - if (st->lastCodedBands) - st->lastCodedBands = IMIN(st->lastCodedBands+1,IMAX(st->lastCodedBands-1,codedBands)); - else - st->lastCodedBands = codedBands; - - quant_fine_energy(mode, start, end, oldBandE, error, fine_quant, enc, C); - - /* Residual quantisation */ - ALLOC(collapse_masks, C*nbEBands, unsigned char); - quant_all_bands(1, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks, - bandE, pulses, shortBlocks, st->spread_decision, - dual_stereo, st->intensity, tf_res, nbCompressedBytes*(8<rng, st->complexity, st->arch, st->disable_inv); - - if (anti_collapse_rsv > 0) - { - anti_collapse_on = st->consec_transient<2; -#ifdef FUZZING - anti_collapse_on = rand()&0x1; -#endif - ec_enc_bits(enc, anti_collapse_on, 1); - } - quant_energy_finalise(mode, start, end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C); - OPUS_CLEAR(energyError, nbEBands*CC); - c=0; - do { - for (i=start;irng); - } - - c=0; do { - OPUS_MOVE(st->syn_mem[c], st->syn_mem[c]+N, 2*MAX_PERIOD-N+overlap/2); - } while (++csyn_mem[c]+2*MAX_PERIOD-N; - } while (++cupsample, silence, st->arch); - - c=0; do { - st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD); - st->prefilter_period_old=IMAX(st->prefilter_period_old, COMBFILTER_MINPERIOD); - comb_filter(out_mem[c], out_mem[c], st->prefilter_period_old, st->prefilter_period, mode->shortMdctSize, - st->prefilter_gain_old, st->prefilter_gain, st->prefilter_tapset_old, st->prefilter_tapset, - mode->window, overlap); - if (LM!=0) - comb_filter(out_mem[c]+mode->shortMdctSize, out_mem[c]+mode->shortMdctSize, st->prefilter_period, pitch_index, N-mode->shortMdctSize, - st->prefilter_gain, gain1, st->prefilter_tapset, prefilter_tapset, - mode->window, overlap); - } while (++cupsample, mode->preemph, st->preemph_memD); - st->prefilter_period_old = st->prefilter_period; - st->prefilter_gain_old = st->prefilter_gain; - st->prefilter_tapset_old = st->prefilter_tapset; - } -#endif - - st->prefilter_period = pitch_index; - st->prefilter_gain = gain1; - st->prefilter_tapset = prefilter_tapset; -#ifdef RESYNTH - if (LM!=0) - { - st->prefilter_period_old = st->prefilter_period; - st->prefilter_gain_old = st->prefilter_gain; - st->prefilter_tapset_old = st->prefilter_tapset; - } -#endif - - if (CC==2&&C==1) { - OPUS_COPY(&oldBandE[nbEBands], oldBandE, nbEBands); - } - - if (!isTransient) - { - OPUS_COPY(oldLogE2, oldLogE, CC*nbEBands); - OPUS_COPY(oldLogE, oldBandE, CC*nbEBands); - } else { - for (i=0;iconsec_transient++; - else - st->consec_transient=0; - st->rng = enc->rng; - - /* If there's any room left (can only happen for very high rates), - it's already filled with zeros */ - ec_enc_done(enc); - -#ifdef CUSTOM_MODES - if (st->signalling) - nbCompressedBytes++; -#endif - - RESTORE_STACK; - if (ec_get_error(enc)) - return OPUS_INTERNAL_ERROR; - else - return nbCompressedBytes; -} - - -#ifdef CUSTOM_MODES - -#ifdef FIXED_POINT -int opus_custom_encode(CELTEncoder * OPUS_RESTRICT st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) -{ - return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL); -} - -#ifndef DISABLE_FLOAT_API -int opus_custom_encode_float(CELTEncoder * OPUS_RESTRICT st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) -{ - int j, ret, C, N; - VARDECL(opus_int16, in); - ALLOC_STACK; - - if (pcm==NULL) - return OPUS_BAD_ARG; - - C = st->channels; - N = frame_size; - ALLOC(in, C*N, opus_int16); - - for (j=0;jchannels; - N=frame_size; - ALLOC(in, C*N, celt_sig); - for (j=0;j10) - goto bad_arg; - st->complexity = value; - } - break; - case CELT_SET_START_BAND_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<0 || value>=st->mode->nbEBands) - goto bad_arg; - st->start = value; - } - break; - case CELT_SET_END_BAND_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<1 || value>st->mode->nbEBands) - goto bad_arg; - st->end = value; - } - break; - case CELT_SET_PREDICTION_REQUEST: - { - int value = va_arg(ap, opus_int32); - if (value<0 || value>2) - goto bad_arg; - st->disable_pf = value<=1; - st->force_intra = value==0; - } - break; - case OPUS_SET_PACKET_LOSS_PERC_REQUEST: - { - int value = va_arg(ap, opus_int32); - if (value<0 || value>100) - goto bad_arg; - st->loss_rate = value; - } - break; - case OPUS_SET_VBR_CONSTRAINT_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - st->constrained_vbr = value; - } - break; - case OPUS_SET_VBR_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - st->vbr = value; - } - break; - case OPUS_SET_BITRATE_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<=500 && value!=OPUS_BITRATE_MAX) - goto bad_arg; - value = IMIN(value, 260000*st->channels); - st->bitrate = value; - } - break; - case CELT_SET_CHANNELS_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<1 || value>2) - goto bad_arg; - st->stream_channels = value; - } - break; - case OPUS_SET_LSB_DEPTH_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<8 || value>24) - goto bad_arg; - st->lsb_depth=value; - } - break; - case OPUS_GET_LSB_DEPTH_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - *value=st->lsb_depth; - } - break; - case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if(value<0 || value>1) - { - goto bad_arg; - } - st->disable_inv = value; - } - break; - case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->disable_inv; - } - break; - case OPUS_RESET_STATE: - { - int i; - opus_val16 *oldBandE, *oldLogE, *oldLogE2; - oldBandE = (opus_val16*)(st->in_mem+st->channels*(st->mode->overlap+COMBFILTER_MAXPERIOD)); - oldLogE = oldBandE + st->channels*st->mode->nbEBands; - oldLogE2 = oldLogE + st->channels*st->mode->nbEBands; - OPUS_CLEAR((char*)&st->ENCODER_RESET_START, - opus_custom_encoder_get_size(st->mode, st->channels)- - ((char*)&st->ENCODER_RESET_START - (char*)st)); - for (i=0;ichannels*st->mode->nbEBands;i++) - oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT); - st->vbr_offset = 0; - st->delayedIntra = 1; - st->spread_decision = SPREAD_NORMAL; - st->tonal_average = 256; - st->hf_average = 0; - st->tapset_decision = 0; - } - break; -#ifdef CUSTOM_MODES - case CELT_SET_INPUT_CLIPPING_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - st->clip = value; - } - break; -#endif - case CELT_SET_SIGNALLING_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - st->signalling = value; - } - break; - case CELT_SET_ANALYSIS_REQUEST: - { - AnalysisInfo *info = va_arg(ap, AnalysisInfo *); - if (info) - OPUS_COPY(&st->analysis, info, 1); - } - break; - case CELT_SET_SILK_INFO_REQUEST: - { - SILKInfo *info = va_arg(ap, SILKInfo *); - if (info) - OPUS_COPY(&st->silk_info, info, 1); - } - break; - case CELT_GET_MODE_REQUEST: - { - const CELTMode ** value = va_arg(ap, const CELTMode**); - if (value==0) - goto bad_arg; - *value=st->mode; - } - break; - case OPUS_GET_FINAL_RANGE_REQUEST: - { - opus_uint32 * value = va_arg(ap, opus_uint32 *); - if (value==0) - goto bad_arg; - *value=st->rng; - } - break; - case OPUS_SET_LFE_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - st->lfe = value; - } - break; - case OPUS_SET_ENERGY_MASK_REQUEST: - { - opus_val16 *value = va_arg(ap, opus_val16*); - st->energy_mask = value; - } - break; - default: - goto bad_request; - } - va_end(ap); - return OPUS_OK; -bad_arg: - va_end(ap); - return OPUS_BAD_ARG; -bad_request: - va_end(ap); - return OPUS_UNIMPLEMENTED; -} diff --git a/src/libopus/celt/celt_lpc.c b/src/libopus/celt/celt_lpc.c index 2b3c7844..7e022946 100644 --- a/src/libopus/celt/celt_lpc.c +++ b/src/libopus/celt/celt_lpc.c @@ -25,9 +25,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "celt_lpc.h" #include "stack_alloc.h" @@ -44,23 +44,27 @@ int p opus_val32 r; opus_val32 error = ac[0]; #ifdef FIXED_POINT - opus_val32 lpc[LPC_ORDER]; + opus_val32 lpc[CELT_LPC_ORDER]; #else float *lpc = _lpc; #endif OPUS_CLEAR(lpc, p); +#ifdef FIXED_POINT if (ac[0] != 0) +#else + if (ac[0] > 1e-10f) +#endif { for (i = 0; i < p; i++) { /* Sum up this iteration's reflection coefficient */ opus_val32 rr = 0; for (j = 0; j < i; j++) rr += MULT32_32_Q31(lpc[j],ac[i - j]); - rr += SHR32(ac[i + 1],3); - r = -frac_div32(SHL32(rr,3), error); + rr += SHR32(ac[i + 1],6); + r = -frac_div32(SHL32(rr,6), error); /* Update LPC coefficients and total error */ - lpc[i] = SHR32(r,3); + lpc[i] = SHR32(r,6); for (j = 0; j < (i+1)>>1; j++) { opus_val32 tmp1, tmp2; @@ -73,17 +77,61 @@ int p error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error); /* Bail out once we get 30 dB gain */ #ifdef FIXED_POINT - if (error maxabs) { + maxabs = absval; + idx = i; + } + } + maxabs = PSHR32(maxabs, 13); /* Q25->Q12 */ + + if (maxabs > 32767) { + maxabs = MIN32(maxabs, 163838); + chirp_Q16 = QCONST32(0.999, 16) - DIV32(SHL32(maxabs - 32767, 14), + SHR32(MULT32_32_32(maxabs, idx + 1), 2)); + chirp_minus_one_Q16 = chirp_Q16 - 65536; + + /* Apply bandwidth expansion. */ + for (i = 0; i < p - 1; i++) { + lpc[i] = MULT32_32_Q16(chirp_Q16, lpc[i]); + chirp_Q16 += PSHR32(MULT32_32_32(chirp_Q16, chirp_minus_one_Q16), 16); + } + lpc[p - 1] = MULT32_32_Q16(chirp_Q16, lpc[p - 1]); + } else { + break; + } + } + + if (iter == 10) { + /* If the coeffs still do not fit into the 16 bit range after 10 iterations, + fall back to the A(z)=1 filter. */ + OPUS_CLEAR(lpc, p); + _lpc[0] = 4096; /* Q12 */ + } else { + for (i = 0; i < p; i++) { + _lpc[i] = EXTRACT16(PSHR32(lpc[i], 13)); /* Q25->Q12 */ + } + } + } #endif } @@ -110,18 +158,28 @@ void celt_fir_c( sum[1] = SHL32(EXTEND32(x[i+1]), SIG_SHIFT); sum[2] = SHL32(EXTEND32(x[i+2]), SIG_SHIFT); sum[3] = SHL32(EXTEND32(x[i+3]), SIG_SHIFT); - xcorr_kernel(rnum, x+i-ord, sum, ord, arch); - y[i ] = ROUND16(sum[0], SIG_SHIFT); - y[i+1] = ROUND16(sum[1], SIG_SHIFT); - y[i+2] = ROUND16(sum[2], SIG_SHIFT); - y[i+3] = ROUND16(sum[3], SIG_SHIFT); +#if defined(OPUS_CHECK_ASM) && defined(FIXED_POINT) + { + opus_val32 sum_c[4]; + memcpy(sum_c, sum, sizeof(sum_c)); + xcorr_kernel_c(rnum, x+i-ord, sum_c, ord); +#endif + xcorr_kernel(rnum, x+i-ord, sum, ord, arch); +#if defined(OPUS_CHECK_ASM) && defined(FIXED_POINT) + celt_assert(memcmp(sum, sum_c, sizeof(sum)) == 0); + } +#endif + y[i ] = SROUND16(sum[0], SIG_SHIFT); + y[i+1] = SROUND16(sum[1], SIG_SHIFT); + y[i+2] = SROUND16(sum[2], SIG_SHIFT); + y[i+3] = SROUND16(sum[3], SIG_SHIFT); } for (;i ARMv4 * arch[1] -> ARMv5E * arch[2] -> ARMv6 * arch[3] -> NEON + * arch[4] -> NEON+DOTPROD */ -#define OPUS_ARCHMASK 3 +#define OPUS_ARCHMASK 7 -#elif (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(OPUS_X86_PRESUME_SSE)) || \ +#elif defined(OPUS_HAVE_RTCD) && \ + ((defined(OPUS_X86_MAY_HAVE_SSE) && !defined(OPUS_X86_PRESUME_SSE)) || \ (defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(OPUS_X86_PRESUME_SSE2)) || \ (defined(OPUS_X86_MAY_HAVE_SSE4_1) && !defined(OPUS_X86_PRESUME_SSE4_1)) || \ - (defined(OPUS_X86_MAY_HAVE_AVX) && !defined(OPUS_X86_PRESUME_AVX)) + (defined(OPUS_X86_MAY_HAVE_AVX2) && !defined(OPUS_X86_PRESUME_AVX2))) #include "x86/x86cpu.h" /* We currently support 5 x86 variants: diff --git a/src/libopus/celt/cwrs.c b/src/libopus/celt/cwrs.c index 402553dd..58c92628 100644 --- a/src/libopus/celt/cwrs.c +++ b/src/libopus/celt/cwrs.c @@ -27,15 +27,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "os_support.h" #include "cwrs.h" #include "mathops.h" #include "arch.h" -#include #ifdef CUSTOM_MODES @@ -209,9 +208,9 @@ int log2_frac(opus_uint32 val, int frac) splitting a band from a standard Opus mode: 176, 144, 96, 88, 72, 64, 48, 44, 36, 32, 24, 22, 18, 16, 8, 4, 2).*/ #if defined(CUSTOM_MODES) -static const opus_uint32 CELT_PVQ_U_DATA[1488] PROGMEM ={ +static const opus_uint32 CELT_PVQ_U_DATA[1488]={ #else -static const opus_uint32 CELT_PVQ_U_DATA[1272] PROGMEM ={ +static const opus_uint32 CELT_PVQ_U_DATA[1272]={ #endif /*N=0, K=0...176:*/ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -411,7 +410,7 @@ static const opus_uint32 CELT_PVQ_U_DATA[1272] PROGMEM ={ }; #if defined(CUSTOM_MODES) -static const opus_uint32 *const CELT_PVQ_U_ROW[15] PROGMEM={ +static const opus_uint32 *const CELT_PVQ_U_ROW[15]={ CELT_PVQ_U_DATA+ 0,CELT_PVQ_U_DATA+ 208,CELT_PVQ_U_DATA+ 415, CELT_PVQ_U_DATA+ 621,CELT_PVQ_U_DATA+ 826,CELT_PVQ_U_DATA+1030, CELT_PVQ_U_DATA+1233,CELT_PVQ_U_DATA+1336,CELT_PVQ_U_DATA+1389, @@ -419,7 +418,7 @@ static const opus_uint32 *const CELT_PVQ_U_ROW[15] PROGMEM={ CELT_PVQ_U_DATA+1464,CELT_PVQ_U_DATA+1470,CELT_PVQ_U_DATA+1473 }; #else -static const opus_uint32 *const CELT_PVQ_U_ROW[15] PROGMEM={ +static const opus_uint32 *const CELT_PVQ_U_ROW[15]={ CELT_PVQ_U_DATA+ 0,CELT_PVQ_U_DATA+ 176,CELT_PVQ_U_DATA+ 351, CELT_PVQ_U_DATA+ 525,CELT_PVQ_U_DATA+ 698,CELT_PVQ_U_DATA+ 870, CELT_PVQ_U_DATA+1041,CELT_PVQ_U_DATA+1131,CELT_PVQ_U_DATA+1178, diff --git a/src/libopus/celt/ecintrin.h b/src/libopus/celt/ecintrin.h index d5a09af9..66a4c36e 100644 --- a/src/libopus/celt/ecintrin.h +++ b/src/libopus/celt/ecintrin.h @@ -26,7 +26,7 @@ */ /*Some common macros for potential platform-specific optimization.*/ -#include "../opus_types.h" +#include "opus_types.h" #include #include #include "arch.h" @@ -49,7 +49,11 @@ This macro should only be used for implementing ec_ilog(), if it is defined. All other code should use EC_ILOG() instead.*/ #if defined(_MSC_VER) && (_MSC_VER >= 1400) +#if defined(_MSC_VER) && (_MSC_VER >= 1910) +# include /* Improve compiler throughput. */ +#else # include +#endif /*In _DEBUG mode this is not an intrinsic by default.*/ # pragma intrinsic(_BitScanReverse) diff --git a/src/libopus/celt/entcode.c b/src/libopus/celt/entcode.c index e689df68..62e0ddfb 100644 --- a/src/libopus/celt/entcode.c +++ b/src/libopus/celt/entcode.c @@ -25,9 +25,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "entcode.h" #include "arch.h" diff --git a/src/libopus/celt/entcode.h b/src/libopus/celt/entcode.h index 89ce2635..3763e3f2 100644 --- a/src/libopus/celt/entcode.h +++ b/src/libopus/celt/entcode.h @@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "../opus_types.h" -#include "../opus_defines.h" +#include "opus_types.h" +#include "opus_defines.h" #if !defined(_entcode_H) # define _entcode_H (1) diff --git a/src/libopus/celt/entdec.c b/src/libopus/celt/entdec.c index a37d9587..c27dd4e1 100644 --- a/src/libopus/celt/entdec.c +++ b/src/libopus/celt/entdec.c @@ -25,9 +25,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include #include "os_support.h" @@ -195,6 +195,27 @@ int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb){ return ret; } +int ec_dec_icdf16(ec_dec *_this,const opus_uint16 *_icdf,unsigned _ftb){ + opus_uint32 r; + opus_uint32 d; + opus_uint32 s; + opus_uint32 t; + int ret; + s=_this->rng; + d=_this->val; + r=s>>_ftb; + ret=-1; + do{ + t=s; + s=IMUL32(r,_icdf[++ret]); + } + while(dval=d-s; + _this->rng=t-s; + ec_dec_normalize(_this); + return ret; +} + opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft){ unsigned ft; unsigned s; diff --git a/src/libopus/celt/entdec.h b/src/libopus/celt/entdec.h index 025fc187..c81f26fd 100644 --- a/src/libopus/celt/entdec.h +++ b/src/libopus/celt/entdec.h @@ -81,6 +81,16 @@ int ec_dec_bit_logp(ec_dec *_this,unsigned _logp); Return: The decoded symbol s.*/ int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb); +/*Decodes a symbol given an "inverse" CDF table. + No call to ec_dec_update() is necessary after this call. + _icdf: The "inverse" CDF, such that symbol s falls in the range + [s>0?ft-_icdf[s-1]:0,ft-_icdf[s]), where ft=1<<_ftb. + The values must be monotonically non-increasing, and the last value + must be 0. + _ftb: The number of bits of precision in the cumulative distribution. + Return: The decoded symbol s.*/ +int ec_dec_icdf16(ec_dec *_this,const opus_uint16 *_icdf,unsigned _ftb); + /*Extracts a raw unsigned integer with a non-power-of-2 range from the stream. The bits must have been encoded with ec_enc_uint(). No call to ec_dec_update() is necessary after this call. diff --git a/src/libopus/celt/entenc.c b/src/libopus/celt/entenc.c index 164f238b..b297ad76 100644 --- a/src/libopus/celt/entenc.c +++ b/src/libopus/celt/entenc.c @@ -25,9 +25,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -//#if defined(HAVE_CONFIG_H) -# include "../config.h" -//#endif +#if defined(__STDC__) +# include "config.h" +#endif #include "os_support.h" #include "arch.h" #include "entenc.h" @@ -172,6 +172,17 @@ void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb){ ec_enc_normalize(_this); } +void ec_enc_icdf16(ec_enc *_this,int _s,const opus_uint16 *_icdf,unsigned _ftb){ + opus_uint32 r; + r=_this->rng>>_ftb; + if(_s>0){ + _this->val+=_this->rng-IMUL32(r,_icdf[_s-1]); + _this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]); + } + else _this->rng-=IMUL32(r,_icdf[_s]); + ec_enc_normalize(_this); +} + void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft){ unsigned ft; unsigned fl; diff --git a/src/libopus/celt/entenc.h b/src/libopus/celt/entenc.h index f502eaf6..010874bb 100644 --- a/src/libopus/celt/entenc.h +++ b/src/libopus/celt/entenc.h @@ -64,6 +64,15 @@ void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp); _ftb: The number of bits of precision in the cumulative distribution.*/ void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb); +/*Encodes a symbol given an "inverse" CDF table. + _s: The index of the symbol to encode. + _icdf: The "inverse" CDF, such that symbol _s falls in the range + [_s>0?ft-_icdf[_s-1]:0,ft-_icdf[_s]), where ft=1<<_ftb. + The values must be monotonically non-increasing, and the last value + must be 0. + _ftb: The number of bits of precision in the cumulative distribution.*/ +void ec_enc_icdf16(ec_enc *_this,int _s,const opus_uint16 *_icdf,unsigned _ftb); + /*Encodes a raw unsigned integer in the stream. _fl: The integer to encode. _ft: The number of integers that can be encoded (one more than the max). diff --git a/src/libopus/celt/fixed_debug.h b/src/libopus/celt/fixed_debug.h index 388d4857..ef2e5d02 100644 --- a/src/libopus/celt/fixed_debug.h +++ b/src/libopus/celt/fixed_debug.h @@ -33,7 +33,7 @@ #define FIXED_DEBUG_H #include -#include "../opus_defines.h" +#include "opus_defines.h" #ifdef CELT_C OPUS_EXPORT opus_int64 celt_mips=0; @@ -167,7 +167,7 @@ static OPUS_INLINE short SHR16_(int a, int shift, char *file, int line) #define SHL16(a, shift) SHL16_(a, shift, __FILE__, __LINE__) static OPUS_INLINE short SHL16_(int a, int shift, char *file, int line) { - int res; + opus_int32 res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) { fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line); @@ -175,7 +175,7 @@ static OPUS_INLINE short SHL16_(int a, int shift, char *file, int line) celt_assert(0); #endif } - res = a<> 16; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "MULT32_32_Q16: output is not int: %lld*%lld=%lld\n", (long long)a, (long long)b, (long long)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips+=5; + return res; +} + #define MULT16_16(a, b) MULT16_16_(a, b, __FILE__, __LINE__) static OPUS_INLINE int MULT16_16_(int a, int b, char *file, int line) { @@ -446,7 +491,7 @@ static OPUS_INLINE int MULT16_32_QX_(int a, opus_int64 b, int Q, char *file, int celt_assert(0); #endif } - if (ABS32(b)>=((opus_val32)(1)<<(15+Q))) + if (ABS32(b)>=((opus_int64)(1)<<(16+Q))) { fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line); #ifdef FIXED_DEBUG_ASSERT @@ -479,7 +524,7 @@ static OPUS_INLINE int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int celt_assert(0); #endif } - if (ABS32(b)>=((opus_int64)(1)<<(15+Q))) + if (ABS32(b)>=((opus_int64)(1)<<(16+Q))) { fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n\n", Q, (int)a, (int)b,file, line); #ifdef FIXED_DEBUG_ASSERT @@ -786,6 +831,6 @@ static OPUS_INLINE opus_val16 SIG2WORD16_generic(celt_sig x) #undef PRINT_MIPS -#define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", celt_mips);} while (0); +#define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", (unsigned long long)celt_mips);} while (0); #endif diff --git a/src/libopus/celt/fixed_generic.h b/src/libopus/celt/fixed_generic.h index 5f4abda7..8f29d46b 100644 --- a/src/libopus/celt/fixed_generic.h +++ b/src/libopus/celt/fixed_generic.h @@ -57,6 +57,13 @@ #define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15)) #endif +/** 32x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ +#if OPUS_FAST_INT64 +#define MULT32_32_Q16(a,b) ((opus_val32)SHR((opus_int64)(a)*(opus_int64)(b),16)) +#else +#define MULT32_32_Q16(a,b) (ADD32(ADD32(ADD32((opus_val32)(SHR32(((opus_uint32)((a)&0x0000ffff)*(opus_uint32)((b)&0x0000ffff)),16)), MULT16_16SU(SHR32(a,16),((b)&0x0000ffff))), MULT16_16SU(SHR32(b,16),((a)&0x0000ffff))), SHL32(MULT16_16(SHR32(a,16),SHR32(b,16)),16))) +#endif + /** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */ #if OPUS_FAST_INT64 #define MULT32_32_Q31(a,b) ((opus_val32)SHR((opus_int64)(a)*(opus_int64)(b),31)) @@ -102,9 +109,9 @@ #define SATURATE16(x) (EXTRACT16((x)>32767 ? 32767 : (x)<-32768 ? -32768 : (x))) -/** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */ +/** Shift by a and round-to-nearest 32-bit value. Result is a 16-bit value */ #define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a)))) -/** Shift by a and round-to-neareast 32-bit value. Result is a saturated 16-bit value */ +/** Shift by a and round-to-nearest 32-bit value. Result is a saturated 16-bit value */ #define SROUND16(x,a) EXTRACT16(SATURATE(PSHR32(x,a), 32767)); /** Divide by two */ @@ -131,6 +138,9 @@ /** 16x16 multiplication where the result fits in 16 bits */ #define MULT16_16_16(a,b) ((((opus_val16)(a))*((opus_val16)(b)))) +/** 32x32 multiplication where the result fits in 32 bits */ +#define MULT32_32_32(a,b) ((((opus_val32)(a))*((opus_val32)(b)))) + /* (opus_val32)(opus_val16) gives TI compiler a hint that it's 16x16->32 multiply */ /** 16x16 multiplication where the result fits in 32 bits */ #define MULT16_16(a,b) (((opus_val32)(opus_val16)(a))*((opus_val32)(opus_val16)(b))) diff --git a/src/libopus/celt/float_cast.h b/src/libopus/celt/float_cast.h index 75d5fe82..8915a5fd 100644 --- a/src/libopus/celt/float_cast.h +++ b/src/libopus/celt/float_cast.h @@ -58,7 +58,7 @@ /* The presence of the required functions are detected during the configure ** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in -** the ../config.h file. +** the config.h file. */ /* With GCC, when SSE is available, the fastest conversion is cvtss2si. */ @@ -67,7 +67,39 @@ #include static OPUS_INLINE opus_int32 float2int(float x) {return _mm_cvt_ss2si(_mm_set_ss(x));} -#elif defined(HAVE_LRINTF) +#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1)) + + #include + static OPUS_INLINE opus_int32 float2int(float value) + { + /* _mm_load_ss will generate same code as _mm_set_ss + ** in _MSC_VER >= 1914 /02 so keep __mm_load__ss + ** for backward compatibility. + */ + return _mm_cvtss_si32(_mm_load_ss(&value)); + } + +#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && defined (_M_IX86) + + #include + + /* Win32 doesn't seem to have these functions. + ** Therefore implement OPUS_INLINE versions of these functions here. + */ + + static OPUS_INLINE opus_int32 + float2int (float flt) + { int intgr; + + _asm + { fld flt + fistp intgr + } ; + + return intgr ; + } + +#elif defined(HAVE_LRINTF) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* These defines enable functionality introduced with the 1999 ISO C ** standard. They must be defined before the inclusion of math.h to @@ -85,7 +117,7 @@ static OPUS_INLINE opus_int32 float2int(float x) {return _mm_cvt_ss2si(_mm_set_s #include #define float2int(x) lrintf(x) -#elif (defined(HAVE_LRINT)) +#elif defined(HAVE_LRINT) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define _ISOC9X_SOURCE 1 #define _ISOC99_SOURCE 1 @@ -96,32 +128,6 @@ static OPUS_INLINE opus_int32 float2int(float x) {return _mm_cvt_ss2si(_mm_set_s #include #define float2int(x) lrint(x) -#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1)) - #include - - static __inline long int float2int(float value) - { - return _mm_cvtss_si32(_mm_load_ss(&value)); - } -#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && defined (_M_IX86) - #include - - /* Win32 doesn't seem to have these functions. - ** Therefore implement OPUS_INLINE versions of these functions here. - */ - - static __inline long int - float2int (float flt) - { int intgr; - - _asm - { fld flt - fistp intgr - } ; - - return intgr ; - } - #else #if (defined(__GNUC__) && defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) diff --git a/src/libopus/celt/kiss_fft.c b/src/libopus/celt/kiss_fft.c index 2b761846..2df03146 100644 --- a/src/libopus/celt/kiss_fft.c +++ b/src/libopus/celt/kiss_fft.c @@ -30,9 +30,9 @@ heavily modified to better suit Opus */ #ifndef SKIP_CONFIG_H -//# ifdef HAVE_CONFIG_H -# include "../config.h" -//# endif +# ifdef __STDC__ +# include "config.h" +# endif #endif #include "_kiss_fft_guts.h" diff --git a/src/libopus/celt/kiss_fft.h b/src/libopus/celt/kiss_fft.h index bffa2bfa..267f72f9 100644 --- a/src/libopus/celt/kiss_fft.h +++ b/src/libopus/celt/kiss_fft.h @@ -52,6 +52,10 @@ extern "C" { # define kiss_fft_scalar opus_int32 # define kiss_twiddle_scalar opus_int16 +/* Some 32-bit CPUs would load/store a kiss_twiddle_cpx with a single memory + * access, and could benefit from additional alignment. + */ +# define KISS_TWIDDLE_CPX_ALIGNMENT (sizeof(opus_int32)) #else # ifndef kiss_fft_scalar @@ -62,6 +66,12 @@ extern "C" { # endif #endif +#if defined(__GNUC__) && defined(KISS_TWIDDLE_CPX_ALIGNMENT) +#define KISS_TWIDDLE_CPX_ALIGNED __attribute__((aligned(KISS_TWIDDLE_CPX_ALIGNMENT))) +#else +#define KISS_TWIDDLE_CPX_ALIGNED +#endif + typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; @@ -70,7 +80,7 @@ typedef struct { typedef struct { kiss_twiddle_scalar r; kiss_twiddle_scalar i; -}kiss_twiddle_cpx; +} KISS_TWIDDLE_CPX_ALIGNED kiss_twiddle_cpx; #define MAXFACTORS 8 /* e.g. an fft of length 128 has 4 factors diff --git a/src/libopus/celt/laplace.c b/src/libopus/celt/laplace.c index 820433aa..8c719a91 100644 --- a/src/libopus/celt/laplace.c +++ b/src/libopus/celt/laplace.c @@ -26,9 +26,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "laplace.h" #include "mathops.h" @@ -132,3 +132,104 @@ int ec_laplace_decode(ec_dec *dec, unsigned fs, int decay) ec_dec_update(dec, fl, IMIN(fl+fs,32768), 32768); return val; } + +void ec_laplace_encode_p0(ec_enc *enc, int value, opus_uint16 p0, opus_uint16 decay) +{ + int s; + opus_uint16 sign_icdf[3]; + sign_icdf[0] = 32768-p0; + sign_icdf[1] = sign_icdf[0]/2; + sign_icdf[2] = 0; + s = value == 0 ? 0 : (value > 0 ? 1 : 2); + ec_enc_icdf16(enc, s, sign_icdf, 15); + value = abs(value); + if (value) + { + int i; + opus_uint16 icdf[8]; + icdf[0] = IMAX(7, decay); + for (i=1;i<7;i++) + { + icdf[i] = IMAX(7-i, (icdf[i-1] * (opus_int32)decay) >> 15); + } + icdf[7] = 0; + value--; + do { + ec_enc_icdf16(enc, IMIN(value, 7), icdf, 15); + value -= 7; + } while (value >= 0); + } +} + +int ec_laplace_decode_p0(ec_dec *dec, opus_uint16 p0, opus_uint16 decay) +{ + int s; + int value; + opus_uint16 sign_icdf[3]; + sign_icdf[0] = 32768-p0; + sign_icdf[1] = sign_icdf[0]/2; + sign_icdf[2] = 0; + s = ec_dec_icdf16(dec, sign_icdf, 15); + if (s==2) s = -1; + if (s != 0) + { + int i; + int v; + opus_uint16 icdf[8]; + icdf[0] = IMAX(7, decay); + for (i=1;i<7;i++) + { + icdf[i] = IMAX(7-i, (icdf[i-1] * (opus_int32)decay) >> 15); + } + icdf[7] = 0; + value = 1; + do { + v = ec_dec_icdf16(dec, icdf, 15); + value += v; + } while (v == 7); + return s*value; + } else return 0; +} + +#if 0 + +#include +#define NB_VALS 10 +#define DATA_SIZE 10000 +int main() { + ec_enc enc; + ec_dec dec; + unsigned char *ptr; + int i; + int decay, p0; + int val[NB_VALS] = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + /*for (i=0;i>23)-127; - in.i -= integer<<23; + in.i -= (opus_uint32)integer<<23; frac = in.f - 1.5f; frac = -0.41445418f + frac*(0.95909232f + frac*(-0.33951290f + frac*0.16541097f)); @@ -153,14 +153,14 @@ static OPUS_INLINE float celt_exp2(float x) float f; opus_uint32 i; } res; - integer = floor(x); + integer = (int)floor(x); if (integer < -50) return 0; frac = x-integer; /* K0 = 1, K1 = log(2), K2 = 3-4*log(2), K3 = 3*log(2) - 2 */ res.f = 0.99992522f + frac * (0.69583354f + frac * (0.22606716f + 0.078024523f*frac)); - res.i = (res.i + (integer<<23)) & 0x7fffffff; + res.i = (res.i + ((opus_uint32)integer<<23)) & 0x7fffffff; return res.f; } @@ -230,6 +230,12 @@ static OPUS_INLINE opus_val32 celt_exp2_frac(opus_val16 x) frac = SHL16(x, 4); return ADD16(D0, MULT16_16_Q15(frac, ADD16(D1, MULT16_16_Q15(frac, ADD16(D2 , MULT16_16_Q15(D3,frac)))))); } + +#undef D0 +#undef D1 +#undef D2 +#undef D3 + /** Base-2 exponential approximation (2^x). (Q10 input, Q16 output) */ static OPUS_INLINE opus_val32 celt_exp2(opus_val16 x) { diff --git a/src/libopus/celt/mdct.c b/src/libopus/celt/mdct.c index f484a179..b67f3c83 100644 --- a/src/libopus/celt/mdct.c +++ b/src/libopus/celt/mdct.c @@ -40,9 +40,9 @@ */ #ifndef SKIP_CONFIG_H -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #endif #include "mdct.h" diff --git a/src/libopus/celt/mdct.h b/src/libopus/celt/mdct.h index 9f92a856..160ae4e0 100644 --- a/src/libopus/celt/mdct.h +++ b/src/libopus/celt/mdct.h @@ -42,7 +42,7 @@ #ifndef MDCT_H #define MDCT_H -#include "../opus_defines.h" +#include "opus_defines.h" #include "kiss_fft.h" #include "arch.h" diff --git a/src/libopus/celt/modes.c b/src/libopus/celt/modes.c index 394a5909..4c3ffcf7 100644 --- a/src/libopus/celt/modes.c +++ b/src/libopus/celt/modes.c @@ -27,9 +27,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "celt.h" #include "modes.h" @@ -173,7 +173,10 @@ static void compute_allocation_table(CELTMode *mode) mode->nbAllocVectors = BITALLOC_SIZE; allocVectors = opus_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands)); if (allocVectors==NULL) + { + mode->allocVectors = NULL; return; + } /* Check for standard mode */ if (mode->Fs == 400*(opus_int32)mode->shortMdctSize) diff --git a/src/libopus/celt/modes.h b/src/libopus/celt/modes.h index 52a1562e..be813ccc 100644 --- a/src/libopus/celt/modes.h +++ b/src/libopus/celt/modes.h @@ -30,7 +30,7 @@ #ifndef MODES_H #define MODES_H -#include "../opus_types.h" +#include "opus_types.h" #include "celt.h" #include "arch.h" #include "mdct.h" diff --git a/src/libopus/celt/opus.h b/src/libopus/celt/opus.h new file mode 100644 index 00000000..0a1b59ca --- /dev/null +++ b/src/libopus/celt/opus.h @@ -0,0 +1 @@ +#include "../include/opus.h" diff --git a/src/libopus/celt/opus_custom.h b/src/libopus/celt/opus_custom.h new file mode 100644 index 00000000..f54a1034 --- /dev/null +++ b/src/libopus/celt/opus_custom.h @@ -0,0 +1 @@ +#include "../include/opus_custom.h" diff --git a/src/libopus/celt/opus_defines.h b/src/libopus/celt/opus_defines.h new file mode 100644 index 00000000..dcc24434 --- /dev/null +++ b/src/libopus/celt/opus_defines.h @@ -0,0 +1 @@ +#include "../include/opus_defines.h" diff --git a/src/libopus/celt/opus_multistream.h b/src/libopus/celt/opus_multistream.h new file mode 100644 index 00000000..89f62298 --- /dev/null +++ b/src/libopus/celt/opus_multistream.h @@ -0,0 +1 @@ +#include "../include/opus_multistream.h" diff --git a/src/libopus/celt/opus_projection.h b/src/libopus/celt/opus_projection.h new file mode 100644 index 00000000..72f59cc1 --- /dev/null +++ b/src/libopus/celt/opus_projection.h @@ -0,0 +1 @@ +#include "../include/opus_projection.h" diff --git a/src/libopus/celt/opus_types.h b/src/libopus/celt/opus_types.h new file mode 100644 index 00000000..a7958a5d --- /dev/null +++ b/src/libopus/celt/opus_types.h @@ -0,0 +1 @@ +#include "../include/opus_types.h" diff --git a/src/libopus/celt/os_support.h b/src/libopus/celt/os_support.h index 52286a5f..7d2d3781 100644 --- a/src/libopus/celt/os_support.h +++ b/src/libopus/celt/os_support.h @@ -35,14 +35,13 @@ # include "custom_support.h" #endif -#include "../opus_types.h" -#include "../opus_defines.h" +#include "opus_types.h" +#include "opus_defines.h" #include -#include #include -/** Opus wrapper for malloc(). To do your own dynamic allocation, all you need to do is replace this function and opus_free */ +/** Opus wrapper for malloc(). To do your own dynamic allocation replace this function, opus_realloc, and opus_free */ #ifndef OVERRIDE_OPUS_ALLOC static OPUS_INLINE void *opus_alloc (size_t size) { @@ -50,7 +49,15 @@ static OPUS_INLINE void *opus_alloc (size_t size) } #endif -/** Same as celt_alloc(), except that the area is only needed inside a CELT call (might cause problem with wideband though) */ +#ifndef OVERRIDE_OPUS_REALLOC +static OPUS_INLINE void *opus_realloc (void *ptr, size_t size) +{ + return realloc(ptr, size); +} +#endif + +/** Used only for non-threadsafe pseudostack. + If desired, this can always return the same area of memory rather than allocating a new one every time. */ #ifndef OVERRIDE_OPUS_ALLOC_SCRATCH static OPUS_INLINE void *opus_alloc_scratch (size_t size) { @@ -59,7 +66,7 @@ static OPUS_INLINE void *opus_alloc_scratch (size_t size) } #endif -/** Opus wrapper for free(). To do your own dynamic allocation, all you need to do is replace this function and opus_alloc */ +/** Opus wrapper for free(). To do your own dynamic allocation replace this function, opus_realloc, and opus_free */ #ifndef OVERRIDE_OPUS_FREE static OPUS_INLINE void opus_free (void *ptr) { diff --git a/src/libopus/celt/pitch.c b/src/libopus/celt/pitch.c index 6b180530..9bc9916c 100644 --- a/src/libopus/celt/pitch.c +++ b/src/libopus/celt/pitch.c @@ -31,9 +31,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "pitch.h" #include "os_support.h" @@ -161,17 +161,26 @@ void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x shift=0; if (C==2) shift++; -#endif for (i=1;i>1;i++) - x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), shift); - x_lp[0] = SHR32(HALF32(HALF32(x[0][1])+x[0][0]), shift); + x_lp[i] = SHR32(x[0][(2*i-1)], shift+2) + SHR32(x[0][(2*i+1)], shift+2) + SHR32(x[0][2*i], shift+1); + x_lp[0] = SHR32(x[0][1], shift+2) + SHR32(x[0][0], shift+1); if (C==2) { for (i=1;i>1;i++) - x_lp[i] += SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), shift); - x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), shift); + x_lp[i] += SHR32(x[1][(2*i-1)], shift+2) + SHR32(x[1][(2*i+1)], shift+2) + SHR32(x[1][2*i], shift+1); + x_lp[0] += SHR32(x[1][1], shift+2) + SHR32(x[1][0], shift+1); } - +#else + for (i=1;i>1;i++) + x_lp[i] = .25f*x[0][(2*i-1)] + .25f*x[0][(2*i+1)] + .5f*x[0][2*i]; + x_lp[0] = .25f*x[0][1] + .5f*x[0][0]; + if (C==2) + { + for (i=1;i>1;i++) + x_lp[i] += .25f*x[1][(2*i-1)] + .25f*x[1][(2*i+1)] + .5f*x[1][2*i]; + x_lp[0] += .25f*x[1][1] + .5f*x[1][0]; + } +#endif _celt_autocorr(x_lp, ac, NULL, 0, 4, len>>1, arch); @@ -249,11 +258,20 @@ celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y, opus_val32 maxcorr=1; #endif celt_assert(max_pitch>0); - celt_sig_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0); + celt_sig_assert(((size_t)_x&3)==0); for (i=0;i #include "modes.h" @@ -356,6 +356,8 @@ static OPUS_INLINE int interp_bits2pulses(const CELTMode *m, int start, int end, else depth_threshold = 0; #ifdef FUZZING + (void)signalBandwidth; + (void)depth_threshold; if ((rand()&0x1) == 0) #else if (codedBands<=start+2 || (band_bits > (depth_threshold*band_width<>4 && j<=signalBandwidth)) diff --git a/src/libopus/celt/stack_alloc.h b/src/libopus/celt/stack_alloc.h index a05120bd..e2739bdf 100644 --- a/src/libopus/celt/stack_alloc.h +++ b/src/libopus/celt/stack_alloc.h @@ -32,15 +32,15 @@ #ifndef STACK_ALLOC_H #define STACK_ALLOC_H -#include "../opus_types.h" -#include "../opus_defines.h" +#include "opus_types.h" +#include "opus_defines.h" #if (!defined (VAR_ARRAYS) && !defined (USE_ALLOCA) && !defined (NONTHREADSAFE_PSEUDOSTACK)) #error "Opus requires one of VAR_ARRAYS, USE_ALLOCA, or NONTHREADSAFE_PSEUDOSTACK be defined to select the temporary allocation mode." #endif #ifdef USE_ALLOCA -# ifdef WIN32 +# ifdef _WIN32 # include # else # ifdef HAVE_ALLOCA_H @@ -102,7 +102,7 @@ #define VARDECL(type, var) type *var -# ifdef WIN32 +# ifdef _WIN32 # define ALLOC(var, size, type) var = ((type*)_alloca(sizeof(type)*(size))) # else # define ALLOC(var, size, type) var = ((type*)alloca(sizeof(type)*(size))) @@ -141,7 +141,7 @@ extern char *global_stack_top; #else #define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1)) -#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)/sizeof(char)),(stack)+=(size)*(sizeof(type)/sizeof(char)),(type*)((stack)-(size)*(sizeof(type)/sizeof(char)))) +#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)/(sizeof(char))),(stack)+=(size)*(sizeof(type)/(sizeof(char))),(type*)((stack)-(size)*(sizeof(type)/(sizeof(char))))) #if 0 /* Set this to 1 to instrument pseudostack usage */ #define RESTORE_STACK (printf("%ld %s:%d\n", global_stack-scratch_ptr, __FILE__, __LINE__),global_stack = _saved_stack) #else diff --git a/src/libopus/celt/vq.c b/src/libopus/celt/vq.c index bc0493f0..81321d9b 100644 --- a/src/libopus/celt/vq.c +++ b/src/libopus/celt/vq.c @@ -26,9 +26,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "mathops.h" #include "cwrs.h" diff --git a/src/libopus/config.h b/src/libopus/include/config.h similarity index 76% rename from src/libopus/config.h rename to src/libopus/include/config.h index 3577204b..636dca03 100644 --- a/src/libopus/config.h +++ b/src/libopus/include/config.h @@ -1,3 +1,6 @@ + +// CFLAGS="-m32 -g -O2 -fstack-usage -Wstack-usage=512" CPPFLAGS="-m32 -g -O2 -fstack-usage -Wstack-usage=512" ./configure --prefix=/tmp/opus --disable-float-api --enable-fixed-point --disable-hardening --disable-asm --disable-intrinsics + /* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ @@ -10,6 +13,12 @@ /* Custom modes */ /* #undef CUSTOM_MODES */ +/* Disable DNN debug float */ +#define DISABLE_DEBUG_FLOAT 1 + +/* Disable dot product instructions */ +/* #undef DISABLE_DOT_PROD */ + /* Do not build the float API */ #define DISABLE_FLOAT_API 1 @@ -19,9 +28,24 @@ /* Assertions */ /* #undef ENABLE_ASSERTIONS */ +/* Deep PLC */ +/* #undef ENABLE_DEEP_PLC */ + +/* DRED */ +/* #undef ENABLE_DRED */ + /* Hardening */ /* #undef ENABLE_HARDENING */ +/* LOSSGEN */ +/* #undef ENABLE_LOSSGEN */ + +/* Enable Opus Speech Coding Enhancement */ +/* #undef ENABLE_OSCE */ + +/* Enable dumping of OSCE training data */ +/* #undef ENABLE_OSCE_TRAINING_DATA */ + /* Debug fixed-point implementation */ /* #undef FIXED_DEBUG */ @@ -29,7 +53,7 @@ #define FIXED_POINT 1 /* Float approximations */ -/* #undef FLOAT_APPROX */ +#define FLOAT_APPROX 1 /* Fuzzing */ /* #undef FUZZING */ @@ -37,27 +61,28 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_ALLOCA_H */ + /* NE10 library is installed on host. Make sure it is on target! */ /* #undef HAVE_ARM_NE10 */ /* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H 0 +#define HAVE_DLFCN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the `lrint' function. */ -#define HAVE_LRINT 0 +#define HAVE_LRINT 1 /* Define to 1 if you have the `lrintf' function. */ -#define HAVE_LRINTF 0 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 +#define HAVE_LRINTF 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 +/* Define to 1 if you have the header file. */ +#define HAVE_STDIO_H 1 + /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 @@ -74,10 +99,10 @@ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 0 +#define HAVE_UNISTD_H 1 /* Define to 1 if you have the `__malloc_hook' function. */ -#define HAVE___MALLOC_HOOK 1 +/* #undef HAVE___MALLOC_HOOK */ /* Define to the sub-directory where libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" @@ -97,6 +122,9 @@ /* Use ARM NEON inline asm optimizations */ /* #undef OPUS_ARM_INLINE_NEON */ +/* Compiler supports Aarch64 DOTPROD Intrinsics */ +/* #undef OPUS_ARM_MAY_HAVE_DOTPROD */ + /* Define if assembler supports EDSP instructions */ /* #undef OPUS_ARM_MAY_HAVE_EDSP */ @@ -112,6 +140,9 @@ /* Define if binary requires Aarch64 Neon Intrinsics */ /* #undef OPUS_ARM_PRESUME_AARCH64_NEON_INTR */ +/* Define if binary requires Aarch64 dotprod Intrinsics */ +/* #undef OPUS_ARM_PRESUME_DOTPROD */ + /* Define if binary requires EDSP instruction support */ /* #undef OPUS_ARM_PRESUME_EDSP */ @@ -133,8 +164,8 @@ /* Use run-time CPU capabilities detection */ /* #undef OPUS_HAVE_RTCD */ -/* Compiler supports X86 AVX Intrinsics */ -/* #undef OPUS_X86_MAY_HAVE_AVX */ +/* Compiler supports X86 AVX2 Intrinsics */ +/* #undef OPUS_X86_MAY_HAVE_AVX2 */ /* Compiler supports X86 SSE Intrinsics */ /* #undef OPUS_X86_MAY_HAVE_SSE */ @@ -145,8 +176,8 @@ /* Compiler supports X86 SSE4.1 Intrinsics */ /* #undef OPUS_X86_MAY_HAVE_SSE4_1 */ -/* Define if binary requires AVX intrinsics support */ -/* #undef OPUS_X86_PRESUME_AVX */ +/* Define if binary requires AVX2 intrinsics support */ +/* #undef OPUS_X86_PRESUME_AVX2 */ /* Define if binary requires SSE intrinsics support */ /* #undef OPUS_X86_PRESUME_SSE */ @@ -164,7 +195,7 @@ #define PACKAGE_NAME "opus" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "opus 1.3.1" +#define PACKAGE_STRING "opus 1.5.2" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "opus" @@ -173,17 +204,25 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.3.1" +#define PACKAGE_VERSION "1.5.2" -/* Define to 1 if you have the ANSI C header files. */ +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ #define STDC_HEADERS 1 /* Make use of alloca */ -/* #undef USE_ALLOCA */ +#undef USE_ALLOCA /* Use C99 variable-size arrays */ #define VAR_ARRAYS 1 +// Enable heap-based stack on Pico. ESP32 should use larger task stack in the sketch +#ifdef ARDUINO_ARCH_RP2040 +#undef VAR_ARRAYS +#define NONTHREADSAFE_PSEUDOSTACK 1 +#endif + /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ diff --git a/src/libopus/opus.h b/src/libopus/include/opus.h similarity index 88% rename from src/libopus/opus.h rename to src/libopus/include/opus.h index d282f21d..eadeda75 100644 --- a/src/libopus/opus.h +++ b/src/libopus/include/opus.h @@ -103,7 +103,7 @@ extern "C" { * @endcode * * where opus_encoder_get_size() returns the required size for the encoder state. Note that - * future versions of this code may change the size, so no assuptions should be made about it. + * future versions of this code may change the size, so no assumptions should be made about it. * * The encoder state is always continuous in memory and only a shallow copy is sufficient * to copy it (e.g. memcpy()) @@ -198,7 +198,7 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels); * This must be one of 8000, 12000, 16000, * 24000, or 48000. * @param [in] channels int: Number of channels (1 or 2) in input signal - * @param [in] application int: Coding mode (@ref OPUS_APPLICATION_VOIP/@ref OPUS_APPLICATION_AUDIO/@ref OPUS_APPLICATION_RESTRICTED_LOWDELAY) + * @param [in] application int: Coding mode (one of @ref OPUS_APPLICATION_VOIP, @ref OPUS_APPLICATION_AUDIO, or @ref OPUS_APPLICATION_RESTRICTED_LOWDELAY) * @param [out] error int*: @ref opus_errorcodes * @note Regardless of the sampling rate and number channels selected, the Opus encoder * can switch to a lower audio bandwidth or number of channels if the bitrate @@ -222,7 +222,7 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create( * This must be one of 8000, 12000, 16000, * 24000, or 48000. * @param [in] channels int: Number of channels (1 or 2) in input signal - * @param [in] application int: Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO/OPUS_APPLICATION_RESTRICTED_LOWDELAY) + * @param [in] application int: Coding mode (one of OPUS_APPLICATION_VOIP, OPUS_APPLICATION_AUDIO, or OPUS_APPLICATION_RESTRICTED_LOWDELAY) * @retval #OPUS_OK Success or @ref opus_errorcodes */ OPUS_EXPORT int opus_encoder_init( @@ -357,7 +357,7 @@ OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NON * error = opus_decoder_init(dec, Fs, channels); * @endcode * where opus_decoder_get_size() returns the required size for the decoder state. Note that - * future versions of this code may change the size, so no assuptions should be made about it. + * future versions of this code may change the size, so no assumptions should be made about it. * * The decoder state is always continuous in memory and only a shallow copy is sufficient * to copy it (e.g. memcpy()) @@ -398,6 +398,21 @@ OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NON */ typedef struct OpusDecoder OpusDecoder; +/** Opus DRED decoder. + * This contains the complete state of an Opus DRED decoder. + * It is position independent and can be freely copied. + * @see opus_dred_decoder_create,opus_dred_decoder_init + */ +typedef struct OpusDREDDecoder OpusDREDDecoder; + + +/** Opus DRED state. + * This contains the complete state of an Opus DRED packet. + * It is position independent and can be freely copied. + * @see opus_dred_create,opus_dred_init + */ +typedef struct OpusDRED OpusDRED; + /** Gets the size of an OpusDecoder structure. * @param [in] channels int: Number of channels. * This must be 1 or 2. @@ -511,6 +526,101 @@ OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NON */ OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st); +/** Gets the size of an OpusDREDDecoder structure. + * @returns The size in bytes. + */ +OPUS_EXPORT int opus_dred_decoder_get_size(void); + +/** Allocates and initializes an OpusDREDDecoder state. + * @param [out] error int*: #OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_EXPORT OpusDREDDecoder *opus_dred_decoder_create(int *error); + +/** Initializes an OpusDREDDecoder state. + * @param[in] dec OpusDREDDecoder*: State to be initialized. + */ +OPUS_EXPORT int opus_dred_decoder_init(OpusDREDDecoder *dec); + +/** Frees an OpusDREDDecoder allocated by opus_dred_decoder_create(). + * @param[in] dec OpusDREDDecoder*: State to be freed. + */ +OPUS_EXPORT void opus_dred_decoder_destroy(OpusDREDDecoder *dec); + +/** Perform a CTL function on an Opus DRED decoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @param dred_dec OpusDREDDecoder*: DRED Decoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls or + * @ref opus_decoderctls. + * @see opus_genericctls + * @see opus_decoderctls + */ +OPUS_EXPORT int opus_dred_decoder_ctl(OpusDREDDecoder *dred_dec, int request, ...); + +/** Gets the size of an OpusDRED structure. + * @returns The size in bytes. + */ +OPUS_EXPORT int opus_dred_get_size(void); + +/** Allocates and initializes a DRED state. + * @param [out] error int*: #OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_EXPORT OpusDRED *opus_dred_alloc(int *error); + +/** Frees an OpusDRED allocated by opus_dred_create(). + * @param[in] dec OpusDRED*: State to be freed. + */ +OPUS_EXPORT void opus_dred_free(OpusDRED *dec); + +/** Decode an Opus DRED packet. + * @param [in] dred_dec OpusDRED*: DRED Decoder state + * @param [in] dred OpusDRED*: DRED state + * @param [in] data char*: Input payload + * @param [in] len opus_int32: Number of bytes in payload + * @param [in] max_dred_samples opus_int32: Maximum number of DRED samples that may be needed (if available in the packet). + * @param [in] sampling_rate opus_int32: Sampling rate used for max_dred_samples argument. Needs not match the actual sampling rate of the decoder. + * @param [out] dred_end opus_int32*: Number of non-encoded (silence) samples between the DRED timestamp and the last DRED sample. + * @param [in] defer_processing int: Flag (0 or 1). If set to one, the CPU-intensive part of the DRED decoding is deferred until opus_dred_process() is called. + * @returns Offset (positive) of the first decoded DRED samples, zero if no DRED is present, or @ref opus_errorcodes + */ +OPUS_EXPORT int opus_dred_parse(OpusDREDDecoder *dred_dec, OpusDRED *dred, const unsigned char *data, opus_int32 len, opus_int32 max_dred_samples, opus_int32 sampling_rate, int *dred_end, int defer_processing) OPUS_ARG_NONNULL(1); + +/** Finish decoding an Opus DRED packet. The function only needs to be called if opus_dred_parse() was called with defer_processing=1. + * The source and destination will often be the same DRED state. + * @param [in] dred_dec OpusDRED*: DRED Decoder state + * @param [in] src OpusDRED*: Source DRED state to start the processing from. + * @param [out] dst OpusDRED*: Destination DRED state to store the updated state after processing. + * @returns @ref opus_errorcodes + */ +OPUS_EXPORT int opus_dred_process(OpusDREDDecoder *dred_dec, const OpusDRED *src, OpusDRED *dst); + +/** Decode audio from an Opus DRED packet with floating point output. + * @param [in] st OpusDecoder*: Decoder state + * @param [in] dred OpusDRED*: DRED state + * @param [in] dred_offset opus_int32: position of the redundancy to decode (in samples before the beginning of the real audio data in the packet). + * @param [out] pcm opus_int16*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(opus_int16) + * @param [in] frame_size Number of samples per channel to decode in \a pcm. + * frame_size must be a multiple of 2.5 ms. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_EXPORT int opus_decoder_dred_decode(OpusDecoder *st, const OpusDRED *dred, opus_int32 dred_offset, opus_int16 *pcm, opus_int32 frame_size); + +/** Decode audio from an Opus DRED packet with floating point output. + * @param [in] st OpusDecoder*: Decoder state + * @param [in] dred OpusDRED*: DRED state + * @param [in] dred_offset opus_int32: position of the redundancy to decode (in samples before the beginning of the real audio data in the packet). + * @param [out] pcm float*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(float) + * @param [in] frame_size Number of samples per channel to decode in \a pcm. + * frame_size must be a multiple of 2.5 ms. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_EXPORT int opus_decoder_dred_decode_float(OpusDecoder *st, const OpusDRED *dred, opus_int32 dred_offset, float *pcm, opus_int32 frame_size); + + /** Parse an opus packet into one or more frames. * Opus_decode will perform this operation internally so most applications do * not need to use this function. @@ -583,6 +693,14 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned */ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, opus_int32 Fs) OPUS_ARG_NONNULL(1); +/** Checks whether an Opus packet has LBRR. + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @returns 1 is LBRR is present, 0 otherwise + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_has_lbrr(const unsigned char packet[], opus_int32 len); + /** Gets the number of samples of an Opus packet. * @param [in] dec OpusDecoder*: Decoder state * @param [in] packet char*: Opus packet diff --git a/src/libopus/opus_custom.h b/src/libopus/include/opus_custom.h similarity index 98% rename from src/libopus/opus_custom.h rename to src/libopus/include/opus_custom.h index 41f36bf2..2f22d4b3 100644 --- a/src/libopus/opus_custom.h +++ b/src/libopus/include/opus_custom.h @@ -104,7 +104,8 @@ typedef struct OpusCustomDecoder OpusCustomDecoder; /** The mode contains all the information necessary to create an encoder. Both the encoder and decoder need to be initialized with exactly the same mode, otherwise the output will be - corrupted. + corrupted. The mode MUST NOT BE DESTROYED until the encoders and + decoders that use it are destroyed as well. @brief Mode configuration */ typedef struct OpusCustomMode OpusCustomMode; @@ -178,7 +179,7 @@ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomEncoder *opus_custom_encode ) OPUS_ARG_NONNULL(1); -/** Destroys a an encoder state. +/** Destroys an encoder state. * @param[in] st OpusCustomEncoder*: State to be freed. */ OPUS_CUSTOM_EXPORT void opus_custom_encoder_destroy(OpusCustomEncoder *st); @@ -286,7 +287,7 @@ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomDecoder *opus_custom_decode int *error ) OPUS_ARG_NONNULL(1); -/** Destroys a an decoder state. +/** Destroys a decoder state. * @param[in] st OpusCustomDecoder*: State to be freed. */ OPUS_CUSTOM_EXPORT void opus_custom_decoder_destroy(OpusCustomDecoder *st); diff --git a/src/libopus/opus_defines.h b/src/libopus/include/opus_defines.h similarity index 94% rename from src/libopus/opus_defines.h rename to src/libopus/include/opus_defines.h index d141418b..cd8f4dde 100644 --- a/src/libopus/opus_defines.h +++ b/src/libopus/include/opus_defines.h @@ -64,7 +64,7 @@ extern "C" { /**Export control for opus functions */ #ifndef OPUS_EXPORT -# if defined(WIN32) +# if defined(_WIN32) # if defined(OPUS_BUILD) && defined(DLL_EXPORT) # define OPUS_EXPORT __declspec(dllexport) # else @@ -169,15 +169,32 @@ extern "C" { #define OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST 4046 #define OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST 4047 #define OPUS_GET_IN_DTX_REQUEST 4049 +#define OPUS_SET_DRED_DURATION_REQUEST 4050 +#define OPUS_GET_DRED_DURATION_REQUEST 4051 +#define OPUS_SET_DNN_BLOB_REQUEST 4052 +/*#define OPUS_GET_DNN_BLOB_REQUEST 4053 */ /** Defines for the presence of extended APIs. */ #define OPUS_HAVE_OPUS_PROJECTION_H /* Macros to trigger compilation errors when the wrong types are provided to a CTL */ #define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x)) + +#ifdef DISABLE_PTR_CHECK +/* Disable checks to prevent ubsan from complaining about NULL checks + in test_opus_api. */ +#define __opus_check_int_ptr(ptr) (ptr) +#define __opus_check_uint_ptr(ptr) (ptr) +#define __opus_check_uint8_ptr(ptr) (ptr) +#define __opus_check_val16_ptr(ptr) (ptr) +#define __opus_check_void_ptr(ptr) (ptr) +#else #define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr))) #define __opus_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr))) +#define __opus_check_uint8_ptr(ptr) ((ptr) + ((ptr) - (opus_uint8*)(ptr))) #define __opus_check_val16_ptr(ptr) ((ptr) + ((ptr) - (opus_val16*)(ptr))) +#define __opus_check_void_ptr(x) ((void)((void *)0 == (x)), (x)) +#endif /** @endcond */ /** @defgroup opus_ctlvalues Pre-defined values for CTL interface @@ -482,7 +499,8 @@ extern "C" { * @param[in] x opus_int32: Allowed values: *
*
0
Disable inband FEC (default).
- *
1
Enable inband FEC.
+ *
1
Inband FEC enabled. If the packet loss rate is sufficiently high, Opus will automatically switch to SILK even at high rates to enable use of that FEC.
+ *
2
Inband FEC enabled, but does not necessarily switch to SILK if we have music.
*
* @hideinitializer */ #define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x) @@ -491,7 +509,8 @@ extern "C" { * @param[out] x opus_int32 *: Returns one of the following values: *
*
0
Inband FEC disabled (default).
- *
1
Inband FEC enabled.
+ *
1
Inband FEC enabled. If the packet loss rate is sufficiently high, Opus will automatically switch to SILK even at high rates to enable use of that FEC.
+ *
2
Inband FEC enabled, but does not necessarily switch to SILK if we have music.
*
* @hideinitializer */ #define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x) @@ -618,6 +637,18 @@ extern "C" { * @hideinitializer */ #define OPUS_GET_PREDICTION_DISABLED(x) OPUS_GET_PREDICTION_DISABLED_REQUEST, __opus_check_int_ptr(x) +/** If non-zero, enables Deep Redundancy (DRED) and use the specified maximum number of 10-ms redundant frames + * @hideinitializer */ +#define OPUS_SET_DRED_DURATION(x) OPUS_SET_DRED_DURATION_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured Deep Redundancy (DRED) maximum number of frames. + * @hideinitializer */ +#define OPUS_GET_DRED_DURATION(x) OPUS_GET_DRED_DURATION_REQUEST, __opus_check_int_ptr(x) + +/** Provide external DNN weights from binary object (only when explicitly built without the weights) + * @hideinitializer */ +#define OPUS_SET_DNN_BLOB(data, len) OPUS_SET_DNN_BLOB_REQUEST, __opus_check_void_ptr(data), __opus_check_int(len) + + /**@}*/ /** @defgroup opus_genericctls Generic CTLs diff --git a/src/libopus/opus_multistream.h b/src/libopus/include/opus_multistream.h similarity index 99% rename from src/libopus/opus_multistream.h rename to src/libopus/include/opus_multistream.h index babcee69..824cc55a 100644 --- a/src/libopus/opus_multistream.h +++ b/src/libopus/include/opus_multistream.h @@ -143,7 +143,7 @@ extern "C" { * Vorbis * channel ordering. A decoder may wish to apply an additional permutation * to the mapping the encoder used to achieve a different output channel - * order (e.g. for outputing in WAV order). + * order (e.g. for outputting in WAV order). * * Each multistream packet contains an Opus packet for each stream, and all of * the Opus packets in a single multistream packet must have the same diff --git a/src/libopus/opus_projection.h b/src/libopus/include/opus_projection.h similarity index 100% rename from src/libopus/opus_projection.h rename to src/libopus/include/opus_projection.h diff --git a/src/libopus/opus_types.h b/src/libopus/include/opus_types.h similarity index 100% rename from src/libopus/opus_types.h rename to src/libopus/include/opus_types.h diff --git a/src/libopus/mapping_matrix.c b/src/libopus/mapping_matrix.c deleted file mode 100644 index eb5a68c4..00000000 --- a/src/libopus/mapping_matrix.c +++ /dev/null @@ -1,378 +0,0 @@ -/* Copyright (c) 2017 Google Inc. - Written by Andrew Allen */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -//#ifdef HAVE_CONFIG_H -#include "config.h" -//#endif - -#include "celt/arch.h" -#include "celt/float_cast.h" -#include "opus_private.h" -#include "opus_defines.h" -#include "mapping_matrix.h" - -#define MATRIX_INDEX(nb_rows, row, col) (nb_rows * col + row) - -opus_int32 mapping_matrix_get_size(int rows, int cols) -{ - opus_int32 size; - - /* Mapping Matrix must only support up to 255 channels in or out. - * Additionally, the total cell count must be <= 65004 octets in order - * for the matrix to be stored in an OGG header. - */ - if (rows > 255 || cols > 255) - return 0; - size = rows * (opus_int32)cols * sizeof(opus_int16); - if (size > 65004) - return 0; - - return align(sizeof(MappingMatrix)) + align(size); -} - -opus_int16 *mapping_matrix_get_data(const MappingMatrix *matrix) -{ - /* void* cast avoids clang -Wcast-align warning */ - return (opus_int16*)(void*)((char*)matrix + align(sizeof(MappingMatrix))); -} - -void mapping_matrix_init(MappingMatrix * const matrix, - int rows, int cols, int gain, const opus_int16 *data, opus_int32 data_size) -{ - int i; - opus_int16 *ptr; - -#if !defined(ENABLE_ASSERTIONS) - (void)data_size; -#endif - celt_assert(align(data_size) == align(rows * cols * sizeof(opus_int16))); - - matrix->rows = rows; - matrix->cols = cols; - matrix->gain = gain; - ptr = mapping_matrix_get_data(matrix); - for (i = 0; i < rows * cols; i++) - { - ptr[i] = data[i]; - } -} - -#ifndef DISABLE_FLOAT_API -void mapping_matrix_multiply_channel_in_float( - const MappingMatrix *matrix, - const float *input, - int input_rows, - opus_val16 *output, - int output_row, - int output_rows, - int frame_size) -{ - /* Matrix data is ordered col-wise. */ - opus_int16* matrix_data; - int i, col; - - celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows); - - matrix_data = mapping_matrix_get_data(matrix); - - for (i = 0; i < frame_size; i++) - { - float tmp = 0; - for (col = 0; col < input_rows; col++) - { - tmp += - matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] * - input[MATRIX_INDEX(input_rows, col, i)]; - } -#if defined(FIXED_POINT) - output[output_rows * i] = FLOAT2INT16((1/32768.f)*tmp); -#else - output[output_rows * i] = (1/32768.f)*tmp; -#endif - } -} - -void mapping_matrix_multiply_channel_out_float( - const MappingMatrix *matrix, - const opus_val16 *input, - int input_row, - int input_rows, - float *output, - int output_rows, - int frame_size -) -{ - /* Matrix data is ordered col-wise. */ - opus_int16* matrix_data; - int i, row; - float input_sample; - - celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows); - - matrix_data = mapping_matrix_get_data(matrix); - - for (i = 0; i < frame_size; i++) - { -#if defined(FIXED_POINT) - input_sample = (1/32768.f)*input[input_rows * i]; -#else - input_sample = input[input_rows * i]; -#endif - for (row = 0; row < output_rows; row++) - { - float tmp = - (1/32768.f)*matrix_data[MATRIX_INDEX(matrix->rows, row, input_row)] * - input_sample; - output[MATRIX_INDEX(output_rows, row, i)] += tmp; - } - } -} -#endif /* DISABLE_FLOAT_API */ - -void mapping_matrix_multiply_channel_in_short( - const MappingMatrix *matrix, - const opus_int16 *input, - int input_rows, - opus_val16 *output, - int output_row, - int output_rows, - int frame_size) -{ - /* Matrix data is ordered col-wise. */ - opus_int16* matrix_data; - int i, col; - - celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows); - - matrix_data = mapping_matrix_get_data(matrix); - - for (i = 0; i < frame_size; i++) - { - opus_val32 tmp = 0; - for (col = 0; col < input_rows; col++) - { -#if defined(FIXED_POINT) - tmp += - ((opus_int32)matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] * - (opus_int32)input[MATRIX_INDEX(input_rows, col, i)]) >> 8; -#else - tmp += - matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] * - input[MATRIX_INDEX(input_rows, col, i)]; -#endif - } -#if defined(FIXED_POINT) - output[output_rows * i] = (opus_int16)((tmp + 64) >> 7); -#else - output[output_rows * i] = (1/(32768.f*32768.f))*tmp; -#endif - } -} - -void mapping_matrix_multiply_channel_out_short( - const MappingMatrix *matrix, - const opus_val16 *input, - int input_row, - int input_rows, - opus_int16 *output, - int output_rows, - int frame_size) -{ - /* Matrix data is ordered col-wise. */ - opus_int16* matrix_data; - int i, row; - opus_int32 input_sample; - - celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows); - - matrix_data = mapping_matrix_get_data(matrix); - - for (i = 0; i < frame_size; i++) - { -#if defined(FIXED_POINT) - input_sample = (opus_int32)input[input_rows * i]; -#else - input_sample = (opus_int32)FLOAT2INT16(input[input_rows * i]); -#endif - for (row = 0; row < output_rows; row++) - { - opus_int32 tmp = - (opus_int32)matrix_data[MATRIX_INDEX(matrix->rows, row, input_row)] * - input_sample; - output[MATRIX_INDEX(output_rows, row, i)] += (tmp + 16384) >> 15; - } - } -} - -const MappingMatrix mapping_matrix_foa_mixing = { 6, 6, 0 }; -const opus_int16 mapping_matrix_foa_mixing_data[36] = { - 16384, 0, -16384, 23170, 0, 0, 16384, 23170, - 16384, 0, 0, 0, 16384, 0, -16384, -23170, - 0, 0, 16384, -23170, 16384, 0, 0, 0, - 0, 0, 0, 0, 32767, 0, 0, 0, - 0, 0, 0, 32767 -}; - -const MappingMatrix mapping_matrix_soa_mixing = { 11, 11, 0 }; -const opus_int16 mapping_matrix_soa_mixing_data[121] = { - 10923, 7723, 13377, -13377, 11585, 9459, 7723, -16384, - -6689, 0, 0, 10923, 7723, 13377, 13377, -11585, - 9459, 7723, 16384, -6689, 0, 0, 10923, -15447, - 13377, 0, 0, -18919, 7723, 0, 13377, 0, - 0, 10923, 7723, -13377, -13377, 11585, -9459, 7723, - 16384, -6689, 0, 0, 10923, -7723, 0, 13377, - -16384, 0, -15447, 0, 9459, 0, 0, 10923, - -7723, 0, -13377, 16384, 0, -15447, 0, 9459, - 0, 0, 10923, 15447, 0, 0, 0, 0, - -15447, 0, -18919, 0, 0, 10923, 7723, -13377, - 13377, -11585, -9459, 7723, -16384, -6689, 0, 0, - 10923, -15447, -13377, 0, 0, 18919, 7723, 0, - 13377, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 32767, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 32767 -}; - -const MappingMatrix mapping_matrix_toa_mixing = { 18, 18, 0 }; -const opus_int16 mapping_matrix_toa_mixing_data[324] = { - 8208, 0, -881, 14369, 0, 0, -8192, -4163, - 13218, 0, 0, 0, 11095, -8836, -6218, 14833, - 0, 0, 8208, -10161, 881, 10161, -13218, -2944, - -8192, 2944, 0, -10488, -6218, 6248, -11095, -6248, - 0, -10488, 0, 0, 8208, 10161, 881, -10161, - -13218, 2944, -8192, -2944, 0, 10488, -6218, -6248, - -11095, 6248, 0, 10488, 0, 0, 8176, 5566, - -11552, 5566, 9681, -11205, 8192, -11205, 0, 4920, - -15158, 9756, -3334, 9756, 0, -4920, 0, 0, - 8176, 7871, 11552, 0, 0, 15846, 8192, 0, - -9681, -6958, 0, 13797, 3334, 0, -15158, 0, - 0, 0, 8176, 0, 11552, 7871, 0, 0, - 8192, 15846, 9681, 0, 0, 0, 3334, 13797, - 15158, 6958, 0, 0, 8176, 5566, -11552, -5566, - -9681, -11205, 8192, 11205, 0, 4920, 15158, 9756, - -3334, -9756, 0, 4920, 0, 0, 8208, 14369, - -881, 0, 0, -4163, -8192, 0, -13218, -14833, - 0, -8836, 11095, 0, 6218, 0, 0, 0, - 8208, 10161, 881, 10161, 13218, 2944, -8192, 2944, - 0, 10488, 6218, -6248, -11095, -6248, 0, -10488, - 0, 0, 8208, -14369, -881, 0, 0, 4163, - -8192, 0, -13218, 14833, 0, 8836, 11095, 0, - 6218, 0, 0, 0, 8208, 0, -881, -14369, - 0, 0, -8192, 4163, 13218, 0, 0, 0, - 11095, 8836, -6218, -14833, 0, 0, 8176, -5566, - -11552, 5566, -9681, 11205, 8192, -11205, 0, -4920, - 15158, -9756, -3334, 9756, 0, -4920, 0, 0, - 8176, 0, 11552, -7871, 0, 0, 8192, -15846, - 9681, 0, 0, 0, 3334, -13797, 15158, -6958, - 0, 0, 8176, -7871, 11552, 0, 0, -15846, - 8192, 0, -9681, 6958, 0, -13797, 3334, 0, - -15158, 0, 0, 0, 8176, -5566, -11552, -5566, - 9681, 11205, 8192, 11205, 0, -4920, -15158, -9756, - -3334, -9756, 0, 4920, 0, 0, 8208, -10161, - 881, -10161, 13218, -2944, -8192, -2944, 0, -10488, - 6218, 6248, -11095, 6248, 0, 10488, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 32767, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 32767 -}; - -const MappingMatrix mapping_matrix_foa_demixing = { 6, 6, 0 }; -const opus_int16 mapping_matrix_foa_demixing_data[36] = { - 16384, 16384, 16384, 16384, 0, 0, 0, 23170, - 0, -23170, 0, 0, -16384, 16384, -16384, 16384, - 0, 0, 23170, 0, -23170, 0, 0, 0, - 0, 0, 0, 0, 32767, 0, 0, 0, - 0, 0, 0, 32767 -}; - -const MappingMatrix mapping_matrix_soa_demixing = { 11, 11, 3050 }; -const opus_int16 mapping_matrix_soa_demixing_data[121] = { - 2771, 2771, 2771, 2771, 2771, 2771, 2771, 2771, - 2771, 0, 0, 10033, 10033, -20066, 10033, 14189, - 14189, -28378, 10033, -20066, 0, 0, 3393, 3393, - 3393, -3393, 0, 0, 0, -3393, -3393, 0, - 0, -17378, 17378, 0, -17378, -24576, 24576, 0, - 17378, 0, 0, 0, -14189, 14189, 0, -14189, - -28378, 28378, 0, 14189, 0, 0, 0, 2399, - 2399, -4799, -2399, 0, 0, 0, -2399, 4799, - 0, 0, 1959, 1959, 1959, 1959, -3918, -3918, - -3918, 1959, 1959, 0, 0, -4156, 4156, 0, - 4156, 0, 0, 0, -4156, 0, 0, 0, - 8192, 8192, -16384, 8192, 16384, 16384, -32768, 8192, - -16384, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8312, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 8312 -}; - -const MappingMatrix mapping_matrix_toa_demixing = { 18, 18, 0 }; -const opus_int16 mapping_matrix_toa_demixing_data[324] = { - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, - 0, 0, 0, -9779, 9779, 6263, 8857, 0, - 6263, 13829, 9779, -13829, 0, -6263, 0, -8857, - -6263, -9779, 0, 0, -3413, 3413, 3413, -11359, - 11359, 11359, -11359, -3413, 3413, -3413, -3413, -11359, - 11359, 11359, -11359, 3413, 0, 0, 13829, 9779, - -9779, 6263, 0, 8857, -6263, 0, 9779, 0, - -13829, 6263, -8857, 0, -6263, -9779, 0, 0, - 0, -15617, -15617, 6406, 0, 0, -6406, 0, - 15617, 0, 0, -6406, 0, 0, 6406, 15617, - 0, 0, 0, -5003, 5003, -10664, 15081, 0, - -10664, -7075, 5003, 7075, 0, 10664, 0, -15081, - 10664, -5003, 0, 0, -8176, -8176, -8176, 8208, - 8208, 8208, 8208, -8176, -8176, -8176, -8176, 8208, - 8208, 8208, 8208, -8176, 0, 0, -7075, 5003, - -5003, -10664, 0, 15081, 10664, 0, 5003, 0, - 7075, -10664, -15081, 0, 10664, -5003, 0, 0, - 15617, 0, 0, 0, -6406, 6406, 0, -15617, - 0, -15617, 15617, 0, 6406, -6406, 0, 0, - 0, 0, 0, -11393, 11393, 2993, -4233, 0, - 2993, -16112, 11393, 16112, 0, -2993, 0, 4233, - -2993, -11393, 0, 0, 0, -9974, -9974, -13617, - 0, 0, 13617, 0, 9974, 0, 0, 13617, - 0, 0, -13617, 9974, 0, 0, 0, 5579, - -5579, 10185, 14403, 0, 10185, -7890, -5579, 7890, - 0, -10185, 0, -14403, -10185, 5579, 0, 0, - 11826, -11826, -11826, -901, 901, 901, -901, 11826, - -11826, 11826, 11826, -901, 901, 901, -901, -11826, - 0, 0, -7890, -5579, 5579, 10185, 0, 14403, - -10185, 0, -5579, 0, 7890, 10185, -14403, 0, - -10185, 5579, 0, 0, -9974, 0, 0, 0, - -13617, 13617, 0, 9974, 0, 9974, -9974, 0, - 13617, -13617, 0, 0, 0, 0, 16112, -11393, - 11393, -2993, 0, 4233, 2993, 0, -11393, 0, - -16112, -2993, -4233, 0, 2993, 11393, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 32767, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 32767 -}; - diff --git a/src/libopus/mapping_matrix.h b/src/libopus/mapping_matrix.h deleted file mode 100644 index 98bc82df..00000000 --- a/src/libopus/mapping_matrix.h +++ /dev/null @@ -1,133 +0,0 @@ -/* Copyright (c) 2017 Google Inc. - Written by Andrew Allen */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/** - * @file mapping_matrix.h - * @brief Opus reference implementation mapping matrix API - */ - -#ifndef MAPPING_MATRIX_H -#define MAPPING_MATRIX_H - -#include "opus_types.h" -#include "opus_projection.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct MappingMatrix -{ - int rows; /* number of channels outputted from matrix. */ - int cols; /* number of channels inputted to matrix. */ - int gain; /* in dB. S7.8-format. */ - /* Matrix cell data goes here using col-wise ordering. */ -} MappingMatrix; - -opus_int32 mapping_matrix_get_size(int rows, int cols); - -opus_int16 *mapping_matrix_get_data(const MappingMatrix *matrix); - -void mapping_matrix_init( - MappingMatrix * const matrix, - int rows, - int cols, - int gain, - const opus_int16 *data, - opus_int32 data_size -); - -#ifndef DISABLE_FLOAT_API -void mapping_matrix_multiply_channel_in_float( - const MappingMatrix *matrix, - const float *input, - int input_rows, - opus_val16 *output, - int output_row, - int output_rows, - int frame_size -); - -void mapping_matrix_multiply_channel_out_float( - const MappingMatrix *matrix, - const opus_val16 *input, - int input_row, - int input_rows, - float *output, - int output_rows, - int frame_size -); -#endif /* DISABLE_FLOAT_API */ - -void mapping_matrix_multiply_channel_in_short( - const MappingMatrix *matrix, - const opus_int16 *input, - int input_rows, - opus_val16 *output, - int output_row, - int output_rows, - int frame_size -); - -void mapping_matrix_multiply_channel_out_short( - const MappingMatrix *matrix, - const opus_val16 *input, - int input_row, - int input_rows, - opus_int16 *output, - int output_rows, - int frame_size -); - -/* Pre-computed mixing and demixing matrices for 1st to 3rd-order ambisonics. - * foa: first-order ambisonics - * soa: second-order ambisonics - * toa: third-order ambisonics - */ -extern const MappingMatrix mapping_matrix_foa_mixing; -extern const opus_int16 mapping_matrix_foa_mixing_data[36]; - -extern const MappingMatrix mapping_matrix_soa_mixing; -extern const opus_int16 mapping_matrix_soa_mixing_data[121]; - -extern const MappingMatrix mapping_matrix_toa_mixing; -extern const opus_int16 mapping_matrix_toa_mixing_data[324]; - -extern const MappingMatrix mapping_matrix_foa_demixing; -extern const opus_int16 mapping_matrix_foa_demixing_data[36]; - -extern const MappingMatrix mapping_matrix_soa_demixing; -extern const opus_int16 mapping_matrix_soa_demixing_data[121]; - -extern const MappingMatrix mapping_matrix_toa_demixing; -extern const opus_int16 mapping_matrix_toa_demixing_data[324]; - -#ifdef __cplusplus -} -#endif - -#endif /* MAPPING_MATRIX_H */ diff --git a/src/libopus/mlp.h b/src/libopus/mlp.h deleted file mode 100644 index d7670550..00000000 --- a/src/libopus/mlp.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2017 Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef _MLP_H_ -#define _MLP_H_ - -#include "opus_types.h" - -#define WEIGHTS_SCALE (1.f/128) - -#define MAX_NEURONS 32 - -typedef struct { - const opus_int8 *bias; - const opus_int8 *input_weights; - int nb_inputs; - int nb_neurons; - int sigmoid; -} DenseLayer; - -typedef struct { - const opus_int8 *bias; - const opus_int8 *input_weights; - const opus_int8 *recurrent_weights; - int nb_inputs; - int nb_neurons; -} GRULayer; - -extern const DenseLayer layer0; -extern const GRULayer layer1; -extern const DenseLayer layer2; - -void compute_dense(const DenseLayer *layer, float *output, const float *input); - -void compute_gru(const GRULayer *gru, float *state, const float *input); - -#endif /* _MLP_H_ */ diff --git a/src/libopus/opus.pc b/src/libopus/opus.pc deleted file mode 100644 index da284cf9..00000000 --- a/src/libopus/opus.pc +++ /dev/null @@ -1,16 +0,0 @@ -# Opus codec reference implementation pkg-config file - -prefix=/usr/local -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -includedir=${prefix}/include - -Name: Opus -Description: Opus IETF audio codec (fixed-point build) -URL: https://opus-codec.org/ -Version: 1.3.1 -Requires: -Conflicts: -Libs: -L${libdir} -lopus -Libs.private: -lm -Cflags: -I${includedir}/opus diff --git a/src/libopus/opus_encoder.c b/src/libopus/opus_encoder.c deleted file mode 100644 index fda4fd15..00000000 --- a/src/libopus/opus_encoder.c +++ /dev/null @@ -1,2783 +0,0 @@ -/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited - Written by Jean-Marc Valin and Koen Vos */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -//#ifdef HAVE_CONFIG_H -#include "config.h" -//#endif - -#include -#include "celt/celt.h" -#include "celt/entenc.h" -#include "celt/modes.h" -#include "silk/API.h" -#include "celt/stack_alloc.h" -#include "celt/float_cast.h" -#include "opus.h" -#include "celt/arch.h" -#include "celt/pitch.h" -#include "opus_private.h" -#include "celt/os_support.h" -#include "celt/cpu_support.h" -#include "analysis.h" -#include "celt/mathops.h" -#include "silk/tuning_parameters.h" -#ifdef FIXED_POINT -#include "silk/fixed/structs_FIX.h" -#else -#include "silk/float/structs_FLP.h" -#endif - -#define MAX_ENCODER_BUFFER 480 - -#ifndef DISABLE_FLOAT_API -#define PSEUDO_SNR_THRESHOLD 316.23f /* 10^(25/10) */ -#endif - -typedef struct { - opus_val32 XX, XY, YY; - opus_val16 smoothed_width; - opus_val16 max_follower; -} StereoWidthState; - -struct OpusEncoder { - int celt_enc_offset; - int silk_enc_offset; - silk_EncControlStruct silk_mode; - int application; - int channels; - int delay_compensation; - int force_channels; - int signal_type; - int user_bandwidth; - int max_bandwidth; - int user_forced_mode; - int voice_ratio; - opus_int32 Fs; - int use_vbr; - int vbr_constraint; - int variable_duration; - opus_int32 bitrate_bps; - opus_int32 user_bitrate_bps; - int lsb_depth; - int encoder_buffer; - int lfe; - int arch; - int use_dtx; /* general DTX for both SILK and CELT */ -#ifndef DISABLE_FLOAT_API - TonalityAnalysisState analysis; -#endif - -#define OPUS_ENCODER_RESET_START stream_channels - int stream_channels; - opus_int16 hybrid_stereo_width_Q14; - opus_int32 variable_HP_smth2_Q15; - opus_val16 prev_HB_gain; - opus_val32 hp_mem[4]; - int mode; - int prev_mode; - int prev_channels; - int prev_framesize; - int bandwidth; - /* Bandwidth determined automatically from the rate (before any other adjustment) */ - int auto_bandwidth; - int silk_bw_switch; - /* Sampling rate (at the API level) */ - int first; - opus_val16 * energy_masking; - StereoWidthState width_mem; - opus_val16 delay_buffer[MAX_ENCODER_BUFFER*2]; -#ifndef DISABLE_FLOAT_API - int detected_bandwidth; - int nb_no_activity_frames; - opus_val32 peak_signal_energy; -#endif - int nonfinal_frame; /* current frame is not the final in a packet */ - opus_uint32 rangeFinal; -}; - -/* Transition tables for the voice and music. First column is the - middle (memoriless) threshold. The second column is the hysteresis - (difference with the middle) */ -static const opus_int32 mono_voice_bandwidth_thresholds[8] = { - 9000, 700, /* NB<->MB */ - 9000, 700, /* MB<->WB */ - 13500, 1000, /* WB<->SWB */ - 14000, 2000, /* SWB<->FB */ -}; -static const opus_int32 mono_music_bandwidth_thresholds[8] = { - 9000, 700, /* NB<->MB */ - 9000, 700, /* MB<->WB */ - 11000, 1000, /* WB<->SWB */ - 12000, 2000, /* SWB<->FB */ -}; -static const opus_int32 stereo_voice_bandwidth_thresholds[8] = { - 9000, 700, /* NB<->MB */ - 9000, 700, /* MB<->WB */ - 13500, 1000, /* WB<->SWB */ - 14000, 2000, /* SWB<->FB */ -}; -static const opus_int32 stereo_music_bandwidth_thresholds[8] = { - 9000, 700, /* NB<->MB */ - 9000, 700, /* MB<->WB */ - 11000, 1000, /* WB<->SWB */ - 12000, 2000, /* SWB<->FB */ -}; -/* Threshold bit-rates for switching between mono and stereo */ -static const opus_int32 stereo_voice_threshold = 19000; -static const opus_int32 stereo_music_threshold = 17000; - -/* Threshold bit-rate for switching between SILK/hybrid and CELT-only */ -static const opus_int32 mode_thresholds[2][2] = { - /* voice */ /* music */ - { 64000, 10000}, /* mono */ - { 44000, 10000}, /* stereo */ -}; - -static const opus_int32 fec_thresholds[] = { - 12000, 1000, /* NB */ - 14000, 1000, /* MB */ - 16000, 1000, /* WB */ - 20000, 1000, /* SWB */ - 22000, 1000, /* FB */ -}; - -int opus_encoder_get_size(int channels) -{ - int silkEncSizeBytes, celtEncSizeBytes; - int ret; - if (channels<1 || channels > 2) - return 0; - ret = silk_Get_Encoder_Size( &silkEncSizeBytes ); - if (ret) - return 0; - silkEncSizeBytes = align(silkEncSizeBytes); - celtEncSizeBytes = celt_encoder_get_size(channels); - return align(sizeof(OpusEncoder))+silkEncSizeBytes+celtEncSizeBytes; -} - -int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int application) -{ - void *silk_enc; - CELTEncoder *celt_enc; - int err; - int ret, silkEncSizeBytes; - - if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)|| - (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO - && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY)) - return OPUS_BAD_ARG; - - OPUS_CLEAR((char*)st, opus_encoder_get_size(channels)); - /* Create SILK encoder */ - ret = silk_Get_Encoder_Size( &silkEncSizeBytes ); - if (ret) - return OPUS_BAD_ARG; - silkEncSizeBytes = align(silkEncSizeBytes); - st->silk_enc_offset = align(sizeof(OpusEncoder)); - st->celt_enc_offset = st->silk_enc_offset+silkEncSizeBytes; - silk_enc = (char*)st+st->silk_enc_offset; - celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); - - st->stream_channels = st->channels = channels; - - st->Fs = Fs; - - st->arch = opus_select_arch(); - - ret = silk_InitEncoder( silk_enc, st->arch, &st->silk_mode ); - if(ret)return OPUS_INTERNAL_ERROR; - - /* default SILK parameters */ - st->silk_mode.nChannelsAPI = channels; - st->silk_mode.nChannelsInternal = channels; - st->silk_mode.API_sampleRate = st->Fs; - st->silk_mode.maxInternalSampleRate = 16000; - st->silk_mode.minInternalSampleRate = 8000; - st->silk_mode.desiredInternalSampleRate = 16000; - st->silk_mode.payloadSize_ms = 20; - st->silk_mode.bitRate = 25000; - st->silk_mode.packetLossPercentage = 0; - st->silk_mode.complexity = 9; - st->silk_mode.useInBandFEC = 0; - st->silk_mode.useDTX = 0; - st->silk_mode.useCBR = 0; - st->silk_mode.reducedDependency = 0; - - /* Create CELT encoder */ - /* Initialize CELT encoder */ - err = celt_encoder_init(celt_enc, Fs, channels, st->arch); - if(err!=OPUS_OK)return OPUS_INTERNAL_ERROR; - - celt_encoder_ctl(celt_enc, CELT_SET_SIGNALLING(0)); - celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(st->silk_mode.complexity)); - - st->use_vbr = 1; - /* Makes constrained VBR the default (safer for real-time use) */ - st->vbr_constraint = 1; - st->user_bitrate_bps = OPUS_AUTO; - st->bitrate_bps = 3000+Fs*channels; - st->application = application; - st->signal_type = OPUS_AUTO; - st->user_bandwidth = OPUS_AUTO; - st->max_bandwidth = OPUS_BANDWIDTH_FULLBAND; - st->force_channels = OPUS_AUTO; - st->user_forced_mode = OPUS_AUTO; - st->voice_ratio = -1; - st->encoder_buffer = st->Fs/100; - st->lsb_depth = 24; - st->variable_duration = OPUS_FRAMESIZE_ARG; - - /* Delay compensation of 4 ms (2.5 ms for SILK's extra look-ahead - + 1.5 ms for SILK resamplers and stereo prediction) */ - st->delay_compensation = st->Fs/250; - - st->hybrid_stereo_width_Q14 = 1 << 14; - st->prev_HB_gain = Q15ONE; - st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ); - st->first = 1; - st->mode = MODE_HYBRID; - st->bandwidth = OPUS_BANDWIDTH_FULLBAND; - -#ifndef DISABLE_FLOAT_API - tonality_analysis_init(&st->analysis, st->Fs); - st->analysis.application = st->application; -#endif - - return OPUS_OK; -} - -static unsigned char gen_toc(int mode, int framerate, int bandwidth, int channels) -{ - int period; - unsigned char toc; - period = 0; - while (framerate < 400) - { - framerate <<= 1; - period++; - } - if (mode == MODE_SILK_ONLY) - { - toc = (bandwidth-OPUS_BANDWIDTH_NARROWBAND)<<5; - toc |= (period-2)<<3; - } else if (mode == MODE_CELT_ONLY) - { - int tmp = bandwidth-OPUS_BANDWIDTH_MEDIUMBAND; - if (tmp < 0) - tmp = 0; - toc = 0x80; - toc |= tmp << 5; - toc |= period<<3; - } else /* Hybrid */ - { - toc = 0x60; - toc |= (bandwidth-OPUS_BANDWIDTH_SUPERWIDEBAND)<<4; - toc |= (period-2)<<3; - } - toc |= (channels==2)<<2; - return toc; -} - -#ifndef FIXED_POINT -static void silk_biquad_float( - const opus_val16 *in, /* I: Input signal */ - const opus_int32 *B_Q28, /* I: MA coefficients [3] */ - const opus_int32 *A_Q28, /* I: AR coefficients [2] */ - opus_val32 *S, /* I/O: State vector [2] */ - opus_val16 *out, /* O: Output signal */ - const opus_int32 len, /* I: Signal length (must be even) */ - int stride -) -{ - /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */ - opus_int k; - opus_val32 vout; - opus_val32 inval; - opus_val32 A[2], B[3]; - - A[0] = (opus_val32)(A_Q28[0] * (1.f/((opus_int32)1<<28))); - A[1] = (opus_val32)(A_Q28[1] * (1.f/((opus_int32)1<<28))); - B[0] = (opus_val32)(B_Q28[0] * (1.f/((opus_int32)1<<28))); - B[1] = (opus_val32)(B_Q28[1] * (1.f/((opus_int32)1<<28))); - B[2] = (opus_val32)(B_Q28[2] * (1.f/((opus_int32)1<<28))); - - /* Negate A_Q28 values and split in two parts */ - - for( k = 0; k < len; k++ ) { - /* S[ 0 ], S[ 1 ]: Q12 */ - inval = in[ k*stride ]; - vout = S[ 0 ] + B[0]*inval; - - S[ 0 ] = S[1] - vout*A[0] + B[1]*inval; - - S[ 1 ] = - vout*A[1] + B[2]*inval + VERY_SMALL; - - /* Scale back to Q0 and saturate */ - out[ k*stride ] = vout; - } -} -#endif - -static void hp_cutoff(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs, int arch) -{ - opus_int32 B_Q28[ 3 ], A_Q28[ 2 ]; - opus_int32 Fc_Q19, r_Q28, r_Q22; - (void)arch; - - silk_assert( cutoff_Hz <= silk_int32_MAX / SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ) ); - Fc_Q19 = silk_DIV32_16( silk_SMULBB( SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ), cutoff_Hz ), Fs/1000 ); - silk_assert( Fc_Q19 > 0 && Fc_Q19 < 32768 ); - - r_Q28 = SILK_FIX_CONST( 1.0, 28 ) - silk_MUL( SILK_FIX_CONST( 0.92, 9 ), Fc_Q19 ); - - /* b = r * [ 1; -2; 1 ]; */ - /* a = [ 1; -2 * r * ( 1 - 0.5 * Fc^2 ); r^2 ]; */ - B_Q28[ 0 ] = r_Q28; - B_Q28[ 1 ] = silk_LSHIFT( -r_Q28, 1 ); - B_Q28[ 2 ] = r_Q28; - - /* -r * ( 2 - Fc * Fc ); */ - r_Q22 = silk_RSHIFT( r_Q28, 6 ); - A_Q28[ 0 ] = silk_SMULWW( r_Q22, silk_SMULWW( Fc_Q19, Fc_Q19 ) - SILK_FIX_CONST( 2.0, 22 ) ); - A_Q28[ 1 ] = silk_SMULWW( r_Q22, r_Q22 ); - -#ifdef FIXED_POINT - if( channels == 1 ) { - silk_biquad_alt_stride1( in, B_Q28, A_Q28, hp_mem, out, len ); - } else { - silk_biquad_alt_stride2( in, B_Q28, A_Q28, hp_mem, out, len, arch ); - } -#else - silk_biquad_float( in, B_Q28, A_Q28, hp_mem, out, len, channels ); - if( channels == 2 ) { - silk_biquad_float( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels ); - } -#endif -} - -#ifdef FIXED_POINT -static void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs) -{ - int c, i; - int shift; - - /* Approximates -round(log2(6.3*cutoff_Hz/Fs)) */ - shift=celt_ilog2(Fs/(cutoff_Hz*4)); - for (c=0;cFs/400; - if (st->user_bitrate_bps==OPUS_AUTO) - return 60*st->Fs/frame_size + st->Fs*st->channels; - else if (st->user_bitrate_bps==OPUS_BITRATE_MAX) - return max_data_bytes*8*st->Fs/frame_size; - else - return st->user_bitrate_bps; -} - -#ifndef DISABLE_FLOAT_API -#ifdef FIXED_POINT -#define PCM2VAL(x) FLOAT2INT16(x) -#else -#define PCM2VAL(x) SCALEIN(x) -#endif - -void downmix_float(const void *_x, opus_val32 *y, int subframe, int offset, int c1, int c2, int C) -{ - const float *x; - int j; - - x = (const float *)_x; - for (j=0;j-1) - { - for (j=0;j-1) - { - for (j=0;j= OPUS_FRAMESIZE_2_5_MS && variable_duration <= OPUS_FRAMESIZE_120_MS) - { - if (variable_duration <= OPUS_FRAMESIZE_40_MS) - new_size = (Fs/400)<<(variable_duration-OPUS_FRAMESIZE_2_5_MS); - else - new_size = (variable_duration-OPUS_FRAMESIZE_2_5_MS-2)*Fs/50; - } - else - return -1; - if (new_size>frame_size) - return -1; - if (400*new_size!=Fs && 200*new_size!=Fs && 100*new_size!=Fs && - 50*new_size!=Fs && 25*new_size!=Fs && 50*new_size!=3*Fs && - 50*new_size!=4*Fs && 50*new_size!=5*Fs && 50*new_size!=6*Fs) - return -1; - return new_size; -} - -opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int32 Fs, StereoWidthState *mem) -{ - opus_val32 xx, xy, yy; - opus_val16 sqrt_xx, sqrt_yy; - opus_val16 qrrt_xx, qrrt_yy; - int frame_rate; - int i; - opus_val16 short_alpha; - - frame_rate = Fs/frame_size; - short_alpha = Q15ONE - MULT16_16(25, Q15ONE)/IMAX(50,frame_rate); - xx=xy=yy=0; - /* Unroll by 4. The frame size is always a multiple of 4 *except* for - 2.5 ms frames at 12 kHz. Since this setting is very rare (and very - stupid), we just discard the last two samples. */ - for (i=0;iXX += MULT16_32_Q15(short_alpha, xx-mem->XX); - mem->XY += MULT16_32_Q15(short_alpha, xy-mem->XY); - mem->YY += MULT16_32_Q15(short_alpha, yy-mem->YY); - mem->XX = MAX32(0, mem->XX); - mem->XY = MAX32(0, mem->XY); - mem->YY = MAX32(0, mem->YY); - if (MAX32(mem->XX, mem->YY)>QCONST16(8e-4f, 18)) - { - opus_val16 corr; - opus_val16 ldiff; - opus_val16 width; - sqrt_xx = celt_sqrt(mem->XX); - sqrt_yy = celt_sqrt(mem->YY); - qrrt_xx = celt_sqrt(sqrt_xx); - qrrt_yy = celt_sqrt(sqrt_yy); - /* Inter-channel correlation */ - mem->XY = MIN32(mem->XY, sqrt_xx*sqrt_yy); - corr = SHR32(frac_div32(mem->XY,EPSILON+MULT16_16(sqrt_xx,sqrt_yy)),16); - /* Approximate loudness difference */ - ldiff = MULT16_16(Q15ONE, ABS16(qrrt_xx-qrrt_yy))/(EPSILON+qrrt_xx+qrrt_yy); - width = MULT16_16_Q15(celt_sqrt(QCONST32(1.f,30)-MULT16_16(corr,corr)), ldiff); - /* Smoothing over one second */ - mem->smoothed_width += (width-mem->smoothed_width)/frame_rate; - /* Peak follower */ - mem->max_follower = MAX16(mem->max_follower-QCONST16(.02f,15)/frame_rate, mem->smoothed_width); - } - /*printf("%f %f %f %f %f ", corr/(float)Q15ONE, ldiff/(float)Q15ONE, width/(float)Q15ONE, mem->smoothed_width/(float)Q15ONE, mem->max_follower/(float)Q15ONE);*/ - return EXTRACT16(MIN32(Q15ONE, MULT16_16(20, mem->max_follower))); -} - -static int decide_fec(int useInBandFEC, int PacketLoss_perc, int last_fec, int mode, int *bandwidth, opus_int32 rate) -{ - int orig_bandwidth; - if (!useInBandFEC || PacketLoss_perc == 0 || mode == MODE_CELT_ONLY) - return 0; - orig_bandwidth = *bandwidth; - for (;;) - { - opus_int32 hysteresis; - opus_int32 LBRR_rate_thres_bps; - /* Compute threshold for using FEC at the current bandwidth setting */ - LBRR_rate_thres_bps = fec_thresholds[2*(*bandwidth - OPUS_BANDWIDTH_NARROWBAND)]; - hysteresis = fec_thresholds[2*(*bandwidth - OPUS_BANDWIDTH_NARROWBAND) + 1]; - if (last_fec == 1) LBRR_rate_thres_bps -= hysteresis; - if (last_fec == 0) LBRR_rate_thres_bps += hysteresis; - LBRR_rate_thres_bps = silk_SMULWB( silk_MUL( LBRR_rate_thres_bps, - 125 - silk_min( PacketLoss_perc, 25 ) ), SILK_FIX_CONST( 0.01, 16 ) ); - /* If loss <= 5%, we look at whether we have enough rate to enable FEC. - If loss > 5%, we decrease the bandwidth until we can enable FEC. */ - if (rate > LBRR_rate_thres_bps) - return 1; - else if (PacketLoss_perc <= 5) - return 0; - else if (*bandwidth > OPUS_BANDWIDTH_NARROWBAND) - (*bandwidth)--; - else - break; - } - /* Couldn't find any bandwidth to enable FEC, keep original bandwidth. */ - *bandwidth = orig_bandwidth; - return 0; -} - -static int compute_silk_rate_for_hybrid(int rate, int bandwidth, int frame20ms, int vbr, int fec, int channels) { - int entry; - int i; - int N; - int silk_rate; - static int rate_table[][5] = { - /* |total| |-------- SILK------------| - |-- No FEC -| |--- FEC ---| - 10ms 20ms 10ms 20ms */ - { 0, 0, 0, 0, 0}, - {12000, 10000, 10000, 11000, 11000}, - {16000, 13500, 13500, 15000, 15000}, - {20000, 16000, 16000, 18000, 18000}, - {24000, 18000, 18000, 21000, 21000}, - {32000, 22000, 22000, 28000, 28000}, - {64000, 38000, 38000, 50000, 50000} - }; - /* Do the allocation per-channel. */ - rate /= channels; - entry = 1 + frame20ms + 2*fec; - N = sizeof(rate_table)/sizeof(rate_table[0]); - for (i=1;i rate) break; - } - if (i == N) - { - silk_rate = rate_table[i-1][entry]; - /* For now, just give 50% of the extra bits to SILK. */ - silk_rate += (rate-rate_table[i-1][0])/2; - } else { - opus_int32 lo, hi, x0, x1; - lo = rate_table[i-1][entry]; - hi = rate_table[i][entry]; - x0 = rate_table[i-1][0]; - x1 = rate_table[i][0]; - silk_rate = (lo*(x1-rate) + hi*(rate-x0))/(x1-x0); - } - if (!vbr) - { - /* Tiny boost to SILK for CBR. We should probably tune this better. */ - silk_rate += 100; - } - if (bandwidth==OPUS_BANDWIDTH_SUPERWIDEBAND) - silk_rate += 300; - silk_rate *= channels; - /* Small adjustment for stereo (calibrated for 32 kb/s, haven't tried other bitrates). */ - if (channels == 2 && rate >= 12000) - silk_rate -= 1000; - return silk_rate; -} - -/* Returns the equivalent bitrate corresponding to 20 ms frames, - complexity 10 VBR operation. */ -static opus_int32 compute_equiv_rate(opus_int32 bitrate, int channels, - int frame_rate, int vbr, int mode, int complexity, int loss) -{ - opus_int32 equiv; - equiv = bitrate; - /* Take into account overhead from smaller frames. */ - if (frame_rate > 50) - equiv -= (40*channels+20)*(frame_rate - 50); - /* CBR is about a 8% penalty for both SILK and CELT. */ - if (!vbr) - equiv -= equiv/12; - /* Complexity makes about 10% difference (from 0 to 10) in general. */ - equiv = equiv * (90+complexity)/100; - if (mode == MODE_SILK_ONLY || mode == MODE_HYBRID) - { - /* SILK complexity 0-1 uses the non-delayed-decision NSQ, which - costs about 20%. */ - if (complexity<2) - equiv = equiv*4/5; - equiv -= equiv*loss/(6*loss + 10); - } else if (mode == MODE_CELT_ONLY) { - /* CELT complexity 0-4 doesn't have the pitch filter, which costs - about 10%. */ - if (complexity<5) - equiv = equiv*9/10; - } else { - /* Mode not known yet */ - /* Half the SILK loss*/ - equiv -= equiv*loss/(12*loss + 20); - } - return equiv; -} - -#ifndef DISABLE_FLOAT_API - -int is_digital_silence(const opus_val16* pcm, int frame_size, int channels, int lsb_depth) -{ - int silence = 0; - opus_val32 sample_max = 0; -#ifdef MLP_TRAINING - return 0; -#endif - sample_max = celt_maxabs16(pcm, frame_size*channels); - -#ifdef FIXED_POINT - silence = (sample_max == 0); - (void)lsb_depth; -#else - silence = (sample_max <= (opus_val16) 1 / (1 << lsb_depth)); -#endif - - return silence; -} - -#ifdef FIXED_POINT -static opus_val32 compute_frame_energy(const opus_val16 *pcm, int frame_size, int channels, int arch) -{ - int i; - opus_val32 sample_max; - int max_shift; - int shift; - opus_val32 energy = 0; - int len = frame_size*channels; - (void)arch; - /* Max amplitude in the signal */ - sample_max = celt_maxabs16(pcm, len); - - /* Compute the right shift required in the MAC to avoid an overflow */ - max_shift = celt_ilog2(len); - shift = IMAX(0, (celt_ilog2(sample_max) << 1) + max_shift - 28); - - /* Compute the energy */ - for (i=0; i= (PSEUDO_SNR_THRESHOLD * noise_energy); - } - } - - if (is_silence) - { - /* The number of consecutive DTX frames should be within the allowed bounds */ - (*nb_no_activity_frames)++; - - if (*nb_no_activity_frames > NB_SPEECH_FRAMES_BEFORE_DTX) - { - if (*nb_no_activity_frames <= (NB_SPEECH_FRAMES_BEFORE_DTX + MAX_CONSECUTIVE_DTX)) - /* Valid frame for DTX! */ - return 1; - else - (*nb_no_activity_frames) = NB_SPEECH_FRAMES_BEFORE_DTX; - } - } else - (*nb_no_activity_frames) = 0; - - return 0; -} - -#endif - -static opus_int32 encode_multiframe_packet(OpusEncoder *st, - const opus_val16 *pcm, - int nb_frames, - int frame_size, - unsigned char *data, - opus_int32 out_data_bytes, - int to_celt, - int lsb_depth, - int float_api) -{ - int i; - int ret = 0; - VARDECL(unsigned char, tmp_data); - int bak_mode, bak_bandwidth, bak_channels, bak_to_mono; - VARDECL(OpusRepacketizer, rp); - int max_header_bytes; - opus_int32 bytes_per_frame; - opus_int32 cbr_bytes; - opus_int32 repacketize_len; - int tmp_len; - ALLOC_STACK; - - /* Worst cases: - * 2 frames: Code 2 with different compressed sizes - * >2 frames: Code 3 VBR */ - max_header_bytes = nb_frames == 2 ? 3 : (2+(nb_frames-1)*2); - - if (st->use_vbr || st->user_bitrate_bps==OPUS_BITRATE_MAX) - repacketize_len = out_data_bytes; - else { - cbr_bytes = 3*st->bitrate_bps/(3*8*st->Fs/(frame_size*nb_frames)); - repacketize_len = IMIN(cbr_bytes, out_data_bytes); - } - bytes_per_frame = IMIN(1276, 1+(repacketize_len-max_header_bytes)/nb_frames); - - ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char); - ALLOC(rp, 1, OpusRepacketizer); - opus_repacketizer_init(rp); - - bak_mode = st->user_forced_mode; - bak_bandwidth = st->user_bandwidth; - bak_channels = st->force_channels; - - st->user_forced_mode = st->mode; - st->user_bandwidth = st->bandwidth; - st->force_channels = st->stream_channels; - - bak_to_mono = st->silk_mode.toMono; - if (bak_to_mono) - st->force_channels = 1; - else - st->prev_channels = st->stream_channels; - - for (i=0;isilk_mode.toMono = 0; - st->nonfinal_frame = i<(nb_frames-1); - - /* When switching from SILK/Hybrid to CELT, only ask for a switch at the last frame */ - if (to_celt && i==nb_frames-1) - st->user_forced_mode = MODE_CELT_ONLY; - - tmp_len = opus_encode_native(st, pcm+i*(st->channels*frame_size), frame_size, - tmp_data+i*bytes_per_frame, bytes_per_frame, lsb_depth, NULL, 0, 0, 0, 0, - NULL, float_api); - - if (tmp_len<0) - { - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - - ret = opus_repacketizer_cat(rp, tmp_data+i*bytes_per_frame, tmp_len); - - if (ret<0) - { - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - } - - ret = opus_repacketizer_out_range_impl(rp, 0, nb_frames, data, repacketize_len, 0, !st->use_vbr); - - if (ret<0) - { - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - - /* Discard configs that were forced locally for the purpose of repacketization */ - st->user_forced_mode = bak_mode; - st->user_bandwidth = bak_bandwidth; - st->force_channels = bak_channels; - st->silk_mode.toMono = bak_to_mono; - - RESTORE_STACK; - return ret; -} - -static int compute_redundancy_bytes(opus_int32 max_data_bytes, opus_int32 bitrate_bps, int frame_rate, int channels) -{ - int redundancy_bytes_cap; - int redundancy_bytes; - opus_int32 redundancy_rate; - int base_bits; - opus_int32 available_bits; - base_bits = (40*channels+20); - - /* Equivalent rate for 5 ms frames. */ - redundancy_rate = bitrate_bps + base_bits*(200 - frame_rate); - /* For VBR, further increase the bitrate if we can afford it. It's pretty short - and we'll avoid artefacts. */ - redundancy_rate = 3*redundancy_rate/2; - redundancy_bytes = redundancy_rate/1600; - - /* Compute the max rate we can use given CBR or VBR with cap. */ - available_bits = max_data_bytes*8 - 2*base_bits; - redundancy_bytes_cap = (available_bits*240/(240+48000/frame_rate) + base_bits)/8; - redundancy_bytes = IMIN(redundancy_bytes, redundancy_bytes_cap); - /* It we can't get enough bits for redundancy to be worth it, rely on the decoder PLC. */ - if (redundancy_bytes > 4 + 8*channels) - redundancy_bytes = IMIN(257, redundancy_bytes); - else - redundancy_bytes = 0; - return redundancy_bytes; -} - -opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size, - unsigned char *data, opus_int32 out_data_bytes, int lsb_depth, - const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2, - int analysis_channels, downmix_func downmix, int float_api) -{ - void *silk_enc; - CELTEncoder *celt_enc; - int i; - int ret=0; - opus_int32 nBytes; - ec_enc enc; - int bytes_target; - int prefill=0; - int start_band = 0; - int redundancy = 0; - int redundancy_bytes = 0; /* Number of bytes to use for redundancy frame */ - int celt_to_silk = 0; - VARDECL(opus_val16, pcm_buf); - int nb_compr_bytes; - int to_celt = 0; - opus_uint32 redundant_rng = 0; - int cutoff_Hz, hp_freq_smth1; - int voice_est; /* Probability of voice in Q7 */ - opus_int32 equiv_rate; - int delay_compensation; - int frame_rate; - opus_int32 max_rate; /* Max bitrate we're allowed to use */ - int curr_bandwidth; - opus_val16 HB_gain; - opus_int32 max_data_bytes; /* Max number of bytes we're allowed to use */ - int total_buffer; - opus_val16 stereo_width; - const CELTMode *celt_mode; -#ifndef DISABLE_FLOAT_API - AnalysisInfo analysis_info; - int analysis_read_pos_bak=-1; - int analysis_read_subframe_bak=-1; - int is_silence = 0; -#endif - VARDECL(opus_val16, tmp_prefill); - - ALLOC_STACK; - - max_data_bytes = IMIN(1276, out_data_bytes); - - st->rangeFinal = 0; - if (frame_size <= 0 || max_data_bytes <= 0) - { - RESTORE_STACK; - return OPUS_BAD_ARG; - } - - /* Cannot encode 100 ms in 1 byte */ - if (max_data_bytes==1 && st->Fs==(frame_size*10)) - { - RESTORE_STACK; - return OPUS_BUFFER_TOO_SMALL; - } - - silk_enc = (char*)st+st->silk_enc_offset; - celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); - if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY) - delay_compensation = 0; - else - delay_compensation = st->delay_compensation; - - lsb_depth = IMIN(lsb_depth, st->lsb_depth); - - celt_encoder_ctl(celt_enc, CELT_GET_MODE(&celt_mode)); -#ifndef DISABLE_FLOAT_API - analysis_info.valid = 0; -#ifdef FIXED_POINT - if (st->silk_mode.complexity >= 10 && st->Fs>=16000) -#else - if (st->silk_mode.complexity >= 7 && st->Fs>=16000) -#endif - { - is_silence = is_digital_silence(pcm, frame_size, st->channels, lsb_depth); - analysis_read_pos_bak = st->analysis.read_pos; - analysis_read_subframe_bak = st->analysis.read_subframe; - run_analysis(&st->analysis, celt_mode, analysis_pcm, analysis_size, frame_size, - c1, c2, analysis_channels, st->Fs, - lsb_depth, downmix, &analysis_info); - - /* Track the peak signal energy */ - if (!is_silence && analysis_info.activity_probability > DTX_ACTIVITY_THRESHOLD) - st->peak_signal_energy = MAX32(MULT16_32_Q15(QCONST16(0.999f, 15), st->peak_signal_energy), - compute_frame_energy(pcm, frame_size, st->channels, st->arch)); - } else if (st->analysis.initialized) { - tonality_analysis_reset(&st->analysis); - } -#else - (void)analysis_pcm; - (void)analysis_size; - (void)c1; - (void)c2; - (void)analysis_channels; - (void)downmix; -#endif - -#ifndef DISABLE_FLOAT_API - /* Reset voice_ratio if this frame is not silent or if analysis is disabled. - * Otherwise, preserve voice_ratio from the last non-silent frame */ - if (!is_silence) - st->voice_ratio = -1; - - st->detected_bandwidth = 0; - if (analysis_info.valid) - { - int analysis_bandwidth; - if (st->signal_type == OPUS_AUTO) - { - float prob; - if (st->prev_mode == 0) - prob = analysis_info.music_prob; - else if (st->prev_mode == MODE_CELT_ONLY) - prob = analysis_info.music_prob_max; - else - prob = analysis_info.music_prob_min; - st->voice_ratio = (int)floor(.5+100*(1-prob)); - } - - analysis_bandwidth = analysis_info.bandwidth; - if (analysis_bandwidth<=12) - st->detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND; - else if (analysis_bandwidth<=14) - st->detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; - else if (analysis_bandwidth<=16) - st->detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND; - else if (analysis_bandwidth<=18) - st->detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; - else - st->detected_bandwidth = OPUS_BANDWIDTH_FULLBAND; - } -#else - st->voice_ratio = -1; -#endif - - if (st->channels==2 && st->force_channels!=1) - stereo_width = compute_stereo_width(pcm, frame_size, st->Fs, &st->width_mem); - else - stereo_width = 0; - total_buffer = delay_compensation; - st->bitrate_bps = user_bitrate_to_bitrate(st, frame_size, max_data_bytes); - - frame_rate = st->Fs/frame_size; - if (!st->use_vbr) - { - int cbrBytes; - /* Multiply by 12 to make sure the division is exact. */ - int frame_rate12 = 12*st->Fs/frame_size; - /* We need to make sure that "int" values always fit in 16 bits. */ - cbrBytes = IMIN( (12*st->bitrate_bps/8 + frame_rate12/2)/frame_rate12, max_data_bytes); - st->bitrate_bps = cbrBytes*(opus_int32)frame_rate12*8/12; - /* Make sure we provide at least one byte to avoid failing. */ - max_data_bytes = IMAX(1, cbrBytes); - } - if (max_data_bytes<3 || st->bitrate_bps < 3*frame_rate*8 - || (frame_rate<50 && (max_data_bytes*frame_rate<300 || st->bitrate_bps < 2400))) - { - /*If the space is too low to do something useful, emit 'PLC' frames.*/ - int tocmode = st->mode; - int bw = st->bandwidth == 0 ? OPUS_BANDWIDTH_NARROWBAND : st->bandwidth; - int packet_code = 0; - int num_multiframes = 0; - - if (tocmode==0) - tocmode = MODE_SILK_ONLY; - if (frame_rate>100) - tocmode = MODE_CELT_ONLY; - /* 40 ms -> 2 x 20 ms if in CELT_ONLY or HYBRID mode */ - if (frame_rate==25 && tocmode!=MODE_SILK_ONLY) - { - frame_rate = 50; - packet_code = 1; - } - - /* >= 60 ms frames */ - if (frame_rate<=16) - { - /* 1 x 60 ms, 2 x 40 ms, 2 x 60 ms */ - if (out_data_bytes==1 || (tocmode==MODE_SILK_ONLY && frame_rate!=10)) - { - tocmode = MODE_SILK_ONLY; - - packet_code = frame_rate <= 12; - frame_rate = frame_rate == 12 ? 25 : 16; - } - else - { - num_multiframes = 50/frame_rate; - frame_rate = 50; - packet_code = 3; - } - } - - if(tocmode==MODE_SILK_ONLY&&bw>OPUS_BANDWIDTH_WIDEBAND) - bw=OPUS_BANDWIDTH_WIDEBAND; - else if (tocmode==MODE_CELT_ONLY&&bw==OPUS_BANDWIDTH_MEDIUMBAND) - bw=OPUS_BANDWIDTH_NARROWBAND; - else if (tocmode==MODE_HYBRID&&bw<=OPUS_BANDWIDTH_SUPERWIDEBAND) - bw=OPUS_BANDWIDTH_SUPERWIDEBAND; - - data[0] = gen_toc(tocmode, frame_rate, bw, st->stream_channels); - data[0] |= packet_code; - - ret = packet_code <= 1 ? 1 : 2; - - max_data_bytes = IMAX(max_data_bytes, ret); - - if (packet_code==3) - data[1] = num_multiframes; - - if (!st->use_vbr) - { - ret = opus_packet_pad(data, ret, max_data_bytes); - if (ret == OPUS_OK) - ret = max_data_bytes; - else - ret = OPUS_INTERNAL_ERROR; - } - RESTORE_STACK; - return ret; - } - max_rate = frame_rate*max_data_bytes*8; - - /* Equivalent 20-ms rate for mode/channel/bandwidth decisions */ - equiv_rate = compute_equiv_rate(st->bitrate_bps, st->channels, st->Fs/frame_size, - st->use_vbr, 0, st->silk_mode.complexity, st->silk_mode.packetLossPercentage); - - if (st->signal_type == OPUS_SIGNAL_VOICE) - voice_est = 127; - else if (st->signal_type == OPUS_SIGNAL_MUSIC) - voice_est = 0; - else if (st->voice_ratio >= 0) - { - voice_est = st->voice_ratio*327>>8; - /* For AUDIO, never be more than 90% confident of having speech */ - if (st->application == OPUS_APPLICATION_AUDIO) - voice_est = IMIN(voice_est, 115); - } else if (st->application == OPUS_APPLICATION_VOIP) - voice_est = 115; - else - voice_est = 48; - - if (st->force_channels!=OPUS_AUTO && st->channels == 2) - { - st->stream_channels = st->force_channels; - } else { -#ifdef FUZZING - /* Random mono/stereo decision */ - if (st->channels == 2 && (rand()&0x1F)==0) - st->stream_channels = 3-st->stream_channels; -#else - /* Rate-dependent mono-stereo decision */ - if (st->channels == 2) - { - opus_int32 stereo_threshold; - stereo_threshold = stereo_music_threshold + ((voice_est*voice_est*(stereo_voice_threshold-stereo_music_threshold))>>14); - if (st->stream_channels == 2) - stereo_threshold -= 1000; - else - stereo_threshold += 1000; - st->stream_channels = (equiv_rate > stereo_threshold) ? 2 : 1; - } else { - st->stream_channels = st->channels; - } -#endif - } - /* Update equivalent rate for channels decision. */ - equiv_rate = compute_equiv_rate(st->bitrate_bps, st->stream_channels, st->Fs/frame_size, - st->use_vbr, 0, st->silk_mode.complexity, st->silk_mode.packetLossPercentage); - - /* Allow SILK DTX if DTX is enabled but the generalized DTX cannot be used, - e.g. because of the complexity setting or sample rate. */ -#ifndef DISABLE_FLOAT_API - st->silk_mode.useDTX = st->use_dtx && !(analysis_info.valid || is_silence); -#else - st->silk_mode.useDTX = st->use_dtx; -#endif - - /* Mode selection depending on application and signal type */ - if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY) - { - st->mode = MODE_CELT_ONLY; - } else if (st->user_forced_mode == OPUS_AUTO) - { -#ifdef FUZZING - /* Random mode switching */ - if ((rand()&0xF)==0) - { - if ((rand()&0x1)==0) - st->mode = MODE_CELT_ONLY; - else - st->mode = MODE_SILK_ONLY; - } else { - if (st->prev_mode==MODE_CELT_ONLY) - st->mode = MODE_CELT_ONLY; - else - st->mode = MODE_SILK_ONLY; - } -#else - opus_int32 mode_voice, mode_music; - opus_int32 threshold; - - /* Interpolate based on stereo width */ - mode_voice = (opus_int32)(MULT16_32_Q15(Q15ONE-stereo_width,mode_thresholds[0][0]) - + MULT16_32_Q15(stereo_width,mode_thresholds[1][0])); - mode_music = (opus_int32)(MULT16_32_Q15(Q15ONE-stereo_width,mode_thresholds[1][1]) - + MULT16_32_Q15(stereo_width,mode_thresholds[1][1])); - /* Interpolate based on speech/music probability */ - threshold = mode_music + ((voice_est*voice_est*(mode_voice-mode_music))>>14); - /* Bias towards SILK for VoIP because of some useful features */ - if (st->application == OPUS_APPLICATION_VOIP) - threshold += 8000; - - /*printf("%f %d\n", stereo_width/(float)Q15ONE, threshold);*/ - /* Hysteresis */ - if (st->prev_mode == MODE_CELT_ONLY) - threshold -= 4000; - else if (st->prev_mode>0) - threshold += 4000; - - st->mode = (equiv_rate >= threshold) ? MODE_CELT_ONLY: MODE_SILK_ONLY; - - /* When FEC is enabled and there's enough packet loss, use SILK */ - if (st->silk_mode.useInBandFEC && st->silk_mode.packetLossPercentage > (128-voice_est)>>4) - st->mode = MODE_SILK_ONLY; - /* When encoding voice and DTX is enabled but the generalized DTX cannot be used, - use SILK in order to make use of its DTX. */ - if (st->silk_mode.useDTX && voice_est > 100) - st->mode = MODE_SILK_ONLY; -#endif - - /* If max_data_bytes represents less than 6 kb/s, switch to CELT-only mode */ - if (max_data_bytes < (frame_rate > 50 ? 9000 : 6000)*frame_size / (st->Fs * 8)) - st->mode = MODE_CELT_ONLY; - } else { - st->mode = st->user_forced_mode; - } - - /* Override the chosen mode to make sure we meet the requested frame size */ - if (st->mode != MODE_CELT_ONLY && frame_size < st->Fs/100) - st->mode = MODE_CELT_ONLY; - if (st->lfe) - st->mode = MODE_CELT_ONLY; - - if (st->prev_mode > 0 && - ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) || - (st->mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY))) - { - redundancy = 1; - celt_to_silk = (st->mode != MODE_CELT_ONLY); - if (!celt_to_silk) - { - /* Switch to SILK/hybrid if frame size is 10 ms or more*/ - if (frame_size >= st->Fs/100) - { - st->mode = st->prev_mode; - to_celt = 1; - } else { - redundancy=0; - } - } - } - - /* When encoding multiframes, we can ask for a switch to CELT only in the last frame. This switch - * is processed above as the requested mode shouldn't interrupt stereo->mono transition. */ - if (st->stream_channels == 1 && st->prev_channels ==2 && st->silk_mode.toMono==0 - && st->mode != MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY) - { - /* Delay stereo->mono transition by two frames so that SILK can do a smooth downmix */ - st->silk_mode.toMono = 1; - st->stream_channels = 2; - } else { - st->silk_mode.toMono = 0; - } - - /* Update equivalent rate with mode decision. */ - equiv_rate = compute_equiv_rate(st->bitrate_bps, st->stream_channels, st->Fs/frame_size, - st->use_vbr, st->mode, st->silk_mode.complexity, st->silk_mode.packetLossPercentage); - - if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) - { - silk_EncControlStruct dummy; - silk_InitEncoder( silk_enc, st->arch, &dummy); - prefill=1; - } - - /* Automatic (rate-dependent) bandwidth selection */ - if (st->mode == MODE_CELT_ONLY || st->first || st->silk_mode.allowBandwidthSwitch) - { - const opus_int32 *voice_bandwidth_thresholds, *music_bandwidth_thresholds; - opus_int32 bandwidth_thresholds[8]; - int bandwidth = OPUS_BANDWIDTH_FULLBAND; - - if (st->channels==2 && st->force_channels!=1) - { - voice_bandwidth_thresholds = stereo_voice_bandwidth_thresholds; - music_bandwidth_thresholds = stereo_music_bandwidth_thresholds; - } else { - voice_bandwidth_thresholds = mono_voice_bandwidth_thresholds; - music_bandwidth_thresholds = mono_music_bandwidth_thresholds; - } - /* Interpolate bandwidth thresholds depending on voice estimation */ - for (i=0;i<8;i++) - { - bandwidth_thresholds[i] = music_bandwidth_thresholds[i] - + ((voice_est*voice_est*(voice_bandwidth_thresholds[i]-music_bandwidth_thresholds[i]))>>14); - } - do { - int threshold, hysteresis; - threshold = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)]; - hysteresis = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)+1]; - if (!st->first) - { - if (st->auto_bandwidth >= bandwidth) - threshold -= hysteresis; - else - threshold += hysteresis; - } - if (equiv_rate >= threshold) - break; - } while (--bandwidth>OPUS_BANDWIDTH_NARROWBAND); - /* We don't use mediumband anymore, except when explicitly requested or during - mode transitions. */ - if (bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) - bandwidth = OPUS_BANDWIDTH_WIDEBAND; - st->bandwidth = st->auto_bandwidth = bandwidth; - /* Prevents any transition to SWB/FB until the SILK layer has fully - switched to WB mode and turned the variable LP filter off */ - if (!st->first && st->mode != MODE_CELT_ONLY && !st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND) - st->bandwidth = OPUS_BANDWIDTH_WIDEBAND; - } - - if (st->bandwidth>st->max_bandwidth) - st->bandwidth = st->max_bandwidth; - - if (st->user_bandwidth != OPUS_AUTO) - st->bandwidth = st->user_bandwidth; - - /* This prevents us from using hybrid at unsafe CBR/max rates */ - if (st->mode != MODE_CELT_ONLY && max_rate < 15000) - { - st->bandwidth = IMIN(st->bandwidth, OPUS_BANDWIDTH_WIDEBAND); - } - - /* Prevents Opus from wasting bits on frequencies that are above - the Nyquist rate of the input signal */ - if (st->Fs <= 24000 && st->bandwidth > OPUS_BANDWIDTH_SUPERWIDEBAND) - st->bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; - if (st->Fs <= 16000 && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND) - st->bandwidth = OPUS_BANDWIDTH_WIDEBAND; - if (st->Fs <= 12000 && st->bandwidth > OPUS_BANDWIDTH_MEDIUMBAND) - st->bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; - if (st->Fs <= 8000 && st->bandwidth > OPUS_BANDWIDTH_NARROWBAND) - st->bandwidth = OPUS_BANDWIDTH_NARROWBAND; -#ifndef DISABLE_FLOAT_API - /* Use detected bandwidth to reduce the encoded bandwidth. */ - if (st->detected_bandwidth && st->user_bandwidth == OPUS_AUTO) - { - int min_detected_bandwidth; - /* Makes bandwidth detection more conservative just in case the detector - gets it wrong when we could have coded a high bandwidth transparently. - When operating in SILK/hybrid mode, we don't go below wideband to avoid - more complicated switches that require redundancy. */ - if (equiv_rate <= 18000*st->stream_channels && st->mode == MODE_CELT_ONLY) - min_detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND; - else if (equiv_rate <= 24000*st->stream_channels && st->mode == MODE_CELT_ONLY) - min_detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; - else if (equiv_rate <= 30000*st->stream_channels) - min_detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND; - else if (equiv_rate <= 44000*st->stream_channels) - min_detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; - else - min_detected_bandwidth = OPUS_BANDWIDTH_FULLBAND; - - st->detected_bandwidth = IMAX(st->detected_bandwidth, min_detected_bandwidth); - st->bandwidth = IMIN(st->bandwidth, st->detected_bandwidth); - } -#endif - st->silk_mode.LBRR_coded = decide_fec(st->silk_mode.useInBandFEC, st->silk_mode.packetLossPercentage, - st->silk_mode.LBRR_coded, st->mode, &st->bandwidth, equiv_rate); - celt_encoder_ctl(celt_enc, OPUS_SET_LSB_DEPTH(lsb_depth)); - - /* CELT mode doesn't support mediumband, use wideband instead */ - if (st->mode == MODE_CELT_ONLY && st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) - st->bandwidth = OPUS_BANDWIDTH_WIDEBAND; - if (st->lfe) - st->bandwidth = OPUS_BANDWIDTH_NARROWBAND; - - curr_bandwidth = st->bandwidth; - - /* Chooses the appropriate mode for speech - *NEVER* switch to/from CELT-only mode here as this will invalidate some assumptions */ - if (st->mode == MODE_SILK_ONLY && curr_bandwidth > OPUS_BANDWIDTH_WIDEBAND) - st->mode = MODE_HYBRID; - if (st->mode == MODE_HYBRID && curr_bandwidth <= OPUS_BANDWIDTH_WIDEBAND) - st->mode = MODE_SILK_ONLY; - - /* Can't support higher than >60 ms frames, and >20 ms when in Hybrid or CELT-only modes */ - if ((frame_size > st->Fs/50 && (st->mode != MODE_SILK_ONLY)) || frame_size > 3*st->Fs/50) - { - int enc_frame_size; - int nb_frames; - - if (st->mode == MODE_SILK_ONLY) - { - if (frame_size == 2*st->Fs/25) /* 80 ms -> 2x 40 ms */ - enc_frame_size = st->Fs/25; - else if (frame_size == 3*st->Fs/25) /* 120 ms -> 2x 60 ms */ - enc_frame_size = 3*st->Fs/50; - else /* 100 ms -> 5x 20 ms */ - enc_frame_size = st->Fs/50; - } - else - enc_frame_size = st->Fs/50; - - nb_frames = frame_size/enc_frame_size; - -#ifndef DISABLE_FLOAT_API - if (analysis_read_pos_bak!= -1) - { - st->analysis.read_pos = analysis_read_pos_bak; - st->analysis.read_subframe = analysis_read_subframe_bak; - } -#endif - - ret = encode_multiframe_packet(st, pcm, nb_frames, enc_frame_size, data, - out_data_bytes, to_celt, lsb_depth, float_api); - - RESTORE_STACK; - return ret; - } - - /* For the first frame at a new SILK bandwidth */ - if (st->silk_bw_switch) - { - redundancy = 1; - celt_to_silk = 1; - st->silk_bw_switch = 0; - /* Do a prefill without reseting the sampling rate control. */ - prefill=2; - } - - /* If we decided to go with CELT, make sure redundancy is off, no matter what - we decided earlier. */ - if (st->mode == MODE_CELT_ONLY) - redundancy = 0; - - if (redundancy) - { - redundancy_bytes = compute_redundancy_bytes(max_data_bytes, st->bitrate_bps, frame_rate, st->stream_channels); - if (redundancy_bytes == 0) - redundancy = 0; - } - - /* printf("%d %d %d %d\n", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */ - bytes_target = IMIN(max_data_bytes-redundancy_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1; - - data += 1; - - ec_enc_init(&enc, data, max_data_bytes-1); - - ALLOC(pcm_buf, (total_buffer+frame_size)*st->channels, opus_val16); - OPUS_COPY(pcm_buf, &st->delay_buffer[(st->encoder_buffer-total_buffer)*st->channels], total_buffer*st->channels); - - if (st->mode == MODE_CELT_ONLY) - hp_freq_smth1 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ); - else - hp_freq_smth1 = ((silk_encoder*)silk_enc)->state_Fxx[0].sCmn.variable_HP_smth1_Q15; - - st->variable_HP_smth2_Q15 = silk_SMLAWB( st->variable_HP_smth2_Q15, - hp_freq_smth1 - st->variable_HP_smth2_Q15, SILK_FIX_CONST( VARIABLE_HP_SMTH_COEF2, 16 ) ); - - /* convert from log scale to Hertz */ - cutoff_Hz = silk_log2lin( silk_RSHIFT( st->variable_HP_smth2_Q15, 8 ) ); - - if (st->application == OPUS_APPLICATION_VOIP) - { - hp_cutoff(pcm, cutoff_Hz, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs, st->arch); - } else { - dc_reject(pcm, 3, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs); - } -#ifndef FIXED_POINT - if (float_api) - { - opus_val32 sum; - sum = celt_inner_prod(&pcm_buf[total_buffer*st->channels], &pcm_buf[total_buffer*st->channels], frame_size*st->channels, st->arch); - /* This should filter out both NaNs and ridiculous signals that could - cause NaNs further down. */ - if (!(sum < 1e9f) || celt_isnan(sum)) - { - OPUS_CLEAR(&pcm_buf[total_buffer*st->channels], frame_size*st->channels); - st->hp_mem[0] = st->hp_mem[1] = st->hp_mem[2] = st->hp_mem[3] = 0; - } - } -#endif - - - /* SILK processing */ - HB_gain = Q15ONE; - if (st->mode != MODE_CELT_ONLY) - { - opus_int32 total_bitRate, celt_rate; - opus_int activity; -#ifdef FIXED_POINT - const opus_int16 *pcm_silk; -#else - VARDECL(opus_int16, pcm_silk); - ALLOC(pcm_silk, st->channels*frame_size, opus_int16); -#endif - - activity = VAD_NO_DECISION; -#ifndef DISABLE_FLOAT_API - if( analysis_info.valid ) { - /* Inform SILK about the Opus VAD decision */ - activity = ( analysis_info.activity_probability >= DTX_ACTIVITY_THRESHOLD ); - } -#endif - - /* Distribute bits between SILK and CELT */ - total_bitRate = 8 * bytes_target * frame_rate; - if( st->mode == MODE_HYBRID ) { - /* Base rate for SILK */ - st->silk_mode.bitRate = compute_silk_rate_for_hybrid(total_bitRate, - curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded, - st->stream_channels); - if (!st->energy_masking) - { - /* Increasingly attenuate high band when it gets allocated fewer bits */ - celt_rate = total_bitRate - st->silk_mode.bitRate; - HB_gain = Q15ONE - SHR32(celt_exp2(-celt_rate * QCONST16(1.f/1024, 10)), 1); - } - } else { - /* SILK gets all bits */ - st->silk_mode.bitRate = total_bitRate; - } - - /* Surround masking for SILK */ - if (st->energy_masking && st->use_vbr && !st->lfe) - { - opus_val32 mask_sum=0; - opus_val16 masking_depth; - opus_int32 rate_offset; - int c; - int end = 17; - opus_int16 srate = 16000; - if (st->bandwidth == OPUS_BANDWIDTH_NARROWBAND) - { - end = 13; - srate = 8000; - } else if (st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) - { - end = 15; - srate = 12000; - } - for (c=0;cchannels;c++) - { - for(i=0;ienergy_masking[21*c+i], - QCONST16(.5f, DB_SHIFT)), -QCONST16(2.0f, DB_SHIFT)); - if (mask > 0) - mask = HALF16(mask); - mask_sum += mask; - } - } - /* Conservative rate reduction, we cut the masking in half */ - masking_depth = mask_sum / end*st->channels; - masking_depth += QCONST16(.2f, DB_SHIFT); - rate_offset = (opus_int32)PSHR32(MULT16_16(srate, masking_depth), DB_SHIFT); - rate_offset = MAX32(rate_offset, -2*st->silk_mode.bitRate/3); - /* Split the rate change between the SILK and CELT part for hybrid. */ - if (st->bandwidth==OPUS_BANDWIDTH_SUPERWIDEBAND || st->bandwidth==OPUS_BANDWIDTH_FULLBAND) - st->silk_mode.bitRate += 3*rate_offset/5; - else - st->silk_mode.bitRate += rate_offset; - } - - st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs; - st->silk_mode.nChannelsAPI = st->channels; - st->silk_mode.nChannelsInternal = st->stream_channels; - if (curr_bandwidth == OPUS_BANDWIDTH_NARROWBAND) { - st->silk_mode.desiredInternalSampleRate = 8000; - } else if (curr_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) { - st->silk_mode.desiredInternalSampleRate = 12000; - } else { - celt_assert( st->mode == MODE_HYBRID || curr_bandwidth == OPUS_BANDWIDTH_WIDEBAND ); - st->silk_mode.desiredInternalSampleRate = 16000; - } - if( st->mode == MODE_HYBRID ) { - /* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */ - st->silk_mode.minInternalSampleRate = 16000; - } else { - st->silk_mode.minInternalSampleRate = 8000; - } - - st->silk_mode.maxInternalSampleRate = 16000; - if (st->mode == MODE_SILK_ONLY) - { - opus_int32 effective_max_rate = max_rate; - if (frame_rate > 50) - effective_max_rate = effective_max_rate*2/3; - if (effective_max_rate < 8000) - { - st->silk_mode.maxInternalSampleRate = 12000; - st->silk_mode.desiredInternalSampleRate = IMIN(12000, st->silk_mode.desiredInternalSampleRate); - } - if (effective_max_rate < 7000) - { - st->silk_mode.maxInternalSampleRate = 8000; - st->silk_mode.desiredInternalSampleRate = IMIN(8000, st->silk_mode.desiredInternalSampleRate); - } - } - - st->silk_mode.useCBR = !st->use_vbr; - - /* Call SILK encoder for the low band */ - - /* Max bits for SILK, counting ToC, redundancy bytes, and optionally redundancy. */ - st->silk_mode.maxBits = (max_data_bytes-1)*8; - if (redundancy && redundancy_bytes >= 2) - { - /* Counting 1 bit for redundancy position and 20 bits for flag+size (only for hybrid). */ - st->silk_mode.maxBits -= redundancy_bytes*8 + 1; - if (st->mode == MODE_HYBRID) - st->silk_mode.maxBits -= 20; - } - if (st->silk_mode.useCBR) - { - if (st->mode == MODE_HYBRID) - { - st->silk_mode.maxBits = IMIN(st->silk_mode.maxBits, st->silk_mode.bitRate * frame_size / st->Fs); - } - } else { - /* Constrained VBR. */ - if (st->mode == MODE_HYBRID) - { - /* Compute SILK bitrate corresponding to the max total bits available */ - opus_int32 maxBitRate = compute_silk_rate_for_hybrid(st->silk_mode.maxBits*st->Fs / frame_size, - curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded, - st->stream_channels); - st->silk_mode.maxBits = maxBitRate * frame_size / st->Fs; - } - } - - if (prefill) - { - opus_int32 zero=0; - int prefill_offset; - /* Use a smooth onset for the SILK prefill to avoid the encoder trying to encode - a discontinuity. The exact location is what we need to avoid leaving any "gap" - in the audio when mixing with the redundant CELT frame. Here we can afford to - overwrite st->delay_buffer because the only thing that uses it before it gets - rewritten is tmp_prefill[] and even then only the part after the ramp really - gets used (rather than sent to the encoder and discarded) */ - prefill_offset = st->channels*(st->encoder_buffer-st->delay_compensation-st->Fs/400); - gain_fade(st->delay_buffer+prefill_offset, st->delay_buffer+prefill_offset, - 0, Q15ONE, celt_mode->overlap, st->Fs/400, st->channels, celt_mode->window, st->Fs); - OPUS_CLEAR(st->delay_buffer, prefill_offset); -#ifdef FIXED_POINT - pcm_silk = st->delay_buffer; -#else - for (i=0;iencoder_buffer*st->channels;i++) - pcm_silk[i] = FLOAT2INT16(st->delay_buffer[i]); -#endif - silk_Encode( silk_enc, &st->silk_mode, pcm_silk, st->encoder_buffer, NULL, &zero, prefill, activity ); - /* Prevent a second switch in the real encode call. */ - st->silk_mode.opusCanSwitch = 0; - } - -#ifdef FIXED_POINT - pcm_silk = pcm_buf+total_buffer*st->channels; -#else - for (i=0;ichannels;i++) - pcm_silk[i] = FLOAT2INT16(pcm_buf[total_buffer*st->channels + i]); -#endif - ret = silk_Encode( silk_enc, &st->silk_mode, pcm_silk, frame_size, &enc, &nBytes, 0, activity ); - if( ret ) { - /*fprintf (stderr, "SILK encode error: %d\n", ret);*/ - /* Handle error */ - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - - /* Extract SILK internal bandwidth for signaling in first byte */ - if( st->mode == MODE_SILK_ONLY ) { - if( st->silk_mode.internalSampleRate == 8000 ) { - curr_bandwidth = OPUS_BANDWIDTH_NARROWBAND; - } else if( st->silk_mode.internalSampleRate == 12000 ) { - curr_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; - } else if( st->silk_mode.internalSampleRate == 16000 ) { - curr_bandwidth = OPUS_BANDWIDTH_WIDEBAND; - } - } else { - celt_assert( st->silk_mode.internalSampleRate == 16000 ); - } - - st->silk_mode.opusCanSwitch = st->silk_mode.switchReady && !st->nonfinal_frame; - - if (nBytes==0) - { - st->rangeFinal = 0; - data[-1] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels); - RESTORE_STACK; - return 1; - } - - /* FIXME: How do we allocate the redundancy for CBR? */ - if (st->silk_mode.opusCanSwitch) - { - redundancy_bytes = compute_redundancy_bytes(max_data_bytes, st->bitrate_bps, frame_rate, st->stream_channels); - redundancy = (redundancy_bytes != 0); - celt_to_silk = 0; - st->silk_bw_switch = 1; - } - } - - /* CELT processing */ - { - int endband=21; - - switch(curr_bandwidth) - { - case OPUS_BANDWIDTH_NARROWBAND: - endband = 13; - break; - case OPUS_BANDWIDTH_MEDIUMBAND: - case OPUS_BANDWIDTH_WIDEBAND: - endband = 17; - break; - case OPUS_BANDWIDTH_SUPERWIDEBAND: - endband = 19; - break; - case OPUS_BANDWIDTH_FULLBAND: - endband = 21; - break; - } - celt_encoder_ctl(celt_enc, CELT_SET_END_BAND(endband)); - celt_encoder_ctl(celt_enc, CELT_SET_CHANNELS(st->stream_channels)); - } - celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX)); - if (st->mode != MODE_SILK_ONLY) - { - opus_val32 celt_pred=2; - celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0)); - /* We may still decide to disable prediction later */ - if (st->silk_mode.reducedDependency) - celt_pred = 0; - celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(celt_pred)); - - if (st->mode == MODE_HYBRID) - { - if( st->use_vbr ) { - celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps-st->silk_mode.bitRate)); - celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(0)); - } - } else { - if (st->use_vbr) - { - celt_encoder_ctl(celt_enc, OPUS_SET_VBR(1)); - celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(st->vbr_constraint)); - celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps)); - } - } - } - - ALLOC(tmp_prefill, st->channels*st->Fs/400, opus_val16); - if (st->mode != MODE_SILK_ONLY && st->mode != st->prev_mode && st->prev_mode > 0) - { - OPUS_COPY(tmp_prefill, &st->delay_buffer[(st->encoder_buffer-total_buffer-st->Fs/400)*st->channels], st->channels*st->Fs/400); - } - - if (st->channels*(st->encoder_buffer-(frame_size+total_buffer)) > 0) - { - OPUS_MOVE(st->delay_buffer, &st->delay_buffer[st->channels*frame_size], st->channels*(st->encoder_buffer-frame_size-total_buffer)); - OPUS_COPY(&st->delay_buffer[st->channels*(st->encoder_buffer-frame_size-total_buffer)], - &pcm_buf[0], - (frame_size+total_buffer)*st->channels); - } else { - OPUS_COPY(st->delay_buffer, &pcm_buf[(frame_size+total_buffer-st->encoder_buffer)*st->channels], st->encoder_buffer*st->channels); - } - /* gain_fade() and stereo_fade() need to be after the buffer copying - because we don't want any of this to affect the SILK part */ - if( st->prev_HB_gain < Q15ONE || HB_gain < Q15ONE ) { - gain_fade(pcm_buf, pcm_buf, - st->prev_HB_gain, HB_gain, celt_mode->overlap, frame_size, st->channels, celt_mode->window, st->Fs); - } - st->prev_HB_gain = HB_gain; - if (st->mode != MODE_HYBRID || st->stream_channels==1) - { - if (equiv_rate > 32000) - st->silk_mode.stereoWidth_Q14 = 16384; - else if (equiv_rate < 16000) - st->silk_mode.stereoWidth_Q14 = 0; - else - st->silk_mode.stereoWidth_Q14 = 16384 - 2048*(opus_int32)(32000-equiv_rate)/(equiv_rate-14000); - } - if( !st->energy_masking && st->channels == 2 ) { - /* Apply stereo width reduction (at low bitrates) */ - if( st->hybrid_stereo_width_Q14 < (1 << 14) || st->silk_mode.stereoWidth_Q14 < (1 << 14) ) { - opus_val16 g1, g2; - g1 = st->hybrid_stereo_width_Q14; - g2 = (opus_val16)(st->silk_mode.stereoWidth_Q14); -#ifdef FIXED_POINT - g1 = g1==16384 ? Q15ONE : SHL16(g1,1); - g2 = g2==16384 ? Q15ONE : SHL16(g2,1); -#else - g1 *= (1.f/16384); - g2 *= (1.f/16384); -#endif - stereo_fade(pcm_buf, pcm_buf, g1, g2, celt_mode->overlap, - frame_size, st->channels, celt_mode->window, st->Fs); - st->hybrid_stereo_width_Q14 = st->silk_mode.stereoWidth_Q14; - } - } - - if ( st->mode != MODE_CELT_ONLY && ec_tell(&enc)+17+20*(st->mode == MODE_HYBRID) <= 8*(max_data_bytes-1)) - { - /* For SILK mode, the redundancy is inferred from the length */ - if (st->mode == MODE_HYBRID) - ec_enc_bit_logp(&enc, redundancy, 12); - if (redundancy) - { - int max_redundancy; - ec_enc_bit_logp(&enc, celt_to_silk, 1); - if (st->mode == MODE_HYBRID) - { - /* Reserve the 8 bits needed for the redundancy length, - and at least a few bits for CELT if possible */ - max_redundancy = (max_data_bytes-1)-((ec_tell(&enc)+8+3+7)>>3); - } - else - max_redundancy = (max_data_bytes-1)-((ec_tell(&enc)+7)>>3); - /* Target the same bit-rate for redundancy as for the rest, - up to a max of 257 bytes */ - redundancy_bytes = IMIN(max_redundancy, redundancy_bytes); - redundancy_bytes = IMIN(257, IMAX(2, redundancy_bytes)); - if (st->mode == MODE_HYBRID) - ec_enc_uint(&enc, redundancy_bytes-2, 256); - } - } else { - redundancy = 0; - } - - if (!redundancy) - { - st->silk_bw_switch = 0; - redundancy_bytes = 0; - } - if (st->mode != MODE_CELT_ONLY)start_band=17; - - if (st->mode == MODE_SILK_ONLY) - { - ret = (ec_tell(&enc)+7)>>3; - ec_enc_done(&enc); - nb_compr_bytes = ret; - } else { - nb_compr_bytes = (max_data_bytes-1)-redundancy_bytes; - ec_enc_shrink(&enc, nb_compr_bytes); - } - -#ifndef DISABLE_FLOAT_API - if (redundancy || st->mode != MODE_SILK_ONLY) - celt_encoder_ctl(celt_enc, CELT_SET_ANALYSIS(&analysis_info)); -#endif - if (st->mode == MODE_HYBRID) { - SILKInfo info; - info.signalType = st->silk_mode.signalType; - info.offset = st->silk_mode.offset; - celt_encoder_ctl(celt_enc, CELT_SET_SILK_INFO(&info)); - } - - /* 5 ms redundant frame for CELT->SILK */ - if (redundancy && celt_to_silk) - { - int err; - celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0)); - celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0)); - celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX)); - err = celt_encode_with_ec(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes, NULL); - if (err < 0) - { - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng)); - celt_encoder_ctl(celt_enc, OPUS_RESET_STATE); - } - - celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(start_band)); - - if (st->mode != MODE_SILK_ONLY) - { - if (st->mode != st->prev_mode && st->prev_mode > 0) - { - unsigned char dummy[2]; - celt_encoder_ctl(celt_enc, OPUS_RESET_STATE); - - /* Prefilling */ - celt_encode_with_ec(celt_enc, tmp_prefill, st->Fs/400, dummy, 2, NULL); - celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0)); - } - /* If false, we already busted the budget and we'll end up with a "PLC frame" */ - if (ec_tell(&enc) <= 8*nb_compr_bytes) - { - /* Set the bitrate again if it was overridden in the redundancy code above*/ - if (redundancy && celt_to_silk && st->mode==MODE_HYBRID && st->use_vbr) - celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps-st->silk_mode.bitRate)); - celt_encoder_ctl(celt_enc, OPUS_SET_VBR(st->use_vbr)); - ret = celt_encode_with_ec(celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc); - if (ret < 0) - { - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - /* Put CELT->SILK redundancy data in the right place. */ - if (redundancy && celt_to_silk && st->mode==MODE_HYBRID && st->use_vbr) - { - OPUS_MOVE(data+ret, data+nb_compr_bytes, redundancy_bytes); - nb_compr_bytes = nb_compr_bytes+redundancy_bytes; - } - } - } - - /* 5 ms redundant frame for SILK->CELT */ - if (redundancy && !celt_to_silk) - { - int err; - unsigned char dummy[2]; - int N2, N4; - N2 = st->Fs/200; - N4 = st->Fs/400; - - celt_encoder_ctl(celt_enc, OPUS_RESET_STATE); - celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0)); - celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0)); - celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0)); - celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX)); - - if (st->mode == MODE_HYBRID) - { - /* Shrink packet to what the encoder actually used. */ - nb_compr_bytes = ret; - ec_enc_shrink(&enc, nb_compr_bytes); - } - /* NOTE: We could speed this up slightly (at the expense of code size) by just adding a function that prefills the buffer */ - celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, dummy, 2, NULL); - - err = celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes, NULL); - if (err < 0) - { - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng)); - } - - - - /* Signalling the mode in the first byte */ - data--; - data[0] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels); - - st->rangeFinal = enc.rng ^ redundant_rng; - - if (to_celt) - st->prev_mode = MODE_CELT_ONLY; - else - st->prev_mode = st->mode; - st->prev_channels = st->stream_channels; - st->prev_framesize = frame_size; - - st->first = 0; - - /* DTX decision */ -#ifndef DISABLE_FLOAT_API - if (st->use_dtx && (analysis_info.valid || is_silence)) - { - if (decide_dtx_mode(analysis_info.activity_probability, &st->nb_no_activity_frames, - st->peak_signal_energy, pcm, frame_size, st->channels, is_silence, st->arch)) - { - st->rangeFinal = 0; - data[0] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels); - RESTORE_STACK; - return 1; - } - } else { - st->nb_no_activity_frames = 0; - } -#endif - - /* In the unlikely case that the SILK encoder busted its target, tell - the decoder to call the PLC */ - if (ec_tell(&enc) > (max_data_bytes-1)*8) - { - if (max_data_bytes < 2) - { - RESTORE_STACK; - return OPUS_BUFFER_TOO_SMALL; - } - data[1] = 0; - ret = 1; - st->rangeFinal = 0; - } else if (st->mode==MODE_SILK_ONLY&&!redundancy) - { - /*When in LPC only mode it's perfectly - reasonable to strip off trailing zero bytes as - the required range decoder behavior is to - fill these in. This can't be done when the MDCT - modes are used because the decoder needs to know - the actual length for allocation purposes.*/ - while(ret>2&&data[ret]==0)ret--; - } - /* Count ToC and redundancy */ - ret += 1+redundancy_bytes; - if (!st->use_vbr) - { - if (opus_packet_pad(data, ret, max_data_bytes) != OPUS_OK) - { - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - ret = max_data_bytes; - } - RESTORE_STACK; - return ret; -} - -#ifdef FIXED_POINT - -#ifndef DISABLE_FLOAT_API -opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_frame_size, - unsigned char *data, opus_int32 max_data_bytes) -{ - int i, ret; - int frame_size; - VARDECL(opus_int16, in); - ALLOC_STACK; - - frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs); - if (frame_size <= 0) - { - RESTORE_STACK; - return OPUS_BAD_ARG; - } - ALLOC(in, frame_size*st->channels, opus_int16); - - for (i=0;ichannels;i++) - in[i] = FLOAT2INT16(pcm[i]); - ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16, - pcm, analysis_frame_size, 0, -2, st->channels, downmix_float, 1); - RESTORE_STACK; - return ret; -} -#endif - -opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_frame_size, - unsigned char *data, opus_int32 out_data_bytes) -{ - int frame_size; - frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs); - return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 16, - pcm, analysis_frame_size, 0, -2, st->channels, downmix_int, 0); -} - -#else -opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_frame_size, - unsigned char *data, opus_int32 max_data_bytes) -{ - int i, ret; - int frame_size; - VARDECL(float, in); - ALLOC_STACK; - - frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs); - if (frame_size <= 0) - { - RESTORE_STACK; - return OPUS_BAD_ARG; - } - ALLOC(in, frame_size*st->channels, float); - - for (i=0;ichannels;i++) - in[i] = (1.0f/32768)*pcm[i]; - ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16, - pcm, analysis_frame_size, 0, -2, st->channels, downmix_int, 0); - RESTORE_STACK; - return ret; -} -opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_frame_size, - unsigned char *data, opus_int32 out_data_bytes) -{ - int frame_size; - frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs); - return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 24, - pcm, analysis_frame_size, 0, -2, st->channels, downmix_float, 1); -} -#endif - - -int opus_encoder_ctl(OpusEncoder *st, int request, ...) -{ - int ret; - CELTEncoder *celt_enc; - va_list ap; - - ret = OPUS_OK; - va_start(ap, request); - - celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); - - switch (request) - { - case OPUS_SET_APPLICATION_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if ( (value != OPUS_APPLICATION_VOIP && value != OPUS_APPLICATION_AUDIO - && value != OPUS_APPLICATION_RESTRICTED_LOWDELAY) - || (!st->first && st->application != value)) - { - ret = OPUS_BAD_ARG; - break; - } - st->application = value; -#ifndef DISABLE_FLOAT_API - st->analysis.application = value; -#endif - } - break; - case OPUS_GET_APPLICATION_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->application; - } - break; - case OPUS_SET_BITRATE_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX) - { - if (value <= 0) - goto bad_arg; - else if (value <= 500) - value = 500; - else if (value > (opus_int32)300000*st->channels) - value = (opus_int32)300000*st->channels; - } - st->user_bitrate_bps = value; - } - break; - case OPUS_GET_BITRATE_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = user_bitrate_to_bitrate(st, st->prev_framesize, 1276); - } - break; - case OPUS_SET_FORCE_CHANNELS_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if((value<1 || value>st->channels) && value != OPUS_AUTO) - { - goto bad_arg; - } - st->force_channels = value; - } - break; - case OPUS_GET_FORCE_CHANNELS_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->force_channels; - } - break; - case OPUS_SET_MAX_BANDWIDTH_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND) - { - goto bad_arg; - } - st->max_bandwidth = value; - if (st->max_bandwidth == OPUS_BANDWIDTH_NARROWBAND) { - st->silk_mode.maxInternalSampleRate = 8000; - } else if (st->max_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) { - st->silk_mode.maxInternalSampleRate = 12000; - } else { - st->silk_mode.maxInternalSampleRate = 16000; - } - } - break; - case OPUS_GET_MAX_BANDWIDTH_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->max_bandwidth; - } - break; - case OPUS_SET_BANDWIDTH_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if ((value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND) && value != OPUS_AUTO) - { - goto bad_arg; - } - st->user_bandwidth = value; - if (st->user_bandwidth == OPUS_BANDWIDTH_NARROWBAND) { - st->silk_mode.maxInternalSampleRate = 8000; - } else if (st->user_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) { - st->silk_mode.maxInternalSampleRate = 12000; - } else { - st->silk_mode.maxInternalSampleRate = 16000; - } - } - break; - case OPUS_GET_BANDWIDTH_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->bandwidth; - } - break; - case OPUS_SET_DTX_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if(value<0 || value>1) - { - goto bad_arg; - } - st->use_dtx = value; - } - break; - case OPUS_GET_DTX_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->use_dtx; - } - break; - case OPUS_SET_COMPLEXITY_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if(value<0 || value>10) - { - goto bad_arg; - } - st->silk_mode.complexity = value; - celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(value)); - } - break; - case OPUS_GET_COMPLEXITY_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->silk_mode.complexity; - } - break; - case OPUS_SET_INBAND_FEC_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if(value<0 || value>1) - { - goto bad_arg; - } - st->silk_mode.useInBandFEC = value; - } - break; - case OPUS_GET_INBAND_FEC_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->silk_mode.useInBandFEC; - } - break; - case OPUS_SET_PACKET_LOSS_PERC_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value < 0 || value > 100) - { - goto bad_arg; - } - st->silk_mode.packetLossPercentage = value; - celt_encoder_ctl(celt_enc, OPUS_SET_PACKET_LOSS_PERC(value)); - } - break; - case OPUS_GET_PACKET_LOSS_PERC_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->silk_mode.packetLossPercentage; - } - break; - case OPUS_SET_VBR_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if(value<0 || value>1) - { - goto bad_arg; - } - st->use_vbr = value; - st->silk_mode.useCBR = 1-value; - } - break; - case OPUS_GET_VBR_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->use_vbr; - } - break; - case OPUS_SET_VOICE_RATIO_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<-1 || value>100) - { - goto bad_arg; - } - st->voice_ratio = value; - } - break; - case OPUS_GET_VOICE_RATIO_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->voice_ratio; - } - break; - case OPUS_SET_VBR_CONSTRAINT_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if(value<0 || value>1) - { - goto bad_arg; - } - st->vbr_constraint = value; - } - break; - case OPUS_GET_VBR_CONSTRAINT_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->vbr_constraint; - } - break; - case OPUS_SET_SIGNAL_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if(value!=OPUS_AUTO && value!=OPUS_SIGNAL_VOICE && value!=OPUS_SIGNAL_MUSIC) - { - goto bad_arg; - } - st->signal_type = value; - } - break; - case OPUS_GET_SIGNAL_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->signal_type; - } - break; - case OPUS_GET_LOOKAHEAD_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->Fs/400; - if (st->application != OPUS_APPLICATION_RESTRICTED_LOWDELAY) - *value += st->delay_compensation; - } - break; - case OPUS_GET_SAMPLE_RATE_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->Fs; - } - break; - case OPUS_GET_FINAL_RANGE_REQUEST: - { - opus_uint32 *value = va_arg(ap, opus_uint32*); - if (!value) - { - goto bad_arg; - } - *value = st->rangeFinal; - } - break; - case OPUS_SET_LSB_DEPTH_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<8 || value>24) - { - goto bad_arg; - } - st->lsb_depth=value; - } - break; - case OPUS_GET_LSB_DEPTH_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->lsb_depth; - } - break; - case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value != OPUS_FRAMESIZE_ARG && value != OPUS_FRAMESIZE_2_5_MS && - value != OPUS_FRAMESIZE_5_MS && value != OPUS_FRAMESIZE_10_MS && - value != OPUS_FRAMESIZE_20_MS && value != OPUS_FRAMESIZE_40_MS && - value != OPUS_FRAMESIZE_60_MS && value != OPUS_FRAMESIZE_80_MS && - value != OPUS_FRAMESIZE_100_MS && value != OPUS_FRAMESIZE_120_MS) - { - goto bad_arg; - } - st->variable_duration = value; - } - break; - case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->variable_duration; - } - break; - case OPUS_SET_PREDICTION_DISABLED_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value > 1 || value < 0) - goto bad_arg; - st->silk_mode.reducedDependency = value; - } - break; - case OPUS_GET_PREDICTION_DISABLED_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - goto bad_arg; - *value = st->silk_mode.reducedDependency; - } - break; - case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if(value<0 || value>1) - { - goto bad_arg; - } - celt_encoder_ctl(celt_enc, OPUS_SET_PHASE_INVERSION_DISABLED(value)); - } - break; - case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - celt_encoder_ctl(celt_enc, OPUS_GET_PHASE_INVERSION_DISABLED(value)); - } - break; - case OPUS_RESET_STATE: - { - void *silk_enc; - silk_EncControlStruct dummy; - char *start; - silk_enc = (char*)st+st->silk_enc_offset; -#ifndef DISABLE_FLOAT_API - tonality_analysis_reset(&st->analysis); -#endif - - start = (char*)&st->OPUS_ENCODER_RESET_START; - OPUS_CLEAR(start, sizeof(OpusEncoder) - (start - (char*)st)); - - celt_encoder_ctl(celt_enc, OPUS_RESET_STATE); - silk_InitEncoder( silk_enc, st->arch, &dummy ); - st->stream_channels = st->channels; - st->hybrid_stereo_width_Q14 = 1 << 14; - st->prev_HB_gain = Q15ONE; - st->first = 1; - st->mode = MODE_HYBRID; - st->bandwidth = OPUS_BANDWIDTH_FULLBAND; - st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ); - } - break; - case OPUS_SET_FORCE_MODE_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if ((value < MODE_SILK_ONLY || value > MODE_CELT_ONLY) && value != OPUS_AUTO) - { - goto bad_arg; - } - st->user_forced_mode = value; - } - break; - case OPUS_SET_LFE_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - st->lfe = value; - ret = celt_encoder_ctl(celt_enc, OPUS_SET_LFE(value)); - } - break; - case OPUS_SET_ENERGY_MASK_REQUEST: - { - opus_val16 *value = va_arg(ap, opus_val16*); - st->energy_masking = value; - ret = celt_encoder_ctl(celt_enc, OPUS_SET_ENERGY_MASK(value)); - } - break; - case OPUS_GET_IN_DTX_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - if (st->silk_mode.useDTX && (st->prev_mode == MODE_SILK_ONLY || st->prev_mode == MODE_HYBRID)) { - /* DTX determined by Silk. */ - int n; - void *silk_enc = (char*)st+st->silk_enc_offset; - *value = 1; - for (n=0;nsilk_mode.nChannelsInternal;n++) { - *value = *value && ((silk_encoder*)silk_enc)->state_Fxx[n].sCmn.noSpeechCounter >= NB_SPEECH_FRAMES_BEFORE_DTX; - } - } -#ifndef DISABLE_FLOAT_API - else if (st->use_dtx) { - /* DTX determined by Opus. */ - *value = st->nb_no_activity_frames >= NB_SPEECH_FRAMES_BEFORE_DTX; - } -#endif - else { - *value = 0; - } - } - break; - - case CELT_GET_MODE_REQUEST: - { - const CELTMode ** value = va_arg(ap, const CELTMode**); - if (!value) - { - goto bad_arg; - } - ret = celt_encoder_ctl(celt_enc, CELT_GET_MODE(value)); - } - break; - default: - /* fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);*/ - ret = OPUS_UNIMPLEMENTED; - break; - } - va_end(ap); - return ret; -bad_arg: - va_end(ap); - return OPUS_BAD_ARG; -} - -void opus_encoder_destroy(OpusEncoder *st) -{ - opus_free(st); -} diff --git a/src/libopus/opus_multistream.c b/src/libopus/opus_multistream.c deleted file mode 100644 index 1c1abffe..00000000 --- a/src/libopus/opus_multistream.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright (c) 2011 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -//#ifdef HAVE_CONFIG_H -#include "config.h" -//#endif - -#include "opus_multistream.h" -#include "opus.h" -#include "opus_private.h" -#include "celt/stack_alloc.h" -#include -#include "celt/float_cast.h" -#include "celt/os_support.h" - - -int validate_layout(const ChannelLayout *layout) -{ - int i, max_channel; - - max_channel = layout->nb_streams+layout->nb_coupled_streams; - if (max_channel>255) - return 0; - for (i=0;inb_channels;i++) - { - if (layout->mapping[i] >= max_channel && layout->mapping[i] != 255) - return 0; - } - return 1; -} - - -int get_left_channel(const ChannelLayout *layout, int stream_id, int prev) -{ - int i; - i = (prev<0) ? 0 : prev+1; - for (;inb_channels;i++) - { - if (layout->mapping[i]==stream_id*2) - return i; - } - return -1; -} - -int get_right_channel(const ChannelLayout *layout, int stream_id, int prev) -{ - int i; - i = (prev<0) ? 0 : prev+1; - for (;inb_channels;i++) - { - if (layout->mapping[i]==stream_id*2+1) - return i; - } - return -1; -} - -int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev) -{ - int i; - i = (prev<0) ? 0 : prev+1; - for (;inb_channels;i++) - { - if (layout->mapping[i]==stream_id+layout->nb_coupled_streams) - return i; - } - return -1; -} - diff --git a/src/libopus/opus_multistream_decoder.c b/src/libopus/opus_multistream_decoder.c deleted file mode 100644 index a9684a84..00000000 --- a/src/libopus/opus_multistream_decoder.c +++ /dev/null @@ -1,549 +0,0 @@ -/* Copyright (c) 2011 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -//#ifdef HAVE_CONFIG_H -#include "config.h" -//#endif - -#include "opus_multistream.h" -#include "opus.h" -#include "opus_private.h" -#include "celt/stack_alloc.h" -#include -#include "celt/float_cast.h" -#include "celt/os_support.h" - -/* DECODER */ - -#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS) -static void validate_ms_decoder(OpusMSDecoder *st) -{ - validate_layout(&st->layout); -} -#define VALIDATE_MS_DECODER(st) validate_ms_decoder(st) -#else -#define VALIDATE_MS_DECODER(st) -#endif - - -opus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams) -{ - int coupled_size; - int mono_size; - - if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0; - coupled_size = opus_decoder_get_size(2); - mono_size = opus_decoder_get_size(1); - return align(sizeof(OpusMSDecoder)) - + nb_coupled_streams * align(coupled_size) - + (nb_streams-nb_coupled_streams) * align(mono_size); -} - -int opus_multistream_decoder_init( - OpusMSDecoder *st, - opus_int32 Fs, - int channels, - int streams, - int coupled_streams, - const unsigned char *mapping -) -{ - int coupled_size; - int mono_size; - int i, ret; - char *ptr; - - if ((channels>255) || (channels<1) || (coupled_streams>streams) || - (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams)) - return OPUS_BAD_ARG; - - st->layout.nb_channels = channels; - st->layout.nb_streams = streams; - st->layout.nb_coupled_streams = coupled_streams; - - for (i=0;ilayout.nb_channels;i++) - st->layout.mapping[i] = mapping[i]; - if (!validate_layout(&st->layout)) - return OPUS_BAD_ARG; - - ptr = (char*)st + align(sizeof(OpusMSDecoder)); - coupled_size = opus_decoder_get_size(2); - mono_size = opus_decoder_get_size(1); - - for (i=0;ilayout.nb_coupled_streams;i++) - { - ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 2); - if(ret!=OPUS_OK)return ret; - ptr += align(coupled_size); - } - for (;ilayout.nb_streams;i++) - { - ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 1); - if(ret!=OPUS_OK)return ret; - ptr += align(mono_size); - } - return OPUS_OK; -} - - -OpusMSDecoder *opus_multistream_decoder_create( - opus_int32 Fs, - int channels, - int streams, - int coupled_streams, - const unsigned char *mapping, - int *error -) -{ - int ret; - OpusMSDecoder *st; - if ((channels>255) || (channels<1) || (coupled_streams>streams) || - (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams)) - { - if (error) - *error = OPUS_BAD_ARG; - return NULL; - } - st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams)); - if (st==NULL) - { - if (error) - *error = OPUS_ALLOC_FAIL; - return NULL; - } - ret = opus_multistream_decoder_init(st, Fs, channels, streams, coupled_streams, mapping); - if (error) - *error = ret; - if (ret != OPUS_OK) - { - opus_free(st); - st = NULL; - } - return st; -} - -static int opus_multistream_packet_validate(const unsigned char *data, - opus_int32 len, int nb_streams, opus_int32 Fs) -{ - int s; - int count; - unsigned char toc; - opus_int16 size[48]; - int samples=0; - opus_int32 packet_offset; - - for (s=0;slayout.nb_streams-1) - { - RESTORE_STACK; - return OPUS_INVALID_PACKET; - } - if (!do_plc) - { - int ret = opus_multistream_packet_validate(data, len, st->layout.nb_streams, Fs); - if (ret < 0) - { - RESTORE_STACK; - return ret; - } else if (ret > frame_size) - { - RESTORE_STACK; - return OPUS_BUFFER_TOO_SMALL; - } - } - for (s=0;slayout.nb_streams;s++) - { - OpusDecoder *dec; - opus_int32 packet_offset; - int ret; - - dec = (OpusDecoder*)ptr; - ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size); - - if (!do_plc && len<=0) - { - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - packet_offset = 0; - ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset, soft_clip); - data += packet_offset; - len -= packet_offset; - if (ret <= 0) - { - RESTORE_STACK; - return ret; - } - frame_size = ret; - if (s < st->layout.nb_coupled_streams) - { - int chan, prev; - prev = -1; - /* Copy "left" audio to the channel(s) where it belongs */ - while ( (chan = get_left_channel(&st->layout, s, prev)) != -1) - { - (*copy_channel_out)(pcm, st->layout.nb_channels, chan, - buf, 2, frame_size, user_data); - prev = chan; - } - prev = -1; - /* Copy "right" audio to the channel(s) where it belongs */ - while ( (chan = get_right_channel(&st->layout, s, prev)) != -1) - { - (*copy_channel_out)(pcm, st->layout.nb_channels, chan, - buf+1, 2, frame_size, user_data); - prev = chan; - } - } else { - int chan, prev; - prev = -1; - /* Copy audio to the channel(s) where it belongs */ - while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1) - { - (*copy_channel_out)(pcm, st->layout.nb_channels, chan, - buf, 1, frame_size, user_data); - prev = chan; - } - } - } - /* Handle muted channels */ - for (c=0;clayout.nb_channels;c++) - { - if (st->layout.mapping[c] == 255) - { - (*copy_channel_out)(pcm, st->layout.nb_channels, c, - NULL, 0, frame_size, user_data); - } - } - RESTORE_STACK; - return frame_size; -} - -#if !defined(DISABLE_FLOAT_API) -static void opus_copy_channel_out_float( - void *dst, - int dst_stride, - int dst_channel, - const opus_val16 *src, - int src_stride, - int frame_size, - void *user_data -) -{ - float *float_dst; - opus_int32 i; - (void)user_data; - float_dst = (float*)dst; - if (src != NULL) - { - for (i=0;ilayout.nb_streams;s++) - { - OpusDecoder *dec; - dec = (OpusDecoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - ret = opus_decoder_ctl(dec, request, &tmp); - if (ret != OPUS_OK) break; - *value ^= tmp; - } - } - break; - case OPUS_RESET_STATE: - { - int s; - for (s=0;slayout.nb_streams;s++) - { - OpusDecoder *dec; - - dec = (OpusDecoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - ret = opus_decoder_ctl(dec, OPUS_RESET_STATE); - if (ret != OPUS_OK) - break; - } - } - break; - case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST: - { - int s; - opus_int32 stream_id; - OpusDecoder **value; - stream_id = va_arg(ap, opus_int32); - if (stream_id<0 || stream_id >= st->layout.nb_streams) - goto bad_arg; - value = va_arg(ap, OpusDecoder**); - if (!value) - { - goto bad_arg; - } - for (s=0;slayout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - } - *value = (OpusDecoder*)ptr; - } - break; - case OPUS_SET_GAIN_REQUEST: - case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST: - { - int s; - /* This works for int32 params */ - opus_int32 value = va_arg(ap, opus_int32); - for (s=0;slayout.nb_streams;s++) - { - OpusDecoder *dec; - - dec = (OpusDecoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - ret = opus_decoder_ctl(dec, request, value); - if (ret != OPUS_OK) - break; - } - } - break; - default: - ret = OPUS_UNIMPLEMENTED; - break; - } - return ret; -bad_arg: - return OPUS_BAD_ARG; -} - -int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) -{ - int ret; - va_list ap; - va_start(ap, request); - ret = opus_multistream_decoder_ctl_va_list(st, request, ap); - va_end(ap); - return ret; -} - -void opus_multistream_decoder_destroy(OpusMSDecoder *st) -{ - opus_free(st); -} diff --git a/src/libopus/opus_multistream_encoder.c b/src/libopus/opus_multistream_encoder.c deleted file mode 100644 index 5b6576a9..00000000 --- a/src/libopus/opus_multistream_encoder.c +++ /dev/null @@ -1,1328 +0,0 @@ -/* Copyright (c) 2011 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -//#ifdef HAVE_CONFIG_H -#include "config.h" -//#endif - -#include "opus_multistream.h" -#include "opus.h" -#include "opus_private.h" -#include "celt/stack_alloc.h" -#include -#include "celt/float_cast.h" -#include "celt/os_support.h" -#include "celt/mathops.h" -#include "celt/mdct.h" -#include "celt/modes.h" -#include "celt/bands.h" -#include "celt/quant_bands.h" -#include "celt/pitch.h" - -typedef struct { - int nb_streams; - int nb_coupled_streams; - unsigned char mapping[8]; -} VorbisLayout; - -/* Index is nb_channel-1*/ -static const VorbisLayout vorbis_mappings[8] = { - {1, 0, {0}}, /* 1: mono */ - {1, 1, {0, 1}}, /* 2: stereo */ - {2, 1, {0, 2, 1}}, /* 3: 1-d surround */ - {2, 2, {0, 1, 2, 3}}, /* 4: quadraphonic surround */ - {3, 2, {0, 4, 1, 2, 3}}, /* 5: 5-channel surround */ - {4, 2, {0, 4, 1, 2, 3, 5}}, /* 6: 5.1 surround */ - {4, 3, {0, 4, 1, 2, 3, 5, 6}}, /* 7: 6.1 surround */ - {5, 3, {0, 6, 1, 2, 3, 4, 5, 7}}, /* 8: 7.1 surround */ -}; - -static opus_val32 *ms_get_preemph_mem(OpusMSEncoder *st) -{ - int s; - char *ptr; - int coupled_size, mono_size; - - coupled_size = opus_encoder_get_size(2); - mono_size = opus_encoder_get_size(1); - ptr = (char*)st + align(sizeof(OpusMSEncoder)); - for (s=0;slayout.nb_streams;s++) - { - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - } - /* void* cast avoids clang -Wcast-align warning */ - return (opus_val32*)(void*)(ptr+st->layout.nb_channels*120*sizeof(opus_val32)); -} - -static opus_val32 *ms_get_window_mem(OpusMSEncoder *st) -{ - int s; - char *ptr; - int coupled_size, mono_size; - - coupled_size = opus_encoder_get_size(2); - mono_size = opus_encoder_get_size(1); - ptr = (char*)st + align(sizeof(OpusMSEncoder)); - for (s=0;slayout.nb_streams;s++) - { - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - } - /* void* cast avoids clang -Wcast-align warning */ - return (opus_val32*)(void*)ptr; -} - -static int validate_ambisonics(int nb_channels, int *nb_streams, int *nb_coupled_streams) -{ - int order_plus_one; - int acn_channels; - int nondiegetic_channels; - - if (nb_channels < 1 || nb_channels > 227) - return 0; - - order_plus_one = isqrt32(nb_channels); - acn_channels = order_plus_one * order_plus_one; - nondiegetic_channels = nb_channels - acn_channels; - - if (nondiegetic_channels != 0 && nondiegetic_channels != 2) - return 0; - - if (nb_streams) - *nb_streams = acn_channels + (nondiegetic_channels != 0); - if (nb_coupled_streams) - *nb_coupled_streams = nondiegetic_channels != 0; - return 1; -} - -static int validate_encoder_layout(const ChannelLayout *layout) -{ - int s; - for (s=0;snb_streams;s++) - { - if (s < layout->nb_coupled_streams) - { - if (get_left_channel(layout, s, -1)==-1) - return 0; - if (get_right_channel(layout, s, -1)==-1) - return 0; - } else { - if (get_mono_channel(layout, s, -1)==-1) - return 0; - } - } - return 1; -} - -static void channel_pos(int channels, int pos[8]) -{ - /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */ - if (channels==4) - { - pos[0]=1; - pos[1]=3; - pos[2]=1; - pos[3]=3; - } else if (channels==3||channels==5||channels==6) - { - pos[0]=1; - pos[1]=2; - pos[2]=3; - pos[3]=1; - pos[4]=3; - pos[5]=0; - } else if (channels==7) - { - pos[0]=1; - pos[1]=2; - pos[2]=3; - pos[3]=1; - pos[4]=3; - pos[5]=2; - pos[6]=0; - } else if (channels==8) - { - pos[0]=1; - pos[1]=2; - pos[2]=3; - pos[3]=1; - pos[4]=3; - pos[5]=1; - pos[6]=3; - pos[7]=0; - } -} - -#if 1 -/* Computes a rough approximation of log2(2^a + 2^b) */ -static opus_val16 logSum(opus_val16 a, opus_val16 b) -{ - opus_val16 max; - opus_val32 diff; - opus_val16 frac; - static const opus_val16 diff_table[17] = { - QCONST16(0.5000000f, DB_SHIFT), QCONST16(0.2924813f, DB_SHIFT), QCONST16(0.1609640f, DB_SHIFT), QCONST16(0.0849625f, DB_SHIFT), - QCONST16(0.0437314f, DB_SHIFT), QCONST16(0.0221971f, DB_SHIFT), QCONST16(0.0111839f, DB_SHIFT), QCONST16(0.0056136f, DB_SHIFT), - QCONST16(0.0028123f, DB_SHIFT) - }; - int low; - if (a>b) - { - max = a; - diff = SUB32(EXTEND32(a),EXTEND32(b)); - } else { - max = b; - diff = SUB32(EXTEND32(b),EXTEND32(a)); - } - if (!(diff < QCONST16(8.f, DB_SHIFT))) /* inverted to catch NaNs */ - return max; -#ifdef FIXED_POINT - low = SHR32(diff, DB_SHIFT-1); - frac = SHL16(diff - SHL16(low, DB_SHIFT-1), 16-DB_SHIFT); -#else - low = (int)floor(2*diff); - frac = 2*diff - low; -#endif - return max + diff_table[low] + MULT16_16_Q15(frac, SUB16(diff_table[low+1], diff_table[low])); -} -#else -opus_val16 logSum(opus_val16 a, opus_val16 b) -{ - return log2(pow(4, a)+ pow(4, b))/2; -} -#endif - -void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *bandLogE, opus_val32 *mem, opus_val32 *preemph_mem, - int len, int overlap, int channels, int rate, opus_copy_channel_in_func copy_channel_in, int arch -) -{ - int c; - int i; - int LM; - int pos[8] = {0}; - int upsample; - int frame_size; - int freq_size; - opus_val16 channel_offset; - opus_val32 bandE[21]; - opus_val16 maskLogE[3][21]; - VARDECL(opus_val32, in); - VARDECL(opus_val16, x); - VARDECL(opus_val32, freq); - SAVE_STACK; - - upsample = resampling_factor(rate); - frame_size = len*upsample; - freq_size = IMIN(960, frame_size); - - /* LM = log2(frame_size / 120) */ - for (LM=0;LMmaxLM;LM++) - if (celt_mode->shortMdctSize<preemph, preemph_mem+c, 0); -#ifndef FIXED_POINT - { - opus_val32 sum; - sum = celt_inner_prod(in, in, frame_size+overlap, 0); - /* This should filter out both NaNs and ridiculous signals that could - cause NaNs further down. */ - if (!(sum < 1e18f) || celt_isnan(sum)) - { - OPUS_CLEAR(in, frame_size+overlap); - preemph_mem[c] = 0; - } - } -#endif - OPUS_CLEAR(bandE, 21); - for (frame=0;framemdct, in+960*frame, freq, celt_mode->window, - overlap, celt_mode->maxLM-LM, 1, arch); - if (upsample != 1) - { - int bound = freq_size/upsample; - for (i=0;i=0;i--) - bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i+1]-QCONST16(2.f, DB_SHIFT)); - if (pos[c]==1) - { - for (i=0;i<21;i++) - maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]); - } else if (pos[c]==3) - { - for (i=0;i<21;i++) - maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]); - } else if (pos[c]==2) - { - for (i=0;i<21;i++) - { - maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT)); - maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT)); - } - } -#if 0 - for (i=0;i<21;i++) - printf("%f ", bandLogE[21*c+i]); - float sum=0; - for (i=0;i<21;i++) - sum += bandLogE[21*c+i]; - printf("%f ", sum/21); -#endif - OPUS_COPY(mem+c*overlap, in+frame_size, overlap); - } - for (i=0;i<21;i++) - maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]); - channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1))); - for (c=0;c<3;c++) - for (i=0;i<21;i++) - maskLogE[c][i] += channel_offset; -#if 0 - for (c=0;c<3;c++) - { - for (i=0;i<21;i++) - printf("%f ", maskLogE[c][i]); - } -#endif - for (c=0;cnb_streams||nb_coupled_streams<0)return 0; - coupled_size = opus_encoder_get_size(2); - mono_size = opus_encoder_get_size(1); - return align(sizeof(OpusMSEncoder)) - + nb_coupled_streams * align(coupled_size) - + (nb_streams-nb_coupled_streams) * align(mono_size); -} - -opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_family) -{ - int nb_streams; - int nb_coupled_streams; - opus_int32 size; - - if (mapping_family==0) - { - if (channels==1) - { - nb_streams=1; - nb_coupled_streams=0; - } else if (channels==2) - { - nb_streams=1; - nb_coupled_streams=1; - } else - return 0; - } else if (mapping_family==1 && channels<=8 && channels>=1) - { - nb_streams=vorbis_mappings[channels-1].nb_streams; - nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams; - } else if (mapping_family==255) - { - nb_streams=channels; - nb_coupled_streams=0; - } else if (mapping_family==2) - { - if (!validate_ambisonics(channels, &nb_streams, &nb_coupled_streams)) - return 0; - } else - return 0; - size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams); - if (channels>2) - { - size += channels*(120*sizeof(opus_val32) + sizeof(opus_val32)); - } - return size; -} - -static int opus_multistream_encoder_init_impl( - OpusMSEncoder *st, - opus_int32 Fs, - int channels, - int streams, - int coupled_streams, - const unsigned char *mapping, - int application, - MappingType mapping_type -) -{ - int coupled_size; - int mono_size; - int i, ret; - char *ptr; - - if ((channels>255) || (channels<1) || (coupled_streams>streams) || - (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams)) - return OPUS_BAD_ARG; - - st->arch = opus_select_arch(); - st->layout.nb_channels = channels; - st->layout.nb_streams = streams; - st->layout.nb_coupled_streams = coupled_streams; - if (mapping_type != MAPPING_TYPE_SURROUND) - st->lfe_stream = -1; - st->bitrate_bps = OPUS_AUTO; - st->application = application; - st->variable_duration = OPUS_FRAMESIZE_ARG; - for (i=0;ilayout.nb_channels;i++) - st->layout.mapping[i] = mapping[i]; - if (!validate_layout(&st->layout)) - return OPUS_BAD_ARG; - if (mapping_type == MAPPING_TYPE_SURROUND && - !validate_encoder_layout(&st->layout)) - return OPUS_BAD_ARG; - if (mapping_type == MAPPING_TYPE_AMBISONICS && - !validate_ambisonics(st->layout.nb_channels, NULL, NULL)) - return OPUS_BAD_ARG; - ptr = (char*)st + align(sizeof(OpusMSEncoder)); - coupled_size = opus_encoder_get_size(2); - mono_size = opus_encoder_get_size(1); - - for (i=0;ilayout.nb_coupled_streams;i++) - { - ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application); - if(ret!=OPUS_OK)return ret; - if (i==st->lfe_stream) - opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1)); - ptr += align(coupled_size); - } - for (;ilayout.nb_streams;i++) - { - ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application); - if (i==st->lfe_stream) - opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1)); - if(ret!=OPUS_OK)return ret; - ptr += align(mono_size); - } - if (mapping_type == MAPPING_TYPE_SURROUND) - { - OPUS_CLEAR(ms_get_preemph_mem(st), channels); - OPUS_CLEAR(ms_get_window_mem(st), channels*120); - } - st->mapping_type = mapping_type; - return OPUS_OK; -} - -int opus_multistream_encoder_init( - OpusMSEncoder *st, - opus_int32 Fs, - int channels, - int streams, - int coupled_streams, - const unsigned char *mapping, - int application -) -{ - return opus_multistream_encoder_init_impl(st, Fs, channels, streams, - coupled_streams, mapping, - application, MAPPING_TYPE_NONE); -} - -int opus_multistream_surround_encoder_init( - OpusMSEncoder *st, - opus_int32 Fs, - int channels, - int mapping_family, - int *streams, - int *coupled_streams, - unsigned char *mapping, - int application -) -{ - MappingType mapping_type; - - if ((channels>255) || (channels<1)) - return OPUS_BAD_ARG; - st->lfe_stream = -1; - if (mapping_family==0) - { - if (channels==1) - { - *streams=1; - *coupled_streams=0; - mapping[0]=0; - } else if (channels==2) - { - *streams=1; - *coupled_streams=1; - mapping[0]=0; - mapping[1]=1; - } else - return OPUS_UNIMPLEMENTED; - } else if (mapping_family==1 && channels<=8 && channels>=1) - { - int i; - *streams=vorbis_mappings[channels-1].nb_streams; - *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams; - for (i=0;i=6) - st->lfe_stream = *streams-1; - } else if (mapping_family==255) - { - int i; - *streams=channels; - *coupled_streams=0; - for(i=0;i2 && mapping_family==1) { - mapping_type = MAPPING_TYPE_SURROUND; - } else if (mapping_family==2) - { - mapping_type = MAPPING_TYPE_AMBISONICS; - } else - { - mapping_type = MAPPING_TYPE_NONE; - } - return opus_multistream_encoder_init_impl(st, Fs, channels, *streams, - *coupled_streams, mapping, - application, mapping_type); -} - -OpusMSEncoder *opus_multistream_encoder_create( - opus_int32 Fs, - int channels, - int streams, - int coupled_streams, - const unsigned char *mapping, - int application, - int *error -) -{ - int ret; - OpusMSEncoder *st; - if ((channels>255) || (channels<1) || (coupled_streams>streams) || - (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams)) - { - if (error) - *error = OPUS_BAD_ARG; - return NULL; - } - st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams)); - if (st==NULL) - { - if (error) - *error = OPUS_ALLOC_FAIL; - return NULL; - } - ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application); - if (ret != OPUS_OK) - { - opus_free(st); - st = NULL; - } - if (error) - *error = ret; - return st; -} - -OpusMSEncoder *opus_multistream_surround_encoder_create( - opus_int32 Fs, - int channels, - int mapping_family, - int *streams, - int *coupled_streams, - unsigned char *mapping, - int application, - int *error -) -{ - int ret; - opus_int32 size; - OpusMSEncoder *st; - if ((channels>255) || (channels<1)) - { - if (error) - *error = OPUS_BAD_ARG; - return NULL; - } - size = opus_multistream_surround_encoder_get_size(channels, mapping_family); - if (!size) - { - if (error) - *error = OPUS_UNIMPLEMENTED; - return NULL; - } - st = (OpusMSEncoder *)opus_alloc(size); - if (st==NULL) - { - if (error) - *error = OPUS_ALLOC_FAIL; - return NULL; - } - ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application); - if (ret != OPUS_OK) - { - opus_free(st); - st = NULL; - } - if (error) - *error = ret; - return st; -} - -static void surround_rate_allocation( - OpusMSEncoder *st, - opus_int32 *rate, - int frame_size, - opus_int32 Fs - ) -{ - int i; - opus_int32 channel_rate; - int stream_offset; - int lfe_offset; - int coupled_ratio; /* Q8 */ - int lfe_ratio; /* Q8 */ - int nb_lfe; - int nb_uncoupled; - int nb_coupled; - int nb_normal; - opus_int32 channel_offset; - opus_int32 bitrate; - int total; - - nb_lfe = (st->lfe_stream!=-1); - nb_coupled = st->layout.nb_coupled_streams; - nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe; - nb_normal = 2*nb_coupled + nb_uncoupled; - - /* Give each non-LFE channel enough bits per channel for coding band energy. */ - channel_offset = 40*IMAX(50, Fs/frame_size); - - if (st->bitrate_bps==OPUS_AUTO) - { - bitrate = nb_normal*(channel_offset + Fs + 10000) + 8000*nb_lfe; - } else if (st->bitrate_bps==OPUS_BITRATE_MAX) - { - bitrate = nb_normal*300000 + nb_lfe*128000; - } else { - bitrate = st->bitrate_bps; - } - - /* Give LFE some basic stream_channel allocation but never exceed 1/20 of the - total rate for the non-energy part to avoid problems at really low rate. */ - lfe_offset = IMIN(bitrate/20, 3000) + 15*IMAX(50, Fs/frame_size); - - /* We give each stream (coupled or uncoupled) a starting bitrate. - This models the main saving of coupled channels over uncoupled. */ - stream_offset = (bitrate - channel_offset*nb_normal - lfe_offset*nb_lfe)/nb_normal/2; - stream_offset = IMAX(0, IMIN(20000, stream_offset)); - - /* Coupled streams get twice the mono rate after the offset is allocated. */ - coupled_ratio = 512; - /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */ - lfe_ratio = 32; - - total = (nb_uncoupled<<8) /* mono */ - + coupled_ratio*nb_coupled /* stereo */ - + nb_lfe*lfe_ratio; - channel_rate = 256*(opus_int64)(bitrate - lfe_offset*nb_lfe - stream_offset*(nb_coupled+nb_uncoupled) - channel_offset*nb_normal)/total; - - for (i=0;ilayout.nb_streams;i++) - { - if (ilayout.nb_coupled_streams) - rate[i] = 2*channel_offset + IMAX(0, stream_offset+(channel_rate*coupled_ratio>>8)); - else if (i!=st->lfe_stream) - rate[i] = channel_offset + IMAX(0, stream_offset + channel_rate); - else - rate[i] = IMAX(0, lfe_offset+(channel_rate*lfe_ratio>>8)); - } -} - -static void ambisonics_rate_allocation( - OpusMSEncoder *st, - opus_int32 *rate, - int frame_size, - opus_int32 Fs - ) -{ - int i; - opus_int32 total_rate; - opus_int32 per_stream_rate; - - const int nb_channels = st->layout.nb_streams + st->layout.nb_coupled_streams; - - if (st->bitrate_bps==OPUS_AUTO) - { - total_rate = (st->layout.nb_coupled_streams + st->layout.nb_streams) * - (Fs+60*Fs/frame_size) + st->layout.nb_streams * (opus_int32)15000; - } else if (st->bitrate_bps==OPUS_BITRATE_MAX) - { - total_rate = nb_channels * 320000; - } else - { - total_rate = st->bitrate_bps; - } - - /* Allocate equal number of bits to Ambisonic (uncoupled) and non-diegetic - * (coupled) streams */ - per_stream_rate = total_rate / st->layout.nb_streams; - for (i = 0; i < st->layout.nb_streams; i++) - { - rate[i] = per_stream_rate; - } -} - -static opus_int32 rate_allocation( - OpusMSEncoder *st, - opus_int32 *rate, - int frame_size - ) -{ - int i; - opus_int32 rate_sum=0; - opus_int32 Fs; - char *ptr; - - ptr = (char*)st + align(sizeof(OpusMSEncoder)); - opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs)); - - if (st->mapping_type == MAPPING_TYPE_AMBISONICS) { - ambisonics_rate_allocation(st, rate, frame_size, Fs); - } else - { - surround_rate_allocation(st, rate, frame_size, Fs); - } - - for (i=0;ilayout.nb_streams;i++) - { - rate[i] = IMAX(rate[i], 500); - rate_sum += rate[i]; - } - return rate_sum; -} - -/* Max size in case the encoder decides to return six frames (6 x 20 ms = 120 ms) */ -#define MS_FRAME_TMP (6*1275+12) -int opus_multistream_encode_native -( - OpusMSEncoder *st, - opus_copy_channel_in_func copy_channel_in, - const void *pcm, - int analysis_frame_size, - unsigned char *data, - opus_int32 max_data_bytes, - int lsb_depth, - downmix_func downmix, - int float_api, - void *user_data -) -{ - opus_int32 Fs; - int coupled_size; - int mono_size; - int s; - char *ptr; - int tot_size; - VARDECL(opus_val16, buf); - VARDECL(opus_val16, bandSMR); - unsigned char tmp_data[MS_FRAME_TMP]; - OpusRepacketizer rp; - opus_int32 vbr; - const CELTMode *celt_mode; - opus_int32 bitrates[256]; - opus_val16 bandLogE[42]; - opus_val32 *mem = NULL; - opus_val32 *preemph_mem=NULL; - int frame_size; - opus_int32 rate_sum; - opus_int32 smallest_packet; - ALLOC_STACK; - - if (st->mapping_type == MAPPING_TYPE_SURROUND) - { - preemph_mem = ms_get_preemph_mem(st); - mem = ms_get_window_mem(st); - } - - ptr = (char*)st + align(sizeof(OpusMSEncoder)); - opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs)); - opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr)); - opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode)); - - frame_size = frame_size_select(analysis_frame_size, st->variable_duration, Fs); - if (frame_size <= 0) - { - RESTORE_STACK; - return OPUS_BAD_ARG; - } - - /* Smallest packet the encoder can produce. */ - smallest_packet = st->layout.nb_streams*2-1; - /* 100 ms needs an extra byte per stream for the ToC. */ - if (Fs/frame_size == 10) - smallest_packet += st->layout.nb_streams; - if (max_data_bytes < smallest_packet) - { - RESTORE_STACK; - return OPUS_BUFFER_TOO_SMALL; - } - ALLOC(buf, 2*frame_size, opus_val16); - coupled_size = opus_encoder_get_size(2); - mono_size = opus_encoder_get_size(1); - - ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16); - if (st->mapping_type == MAPPING_TYPE_SURROUND) - { - surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, 120, st->layout.nb_channels, Fs, copy_channel_in, st->arch); - } - - /* Compute bitrate allocation between streams (this could be a lot better) */ - rate_sum = rate_allocation(st, bitrates, frame_size); - - if (!vbr) - { - if (st->bitrate_bps == OPUS_AUTO) - { - max_data_bytes = IMIN(max_data_bytes, 3*rate_sum/(3*8*Fs/frame_size)); - } else if (st->bitrate_bps != OPUS_BITRATE_MAX) - { - max_data_bytes = IMIN(max_data_bytes, IMAX(smallest_packet, - 3*st->bitrate_bps/(3*8*Fs/frame_size))); - } - } - ptr = (char*)st + align(sizeof(OpusMSEncoder)); - for (s=0;slayout.nb_streams;s++) - { - OpusEncoder *enc; - enc = (OpusEncoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s])); - if (st->mapping_type == MAPPING_TYPE_SURROUND) - { - opus_int32 equiv_rate; - equiv_rate = st->bitrate_bps; - if (frame_size*50 < Fs) - equiv_rate -= 60*(Fs/frame_size - 50)*st->layout.nb_channels; - if (equiv_rate > 10000*st->layout.nb_channels) - opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); - else if (equiv_rate > 7000*st->layout.nb_channels) - opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND)); - else if (equiv_rate > 5000*st->layout.nb_channels) - opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND)); - else - opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); - if (s < st->layout.nb_coupled_streams) - { - /* To preserve the spatial image, force stereo CELT on coupled streams */ - opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY)); - opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2)); - } - } - else if (st->mapping_type == MAPPING_TYPE_AMBISONICS) { - opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY)); - } - } - - ptr = (char*)st + align(sizeof(OpusMSEncoder)); - /* Counting ToC */ - tot_size = 0; - for (s=0;slayout.nb_streams;s++) - { - OpusEncoder *enc; - int len; - int curr_max; - int c1, c2; - int ret; - - opus_repacketizer_init(&rp); - enc = (OpusEncoder*)ptr; - if (s < st->layout.nb_coupled_streams) - { - int i; - int left, right; - left = get_left_channel(&st->layout, s, -1); - right = get_right_channel(&st->layout, s, -1); - (*copy_channel_in)(buf, 2, - pcm, st->layout.nb_channels, left, frame_size, user_data); - (*copy_channel_in)(buf+1, 2, - pcm, st->layout.nb_channels, right, frame_size, user_data); - ptr += align(coupled_size); - if (st->mapping_type == MAPPING_TYPE_SURROUND) - { - for (i=0;i<21;i++) - { - bandLogE[i] = bandSMR[21*left+i]; - bandLogE[21+i] = bandSMR[21*right+i]; - } - } - c1 = left; - c2 = right; - } else { - int i; - int chan = get_mono_channel(&st->layout, s, -1); - (*copy_channel_in)(buf, 1, - pcm, st->layout.nb_channels, chan, frame_size, user_data); - ptr += align(mono_size); - if (st->mapping_type == MAPPING_TYPE_SURROUND) - { - for (i=0;i<21;i++) - bandLogE[i] = bandSMR[21*chan+i]; - } - c1 = chan; - c2 = -1; - } - if (st->mapping_type == MAPPING_TYPE_SURROUND) - opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE)); - /* number of bytes left (+Toc) */ - curr_max = max_data_bytes - tot_size; - /* Reserve one byte for the last stream and two for the others */ - curr_max -= IMAX(0,2*(st->layout.nb_streams-s-1)-1); - /* For 100 ms, reserve an extra byte per stream for the ToC */ - if (Fs/frame_size == 10) - curr_max -= st->layout.nb_streams-s-1; - curr_max = IMIN(curr_max,MS_FRAME_TMP); - /* Repacketizer will add one or two bytes for self-delimited frames */ - if (s != st->layout.nb_streams-1) curr_max -= curr_max>253 ? 2 : 1; - if (!vbr && s == st->layout.nb_streams-1) - opus_encoder_ctl(enc, OPUS_SET_BITRATE(curr_max*(8*Fs/frame_size))); - len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth, - pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix, float_api); - if (len<0) - { - RESTORE_STACK; - return len; - } - /* We need to use the repacketizer to add the self-delimiting lengths - while taking into account the fact that the encoder can now return - more than one frame at a time (e.g. 60 ms CELT-only) */ - ret = opus_repacketizer_cat(&rp, tmp_data, len); - /* If the opus_repacketizer_cat() fails, then something's seriously wrong - with the encoder. */ - if (ret != OPUS_OK) - { - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp), - data, max_data_bytes-tot_size, s != st->layout.nb_streams-1, !vbr && s == st->layout.nb_streams-1); - data += len; - tot_size += len; - } - /*printf("\n");*/ - RESTORE_STACK; - return tot_size; -} - -#if !defined(DISABLE_FLOAT_API) -static void opus_copy_channel_in_float( - opus_val16 *dst, - int dst_stride, - const void *src, - int src_stride, - int src_channel, - int frame_size, - void *user_data -) -{ - const float *float_src; - opus_int32 i; - (void)user_data; - float_src = (const float *)src; - for (i=0;ilayout.nb_channels, IMAX(500*st->layout.nb_channels, value)); - } - st->bitrate_bps = value; - } - break; - case OPUS_GET_BITRATE_REQUEST: - { - int s; - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = 0; - for (s=0;slayout.nb_streams;s++) - { - opus_int32 rate; - OpusEncoder *enc; - enc = (OpusEncoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - opus_encoder_ctl(enc, request, &rate); - *value += rate; - } - } - break; - case OPUS_GET_LSB_DEPTH_REQUEST: - case OPUS_GET_VBR_REQUEST: - case OPUS_GET_APPLICATION_REQUEST: - case OPUS_GET_BANDWIDTH_REQUEST: - case OPUS_GET_COMPLEXITY_REQUEST: - case OPUS_GET_PACKET_LOSS_PERC_REQUEST: - case OPUS_GET_DTX_REQUEST: - case OPUS_GET_VOICE_RATIO_REQUEST: - case OPUS_GET_VBR_CONSTRAINT_REQUEST: - case OPUS_GET_SIGNAL_REQUEST: - case OPUS_GET_LOOKAHEAD_REQUEST: - case OPUS_GET_SAMPLE_RATE_REQUEST: - case OPUS_GET_INBAND_FEC_REQUEST: - case OPUS_GET_FORCE_CHANNELS_REQUEST: - case OPUS_GET_PREDICTION_DISABLED_REQUEST: - case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST: - { - OpusEncoder *enc; - /* For int32* GET params, just query the first stream */ - opus_int32 *value = va_arg(ap, opus_int32*); - enc = (OpusEncoder*)ptr; - ret = opus_encoder_ctl(enc, request, value); - } - break; - case OPUS_GET_FINAL_RANGE_REQUEST: - { - int s; - opus_uint32 *value = va_arg(ap, opus_uint32*); - opus_uint32 tmp; - if (!value) - { - goto bad_arg; - } - *value=0; - for (s=0;slayout.nb_streams;s++) - { - OpusEncoder *enc; - enc = (OpusEncoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - ret = opus_encoder_ctl(enc, request, &tmp); - if (ret != OPUS_OK) break; - *value ^= tmp; - } - } - break; - case OPUS_SET_LSB_DEPTH_REQUEST: - case OPUS_SET_COMPLEXITY_REQUEST: - case OPUS_SET_VBR_REQUEST: - case OPUS_SET_VBR_CONSTRAINT_REQUEST: - case OPUS_SET_MAX_BANDWIDTH_REQUEST: - case OPUS_SET_BANDWIDTH_REQUEST: - case OPUS_SET_SIGNAL_REQUEST: - case OPUS_SET_APPLICATION_REQUEST: - case OPUS_SET_INBAND_FEC_REQUEST: - case OPUS_SET_PACKET_LOSS_PERC_REQUEST: - case OPUS_SET_DTX_REQUEST: - case OPUS_SET_FORCE_MODE_REQUEST: - case OPUS_SET_FORCE_CHANNELS_REQUEST: - case OPUS_SET_PREDICTION_DISABLED_REQUEST: - case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST: - { - int s; - /* This works for int32 params */ - opus_int32 value = va_arg(ap, opus_int32); - for (s=0;slayout.nb_streams;s++) - { - OpusEncoder *enc; - - enc = (OpusEncoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - ret = opus_encoder_ctl(enc, request, value); - if (ret != OPUS_OK) - break; - } - } - break; - case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST: - { - int s; - opus_int32 stream_id; - OpusEncoder **value; - stream_id = va_arg(ap, opus_int32); - if (stream_id<0 || stream_id >= st->layout.nb_streams) - goto bad_arg; - value = va_arg(ap, OpusEncoder**); - if (!value) - { - goto bad_arg; - } - for (s=0;slayout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - } - *value = (OpusEncoder*)ptr; - } - break; - case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - st->variable_duration = value; - } - break; - case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = st->variable_duration; - } - break; - case OPUS_RESET_STATE: - { - int s; - if (st->mapping_type == MAPPING_TYPE_SURROUND) - { - OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels); - OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*120); - } - for (s=0;slayout.nb_streams;s++) - { - OpusEncoder *enc; - enc = (OpusEncoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - ret = opus_encoder_ctl(enc, OPUS_RESET_STATE); - if (ret != OPUS_OK) - break; - } - } - break; - default: - ret = OPUS_UNIMPLEMENTED; - break; - } - return ret; -bad_arg: - return OPUS_BAD_ARG; -} - -int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) -{ - int ret; - va_list ap; - va_start(ap, request); - ret = opus_multistream_encoder_ctl_va_list(st, request, ap); - va_end(ap); - return ret; -} - -void opus_multistream_encoder_destroy(OpusMSEncoder *st) -{ - opus_free(st); -} diff --git a/src/libopus/opus_projection_decoder.c b/src/libopus/opus_projection_decoder.c deleted file mode 100644 index 15cefaf0..00000000 --- a/src/libopus/opus_projection_decoder.c +++ /dev/null @@ -1,258 +0,0 @@ -/* Copyright (c) 2017 Google Inc. - Written by Andrew Allen */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -//#ifdef HAVE_CONFIG_H -#include "config.h" -//#endif - -#include "celt/mathops.h" -#include "celt/os_support.h" -#include "opus_private.h" -#include "opus_defines.h" -#include "opus_projection.h" -#include "opus_multistream.h" -#include "mapping_matrix.h" -#include "celt/stack_alloc.h" - -struct OpusProjectionDecoder -{ - opus_int32 demixing_matrix_size_in_bytes; - /* Encoder states go here */ -}; - -#if !defined(DISABLE_FLOAT_API) -static void opus_projection_copy_channel_out_float( - void *dst, - int dst_stride, - int dst_channel, - const opus_val16 *src, - int src_stride, - int frame_size, - void *user_data) -{ - float *float_dst; - const MappingMatrix *matrix; - float_dst = (float *)dst; - matrix = (const MappingMatrix *)user_data; - - if (dst_channel == 0) - OPUS_CLEAR(float_dst, frame_size * dst_stride); - - if (src != NULL) - mapping_matrix_multiply_channel_out_float(matrix, src, dst_channel, - src_stride, float_dst, dst_stride, frame_size); -} -#endif - -static void opus_projection_copy_channel_out_short( - void *dst, - int dst_stride, - int dst_channel, - const opus_val16 *src, - int src_stride, - int frame_size, - void *user_data) -{ - opus_int16 *short_dst; - const MappingMatrix *matrix; - short_dst = (opus_int16 *)dst; - matrix = (const MappingMatrix *)user_data; - if (dst_channel == 0) - OPUS_CLEAR(short_dst, frame_size * dst_stride); - - if (src != NULL) - mapping_matrix_multiply_channel_out_short(matrix, src, dst_channel, - src_stride, short_dst, dst_stride, frame_size); -} - -static MappingMatrix *get_dec_demixing_matrix(OpusProjectionDecoder *st) -{ - /* void* cast avoids clang -Wcast-align warning */ - return (MappingMatrix*)(void*)((char*)st + - align(sizeof(OpusProjectionDecoder))); -} - -static OpusMSDecoder *get_multistream_decoder(OpusProjectionDecoder *st) -{ - /* void* cast avoids clang -Wcast-align warning */ - return (OpusMSDecoder*)(void*)((char*)st + - align(sizeof(OpusProjectionDecoder) + - st->demixing_matrix_size_in_bytes)); -} - -opus_int32 opus_projection_decoder_get_size(int channels, int streams, - int coupled_streams) -{ - opus_int32 matrix_size; - opus_int32 decoder_size; - - matrix_size = - mapping_matrix_get_size(streams + coupled_streams, channels); - if (!matrix_size) - return 0; - - decoder_size = opus_multistream_decoder_get_size(streams, coupled_streams); - if (!decoder_size) - return 0; - - return align(sizeof(OpusProjectionDecoder)) + matrix_size + decoder_size; -} - -int opus_projection_decoder_init(OpusProjectionDecoder *st, opus_int32 Fs, - int channels, int streams, int coupled_streams, - unsigned char *demixing_matrix, opus_int32 demixing_matrix_size) -{ - int nb_input_streams; - opus_int32 expected_matrix_size; - int i, ret; - unsigned char mapping[255]; - VARDECL(opus_int16, buf); - ALLOC_STACK; - - /* Verify supplied matrix size. */ - nb_input_streams = streams + coupled_streams; - expected_matrix_size = nb_input_streams * channels * sizeof(opus_int16); - if (expected_matrix_size != demixing_matrix_size) - { - RESTORE_STACK; - return OPUS_BAD_ARG; - } - - /* Convert demixing matrix input into internal format. */ - ALLOC(buf, nb_input_streams * channels, opus_int16); - for (i = 0; i < nb_input_streams * channels; i++) - { - int s = demixing_matrix[2*i + 1] << 8 | demixing_matrix[2*i]; - s = ((s & 0xFFFF) ^ 0x8000) - 0x8000; - buf[i] = (opus_int16)s; - } - - /* Assign demixing matrix. */ - st->demixing_matrix_size_in_bytes = - mapping_matrix_get_size(channels, nb_input_streams); - if (!st->demixing_matrix_size_in_bytes) - { - RESTORE_STACK; - return OPUS_BAD_ARG; - } - - mapping_matrix_init(get_dec_demixing_matrix(st), channels, nb_input_streams, 0, - buf, demixing_matrix_size); - - /* Set trivial mapping so each input channel pairs with a matrix column. */ - for (i = 0; i < channels; i++) - mapping[i] = i; - - ret = opus_multistream_decoder_init( - get_multistream_decoder(st), Fs, channels, streams, coupled_streams, mapping); - RESTORE_STACK; - return ret; -} - -OpusProjectionDecoder *opus_projection_decoder_create( - opus_int32 Fs, int channels, int streams, int coupled_streams, - unsigned char *demixing_matrix, opus_int32 demixing_matrix_size, int *error) -{ - int size; - int ret; - OpusProjectionDecoder *st; - - /* Allocate space for the projection decoder. */ - size = opus_projection_decoder_get_size(channels, streams, coupled_streams); - if (!size) { - if (error) - *error = OPUS_ALLOC_FAIL; - return NULL; - } - st = (OpusProjectionDecoder *)opus_alloc(size); - if (!st) - { - if (error) - *error = OPUS_ALLOC_FAIL; - return NULL; - } - - /* Initialize projection decoder with provided settings. */ - ret = opus_projection_decoder_init(st, Fs, channels, streams, coupled_streams, - demixing_matrix, demixing_matrix_size); - if (ret != OPUS_OK) - { - opus_free(st); - st = NULL; - } - if (error) - *error = ret; - return st; -} - -#ifdef FIXED_POINT -int opus_projection_decode(OpusProjectionDecoder *st, const unsigned char *data, - opus_int32 len, opus_int16 *pcm, int frame_size, - int decode_fec) -{ - return opus_multistream_decode_native(get_multistream_decoder(st), data, len, - pcm, opus_projection_copy_channel_out_short, frame_size, decode_fec, 0, - get_dec_demixing_matrix(st)); -} -#else -int opus_projection_decode(OpusProjectionDecoder *st, const unsigned char *data, - opus_int32 len, opus_int16 *pcm, int frame_size, - int decode_fec) -{ - return opus_multistream_decode_native(get_multistream_decoder(st), data, len, - pcm, opus_projection_copy_channel_out_short, frame_size, decode_fec, 1, - get_dec_demixing_matrix(st)); -} -#endif - -#ifndef DISABLE_FLOAT_API -int opus_projection_decode_float(OpusProjectionDecoder *st, const unsigned char *data, - opus_int32 len, float *pcm, int frame_size, int decode_fec) -{ - return opus_multistream_decode_native(get_multistream_decoder(st), data, len, - pcm, opus_projection_copy_channel_out_float, frame_size, decode_fec, 0, - get_dec_demixing_matrix(st)); -} -#endif - -int opus_projection_decoder_ctl(OpusProjectionDecoder *st, int request, ...) -{ - va_list ap; - int ret = OPUS_OK; - - va_start(ap, request); - ret = opus_multistream_decoder_ctl_va_list(get_multistream_decoder(st), - request, ap); - va_end(ap); - return ret; -} - -void opus_projection_decoder_destroy(OpusProjectionDecoder *st) -{ - opus_free(st); -} - diff --git a/src/libopus/opus_projection_encoder.c b/src/libopus/opus_projection_encoder.c deleted file mode 100644 index a3a9762a..00000000 --- a/src/libopus/opus_projection_encoder.c +++ /dev/null @@ -1,468 +0,0 @@ -/* Copyright (c) 2017 Google Inc. - Written by Andrew Allen */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -//#ifdef HAVE_CONFIG_H -#include "config.h" -//#endif - -#include "celt/mathops.h" -#include "celt/os_support.h" -#include "opus_private.h" -#include "opus_defines.h" -#include "opus_projection.h" -#include "opus_multistream.h" -#include "celt/stack_alloc.h" -#include "mapping_matrix.h" - -struct OpusProjectionEncoder -{ - opus_int32 mixing_matrix_size_in_bytes; - opus_int32 demixing_matrix_size_in_bytes; - /* Encoder states go here */ -}; - -#if !defined(DISABLE_FLOAT_API) -static void opus_projection_copy_channel_in_float( - opus_val16 *dst, - int dst_stride, - const void *src, - int src_stride, - int src_channel, - int frame_size, - void *user_data -) -{ - mapping_matrix_multiply_channel_in_float((const MappingMatrix*)user_data, - (const float*)src, src_stride, dst, src_channel, dst_stride, frame_size); -} -#endif - -static void opus_projection_copy_channel_in_short( - opus_val16 *dst, - int dst_stride, - const void *src, - int src_stride, - int src_channel, - int frame_size, - void *user_data -) -{ - mapping_matrix_multiply_channel_in_short((const MappingMatrix*)user_data, - (const opus_int16*)src, src_stride, dst, src_channel, dst_stride, frame_size); -} - -static int get_order_plus_one_from_channels(int channels, int *order_plus_one) -{ - int order_plus_one_; - int acn_channels; - int nondiegetic_channels; - - /* Allowed numbers of channels: - * (1 + n)^2 + 2j, for n = 0...14 and j = 0 or 1. - */ - if (channels < 1 || channels > 227) - return OPUS_BAD_ARG; - - order_plus_one_ = isqrt32(channels); - acn_channels = order_plus_one_ * order_plus_one_; - nondiegetic_channels = channels - acn_channels; - if (nondiegetic_channels != 0 && nondiegetic_channels != 2) - return OPUS_BAD_ARG; - - if (order_plus_one) - *order_plus_one = order_plus_one_; - return OPUS_OK; -} - -static int get_streams_from_channels(int channels, int mapping_family, - int *streams, int *coupled_streams, - int *order_plus_one) -{ - if (mapping_family == 3) - { - if (get_order_plus_one_from_channels(channels, order_plus_one) != OPUS_OK) - return OPUS_BAD_ARG; - if (streams) - *streams = (channels + 1) / 2; - if (coupled_streams) - *coupled_streams = channels / 2; - return OPUS_OK; - } - return OPUS_BAD_ARG; -} - -static MappingMatrix *get_mixing_matrix(OpusProjectionEncoder *st) -{ - /* void* cast avoids clang -Wcast-align warning */ - return (MappingMatrix *)(void*)((char*)st + - align(sizeof(OpusProjectionEncoder))); -} - -static MappingMatrix *get_enc_demixing_matrix(OpusProjectionEncoder *st) -{ - /* void* cast avoids clang -Wcast-align warning */ - return (MappingMatrix *)(void*)((char*)st + - align(sizeof(OpusProjectionEncoder) + - st->mixing_matrix_size_in_bytes)); -} - -static OpusMSEncoder *get_multistream_encoder(OpusProjectionEncoder *st) -{ - /* void* cast avoids clang -Wcast-align warning */ - return (OpusMSEncoder *)(void*)((char*)st + - align(sizeof(OpusProjectionEncoder) + - st->mixing_matrix_size_in_bytes + - st->demixing_matrix_size_in_bytes)); -} - -opus_int32 opus_projection_ambisonics_encoder_get_size(int channels, - int mapping_family) -{ - int nb_streams; - int nb_coupled_streams; - int order_plus_one; - int mixing_matrix_rows, mixing_matrix_cols; - int demixing_matrix_rows, demixing_matrix_cols; - opus_int32 mixing_matrix_size, demixing_matrix_size; - opus_int32 encoder_size; - int ret; - - ret = get_streams_from_channels(channels, mapping_family, &nb_streams, - &nb_coupled_streams, &order_plus_one); - if (ret != OPUS_OK) - return 0; - - if (order_plus_one == 2) - { - mixing_matrix_rows = mapping_matrix_foa_mixing.rows; - mixing_matrix_cols = mapping_matrix_foa_mixing.cols; - demixing_matrix_rows = mapping_matrix_foa_demixing.rows; - demixing_matrix_cols = mapping_matrix_foa_demixing.cols; - } - else if (order_plus_one == 3) - { - mixing_matrix_rows = mapping_matrix_soa_mixing.rows; - mixing_matrix_cols = mapping_matrix_soa_mixing.cols; - demixing_matrix_rows = mapping_matrix_soa_demixing.rows; - demixing_matrix_cols = mapping_matrix_soa_demixing.cols; - } - else if (order_plus_one == 4) - { - mixing_matrix_rows = mapping_matrix_toa_mixing.rows; - mixing_matrix_cols = mapping_matrix_toa_mixing.cols; - demixing_matrix_rows = mapping_matrix_toa_demixing.rows; - demixing_matrix_cols = mapping_matrix_toa_demixing.cols; - } - else - return 0; - - mixing_matrix_size = - mapping_matrix_get_size(mixing_matrix_rows, mixing_matrix_cols); - if (!mixing_matrix_size) - return 0; - - demixing_matrix_size = - mapping_matrix_get_size(demixing_matrix_rows, demixing_matrix_cols); - if (!demixing_matrix_size) - return 0; - - encoder_size = - opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams); - if (!encoder_size) - return 0; - - return align(sizeof(OpusProjectionEncoder)) + - mixing_matrix_size + demixing_matrix_size + encoder_size; -} - -int opus_projection_ambisonics_encoder_init(OpusProjectionEncoder *st, opus_int32 Fs, - int channels, int mapping_family, - int *streams, int *coupled_streams, - int application) -{ - MappingMatrix *mixing_matrix; - MappingMatrix *demixing_matrix; - OpusMSEncoder *ms_encoder; - int i; - int ret; - int order_plus_one; - unsigned char mapping[255]; - - if (streams == NULL || coupled_streams == NULL) { - return OPUS_BAD_ARG; - } - - if (get_streams_from_channels(channels, mapping_family, streams, - coupled_streams, &order_plus_one) != OPUS_OK) - return OPUS_BAD_ARG; - - if (mapping_family == 3) - { - /* Assign mixing matrix based on available pre-computed matrices. */ - mixing_matrix = get_mixing_matrix(st); - if (order_plus_one == 2) - { - mapping_matrix_init(mixing_matrix, mapping_matrix_foa_mixing.rows, - mapping_matrix_foa_mixing.cols, mapping_matrix_foa_mixing.gain, - mapping_matrix_foa_mixing_data, - sizeof(mapping_matrix_foa_mixing_data)); - } - else if (order_plus_one == 3) - { - mapping_matrix_init(mixing_matrix, mapping_matrix_soa_mixing.rows, - mapping_matrix_soa_mixing.cols, mapping_matrix_soa_mixing.gain, - mapping_matrix_soa_mixing_data, - sizeof(mapping_matrix_soa_mixing_data)); - } - else if (order_plus_one == 4) - { - mapping_matrix_init(mixing_matrix, mapping_matrix_toa_mixing.rows, - mapping_matrix_toa_mixing.cols, mapping_matrix_toa_mixing.gain, - mapping_matrix_toa_mixing_data, - sizeof(mapping_matrix_toa_mixing_data)); - } - else - return OPUS_BAD_ARG; - - st->mixing_matrix_size_in_bytes = mapping_matrix_get_size( - mixing_matrix->rows, mixing_matrix->cols); - if (!st->mixing_matrix_size_in_bytes) - return OPUS_BAD_ARG; - - /* Assign demixing matrix based on available pre-computed matrices. */ - demixing_matrix = get_enc_demixing_matrix(st); - if (order_plus_one == 2) - { - mapping_matrix_init(demixing_matrix, mapping_matrix_foa_demixing.rows, - mapping_matrix_foa_demixing.cols, mapping_matrix_foa_demixing.gain, - mapping_matrix_foa_demixing_data, - sizeof(mapping_matrix_foa_demixing_data)); - } - else if (order_plus_one == 3) - { - mapping_matrix_init(demixing_matrix, mapping_matrix_soa_demixing.rows, - mapping_matrix_soa_demixing.cols, mapping_matrix_soa_demixing.gain, - mapping_matrix_soa_demixing_data, - sizeof(mapping_matrix_soa_demixing_data)); - } - else if (order_plus_one == 4) - { - mapping_matrix_init(demixing_matrix, mapping_matrix_toa_demixing.rows, - mapping_matrix_toa_demixing.cols, mapping_matrix_toa_demixing.gain, - mapping_matrix_toa_demixing_data, - sizeof(mapping_matrix_toa_demixing_data)); - } - else - return OPUS_BAD_ARG; - - st->demixing_matrix_size_in_bytes = mapping_matrix_get_size( - demixing_matrix->rows, demixing_matrix->cols); - if (!st->demixing_matrix_size_in_bytes) - return OPUS_BAD_ARG; - } - else - return OPUS_UNIMPLEMENTED; - - /* Ensure matrices are large enough for desired coding scheme. */ - if (*streams + *coupled_streams > mixing_matrix->rows || - channels > mixing_matrix->cols || - channels > demixing_matrix->rows || - *streams + *coupled_streams > demixing_matrix->cols) - return OPUS_BAD_ARG; - - /* Set trivial mapping so each input channel pairs with a matrix column. */ - for (i = 0; i < channels; i++) - mapping[i] = i; - - /* Initialize multistream encoder with provided settings. */ - ms_encoder = get_multistream_encoder(st); - ret = opus_multistream_encoder_init(ms_encoder, Fs, channels, *streams, - *coupled_streams, mapping, application); - return ret; -} - -OpusProjectionEncoder *opus_projection_ambisonics_encoder_create( - opus_int32 Fs, int channels, int mapping_family, int *streams, - int *coupled_streams, int application, int *error) -{ - int size; - int ret; - OpusProjectionEncoder *st; - - /* Allocate space for the projection encoder. */ - size = opus_projection_ambisonics_encoder_get_size(channels, mapping_family); - if (!size) { - if (error) - *error = OPUS_ALLOC_FAIL; - return NULL; - } - st = (OpusProjectionEncoder *)opus_alloc(size); - if (!st) - { - if (error) - *error = OPUS_ALLOC_FAIL; - return NULL; - } - - /* Initialize projection encoder with provided settings. */ - ret = opus_projection_ambisonics_encoder_init(st, Fs, channels, - mapping_family, streams, coupled_streams, application); - if (ret != OPUS_OK) - { - opus_free(st); - st = NULL; - } - if (error) - *error = ret; - return st; -} - -int opus_projection_encode(OpusProjectionEncoder *st, const opus_int16 *pcm, - int frame_size, unsigned char *data, - opus_int32 max_data_bytes) -{ - return opus_multistream_encode_native(get_multistream_encoder(st), - opus_projection_copy_channel_in_short, pcm, frame_size, data, - max_data_bytes, 16, downmix_int, 0, get_mixing_matrix(st)); -} - -#ifndef DISABLE_FLOAT_API -#ifdef FIXED_POINT -int opus_projection_encode_float(OpusProjectionEncoder *st, const float *pcm, - int frame_size, unsigned char *data, - opus_int32 max_data_bytes) -{ - return opus_multistream_encode_native(get_multistream_encoder(st), - opus_projection_copy_channel_in_float, pcm, frame_size, data, - max_data_bytes, 16, downmix_float, 1, get_mixing_matrix(st)); -} -#else -int opus_projection_encode_float(OpusProjectionEncoder *st, const float *pcm, - int frame_size, unsigned char *data, - opus_int32 max_data_bytes) -{ - return opus_multistream_encode_native(get_multistream_encoder(st), - opus_projection_copy_channel_in_float, pcm, frame_size, data, - max_data_bytes, 24, downmix_float, 1, get_mixing_matrix(st)); -} -#endif -#endif - -void opus_projection_encoder_destroy(OpusProjectionEncoder *st) -{ - opus_free(st); -} - -int opus_projection_encoder_ctl(OpusProjectionEncoder *st, int request, ...) -{ - va_list ap; - MappingMatrix *demixing_matrix; - OpusMSEncoder *ms_encoder; - int ret = OPUS_OK; - - ms_encoder = get_multistream_encoder(st); - demixing_matrix = get_enc_demixing_matrix(st); - - va_start(ap, request); - switch(request) - { - case OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = - ms_encoder->layout.nb_channels * (ms_encoder->layout.nb_streams - + ms_encoder->layout.nb_coupled_streams) * sizeof(opus_int16); - } - break; - case OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (!value) - { - goto bad_arg; - } - *value = demixing_matrix->gain; - } - break; - case OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST: - { - int i, j, k, l; - int nb_input_streams; - int nb_output_streams; - unsigned char *external_char; - opus_int16 *internal_short; - opus_int32 external_size; - opus_int32 internal_size; - - /* (I/O is in relation to the decoder's perspective). */ - nb_input_streams = ms_encoder->layout.nb_streams + - ms_encoder->layout.nb_coupled_streams; - nb_output_streams = ms_encoder->layout.nb_channels; - - external_char = va_arg(ap, unsigned char *); - external_size = va_arg(ap, opus_int32); - if (!external_char) - { - goto bad_arg; - } - internal_short = mapping_matrix_get_data(demixing_matrix); - internal_size = nb_input_streams * nb_output_streams * sizeof(opus_int16); - if (external_size != internal_size) - { - goto bad_arg; - } - - /* Copy demixing matrix subset to output destination. */ - l = 0; - for (i = 0; i < nb_input_streams; i++) { - for (j = 0; j < nb_output_streams; j++) { - k = demixing_matrix->rows * i + j; - external_char[2*l] = (unsigned char)internal_short[k]; - external_char[2*l+1] = (unsigned char)(internal_short[k] >> 8); - l++; - } - } - } - break; - default: - { - ret = opus_multistream_encoder_ctl_va_list(ms_encoder, request, ap); - } - break; - } - va_end(ap); - return ret; - -bad_arg: - va_end(ap); - return OPUS_BAD_ARG; -} - diff --git a/src/libopus/repacketizer.c b/src/libopus/repacketizer.c deleted file mode 100644 index 5a1eb675..00000000 --- a/src/libopus/repacketizer.c +++ /dev/null @@ -1,349 +0,0 @@ -/* Copyright (c) 2011 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -//#ifdef HAVE_CONFIG_H -#include "config.h" -//#endif - -#include "opus.h" -#include "opus_private.h" -#include "celt/os_support.h" - - -int opus_repacketizer_get_size(void) -{ - return sizeof(OpusRepacketizer); -} - -OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) -{ - rp->nb_frames = 0; - return rp; -} - -OpusRepacketizer *opus_repacketizer_create(void) -{ - OpusRepacketizer *rp; - rp=(OpusRepacketizer *)opus_alloc(opus_repacketizer_get_size()); - if(rp==NULL)return NULL; - return opus_repacketizer_init(rp); -} - -void opus_repacketizer_destroy(OpusRepacketizer *rp) -{ - opus_free(rp); -} - -static int opus_repacketizer_cat_impl(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len, int self_delimited) -{ - unsigned char tmp_toc; - int curr_nb_frames,ret; - /* Set of check ToC */ - if (len<1) return OPUS_INVALID_PACKET; - if (rp->nb_frames == 0) - { - rp->toc = data[0]; - rp->framesize = opus_packet_get_samples_per_frame(data, 8000); - } else if ((rp->toc&0xFC) != (data[0]&0xFC)) - { - /*fprintf(stderr, "toc mismatch: 0x%x vs 0x%x\n", rp->toc, data[0]);*/ - return OPUS_INVALID_PACKET; - } - curr_nb_frames = opus_packet_get_nb_frames(data, len); - if(curr_nb_frames<1) return OPUS_INVALID_PACKET; - - /* Check the 120 ms maximum packet size */ - if ((curr_nb_frames+rp->nb_frames)*rp->framesize > 960) - { - return OPUS_INVALID_PACKET; - } - - ret=opus_packet_parse_impl(data, len, self_delimited, &tmp_toc, &rp->frames[rp->nb_frames], &rp->len[rp->nb_frames], NULL, NULL); - if(ret<1)return ret; - - rp->nb_frames += curr_nb_frames; - return OPUS_OK; -} - -int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) -{ - return opus_repacketizer_cat_impl(rp, data, len, 0); -} - -int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) -{ - return rp->nb_frames; -} - -opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end, - unsigned char *data, opus_int32 maxlen, int self_delimited, int pad) -{ - int i, count; - opus_int32 tot_size; - opus_int16 *len; - const unsigned char **frames; - unsigned char * ptr; - - if (begin<0 || begin>=end || end>rp->nb_frames) - { - /*fprintf(stderr, "%d %d %d\n", begin, end, rp->nb_frames);*/ - return OPUS_BAD_ARG; - } - count = end-begin; - - len = rp->len+begin; - frames = rp->frames+begin; - if (self_delimited) - tot_size = 1 + (len[count-1]>=252); - else - tot_size = 0; - - ptr = data; - if (count==1) - { - /* Code 0 */ - tot_size += len[0]+1; - if (tot_size > maxlen) - return OPUS_BUFFER_TOO_SMALL; - *ptr++ = rp->toc&0xFC; - } else if (count==2) - { - if (len[1] == len[0]) - { - /* Code 1 */ - tot_size += 2*len[0]+1; - if (tot_size > maxlen) - return OPUS_BUFFER_TOO_SMALL; - *ptr++ = (rp->toc&0xFC) | 0x1; - } else { - /* Code 2 */ - tot_size += len[0]+len[1]+2+(len[0]>=252); - if (tot_size > maxlen) - return OPUS_BUFFER_TOO_SMALL; - *ptr++ = (rp->toc&0xFC) | 0x2; - ptr += encode_size(len[0], ptr); - } - } - if (count > 2 || (pad && tot_size < maxlen)) - { - /* Code 3 */ - int vbr; - int pad_amount=0; - - /* Restart the process for the padding case */ - ptr = data; - if (self_delimited) - tot_size = 1 + (len[count-1]>=252); - else - tot_size = 0; - vbr = 0; - for (i=1;i=252) + len[i]; - tot_size += len[count-1]; - - if (tot_size > maxlen) - return OPUS_BUFFER_TOO_SMALL; - *ptr++ = (rp->toc&0xFC) | 0x3; - *ptr++ = count | 0x80; - } else { - tot_size += count*len[0]+2; - if (tot_size > maxlen) - return OPUS_BUFFER_TOO_SMALL; - *ptr++ = (rp->toc&0xFC) | 0x3; - *ptr++ = count; - } - pad_amount = pad ? (maxlen-tot_size) : 0; - if (pad_amount != 0) - { - int nb_255s; - data[1] |= 0x40; - nb_255s = (pad_amount-1)/255; - for (i=0;inb_frames, data, maxlen, 0, 0); -} - -int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len) -{ - OpusRepacketizer rp; - opus_int32 ret; - if (len < 1) - return OPUS_BAD_ARG; - if (len==new_len) - return OPUS_OK; - else if (len > new_len) - return OPUS_BAD_ARG; - opus_repacketizer_init(&rp); - /* Moving payload to the end of the packet so we can do in-place padding */ - OPUS_MOVE(data+new_len-len, data, len); - ret = opus_repacketizer_cat(&rp, data+new_len-len, len); - if (ret != OPUS_OK) - return ret; - ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, new_len, 0, 1); - if (ret > 0) - return OPUS_OK; - else - return ret; -} - -opus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len) -{ - OpusRepacketizer rp; - opus_int32 ret; - if (len < 1) - return OPUS_BAD_ARG; - opus_repacketizer_init(&rp); - ret = opus_repacketizer_cat(&rp, data, len); - if (ret < 0) - return ret; - ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, len, 0, 0); - celt_assert(ret > 0 && ret <= len); - return ret; -} - -int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len, int nb_streams) -{ - int s; - int count; - unsigned char toc; - opus_int16 size[48]; - opus_int32 packet_offset; - opus_int32 amount; - - if (len < 1) - return OPUS_BAD_ARG; - if (len==new_len) - return OPUS_OK; - else if (len > new_len) - return OPUS_BAD_ARG; - amount = new_len - len; - /* Seek to last stream */ - for (s=0;snb_subfr; i++ ) { psCNG->CNG_smth_Gain_Q16 += silk_SMULWB( psDecCtrl->Gains_Q16[ i ] - psCNG->CNG_smth_Gain_Q16, CNG_GAIN_SMTH_Q16 ); + /* If the smoothed gain is 3 dB greater than this subframe's gain, use this subframe's gain to adapt faster. */ + if( silk_SMULWW( psCNG->CNG_smth_Gain_Q16, CNG_GAIN_SMTH_THRESHOLD_Q16 ) > psDecCtrl->Gains_Q16[ i ] ) { + psCNG->CNG_smth_Gain_Q16 = psDecCtrl->Gains_Q16[ i ]; + } } } diff --git a/src/libopus/silk/HP_variable_cutoff.c b/src/libopus/silk/HP_variable_cutoff.c index 6a8c900b..31352e6d 100644 --- a/src/libopus/silk/HP_variable_cutoff.c +++ b/src/libopus/silk/HP_variable_cutoff.c @@ -25,11 +25,11 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #ifdef FIXED_POINT -#include "fixed/main_FIX.h" +#include "main_FIX.h" #else #include "main_FLP.h" #endif diff --git a/src/libopus/silk/LPC_analysis_filter.c b/src/libopus/silk/LPC_analysis_filter.c index 4e838189..494c93c4 100644 --- a/src/libopus/silk/LPC_analysis_filter.c +++ b/src/libopus/silk/LPC_analysis_filter.c @@ -25,12 +25,12 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "SigProc_FIX.h" -#include "../celt/celt_lpc.h" +#include "celt_lpc.h" /*******************************************/ /* LPC analysis filter */ diff --git a/src/libopus/silk/LPC_fit.c b/src/libopus/silk/LPC_fit.c index edc930ca..c63dbc41 100644 --- a/src/libopus/silk/LPC_fit.c +++ b/src/libopus/silk/LPC_fit.c @@ -25,13 +25,14 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "SigProc_FIX.h" -/* Convert int32 coefficients to int16 coefs and make sure there's no wrap-around */ +/* Convert int32 coefficients to int16 coefs and make sure there's no wrap-around. + This logic is reused in _celt_lpc(). Any bug fixes should also be applied there. */ void silk_LPC_fit( opus_int16 *a_QOUT, /* O Output signal */ opus_int32 *a_QIN, /* I/O Input signal */ diff --git a/src/libopus/silk/LPC_inv_pred_gain.c b/src/libopus/silk/LPC_inv_pred_gain.c index a9389a08..4cc91b2d 100644 --- a/src/libopus/silk/LPC_inv_pred_gain.c +++ b/src/libopus/silk/LPC_inv_pred_gain.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "SigProc_FIX.h" #include "define.h" diff --git a/src/libopus/silk/LP_variable_cutoff.c b/src/libopus/silk/LP_variable_cutoff.c index 49ad4157..1f393245 100644 --- a/src/libopus/silk/LP_variable_cutoff.c +++ b/src/libopus/silk/LP_variable_cutoff.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif /* Elliptic/Cauer filters designed with 0.1 dB passband ripple, diff --git a/src/libopus/silk/MacroCount.h b/src/libopus/silk/MacroCount.h index 78100ffe..dab2f57a 100644 --- a/src/libopus/silk/MacroCount.h +++ b/src/libopus/silk/MacroCount.h @@ -27,9 +27,9 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef SIGPROCFIX_API_MACROCOUNT_H #define SIGPROCFIX_API_MACROCOUNT_H -#include #ifdef silk_MACRO_COUNT +#include #define varDefine opus_int64 ops_count = 0; extern opus_int64 ops_count; diff --git a/src/libopus/silk/MacroDebug.h b/src/libopus/silk/MacroDebug.h index 8dd4ce2e..3110da9a 100644 --- a/src/libopus/silk/MacroDebug.h +++ b/src/libopus/silk/MacroDebug.h @@ -55,7 +55,7 @@ static OPUS_INLINE opus_int16 silk_ADD16_(opus_int16 a, opus_int16 b, char *file static OPUS_INLINE opus_int32 silk_ADD32_(opus_int32 a, opus_int32 b, char *file, int line){ opus_int32 ret; - ret = a + b; + ret = (opus_int32)((opus_uint32)a + (opus_uint32)b); if ( ret != silk_ADD_SAT32( a, b ) ) { fprintf (stderr, "silk_ADD32(%d, %d) in %s: line %d\n", a, b, file, line); @@ -101,9 +101,9 @@ static OPUS_INLINE opus_int16 silk_SUB16_(opus_int16 a, opus_int16 b, char *file #undef silk_SUB32 #define silk_SUB32(a,b) silk_SUB32_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SUB32_(opus_int32 a, opus_int32 b, char *file, int line){ - opus_int32 ret; + opus_int64 ret; - ret = a - b; + ret = a - (opus_int64)b; if ( ret != silk_SUB_SAT32( a, b ) ) { fprintf (stderr, "silk_SUB32(%d, %d) in %s: line %d\n", a, b, file, line); @@ -257,7 +257,7 @@ static OPUS_INLINE opus_int64 silk_SUB_SAT64_( opus_int64 a64, opus_int64 b64, c static OPUS_INLINE opus_int32 silk_MUL_(opus_int32 a32, opus_int32 b32, char *file, int line){ opus_int32 ret; opus_int64 ret64; - ret = a32 * b32; + ret = (opus_int32)((opus_uint32)a32 * (opus_uint32)b32); ret64 = (opus_int64)a32 * (opus_int64)b32; if ( (opus_int64)ret != ret64 ) { @@ -333,8 +333,8 @@ static OPUS_INLINE opus_int32 silk_SMULWB_(opus_int32 a32, opus_int32 b32, char #define silk_SMLAWB(a,b,c) silk_SMLAWB_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SMLAWB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ opus_int32 ret; - ret = silk_ADD32( a32, silk_SMULWB( b32, c32 ) ); - if ( silk_ADD32( a32, silk_SMULWB( b32, c32 ) ) != silk_ADD_SAT32( a32, silk_SMULWB( b32, c32 ) ) ) + ret = silk_ADD32_ovflw( a32, silk_SMULWB( b32, c32 ) ); + if ( ret != silk_ADD_SAT32( a32, silk_SMULWB( b32, c32 ) ) ) { fprintf (stderr, "silk_SMLAWB(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); #ifdef FIXED_DEBUG_ASSERT @@ -465,7 +465,7 @@ static OPUS_INLINE opus_int32 silk_SMULWW_(opus_int32 a32, opus_int32 b32, char if ( fail ) { - fprintf (stderr, "silk_SMULWT(%d, %d) in %s: line %d\n", a32, b32, file, line); + fprintf (stderr, "silk_SMULWW(%d, %d) in %s: line %d\n", a32, b32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif @@ -491,12 +491,6 @@ static OPUS_INLINE opus_int32 silk_SMLAWW_(opus_int32 a32, opus_int32 b32, opus_ return ret; } -/* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */ -#undef silk_MLA_ovflw -#define silk_MLA_ovflw(a32, b32, c32) ((a32) + ((b32) * (c32))) -#undef silk_SMLABB_ovflw -#define silk_SMLABB_ovflw(a32, b32, c32) ((a32) + ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32))) - /* no checking needed for silk_SMULL no checking needed for silk_SMLAL no checking needed for silk_SMLALBB @@ -546,10 +540,10 @@ static OPUS_INLINE opus_int32 silk_DIV32_16_(opus_int32 a32, opus_int32 b32, cha static OPUS_INLINE opus_int8 silk_LSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){ opus_int8 ret; int fail = 0; - ret = a << shift; + ret = (opus_int8)((opus_uint8)a << shift); fail |= shift < 0; fail |= shift >= 8; - fail |= (opus_int64)ret != ((opus_int64)a) << shift; + fail |= (opus_int64)ret != (opus_int64)(((opus_uint64)a) << shift); if ( fail ) { fprintf (stderr, "silk_LSHIFT8(%d, %d) in %s: line %d\n", a, shift, file, line); @@ -565,10 +559,10 @@ static OPUS_INLINE opus_int8 silk_LSHIFT8_(opus_int8 a, opus_int32 shift, char * static OPUS_INLINE opus_int16 silk_LSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){ opus_int16 ret; int fail = 0; - ret = a << shift; + ret = (opus_int16)((opus_uint16)a << shift); fail |= shift < 0; fail |= shift >= 16; - fail |= (opus_int64)ret != ((opus_int64)a) << shift; + fail |= (opus_int64)ret != (opus_int64)(((opus_uint64)a) << shift); if ( fail ) { fprintf (stderr, "silk_LSHIFT16(%d, %d) in %s: line %d\n", a, shift, file, line); @@ -584,10 +578,10 @@ static OPUS_INLINE opus_int16 silk_LSHIFT16_(opus_int16 a, opus_int32 shift, cha static OPUS_INLINE opus_int32 silk_LSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){ opus_int32 ret; int fail = 0; - ret = a << shift; + ret = (opus_int32)((opus_uint32)a << shift); fail |= shift < 0; fail |= shift >= 32; - fail |= (opus_int64)ret != ((opus_int64)a) << shift; + fail |= (opus_int64)ret != (opus_int64)(((opus_uint64)a) << shift); if ( fail ) { fprintf (stderr, "silk_LSHIFT32(%d, %d) in %s: line %d\n", a, shift, file, line); @@ -603,7 +597,7 @@ static OPUS_INLINE opus_int32 silk_LSHIFT32_(opus_int32 a, opus_int32 shift, cha static OPUS_INLINE opus_int64 silk_LSHIFT64_(opus_int64 a, opus_int shift, char *file, int line){ opus_int64 ret; int fail = 0; - ret = a << shift; + ret = (opus_int64)((opus_uint64)a << shift); fail |= shift < 0; fail |= shift >= 64; fail |= (ret>>shift) != ((opus_int64)a); @@ -714,8 +708,8 @@ static OPUS_INLINE opus_uint32 silk_RSHIFT_uint_(opus_uint32 a, opus_int32 shift #define silk_ADD_LSHIFT(a,b,c) silk_ADD_LSHIFT_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE int silk_ADD_LSHIFT_(int a, int b, int shift, char *file, int line){ opus_int16 ret; - ret = a + (b << shift); - if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) ) + ret = a + (opus_int16)((opus_uint16)b << shift); + if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (opus_int64)(((opus_uint64)b) << shift)) ) { fprintf (stderr, "silk_ADD_LSHIFT(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); #ifdef FIXED_DEBUG_ASSERT @@ -729,8 +723,8 @@ static OPUS_INLINE int silk_ADD_LSHIFT_(int a, int b, int shift, char *file, int #define silk_ADD_LSHIFT32(a,b,c) silk_ADD_LSHIFT32_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_ADD_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ opus_int32 ret; - ret = a + (b << shift); - if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) ) + ret = silk_ADD32_ovflw(a, (opus_int32)((opus_uint32)b << shift)); + if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (opus_int64)(((opus_uint64)b) << shift)) ) { fprintf (stderr, "silk_ADD_LSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); #ifdef FIXED_DEBUG_ASSERT @@ -774,7 +768,7 @@ static OPUS_INLINE int silk_ADD_RSHIFT_(int a, int b, int shift, char *file, int #define silk_ADD_RSHIFT32(a,b,c) silk_ADD_RSHIFT32_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_ADD_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ opus_int32 ret; - ret = a + (b >> shift); + ret = silk_ADD32_ovflw(a, (b >> shift)); if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) ) { fprintf (stderr, "silk_ADD_RSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); @@ -804,8 +798,8 @@ static OPUS_INLINE opus_uint32 silk_ADD_RSHIFT_uint_(opus_uint32 a, opus_uint32 #define silk_SUB_LSHIFT32(a,b,c) silk_SUB_LSHIFT32_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SUB_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ opus_int32 ret; - ret = a - (b << shift); - if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) << shift)) ) + ret = silk_SUB32_ovflw(a, (opus_int32)((opus_uint32)b << shift)); + if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (opus_int64)(((opus_uint64)b) << shift)) ) { fprintf (stderr, "silk_SUB_LSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); #ifdef FIXED_DEBUG_ASSERT @@ -819,7 +813,7 @@ static OPUS_INLINE opus_int32 silk_SUB_LSHIFT32_(opus_int32 a, opus_int32 b, opu #define silk_SUB_RSHIFT32(a,b,c) silk_SUB_RSHIFT32_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SUB_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ opus_int32 ret; - ret = a - (b >> shift); + ret = silk_SUB32_ovflw(a, (b >> shift)); if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) >> shift)) ) { fprintf (stderr, "silk_SUB_RSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); @@ -835,7 +829,7 @@ static OPUS_INLINE opus_int32 silk_SUB_RSHIFT32_(opus_int32 a, opus_int32 b, opu static OPUS_INLINE opus_int32 silk_RSHIFT_ROUND_(opus_int32 a, opus_int32 shift, char *file, int line){ opus_int32 ret; ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; - /* the marco definition can't handle a shift of zero */ + /* the macro definition can't handle a shift of zero */ if ( (shift <= 0) || (shift>31) || ((opus_int64)ret != ((opus_int64)a + ((opus_int64)1 << (shift - 1))) >> shift) ) { fprintf (stderr, "silk_RSHIFT_ROUND(%d, %d) in %s: line %d\n", a, shift, file, line); @@ -850,7 +844,7 @@ static OPUS_INLINE opus_int32 silk_RSHIFT_ROUND_(opus_int32 a, opus_int32 shift, #define silk_RSHIFT_ROUND64(a,b) silk_RSHIFT_ROUND64_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int64 silk_RSHIFT_ROUND64_(opus_int64 a, opus_int32 shift, char *file, int line){ opus_int64 ret; - /* the marco definition can't handle a shift of zero */ + /* the macro definition can't handle a shift of zero */ if ( (shift <= 0) || (shift>=64) ) { fprintf (stderr, "silk_RSHIFT_ROUND64(%lld, %d) in %s: line %d\n", (long long)a, shift, file, line); diff --git a/src/libopus/silk/NLSF2A.c b/src/libopus/silk/NLSF2A.c index 40718e7a..a2c15b9a 100644 --- a/src/libopus/silk/NLSF2A.c +++ b/src/libopus/silk/NLSF2A.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif /* conversion between prediction filter coefficients and LSFs */ /* order should be even */ diff --git a/src/libopus/silk/NLSF_VQ.c b/src/libopus/silk/NLSF_VQ.c index 372a0131..81f30e7f 100644 --- a/src/libopus/silk/NLSF_VQ.c +++ b/src/libopus/silk/NLSF_VQ.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/NLSF_VQ_weights_laroia.c b/src/libopus/silk/NLSF_VQ_weights_laroia.c index 387e62da..86cdc5c6 100644 --- a/src/libopus/silk/NLSF_VQ_weights_laroia.c +++ b/src/libopus/silk/NLSF_VQ_weights_laroia.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "define.h" #include "SigProc_FIX.h" diff --git a/src/libopus/silk/NLSF_decode.c b/src/libopus/silk/NLSF_decode.c index 87a57e13..f4d10fca 100644 --- a/src/libopus/silk/NLSF_decode.c +++ b/src/libopus/silk/NLSF_decode.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/NLSF_del_dec_quant.c b/src/libopus/silk/NLSF_del_dec_quant.c index 32f747d6..728aa814 100644 --- a/src/libopus/silk/NLSF_del_dec_quant.c +++ b/src/libopus/silk/NLSF_del_dec_quant.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/NLSF_encode.c b/src/libopus/silk/NLSF_encode.c index 8aabe752..01aadd01 100644 --- a/src/libopus/silk/NLSF_encode.c +++ b/src/libopus/silk/NLSF_encode.c @@ -25,12 +25,12 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" -#include "../celt/stack_alloc.h" +#include "stack_alloc.h" /***********************/ /* NLSF vector encoder */ diff --git a/src/libopus/silk/NLSF_stabilize.c b/src/libopus/silk/NLSF_stabilize.c index b7530db1..ab389ccd 100644 --- a/src/libopus/silk/NLSF_stabilize.c +++ b/src/libopus/silk/NLSF_stabilize.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif /* NLSF stabilizer: */ /* */ diff --git a/src/libopus/silk/NLSF_unpack.c b/src/libopus/silk/NLSF_unpack.c index bf3b047a..ed0d9c38 100644 --- a/src/libopus/silk/NLSF_unpack.c +++ b/src/libopus/silk/NLSF_unpack.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/NSQ.c b/src/libopus/silk/NSQ.c deleted file mode 100644 index a5f085df..00000000 --- a/src/libopus/silk/NSQ.c +++ /dev/null @@ -1,437 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif - -#include "main.h" -#include "../celt/stack_alloc.h" -#include "NSQ.h" - - -static OPUS_INLINE void silk_nsq_scale_states( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - const opus_int16 x16[], /* I input */ - opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ - const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ - opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ - opus_int subfr, /* I subframe number */ - const opus_int LTP_scale_Q14, /* I */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ - const opus_int signal_type /* I Signal type */ -); - -#if !defined(OPUS_X86_MAY_HAVE_SSE4_1) -static OPUS_INLINE void silk_noise_shape_quantizer( - silk_nsq_state *NSQ, /* I/O NSQ state */ - opus_int signalType, /* I Signal type */ - const opus_int32 x_sc_Q10[], /* I */ - opus_int8 pulses[], /* O */ - opus_int16 xq[], /* O */ - opus_int32 sLTP_Q15[], /* I/O LTP state */ - const opus_int16 a_Q12[], /* I Short term prediction coefs */ - const opus_int16 b_Q14[], /* I Long term prediction coefs */ - const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ - opus_int lag, /* I Pitch lag */ - opus_int32 HarmShapeFIRPacked_Q14, /* I */ - opus_int Tilt_Q14, /* I Spectral tilt */ - opus_int32 LF_shp_Q14, /* I */ - opus_int32 Gain_Q16, /* I */ - opus_int Lambda_Q10, /* I */ - opus_int offset_Q10, /* I */ - opus_int length, /* I Input length */ - opus_int shapingLPCOrder, /* I Noise shaping AR filter order */ - opus_int predictLPCOrder, /* I Prediction filter order */ - int arch /* I Architecture */ -); -#endif - -void silk_NSQ_c -( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int16 x16[], /* I Input */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ -) -{ - opus_int k, lag, start_idx, LSF_interpolation_flag; - const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; - opus_int16 *pxq; - VARDECL( opus_int32, sLTP_Q15 ); - VARDECL( opus_int16, sLTP ); - opus_int32 HarmShapeFIRPacked_Q14; - opus_int offset_Q10; - VARDECL( opus_int32, x_sc_Q10 ); - SAVE_STACK; - - NSQ->rand_seed = psIndices->Seed; - - /* Set unvoiced lag to the previous one, overwrite later for voiced */ - lag = NSQ->lagPrev; - - silk_assert( NSQ->prev_gain_Q16 != 0 ); - - offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; - - if( psIndices->NLSFInterpCoef_Q2 == 4 ) { - LSF_interpolation_flag = 0; - } else { - LSF_interpolation_flag = 1; - } - - ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); - ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); - ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); - /* Set up pointers to start of sub frame */ - NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; - NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; - pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; - for( k = 0; k < psEncC->nb_subfr; k++ ) { - A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ]; - B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; - AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ]; - - /* Noise shape parameters */ - silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); - HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); - HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); - - NSQ->rewhite_flag = 0; - if( psIndices->signalType == TYPE_VOICED ) { - /* Voiced */ - lag = pitchL[ k ]; - - /* Re-whitening */ - if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { - /* Rewhiten with new A coefs */ - start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; - celt_assert( start_idx > 0 ); - - silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], - A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch ); - - NSQ->rewhite_flag = 1; - NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; - } - } - - silk_nsq_scale_states( psEncC, NSQ, x16, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType ); - - silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14, - AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, - offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->arch ); - - x16 += psEncC->subfr_length; - pulses += psEncC->subfr_length; - pxq += psEncC->subfr_length; - } - - /* Update lagPrev for next frame */ - NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; - - /* Save quantized speech and noise shaping signals */ - silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); - silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); - RESTORE_STACK; -} - -/***********************************/ -/* silk_noise_shape_quantizer */ -/***********************************/ - -#if !defined(OPUS_X86_MAY_HAVE_SSE4_1) -static OPUS_INLINE -#endif -void silk_noise_shape_quantizer( - silk_nsq_state *NSQ, /* I/O NSQ state */ - opus_int signalType, /* I Signal type */ - const opus_int32 x_sc_Q10[], /* I */ - opus_int8 pulses[], /* O */ - opus_int16 xq[], /* O */ - opus_int32 sLTP_Q15[], /* I/O LTP state */ - const opus_int16 a_Q12[], /* I Short term prediction coefs */ - const opus_int16 b_Q14[], /* I Long term prediction coefs */ - const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ - opus_int lag, /* I Pitch lag */ - opus_int32 HarmShapeFIRPacked_Q14, /* I */ - opus_int Tilt_Q14, /* I Spectral tilt */ - opus_int32 LF_shp_Q14, /* I */ - opus_int32 Gain_Q16, /* I */ - opus_int Lambda_Q10, /* I */ - opus_int offset_Q10, /* I */ - opus_int length, /* I Input length */ - opus_int shapingLPCOrder, /* I Noise shaping AR filter order */ - opus_int predictLPCOrder, /* I Prediction filter order */ - int arch /* I Architecture */ -) -{ - opus_int i; - opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13; - opus_int32 n_LF_Q12, r_Q10, rr_Q10, q1_Q0, q1_Q10, q2_Q10, rd1_Q20, rd2_Q20; - opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; - opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; - opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr; -#ifdef silk_short_prediction_create_arch_coef - opus_int32 a_Q12_arch[MAX_LPC_ORDER]; -#endif - - shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; - pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; - Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); - - /* Set up short term AR state */ - psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ]; - -#ifdef silk_short_prediction_create_arch_coef - silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder); -#endif - - for( i = 0; i < length; i++ ) { - /* Generate dither */ - NSQ->rand_seed = silk_RAND( NSQ->rand_seed ); - - /* Short-term prediction */ - LPC_pred_Q10 = silk_noise_shape_quantizer_short_prediction(psLPC_Q14, a_Q12, a_Q12_arch, predictLPCOrder, arch); - - /* Long-term prediction */ - if( signalType == TYPE_VOICED ) { - /* Unrolled loop */ - /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ - LTP_pred_Q13 = 2; - LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ 0 ], b_Q14[ 0 ] ); - LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], b_Q14[ 1 ] ); - LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], b_Q14[ 2 ] ); - LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], b_Q14[ 3 ] ); - LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); - pred_lag_ptr++; - } else { - LTP_pred_Q13 = 0; - } - - /* Noise shape feedback */ - celt_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ - n_AR_Q12 = silk_NSQ_noise_shape_feedback_loop(&NSQ->sDiff_shp_Q14, NSQ->sAR2_Q14, AR_shp_Q13, shapingLPCOrder, arch); - - n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sLF_AR_shp_Q14, Tilt_Q14 ); - - n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 ); - n_LF_Q12 = silk_SMLAWT( n_LF_Q12, NSQ->sLF_AR_shp_Q14, LF_shp_Q14 ); - - celt_assert( lag > 0 || signalType != TYPE_VOICED ); - - /* Combine prediction and noise shaping signals */ - tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 ); /* Q12 */ - tmp1 = silk_SUB32( tmp1, n_LF_Q12 ); /* Q12 */ - if( lag > 0 ) { - /* Symmetric, packed FIR coefficients */ - n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); - n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); - n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 ); - shp_lag_ptr++; - - tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 ); /* Q13 */ - tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 ); /* Q13 */ - tmp1 = silk_RSHIFT_ROUND( tmp1, 3 ); /* Q10 */ - } else { - tmp1 = silk_RSHIFT_ROUND( tmp1, 2 ); /* Q10 */ - } - - r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 ); /* residual error Q10 */ - - /* Flip sign depending on dither */ - if( NSQ->rand_seed < 0 ) { - r_Q10 = -r_Q10; - } - r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); - - /* Find two quantization level candidates and measure their rate-distortion */ - q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); - q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); - if (Lambda_Q10 > 2048) { - /* For aggressive RDO, the bias becomes more than one pulse. */ - int rdo_offset = Lambda_Q10/2 - 512; - if (q1_Q10 > rdo_offset) { - q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 ); - } else if (q1_Q10 < -rdo_offset) { - q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 ); - } else if (q1_Q10 < 0) { - q1_Q0 = -1; - } else { - q1_Q0 = 0; - } - } - if( q1_Q0 > 0 ) { - q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); - q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); - q2_Q10 = silk_ADD32( q1_Q10, 1024 ); - rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 ); - rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); - } else if( q1_Q0 == 0 ) { - q1_Q10 = offset_Q10; - q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); - rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 ); - rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); - } else if( q1_Q0 == -1 ) { - q2_Q10 = offset_Q10; - q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); - rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); - rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); - } else { /* Q1_Q0 < -1 */ - q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); - q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); - q2_Q10 = silk_ADD32( q1_Q10, 1024 ); - rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); - rd2_Q20 = silk_SMULBB( -q2_Q10, Lambda_Q10 ); - } - rr_Q10 = silk_SUB32( r_Q10, q1_Q10 ); - rd1_Q20 = silk_SMLABB( rd1_Q20, rr_Q10, rr_Q10 ); - rr_Q10 = silk_SUB32( r_Q10, q2_Q10 ); - rd2_Q20 = silk_SMLABB( rd2_Q20, rr_Q10, rr_Q10 ); - - if( rd2_Q20 < rd1_Q20 ) { - q1_Q10 = q2_Q10; - } - - pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 ); - - /* Excitation */ - exc_Q14 = silk_LSHIFT( q1_Q10, 4 ); - if ( NSQ->rand_seed < 0 ) { - exc_Q14 = -exc_Q14; - } - - /* Add predictions */ - LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 ); - xq_Q14 = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 ); - - /* Scale XQ back to normal level before saving */ - xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( xq_Q14, Gain_Q10 ), 8 ) ); - - /* Update states */ - psLPC_Q14++; - *psLPC_Q14 = xq_Q14; - NSQ->sDiff_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_sc_Q10[ i ], 4 ); - sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( NSQ->sDiff_shp_Q14, n_AR_Q12, 2 ); - NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14; - - NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 ); - sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 ); - NSQ->sLTP_shp_buf_idx++; - NSQ->sLTP_buf_idx++; - - /* Make dither dependent on quantized signal */ - NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] ); - } - - /* Update LPC synth buffer */ - silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); -} - -static OPUS_INLINE void silk_nsq_scale_states( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - const opus_int16 x16[], /* I input */ - opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ - const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ - opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ - opus_int subfr, /* I subframe number */ - const opus_int LTP_scale_Q14, /* I */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ - const opus_int signal_type /* I Signal type */ -) -{ - opus_int i, lag; - opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26; - - lag = pitchL[ subfr ]; - inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); - silk_assert( inv_gain_Q31 != 0 ); - - /* Scale input */ - inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 ); - for( i = 0; i < psEncC->subfr_length; i++ ) { - x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 ); - } - - /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ - if( NSQ->rewhite_flag ) { - if( subfr == 0 ) { - /* Do LTP downscaling */ - inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); - } - for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { - silk_assert( i < MAX_FRAME_LENGTH ); - sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] ); - } - } - - /* Adjust for changing gain */ - if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { - gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); - - /* Scale long-term shaping state */ - for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) { - NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); - } - - /* Scale long-term prediction state */ - if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { - for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { - sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); - } - } - - NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 ); - NSQ->sDiff_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sDiff_shp_Q14 ); - - /* Scale short-term prediction and shaping states */ - for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { - NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] ); - } - for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { - NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] ); - } - - /* Save inverse gain */ - NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; - } -} diff --git a/src/libopus/silk/NSQ_del_dec.c b/src/libopus/silk/NSQ_del_dec.c deleted file mode 100644 index 5af56793..00000000 --- a/src/libopus/silk/NSQ_del_dec.c +++ /dev/null @@ -1,733 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif - -#include "main.h" -#include "../celt/stack_alloc.h" -#include "NSQ.h" - - -typedef struct { - opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ]; - opus_int32 RandState[ DECISION_DELAY ]; - opus_int32 Q_Q10[ DECISION_DELAY ]; - opus_int32 Xq_Q14[ DECISION_DELAY ]; - opus_int32 Pred_Q15[ DECISION_DELAY ]; - opus_int32 Shape_Q14[ DECISION_DELAY ]; - opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; - opus_int32 LF_AR_Q14; - opus_int32 Diff_Q14; - opus_int32 Seed; - opus_int32 SeedInit; - opus_int32 RD_Q10; -} NSQ_del_dec_struct; - -typedef struct { - opus_int32 Q_Q10; - opus_int32 RD_Q10; - opus_int32 xq_Q14; - opus_int32 LF_AR_Q14; - opus_int32 Diff_Q14; - opus_int32 sLTP_shp_Q14; - opus_int32 LPC_exc_Q14; -} NSQ_sample_struct; - -typedef NSQ_sample_struct NSQ_sample_pair[ 2 ]; - -#if defined(MIPSr1_ASM) -#include "mips/NSQ_del_dec_mipsr1.h" -#endif -static OPUS_INLINE void silk_nsq_del_dec_scale_states( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ - const opus_int16 x16[], /* I Input */ - opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ - const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ - opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ - opus_int subfr, /* I Subframe number */ - opus_int nStatesDelayedDecision, /* I Number of del dec states */ - const opus_int LTP_scale_Q14, /* I LTP state scaling */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ - const opus_int signal_type, /* I Signal type */ - const opus_int decisionDelay /* I Decision delay */ -); - -/******************************************/ -/* Noise shape quantizer for one subframe */ -/******************************************/ -static OPUS_INLINE void silk_noise_shape_quantizer_del_dec( - silk_nsq_state *NSQ, /* I/O NSQ state */ - NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ - opus_int signalType, /* I Signal type */ - const opus_int32 x_Q10[], /* I */ - opus_int8 pulses[], /* O */ - opus_int16 xq[], /* O */ - opus_int32 sLTP_Q15[], /* I/O LTP filter state */ - opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ - const opus_int16 a_Q12[], /* I Short term prediction coefs */ - const opus_int16 b_Q14[], /* I Long term prediction coefs */ - const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ - opus_int lag, /* I Pitch lag */ - opus_int32 HarmShapeFIRPacked_Q14, /* I */ - opus_int Tilt_Q14, /* I Spectral tilt */ - opus_int32 LF_shp_Q14, /* I */ - opus_int32 Gain_Q16, /* I */ - opus_int Lambda_Q10, /* I */ - opus_int offset_Q10, /* I */ - opus_int length, /* I Input length */ - opus_int subfr, /* I Subframe number */ - opus_int shapingLPCOrder, /* I Shaping LPC filter order */ - opus_int predictLPCOrder, /* I Prediction filter order */ - opus_int warping_Q16, /* I */ - opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ - opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */ - opus_int decisionDelay, /* I */ - int arch /* I */ -); - -void silk_NSQ_del_dec_c( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int16 x16[], /* I Input */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ -) -{ - opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr; - opus_int last_smple_idx, smpl_buf_idx, decisionDelay; - const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; - opus_int16 *pxq; - VARDECL( opus_int32, sLTP_Q15 ); - VARDECL( opus_int16, sLTP ); - opus_int32 HarmShapeFIRPacked_Q14; - opus_int offset_Q10; - opus_int32 RDmin_Q10, Gain_Q10; - VARDECL( opus_int32, x_sc_Q10 ); - VARDECL( opus_int32, delayedGain_Q10 ); - VARDECL( NSQ_del_dec_struct, psDelDec ); - NSQ_del_dec_struct *psDD; - SAVE_STACK; - - /* Set unvoiced lag to the previous one, overwrite later for voiced */ - lag = NSQ->lagPrev; - - silk_assert( NSQ->prev_gain_Q16 != 0 ); - - /* Initialize delayed decision states */ - ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct ); - silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) ); - for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) { - psDD = &psDelDec[ k ]; - psDD->Seed = ( k + psIndices->Seed ) & 3; - psDD->SeedInit = psDD->Seed; - psDD->RD_Q10 = 0; - psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14; - psDD->Diff_Q14 = NSQ->sDiff_shp_Q14; - psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ]; - silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); - silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) ); - } - - offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; - smpl_buf_idx = 0; /* index of oldest samples */ - - decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length ); - - /* For voiced frames limit the decision delay to lower than the pitch lag */ - if( psIndices->signalType == TYPE_VOICED ) { - for( k = 0; k < psEncC->nb_subfr; k++ ) { - decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 ); - } - } else { - if( lag > 0 ) { - decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 ); - } - } - - if( psIndices->NLSFInterpCoef_Q2 == 4 ) { - LSF_interpolation_flag = 0; - } else { - LSF_interpolation_flag = 1; - } - - ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); - ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); - ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); - ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 ); - /* Set up pointers to start of sub frame */ - pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; - NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; - NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; - subfr = 0; - for( k = 0; k < psEncC->nb_subfr; k++ ) { - A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ]; - B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; - AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ]; - - /* Noise shape parameters */ - silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); - HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); - HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); - - NSQ->rewhite_flag = 0; - if( psIndices->signalType == TYPE_VOICED ) { - /* Voiced */ - lag = pitchL[ k ]; - - /* Re-whitening */ - if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { - if( k == 2 ) { - /* RESET DELAYED DECISIONS */ - /* Find winner */ - RDmin_Q10 = psDelDec[ 0 ].RD_Q10; - Winner_ind = 0; - for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) { - if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) { - RDmin_Q10 = psDelDec[ i ].RD_Q10; - Winner_ind = i; - } - } - for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) { - if( i != Winner_ind ) { - psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 ); - silk_assert( psDelDec[ i ].RD_Q10 >= 0 ); - } - } - - /* Copy final part of signals from winner state to output and long-term filter states */ - psDD = &psDelDec[ Winner_ind ]; - last_smple_idx = smpl_buf_idx + decisionDelay; - for( i = 0; i < decisionDelay; i++ ) { - last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY; - if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY; - pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); - pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( - silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) ); - NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ]; - } - - subfr = 0; - } - - /* Rewhiten with new A coefs */ - start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; - celt_assert( start_idx > 0 ); - - silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], - A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch ); - - NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; - NSQ->rewhite_flag = 1; - } - } - - silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x16, x_sc_Q10, sLTP, sLTP_Q15, k, - psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay ); - - silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, - delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], - Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder, - psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay, psEncC->arch ); - - x16 += psEncC->subfr_length; - pulses += psEncC->subfr_length; - pxq += psEncC->subfr_length; - } - - /* Find winner */ - RDmin_Q10 = psDelDec[ 0 ].RD_Q10; - Winner_ind = 0; - for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) { - if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) { - RDmin_Q10 = psDelDec[ k ].RD_Q10; - Winner_ind = k; - } - } - - /* Copy final part of signals from winner state to output and long-term filter states */ - psDD = &psDelDec[ Winner_ind ]; - psIndices->Seed = psDD->SeedInit; - last_smple_idx = smpl_buf_idx + decisionDelay; - Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 ); - for( i = 0; i < decisionDelay; i++ ) { - last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY; - if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY; - - pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); - pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( - silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) ); - NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ]; - } - silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); - silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) ); - - /* Update states */ - NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14; - NSQ->sDiff_shp_Q14 = psDD->Diff_Q14; - NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; - - /* Save quantized speech signal */ - silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); - silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); - RESTORE_STACK; -} - -/******************************************/ -/* Noise shape quantizer for one subframe */ -/******************************************/ -#ifndef OVERRIDE_silk_noise_shape_quantizer_del_dec -static OPUS_INLINE void silk_noise_shape_quantizer_del_dec( - silk_nsq_state *NSQ, /* I/O NSQ state */ - NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ - opus_int signalType, /* I Signal type */ - const opus_int32 x_Q10[], /* I */ - opus_int8 pulses[], /* O */ - opus_int16 xq[], /* O */ - opus_int32 sLTP_Q15[], /* I/O LTP filter state */ - opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ - const opus_int16 a_Q12[], /* I Short term prediction coefs */ - const opus_int16 b_Q14[], /* I Long term prediction coefs */ - const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ - opus_int lag, /* I Pitch lag */ - opus_int32 HarmShapeFIRPacked_Q14, /* I */ - opus_int Tilt_Q14, /* I Spectral tilt */ - opus_int32 LF_shp_Q14, /* I */ - opus_int32 Gain_Q16, /* I */ - opus_int Lambda_Q10, /* I */ - opus_int offset_Q10, /* I */ - opus_int length, /* I Input length */ - opus_int subfr, /* I Subframe number */ - opus_int shapingLPCOrder, /* I Shaping LPC filter order */ - opus_int predictLPCOrder, /* I Prediction filter order */ - opus_int warping_Q16, /* I */ - opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ - opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */ - opus_int decisionDelay, /* I */ - int arch /* I */ -) -{ - opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx; - opus_int32 Winner_rand_state; - opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14; - opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10; - opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; - opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; - opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14; -#ifdef silk_short_prediction_create_arch_coef - opus_int32 a_Q12_arch[MAX_LPC_ORDER]; -#endif - - VARDECL( NSQ_sample_pair, psSampleState ); - NSQ_del_dec_struct *psDD; - NSQ_sample_struct *psSS; - SAVE_STACK; - - celt_assert( nStatesDelayedDecision > 0 ); - ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair ); - - shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; - pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; - Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); - -#ifdef silk_short_prediction_create_arch_coef - silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder); -#endif - - for( i = 0; i < length; i++ ) { - /* Perform common calculations used in all states */ - - /* Long-term prediction */ - if( signalType == TYPE_VOICED ) { - /* Unrolled loop */ - /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ - LTP_pred_Q14 = 2; - LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ 0 ], b_Q14[ 0 ] ); - LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] ); - LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] ); - LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] ); - LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); - LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */ - pred_lag_ptr++; - } else { - LTP_pred_Q14 = 0; - } - - /* Long-term shaping */ - if( lag > 0 ) { - /* Symmetric, packed FIR coefficients */ - n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); - n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); - n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */ - shp_lag_ptr++; - } else { - n_LTP_Q14 = 0; - } - - for( k = 0; k < nStatesDelayedDecision; k++ ) { - /* Delayed decision state */ - psDD = &psDelDec[ k ]; - - /* Sample state */ - psSS = psSampleState[ k ]; - - /* Generate dither */ - psDD->Seed = silk_RAND( psDD->Seed ); - - /* Pointer used in short term prediction and shaping */ - psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ]; - /* Short-term prediction */ - LPC_pred_Q14 = silk_noise_shape_quantizer_short_prediction(psLPC_Q14, a_Q12, a_Q12_arch, predictLPCOrder, arch); - LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */ - - /* Noise shape feedback */ - celt_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ - /* Output of lowpass section */ - tmp2 = silk_SMLAWB( psDD->Diff_Q14, psDD->sAR2_Q14[ 0 ], warping_Q16 ); - /* Output of allpass section */ - tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 ); - psDD->sAR2_Q14[ 0 ] = tmp2; - n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 ); - n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] ); - /* Loop over allpass sections */ - for( j = 2; j < shapingLPCOrder; j += 2 ) { - /* Output of allpass section */ - tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 ); - psDD->sAR2_Q14[ j - 1 ] = tmp1; - n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] ); - /* Output of allpass section */ - tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 ); - psDD->sAR2_Q14[ j + 0 ] = tmp2; - n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] ); - } - psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1; - n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] ); - - n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */ - n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */ - n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */ - - n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */ - n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */ - n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */ - - /* Input minus prediction plus noise feedback */ - /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */ - tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */ - tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */ - tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */ - tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */ - - r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */ - - /* Flip sign depending on dither */ - if ( psDD->Seed < 0 ) { - r_Q10 = -r_Q10; - } - r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); - - /* Find two quantization level candidates and measure their rate-distortion */ - q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); - q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); - if (Lambda_Q10 > 2048) { - /* For aggressive RDO, the bias becomes more than one pulse. */ - int rdo_offset = Lambda_Q10/2 - 512; - if (q1_Q10 > rdo_offset) { - q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 ); - } else if (q1_Q10 < -rdo_offset) { - q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 ); - } else if (q1_Q10 < 0) { - q1_Q0 = -1; - } else { - q1_Q0 = 0; - } - } - if( q1_Q0 > 0 ) { - q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); - q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); - q2_Q10 = silk_ADD32( q1_Q10, 1024 ); - rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); - rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); - } else if( q1_Q0 == 0 ) { - q1_Q10 = offset_Q10; - q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); - rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); - rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); - } else if( q1_Q0 == -1 ) { - q2_Q10 = offset_Q10; - q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); - rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); - rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); - } else { /* q1_Q0 < -1 */ - q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); - q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); - q2_Q10 = silk_ADD32( q1_Q10, 1024 ); - rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); - rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 ); - } - rr_Q10 = silk_SUB32( r_Q10, q1_Q10 ); - rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 ); - rr_Q10 = silk_SUB32( r_Q10, q2_Q10 ); - rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 ); - - if( rd1_Q10 < rd2_Q10 ) { - psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); - psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); - psSS[ 0 ].Q_Q10 = q1_Q10; - psSS[ 1 ].Q_Q10 = q2_Q10; - } else { - psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); - psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); - psSS[ 0 ].Q_Q10 = q2_Q10; - psSS[ 1 ].Q_Q10 = q1_Q10; - } - - /* Update states for best quantization */ - - /* Quantized excitation */ - exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 ); - if ( psDD->Seed < 0 ) { - exc_Q14 = -exc_Q14; - } - - /* Add predictions */ - LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); - xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); - - /* Update states */ - psSS[ 0 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 ); - sLF_AR_shp_Q14 = silk_SUB32( psSS[ 0 ].Diff_Q14, n_AR_Q14 ); - psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); - psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14; - psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14; - psSS[ 0 ].xq_Q14 = xq_Q14; - - /* Update states for second best quantization */ - - /* Quantized excitation */ - exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 ); - if ( psDD->Seed < 0 ) { - exc_Q14 = -exc_Q14; - } - - /* Add predictions */ - LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); - xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); - - /* Update states */ - psSS[ 1 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 ); - sLF_AR_shp_Q14 = silk_SUB32( psSS[ 1 ].Diff_Q14, n_AR_Q14 ); - psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); - psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14; - psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14; - psSS[ 1 ].xq_Q14 = xq_Q14; - } - - *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY; - if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY; - last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY; - - /* Find winner */ - RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; - Winner_ind = 0; - for( k = 1; k < nStatesDelayedDecision; k++ ) { - if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) { - RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10; - Winner_ind = k; - } - } - - /* Increase RD values of expired states */ - Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ]; - for( k = 0; k < nStatesDelayedDecision; k++ ) { - if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) { - psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 ); - psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 ); - silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 ); - } - } - - /* Find worst in first set and best in second set */ - RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; - RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10; - RDmax_ind = 0; - RDmin_ind = 0; - for( k = 1; k < nStatesDelayedDecision; k++ ) { - /* find worst in first set */ - if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) { - RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10; - RDmax_ind = k; - } - /* find best in second set */ - if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) { - RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10; - RDmin_ind = k; - } - } - - /* Replace a state if best from second set outperforms worst in first set */ - if( RDmin_Q10 < RDmax_Q10 ) { - silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i, - ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) ); - silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) ); - } - - /* Write samples from winner to output and long-term filter states */ - psDD = &psDelDec[ Winner_ind ]; - if( subfr > 0 || i >= decisionDelay ) { - pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); - xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( - silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) ); - NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ]; - sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ]; - } - NSQ->sLTP_shp_buf_idx++; - NSQ->sLTP_buf_idx++; - - /* Update states */ - for( k = 0; k < nStatesDelayedDecision; k++ ) { - psDD = &psDelDec[ k ]; - psSS = &psSampleState[ k ][ 0 ]; - psDD->LF_AR_Q14 = psSS->LF_AR_Q14; - psDD->Diff_Q14 = psSS->Diff_Q14; - psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14; - psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14; - psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10; - psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 ); - psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14; - psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) ); - psDD->RandState[ *smpl_buf_idx ] = psDD->Seed; - psDD->RD_Q10 = psSS->RD_Q10; - } - delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10; - } - /* Update LPC states */ - for( k = 0; k < nStatesDelayedDecision; k++ ) { - psDD = &psDelDec[ k ]; - silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); - } - RESTORE_STACK; -} -#endif /* OVERRIDE_silk_noise_shape_quantizer_del_dec */ - -static OPUS_INLINE void silk_nsq_del_dec_scale_states( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ - const opus_int16 x16[], /* I Input */ - opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ - const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ - opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ - opus_int subfr, /* I Subframe number */ - opus_int nStatesDelayedDecision, /* I Number of del dec states */ - const opus_int LTP_scale_Q14, /* I LTP state scaling */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ - const opus_int signal_type, /* I Signal type */ - const opus_int decisionDelay /* I Decision delay */ -) -{ - opus_int i, k, lag; - opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26; - NSQ_del_dec_struct *psDD; - - lag = pitchL[ subfr ]; - inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); - silk_assert( inv_gain_Q31 != 0 ); - - /* Scale input */ - inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 ); - for( i = 0; i < psEncC->subfr_length; i++ ) { - x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 ); - } - - /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ - if( NSQ->rewhite_flag ) { - if( subfr == 0 ) { - /* Do LTP downscaling */ - inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); - } - for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { - silk_assert( i < MAX_FRAME_LENGTH ); - sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] ); - } - } - - /* Adjust for changing gain */ - if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { - gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); - - /* Scale long-term shaping state */ - for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) { - NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); - } - - /* Scale long-term prediction state */ - if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { - for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) { - sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); - } - } - - for( k = 0; k < nStatesDelayedDecision; k++ ) { - psDD = &psDelDec[ k ]; - - /* Scale scalar states */ - psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 ); - psDD->Diff_Q14 = silk_SMULWW( gain_adj_Q16, psDD->Diff_Q14 ); - - /* Scale short-term prediction and shaping states */ - for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { - psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] ); - } - for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { - psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] ); - } - for( i = 0; i < DECISION_DELAY; i++ ) { - psDD->Pred_Q15[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[ i ] ); - psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] ); - } - } - - /* Save inverse gain */ - NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; - } -} diff --git a/src/libopus/silk/PLC.c b/src/libopus/silk/PLC.c index fc2f09e1..d9c6c407 100644 --- a/src/libopus/silk/PLC.c +++ b/src/libopus/silk/PLC.c @@ -25,14 +25,18 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" -#include "../celt/stack_alloc.h" +#include "stack_alloc.h" #include "PLC.h" +#ifdef ENABLE_DEEP_PLC +#include "lpcnet.h" +#endif + #define NB_ATT 2 static const opus_int16 HARM_ATT_Q15[NB_ATT] = { 32440, 31130 }; /* 0.99, 0.95 */ static const opus_int16 PLC_RAND_ATTENUATE_V_Q15[NB_ATT] = { 31130, 26214 }; /* 0.95, 0.8 */ @@ -47,6 +51,9 @@ static OPUS_INLINE void silk_PLC_conceal( silk_decoder_state *psDec, /* I/O Decoder state */ silk_decoder_control *psDecCtrl, /* I/O Decoder control */ opus_int16 frame[], /* O LPC residual signal */ +#ifdef ENABLE_DEEP_PLC + LPCNetPLCState *lpcnet, +#endif int arch /* I Run-time architecture */ ); @@ -67,6 +74,9 @@ void silk_PLC( silk_decoder_control *psDecCtrl, /* I/O Decoder control */ opus_int16 frame[], /* I/O signal */ opus_int lost, /* I Loss flag */ +#ifdef ENABLE_DEEP_PLC + LPCNetPLCState *lpcnet, +#endif int arch /* I Run-time architecture */ ) { @@ -80,7 +90,11 @@ void silk_PLC( /****************************/ /* Generate Signal */ /****************************/ - silk_PLC_conceal( psDec, psDecCtrl, frame, arch ); + silk_PLC_conceal( psDec, psDecCtrl, frame, +#ifdef ENABLE_DEEP_PLC + lpcnet, +#endif + arch ); psDec->lossCnt++; } else { @@ -88,6 +102,14 @@ void silk_PLC( /* Update state */ /****************************/ silk_PLC_update( psDec, psDecCtrl ); +#ifdef ENABLE_DEEP_PLC + if ( lpcnet != NULL && psDec->sPLC.fs_kHz == 16 ) { + int k; + for( k = 0; k < psDec->nb_subfr; k += 2 ) { + lpcnet_plc_update( lpcnet, frame + k * psDec->subfr_length ); + } + } +#endif } } @@ -195,6 +217,9 @@ static OPUS_INLINE void silk_PLC_conceal( silk_decoder_state *psDec, /* I/O Decoder state */ silk_decoder_control *psDecCtrl, /* I/O Decoder control */ opus_int16 frame[], /* O LPC residual signal */ +#ifdef ENABLE_DEEP_PLC + LPCNetPLCState *lpcnet, +#endif int arch /* I Run-time architecture */ ) { @@ -328,10 +353,8 @@ static OPUS_INLINE void silk_PLC_conceal( for( j = 0; j < LTP_ORDER; j++ ) { B_Q14[ j ] = silk_RSHIFT( silk_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 ); } - if ( psDec->indices.signalType != TYPE_NO_VOICE_ACTIVITY ) { - /* Gradually reduce excitation gain */ - rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 ); - } + /* Gradually reduce excitation gain */ + rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 ); /* Slowly increase pitch lag */ psPLC->pitchL_Q8 = silk_SMLAWB( psPLC->pitchL_Q8, psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 ); @@ -373,6 +396,24 @@ static OPUS_INLINE void silk_PLC_conceal( /* Scale with Gain */ frame[ i ] = (opus_int16)silk_SAT16( silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], prevGain_Q10[ 1 ] ), 8 ) ) ); } +#ifdef ENABLE_DEEP_PLC + if ( lpcnet != NULL && lpcnet->loaded && psDec->sPLC.fs_kHz == 16 ) { + int run_deep_plc = psDec->sPLC.enable_deep_plc || lpcnet->fec_fill_pos != 0; + if( run_deep_plc ) { + for( k = 0; k < psDec->nb_subfr; k += 2 ) { + lpcnet_plc_conceal( lpcnet, frame + k * psDec->subfr_length ); + } + /* We *should* be able to copy only from psDec->frame_length-MAX_LPC_ORDER, i.e. the last MAX_LPC_ORDER samples. */ + for( i = 0; i < psDec->frame_length; i++ ) { + sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = (int)floor(.5 + frame[ i ] * (float)(1 << 24) / prevGain_Q10[ 1 ] ); + } + } else { + for( k = 0; k < psDec->nb_subfr; k += 2 ) { + lpcnet_plc_update( lpcnet, frame + k * psDec->subfr_length ); + } + } + } +#endif /* Save LPC state */ silk_memcpy( psDec->sLPC_Q14_buf, &sLPC_Q14_ptr[ psDec->frame_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); @@ -433,12 +474,16 @@ void silk_PLC_glue_frames( slope_Q16 = silk_DIV32_16( ( (opus_int32)1 << 16 ) - gain_Q16, length ); /* Make slope 4x steeper to avoid missing onsets after DTX */ slope_Q16 = silk_LSHIFT( slope_Q16, 2 ); - - for( i = 0; i < length; i++ ) { - frame[ i ] = silk_SMULWB( gain_Q16, frame[ i ] ); - gain_Q16 += slope_Q16; - if( gain_Q16 > (opus_int32)1 << 16 ) { - break; +#ifdef ENABLE_DEEP_PLC + if ( psDec->sPLC.fs_kHz != 16 ) +#endif + { + for( i = 0; i < length; i++ ) { + frame[ i ] = silk_SMULWB( gain_Q16, frame[ i ] ); + gain_Q16 += slope_Q16; + if( gain_Q16 > (opus_int32)1 << 16 ) { + break; + } } } } diff --git a/src/libopus/silk/PLC.h b/src/libopus/silk/PLC.h index 6438f516..1bebb786 100644 --- a/src/libopus/silk/PLC.h +++ b/src/libopus/silk/PLC.h @@ -49,6 +49,9 @@ void silk_PLC( silk_decoder_control *psDecCtrl, /* I/O Decoder control */ opus_int16 frame[], /* I/O signal */ opus_int lost, /* I Loss flag */ +#ifdef ENABLE_DEEP_PLC + LPCNetPLCState *lpcnet, +#endif int arch /* I Run-time architecture */ ); diff --git a/src/libopus/silk/SigProc_FIX.h b/src/libopus/silk/SigProc_FIX.h index 686b3a2e..fbdfa82e 100644 --- a/src/libopus/silk/SigProc_FIX.h +++ b/src/libopus/silk/SigProc_FIX.h @@ -41,7 +41,7 @@ extern "C" #include "typedef.h" #include "resampler_structs.h" #include "macros.h" -#include "../celt/cpu_support.h" +#include "cpu_support.h" #if defined(OPUS_X86_MAY_HAVE_SSE4_1) #include "x86/SigProc_FIX_sse.h" @@ -381,7 +381,7 @@ opus_int32 silk_inner_prod_aligned_scale( const opus_int len /* I vector lengths */ ); -opus_int64 silk_inner_prod16_aligned_64_c( +opus_int64 silk_inner_prod16_c( const opus_int16 *inVec1, /* I input vector 1 */ const opus_int16 *inVec2, /* I input vector 2 */ const opus_int len /* I vector lengths */ @@ -609,12 +609,14 @@ static OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b) /* the following seems faster on x86 */ #define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT64(silk_SMULL((a32), (b32)), 32) -#if !defined(OPUS_X86_MAY_HAVE_SSE4_1) +#if !defined(OVERRIDE_silk_burg_modified) #define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \ ((void)(arch), silk_burg_modified_c(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch)) +#endif -#define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \ - ((void)(arch),silk_inner_prod16_aligned_64_c(inVec1, inVec2, len)) +#if !defined(OVERRIDE_silk_inner_prod16) +#define silk_inner_prod16(inVec1, inVec2, len, arch) \ + ((void)(arch),silk_inner_prod16_c(inVec1, inVec2, len)) #endif #include "Inlines.h" diff --git a/src/libopus/silk/VAD.c b/src/libopus/silk/VAD.c deleted file mode 100644 index 3f90f0b8..00000000 --- a/src/libopus/silk/VAD.c +++ /dev/null @@ -1,361 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif -#include - -#include "main.h" -#include "../celt/stack_alloc.h" - -/* Silk VAD noise level estimation */ -# if !defined(OPUS_X86_MAY_HAVE_SSE4_1) -static OPUS_INLINE void silk_VAD_GetNoiseLevels( - const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */ - silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ -); -#endif - -/**********************************/ -/* Initialization of the Silk VAD */ -/**********************************/ -opus_int silk_VAD_Init( /* O Return value, 0 if success */ - silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ -) -{ - opus_int b, ret = 0; - - /* reset state memory */ - silk_memset( psSilk_VAD, 0, sizeof( silk_VAD_state ) ); - - /* init noise levels */ - /* Initialize array with approx pink noise levels (psd proportional to inverse of frequency) */ - for( b = 0; b < VAD_N_BANDS; b++ ) { - psSilk_VAD->NoiseLevelBias[ b ] = silk_max_32( silk_DIV32_16( VAD_NOISE_LEVELS_BIAS, b + 1 ), 1 ); - } - - /* Initialize state */ - for( b = 0; b < VAD_N_BANDS; b++ ) { - psSilk_VAD->NL[ b ] = silk_MUL( 100, psSilk_VAD->NoiseLevelBias[ b ] ); - psSilk_VAD->inv_NL[ b ] = silk_DIV32( silk_int32_MAX, psSilk_VAD->NL[ b ] ); - } - psSilk_VAD->counter = 15; - - /* init smoothed energy-to-noise ratio*/ - for( b = 0; b < VAD_N_BANDS; b++ ) { - psSilk_VAD->NrgRatioSmth_Q8[ b ] = 100 * 256; /* 100 * 256 --> 20 dB SNR */ - } - - return( ret ); -} - -/* Weighting factors for tilt measure */ -static const opus_int32 tiltWeights[ VAD_N_BANDS ] PROGMEM = { 30000, 6000, -12000, -12000 }; - -/***************************************/ -/* Get the speech activity level in Q8 */ -/***************************************/ -opus_int silk_VAD_GetSA_Q8_c( /* O Return value, 0 if success */ - silk_encoder_state *psEncC, /* I/O Encoder state */ - const opus_int16 pIn[] /* I PCM input */ -) -{ - opus_int SA_Q15, pSNR_dB_Q7, input_tilt; - opus_int decimated_framelength1, decimated_framelength2; - opus_int decimated_framelength; - opus_int dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s; - opus_int32 sumSquared, smooth_coef_Q16; - opus_int16 HPstateTmp; - VARDECL( opus_int16, X ); - opus_int32 Xnrg[ VAD_N_BANDS ]; - opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ]; - opus_int32 speech_nrg, x_tmp; - opus_int X_offset[ VAD_N_BANDS ]; - opus_int ret = 0; - silk_VAD_state *psSilk_VAD = &psEncC->sVAD; - SAVE_STACK; - - /* Safety checks */ - silk_assert( VAD_N_BANDS == 4 ); - celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length ); - celt_assert( psEncC->frame_length <= 512 ); - celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) ); - - /***********************/ - /* Filter and Decimate */ - /***********************/ - decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 ); - decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 ); - decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 ); - /* Decimate into 4 bands: - 0 L 3L L 3L 5L - - -- - -- -- - 8 8 2 4 4 - - [0-1 kHz| temp. |1-2 kHz| 2-4 kHz | 4-8 kHz | - - They're arranged to allow the minimal ( frame_length / 4 ) extra - scratch space during the downsampling process */ - X_offset[ 0 ] = 0; - X_offset[ 1 ] = decimated_framelength + decimated_framelength2; - X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength; - X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2; - ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 ); - - /* 0-8 kHz to 0-4 kHz and 4-8 kHz */ - silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ], - X, &X[ X_offset[ 3 ] ], psEncC->frame_length ); - - /* 0-4 kHz to 0-2 kHz and 2-4 kHz */ - silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ], - X, &X[ X_offset[ 2 ] ], decimated_framelength1 ); - - /* 0-2 kHz to 0-1 kHz and 1-2 kHz */ - silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ], - X, &X[ X_offset[ 1 ] ], decimated_framelength2 ); - - /*********************************************/ - /* HP filter on lowest band (differentiator) */ - /*********************************************/ - X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 ); - HPstateTmp = X[ decimated_framelength - 1 ]; - for( i = decimated_framelength - 1; i > 0; i-- ) { - X[ i - 1 ] = silk_RSHIFT( X[ i - 1 ], 1 ); - X[ i ] -= X[ i - 1 ]; - } - X[ 0 ] -= psSilk_VAD->HPstate; - psSilk_VAD->HPstate = HPstateTmp; - - /*************************************/ - /* Calculate the energy in each band */ - /*************************************/ - for( b = 0; b < VAD_N_BANDS; b++ ) { - /* Find the decimated framelength in the non-uniformly divided bands */ - decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) ); - - /* Split length into subframe lengths */ - dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 ); - dec_subframe_offset = 0; - - /* Compute energy per sub-frame */ - /* initialize with summed energy of last subframe */ - Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ]; - for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) { - sumSquared = 0; - for( i = 0; i < dec_subframe_length; i++ ) { - /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2. */ - /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */ - x_tmp = silk_RSHIFT( - X[ X_offset[ b ] + i + dec_subframe_offset ], 3 ); - sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp ); - - /* Safety check */ - silk_assert( sumSquared >= 0 ); - } - - /* Add/saturate summed energy of current subframe */ - if( s < VAD_INTERNAL_SUBFRAMES - 1 ) { - Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared ); - } else { - /* Look-ahead subframe */ - Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) ); - } - - dec_subframe_offset += dec_subframe_length; - } - psSilk_VAD->XnrgSubfr[ b ] = sumSquared; - } - - /********************/ - /* Noise estimation */ - /********************/ - silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD ); - - /***********************************************/ - /* Signal-plus-noise to noise ratio estimation */ - /***********************************************/ - sumSquared = 0; - input_tilt = 0; - for( b = 0; b < VAD_N_BANDS; b++ ) { - speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ]; - if( speech_nrg > 0 ) { - /* Divide, with sufficient resolution */ - if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) { - NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 ); - } else { - NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 ); - } - - /* Convert to log domain */ - SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128; - - /* Sum-of-squares */ - sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */ - - /* Tilt measure */ - if( speech_nrg < ( (opus_int32)1 << 20 ) ) { - /* Scale down SNR value for small subband speech energies */ - SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 ); - } - input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 ); - } else { - NrgToNoiseRatio_Q8[ b ] = 256; - } - } - - /* Mean-of-squares */ - sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */ - - /* Root-mean-square approximation, scale to dBs, and write to output pointer */ - pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */ - - /*********************************/ - /* Speech Probability Estimation */ - /*********************************/ - SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 ); - - /**************************/ - /* Frequency Tilt Measure */ - /**************************/ - psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 ); - - /**************************************************/ - /* Scale the sigmoid output based on power levels */ - /**************************************************/ - speech_nrg = 0; - for( b = 0; b < VAD_N_BANDS; b++ ) { - /* Accumulate signal-without-noise energies, higher frequency bands have more weight */ - speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 ); - } - - if( psEncC->frame_length == 20 * psEncC->fs_kHz ) { - speech_nrg = silk_RSHIFT32( speech_nrg, 1 ); - } - /* Power scaling */ - if( speech_nrg <= 0 ) { - SA_Q15 = silk_RSHIFT( SA_Q15, 1 ); - } else if( speech_nrg < 16384 ) { - speech_nrg = silk_LSHIFT32( speech_nrg, 16 ); - - /* square-root */ - speech_nrg = silk_SQRT_APPROX( speech_nrg ); - SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 ); - } - - /* Copy the resulting speech activity in Q8 */ - psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX ); - - /***********************************/ - /* Energy Level and SNR estimation */ - /***********************************/ - /* Smoothing coefficient */ - smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) ); - - if( psEncC->frame_length == 10 * psEncC->fs_kHz ) { - smooth_coef_Q16 >>= 1; - } - - for( b = 0; b < VAD_N_BANDS; b++ ) { - /* compute smoothed energy-to-noise ratio per band */ - psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ], - NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 ); - - /* signal to noise ratio in dB per band */ - SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 ); - /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */ - psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) ); - } - - RESTORE_STACK; - return( ret ); -} - -/**************************/ -/* Noise level estimation */ -/**************************/ -# if !defined(OPUS_X86_MAY_HAVE_SSE4_1) -static OPUS_INLINE -#endif -void silk_VAD_GetNoiseLevels( - const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */ - silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ -) -{ - opus_int k; - opus_int32 nl, nrg, inv_nrg; - opus_int coef, min_coef; - - /* Initially faster smoothing */ - if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */ - min_coef = silk_DIV32_16( silk_int16_MAX, silk_RSHIFT( psSilk_VAD->counter, 4 ) + 1 ); - /* Increment frame counter */ - psSilk_VAD->counter++; - } else { - min_coef = 0; - } - - for( k = 0; k < VAD_N_BANDS; k++ ) { - /* Get old noise level estimate for current band */ - nl = psSilk_VAD->NL[ k ]; - silk_assert( nl >= 0 ); - - /* Add bias */ - nrg = silk_ADD_POS_SAT32( pX[ k ], psSilk_VAD->NoiseLevelBias[ k ] ); - silk_assert( nrg > 0 ); - - /* Invert energies */ - inv_nrg = silk_DIV32( silk_int32_MAX, nrg ); - silk_assert( inv_nrg >= 0 ); - - /* Less update when subband energy is high */ - if( nrg > silk_LSHIFT( nl, 3 ) ) { - coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3; - } else if( nrg < nl ) { - coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16; - } else { - coef = silk_SMULWB( silk_SMULWW( inv_nrg, nl ), VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 << 1 ); - } - - /* Initially faster smoothing */ - coef = silk_max_int( coef, min_coef ); - - /* Smooth inverse energies */ - psSilk_VAD->inv_NL[ k ] = silk_SMLAWB( psSilk_VAD->inv_NL[ k ], inv_nrg - psSilk_VAD->inv_NL[ k ], coef ); - silk_assert( psSilk_VAD->inv_NL[ k ] >= 0 ); - - /* Compute noise level by inverting again */ - nl = silk_DIV32( silk_int32_MAX, psSilk_VAD->inv_NL[ k ] ); - silk_assert( nl >= 0 ); - - /* Limit noise levels (guarantee 7 bits of head room) */ - nl = silk_min( nl, 0x00FFFFFF ); - - /* Store as part of state */ - psSilk_VAD->NL[ k ] = nl; - } -} diff --git a/src/libopus/silk/VQ_WMat_EC.c b/src/libopus/silk/VQ_WMat_EC.c index 601e3969..bf9ef7b3 100644 --- a/src/libopus/silk/VQ_WMat_EC.c +++ b/src/libopus/silk/VQ_WMat_EC.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" @@ -64,7 +64,7 @@ void silk_VQ_WMat_EC_c( *rate_dist_Q8 = silk_int32_MAX; *res_nrg_Q15 = silk_int32_MAX; cb_row_Q7 = cb_Q7; - /* In things go really bad, at least *ind is set to something safe. */ + /* If things go really bad, at least *ind is set to something safe. */ *ind = 0; for( k = 0; k < L; k++ ) { opus_int32 penalty; @@ -115,7 +115,7 @@ void silk_VQ_WMat_EC_c( if( sum1_Q15 >= 0 ) { /* Translate residual energy to bits using high-rate assumption (6 dB ==> 1 bit/sample) */ bits_res_Q8 = silk_SMULBB( subfr_len, silk_lin2log( sum1_Q15 + penalty) - (15 << 7) ); - /* In the following line we reduce the codelength component by half ("-1"); seems to slghtly improve quality */ + /* In the following line we reduce the codelength component by half ("-1"); seems to slightly improve quality */ bits_tot_Q8 = silk_ADD_LSHIFT32( bits_res_Q8, cl_Q5[ k ], 3-1 ); if( bits_tot_Q8 <= *rate_dist_Q8 ) { *rate_dist_Q8 = bits_tot_Q8; diff --git a/src/libopus/silk/ana_filt_bank_1.c b/src/libopus/silk/ana_filt_bank_1.c index 30e42f21..1211ffa0 100644 --- a/src/libopus/silk/ana_filt_bank_1.c +++ b/src/libopus/silk/ana_filt_bank_1.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "SigProc_FIX.h" diff --git a/src/libopus/silk/arch.h b/src/libopus/silk/arch.h new file mode 100644 index 00000000..0530293d --- /dev/null +++ b/src/libopus/silk/arch.h @@ -0,0 +1 @@ +#include "../celt/arch.h" diff --git a/src/libopus/silk/biquad_alt.c b/src/libopus/silk/biquad_alt.c index 5ae2f516..f3844f37 100644 --- a/src/libopus/silk/biquad_alt.c +++ b/src/libopus/silk/biquad_alt.c @@ -32,9 +32,9 @@ POSSIBILITY OF SUCH DAMAGE. * Can handle slowly varying filter coefficients * * */ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "SigProc_FIX.h" diff --git a/src/libopus/silk/bwexpander.c b/src/libopus/silk/bwexpander.c index 509146c8..a70eb08e 100644 --- a/src/libopus/silk/bwexpander.c +++ b/src/libopus/silk/bwexpander.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "SigProc_FIX.h" diff --git a/src/libopus/silk/bwexpander_32.c b/src/libopus/silk/bwexpander_32.c index 703b475e..d6cd8746 100644 --- a/src/libopus/silk/bwexpander_32.c +++ b/src/libopus/silk/bwexpander_32.c @@ -25,13 +25,14 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "SigProc_FIX.h" -/* Chirp (bandwidth expand) LP AR filter */ +/* Chirp (bandwidth expand) LP AR filter. + This logic is reused in _celt_lpc(). Any bug fixes should also be applied there. */ void silk_bwexpander_32( opus_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */ const opus_int d, /* I Length of ar */ diff --git a/src/libopus/silk/celt_lpc.h b/src/libopus/silk/celt_lpc.h new file mode 100644 index 00000000..69756654 --- /dev/null +++ b/src/libopus/silk/celt_lpc.h @@ -0,0 +1 @@ +#include "../celt/celt_lpc.h" diff --git a/src/libopus/silk/check_control_input.c b/src/libopus/silk/check_control_input.c index 31b8a7c4..016fee20 100644 --- a/src/libopus/silk/check_control_input.c +++ b/src/libopus/silk/check_control_input.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" #include "control.h" diff --git a/src/libopus/silk/code_signs.c b/src/libopus/silk/code_signs.c index 8abf67e9..b9eae242 100644 --- a/src/libopus/silk/code_signs.c +++ b/src/libopus/silk/code_signs.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/config.h b/src/libopus/silk/config.h new file mode 100644 index 00000000..2989b6b0 --- /dev/null +++ b/src/libopus/silk/config.h @@ -0,0 +1 @@ +#include "../include/config.h" diff --git a/src/libopus/silk/control.h b/src/libopus/silk/control.h index b76ec33c..f5633e62 100644 --- a/src/libopus/silk/control.h +++ b/src/libopus/silk/control.h @@ -77,6 +77,9 @@ typedef struct { /* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */ opus_int useInBandFEC; + /* I: Flag to enable in-band Deep REDundancy (DRED); 0/1 */ + opus_int useDRED; + /* I: Flag to actually code in-band Forward Error Correction (FEC) in the current packet; 0/1 */ opus_int LBRR_coded; @@ -141,6 +144,14 @@ typedef struct { /* O: Pitch lag of previous frame (0 if unvoiced), measured in samples at 48 kHz */ opus_int prevPitchLag; + + /* I: Enable Deep PLC */ + opus_int enable_deep_plc; + +#ifdef ENABLE_OSCE + /* I: OSCE method */ + opus_int osce_method; +#endif } silk_DecControlStruct; #ifdef __cplusplus diff --git a/src/libopus/silk/control_SNR.c b/src/libopus/silk/control_SNR.c index 182c0d8e..cb26f267 100644 --- a/src/libopus/silk/control_SNR.c +++ b/src/libopus/silk/control_SNR.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" #include "tuning_parameters.h" diff --git a/src/libopus/silk/control_audio_bandwidth.c b/src/libopus/silk/control_audio_bandwidth.c index b7913b84..3a05cc04 100644 --- a/src/libopus/silk/control_audio_bandwidth.c +++ b/src/libopus/silk/control_audio_bandwidth.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" #include "tuning_parameters.h" diff --git a/src/libopus/silk/control_codec.c b/src/libopus/silk/control_codec.c index cd2e2f21..2eac36b1 100644 --- a/src/libopus/silk/control_codec.c +++ b/src/libopus/silk/control_codec.c @@ -25,17 +25,17 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #ifdef FIXED_POINT -#include "fixed/main_FIX.h" +#include "main_FIX.h" #define silk_encoder_state_Fxx silk_encoder_state_FIX #else #include "main_FLP.h" #define silk_encoder_state_Fxx silk_encoder_state_FLP #endif -#include "../celt/stack_alloc.h" +#include "stack_alloc.h" #include "tuning_parameters.h" #include "pitch_est_defines.h" @@ -415,7 +415,7 @@ static OPUS_INLINE opus_int silk_setup_LBRR( /* Previous packet did not have LBRR, and was therefore coded at a higher bitrate */ psEncC->LBRR_GainIncreases = 7; } else { - psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 ); + psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.2, 16 ) ), 3 ); } } diff --git a/src/libopus/silk/cpu_support.h b/src/libopus/silk/cpu_support.h new file mode 100644 index 00000000..32e7df22 --- /dev/null +++ b/src/libopus/silk/cpu_support.h @@ -0,0 +1 @@ +#include "../celt/cpu_support.h" diff --git a/src/libopus/silk/debug.c b/src/libopus/silk/debug.c index b9550c40..ec8c5256 100644 --- a/src/libopus/silk/debug.c +++ b/src/libopus/silk/debug.c @@ -25,23 +25,27 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif + +typedef int prevent_empty_translation_unit_warning; #include "debug.h" + +#if SILK_DEBUG || SILK_TIC_TOC #include "SigProc_FIX.h" +#endif #if SILK_TIC_TOC -#ifdef _WIN32 - #if (defined(_WIN32) || defined(_WINCE)) #include /* timer */ #else /* Linux or Mac*/ #include #endif +#ifdef _WIN32 unsigned long silk_GetHighResolutionTime(void) /* O time in usec*/ { /* Returns a time counter in microsec */ @@ -65,7 +69,7 @@ unsigned long GetHighResolutionTime(void) /* O time in usec*/ int silk_Timer_nTimers = 0; int silk_Timer_depth_ctr = 0; char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN]; -#ifdef WIN32 +#ifdef _WIN32 LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX]; #else unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX]; @@ -76,7 +80,7 @@ opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX]; opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX]; opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX]; -#ifdef WIN32 +#ifdef _WIN32 void silk_TimerSave(char *file_name) { if( silk_Timer_nTimers > 0 ) diff --git a/src/libopus/silk/debug.h b/src/libopus/silk/debug.h index 6f68c1ca..36163e47 100644 --- a/src/libopus/silk/debug.h +++ b/src/libopus/silk/debug.h @@ -28,28 +28,29 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef SILK_DEBUG_H #define SILK_DEBUG_H -#include "typedef.h" -#include /* file writing */ -#include /* strcpy, strcmp */ - -#ifdef __cplusplus -extern "C" -{ -#endif - -unsigned long GetHighResolutionTime(void); /* O time in usec*/ - /* Set to 1 to enable DEBUG_STORE_DATA() macros for dumping * intermediate signals from the codec. */ #define SILK_DEBUG 0 /* Flag for using timers */ -#define SILK_TIC_TOC 0 +#define SILK_TIC_TOC 0 +#if SILK_DEBUG || SILK_TIC_TOC +#include "typedef.h" +#include /* strcpy, strcmp */ +#include /* file writing */ +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif #if SILK_TIC_TOC +unsigned long GetHighResolutionTime(void); /* O time in usec*/ + #if (defined(_WIN32) || defined(_WINCE)) #include /* timer */ #else /* Linux or Mac*/ diff --git a/src/libopus/silk/dec_API.c b/src/libopus/silk/dec_API.c index 36b5ba5a..ebe80e5f 100644 --- a/src/libopus/silk/dec_API.c +++ b/src/libopus/silk/dec_API.c @@ -25,13 +25,18 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "API.h" #include "main.h" -#include "../celt/stack_alloc.h" -#include "../celt/os_support.h" +#include "stack_alloc.h" +#include "os_support.h" + +#ifdef ENABLE_OSCE +#include "osce.h" +#include "osce_structs.h" +#endif /************************/ /* Decoder Super Struct */ @@ -42,12 +47,33 @@ typedef struct { opus_int nChannelsAPI; opus_int nChannelsInternal; opus_int prev_decode_only_middle; +#ifdef ENABLE_OSCE + OSCEModel osce_model; +#endif } silk_decoder; /*********************/ /* Decoder functions */ /*********************/ + + +opus_int silk_LoadOSCEModels(void *decState, const unsigned char *data, int len) +{ +#ifdef ENABLE_OSCE + opus_int ret = SILK_NO_ERROR; + + ret = osce_load_models(&((silk_decoder *)decState)->osce_model, data, len); + ((silk_decoder *)decState)->osce_model.loaded = (ret == 0); + return ret; +#else + (void) decState; + (void) data; + (void) len; + return SILK_NO_ERROR; +#endif +} + opus_int silk_Get_Decoder_Size( /* O Returns error code */ opus_int *decSizeBytes /* O Number of bytes in SILK decoder state */ ) @@ -60,12 +86,37 @@ opus_int silk_Get_Decoder_Size( /* O Returns error co } /* Reset decoder state */ +opus_int silk_ResetDecoder( /* O Returns error code */ + void *decState /* I/O State */ +) +{ + opus_int n, ret = SILK_NO_ERROR; + silk_decoder_state *channel_state = ((silk_decoder *)decState)->channel_state; + + for( n = 0; n < DECODER_NUM_CHANNELS; n++ ) { + ret = silk_reset_decoder( &channel_state[ n ] ); + } + silk_memset(&((silk_decoder *)decState)->sStereo, 0, sizeof(((silk_decoder *)decState)->sStereo)); + /* Not strictly needed, but it's cleaner that way */ + ((silk_decoder *)decState)->prev_decode_only_middle = 0; + + return ret; +} + + opus_int silk_InitDecoder( /* O Returns error code */ void *decState /* I/O State */ ) { opus_int n, ret = SILK_NO_ERROR; silk_decoder_state *channel_state = ((silk_decoder *)decState)->channel_state; +#ifdef ENABLE_OSCE + ((silk_decoder *)decState)->osce_model.loaded = 0; +#endif +#ifndef USE_WEIGHTS_FILE + /* load osce models */ + silk_LoadOSCEModels(decState, NULL, 0); +#endif for( n = 0; n < DECODER_NUM_CHANNELS; n++ ) { ret = silk_init_decoder( &channel_state[ n ] ); @@ -86,6 +137,9 @@ opus_int silk_Decode( /* O Returns error co ec_dec *psRangeDec, /* I/O Compressor data structure */ opus_int16 *samplesOut, /* O Decoded output speech vector */ opus_int32 *nSamplesOut, /* O Number of samples decoded */ +#ifdef ENABLE_DEEP_PLC + LPCNetPLCState *lpcnet, +#endif int arch /* I Run-time architecture */ ) { @@ -278,6 +332,7 @@ opus_int silk_Decode( /* O Returns error co has_side = !psDec->prev_decode_only_middle || (decControl->nChannelsInternal == 2 && lostFlag == FLAG_DECODE_LBRR && channel_state[1].LBRR_flags[ channel_state[1].nFramesDecoded ] == 1 ); } + channel_state[ 0 ].sPLC.enable_deep_plc = decControl->enable_deep_plc; /* Call decoder for one frame */ for( n = 0; n < decControl->nChannelsInternal; n++ ) { if( n == 0 || has_side ) { @@ -297,7 +352,19 @@ opus_int silk_Decode( /* O Returns error co } else { condCoding = CODE_CONDITIONALLY; } - ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 ], &nSamplesOutDec, lostFlag, condCoding, arch); +#ifdef ENABLE_OSCE + if ( channel_state[n].osce.method != decControl->osce_method ) { + osce_reset( &channel_state[n].osce, decControl->osce_method ); + } +#endif + ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 ], &nSamplesOutDec, lostFlag, condCoding, +#ifdef ENABLE_DEEP_PLC + n == 0 ? lpcnet : NULL, +#endif +#ifdef ENABLE_OSCE + &psDec->osce_model, +#endif + arch); } else { silk_memset( &samplesOut1_tmp[ n ][ 2 ], 0, nSamplesOutDec * sizeof( opus_int16 ) ); } diff --git a/src/libopus/silk/decode_core.c b/src/libopus/silk/decode_core.c index eb7a9d26..ffe752c9 100644 --- a/src/libopus/silk/decode_core.c +++ b/src/libopus/silk/decode_core.c @@ -25,12 +25,12 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" -#include "../celt/stack_alloc.h" +#include "stack_alloc.h" /**********************************************************/ /* Core decoder. Performs inverse NSQ operation LTP + LPC */ diff --git a/src/libopus/silk/decode_frame.c b/src/libopus/silk/decode_frame.c index bb8952d2..fcb51890 100644 --- a/src/libopus/silk/decode_frame.c +++ b/src/libopus/silk/decode_frame.c @@ -25,14 +25,18 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" -#include "../celt/stack_alloc.h" +#include "stack_alloc.h" #include "PLC.h" +#ifdef ENABLE_OSCE +#include "osce.h" +#endif + /****************/ /* Decode frame */ /****************/ @@ -43,6 +47,12 @@ opus_int silk_decode_frame( opus_int32 *pN, /* O Pointer to size of output frame */ opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ opus_int condCoding, /* I The type of conditional coding to use */ +#ifdef ENABLE_DEEP_PLC + LPCNetPLCState *lpcnet, +#endif +#ifdef ENABLE_OSCE + OSCEModel *osce_model, +#endif int arch /* I Run-time architecture */ ) { @@ -61,6 +71,10 @@ opus_int silk_decode_frame( ( lostFlag == FLAG_DECODE_LBRR && psDec->LBRR_flags[ psDec->nFramesDecoded ] == 1 ) ) { VARDECL( opus_int16, pulses ); +#ifdef ENABLE_OSCE + opus_int32 ec_start; + ec_start = ec_tell(psRangeDec); +#endif ALLOC( pulses, (L + SHELL_CODEC_FRAME_LENGTH - 1) & ~(SHELL_CODEC_FRAME_LENGTH - 1), opus_int16 ); /*********************************************/ @@ -84,10 +98,29 @@ opus_int silk_decode_frame( /********************************************************/ silk_decode_core( psDec, psDecCtrl, pOut, pulses, arch ); + /*************************/ + /* Update output buffer. */ + /*************************/ + celt_assert( psDec->ltp_mem_length >= psDec->frame_length ); + mv_len = psDec->ltp_mem_length - psDec->frame_length; + silk_memmove( psDec->outBuf, &psDec->outBuf[ psDec->frame_length ], mv_len * sizeof(opus_int16) ); + silk_memcpy( &psDec->outBuf[ mv_len ], pOut, psDec->frame_length * sizeof( opus_int16 ) ); + +#ifdef ENABLE_OSCE + /********************************************************/ + /* Run SILK enhancer */ + /********************************************************/ + osce_enhance_frame( osce_model, psDec, psDecCtrl, pOut, ec_tell(psRangeDec) - ec_start, arch ); +#endif + /********************************************************/ /* Update PLC state */ /********************************************************/ - silk_PLC( psDec, psDecCtrl, pOut, 0, arch ); + silk_PLC( psDec, psDecCtrl, pOut, 0, +#ifdef ENABLE_DEEP_PLC + lpcnet, +#endif + arch ); psDec->lossCnt = 0; psDec->prevSignalType = psDec->indices.signalType; @@ -97,18 +130,24 @@ opus_int silk_decode_frame( psDec->first_frame_after_reset = 0; } else { /* Handle packet loss by extrapolation */ - psDec->indices.signalType = psDec->prevSignalType; - silk_PLC( psDec, psDecCtrl, pOut, 1, arch ); + silk_PLC( psDec, psDecCtrl, pOut, 1, +#ifdef ENABLE_DEEP_PLC + lpcnet, +#endif + arch ); + +#ifdef ENABLE_OSCE + osce_reset( &psDec->osce, psDec->osce.method ); +#endif + /*************************/ + /* Update output buffer. */ + /*************************/ + celt_assert( psDec->ltp_mem_length >= psDec->frame_length ); + mv_len = psDec->ltp_mem_length - psDec->frame_length; + silk_memmove( psDec->outBuf, &psDec->outBuf[ psDec->frame_length ], mv_len * sizeof(opus_int16) ); + silk_memcpy( &psDec->outBuf[ mv_len ], pOut, psDec->frame_length * sizeof( opus_int16 ) ); } - /*************************/ - /* Update output buffer. */ - /*************************/ - celt_assert( psDec->ltp_mem_length >= psDec->frame_length ); - mv_len = psDec->ltp_mem_length - psDec->frame_length; - silk_memmove( psDec->outBuf, &psDec->outBuf[ psDec->frame_length ], mv_len * sizeof(opus_int16) ); - silk_memcpy( &psDec->outBuf[ mv_len ], pOut, psDec->frame_length * sizeof( opus_int16 ) ); - /************************************************/ /* Comfort noise generation / estimation */ /************************************************/ diff --git a/src/libopus/silk/decode_indices.c b/src/libopus/silk/decode_indices.c index da2952fb..227235c9 100644 --- a/src/libopus/silk/decode_indices.c +++ b/src/libopus/silk/decode_indices.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/decode_parameters.c b/src/libopus/silk/decode_parameters.c index 40a571b5..80f1497e 100644 --- a/src/libopus/silk/decode_parameters.c +++ b/src/libopus/silk/decode_parameters.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/decode_pitch.c b/src/libopus/silk/decode_pitch.c index 620f6a19..49f59059 100644 --- a/src/libopus/silk/decode_pitch.c +++ b/src/libopus/silk/decode_pitch.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif /*********************************************************** * Pitch analyser function diff --git a/src/libopus/silk/decode_pulses.c b/src/libopus/silk/decode_pulses.c index 872b7e73..d279820e 100644 --- a/src/libopus/silk/decode_pulses.c +++ b/src/libopus/silk/decode_pulses.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/decoder_set_fs.c b/src/libopus/silk/decoder_set_fs.c index 4550d767..3a6a47c7 100644 --- a/src/libopus/silk/decoder_set_fs.c +++ b/src/libopus/silk/decoder_set_fs.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/define.h b/src/libopus/silk/define.h index 247cb0bf..491c86f3 100644 --- a/src/libopus/silk/define.h +++ b/src/libopus/silk/define.h @@ -225,6 +225,7 @@ extern "C" /* Defines for CN generation */ #define CNG_BUF_MASK_MAX 255 /* 2^floor(log2(MAX_FRAME_LENGTH))-1 */ #define CNG_GAIN_SMTH_Q16 4634 /* 0.25^(1/4) */ +#define CNG_GAIN_SMTH_THRESHOLD_Q16 46396 /* -3 dB */ #define CNG_NLSF_SMTH_Q16 16348 /* 0.25 */ #ifdef __cplusplus diff --git a/src/libopus/silk/ecintrin.h b/src/libopus/silk/ecintrin.h new file mode 100644 index 00000000..c6cc9b24 --- /dev/null +++ b/src/libopus/silk/ecintrin.h @@ -0,0 +1 @@ +#include "../celt/ecintrin.h" diff --git a/src/libopus/silk/enc_API.c b/src/libopus/silk/enc_API.c deleted file mode 100644 index 97f37935..00000000 --- a/src/libopus/silk/enc_API.c +++ /dev/null @@ -1,576 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif -#include "define.h" -#include "API.h" -#include "control.h" -#include "typedef.h" -#include "../celt/stack_alloc.h" -#include "structs.h" -#include "tuning_parameters.h" -#ifdef FIXED_POINT -#include "fixed/main_FIX.h" -#else -#include "main_FLP.h" -#endif - -/***************************************/ -/* Read control structure from encoder */ -/***************************************/ -static opus_int silk_QueryEncoder( /* O Returns error code */ - const void *encState, /* I State */ - silk_EncControlStruct *encStatus /* O Encoder Status */ -); - -/****************************************/ -/* Encoder functions */ -/****************************************/ - -opus_int silk_Get_Encoder_Size( /* O Returns error code */ - opus_int *encSizeBytes /* O Number of bytes in SILK encoder state */ -) -{ - opus_int ret = SILK_NO_ERROR; - - *encSizeBytes = sizeof( silk_encoder ); - - return ret; -} - -/*************************/ -/* Init or Reset encoder */ -/*************************/ -opus_int silk_InitEncoder( /* O Returns error code */ - void *encState, /* I/O State */ - int arch, /* I Run-time architecture */ - silk_EncControlStruct *encStatus /* O Encoder Status */ -) -{ - silk_encoder *psEnc; - opus_int n, ret = SILK_NO_ERROR; - - psEnc = (silk_encoder *)encState; - - /* Reset encoder */ - silk_memset( psEnc, 0, sizeof( silk_encoder ) ); - for( n = 0; n < ENCODER_NUM_CHANNELS; n++ ) { - if( ret += silk_init_encoder( &psEnc->state_Fxx[ n ], arch ) ) { - celt_assert( 0 ); - } - } - - psEnc->nChannelsAPI = 1; - psEnc->nChannelsInternal = 1; - - /* Read control structure */ - if( ret += silk_QueryEncoder( encState, encStatus ) ) { - celt_assert( 0 ); - } - - return ret; -} - -/***************************************/ -/* Read control structure from encoder */ -/***************************************/ -static opus_int silk_QueryEncoder( /* O Returns error code */ - const void *encState, /* I State */ - silk_EncControlStruct *encStatus /* O Encoder Status */ -) -{ - opus_int ret = SILK_NO_ERROR; - silk_encoder_state_Fxx *state_Fxx; - silk_encoder *psEnc = (silk_encoder *)encState; - - state_Fxx = psEnc->state_Fxx; - - encStatus->nChannelsAPI = psEnc->nChannelsAPI; - encStatus->nChannelsInternal = psEnc->nChannelsInternal; - encStatus->API_sampleRate = state_Fxx[ 0 ].sCmn.API_fs_Hz; - encStatus->maxInternalSampleRate = state_Fxx[ 0 ].sCmn.maxInternal_fs_Hz; - encStatus->minInternalSampleRate = state_Fxx[ 0 ].sCmn.minInternal_fs_Hz; - encStatus->desiredInternalSampleRate = state_Fxx[ 0 ].sCmn.desiredInternal_fs_Hz; - encStatus->payloadSize_ms = state_Fxx[ 0 ].sCmn.PacketSize_ms; - encStatus->bitRate = state_Fxx[ 0 ].sCmn.TargetRate_bps; - encStatus->packetLossPercentage = state_Fxx[ 0 ].sCmn.PacketLoss_perc; - encStatus->complexity = state_Fxx[ 0 ].sCmn.Complexity; - encStatus->useInBandFEC = state_Fxx[ 0 ].sCmn.useInBandFEC; - encStatus->useDTX = state_Fxx[ 0 ].sCmn.useDTX; - encStatus->useCBR = state_Fxx[ 0 ].sCmn.useCBR; - encStatus->internalSampleRate = silk_SMULBB( state_Fxx[ 0 ].sCmn.fs_kHz, 1000 ); - encStatus->allowBandwidthSwitch = state_Fxx[ 0 ].sCmn.allow_bandwidth_switch; - encStatus->inWBmodeWithoutVariableLP = state_Fxx[ 0 ].sCmn.fs_kHz == 16 && state_Fxx[ 0 ].sCmn.sLP.mode == 0; - - return ret; -} - - -/**************************/ -/* Encode frame with Silk */ -/**************************/ -/* Note: if prefillFlag is set, the input must contain 10 ms of audio, irrespective of what */ -/* encControl->payloadSize_ms is set to */ -opus_int silk_Encode( /* O Returns error code */ - void *encState, /* I/O State */ - silk_EncControlStruct *encControl, /* I Control status */ - const opus_int16 *samplesIn, /* I Speech sample input vector */ - opus_int nSamplesIn, /* I Number of samples in input vector */ - ec_enc *psRangeEnc, /* I/O Compressor data structure */ - opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */ - const opus_int prefillFlag, /* I Flag to indicate prefilling buffers no coding */ - opus_int activity /* I Decision of Opus voice activity detector */ -) -{ - opus_int n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0; - opus_int nSamplesToBuffer, nSamplesToBufferMax, nBlocksOf10ms; - opus_int nSamplesFromInput = 0, nSamplesFromInputMax; - opus_int speech_act_thr_for_switch_Q8; - opus_int32 TargetRate_bps, MStargetRates_bps[ 2 ], channelRate_bps, LBRR_symbol, sum; - silk_encoder *psEnc = ( silk_encoder * )encState; - VARDECL( opus_int16, buf ); - opus_int transition, curr_block, tot_blocks; - SAVE_STACK; - - if (encControl->reducedDependency) - { - psEnc->state_Fxx[0].sCmn.first_frame_after_reset = 1; - psEnc->state_Fxx[1].sCmn.first_frame_after_reset = 1; - } - psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded = psEnc->state_Fxx[ 1 ].sCmn.nFramesEncoded = 0; - - /* Check values in encoder control structure */ - if( ( ret = check_control_input( encControl ) ) != 0 ) { - celt_assert( 0 ); - RESTORE_STACK; - return ret; - } - - encControl->switchReady = 0; - - if( encControl->nChannelsInternal > psEnc->nChannelsInternal ) { - /* Mono -> Stereo transition: init state of second channel and stereo state */ - ret += silk_init_encoder( &psEnc->state_Fxx[ 1 ], psEnc->state_Fxx[ 0 ].sCmn.arch ); - silk_memset( psEnc->sStereo.pred_prev_Q13, 0, sizeof( psEnc->sStereo.pred_prev_Q13 ) ); - silk_memset( psEnc->sStereo.sSide, 0, sizeof( psEnc->sStereo.sSide ) ); - psEnc->sStereo.mid_side_amp_Q0[ 0 ] = 0; - psEnc->sStereo.mid_side_amp_Q0[ 1 ] = 1; - psEnc->sStereo.mid_side_amp_Q0[ 2 ] = 0; - psEnc->sStereo.mid_side_amp_Q0[ 3 ] = 1; - psEnc->sStereo.width_prev_Q14 = 0; - psEnc->sStereo.smth_width_Q14 = SILK_FIX_CONST( 1, 14 ); - if( psEnc->nChannelsAPI == 2 ) { - silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof( silk_resampler_state_struct ) ); - silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.In_HP_State, &psEnc->state_Fxx[ 0 ].sCmn.In_HP_State, sizeof( psEnc->state_Fxx[ 1 ].sCmn.In_HP_State ) ); - } - } - - transition = (encControl->payloadSize_ms != psEnc->state_Fxx[ 0 ].sCmn.PacketSize_ms) || (psEnc->nChannelsInternal != encControl->nChannelsInternal); - - psEnc->nChannelsAPI = encControl->nChannelsAPI; - psEnc->nChannelsInternal = encControl->nChannelsInternal; - - nBlocksOf10ms = silk_DIV32( 100 * nSamplesIn, encControl->API_sampleRate ); - tot_blocks = ( nBlocksOf10ms > 1 ) ? nBlocksOf10ms >> 1 : 1; - curr_block = 0; - if( prefillFlag ) { - silk_LP_state save_LP; - /* Only accept input length of 10 ms */ - if( nBlocksOf10ms != 1 ) { - celt_assert( 0 ); - RESTORE_STACK; - return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; - } - if ( prefillFlag == 2 ) { - save_LP = psEnc->state_Fxx[ 0 ].sCmn.sLP; - /* Save the sampling rate so the bandwidth switching code can keep handling transitions. */ - save_LP.saved_fs_kHz = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz; - } - /* Reset Encoder */ - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - ret = silk_init_encoder( &psEnc->state_Fxx[ n ], psEnc->state_Fxx[ n ].sCmn.arch ); - /* Restore the variable LP state. */ - if ( prefillFlag == 2 ) { - psEnc->state_Fxx[ n ].sCmn.sLP = save_LP; - } - celt_assert( !ret ); - } - tmp_payloadSize_ms = encControl->payloadSize_ms; - encControl->payloadSize_ms = 10; - tmp_complexity = encControl->complexity; - encControl->complexity = 0; - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0; - psEnc->state_Fxx[ n ].sCmn.prefillFlag = 1; - } - } else { - /* Only accept input lengths that are a multiple of 10 ms */ - if( nBlocksOf10ms * encControl->API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0 ) { - celt_assert( 0 ); - RESTORE_STACK; - return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; - } - /* Make sure no more than one packet can be produced */ - if( 1000 * (opus_int32)nSamplesIn > encControl->payloadSize_ms * encControl->API_sampleRate ) { - celt_assert( 0 ); - RESTORE_STACK; - return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; - } - } - - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - /* Force the side channel to the same rate as the mid */ - opus_int force_fs_kHz = (n==1) ? psEnc->state_Fxx[0].sCmn.fs_kHz : 0; - if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) { - silk_assert( 0 ); - RESTORE_STACK; - return ret; - } - if( psEnc->state_Fxx[n].sCmn.first_frame_after_reset || transition ) { - for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) { - psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] = 0; - } - } - psEnc->state_Fxx[ n ].sCmn.inDTX = psEnc->state_Fxx[ n ].sCmn.useDTX; - } - celt_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz ); - - /* Input buffering/resampling and encoding */ - nSamplesToBufferMax = - 10 * nBlocksOf10ms * psEnc->state_Fxx[ 0 ].sCmn.fs_kHz; - nSamplesFromInputMax = - silk_DIV32_16( nSamplesToBufferMax * - psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, - psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 ); - ALLOC( buf, nSamplesFromInputMax, opus_int16 ); - while( 1 ) { - nSamplesToBuffer = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx; - nSamplesToBuffer = silk_min( nSamplesToBuffer, nSamplesToBufferMax ); - nSamplesFromInput = silk_DIV32_16( nSamplesToBuffer * psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 ); - /* Resample and write to buffer */ - if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 2 ) { - opus_int id = psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded; - for( n = 0; n < nSamplesFromInput; n++ ) { - buf[ n ] = samplesIn[ 2 * n ]; - } - /* Making sure to start both resamplers from the same state when switching from mono to stereo */ - if( psEnc->nPrevChannelsInternal == 1 && id==0 ) { - silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof(psEnc->state_Fxx[ 1 ].sCmn.resampler_state)); - } - - ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, - &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer; - - nSamplesToBuffer = psEnc->state_Fxx[ 1 ].sCmn.frame_length - psEnc->state_Fxx[ 1 ].sCmn.inputBufIx; - nSamplesToBuffer = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 1 ].sCmn.fs_kHz ); - for( n = 0; n < nSamplesFromInput; n++ ) { - buf[ n ] = samplesIn[ 2 * n + 1 ]; - } - ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, - &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); - - psEnc->state_Fxx[ 1 ].sCmn.inputBufIx += nSamplesToBuffer; - } else if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 1 ) { - /* Combine left and right channels before resampling */ - for( n = 0; n < nSamplesFromInput; n++ ) { - sum = samplesIn[ 2 * n ] + samplesIn[ 2 * n + 1 ]; - buf[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 ); - } - ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, - &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); - /* On the first mono frame, average the results for the two resampler states */ - if( psEnc->nPrevChannelsInternal == 2 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 ) { - ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, - &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); - for( n = 0; n < psEnc->state_Fxx[ 0 ].sCmn.frame_length; n++ ) { - psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ] = - silk_RSHIFT(psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ] - + psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx+n+2 ], 1); - } - } - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer; - } else { - celt_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 ); - silk_memcpy(buf, samplesIn, nSamplesFromInput*sizeof(opus_int16)); - ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, - &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer; - } - - samplesIn += nSamplesFromInput * encControl->nChannelsAPI; - nSamplesIn -= nSamplesFromInput; - - /* Default */ - psEnc->allowBandwidthSwitch = 0; - - /* Silk encoder */ - if( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx >= psEnc->state_Fxx[ 0 ].sCmn.frame_length ) { - /* Enough data in input buffer, so encode */ - celt_assert( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx == psEnc->state_Fxx[ 0 ].sCmn.frame_length ); - celt_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inputBufIx == psEnc->state_Fxx[ 1 ].sCmn.frame_length ); - - /* Deal with LBRR data */ - if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 && !prefillFlag ) { - /* Create space at start of payload for VAD and FEC flags */ - opus_uint8 iCDF[ 2 ] = { 0, 0 }; - iCDF[ 0 ] = 256 - silk_RSHIFT( 256, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal ); - ec_enc_icdf( psRangeEnc, 0, iCDF, 8 ); - - /* Encode any LBRR data from previous packet */ - /* Encode LBRR flags */ - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - LBRR_symbol = 0; - for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) { - LBRR_symbol |= silk_LSHIFT( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ], i ); - } - psEnc->state_Fxx[ n ].sCmn.LBRR_flag = LBRR_symbol > 0 ? 1 : 0; - if( LBRR_symbol && psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket > 1 ) { - ec_enc_icdf( psRangeEnc, LBRR_symbol - 1, silk_LBRR_flags_iCDF_ptr[ psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket - 2 ], 8 ); - } - } - - /* Code LBRR indices and excitation signals */ - for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) { - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - if( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] ) { - opus_int condCoding; - - if( encControl->nChannelsInternal == 2 && n == 0 ) { - silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ i ] ); - /* For LBRR data there's no need to code the mid-only flag if the side-channel LBRR flag is set */ - if( psEnc->state_Fxx[ 1 ].sCmn.LBRR_flags[ i ] == 0 ) { - silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ i ] ); - } - } - /* Use conditional coding if previous frame available */ - if( i > 0 && psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i - 1 ] ) { - condCoding = CODE_CONDITIONALLY; - } else { - condCoding = CODE_INDEPENDENTLY; - } - silk_encode_indices( &psEnc->state_Fxx[ n ].sCmn, psRangeEnc, i, 1, condCoding ); - silk_encode_pulses( psRangeEnc, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].signalType, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].quantOffsetType, - psEnc->state_Fxx[ n ].sCmn.pulses_LBRR[ i ], psEnc->state_Fxx[ n ].sCmn.frame_length ); - } - } - } - - /* Reset LBRR flags */ - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - silk_memset( psEnc->state_Fxx[ n ].sCmn.LBRR_flags, 0, sizeof( psEnc->state_Fxx[ n ].sCmn.LBRR_flags ) ); - } - - psEnc->nBitsUsedLBRR = ec_tell( psRangeEnc ); - } - - silk_HP_variable_cutoff( psEnc->state_Fxx ); - - /* Total target bits for packet */ - nBits = silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 ); - /* Subtract bits used for LBRR */ - if( !prefillFlag ) { - nBits -= psEnc->nBitsUsedLBRR; - } - /* Divide by number of uncoded frames left in packet */ - nBits = silk_DIV32_16( nBits, psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket ); - /* Convert to bits/second */ - if( encControl->payloadSize_ms == 10 ) { - TargetRate_bps = silk_SMULBB( nBits, 100 ); - } else { - TargetRate_bps = silk_SMULBB( nBits, 50 ); - } - /* Subtract fraction of bits in excess of target in previous frames and packets */ - TargetRate_bps -= silk_DIV32_16( silk_MUL( psEnc->nBitsExceeded, 1000 ), BITRESERVOIR_DECAY_TIME_MS ); - if( !prefillFlag && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded > 0 ) { - /* Compare actual vs target bits so far in this packet */ - opus_int32 bitsBalance = ec_tell( psRangeEnc ) - psEnc->nBitsUsedLBRR - nBits * psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded; - TargetRate_bps -= silk_DIV32_16( silk_MUL( bitsBalance, 1000 ), BITRESERVOIR_DECAY_TIME_MS ); - } - /* Never exceed input bitrate */ - TargetRate_bps = silk_LIMIT( TargetRate_bps, encControl->bitRate, 5000 ); - - /* Convert Left/Right to Mid/Side */ - if( encControl->nChannelsInternal == 2 ) { - silk_stereo_LR_to_MS( &psEnc->sStereo, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ 2 ], &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ 2 ], - psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ], &psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ], - MStargetRates_bps, TargetRate_bps, psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8, encControl->toMono, - psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, psEnc->state_Fxx[ 0 ].sCmn.frame_length ); - if( psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) { - /* Reset side channel encoder memory for first frame with side coding */ - if( psEnc->prev_decode_only_middle == 1 ) { - silk_memset( &psEnc->state_Fxx[ 1 ].sShape, 0, sizeof( psEnc->state_Fxx[ 1 ].sShape ) ); - silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sNSQ, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sNSQ ) ); - silk_memset( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15 ) ); - silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State ) ); - psEnc->state_Fxx[ 1 ].sCmn.prevLag = 100; - psEnc->state_Fxx[ 1 ].sCmn.sNSQ.lagPrev = 100; - psEnc->state_Fxx[ 1 ].sShape.LastGainIndex = 10; - psEnc->state_Fxx[ 1 ].sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY; - psEnc->state_Fxx[ 1 ].sCmn.sNSQ.prev_gain_Q16 = 65536; - psEnc->state_Fxx[ 1 ].sCmn.first_frame_after_reset = 1; - } - silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 1 ], activity ); - } else { - psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] = 0; - } - if( !prefillFlag ) { - silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] ); - if( psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) { - silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] ); - } - } - } else { - /* Buffering */ - silk_memcpy( psEnc->state_Fxx[ 0 ].sCmn.inputBuf, psEnc->sStereo.sMid, 2 * sizeof( opus_int16 ) ); - silk_memcpy( psEnc->sStereo.sMid, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.frame_length ], 2 * sizeof( opus_int16 ) ); - } - silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 0 ], activity ); - - /* Encode */ - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - opus_int maxBits, useCBR; - - /* Handling rate constraints */ - maxBits = encControl->maxBits; - if( tot_blocks == 2 && curr_block == 0 ) { - maxBits = maxBits * 3 / 5; - } else if( tot_blocks == 3 ) { - if( curr_block == 0 ) { - maxBits = maxBits * 2 / 5; - } else if( curr_block == 1 ) { - maxBits = maxBits * 3 / 4; - } - } - useCBR = encControl->useCBR && curr_block == tot_blocks - 1; - - if( encControl->nChannelsInternal == 1 ) { - channelRate_bps = TargetRate_bps; - } else { - channelRate_bps = MStargetRates_bps[ n ]; - if( n == 0 && MStargetRates_bps[ 1 ] > 0 ) { - useCBR = 0; - /* Give mid up to 1/2 of the max bits for that frame */ - maxBits -= encControl->maxBits / ( tot_blocks * 2 ); - } - } - - if( channelRate_bps > 0 ) { - opus_int condCoding; - - silk_control_SNR( &psEnc->state_Fxx[ n ].sCmn, channelRate_bps ); - - /* Use independent coding if no previous frame available */ - if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - n <= 0 ) { - condCoding = CODE_INDEPENDENTLY; - } else if( n > 0 && psEnc->prev_decode_only_middle ) { - /* If we skipped a side frame in this packet, we don't - need LTP scaling; the LTP state is well-defined. */ - condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING; - } else { - condCoding = CODE_CONDITIONALLY; - } - if( ( ret = silk_encode_frame_Fxx( &psEnc->state_Fxx[ n ], nBytesOut, psRangeEnc, condCoding, maxBits, useCBR ) ) != 0 ) { - silk_assert( 0 ); - } - } - psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0; - psEnc->state_Fxx[ n ].sCmn.inputBufIx = 0; - psEnc->state_Fxx[ n ].sCmn.nFramesEncoded++; - } - psEnc->prev_decode_only_middle = psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - 1 ]; - - /* Insert VAD and FEC flags at beginning of bitstream */ - if( *nBytesOut > 0 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket) { - flags = 0; - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) { - flags = silk_LSHIFT( flags, 1 ); - flags |= psEnc->state_Fxx[ n ].sCmn.VAD_flags[ i ]; - } - flags = silk_LSHIFT( flags, 1 ); - flags |= psEnc->state_Fxx[ n ].sCmn.LBRR_flag; - } - if( !prefillFlag ) { - ec_enc_patch_initial_bits( psRangeEnc, flags, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal ); - } - - /* Return zero bytes if all channels DTXed */ - if( psEnc->state_Fxx[ 0 ].sCmn.inDTX && ( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inDTX ) ) { - *nBytesOut = 0; - } - - psEnc->nBitsExceeded += *nBytesOut * 8; - psEnc->nBitsExceeded -= silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 ); - psEnc->nBitsExceeded = silk_LIMIT( psEnc->nBitsExceeded, 0, 10000 ); - - /* Update flag indicating if bandwidth switching is allowed */ - speech_act_thr_for_switch_Q8 = silk_SMLAWB( SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ), - SILK_FIX_CONST( ( 1 - SPEECH_ACTIVITY_DTX_THRES ) / MAX_BANDWIDTH_SWITCH_DELAY_MS, 16 + 8 ), psEnc->timeSinceSwitchAllowed_ms ); - if( psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8 < speech_act_thr_for_switch_Q8 ) { - psEnc->allowBandwidthSwitch = 1; - psEnc->timeSinceSwitchAllowed_ms = 0; - } else { - psEnc->allowBandwidthSwitch = 0; - psEnc->timeSinceSwitchAllowed_ms += encControl->payloadSize_ms; - } - } - - if( nSamplesIn == 0 ) { - break; - } - } else { - break; - } - curr_block++; - } - - psEnc->nPrevChannelsInternal = encControl->nChannelsInternal; - - encControl->allowBandwidthSwitch = psEnc->allowBandwidthSwitch; - encControl->inWBmodeWithoutVariableLP = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == 16 && psEnc->state_Fxx[ 0 ].sCmn.sLP.mode == 0; - encControl->internalSampleRate = silk_SMULBB( psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, 1000 ); - encControl->stereoWidth_Q14 = encControl->toMono ? 0 : psEnc->sStereo.smth_width_Q14; - if( prefillFlag ) { - encControl->payloadSize_ms = tmp_payloadSize_ms; - encControl->complexity = tmp_complexity; - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0; - psEnc->state_Fxx[ n ].sCmn.prefillFlag = 0; - } - } - - encControl->signalType = psEnc->state_Fxx[0].sCmn.indices.signalType; - encControl->offset = silk_Quantization_Offsets_Q10 - [ psEnc->state_Fxx[0].sCmn.indices.signalType >> 1 ] - [ psEnc->state_Fxx[0].sCmn.indices.quantOffsetType ]; - RESTORE_STACK; - return ret; -} - diff --git a/src/libopus/silk/encode_indices.c b/src/libopus/silk/encode_indices.c index 0892b3f7..1ef24423 100644 --- a/src/libopus/silk/encode_indices.c +++ b/src/libopus/silk/encode_indices.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/encode_pulses.c b/src/libopus/silk/encode_pulses.c index 4c5db41a..a753e866 100644 --- a/src/libopus/silk/encode_pulses.c +++ b/src/libopus/silk/encode_pulses.c @@ -25,12 +25,12 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" -#include "../celt/stack_alloc.h" +#include "stack_alloc.h" /*********************************************/ /* Encode quantization indices of excitation */ diff --git a/src/libopus/silk/entdec.h b/src/libopus/silk/entdec.h new file mode 100644 index 00000000..07f6c038 --- /dev/null +++ b/src/libopus/silk/entdec.h @@ -0,0 +1 @@ +#include "../celt/entdec.h" diff --git a/src/libopus/silk/entenc.h b/src/libopus/silk/entenc.h new file mode 100644 index 00000000..0ee730b3 --- /dev/null +++ b/src/libopus/silk/entenc.h @@ -0,0 +1 @@ +#include "../celt/entenc.h" diff --git a/src/libopus/silk/fixed/LTP_analysis_filter_FIX.c b/src/libopus/silk/fixed/LTP_analysis_filter_FIX.c index a14eca78..e7eaabdb 100644 --- a/src/libopus/silk/fixed/LTP_analysis_filter_FIX.c +++ b/src/libopus/silk/fixed/LTP_analysis_filter_FIX.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main_FIX.h" diff --git a/src/libopus/silk/fixed/LTP_analysis_filter_FIX.lo b/src/libopus/silk/fixed/LTP_analysis_filter_FIX.lo deleted file mode 100644 index 762ccd9e..00000000 --- a/src/libopus/silk/fixed/LTP_analysis_filter_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/LTP_analysis_filter_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/LTP_analysis_filter_FIX.o' - -# Name of the non-PIC object -non_pic_object='LTP_analysis_filter_FIX.o' - diff --git a/src/libopus/silk/fixed/LTP_analysis_filter_FIX.o b/src/libopus/silk/fixed/LTP_analysis_filter_FIX.o deleted file mode 100644 index 714ff662..00000000 Binary files a/src/libopus/silk/fixed/LTP_analysis_filter_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/LTP_scale_ctrl_FIX.c b/src/libopus/silk/fixed/LTP_scale_ctrl_FIX.c index d607134f..9b108796 100644 --- a/src/libopus/silk/fixed/LTP_scale_ctrl_FIX.c +++ b/src/libopus/silk/fixed/LTP_scale_ctrl_FIX.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main_FIX.h" @@ -42,9 +42,14 @@ void silk_LTP_scale_ctrl_FIX( if( condCoding == CODE_INDEPENDENTLY ) { /* Only scale if first frame in packet */ - round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket; - psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT( - silk_SMULWB( silk_SMULBB( round_loss, psEncCtrl->LTPredCodGain_Q7 ), SILK_FIX_CONST( 0.1, 9 ) ), 0, 2 ); + round_loss = psEnc->sCmn.PacketLoss_perc * psEnc->sCmn.nFramesPerPacket; + if ( psEnc->sCmn.LBRR_flag ) { + /* LBRR reduces the effective loss. In practice, it does not square the loss because + losses aren't independent, but that still seems to work best. We also never go below 2%. */ + round_loss = 2 + silk_SMULBB( round_loss, round_loss ) / 100; + } + psEnc->sCmn.indices.LTP_scaleIndex = silk_SMULBB( psEncCtrl->LTPredCodGain_Q7, round_loss ) > silk_log2lin( 128*7 + 2900-psEnc->sCmn.SNR_dB_Q7 ); + psEnc->sCmn.indices.LTP_scaleIndex += silk_SMULBB( psEncCtrl->LTPredCodGain_Q7, round_loss ) > silk_log2lin( 128*7 + 3900-psEnc->sCmn.SNR_dB_Q7 ); } else { /* Default is minimum scaling */ psEnc->sCmn.indices.LTP_scaleIndex = 0; diff --git a/src/libopus/silk/fixed/LTP_scale_ctrl_FIX.lo b/src/libopus/silk/fixed/LTP_scale_ctrl_FIX.lo deleted file mode 100644 index 24d93f5b..00000000 --- a/src/libopus/silk/fixed/LTP_scale_ctrl_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/LTP_scale_ctrl_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/LTP_scale_ctrl_FIX.o' - -# Name of the non-PIC object -non_pic_object='LTP_scale_ctrl_FIX.o' - diff --git a/src/libopus/silk/fixed/LTP_scale_ctrl_FIX.o b/src/libopus/silk/fixed/LTP_scale_ctrl_FIX.o deleted file mode 100644 index 06f6521d..00000000 Binary files a/src/libopus/silk/fixed/LTP_scale_ctrl_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/PLC.h b/src/libopus/silk/fixed/PLC.h new file mode 100644 index 00000000..7b741074 --- /dev/null +++ b/src/libopus/silk/fixed/PLC.h @@ -0,0 +1 @@ +#include "../PLC.h" diff --git a/src/libopus/silk/fixed/SigProc_FIX.h b/src/libopus/silk/fixed/SigProc_FIX.h new file mode 100644 index 00000000..54611bd6 --- /dev/null +++ b/src/libopus/silk/fixed/SigProc_FIX.h @@ -0,0 +1 @@ +#include "../SigProc_FIX.h" diff --git a/src/libopus/silk/fixed/apply_sine_window_FIX.c b/src/libopus/silk/fixed/apply_sine_window_FIX.c index f5bb4544..3349213c 100644 --- a/src/libopus/silk/fixed/apply_sine_window_FIX.c +++ b/src/libopus/silk/fixed/apply_sine_window_FIX.c @@ -25,11 +25,11 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif -#include "../SigProc_FIX.h" +#include "SigProc_FIX.h" /* Apply sine window to signal vector. */ /* Window types: */ diff --git a/src/libopus/silk/fixed/apply_sine_window_FIX.lo b/src/libopus/silk/fixed/apply_sine_window_FIX.lo deleted file mode 100644 index 0228ba81..00000000 --- a/src/libopus/silk/fixed/apply_sine_window_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/apply_sine_window_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/apply_sine_window_FIX.o' - -# Name of the non-PIC object -non_pic_object='apply_sine_window_FIX.o' - diff --git a/src/libopus/silk/fixed/apply_sine_window_FIX.o b/src/libopus/silk/fixed/apply_sine_window_FIX.o deleted file mode 100644 index fdbd8fc6..00000000 Binary files a/src/libopus/silk/fixed/apply_sine_window_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/autocorr_FIX.c b/src/libopus/silk/fixed/autocorr_FIX.c index 5ed29cd1..fe7a800f 100644 --- a/src/libopus/silk/fixed/autocorr_FIX.c +++ b/src/libopus/silk/fixed/autocorr_FIX.c @@ -25,12 +25,12 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif -#include "../SigProc_FIX.h" -#include "../../celt/celt_lpc.h" +#include "SigProc_FIX.h" +#include "celt_lpc.h" /* Compute autocorrelation */ void silk_autocorr( diff --git a/src/libopus/silk/fixed/autocorr_FIX.lo b/src/libopus/silk/fixed/autocorr_FIX.lo deleted file mode 100644 index b0ef65da..00000000 --- a/src/libopus/silk/fixed/autocorr_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/autocorr_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/autocorr_FIX.o' - -# Name of the non-PIC object -non_pic_object='autocorr_FIX.o' - diff --git a/src/libopus/silk/fixed/autocorr_FIX.o b/src/libopus/silk/fixed/autocorr_FIX.o deleted file mode 100644 index 9d4cbba4..00000000 Binary files a/src/libopus/silk/fixed/autocorr_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/burg_modified_FIX.c b/src/libopus/silk/fixed/burg_modified_FIX.c index b4a31d60..745e3f9f 100644 --- a/src/libopus/silk/fixed/burg_modified_FIX.c +++ b/src/libopus/silk/fixed/burg_modified_FIX.c @@ -25,14 +25,14 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif -#include "../SigProc_FIX.h" -#include "../define.h" -#include "../tuning_parameters.h" -#include "../../celt/pitch.h" +#include "SigProc_FIX.h" +#include "define.h" +#include "tuning_parameters.h" +#include "pitch.h" #define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */ @@ -68,7 +68,7 @@ void silk_burg_modified_c( celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE ); /* Compute autocorrelations, added over subframes */ - C0_64 = silk_inner_prod16_aligned_64( x, x, subfr_length*nb_subfr, arch ); + C0_64 = silk_inner_prod16( x, x, subfr_length*nb_subfr, arch ); lz = silk_CLZ64(C0_64); rshifts = 32 + 1 + N_BITS_HEAD_ROOM - lz; if (rshifts > MAX_RSHIFTS) rshifts = MAX_RSHIFTS; @@ -87,7 +87,7 @@ void silk_burg_modified_c( x_ptr = x + s * subfr_length; for( n = 1; n < D + 1; n++ ) { C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64( - silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts ); + silk_inner_prod16( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts ); } } } else { @@ -150,7 +150,7 @@ void silk_burg_modified_c( C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */ C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */ Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */ - /* We sometimes have get overflows in the multiplications (even beyond +/- 2^32), + /* We sometimes get overflows in the multiplications (even beyond +/- 2^32), but they cancel each other and the real result seems to always fit in a 32-bit signed integer. This was determined experimentally, not theoretically (unfortunately). */ tmp1 = silk_MLA_ovflw( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */ @@ -253,7 +253,7 @@ void silk_burg_modified_c( if( rshifts > 0 ) { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; - C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts ); + C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16( x_ptr, x_ptr, D, arch ), rshifts ); } } else { for( s = 0; s < nb_subfr; s++ ) { diff --git a/src/libopus/silk/fixed/burg_modified_FIX.lo b/src/libopus/silk/fixed/burg_modified_FIX.lo deleted file mode 100644 index 05cdcd59..00000000 --- a/src/libopus/silk/fixed/burg_modified_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/burg_modified_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/burg_modified_FIX.o' - -# Name of the non-PIC object -non_pic_object='burg_modified_FIX.o' - diff --git a/src/libopus/silk/fixed/burg_modified_FIX.o b/src/libopus/silk/fixed/burg_modified_FIX.o deleted file mode 100644 index aa1a769e..00000000 Binary files a/src/libopus/silk/fixed/burg_modified_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/celt_lpc.h b/src/libopus/silk/fixed/celt_lpc.h new file mode 100644 index 00000000..47c4b7d3 --- /dev/null +++ b/src/libopus/silk/fixed/celt_lpc.h @@ -0,0 +1 @@ +#include "../../celt/celt_lpc.h" diff --git a/src/libopus/silk/fixed/config.h b/src/libopus/silk/fixed/config.h new file mode 100644 index 00000000..283c0577 --- /dev/null +++ b/src/libopus/silk/fixed/config.h @@ -0,0 +1 @@ +#include "../../include/config.h" diff --git a/src/libopus/silk/fixed/control.h b/src/libopus/silk/fixed/control.h new file mode 100644 index 00000000..090fb99c --- /dev/null +++ b/src/libopus/silk/fixed/control.h @@ -0,0 +1 @@ +#include "../control.h" diff --git a/src/libopus/silk/fixed/corrMatrix_FIX.c b/src/libopus/silk/fixed/corrMatrix_FIX.c index 2709a38f..28c37dac 100644 --- a/src/libopus/silk/fixed/corrMatrix_FIX.c +++ b/src/libopus/silk/fixed/corrMatrix_FIX.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif /********************************************************************** * Correlation Matrix Computations for LS estimate. diff --git a/src/libopus/silk/fixed/corrMatrix_FIX.lo b/src/libopus/silk/fixed/corrMatrix_FIX.lo deleted file mode 100644 index be8b343e..00000000 --- a/src/libopus/silk/fixed/corrMatrix_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/corrMatrix_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/corrMatrix_FIX.o' - -# Name of the non-PIC object -non_pic_object='corrMatrix_FIX.o' - diff --git a/src/libopus/silk/fixed/corrMatrix_FIX.o b/src/libopus/silk/fixed/corrMatrix_FIX.o deleted file mode 100644 index 9bdb7b93..00000000 Binary files a/src/libopus/silk/fixed/corrMatrix_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/debug.h b/src/libopus/silk/fixed/debug.h new file mode 100644 index 00000000..4b4c44e0 --- /dev/null +++ b/src/libopus/silk/fixed/debug.h @@ -0,0 +1 @@ +#include "../debug.h" diff --git a/src/libopus/silk/fixed/define.h b/src/libopus/silk/fixed/define.h new file mode 100644 index 00000000..ce1ede27 --- /dev/null +++ b/src/libopus/silk/fixed/define.h @@ -0,0 +1 @@ +#include "../define.h" diff --git a/src/libopus/silk/fixed/encode_frame_FIX.c b/src/libopus/silk/fixed/encode_frame_FIX.c deleted file mode 100644 index a121d0a1..00000000 --- a/src/libopus/silk/fixed/encode_frame_FIX.c +++ /dev/null @@ -1,448 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif - -#include -#include "main_FIX.h" -#include "../../celt/stack_alloc.h" -#include "../tuning_parameters.h" - -/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */ -static OPUS_INLINE void silk_LBRR_encode_FIX( - silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ - silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ - const opus_int16 x16[], /* I Input signal */ - opus_int condCoding /* I The type of conditional coding used so far for this frame */ -); - -void silk_encode_do_VAD_FIX( - silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ - opus_int activity /* I Decision of Opus voice activity detector */ -) -{ - const opus_int activity_threshold = SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ); - - /****************************/ - /* Voice Activity Detection */ - /****************************/ - silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch ); - /* If Opus VAD is inactive and Silk VAD is active: lower Silk VAD to just under the threshold */ - if( activity == VAD_NO_ACTIVITY && psEnc->sCmn.speech_activity_Q8 >= activity_threshold ) { - psEnc->sCmn.speech_activity_Q8 = activity_threshold - 1; - } - - /**************************************************/ - /* Convert speech activity into VAD and DTX flags */ - /**************************************************/ - if( psEnc->sCmn.speech_activity_Q8 < activity_threshold ) { - psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY; - psEnc->sCmn.noSpeechCounter++; - if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) { - psEnc->sCmn.inDTX = 0; - } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) { - psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX; - psEnc->sCmn.inDTX = 0; - } - psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0; - } else { - psEnc->sCmn.noSpeechCounter = 0; - psEnc->sCmn.inDTX = 0; - psEnc->sCmn.indices.signalType = TYPE_UNVOICED; - psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1; - } -} - -/****************/ -/* Encode frame */ -/****************/ -opus_int silk_encode_frame_FIX( - silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ - opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */ - ec_enc *psRangeEnc, /* I/O compressor data structure */ - opus_int condCoding, /* I The type of conditional coding to use */ - opus_int maxBits, /* I If > 0: maximum number of output bits */ - opus_int useCBR /* I Flag to force constant-bitrate operation */ -) -{ - silk_encoder_control_FIX sEncCtrl; - opus_int i, iter, maxIter, found_upper, found_lower, ret = 0; - opus_int16 *x_frame; - ec_enc sRangeEnc_copy, sRangeEnc_copy2; - silk_nsq_state sNSQ_copy, sNSQ_copy2; - opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper; - opus_int32 gainsID, gainsID_lower, gainsID_upper; - opus_int16 gainMult_Q8; - opus_int16 ec_prevLagIndex_copy; - opus_int ec_prevSignalType_copy; - opus_int8 LastGainIndex_copy2; - opus_int gain_lock[ MAX_NB_SUBFR ] = {0}; - opus_int16 best_gain_mult[ MAX_NB_SUBFR ]; - opus_int best_sum[ MAX_NB_SUBFR ]; - SAVE_STACK; - - /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */ - LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0; - - psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3; - - /**************************************************************/ - /* Set up Input Pointers, and insert frame in input buffer */ - /*************************************************************/ - /* start of frame to encode */ - x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; - - /***************************************/ - /* Ensure smooth bandwidth transitions */ - /***************************************/ - silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length ); - - /*******************************************/ - /* Copy new frame to front of input buffer */ - /*******************************************/ - silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) ); - - if( !psEnc->sCmn.prefillFlag ) { - VARDECL( opus_int16, res_pitch ); - VARDECL( opus_uint8, ec_buf_copy ); - opus_int16 *res_pitch_frame; - - ALLOC( res_pitch, - psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length - + psEnc->sCmn.ltp_mem_length, opus_int16 ); - /* start of pitch LPC residual frame */ - res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; - - /*****************************************/ - /* Find pitch lags, initial LPC analysis */ - /*****************************************/ - silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame - psEnc->sCmn.ltp_mem_length, psEnc->sCmn.arch ); - - /************************/ - /* Noise shape analysis */ - /************************/ - silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, psEnc->sCmn.arch ); - - /***************************************************/ - /* Find linear prediction coefficients (LPC + LTP) */ - /***************************************************/ - silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding ); - - /****************************************/ - /* Process gains */ - /****************************************/ - silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding ); - - /****************************************/ - /* Low Bitrate Redundant Encoding */ - /****************************************/ - silk_LBRR_encode_FIX( psEnc, &sEncCtrl, x_frame, condCoding ); - - /* Loop over quantizer and entropy coding to control bitrate */ - maxIter = 6; - gainMult_Q8 = SILK_FIX_CONST( 1, 8 ); - found_lower = 0; - found_upper = 0; - gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); - gainsID_lower = -1; - gainsID_upper = -1; - /* Copy part of the input state */ - silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) ); - silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); - seed_copy = psEnc->sCmn.indices.Seed; - ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; - ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; - ALLOC( ec_buf_copy, 1275, opus_uint8 ); - for( iter = 0; ; iter++ ) { - if( gainsID == gainsID_lower ) { - nBits = nBits_lower; - } else if( gainsID == gainsID_upper ) { - nBits = nBits_upper; - } else { - /* Restore part of the input state */ - if( iter > 0 ) { - silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) ); - silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) ); - psEnc->sCmn.indices.Seed = seed_copy; - psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; - psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; - } - - /*****************************************/ - /* Noise shaping quantization */ - /*****************************************/ - if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { - silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses, - sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14, - sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14, - psEnc->sCmn.arch ); - } else { - silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses, - sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14, - sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14, - psEnc->sCmn.arch); - } - - if ( iter == maxIter && !found_lower ) { - silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); - } - - /****************************************/ - /* Encode Parameters */ - /****************************************/ - silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); - - /****************************************/ - /* Encode Excitation Signal */ - /****************************************/ - silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, - psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); - - nBits = ec_tell( psRangeEnc ); - - /* If we still bust after the last iteration, do some damage control. */ - if ( iter == maxIter && !found_lower && nBits > maxBits ) { - silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); - - /* Keep gains the same as the last frame. */ - psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; - for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - psEnc->sCmn.indices.GainsIndices[ i ] = 4; - } - if (condCoding != CODE_CONDITIONALLY) { - psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev; - } - psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; - psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; - /* Clear all pulses. */ - for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) { - psEnc->sCmn.pulses[ i ] = 0; - } - - silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); - - silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, - psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); - - nBits = ec_tell( psRangeEnc ); - } - - if( useCBR == 0 && iter == 0 && nBits <= maxBits ) { - break; - } - } - - if( iter == maxIter ) { - if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) { - /* Restore output state from earlier iteration that did meet the bitrate budget */ - silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); - celt_assert( sRangeEnc_copy2.offs <= 1275 ); - silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs ); - silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) ); - psEnc->sShape.LastGainIndex = LastGainIndex_copy2; - } - break; - } - - if( nBits > maxBits ) { - if( found_lower == 0 && iter >= 2 ) { - /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */ - sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 ); - found_upper = 0; - gainsID_upper = -1; - } else { - found_upper = 1; - nBits_upper = nBits; - gainMult_upper = gainMult_Q8; - gainsID_upper = gainsID; - } - } else if( nBits < maxBits - 5 ) { - found_lower = 1; - nBits_lower = nBits; - gainMult_lower = gainMult_Q8; - if( gainsID != gainsID_lower ) { - gainsID_lower = gainsID; - /* Copy part of the output state */ - silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); - celt_assert( psRangeEnc->offs <= 1275 ); - silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); - silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); - LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; - } - } else { - /* Within 5 bits of budget: close enough */ - break; - } - - if ( !found_lower && nBits > maxBits ) { - int j; - for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - int sum=0; - for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) { - sum += abs( psEnc->sCmn.pulses[j] ); - } - if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) { - best_sum[i] = sum; - best_gain_mult[i] = gainMult_Q8; - } else { - gain_lock[i] = 1; - } - } - } - if( ( found_lower & found_upper ) == 0 ) { - /* Adjust gain according to high-rate rate/distortion curve */ - if( nBits > maxBits ) { - if (gainMult_Q8 < 16384) { - gainMult_Q8 *= 2; - } else { - gainMult_Q8 = 32767; - } - } else { - opus_int32 gain_factor_Q16; - gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) ); - gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 ); - } - - } else { - /* Adjust gain by interpolating */ - gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower ); - /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */ - if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) { - gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ); - } else - if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) { - gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ); - } - } - - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - opus_int16 tmp; - if ( gain_lock[i] ) { - tmp = best_gain_mult[i]; - } else { - tmp = gainMult_Q8; - } - sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 ); - } - - /* Quantize gains */ - psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; - silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16, - &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); - - /* Unique identifier of gains vector */ - gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); - } - } - - /* Update input buffer */ - silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], - ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) ); - - /* Exit without entropy coding */ - if( psEnc->sCmn.prefillFlag ) { - /* No payload */ - *pnBytesOut = 0; - RESTORE_STACK; - return ret; - } - - /* Parameters needed for next frame */ - psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ]; - psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType; - - /****************************************/ - /* Finalize payload */ - /****************************************/ - psEnc->sCmn.first_frame_after_reset = 0; - /* Payload size */ - *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 ); - - RESTORE_STACK; - return ret; -} - -/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */ -static OPUS_INLINE void silk_LBRR_encode_FIX( - silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ - silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ - const opus_int16 x16[], /* I Input signal */ - opus_int condCoding /* I The type of conditional coding used so far for this frame */ -) -{ - opus_int32 TempGains_Q16[ MAX_NB_SUBFR ]; - SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ]; - silk_nsq_state sNSQ_LBRR; - - /*******************************************/ - /* Control use of inband LBRR */ - /*******************************************/ - if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { - psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1; - - /* Copy noise shaping quantizer state and quantization indices from regular encoding */ - silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); - silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) ); - - /* Save original gains */ - silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); - - if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) { - /* First frame in packet or previous frame not LBRR coded */ - psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; - - /* Increase Gains to get target LBRR rate */ - psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases; - psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 ); - } - - /* Decode to get gains in sync with decoder */ - /* Overwrite unquantized gains with quantized gains */ - silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices, - &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); - - /*****************************************/ - /* Noise shaping quantization */ - /*****************************************/ - if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { - silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16, - psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, - psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, - psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch ); - } else { - silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16, - psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, - psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, - psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch ); - } - - /* Restore original gains */ - silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); - } -} diff --git a/src/libopus/silk/fixed/encode_frame_FIX.lo b/src/libopus/silk/fixed/encode_frame_FIX.lo deleted file mode 100644 index 1c4a00ae..00000000 --- a/src/libopus/silk/fixed/encode_frame_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/encode_frame_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/encode_frame_FIX.o' - -# Name of the non-PIC object -non_pic_object='encode_frame_FIX.o' - diff --git a/src/libopus/silk/fixed/encode_frame_FIX.o b/src/libopus/silk/fixed/encode_frame_FIX.o deleted file mode 100644 index d9ef799f..00000000 Binary files a/src/libopus/silk/fixed/encode_frame_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/entdec.h b/src/libopus/silk/fixed/entdec.h new file mode 100644 index 00000000..d3c6484c --- /dev/null +++ b/src/libopus/silk/fixed/entdec.h @@ -0,0 +1 @@ +#include "../../celt/entdec.h" diff --git a/src/libopus/silk/fixed/entenc.h b/src/libopus/silk/fixed/entenc.h new file mode 100644 index 00000000..13312cda --- /dev/null +++ b/src/libopus/silk/fixed/entenc.h @@ -0,0 +1 @@ +#include "../../celt/entenc.h" diff --git a/src/libopus/silk/fixed/find_LPC_FIX.c b/src/libopus/silk/fixed/find_LPC_FIX.c index feb4330f..e54940d4 100644 --- a/src/libopus/silk/fixed/find_LPC_FIX.c +++ b/src/libopus/silk/fixed/find_LPC_FIX.c @@ -25,13 +25,13 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main_FIX.h" -#include "../../celt/stack_alloc.h" -#include "../tuning_parameters.h" +#include "stack_alloc.h" +#include "tuning_parameters.h" /* Finds LPC vector from correlations, and converts to NLSF */ void silk_find_LPC_FIX( diff --git a/src/libopus/silk/fixed/find_LPC_FIX.lo b/src/libopus/silk/fixed/find_LPC_FIX.lo deleted file mode 100644 index f668a4f0..00000000 --- a/src/libopus/silk/fixed/find_LPC_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/find_LPC_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/find_LPC_FIX.o' - -# Name of the non-PIC object -non_pic_object='find_LPC_FIX.o' - diff --git a/src/libopus/silk/fixed/find_LPC_FIX.o b/src/libopus/silk/fixed/find_LPC_FIX.o deleted file mode 100644 index d55f49ef..00000000 Binary files a/src/libopus/silk/fixed/find_LPC_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/find_LTP_FIX.c b/src/libopus/silk/fixed/find_LTP_FIX.c index 7a8143f5..70961b0b 100644 --- a/src/libopus/silk/fixed/find_LTP_FIX.c +++ b/src/libopus/silk/fixed/find_LTP_FIX.c @@ -25,12 +25,12 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main_FIX.h" -#include "../tuning_parameters.h" +#include "tuning_parameters.h" void silk_find_LTP_FIX( opus_int32 XXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Correlation matrix */ diff --git a/src/libopus/silk/fixed/find_LTP_FIX.lo b/src/libopus/silk/fixed/find_LTP_FIX.lo deleted file mode 100644 index 9bf636a0..00000000 --- a/src/libopus/silk/fixed/find_LTP_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/find_LTP_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/find_LTP_FIX.o' - -# Name of the non-PIC object -non_pic_object='find_LTP_FIX.o' - diff --git a/src/libopus/silk/fixed/find_LTP_FIX.o b/src/libopus/silk/fixed/find_LTP_FIX.o deleted file mode 100644 index c81c0f68..00000000 Binary files a/src/libopus/silk/fixed/find_LTP_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/find_pitch_lags_FIX.c b/src/libopus/silk/fixed/find_pitch_lags_FIX.c deleted file mode 100644 index 7d9de29f..00000000 --- a/src/libopus/silk/fixed/find_pitch_lags_FIX.c +++ /dev/null @@ -1,143 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif - -#include "main_FIX.h" -#include "../../celt/stack_alloc.h" -#include "../tuning_parameters.h" - -/* Find pitch lags */ -void silk_find_pitch_lags_FIX( - silk_encoder_state_FIX *psEnc, /* I/O encoder state */ - silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ - opus_int16 res[], /* O residual */ - const opus_int16 x[], /* I Speech signal */ - int arch /* I Run-time architecture */ -) -{ - opus_int buf_len, i, scale; - opus_int32 thrhld_Q13, res_nrg; - const opus_int16 *x_ptr; - VARDECL( opus_int16, Wsig ); - opus_int16 *Wsig_ptr; - opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ]; - opus_int16 rc_Q15[ MAX_FIND_PITCH_LPC_ORDER ]; - opus_int32 A_Q24[ MAX_FIND_PITCH_LPC_ORDER ]; - opus_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ]; - SAVE_STACK; - - /******************************************/ - /* Set up buffer lengths etc based on Fs */ - /******************************************/ - buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length; - - /* Safety check */ - celt_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length ); - - /*************************************/ - /* Estimate LPC AR coefficients */ - /*************************************/ - - /* Calculate windowed signal */ - - ALLOC( Wsig, psEnc->sCmn.pitch_LPC_win_length, opus_int16 ); - - /* First LA_LTP samples */ - x_ptr = x + buf_len - psEnc->sCmn.pitch_LPC_win_length; - Wsig_ptr = Wsig; - silk_apply_sine_window( Wsig_ptr, x_ptr, 1, psEnc->sCmn.la_pitch ); - - /* Middle un - windowed samples */ - Wsig_ptr += psEnc->sCmn.la_pitch; - x_ptr += psEnc->sCmn.la_pitch; - silk_memcpy( Wsig_ptr, x_ptr, ( psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( opus_int16 ) ); - - /* Last LA_LTP samples */ - Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ); - x_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ); - silk_apply_sine_window( Wsig_ptr, x_ptr, 2, psEnc->sCmn.la_pitch ); - - /* Calculate autocorrelation sequence */ - silk_autocorr( auto_corr, &scale, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1, arch ); - - /* Add white noise, as fraction of energy */ - auto_corr[ 0 ] = silk_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ) + 1; - - /* Calculate the reflection coefficients using schur */ - res_nrg = silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder ); - - /* Prediction gain */ - psEncCtrl->predGain_Q16 = silk_DIV32_varQ( auto_corr[ 0 ], silk_max_int( res_nrg, 1 ), 16 ); - - /* Convert reflection coefficients to prediction coefficients */ - silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder ); - - /* Convert From 32 bit Q24 to 16 bit Q12 coefs */ - for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) { - A_Q12[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT( A_Q24[ i ], 12 ) ); - } - - /* Do BWE */ - silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWIDTH_EXPANSION, 16 ) ); - - /*****************************************/ - /* LPC analysis filtering */ - /*****************************************/ - silk_LPC_analysis_filter( res, x, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder, psEnc->sCmn.arch ); - - if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) { - /* Threshold for pitch estimator */ - thrhld_Q13 = SILK_FIX_CONST( 0.6, 13 ); - thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.004, 13 ), psEnc->sCmn.pitchEstimationLPCOrder ); - thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 21 ), psEnc->sCmn.speech_activity_Q8 ); - thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.15, 13 ), silk_RSHIFT( psEnc->sCmn.prevSignalType, 1 ) ); - thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 14 ), psEnc->sCmn.input_tilt_Q15 ); - thrhld_Q13 = silk_SAT16( thrhld_Q13 ); - - /*****************************************/ - /* Call pitch estimator */ - /*****************************************/ - if( silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex, - &psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16, - (opus_int)thrhld_Q13, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr, - psEnc->sCmn.arch) == 0 ) - { - psEnc->sCmn.indices.signalType = TYPE_VOICED; - } else { - psEnc->sCmn.indices.signalType = TYPE_UNVOICED; - } - } else { - silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) ); - psEnc->sCmn.indices.lagIndex = 0; - psEnc->sCmn.indices.contourIndex = 0; - psEnc->LTPCorr_Q15 = 0; - } - RESTORE_STACK; -} diff --git a/src/libopus/silk/fixed/find_pitch_lags_FIX.lo b/src/libopus/silk/fixed/find_pitch_lags_FIX.lo deleted file mode 100644 index 227482c9..00000000 --- a/src/libopus/silk/fixed/find_pitch_lags_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/find_pitch_lags_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/find_pitch_lags_FIX.o' - -# Name of the non-PIC object -non_pic_object='find_pitch_lags_FIX.o' - diff --git a/src/libopus/silk/fixed/find_pitch_lags_FIX.o b/src/libopus/silk/fixed/find_pitch_lags_FIX.o deleted file mode 100644 index 9d37442e..00000000 Binary files a/src/libopus/silk/fixed/find_pitch_lags_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/find_pred_coefs_FIX.c b/src/libopus/silk/fixed/find_pred_coefs_FIX.c index 7e59eefe..8be54322 100644 --- a/src/libopus/silk/fixed/find_pred_coefs_FIX.c +++ b/src/libopus/silk/fixed/find_pred_coefs_FIX.c @@ -25,12 +25,12 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main_FIX.h" -#include "../../celt/stack_alloc.h" +#include "stack_alloc.h" void silk_find_pred_coefs_FIX( silk_encoder_state_FIX *psEnc, /* I/O encoder state */ @@ -42,7 +42,8 @@ void silk_find_pred_coefs_FIX( { opus_int i; opus_int32 invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ]; - opus_int16 NLSF_Q15[ MAX_LPC_ORDER ]; + /* Set to NLSF_Q15 to zero so we don't copy junk to the state. */ + opus_int16 NLSF_Q15[ MAX_LPC_ORDER ]={0}; const opus_int16 *x_ptr; opus_int16 *x_pre_ptr; VARDECL( opus_int16, LPC_in_pre ); diff --git a/src/libopus/silk/fixed/find_pred_coefs_FIX.lo b/src/libopus/silk/fixed/find_pred_coefs_FIX.lo deleted file mode 100644 index 330842e2..00000000 --- a/src/libopus/silk/fixed/find_pred_coefs_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/find_pred_coefs_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/find_pred_coefs_FIX.o' - -# Name of the non-PIC object -non_pic_object='find_pred_coefs_FIX.o' - diff --git a/src/libopus/silk/fixed/find_pred_coefs_FIX.o b/src/libopus/silk/fixed/find_pred_coefs_FIX.o deleted file mode 100644 index e3e2d061..00000000 Binary files a/src/libopus/silk/fixed/find_pred_coefs_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/k2a_FIX.c b/src/libopus/silk/fixed/k2a_FIX.c index a6fd0b15..12708681 100644 --- a/src/libopus/silk/fixed/k2a_FIX.c +++ b/src/libopus/silk/fixed/k2a_FIX.c @@ -25,11 +25,11 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif -#include "../SigProc_FIX.h" +#include "SigProc_FIX.h" /* Step up function, converts reflection coefficients to prediction coefficients */ void silk_k2a( diff --git a/src/libopus/silk/fixed/k2a_FIX.lo b/src/libopus/silk/fixed/k2a_FIX.lo deleted file mode 100644 index 7a39cd6f..00000000 --- a/src/libopus/silk/fixed/k2a_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/k2a_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/k2a_FIX.o' - -# Name of the non-PIC object -non_pic_object='k2a_FIX.o' - diff --git a/src/libopus/silk/fixed/k2a_FIX.o b/src/libopus/silk/fixed/k2a_FIX.o deleted file mode 100644 index b3c43fc3..00000000 Binary files a/src/libopus/silk/fixed/k2a_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/k2a_Q16_FIX.c b/src/libopus/silk/fixed/k2a_Q16_FIX.c index 357a3fe2..dbb6f0e2 100644 --- a/src/libopus/silk/fixed/k2a_Q16_FIX.c +++ b/src/libopus/silk/fixed/k2a_Q16_FIX.c @@ -25,11 +25,11 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif -#include "../SigProc_FIX.h" +#include "SigProc_FIX.h" /* Step up function, converts reflection coefficients to prediction coefficients */ void silk_k2a_Q16( diff --git a/src/libopus/silk/fixed/k2a_Q16_FIX.lo b/src/libopus/silk/fixed/k2a_Q16_FIX.lo deleted file mode 100644 index 59a6439f..00000000 --- a/src/libopus/silk/fixed/k2a_Q16_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/k2a_Q16_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/k2a_Q16_FIX.o' - -# Name of the non-PIC object -non_pic_object='k2a_Q16_FIX.o' - diff --git a/src/libopus/silk/fixed/k2a_Q16_FIX.o b/src/libopus/silk/fixed/k2a_Q16_FIX.o deleted file mode 100644 index 23dfe4e0..00000000 Binary files a/src/libopus/silk/fixed/k2a_Q16_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/main.h b/src/libopus/silk/fixed/main.h new file mode 100644 index 00000000..44f40ec3 --- /dev/null +++ b/src/libopus/silk/fixed/main.h @@ -0,0 +1 @@ +#include "../main.h" diff --git a/src/libopus/silk/fixed/main_FIX.h b/src/libopus/silk/fixed/main_FIX.h index 27d28663..6d2112e5 100644 --- a/src/libopus/silk/fixed/main_FIX.h +++ b/src/libopus/silk/fixed/main_FIX.h @@ -28,13 +28,13 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef SILK_MAIN_FIX_H #define SILK_MAIN_FIX_H -#include "../SigProc_FIX.h" +#include "SigProc_FIX.h" #include "structs_FIX.h" -#include "../control.h" -#include "../main.h" -#include "../PLC.h" -#include "../debug.h" -#include "../../celt/entenc.h" +#include "control.h" +#include "main.h" +#include "PLC.h" +#include "debug.h" +#include "entenc.h" #if ((defined(OPUS_ARM_ASM) && defined(FIXED_POINT)) \ || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)) diff --git a/src/libopus/silk/fixed/noise_shape_analysis_FIX.c b/src/libopus/silk/fixed/noise_shape_analysis_FIX.c deleted file mode 100644 index 6714e705..00000000 --- a/src/libopus/silk/fixed/noise_shape_analysis_FIX.c +++ /dev/null @@ -1,407 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif - -#include "main_FIX.h" -#include "../../celt/stack_alloc.h" -#include "../tuning_parameters.h" - -/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */ -/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */ -/* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */ -/* coefficient in an array of coefficients, for monic filters. */ -static OPUS_INLINE opus_int32 warped_gain( /* gain in Q16*/ - const opus_int32 *coefs_Q24, - opus_int lambda_Q16, - opus_int order -) { - opus_int i; - opus_int32 gain_Q24; - - lambda_Q16 = -lambda_Q16; - gain_Q24 = coefs_Q24[ order - 1 ]; - for( i = order - 2; i >= 0; i-- ) { - gain_Q24 = silk_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 ); - } - gain_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 ); - return silk_INVERSE32_varQ( gain_Q24, 40 ); -} - -/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */ -/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */ -static OPUS_INLINE void limit_warped_coefs( - opus_int32 *coefs_Q24, - opus_int lambda_Q16, - opus_int32 limit_Q24, - opus_int order -) { - opus_int i, iter, ind = 0; - opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_Q16; - opus_int32 nom_Q16, den_Q24; - opus_int32 limit_Q20, maxabs_Q20; - - /* Convert to monic coefficients */ - lambda_Q16 = -lambda_Q16; - for( i = order - 1; i > 0; i-- ) { - coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 ); - } - lambda_Q16 = -lambda_Q16; - nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 ); - den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 ); - gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 ); - for( i = 0; i < order; i++ ) { - coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] ); - } - limit_Q20 = silk_RSHIFT(limit_Q24, 4); - for( iter = 0; iter < 10; iter++ ) { - /* Find maximum absolute value */ - maxabs_Q24 = -1; - for( i = 0; i < order; i++ ) { - tmp = silk_abs_int32( coefs_Q24[ i ] ); - if( tmp > maxabs_Q24 ) { - maxabs_Q24 = tmp; - ind = i; - } - } - /* Use Q20 to avoid any overflow when multiplying by (ind + 1) later. */ - maxabs_Q20 = silk_RSHIFT(maxabs_Q24, 4); - if( maxabs_Q20 <= limit_Q20 ) { - /* Coefficients are within range - done */ - return; - } - - /* Convert back to true warped coefficients */ - for( i = 1; i < order; i++ ) { - coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 ); - } - gain_Q16 = silk_INVERSE32_varQ( gain_Q16, 32 ); - for( i = 0; i < order; i++ ) { - coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] ); - } - - /* Apply bandwidth expansion */ - chirp_Q16 = SILK_FIX_CONST( 0.99, 16 ) - silk_DIV32_varQ( - silk_SMULWB( maxabs_Q20 - limit_Q20, silk_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ), - silk_MUL( maxabs_Q20, ind + 1 ), 22 ); - silk_bwexpander_32( coefs_Q24, order, chirp_Q16 ); - - /* Convert to monic warped coefficients */ - lambda_Q16 = -lambda_Q16; - for( i = order - 1; i > 0; i-- ) { - coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 ); - } - lambda_Q16 = -lambda_Q16; - nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 ); - den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 ); - gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 ); - for( i = 0; i < order; i++ ) { - coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] ); - } - } - silk_assert( 0 ); -} - -/* Disable MIPS version until it's updated. */ -#if 0 && defined(MIPSr1_ASM) -#include "mips/noise_shape_analysis_FIX_mipsr1.h" -#endif - -/**************************************************************/ -/* Compute noise shaping coefficients and initial gain values */ -/**************************************************************/ -#ifndef OVERRIDE_silk_noise_shape_analysis_FIX -void silk_noise_shape_analysis_FIX( - silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ - silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ - const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */ - const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */ - int arch /* I Run-time architecture */ -) -{ - silk_shape_state_FIX *psShapeSt = &psEnc->sShape; - opus_int k, i, nSamples, nSegs, Qnrg, b_Q14, warping_Q16, scale = 0; - opus_int32 SNR_adj_dB_Q7, HarmShapeGain_Q16, Tilt_Q16, tmp32; - opus_int32 nrg, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7; - opus_int32 BWExp_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8; - opus_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; - opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ]; - opus_int32 AR_Q24[ MAX_SHAPE_LPC_ORDER ]; - VARDECL( opus_int16, x_windowed ); - const opus_int16 *x_ptr, *pitch_res_ptr; - SAVE_STACK; - - /* Point to start of first LPC analysis block */ - x_ptr = x - psEnc->sCmn.la_shape; - - /****************/ - /* GAIN CONTROL */ - /****************/ - SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7; - - /* Input quality is the average of the quality in the lowest two VAD bands */ - psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ] - + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 ); - - /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */ - psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 - - SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 ); - - /* Reduce coding SNR during low speech activity */ - if( psEnc->sCmn.useCBR == 0 ) { - b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8; - b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 ); - SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, - silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), /* Q11*/ - silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); /* Q12*/ - } - - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Reduce gains for periodic signals */ - SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 ); - } else { - /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ - SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, - silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ), - SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 ); - } - - /*************************/ - /* SPARSENESS PROCESSING */ - /*************************/ - /* Set quantizer offset */ - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Initially set to 0; may be overruled in process_gains(..) */ - psEnc->sCmn.indices.quantOffsetType = 0; - } else { - /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ - nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 ); - energy_variation_Q7 = 0; - log_energy_prev_Q7 = 0; - pitch_res_ptr = pitch_res; - nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; - for( k = 0; k < nSegs; k++ ) { - silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples ); - nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/ - - log_energy_Q7 = silk_lin2log( nrg ); - if( k > 0 ) { - energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 ); - } - log_energy_prev_Q7 = log_energy_Q7; - pitch_res_ptr += nSamples; - } - - /* Set quantization offset depending on sparseness measure */ - if( energy_variation_Q7 > SILK_FIX_CONST( ENERGY_VARIATION_THRESHOLD_QNT_OFFSET, 7 ) * (nSegs-1) ) { - psEnc->sCmn.indices.quantOffsetType = 0; - } else { - psEnc->sCmn.indices.quantOffsetType = 1; - } - } - - /*******************************/ - /* Control bandwidth expansion */ - /*******************************/ - /* More BWE for signals with high prediction gain */ - strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ); - BWExp_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ), - silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 ); - - if( psEnc->sCmn.warping_Q16 > 0 ) { - /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ - warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) ); - } else { - warping_Q16 = 0; - } - - /********************************************/ - /* Compute noise shaping AR coefs and gains */ - /********************************************/ - ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 ); - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - /* Apply window: sine slope followed by flat part followed by cosine slope */ - opus_int shift, slope_part, flat_part; - flat_part = psEnc->sCmn.fs_kHz * 3; - slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 ); - - silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part ); - shift = slope_part; - silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) ); - shift += flat_part; - silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part ); - - /* Update pointer: next LPC analysis block */ - x_ptr += psEnc->sCmn.subfr_length; - - if( psEnc->sCmn.warping_Q16 > 0 ) { - /* Calculate warped auto correlation */ - silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch ); - } else { - /* Calculate regular auto correlation */ - silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch ); - } - - /* Add white noise, as a fraction of energy */ - auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ), - SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) ); - - /* Calculate the reflection coefficients using schur */ - nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder ); - silk_assert( nrg >= 0 ); - - /* Convert reflection coefficients to prediction coefficients */ - silk_k2a_Q16( AR_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder ); - - Qnrg = -scale; /* range: -12...30*/ - silk_assert( Qnrg >= -12 ); - silk_assert( Qnrg <= 30 ); - - /* Make sure that Qnrg is an even number */ - if( Qnrg & 1 ) { - Qnrg -= 1; - nrg >>= 1; - } - - tmp32 = silk_SQRT_APPROX( nrg ); - Qnrg >>= 1; /* range: -6...15*/ - - psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( tmp32, 16 - Qnrg ); - - if( psEnc->sCmn.warping_Q16 > 0 ) { - /* Adjust gain for warping */ - gain_mult_Q16 = warped_gain( AR_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder ); - silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 ); - if( psEncCtrl->Gains_Q16[ k ] < SILK_FIX_CONST( 0.25, 16 ) ) { - psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); - } else { - psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ); - if ( psEncCtrl->Gains_Q16[ k ] >= ( silk_int32_MAX >> 1 ) ) { - psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX; - } else { - psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT32( psEncCtrl->Gains_Q16[ k ], 1 ); - } - } - silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 ); - } - - /* Bandwidth expansion */ - silk_bwexpander_32( AR_Q24, psEnc->sCmn.shapingLPCOrder, BWExp_Q16 ); - - if( psEnc->sCmn.warping_Q16 > 0 ) { - /* Convert to monic warped prediction coefficients and limit absolute values */ - limit_warped_coefs( AR_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder ); - - /* Convert from Q24 to Q13 and store in int16 */ - for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) { - psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR_Q24[ i ], 11 ) ); - } - } else { - silk_LPC_fit( &psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER ], AR_Q24, 13, 24, psEnc->sCmn.shapingLPCOrder ); - } - } - - /*****************/ - /* Gain tweaking */ - /*****************/ - /* Increase gains during low speech activity and put lower limit on gains */ - gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) ); - gain_add_Q16 = silk_log2lin( silk_SMLAWB( SILK_FIX_CONST( 16.0, 7 ), SILK_FIX_CONST( MIN_QGAIN_DB, 7 ), SILK_FIX_CONST( 0.16, 16 ) ) ); - silk_assert( gain_mult_Q16 > 0 ); - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); - silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 ); - psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 ); - } - - - /************************************************/ - /* Control low-frequency shaping and noise tilt */ - /************************************************/ - /* Less low frequency shaping for noisy inputs */ - strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ), - SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) ); - strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 ); - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ - /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ - opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz ); - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] ); - /* Pack two coefficients in one int32 */ - psEncCtrl->LF_shp_Q14[ k ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 ); - psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) ); - } - silk_assert( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SILK_FIX_CONST( 0.5, 24 ) ); /* Guarantees that second argument to SMULWB() is within range of an opus_int16*/ - Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) - - silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ), - silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) ); - } else { - b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/ - /* Pack two coefficients in one int32 */ - psEncCtrl->LF_shp_Q14[ 0 ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - - silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 ); - psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) ); - for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ]; - } - Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 ); - } - - /****************************/ - /* HARMONIC SHAPING CONTROL */ - /****************************/ - if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* More harmonic noise shaping for high bitrates or noisy input */ - HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ), - SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ), - psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) ); - - /* Less harmonic noise shaping for less periodic signals */ - HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ), - silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) ); - } else { - HarmShapeGain_Q16 = 0; - } - - /*************************/ - /* Smooth over subframes */ - /*************************/ - for( k = 0; k < MAX_NB_SUBFR; k++ ) { - psShapeSt->HarmShapeGain_smth_Q16 = - silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); - psShapeSt->Tilt_smth_Q16 = - silk_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); - - psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 ); - psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 ); - } - RESTORE_STACK; -} -#endif /* OVERRIDE_silk_noise_shape_analysis_FIX */ diff --git a/src/libopus/silk/fixed/noise_shape_analysis_FIX.lo b/src/libopus/silk/fixed/noise_shape_analysis_FIX.lo deleted file mode 100644 index 9c74371a..00000000 --- a/src/libopus/silk/fixed/noise_shape_analysis_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/noise_shape_analysis_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/noise_shape_analysis_FIX.o' - -# Name of the non-PIC object -non_pic_object='noise_shape_analysis_FIX.o' - diff --git a/src/libopus/silk/fixed/noise_shape_analysis_FIX.o b/src/libopus/silk/fixed/noise_shape_analysis_FIX.o deleted file mode 100644 index 423d350d..00000000 Binary files a/src/libopus/silk/fixed/noise_shape_analysis_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/pitch.h b/src/libopus/silk/fixed/pitch.h new file mode 100644 index 00000000..f2cf322e --- /dev/null +++ b/src/libopus/silk/fixed/pitch.h @@ -0,0 +1 @@ +#include "../../celt/pitch.h" diff --git a/src/libopus/silk/fixed/pitch_analysis_core_FIX.c b/src/libopus/silk/fixed/pitch_analysis_core_FIX.c deleted file mode 100644 index 6e7ebffe..00000000 --- a/src/libopus/silk/fixed/pitch_analysis_core_FIX.c +++ /dev/null @@ -1,721 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif - -/*********************************************************** -* Pitch analyser function -********************************************************** */ -#include "../SigProc_FIX.h" -#include "../pitch_est_defines.h" -#include "../../celt/stack_alloc.h" -#include "../debug.h" -#include "../../celt/pitch.h" - -#define SCRATCH_SIZE 22 -#define SF_LENGTH_4KHZ ( PE_SUBFR_LENGTH_MS * 4 ) -#define SF_LENGTH_8KHZ ( PE_SUBFR_LENGTH_MS * 8 ) -#define MIN_LAG_4KHZ ( PE_MIN_LAG_MS * 4 ) -#define MIN_LAG_8KHZ ( PE_MIN_LAG_MS * 8 ) -#define MAX_LAG_4KHZ ( PE_MAX_LAG_MS * 4 ) -#define MAX_LAG_8KHZ ( PE_MAX_LAG_MS * 8 - 1 ) -#define CSTRIDE_4KHZ ( MAX_LAG_4KHZ + 1 - MIN_LAG_4KHZ ) -#define CSTRIDE_8KHZ ( MAX_LAG_8KHZ + 3 - ( MIN_LAG_8KHZ - 2 ) ) -#define D_COMP_MIN ( MIN_LAG_8KHZ - 3 ) -#define D_COMP_MAX ( MAX_LAG_8KHZ + 4 ) -#define D_COMP_STRIDE ( D_COMP_MAX - D_COMP_MIN ) - -typedef opus_int32 silk_pe_stage3_vals[ PE_NB_STAGE3_LAGS ]; - -/************************************************************/ -/* Internally used functions */ -/************************************************************/ -static void silk_P_Ana_calc_corr_st3( - silk_pe_stage3_vals cross_corr_st3[], /* O 3 DIM correlation array */ - const opus_int16 frame[], /* I vector to correlate */ - opus_int start_lag, /* I lag offset to search around */ - opus_int sf_length, /* I length of a 5 ms subframe */ - opus_int nb_subfr, /* I number of subframes */ - opus_int complexity, /* I Complexity setting */ - int arch /* I Run-time architecture */ -); - -static void silk_P_Ana_calc_energy_st3( - silk_pe_stage3_vals energies_st3[], /* O 3 DIM energy array */ - const opus_int16 frame[], /* I vector to calc energy in */ - opus_int start_lag, /* I lag offset to search around */ - opus_int sf_length, /* I length of one 5 ms subframe */ - opus_int nb_subfr, /* I number of subframes */ - opus_int complexity, /* I Complexity setting */ - int arch /* I Run-time architecture */ -); - -/*************************************************************/ -/* FIXED POINT CORE PITCH ANALYSIS FUNCTION */ -/*************************************************************/ -opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */ - const opus_int16 *frame_unscaled, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ - opus_int *pitch_out, /* O 4 pitch lag values */ - opus_int16 *lagIndex, /* O Lag Index */ - opus_int8 *contourIndex, /* O Pitch contour Index */ - opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */ - opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ - const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */ - const opus_int search_thres2_Q13, /* I Final threshold for lag candidates 0 - 1 */ - const opus_int Fs_kHz, /* I Sample frequency (kHz) */ - const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ - const opus_int nb_subfr, /* I number of 5 ms subframes */ - int arch /* I Run-time architecture */ -) -{ - VARDECL( opus_int16, frame_8kHz_buf ); - VARDECL( opus_int16, frame_4kHz ); - VARDECL( opus_int16, frame_scaled ); - opus_int32 filt_state[ 6 ]; - const opus_int16 *frame, *frame_8kHz; - opus_int i, k, d, j; - VARDECL( opus_int16, C ); - VARDECL( opus_int32, xcorr32 ); - const opus_int16 *target_ptr, *basis_ptr; - opus_int32 cross_corr, normalizer, energy, energy_basis, energy_target; - opus_int d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp, shift; - VARDECL( opus_int16, d_comp ); - opus_int32 sum, threshold, lag_counter; - opus_int CBimax, CBimax_new, CBimax_old, lag, start_lag, end_lag, lag_new; - opus_int32 CC[ PE_NB_CBKS_STAGE2_EXT ], CCmax, CCmax_b, CCmax_new_b, CCmax_new; - VARDECL( silk_pe_stage3_vals, energies_st3 ); - VARDECL( silk_pe_stage3_vals, cross_corr_st3 ); - opus_int frame_length, frame_length_8kHz, frame_length_4kHz; - opus_int sf_length; - opus_int min_lag; - opus_int max_lag; - opus_int32 contour_bias_Q15, diff; - opus_int nb_cbk_search, cbk_size; - opus_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q13; - const opus_int8 *Lag_CB_ptr; - SAVE_STACK; - - /* Check for valid sampling frequency */ - celt_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 ); - - /* Check for valid complexity setting */ - celt_assert( complexity >= SILK_PE_MIN_COMPLEX ); - celt_assert( complexity <= SILK_PE_MAX_COMPLEX ); - - silk_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) ); - silk_assert( search_thres2_Q13 >= 0 && search_thres2_Q13 <= (1<<13) ); - - /* Set up frame lengths max / min lag for the sampling frequency */ - frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz; - frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4; - frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8; - sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz; - min_lag = PE_MIN_LAG_MS * Fs_kHz; - max_lag = PE_MAX_LAG_MS * Fs_kHz - 1; - - /* Downscale input if necessary */ - silk_sum_sqr_shift( &energy, &shift, frame_unscaled, frame_length ); - shift += 3 - silk_CLZ32( energy ); /* at least two bits headroom */ - ALLOC( frame_scaled, frame_length, opus_int16 ); - if( shift > 0 ) { - shift = silk_RSHIFT( shift + 1, 1 ); - for( i = 0; i < frame_length; i++ ) { - frame_scaled[ i ] = silk_RSHIFT( frame_unscaled[ i ], shift ); - } - frame = frame_scaled; - } else { - frame = frame_unscaled; - } - - ALLOC( frame_8kHz_buf, ( Fs_kHz == 8 ) ? 1 : frame_length_8kHz, opus_int16 ); - /* Resample from input sampled at Fs_kHz to 8 kHz */ - if( Fs_kHz == 16 ) { - silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) ); - silk_resampler_down2( filt_state, frame_8kHz_buf, frame, frame_length ); - frame_8kHz = frame_8kHz_buf; - } else if( Fs_kHz == 12 ) { - silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) ); - silk_resampler_down2_3( filt_state, frame_8kHz_buf, frame, frame_length ); - frame_8kHz = frame_8kHz_buf; - } else { - celt_assert( Fs_kHz == 8 ); - frame_8kHz = frame; - } - - /* Decimate again to 4 kHz */ - silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );/* Set state to zero */ - ALLOC( frame_4kHz, frame_length_4kHz, opus_int16 ); - silk_resampler_down2( filt_state, frame_4kHz, frame_8kHz, frame_length_8kHz ); - - /* Low-pass filter */ - for( i = frame_length_4kHz - 1; i > 0; i-- ) { - frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] ); - } - - - /****************************************************************************** - * FIRST STAGE, operating in 4 khz - ******************************************************************************/ - ALLOC( C, nb_subfr * CSTRIDE_8KHZ, opus_int16 ); - ALLOC( xcorr32, MAX_LAG_4KHZ-MIN_LAG_4KHZ+1, opus_int32 ); - silk_memset( C, 0, (nb_subfr >> 1) * CSTRIDE_4KHZ * sizeof( opus_int16 ) ); - target_ptr = &frame_4kHz[ silk_LSHIFT( SF_LENGTH_4KHZ, 2 ) ]; - for( k = 0; k < nb_subfr >> 1; k++ ) { - /* Check that we are within range of the array */ - celt_assert( target_ptr >= frame_4kHz ); - celt_assert( target_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz ); - - basis_ptr = target_ptr - MIN_LAG_4KHZ; - - /* Check that we are within range of the array */ - celt_assert( basis_ptr >= frame_4kHz ); - celt_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz ); - - celt_pitch_xcorr( target_ptr, target_ptr - MAX_LAG_4KHZ, xcorr32, SF_LENGTH_8KHZ, MAX_LAG_4KHZ - MIN_LAG_4KHZ + 1, arch ); - - /* Calculate first vector products before loop */ - cross_corr = xcorr32[ MAX_LAG_4KHZ - MIN_LAG_4KHZ ]; - normalizer = silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch ); - normalizer = silk_ADD32( normalizer, silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ, arch ) ); - normalizer = silk_ADD32( normalizer, silk_SMULBB( SF_LENGTH_8KHZ, 4000 ) ); - - matrix_ptr( C, k, 0, CSTRIDE_4KHZ ) = - (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */ - - /* From now on normalizer is computed recursively */ - for( d = MIN_LAG_4KHZ + 1; d <= MAX_LAG_4KHZ; d++ ) { - basis_ptr--; - - /* Check that we are within range of the array */ - silk_assert( basis_ptr >= frame_4kHz ); - silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz ); - - cross_corr = xcorr32[ MAX_LAG_4KHZ - d ]; - - /* Add contribution of new sample and remove contribution from oldest sample */ - normalizer = silk_ADD32( normalizer, - silk_SMULBB( basis_ptr[ 0 ], basis_ptr[ 0 ] ) - - silk_SMULBB( basis_ptr[ SF_LENGTH_8KHZ ], basis_ptr[ SF_LENGTH_8KHZ ] ) ); - - matrix_ptr( C, k, d - MIN_LAG_4KHZ, CSTRIDE_4KHZ) = - (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */ - } - /* Update target pointer */ - target_ptr += SF_LENGTH_8KHZ; - } - - /* Combine two subframes into single correlation measure and apply short-lag bias */ - if( nb_subfr == PE_MAX_NB_SUBFR ) { - for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) { - sum = (opus_int32)matrix_ptr( C, 0, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ ) - + (opus_int32)matrix_ptr( C, 1, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ ); /* Q14 */ - sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */ - C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */ - } - } else { - /* Only short-lag bias */ - for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) { - sum = silk_LSHIFT( (opus_int32)C[ i - MIN_LAG_4KHZ ], 1 ); /* Q14 */ - sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */ - C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */ - } - } - - /* Sort */ - length_d_srch = silk_ADD_LSHIFT32( 4, complexity, 1 ); - celt_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH ); - silk_insertion_sort_decreasing_int16( C, d_srch, CSTRIDE_4KHZ, - length_d_srch ); - - /* Escape if correlation is very low already here */ - Cmax = (opus_int)C[ 0 ]; /* Q14 */ - if( Cmax < SILK_FIX_CONST( 0.2, 14 ) ) { - silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) ); - *LTPCorr_Q15 = 0; - *lagIndex = 0; - *contourIndex = 0; - RESTORE_STACK; - return 1; - } - - threshold = silk_SMULWB( search_thres1_Q16, Cmax ); - for( i = 0; i < length_d_srch; i++ ) { - /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */ - if( C[ i ] > threshold ) { - d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + MIN_LAG_4KHZ, 1 ); - } else { - length_d_srch = i; - break; - } - } - celt_assert( length_d_srch > 0 ); - - ALLOC( d_comp, D_COMP_STRIDE, opus_int16 ); - for( i = D_COMP_MIN; i < D_COMP_MAX; i++ ) { - d_comp[ i - D_COMP_MIN ] = 0; - } - for( i = 0; i < length_d_srch; i++ ) { - d_comp[ d_srch[ i ] - D_COMP_MIN ] = 1; - } - - /* Convolution */ - for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) { - d_comp[ i - D_COMP_MIN ] += - d_comp[ i - 1 - D_COMP_MIN ] + d_comp[ i - 2 - D_COMP_MIN ]; - } - - length_d_srch = 0; - for( i = MIN_LAG_8KHZ; i < MAX_LAG_8KHZ + 1; i++ ) { - if( d_comp[ i + 1 - D_COMP_MIN ] > 0 ) { - d_srch[ length_d_srch ] = i; - length_d_srch++; - } - } - - /* Convolution */ - for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) { - d_comp[ i - D_COMP_MIN ] += d_comp[ i - 1 - D_COMP_MIN ] - + d_comp[ i - 2 - D_COMP_MIN ] + d_comp[ i - 3 - D_COMP_MIN ]; - } - - length_d_comp = 0; - for( i = MIN_LAG_8KHZ; i < D_COMP_MAX; i++ ) { - if( d_comp[ i - D_COMP_MIN ] > 0 ) { - d_comp[ length_d_comp ] = i - 2; - length_d_comp++; - } - } - - /********************************************************************************** - ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation - *************************************************************************************/ - - /********************************************************************************* - * Find energy of each subframe projected onto its history, for a range of delays - *********************************************************************************/ - silk_memset( C, 0, nb_subfr * CSTRIDE_8KHZ * sizeof( opus_int16 ) ); - - target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ]; - for( k = 0; k < nb_subfr; k++ ) { - - /* Check that we are within range of the array */ - celt_assert( target_ptr >= frame_8kHz ); - celt_assert( target_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz ); - - energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch ), 1 ); - for( j = 0; j < length_d_comp; j++ ) { - d = d_comp[ j ]; - basis_ptr = target_ptr - d; - - /* Check that we are within range of the array */ - silk_assert( basis_ptr >= frame_8kHz ); - silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz ); - - cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, SF_LENGTH_8KHZ, arch ); - if( cross_corr > 0 ) { - energy_basis = silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ, arch ); - matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) = - (opus_int16)silk_DIV32_varQ( cross_corr, - silk_ADD32( energy_target, - energy_basis ), - 13 + 1 ); /* Q13 */ - } else { - matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) = 0; - } - } - target_ptr += SF_LENGTH_8KHZ; - } - - /* search over lag range and lags codebook */ - /* scale factor for lag codebook, as a function of center lag */ - - CCmax = silk_int32_MIN; - CCmax_b = silk_int32_MIN; - - CBimax = 0; /* To avoid returning undefined lag values */ - lag = -1; /* To check if lag with strong enough correlation has been found */ - - if( prevLag > 0 ) { - if( Fs_kHz == 12 ) { - prevLag = silk_DIV32_16( silk_LSHIFT( prevLag, 1 ), 3 ); - } else if( Fs_kHz == 16 ) { - prevLag = silk_RSHIFT( prevLag, 1 ); - } - prevLag_log2_Q7 = silk_lin2log( (opus_int32)prevLag ); - } else { - prevLag_log2_Q7 = 0; - } - silk_assert( search_thres2_Q13 == silk_SAT16( search_thres2_Q13 ) ); - /* Set up stage 2 codebook based on number of subframes */ - if( nb_subfr == PE_MAX_NB_SUBFR ) { - cbk_size = PE_NB_CBKS_STAGE2_EXT; - Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ]; - if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) { - /* If input is 8 khz use a larger codebook here because it is last stage */ - nb_cbk_search = PE_NB_CBKS_STAGE2_EXT; - } else { - nb_cbk_search = PE_NB_CBKS_STAGE2; - } - } else { - cbk_size = PE_NB_CBKS_STAGE2_10MS; - Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ]; - nb_cbk_search = PE_NB_CBKS_STAGE2_10MS; - } - - for( k = 0; k < length_d_srch; k++ ) { - d = d_srch[ k ]; - for( j = 0; j < nb_cbk_search; j++ ) { - CC[ j ] = 0; - for( i = 0; i < nb_subfr; i++ ) { - opus_int d_subfr; - /* Try all codebooks */ - d_subfr = d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size ); - CC[ j ] = CC[ j ] - + (opus_int32)matrix_ptr( C, i, - d_subfr - ( MIN_LAG_8KHZ - 2 ), - CSTRIDE_8KHZ ); - } - } - /* Find best codebook */ - CCmax_new = silk_int32_MIN; - CBimax_new = 0; - for( i = 0; i < nb_cbk_search; i++ ) { - if( CC[ i ] > CCmax_new ) { - CCmax_new = CC[ i ]; - CBimax_new = i; - } - } - - /* Bias towards shorter lags */ - lag_log2_Q7 = silk_lin2log( d ); /* Q7 */ - silk_assert( lag_log2_Q7 == silk_SAT16( lag_log2_Q7 ) ); - silk_assert( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) ) ); - CCmax_new_b = CCmax_new - silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ), lag_log2_Q7 ), 7 ); /* Q13 */ - - /* Bias towards previous lag */ - silk_assert( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) ) ); - if( prevLag > 0 ) { - delta_lag_log2_sqr_Q7 = lag_log2_Q7 - prevLag_log2_Q7; - silk_assert( delta_lag_log2_sqr_Q7 == silk_SAT16( delta_lag_log2_sqr_Q7 ) ); - delta_lag_log2_sqr_Q7 = silk_RSHIFT( silk_SMULBB( delta_lag_log2_sqr_Q7, delta_lag_log2_sqr_Q7 ), 7 ); - prev_lag_bias_Q13 = silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ), *LTPCorr_Q15 ), 15 ); /* Q13 */ - prev_lag_bias_Q13 = silk_DIV32( silk_MUL( prev_lag_bias_Q13, delta_lag_log2_sqr_Q7 ), delta_lag_log2_sqr_Q7 + SILK_FIX_CONST( 0.5, 7 ) ); - CCmax_new_b -= prev_lag_bias_Q13; /* Q13 */ - } - - if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */ - CCmax_new > silk_SMULBB( nb_subfr, search_thres2_Q13 ) && /* Correlation needs to be high enough to be voiced */ - silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= MIN_LAG_8KHZ /* Lag must be in range */ - ) { - CCmax_b = CCmax_new_b; - CCmax = CCmax_new; - lag = d; - CBimax = CBimax_new; - } - } - - if( lag == -1 ) { - /* No suitable candidate found */ - silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) ); - *LTPCorr_Q15 = 0; - *lagIndex = 0; - *contourIndex = 0; - RESTORE_STACK; - return 1; - } - - /* Output normalized correlation */ - *LTPCorr_Q15 = (opus_int)silk_LSHIFT( silk_DIV32_16( CCmax, nb_subfr ), 2 ); - silk_assert( *LTPCorr_Q15 >= 0 ); - - if( Fs_kHz > 8 ) { - /* Search in original signal */ - - CBimax_old = CBimax; - /* Compensate for decimation */ - silk_assert( lag == silk_SAT16( lag ) ); - if( Fs_kHz == 12 ) { - lag = silk_RSHIFT( silk_SMULBB( lag, 3 ), 1 ); - } else if( Fs_kHz == 16 ) { - lag = silk_LSHIFT( lag, 1 ); - } else { - lag = silk_SMULBB( lag, 3 ); - } - - lag = silk_LIMIT_int( lag, min_lag, max_lag ); - start_lag = silk_max_int( lag - 2, min_lag ); - end_lag = silk_min_int( lag + 2, max_lag ); - lag_new = lag; /* to avoid undefined lag */ - CBimax = 0; /* to avoid undefined lag */ - - CCmax = silk_int32_MIN; - /* pitch lags according to second stage */ - for( k = 0; k < nb_subfr; k++ ) { - pitch_out[ k ] = lag + 2 * silk_CB_lags_stage2[ k ][ CBimax_old ]; - } - - /* Set up codebook parameters according to complexity setting and frame length */ - if( nb_subfr == PE_MAX_NB_SUBFR ) { - nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ]; - cbk_size = PE_NB_CBKS_STAGE3_MAX; - Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; - } else { - nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; - cbk_size = PE_NB_CBKS_STAGE3_10MS; - Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; - } - - /* Calculate the correlations and energies needed in stage 3 */ - ALLOC( energies_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals ); - ALLOC( cross_corr_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals ); - silk_P_Ana_calc_corr_st3( cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch ); - silk_P_Ana_calc_energy_st3( energies_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch ); - - lag_counter = 0; - silk_assert( lag == silk_SAT16( lag ) ); - contour_bias_Q15 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 15 ), lag ); - - target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ]; - energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, nb_subfr * sf_length, arch ), 1 ); - for( d = start_lag; d <= end_lag; d++ ) { - for( j = 0; j < nb_cbk_search; j++ ) { - cross_corr = 0; - energy = energy_target; - for( k = 0; k < nb_subfr; k++ ) { - cross_corr = silk_ADD32( cross_corr, - matrix_ptr( cross_corr_st3, k, j, - nb_cbk_search )[ lag_counter ] ); - energy = silk_ADD32( energy, - matrix_ptr( energies_st3, k, j, - nb_cbk_search )[ lag_counter ] ); - silk_assert( energy >= 0 ); - } - if( cross_corr > 0 ) { - CCmax_new = silk_DIV32_varQ( cross_corr, energy, 13 + 1 ); /* Q13 */ - /* Reduce depending on flatness of contour */ - diff = silk_int16_MAX - silk_MUL( contour_bias_Q15, j ); /* Q15 */ - silk_assert( diff == silk_SAT16( diff ) ); - CCmax_new = silk_SMULWB( CCmax_new, diff ); /* Q14 */ - } else { - CCmax_new = 0; - } - - if( CCmax_new > CCmax && ( d + silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) { - CCmax = CCmax_new; - lag_new = d; - CBimax = j; - } - } - lag_counter++; - } - - for( k = 0; k < nb_subfr; k++ ) { - pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); - pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz ); - } - *lagIndex = (opus_int16)( lag_new - min_lag); - *contourIndex = (opus_int8)CBimax; - } else { /* Fs_kHz == 8 */ - /* Save Lags */ - for( k = 0; k < nb_subfr; k++ ) { - pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); - pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], MIN_LAG_8KHZ, PE_MAX_LAG_MS * 8 ); - } - *lagIndex = (opus_int16)( lag - MIN_LAG_8KHZ ); - *contourIndex = (opus_int8)CBimax; - } - celt_assert( *lagIndex >= 0 ); - /* return as voiced */ - RESTORE_STACK; - return 0; -} - -/*********************************************************************** - * Calculates the correlations used in stage 3 search. In order to cover - * the whole lag codebook for all the searched offset lags (lag +- 2), - * the following correlations are needed in each sub frame: - * - * sf1: lag range [-8,...,7] total 16 correlations - * sf2: lag range [-4,...,4] total 9 correlations - * sf3: lag range [-3,....4] total 8 correltions - * sf4: lag range [-6,....8] total 15 correlations - * - * In total 48 correlations. The direct implementation computed in worst - * case 4*12*5 = 240 correlations, but more likely around 120. - ***********************************************************************/ -static void silk_P_Ana_calc_corr_st3( - silk_pe_stage3_vals cross_corr_st3[], /* O 3 DIM correlation array */ - const opus_int16 frame[], /* I vector to correlate */ - opus_int start_lag, /* I lag offset to search around */ - opus_int sf_length, /* I length of a 5 ms subframe */ - opus_int nb_subfr, /* I number of subframes */ - opus_int complexity, /* I Complexity setting */ - int arch /* I Run-time architecture */ -) -{ - const opus_int16 *target_ptr; - opus_int i, j, k, lag_counter, lag_low, lag_high; - opus_int nb_cbk_search, delta, idx, cbk_size; - VARDECL( opus_int32, scratch_mem ); - VARDECL( opus_int32, xcorr32 ); - const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; - SAVE_STACK; - - celt_assert( complexity >= SILK_PE_MIN_COMPLEX ); - celt_assert( complexity <= SILK_PE_MAX_COMPLEX ); - - if( nb_subfr == PE_MAX_NB_SUBFR ) { - Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; - Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; - nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; - cbk_size = PE_NB_CBKS_STAGE3_MAX; - } else { - celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); - Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; - Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; - nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; - cbk_size = PE_NB_CBKS_STAGE3_10MS; - } - ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 ); - ALLOC( xcorr32, SCRATCH_SIZE, opus_int32 ); - - target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */ - for( k = 0; k < nb_subfr; k++ ) { - lag_counter = 0; - - /* Calculate the correlations for each subframe */ - lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 ); - lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 ); - celt_assert(lag_high-lag_low+1 <= SCRATCH_SIZE); - celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr32, sf_length, lag_high - lag_low + 1, arch ); - for( j = lag_low; j <= lag_high; j++ ) { - silk_assert( lag_counter < SCRATCH_SIZE ); - scratch_mem[ lag_counter ] = xcorr32[ lag_high - j ]; - lag_counter++; - } - - delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); - for( i = 0; i < nb_cbk_search; i++ ) { - /* Fill out the 3 dim array that stores the correlations for */ - /* each code_book vector for each start lag */ - idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; - for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { - silk_assert( idx + j < SCRATCH_SIZE ); - silk_assert( idx + j < lag_counter ); - matrix_ptr( cross_corr_st3, k, i, nb_cbk_search )[ j ] = - scratch_mem[ idx + j ]; - } - } - target_ptr += sf_length; - } - RESTORE_STACK; -} - -/********************************************************************/ -/* Calculate the energies for first two subframes. The energies are */ -/* calculated recursively. */ -/********************************************************************/ -static void silk_P_Ana_calc_energy_st3( - silk_pe_stage3_vals energies_st3[], /* O 3 DIM energy array */ - const opus_int16 frame[], /* I vector to calc energy in */ - opus_int start_lag, /* I lag offset to search around */ - opus_int sf_length, /* I length of one 5 ms subframe */ - opus_int nb_subfr, /* I number of subframes */ - opus_int complexity, /* I Complexity setting */ - int arch /* I Run-time architecture */ -) -{ - const opus_int16 *target_ptr, *basis_ptr; - opus_int32 energy; - opus_int k, i, j, lag_counter; - opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff; - VARDECL( opus_int32, scratch_mem ); - const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; - SAVE_STACK; - - celt_assert( complexity >= SILK_PE_MIN_COMPLEX ); - celt_assert( complexity <= SILK_PE_MAX_COMPLEX ); - - if( nb_subfr == PE_MAX_NB_SUBFR ) { - Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; - Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; - nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; - cbk_size = PE_NB_CBKS_STAGE3_MAX; - } else { - celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); - Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; - Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; - nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; - cbk_size = PE_NB_CBKS_STAGE3_10MS; - } - ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 ); - - target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; - for( k = 0; k < nb_subfr; k++ ) { - lag_counter = 0; - - /* Calculate the energy for first lag */ - basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) ); - energy = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length, arch ); - silk_assert( energy >= 0 ); - scratch_mem[ lag_counter ] = energy; - lag_counter++; - - lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 ); - for( i = 1; i < lag_diff; i++ ) { - /* remove part outside new window */ - energy -= silk_SMULBB( basis_ptr[ sf_length - i ], basis_ptr[ sf_length - i ] ); - silk_assert( energy >= 0 ); - - /* add part that comes into window */ - energy = silk_ADD_SAT32( energy, silk_SMULBB( basis_ptr[ -i ], basis_ptr[ -i ] ) ); - silk_assert( energy >= 0 ); - silk_assert( lag_counter < SCRATCH_SIZE ); - scratch_mem[ lag_counter ] = energy; - lag_counter++; - } - - delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); - for( i = 0; i < nb_cbk_search; i++ ) { - /* Fill out the 3 dim array that stores the correlations for */ - /* each code_book vector for each start lag */ - idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; - for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { - silk_assert( idx + j < SCRATCH_SIZE ); - silk_assert( idx + j < lag_counter ); - matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] = - scratch_mem[ idx + j ]; - silk_assert( - matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] >= 0 ); - } - } - target_ptr += sf_length; - } - RESTORE_STACK; -} diff --git a/src/libopus/silk/fixed/pitch_analysis_core_FIX.lo b/src/libopus/silk/fixed/pitch_analysis_core_FIX.lo deleted file mode 100644 index 46ccdff3..00000000 --- a/src/libopus/silk/fixed/pitch_analysis_core_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/pitch_analysis_core_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/pitch_analysis_core_FIX.o' - -# Name of the non-PIC object -non_pic_object='pitch_analysis_core_FIX.o' - diff --git a/src/libopus/silk/fixed/pitch_analysis_core_FIX.o b/src/libopus/silk/fixed/pitch_analysis_core_FIX.o deleted file mode 100644 index 351cae6a..00000000 Binary files a/src/libopus/silk/fixed/pitch_analysis_core_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/pitch_est_defines.h b/src/libopus/silk/fixed/pitch_est_defines.h new file mode 100644 index 00000000..77b7e3d7 --- /dev/null +++ b/src/libopus/silk/fixed/pitch_est_defines.h @@ -0,0 +1 @@ +#include "../pitch_est_defines.h" diff --git a/src/libopus/silk/fixed/process_gains_FIX.c b/src/libopus/silk/fixed/process_gains_FIX.c index f8dc2385..fb3a4fe0 100644 --- a/src/libopus/silk/fixed/process_gains_FIX.c +++ b/src/libopus/silk/fixed/process_gains_FIX.c @@ -25,12 +25,12 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main_FIX.h" -#include "../tuning_parameters.h" +#include "tuning_parameters.h" /* Processing of gains */ void silk_process_gains_FIX( diff --git a/src/libopus/silk/fixed/process_gains_FIX.lo b/src/libopus/silk/fixed/process_gains_FIX.lo deleted file mode 100644 index 80571ccf..00000000 --- a/src/libopus/silk/fixed/process_gains_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/process_gains_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/process_gains_FIX.o' - -# Name of the non-PIC object -non_pic_object='process_gains_FIX.o' - diff --git a/src/libopus/silk/fixed/process_gains_FIX.o b/src/libopus/silk/fixed/process_gains_FIX.o deleted file mode 100644 index d443070f..00000000 Binary files a/src/libopus/silk/fixed/process_gains_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/regularize_correlations_FIX.c b/src/libopus/silk/fixed/regularize_correlations_FIX.c index dcaac56c..0d799ec9 100644 --- a/src/libopus/silk/fixed/regularize_correlations_FIX.c +++ b/src/libopus/silk/fixed/regularize_correlations_FIX.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main_FIX.h" diff --git a/src/libopus/silk/fixed/regularize_correlations_FIX.lo b/src/libopus/silk/fixed/regularize_correlations_FIX.lo deleted file mode 100644 index 5e873c65..00000000 --- a/src/libopus/silk/fixed/regularize_correlations_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/regularize_correlations_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/regularize_correlations_FIX.o' - -# Name of the non-PIC object -non_pic_object='regularize_correlations_FIX.o' - diff --git a/src/libopus/silk/fixed/regularize_correlations_FIX.o b/src/libopus/silk/fixed/regularize_correlations_FIX.o deleted file mode 100644 index da672465..00000000 Binary files a/src/libopus/silk/fixed/regularize_correlations_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/residual_energy16_FIX.c b/src/libopus/silk/fixed/residual_energy16_FIX.c index 0b8c63c4..57b876b2 100644 --- a/src/libopus/silk/fixed/residual_energy16_FIX.c +++ b/src/libopus/silk/fixed/residual_energy16_FIX.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main_FIX.h" diff --git a/src/libopus/silk/fixed/residual_energy16_FIX.lo b/src/libopus/silk/fixed/residual_energy16_FIX.lo deleted file mode 100644 index 1bcfabe8..00000000 --- a/src/libopus/silk/fixed/residual_energy16_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/residual_energy16_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/residual_energy16_FIX.o' - -# Name of the non-PIC object -non_pic_object='residual_energy16_FIX.o' - diff --git a/src/libopus/silk/fixed/residual_energy16_FIX.o b/src/libopus/silk/fixed/residual_energy16_FIX.o deleted file mode 100644 index 4524d65e..00000000 Binary files a/src/libopus/silk/fixed/residual_energy16_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/residual_energy_FIX.c b/src/libopus/silk/fixed/residual_energy_FIX.c index f8abd232..14a5a314 100644 --- a/src/libopus/silk/fixed/residual_energy_FIX.c +++ b/src/libopus/silk/fixed/residual_energy_FIX.c @@ -25,12 +25,12 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main_FIX.h" -#include "../../celt/stack_alloc.h" +#include "stack_alloc.h" /* Calculates residual energies of input subframes where all subframes have LPC_order */ /* of preceding samples */ diff --git a/src/libopus/silk/fixed/residual_energy_FIX.lo b/src/libopus/silk/fixed/residual_energy_FIX.lo deleted file mode 100644 index e84657cd..00000000 --- a/src/libopus/silk/fixed/residual_energy_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/residual_energy_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/residual_energy_FIX.o' - -# Name of the non-PIC object -non_pic_object='residual_energy_FIX.o' - diff --git a/src/libopus/silk/fixed/residual_energy_FIX.o b/src/libopus/silk/fixed/residual_energy_FIX.o deleted file mode 100644 index 1fa2cc62..00000000 Binary files a/src/libopus/silk/fixed/residual_energy_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/schur64_FIX.c b/src/libopus/silk/fixed/schur64_FIX.c index c6485034..cc44dfa0 100644 --- a/src/libopus/silk/fixed/schur64_FIX.c +++ b/src/libopus/silk/fixed/schur64_FIX.c @@ -25,11 +25,11 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif -#include "../SigProc_FIX.h" +#include "SigProc_FIX.h" /* Slower than schur(), but more accurate. */ /* Uses SMULL(), available on armv4 */ diff --git a/src/libopus/silk/fixed/schur64_FIX.lo b/src/libopus/silk/fixed/schur64_FIX.lo deleted file mode 100644 index 644480e0..00000000 --- a/src/libopus/silk/fixed/schur64_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/schur64_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/schur64_FIX.o' - -# Name of the non-PIC object -non_pic_object='schur64_FIX.o' - diff --git a/src/libopus/silk/fixed/schur64_FIX.o b/src/libopus/silk/fixed/schur64_FIX.o deleted file mode 100644 index 94d69ae9..00000000 Binary files a/src/libopus/silk/fixed/schur64_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/schur_FIX.c b/src/libopus/silk/fixed/schur_FIX.c index 348624e5..6278c6a9 100644 --- a/src/libopus/silk/fixed/schur_FIX.c +++ b/src/libopus/silk/fixed/schur_FIX.c @@ -25,11 +25,11 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif -#include "../SigProc_FIX.h" +#include "SigProc_FIX.h" /* Faster than schur64(), but much less accurate. */ /* uses SMLAWB(), requiring armv5E and higher. */ diff --git a/src/libopus/silk/fixed/schur_FIX.lo b/src/libopus/silk/fixed/schur_FIX.lo deleted file mode 100644 index f98ce3dc..00000000 --- a/src/libopus/silk/fixed/schur_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/schur_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/schur_FIX.o' - -# Name of the non-PIC object -non_pic_object='schur_FIX.o' - diff --git a/src/libopus/silk/fixed/schur_FIX.o b/src/libopus/silk/fixed/schur_FIX.o deleted file mode 100644 index 36c8f8b0..00000000 Binary files a/src/libopus/silk/fixed/schur_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/stack_alloc.h b/src/libopus/silk/fixed/stack_alloc.h new file mode 100644 index 00000000..7b53013e --- /dev/null +++ b/src/libopus/silk/fixed/stack_alloc.h @@ -0,0 +1 @@ +#include "../../celt/stack_alloc.h" diff --git a/src/libopus/silk/fixed/structs.h b/src/libopus/silk/fixed/structs.h new file mode 100644 index 00000000..e564d5dc --- /dev/null +++ b/src/libopus/silk/fixed/structs.h @@ -0,0 +1 @@ +#include "../structs.h" diff --git a/src/libopus/silk/fixed/structs_FIX.h b/src/libopus/silk/fixed/structs_FIX.h index ae87241e..2774a97b 100644 --- a/src/libopus/silk/fixed/structs_FIX.h +++ b/src/libopus/silk/fixed/structs_FIX.h @@ -28,9 +28,9 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef SILK_STRUCTS_FIX_H #define SILK_STRUCTS_FIX_H -#include "../typedef.h" -#include "../main.h" -#include "../structs.h" +#include "typedef.h" +#include "main.h" +#include "structs.h" #ifdef __cplusplus extern "C" diff --git a/src/libopus/silk/fixed/tuning_parameters.h b/src/libopus/silk/fixed/tuning_parameters.h new file mode 100644 index 00000000..b2cb6386 --- /dev/null +++ b/src/libopus/silk/fixed/tuning_parameters.h @@ -0,0 +1 @@ +#include "../tuning_parameters.h" diff --git a/src/libopus/silk/fixed/typedef.h b/src/libopus/silk/fixed/typedef.h new file mode 100644 index 00000000..95a45fd8 --- /dev/null +++ b/src/libopus/silk/fixed/typedef.h @@ -0,0 +1 @@ +#include "../typedef.h" diff --git a/src/libopus/silk/fixed/vector_ops_FIX.c b/src/libopus/silk/fixed/vector_ops_FIX.c index 74876f32..dee22257 100644 --- a/src/libopus/silk/fixed/vector_ops_FIX.c +++ b/src/libopus/silk/fixed/vector_ops_FIX.c @@ -25,12 +25,12 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif -#include "../SigProc_FIX.h" -#include "../../celt/pitch.h" +#include "SigProc_FIX.h" +#include "pitch.h" /* Copy and multiply a vector by a constant */ void silk_scale_copy_vector16( @@ -87,7 +87,7 @@ opus_int32 silk_inner_prod_aligned( #endif } -opus_int64 silk_inner_prod16_aligned_64_c( +opus_int64 silk_inner_prod16_c( const opus_int16 *inVec1, /* I input vector 1 */ const opus_int16 *inVec2, /* I input vector 2 */ const opus_int len /* I vector lengths */ diff --git a/src/libopus/silk/fixed/vector_ops_FIX.lo b/src/libopus/silk/fixed/vector_ops_FIX.lo deleted file mode 100644 index 1e7ba8fc..00000000 --- a/src/libopus/silk/fixed/vector_ops_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/vector_ops_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/vector_ops_FIX.o' - -# Name of the non-PIC object -non_pic_object='vector_ops_FIX.o' - diff --git a/src/libopus/silk/fixed/vector_ops_FIX.o b/src/libopus/silk/fixed/vector_ops_FIX.o deleted file mode 100644 index bc0f42d6..00000000 Binary files a/src/libopus/silk/fixed/vector_ops_FIX.o and /dev/null differ diff --git a/src/libopus/silk/fixed/warped_autocorrelation_FIX.c b/src/libopus/silk/fixed/warped_autocorrelation_FIX.c index 7ef3a7ef..473e28eb 100644 --- a/src/libopus/silk/fixed/warped_autocorrelation_FIX.c +++ b/src/libopus/silk/fixed/warped_autocorrelation_FIX.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main_FIX.h" diff --git a/src/libopus/silk/fixed/warped_autocorrelation_FIX.lo b/src/libopus/silk/fixed/warped_autocorrelation_FIX.lo deleted file mode 100644 index 2e032966..00000000 --- a/src/libopus/silk/fixed/warped_autocorrelation_FIX.lo +++ /dev/null @@ -1,12 +0,0 @@ -# silk/fixed/warped_autocorrelation_FIX.lo - a libtool object file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object='.libs/warped_autocorrelation_FIX.o' - -# Name of the non-PIC object -non_pic_object='warped_autocorrelation_FIX.o' - diff --git a/src/libopus/silk/fixed/warped_autocorrelation_FIX.o b/src/libopus/silk/fixed/warped_autocorrelation_FIX.o deleted file mode 100644 index 500bd7e1..00000000 Binary files a/src/libopus/silk/fixed/warped_autocorrelation_FIX.o and /dev/null differ diff --git a/src/libopus/silk/gain_quant.c b/src/libopus/silk/gain_quant.c index 554165b6..45842bdb 100644 --- a/src/libopus/silk/gain_quant.c +++ b/src/libopus/silk/gain_quant.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/init_decoder.c b/src/libopus/silk/init_decoder.c index 9d72341e..21c8d014 100644 --- a/src/libopus/silk/init_decoder.c +++ b/src/libopus/silk/init_decoder.c @@ -25,21 +25,27 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" +#ifdef ENABLE_OSCE +#include "osce.h" +#endif + +#include "structs.h" + /************************/ -/* Init Decoder State */ +/* Reset Decoder State */ /************************/ -opus_int silk_init_decoder( +opus_int silk_reset_decoder( silk_decoder_state *psDec /* I/O Decoder state pointer */ ) { /* Clear the entire encoder state, except anything copied */ - silk_memset( psDec, 0, sizeof( silk_decoder_state ) ); + silk_memset( &psDec->SILK_DECODER_STATE_RESET_START, 0, sizeof( silk_decoder_state ) - ((char*) &psDec->SILK_DECODER_STATE_RESET_START - (char*)psDec) ); /* Used to deactivate LSF interpolation */ psDec->first_frame_after_reset = 1; @@ -52,6 +58,27 @@ opus_int silk_init_decoder( /* Reset PLC state */ silk_PLC_Reset( psDec ); +#ifdef ENABLE_OSCE + /* Reset OSCE state and method */ + osce_reset(&psDec->osce, OSCE_DEFAULT_METHOD); +#endif + + return 0; +} + + +/************************/ +/* Init Decoder State */ +/************************/ +opus_int silk_init_decoder( + silk_decoder_state *psDec /* I/O Decoder state pointer */ +) +{ + /* Clear the entire encoder state, except anything copied */ + silk_memset( psDec, 0, sizeof( silk_decoder_state ) ); + + silk_reset_decoder( psDec ); + return(0); } diff --git a/src/libopus/silk/init_encoder.c b/src/libopus/silk/init_encoder.c deleted file mode 100644 index 2ffad48f..00000000 --- a/src/libopus/silk/init_encoder.c +++ /dev/null @@ -1,64 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif -#ifdef FIXED_POINT -#include "fixed/main_FIX.h" -#else -#include "main_FLP.h" -#endif -#include "tuning_parameters.h" -#include "../celt/cpu_support.h" - -/*********************************/ -/* Initialize Silk Encoder state */ -/*********************************/ -opus_int silk_init_encoder( - silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk FIX encoder state */ - int arch /* I Run-time architecture */ -) -{ - opus_int ret = 0; - - /* Clear the entire encoder state */ - silk_memset( psEnc, 0, sizeof( silk_encoder_state_Fxx ) ); - - psEnc->sCmn.arch = arch; - - psEnc->sCmn.variable_HP_smth1_Q15 = silk_LSHIFT( silk_lin2log( SILK_FIX_CONST( VARIABLE_HP_MIN_CUTOFF_HZ, 16 ) ) - ( 16 << 7 ), 8 ); - psEnc->sCmn.variable_HP_smth2_Q15 = psEnc->sCmn.variable_HP_smth1_Q15; - - /* Used to deactivate LSF interpolation, pitch prediction */ - psEnc->sCmn.first_frame_after_reset = 1; - - /* Initialize Silk VAD */ - ret += silk_VAD_Init( &psEnc->sCmn.sVAD ); - - return ret; -} diff --git a/src/libopus/silk/inner_prod_aligned.c b/src/libopus/silk/inner_prod_aligned.c index cdaeaf85..69eee899 100644 --- a/src/libopus/silk/inner_prod_aligned.c +++ b/src/libopus/silk/inner_prod_aligned.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "SigProc_FIX.h" diff --git a/src/libopus/silk/interpolate.c b/src/libopus/silk/interpolate.c index 6be988f9..b2856f87 100644 --- a/src/libopus/silk/interpolate.c +++ b/src/libopus/silk/interpolate.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/lin2log.c b/src/libopus/silk/lin2log.c index 87513677..0826ccd1 100644 --- a/src/libopus/silk/lin2log.c +++ b/src/libopus/silk/lin2log.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "SigProc_FIX.h" /* Approximation of 128 * log2() (very close inverse of silk_log2lin()) */ diff --git a/src/libopus/silk/log2lin.c b/src/libopus/silk/log2lin.c index ea847bfb..860c3dcd 100644 --- a/src/libopus/silk/log2lin.c +++ b/src/libopus/silk/log2lin.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "SigProc_FIX.h" diff --git a/src/libopus/silk/macros.h b/src/libopus/silk/macros.h index 22022f9b..d5ac4091 100644 --- a/src/libopus/silk/macros.h +++ b/src/libopus/silk/macros.h @@ -28,13 +28,13 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef SILK_MACROS_H #define SILK_MACROS_H -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif -#include "../opus_types.h" -#include "../opus_defines.h" -#include "../celt/arch.h" +#include "opus_types.h" +#include "opus_defines.h" +#include "arch.h" /* This is an OPUS_INLINE header file for general platform. */ @@ -108,7 +108,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "mips/macros_mipsr1.h" #endif -#include "../celt/ecintrin.h" +#include "ecintrin.h" #ifndef OVERRIDE_silk_CLZ16 static OPUS_INLINE opus_int32 silk_CLZ16(opus_int16 in16) { diff --git a/src/libopus/silk/main.h b/src/libopus/silk/main.h index 8d9f560c..cd576d8c 100644 --- a/src/libopus/silk/main.h +++ b/src/libopus/silk/main.h @@ -35,8 +35,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "PLC.h" #include "control.h" #include "debug.h" -#include "../celt/entenc.h" -#include "../celt/entdec.h" +#include "entenc.h" +#include "entdec.h" #if defined(OPUS_X86_MAY_HAVE_SSE4_1) #include "x86/main_sse.h" @@ -247,21 +247,21 @@ void silk_VQ_WMat_EC_c( /************************************/ void silk_NSQ_c( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int16 x16[], /* I Input */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const opus_int16 x16[], /* I Input */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 *PredCoef_Q12, /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ ); #if !defined(OVERRIDE_silk_NSQ) @@ -273,21 +273,21 @@ void silk_NSQ_c( /* Noise shaping using delayed decision */ void silk_NSQ_del_dec_c( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int16 x16[], /* I Input */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const opus_int16 x16[], /* I Input */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 *PredCoef_Q12, /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ ); #if !defined(OVERRIDE_silk_NSQ_del_dec) @@ -389,6 +389,10 @@ void silk_NLSF_decode( /****************************************************/ /* Decoder Functions */ /****************************************************/ +opus_int silk_reset_decoder( + silk_decoder_state *psDec /* I/O Decoder state pointer */ +); + opus_int silk_init_decoder( silk_decoder_state *psDec /* I/O Decoder state pointer */ ); @@ -410,6 +414,12 @@ opus_int silk_decode_frame( opus_int32 *pN, /* O Pointer to size of output frame */ opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ opus_int condCoding, /* I The type of conditional coding to use */ +#ifdef ENABLE_DEEP_PLC + LPCNetPLCState *lpcnet, +#endif +#ifdef ENABLE_OSCE + OSCEModel *osce_model, +#endif int arch /* I Run-time architecture */ ); diff --git a/src/libopus/silk/main_FIX.h b/src/libopus/silk/main_FIX.h new file mode 100644 index 00000000..4143f360 --- /dev/null +++ b/src/libopus/silk/main_FIX.h @@ -0,0 +1 @@ +#include "fixed/main_FIX.h" diff --git a/src/libopus/silk/opus.h b/src/libopus/silk/opus.h new file mode 100644 index 00000000..0a1b59ca --- /dev/null +++ b/src/libopus/silk/opus.h @@ -0,0 +1 @@ +#include "../include/opus.h" diff --git a/src/libopus/silk/opus_custom.h b/src/libopus/silk/opus_custom.h new file mode 100644 index 00000000..f54a1034 --- /dev/null +++ b/src/libopus/silk/opus_custom.h @@ -0,0 +1 @@ +#include "../include/opus_custom.h" diff --git a/src/libopus/silk/opus_defines.h b/src/libopus/silk/opus_defines.h new file mode 100644 index 00000000..dcc24434 --- /dev/null +++ b/src/libopus/silk/opus_defines.h @@ -0,0 +1 @@ +#include "../include/opus_defines.h" diff --git a/src/libopus/silk/opus_multistream.h b/src/libopus/silk/opus_multistream.h new file mode 100644 index 00000000..89f62298 --- /dev/null +++ b/src/libopus/silk/opus_multistream.h @@ -0,0 +1 @@ +#include "../include/opus_multistream.h" diff --git a/src/libopus/silk/opus_projection.h b/src/libopus/silk/opus_projection.h new file mode 100644 index 00000000..72f59cc1 --- /dev/null +++ b/src/libopus/silk/opus_projection.h @@ -0,0 +1 @@ +#include "../include/opus_projection.h" diff --git a/src/libopus/silk/opus_types.h b/src/libopus/silk/opus_types.h new file mode 100644 index 00000000..a7958a5d --- /dev/null +++ b/src/libopus/silk/opus_types.h @@ -0,0 +1 @@ +#include "../include/opus_types.h" diff --git a/src/libopus/silk/os_support.h b/src/libopus/silk/os_support.h new file mode 100644 index 00000000..dc47379f --- /dev/null +++ b/src/libopus/silk/os_support.h @@ -0,0 +1 @@ +#include "../celt/os_support.h" diff --git a/src/libopus/silk/pitch_est_tables.c b/src/libopus/silk/pitch_est_tables.c index 660c3d6a..3706f21e 100644 --- a/src/libopus/silk/pitch_est_tables.c +++ b/src/libopus/silk/pitch_est_tables.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "typedef.h" #include "pitch_est_defines.h" diff --git a/src/libopus/silk/process_NLSFs.c b/src/libopus/silk/process_NLSFs.c index a9b606af..b1f23141 100644 --- a/src/libopus/silk/process_NLSFs.c +++ b/src/libopus/silk/process_NLSFs.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/quant_LTP_gains.c b/src/libopus/silk/quant_LTP_gains.c index f8dc4c3a..197a13cc 100644 --- a/src/libopus/silk/quant_LTP_gains.c +++ b/src/libopus/silk/quant_LTP_gains.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" #include "tuning_parameters.h" diff --git a/src/libopus/silk/resampler.c b/src/libopus/silk/resampler.c index a2f05b0b..1f3e6424 100644 --- a/src/libopus/silk/resampler.c +++ b/src/libopus/silk/resampler.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif /* * Matrix of resampling methods used: diff --git a/src/libopus/silk/resampler_down2.c b/src/libopus/silk/resampler_down2.c index bb5d0116..2fcd156b 100644 --- a/src/libopus/silk/resampler_down2.c +++ b/src/libopus/silk/resampler_down2.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "SigProc_FIX.h" #include "resampler_rom.h" diff --git a/src/libopus/silk/resampler_down2_3.c b/src/libopus/silk/resampler_down2_3.c index d8ce95c6..595f00c3 100644 --- a/src/libopus/silk/resampler_down2_3.c +++ b/src/libopus/silk/resampler_down2_3.c @@ -25,13 +25,13 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "SigProc_FIX.h" #include "resampler_private.h" -#include "../celt/stack_alloc.h" +#include "stack_alloc.h" #define ORDER_FIR 4 diff --git a/src/libopus/silk/resampler_private_AR2.c b/src/libopus/silk/resampler_private_AR2.c index 0aed3807..8468578d 100644 --- a/src/libopus/silk/resampler_private_AR2.c +++ b/src/libopus/silk/resampler_private_AR2.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "SigProc_FIX.h" #include "resampler_private.h" diff --git a/src/libopus/silk/resampler_private_IIR_FIR.c b/src/libopus/silk/resampler_private_IIR_FIR.c index 867a15ce..5aff032e 100644 --- a/src/libopus/silk/resampler_private_IIR_FIR.c +++ b/src/libopus/silk/resampler_private_IIR_FIR.c @@ -25,13 +25,13 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "SigProc_FIX.h" #include "resampler_private.h" -#include "../celt/stack_alloc.h" +#include "stack_alloc.h" static OPUS_INLINE opus_int16 *silk_resampler_private_IIR_FIR_INTERPOL( opus_int16 *out, diff --git a/src/libopus/silk/resampler_private_down_FIR.c b/src/libopus/silk/resampler_private_down_FIR.c index 274284fb..4ee88979 100644 --- a/src/libopus/silk/resampler_private_down_FIR.c +++ b/src/libopus/silk/resampler_private_down_FIR.c @@ -25,13 +25,13 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "SigProc_FIX.h" #include "resampler_private.h" -#include "../celt/stack_alloc.h" +#include "stack_alloc.h" static OPUS_INLINE opus_int16 *silk_resampler_private_down_FIR_INTERPOL( opus_int16 *out, diff --git a/src/libopus/silk/resampler_private_up2_HQ.c b/src/libopus/silk/resampler_private_up2_HQ.c index f5fd6de3..db8ce7fb 100644 --- a/src/libopus/silk/resampler_private_up2_HQ.c +++ b/src/libopus/silk/resampler_private_up2_HQ.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "SigProc_FIX.h" #include "resampler_private.h" diff --git a/src/libopus/silk/resampler_rom.c b/src/libopus/silk/resampler_rom.c index a684bcd2..70d9d785 100644 --- a/src/libopus/silk/resampler_rom.c +++ b/src/libopus/silk/resampler_rom.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif /* Filter coefficients for IIR/FIR polyphase resampling * * Total size: 179 Words (358 Bytes) */ diff --git a/src/libopus/silk/shell_coder.c b/src/libopus/silk/shell_coder.c index d8c1d704..6efa4eac 100644 --- a/src/libopus/silk/shell_coder.c +++ b/src/libopus/silk/shell_coder.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/sigm_Q15.c b/src/libopus/silk/sigm_Q15.c index 8afdcb90..75c872ec 100644 --- a/src/libopus/silk/sigm_Q15.c +++ b/src/libopus/silk/sigm_Q15.c @@ -25,25 +25,24 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif -#include +#ifdef __STDC__ +#include "config.h" +#endif /* Approximate sigmoid function */ #include "SigProc_FIX.h" /* fprintf(1, '%d, ', round(1024 * ([1 ./ (1 + exp(-(1:5))), 1] - 1 ./ (1 + exp(-(0:5)))))); */ -static const opus_int32 sigm_LUT_slope_Q10[ 6 ] PROGMEM = { +static const opus_int32 sigm_LUT_slope_Q10[ 6 ] = { 237, 153, 73, 30, 12, 7 }; /* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp(-(0:5))))); */ -static const opus_int32 sigm_LUT_pos_Q15[ 6 ] PROGMEM = { +static const opus_int32 sigm_LUT_pos_Q15[ 6 ] = { 16384, 23955, 28861, 31213, 32178, 32548 }; /* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp((0:5))))); */ -static const opus_int32 sigm_LUT_neg_Q15[ 6 ] PROGMEM = { +static const opus_int32 sigm_LUT_neg_Q15[ 6 ] = { 16384, 8812, 3906, 1554, 589, 219 }; diff --git a/src/libopus/silk/sort.c b/src/libopus/silk/sort.c index 2aeea6ef..776e0884 100644 --- a/src/libopus/silk/sort.c +++ b/src/libopus/silk/sort.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif /* Insertion sort (fast for already almost sorted arrays): */ /* Best case: O(n) for an already sorted array */ diff --git a/src/libopus/silk/stack_alloc.h b/src/libopus/silk/stack_alloc.h new file mode 100644 index 00000000..416720bf --- /dev/null +++ b/src/libopus/silk/stack_alloc.h @@ -0,0 +1 @@ +#include "../celt/stack_alloc.h" diff --git a/src/libopus/silk/stereo_LR_to_MS.c b/src/libopus/silk/stereo_LR_to_MS.c index f19acbb9..70501c2d 100644 --- a/src/libopus/silk/stereo_LR_to_MS.c +++ b/src/libopus/silk/stereo_LR_to_MS.c @@ -25,12 +25,12 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" -#include "../celt/stack_alloc.h" +#include "stack_alloc.h" /* Convert Left/Right stereo signal to adaptive Mid/Side representation */ void silk_stereo_LR_to_MS( @@ -77,7 +77,7 @@ void silk_stereo_LR_to_MS( ALLOC( LP_mid, frame_length, opus_int16 ); ALLOC( HP_mid, frame_length, opus_int16 ); for( n = 0; n < frame_length; n++ ) { - sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 2 ); + sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT32( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 2 ); LP_mid[ n ] = sum; HP_mid[ n ] = mid[ n + 1 ] - sum; } @@ -86,7 +86,7 @@ void silk_stereo_LR_to_MS( ALLOC( LP_side, frame_length, opus_int16 ); ALLOC( HP_side, frame_length, opus_int16 ); for( n = 0; n < frame_length; n++ ) { - sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( side[ n ] + (opus_int32)side[ n + 2 ], side[ n + 1 ], 1 ), 2 ); + sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT32( side[ n ] + (opus_int32)side[ n + 2 ], side[ n + 1 ], 1 ), 2 ); LP_side[ n ] = sum; HP_side[ n ] = side[ n + 1 ] - sum; } @@ -207,7 +207,7 @@ void silk_stereo_LR_to_MS( pred0_Q13 += delta0_Q13; pred1_Q13 += delta1_Q13; w_Q24 += deltaw_Q24; - sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */ + sum = silk_LSHIFT( silk_ADD_LSHIFT32( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */ sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */ sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); @@ -217,7 +217,7 @@ void silk_stereo_LR_to_MS( pred1_Q13 = -pred_Q13[ 1 ]; w_Q24 = silk_LSHIFT( width_Q14, 10 ); for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) { - sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */ + sum = silk_LSHIFT( silk_ADD_LSHIFT32( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */ sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */ sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); diff --git a/src/libopus/silk/stereo_MS_to_LR.c b/src/libopus/silk/stereo_MS_to_LR.c index e6e94b1d..26342fb3 100644 --- a/src/libopus/silk/stereo_MS_to_LR.c +++ b/src/libopus/silk/stereo_MS_to_LR.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" @@ -59,7 +59,7 @@ void silk_stereo_MS_to_LR( for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) { pred0_Q13 += delta0_Q13; pred1_Q13 += delta1_Q13; - sum = silk_LSHIFT( silk_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */ + sum = silk_LSHIFT( silk_ADD_LSHIFT32( x1[ n ] + (opus_int32)x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */ sum = silk_SMLAWB( silk_LSHIFT( (opus_int32)x2[ n + 1 ], 8 ), sum, pred0_Q13 ); /* Q8 */ sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)x1[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ x2[ n + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); @@ -67,7 +67,7 @@ void silk_stereo_MS_to_LR( pred0_Q13 = pred_Q13[ 0 ]; pred1_Q13 = pred_Q13[ 1 ]; for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) { - sum = silk_LSHIFT( silk_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */ + sum = silk_LSHIFT( silk_ADD_LSHIFT32( x1[ n ] + (opus_int32)x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */ sum = silk_SMLAWB( silk_LSHIFT( (opus_int32)x2[ n + 1 ], 8 ), sum, pred0_Q13 ); /* Q8 */ sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)x1[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ x2[ n + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); diff --git a/src/libopus/silk/stereo_decode_pred.c b/src/libopus/silk/stereo_decode_pred.c index 513d4d37..b6075f9f 100644 --- a/src/libopus/silk/stereo_decode_pred.c +++ b/src/libopus/silk/stereo_decode_pred.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/stereo_encode_pred.c b/src/libopus/silk/stereo_encode_pred.c index 19c1c760..ef1edcd5 100644 --- a/src/libopus/silk/stereo_encode_pred.c +++ b/src/libopus/silk/stereo_encode_pred.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/stereo_find_predictor.c b/src/libopus/silk/stereo_find_predictor.c index 0a53ad36..96cd3e5b 100644 --- a/src/libopus/silk/stereo_find_predictor.c +++ b/src/libopus/silk/stereo_find_predictor.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/stereo_quant_pred.c b/src/libopus/silk/stereo_quant_pred.c index 4ad28653..5f349da2 100644 --- a/src/libopus/silk/stereo_quant_pred.c +++ b/src/libopus/silk/stereo_quant_pred.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "main.h" diff --git a/src/libopus/silk/structs.h b/src/libopus/silk/structs.h index 02a0ed1a..38243be1 100644 --- a/src/libopus/silk/structs.h +++ b/src/libopus/silk/structs.h @@ -31,8 +31,23 @@ POSSIBILITY OF SUCH DAMAGE. #include "typedef.h" #include "SigProc_FIX.h" #include "define.h" -#include "../celt/entenc.h" -#include "../celt/entdec.h" +#include "entenc.h" +#include "entdec.h" + +#ifdef ENABLE_DEEP_PLC +#include "lpcnet.h" +#include "lpcnet_private.h" +#endif + +#ifdef ENABLE_DRED +#include "dred_encoder.h" +#include "dred_decoder.h" +#endif + +#ifdef ENABLE_OSCE +#include "osce_config.h" +#include "osce_structs.h" +#endif #ifdef __cplusplus extern "C" @@ -228,6 +243,14 @@ typedef struct { } silk_encoder_state; +#ifdef ENABLE_OSCE +typedef struct { + OSCEFeatureState features; + OSCEState state; + int method; +} silk_OSCE_struct; +#endif + /* Struct for Packet Loss Concealment */ typedef struct { opus_int32 pitchL_Q8; /* Pitch lag to use for voiced concealment */ @@ -243,6 +266,7 @@ typedef struct { opus_int fs_kHz; opus_int nb_subfr; opus_int subfr_length; + opus_int enable_deep_plc; } silk_PLC_struct; /* Struct for CNG */ @@ -259,6 +283,10 @@ typedef struct { /* Decoder state */ /********************************/ typedef struct { +#ifdef ENABLE_OSCE + silk_OSCE_struct osce; +#endif +#define SILK_DECODER_STATE_RESET_START prev_gain_Q16 opus_int32 prev_gain_Q16; opus_int32 exc_Q14[ MAX_FRAME_LENGTH ]; opus_int32 sLPC_Q14_buf[ MAX_LPC_ORDER ]; diff --git a/src/libopus/silk/structs_FIX.h b/src/libopus/silk/structs_FIX.h new file mode 100644 index 00000000..e46bd479 --- /dev/null +++ b/src/libopus/silk/structs_FIX.h @@ -0,0 +1 @@ +#include "fixed/structs_FIX.h" diff --git a/src/libopus/silk/sum_sqr_shift.c b/src/libopus/silk/sum_sqr_shift.c index df0bd2e6..5b335079 100644 --- a/src/libopus/silk/sum_sqr_shift.c +++ b/src/libopus/silk/sum_sqr_shift.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "SigProc_FIX.h" diff --git a/src/libopus/silk/table_LSF_cos.c b/src/libopus/silk/table_LSF_cos.c index a78748ee..6608f5d2 100644 --- a/src/libopus/silk/table_LSF_cos.c +++ b/src/libopus/silk/table_LSF_cos.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "tables.h" diff --git a/src/libopus/silk/tables_LTP.c b/src/libopus/silk/tables_LTP.c index ce736e85..e79edd92 100644 --- a/src/libopus/silk/tables_LTP.c +++ b/src/libopus/silk/tables_LTP.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "tables.h" diff --git a/src/libopus/silk/tables_NLSF_CB_NB_MB.c b/src/libopus/silk/tables_NLSF_CB_NB_MB.c index ce76ea8c..4ef4e124 100644 --- a/src/libopus/silk/tables_NLSF_CB_NB_MB.c +++ b/src/libopus/silk/tables_NLSF_CB_NB_MB.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "tables.h" diff --git a/src/libopus/silk/tables_NLSF_CB_WB.c b/src/libopus/silk/tables_NLSF_CB_WB.c index f0b35552..1baa75c9 100644 --- a/src/libopus/silk/tables_NLSF_CB_WB.c +++ b/src/libopus/silk/tables_NLSF_CB_WB.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "tables.h" diff --git a/src/libopus/silk/tables_gain.c b/src/libopus/silk/tables_gain.c index b79eb2b1..47b659af 100644 --- a/src/libopus/silk/tables_gain.c +++ b/src/libopus/silk/tables_gain.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "tables.h" diff --git a/src/libopus/silk/tables_other.c b/src/libopus/silk/tables_other.c index a15c06e0..045a7e4e 100644 --- a/src/libopus/silk/tables_other.c +++ b/src/libopus/silk/tables_other.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "structs.h" #include "define.h" diff --git a/src/libopus/silk/tables_pitch_lag.c b/src/libopus/silk/tables_pitch_lag.c index 50701a18..bb275217 100644 --- a/src/libopus/silk/tables_pitch_lag.c +++ b/src/libopus/silk/tables_pitch_lag.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "tables.h" diff --git a/src/libopus/silk/tables_pulses_per_block.c b/src/libopus/silk/tables_pulses_per_block.c index fd22b3ee..83935b02 100644 --- a/src/libopus/silk/tables_pulses_per_block.c +++ b/src/libopus/silk/tables_pulses_per_block.c @@ -25,9 +25,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "../config.h" -//#endif +#ifdef __STDC__ +#include "config.h" +#endif #include "tables.h" diff --git a/src/libopus/silk/typedef.h b/src/libopus/silk/typedef.h index 58ef72bf..793d2c0c 100644 --- a/src/libopus/silk/typedef.h +++ b/src/libopus/silk/typedef.h @@ -28,8 +28,8 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef SILK_TYPEDEF_H #define SILK_TYPEDEF_H -#include "../opus_types.h" -#include "../opus_defines.h" +#include "opus_types.h" +#include "opus_defines.h" #ifndef FIXED_POINT # include @@ -67,6 +67,9 @@ __attribute__((noreturn)) static OPUS_INLINE void _silk_fatal(const char *str, const char *file, int line) { fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str); +#if defined(_MSC_VER) + _set_abort_behavior( 0, _WRITE_ABORT_MSG); +#endif abort(); } # define silk_assert(COND) {if (!(COND)) {silk_fatal("assertion failed: " #COND);}} diff --git a/src/libopus/src/API.h b/src/libopus/src/API.h new file mode 100644 index 00000000..55ab447a --- /dev/null +++ b/src/libopus/src/API.h @@ -0,0 +1 @@ +#include "../silk/API.h" diff --git a/src/libopus/src/arch.h b/src/libopus/src/arch.h new file mode 100644 index 00000000..0530293d --- /dev/null +++ b/src/libopus/src/arch.h @@ -0,0 +1 @@ +#include "../celt/arch.h" diff --git a/src/libopus/src/celt.h b/src/libopus/src/celt.h new file mode 100644 index 00000000..f66c3ba0 --- /dev/null +++ b/src/libopus/src/celt.h @@ -0,0 +1 @@ +#include "../celt/celt.h" diff --git a/src/libopus/src/config.h b/src/libopus/src/config.h new file mode 100644 index 00000000..2989b6b0 --- /dev/null +++ b/src/libopus/src/config.h @@ -0,0 +1 @@ +#include "../include/config.h" diff --git a/src/libopus/src/cpu_support.h b/src/libopus/src/cpu_support.h new file mode 100644 index 00000000..32e7df22 --- /dev/null +++ b/src/libopus/src/cpu_support.h @@ -0,0 +1 @@ +#include "../celt/cpu_support.h" diff --git a/src/libopus/src/define.h b/src/libopus/src/define.h new file mode 100644 index 00000000..3a4554e1 --- /dev/null +++ b/src/libopus/src/define.h @@ -0,0 +1 @@ +#include "../silk/define.h" diff --git a/src/libopus/src/entdec.h b/src/libopus/src/entdec.h new file mode 100644 index 00000000..07f6c038 --- /dev/null +++ b/src/libopus/src/entdec.h @@ -0,0 +1 @@ +#include "../celt/entdec.h" diff --git a/src/libopus/src/float_cast.h b/src/libopus/src/float_cast.h new file mode 100644 index 00000000..84ec9349 --- /dev/null +++ b/src/libopus/src/float_cast.h @@ -0,0 +1 @@ +#include "../celt/float_cast.h" diff --git a/src/libopus/src/mathops.h b/src/libopus/src/mathops.h new file mode 100644 index 00000000..f4dee750 --- /dev/null +++ b/src/libopus/src/mathops.h @@ -0,0 +1 @@ +#include "../celt/mathops.h" diff --git a/src/libopus/src/modes.h b/src/libopus/src/modes.h new file mode 100644 index 00000000..5623259a --- /dev/null +++ b/src/libopus/src/modes.h @@ -0,0 +1 @@ +#include "../celt/modes.h" diff --git a/src/libopus/opus.c b/src/libopus/src/opus.c similarity index 97% rename from src/libopus/opus.c rename to src/libopus/src/opus.c index 5d09056b..c08de753 100644 --- a/src/libopus/opus.c +++ b/src/libopus/src/opus.c @@ -25,9 +25,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -//#ifdef HAVE_CONFIG_H +#ifdef __STDC__ #include "config.h" -//#endif +#endif #include "opus.h" #include "opus_private.h" @@ -194,7 +194,8 @@ int opus_packet_get_samples_per_frame(const unsigned char *data, int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, int self_delimited, unsigned char *out_toc, const unsigned char *frames[48], opus_int16 size[48], - int *payload_offset, opus_int32 *packet_offset) + int *payload_offset, opus_int32 *packet_offset, + const unsigned char **padding, opus_int32 *padding_len) { int i, bytes; int count; @@ -337,6 +338,11 @@ int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, data += size[i]; } + if (padding != NULL) + { + *padding = data; + *padding_len = pad; + } if (packet_offset) *packet_offset = pad+(opus_int32)(data-data0); @@ -351,6 +357,6 @@ int opus_packet_parse(const unsigned char *data, opus_int32 len, opus_int16 size[48], int *payload_offset) { return opus_packet_parse_impl(data, len, 0, out_toc, - frames, size, payload_offset, NULL); + frames, size, payload_offset, NULL, NULL, NULL); } diff --git a/src/libopus/src/opus.h b/src/libopus/src/opus.h new file mode 100644 index 00000000..0a1b59ca --- /dev/null +++ b/src/libopus/src/opus.h @@ -0,0 +1 @@ +#include "../include/opus.h" diff --git a/src/libopus/src/opus_custom.h b/src/libopus/src/opus_custom.h new file mode 100644 index 00000000..f54a1034 --- /dev/null +++ b/src/libopus/src/opus_custom.h @@ -0,0 +1 @@ +#include "../include/opus_custom.h" diff --git a/src/libopus/opus_decoder.c b/src/libopus/src/opus_decoder.c similarity index 68% rename from src/libopus/opus_decoder.c rename to src/libopus/src/opus_decoder.c index 23f9a01e..adef3f54 100644 --- a/src/libopus/opus_decoder.c +++ b/src/libopus/src/opus_decoder.c @@ -25,33 +25,41 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -//#ifdef HAVE_CONFIG_H +#ifdef __STDC__ # include "config.h" -//#endif +#endif #ifndef OPUS_BUILD # error "OPUS_BUILD _MUST_ be defined to build Opus. This probably means you need other defines as well, as in a config.h. See the included build files for details." #endif #if defined(__GNUC__) && (__GNUC__ >= 2) && !defined(__OPTIMIZE__) && !defined(OPUS_WILL_BE_SLOW) -// Yes, I know... -// # pragma message "You appear to be compiling without optimization, if so opus will be very slow." +# pragma message "You appear to be compiling without optimization, if so opus will be very slow." #endif #include -#include "celt/celt.h" +#include "celt.h" #include "opus.h" -#include "celt/entdec.h" -#include "celt/modes.h" -#include "silk/API.h" -#include "celt/stack_alloc.h" -#include "celt/float_cast.h" +#include "entdec.h" +#include "modes.h" +#include "API.h" +#include "stack_alloc.h" +#include "float_cast.h" #include "opus_private.h" -#include "celt/os_support.h" -#include "silk/structs.h" -#include "silk/define.h" -#include "celt/mathops.h" -#include "celt/cpu_support.h" +#include "os_support.h" +#include "structs.h" +#include "define.h" +#include "mathops.h" +#include "cpu_support.h" + +#ifdef ENABLE_DEEP_PLC +#include "dred_rdovae_dec_data.h" +#include "dred_rdovae_dec.h" +#endif + +#ifdef ENABLE_OSCE +#include "osce.h" +#endif struct OpusDecoder { int celt_dec_offset; @@ -60,7 +68,11 @@ struct OpusDecoder { opus_int32 Fs; /** Sampling rate (at the API level) */ silk_DecControlStruct DecControl; int decode_gain; + int complexity; int arch; +#ifdef ENABLE_DEEP_PLC + LPCNetPLCState lpcnet; +#endif /* Everything beyond this point gets cleared on a reset */ #define OPUS_DECODER_RESET_START stream_channels @@ -136,6 +148,7 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels) silk_dec = (char*)st+st->silk_dec_offset; celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); st->stream_channels = st->channels = channels; + st->complexity = 0; st->Fs = Fs; st->DecControl.API_sampleRate = st->Fs; @@ -153,6 +166,9 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels) st->prev_mode = 0; st->frame_size = Fs/400; +#ifdef ENABLE_DEEP_PLC + lpcnet_plc_init( &st->lpcnet); +#endif st->arch = opus_select_arch(); return OPUS_OK; } @@ -279,7 +295,8 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, ec_dec_init(&dec,(unsigned char*)data,len); } else { audiosize = frame_size; - mode = st->prev_mode; + /* Run PLC using last used mode (CELT if we ended with CELT redundancy) */ + mode = st->prev_redundancy ? MODE_CELT_ONLY : st->prev_mode; bandwidth = 0; if (mode == 0) @@ -370,7 +387,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, pcm_ptr = pcm_silk; if (st->prev_mode==MODE_CELT_ONLY) - silk_InitDecoder( silk_dec ); + silk_ResetDecoder( silk_dec ); /* The SILK PLC cannot produce frames of less than 10 ms */ st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs); @@ -394,14 +411,28 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, st->DecControl.internalSampleRate = 16000; } } + st->DecControl.enable_deep_plc = st->complexity >= 5; +#ifdef ENABLE_OSCE + st->DecControl.osce_method = OSCE_METHOD_NONE; +#ifndef DISABLE_LACE + if (st->complexity >= 6) {st->DecControl.osce_method = OSCE_METHOD_LACE;} +#endif +#ifndef DISABLE_NOLACE + if (st->complexity >= 7) {st->DecControl.osce_method = OSCE_METHOD_NOLACE;} +#endif +#endif - lost_flag = data == NULL ? 1 : 2 * decode_fec; + lost_flag = data == NULL ? 1 : 2 * !!decode_fec; decoded_samples = 0; do { /* Call SILK decoder */ int first_frame = decoded_samples == 0; silk_ret = silk_Decode( silk_dec, &st->DecControl, - lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size, st->arch ); + lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size, +#ifdef ENABLE_DEEP_PLC + &st->lpcnet, +#endif + st->arch ); if( silk_ret ) { if (lost_flag) { /* PLC failure should not be fatal */ @@ -420,7 +451,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, start_band = 0; if (!decode_fec && mode != MODE_CELT_ONLY && data != NULL - && ec_tell(&dec)+17+20*(st->mode == MODE_HYBRID) <= 8*len) + && ec_tell(&dec)+17+20*(mode == MODE_HYBRID) <= 8*len) { /* Check if we have a redundant 0-8 kHz band */ if (mode == MODE_HYBRID) @@ -500,6 +531,11 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, /* 5 ms redundant frame for CELT->SILK*/ if (redundancy && celt_to_silk) { + /* If the previous frame did not use CELT (the first redundancy frame in + a transition from SILK may have been lost) then the CELT decoder is + stale at this point and the redundancy audio is not useful, however + the final range is still needed (for testing), so the redundancy is + always decoded but the decoded audio may not be used */ MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0))); celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL, 0); @@ -516,8 +552,12 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy) MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_RESET_STATE)); /* Decode CELT */ - celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data, - len, pcm, celt_frame_size, &dec, celt_accum); + celt_ret = celt_decode_with_ec_dred(celt_dec, decode_fec ? NULL : data, + len, pcm, celt_frame_size, &dec, celt_accum +#ifdef ENABLE_DEEP_PLC + , &st->lpcnet +#endif + ); } else { unsigned char silence[2] = {0xFF, 0xFF}; if (!celt_accum) @@ -562,7 +602,10 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5, pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs); } - if (redundancy && celt_to_silk) + /* 5ms redundant frame for CELT->SILK; ignore if the previous frame did not + use CELT (the first redundancy frame in a transition from SILK may have + been lost) */ + if (redundancy && celt_to_silk && (st->prev_mode != MODE_SILK_ONLY || st->prev_redundancy)) { for (c=0;cchannels;c++) { @@ -626,7 +669,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, int opus_decode_native(OpusDecoder *st, const unsigned char *data, opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec, - int self_delimited, opus_int32 *packet_offset, int soft_clip) + int self_delimited, opus_int32 *packet_offset, int soft_clip, const OpusDRED *dred, opus_int32 dred_offset) { int i, nb_samples; int count, offset; @@ -640,6 +683,35 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data, /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */ if ((decode_fec || len==0 || data==NULL) && frame_size%(st->Fs/400)!=0) return OPUS_BAD_ARG; +#ifdef ENABLE_DRED + if (dred != NULL && dred->process_stage == 2) { + int F10; + int features_per_frame; + int needed_feature_frames; + int init_frames; + lpcnet_plc_fec_clear(&st->lpcnet); + F10 = st->Fs/100; + /* if blend==0, the last PLC call was "update" and we need to feed two extra 10-ms frames. */ + init_frames = (st->lpcnet.blend == 0) ? 2 : 0; + features_per_frame = IMAX(1, frame_size/F10); + needed_feature_frames = init_frames + features_per_frame; + lpcnet_plc_fec_clear(&st->lpcnet); + for (i=0;idred_offset*F10/4)/F10); + if (feature_offset <= 4*dred->nb_latents-1 && feature_offset >= 0) { + lpcnet_plc_fec_add(&st->lpcnet, dred->fec_features+feature_offset*DRED_NUM_FEATURES); + } else { + if (feature_offset >= 0) lpcnet_plc_fec_add(&st->lpcnet, NULL); + } + + } + } +#else + (void)dred; + (void)dred_offset; +#endif if (len==0 || data==NULL) { int pcm_count=0; @@ -664,7 +736,7 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data, packet_stream_channels = opus_packet_get_nb_channels(data); count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, - size, &offset, packet_offset); + size, &offset, packet_offset, NULL, NULL); if (count<0) return count; @@ -676,12 +748,12 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data, int ret; /* If no FEC can be present, run the PLC (recursive call) */ if (frame_size < packet_frame_size || packet_mode == MODE_CELT_ONLY || st->mode == MODE_CELT_ONLY) - return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL, soft_clip); + return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL, soft_clip, NULL, 0); /* Otherwise, run the PLC on everything except the size for which we might have FEC */ duration_copy = st->last_packet_duration; if (frame_size-packet_frame_size!=0) { - ret = opus_decode_native(st, NULL, 0, pcm, frame_size-packet_frame_size, 0, 0, NULL, soft_clip); + ret = opus_decode_native(st, NULL, 0, pcm, frame_size-packet_frame_size, 0, 0, NULL, soft_clip, NULL, 0); if (ret<0) { st->last_packet_duration = duration_copy; @@ -745,7 +817,7 @@ int opus_decode(OpusDecoder *st, const unsigned char *data, { if(frame_size<=0) return OPUS_BAD_ARG; - return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0); + return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0, NULL, 0); } #ifndef DISABLE_FLOAT_API @@ -773,7 +845,7 @@ int opus_decode_float(OpusDecoder *st, const unsigned char *data, celt_assert(st->channels == 1 || st->channels == 2); ALLOC(out, frame_size*st->channels, opus_int16); - ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0); + ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0, NULL, 0); if (ret > 0) { for (i=0;ichannels;i++) @@ -811,7 +883,7 @@ int opus_decode(OpusDecoder *st, const unsigned char *data, celt_assert(st->channels == 1 || st->channels == 2); ALLOC(out, frame_size*st->channels, float); - ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1); + ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1, NULL, 0); if (ret > 0) { for (i=0;ichannels;i++) @@ -826,7 +898,7 @@ int opus_decode_float(OpusDecoder *st, const unsigned char *data, { if(frame_size<=0) return OPUS_BAD_ARG; - return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0); + return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0, NULL, 0); } #endif @@ -856,6 +928,27 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...) *value = st->bandwidth; } break; + case OPUS_SET_COMPLEXITY_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if(value<0 || value>10) + { + goto bad_arg; + } + st->complexity = value; + celt_decoder_ctl(celt_dec, OPUS_SET_COMPLEXITY(value)); + } + break; + case OPUS_GET_COMPLEXITY_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->complexity; + } + break; case OPUS_GET_FINAL_RANGE_REQUEST: { opus_uint32 *value = va_arg(ap, opus_uint32*); @@ -873,9 +966,12 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...) ((char*)&st->OPUS_DECODER_RESET_START - (char*)st)); celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); - silk_InitDecoder( silk_dec ); + silk_ResetDecoder( silk_dec ); st->stream_channels = st->channels; st->frame_size = st->Fs/400; +#ifdef ENABLE_DEEP_PLC + lpcnet_plc_reset( &st->lpcnet ); +#endif } break; case OPUS_GET_SAMPLE_RATE_REQUEST: @@ -951,6 +1047,20 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...) ret = celt_decoder_ctl(celt_dec, OPUS_GET_PHASE_INVERSION_DISABLED(value)); } break; +#ifdef USE_WEIGHTS_FILE + case OPUS_SET_DNN_BLOB_REQUEST: + { + const unsigned char *data = va_arg(ap, const unsigned char *); + opus_int32 len = va_arg(ap, opus_int32); + if(len<0 || data == NULL) + { + goto bad_arg; + } + ret = lpcnet_plc_load_model(&st->lpcnet, data, len); + ret = silk_LoadOSCEModels(silk_dec, data, len) || ret; + } + break; +#endif default: /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/ ret = OPUS_UNIMPLEMENTED; @@ -1026,8 +1136,373 @@ int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, return samples; } +int opus_packet_has_lbrr(const unsigned char packet[], opus_int32 len) +{ + int ret; + const unsigned char *frames[48]; + opus_int16 size[48]; + int packet_mode, packet_frame_size, packet_stream_channels; + int nb_frames=1; + int lbrr; + + packet_mode = opus_packet_get_mode(packet); + if (packet_mode == MODE_CELT_ONLY) + return 0; + packet_frame_size = opus_packet_get_samples_per_frame(packet, 48000); + if (packet_frame_size > 960) + nb_frames = packet_frame_size/960; + packet_stream_channels = opus_packet_get_nb_channels(packet); + ret = opus_packet_parse(packet, len, NULL, frames, size, NULL); + if (ret <= 0) + return ret; + lbrr = (frames[0][0] >> (7-nb_frames)) & 0x1; + if (packet_stream_channels == 2) + lbrr = lbrr || ((frames[0][0] >> (6-2*nb_frames)) & 0x1); + return lbrr; +} + int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], opus_int32 len) { return opus_packet_get_nb_samples(packet, len, dec->Fs); } + +struct OpusDREDDecoder { +#ifdef ENABLE_DRED + RDOVAEDec model; +#endif + int loaded; + int arch; + opus_uint32 magic; +}; + +#if defined(ENABLE_DRED) && (defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)) +static void validate_dred_decoder(OpusDREDDecoder *st) +{ + celt_assert(st->magic == 0xD8EDDEC0); +#ifdef OPUS_ARCHMASK + celt_assert(st->arch >= 0); + celt_assert(st->arch <= OPUS_ARCHMASK); +#endif +} +#define VALIDATE_DRED_DECODER(st) validate_dred_decoder(st) +#else +#define VALIDATE_DRED_DECODER(st) +#endif + + +int opus_dred_decoder_get_size(void) +{ + return sizeof(OpusDREDDecoder); +} + +#ifdef ENABLE_DRED +int dred_decoder_load_model(OpusDREDDecoder *dec, const unsigned char *data, int len) +{ + WeightArray *list; + int ret; + parse_weights(&list, data, len); + ret = init_rdovaedec(&dec->model, list); + opus_free(list); + if (ret == 0) dec->loaded = 1; + return (ret == 0) ? OPUS_OK : OPUS_BAD_ARG; +} +#endif + +int opus_dred_decoder_init(OpusDREDDecoder *dec) +{ + int ret = 0; + dec->loaded = 0; +#if defined(ENABLE_DRED) && !defined(USE_WEIGHTS_FILE) + ret = init_rdovaedec(&dec->model, rdovaedec_arrays); + if (ret == 0) dec->loaded = 1; +#endif + dec->arch = opus_select_arch(); + /* To make sure nobody forgets to init, use a magic number. */ + dec->magic = 0xD8EDDEC0; + return (ret == 0) ? OPUS_OK : OPUS_UNIMPLEMENTED; +} + +OpusDREDDecoder *opus_dred_decoder_create(int *error) +{ + int ret; + OpusDREDDecoder *dec; + dec = (OpusDREDDecoder *)opus_alloc(opus_dred_decoder_get_size()); + if (dec == NULL) + { + if (error) + *error = OPUS_ALLOC_FAIL; + return NULL; + } + ret = opus_dred_decoder_init(dec); + if (error) + *error = ret; + if (ret != OPUS_OK) + { + opus_free(dec); + dec = NULL; + } + return dec; +} + +void opus_dred_decoder_destroy(OpusDREDDecoder *dec) +{ + if (dec) dec->magic = 0xDE57801D; + opus_free(dec); +} + +int opus_dred_decoder_ctl(OpusDREDDecoder *dred_dec, int request, ...) +{ +#ifdef ENABLE_DRED + int ret = OPUS_OK; + va_list ap; + + va_start(ap, request); + (void)dred_dec; + switch (request) + { +# ifdef USE_WEIGHTS_FILE + case OPUS_SET_DNN_BLOB_REQUEST: + { + const unsigned char *data = va_arg(ap, const unsigned char *); + opus_int32 len = va_arg(ap, opus_int32); + if(len<0 || data == NULL) + { + goto bad_arg; + } + return dred_decoder_load_model(dred_dec, data, len); + } + break; +# endif + default: + /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/ + ret = OPUS_UNIMPLEMENTED; + break; + } + va_end(ap); + return ret; +# ifdef USE_WEIGHTS_FILE +bad_arg: + va_end(ap); + return OPUS_BAD_ARG; +# endif +#else + (void)dred_dec; + (void)request; + return OPUS_UNIMPLEMENTED; +#endif +} + +#ifdef ENABLE_DRED +static int dred_find_payload(const unsigned char *data, opus_int32 len, const unsigned char **payload, int *dred_frame_offset) +{ + const unsigned char *data0; + int len0; + int frame = 0; + int ret; + const unsigned char *frames[48]; + opus_int16 size[48]; + int frame_size; + + *payload = NULL; + /* Get the padding section of the packet. */ + ret = opus_packet_parse_impl(data, len, 0, NULL, frames, size, NULL, NULL, &data0, &len0); + if (ret < 0) + return ret; + frame_size = opus_packet_get_samples_per_frame(data, 48000); + data = data0; + len = len0; + /* Scan extensions in order until we find the earliest frame with DRED data. */ + while (len > 0) + { + opus_int32 header_size; + int id, L; + len0 = len; + data0 = data; + id = *data0 >> 1; + L = *data0 & 0x1; + len = skip_extension(&data, len, &header_size); + if (len < 0) + break; + if (id == 1) + { + if (L==0) + { + frame++; + } else { + frame += data0[1]; + } + } else if (id == DRED_EXTENSION_ID) + { + const unsigned char *curr_payload; + opus_int32 curr_payload_len; + curr_payload = data0+header_size; + curr_payload_len = (data-data0)-header_size; + /* DRED position in the packet, in units of 2.5 ms like for the signaled DRED offset. */ + *dred_frame_offset = frame*frame_size/120; +#ifdef DRED_EXPERIMENTAL_VERSION + /* Check that temporary extension type and version match. + This check will be removed once extension is finalized. */ + if (curr_payload_len > DRED_EXPERIMENTAL_BYTES && curr_payload[0] == 'D' && curr_payload[1] == DRED_EXPERIMENTAL_VERSION) { + *payload = curr_payload+2; + return curr_payload_len-2; + } +#else + if (curr_payload_len > 0) { + *payload = curr_payload; + return curr_payload_len; + } +#endif + } + } + return 0; +} +#endif + +int opus_dred_get_size(void) +{ +#ifdef ENABLE_DRED + return sizeof(OpusDRED); +#else + return 0; +#endif +} + +OpusDRED *opus_dred_alloc(int *error) +{ +#ifdef ENABLE_DRED + OpusDRED *dec; + dec = (OpusDRED *)opus_alloc(opus_dred_get_size()); + if (dec == NULL) + { + if (error) + *error = OPUS_ALLOC_FAIL; + return NULL; + } + return dec; +#else + if (error) + *error = OPUS_UNIMPLEMENTED; + return NULL; +#endif +} + +void opus_dred_free(OpusDRED *dec) +{ +#ifdef ENABLE_DRED + opus_free(dec); +#else + (void)dec; +#endif +} + +int opus_dred_parse(OpusDREDDecoder *dred_dec, OpusDRED *dred, const unsigned char *data, opus_int32 len, opus_int32 max_dred_samples, opus_int32 sampling_rate, int *dred_end, int defer_processing) +{ +#ifdef ENABLE_DRED + const unsigned char *payload; + opus_int32 payload_len; + int dred_frame_offset=0; + VALIDATE_DRED_DECODER(dred_dec); + if (!dred_dec->loaded) return OPUS_UNIMPLEMENTED; + dred->process_stage = -1; + payload_len = dred_find_payload(data, len, &payload, &dred_frame_offset); + if (payload_len < 0) + return payload_len; + if (payload != NULL) + { + int offset; + int min_feature_frames; + offset = 100*max_dred_samples/sampling_rate; + min_feature_frames = IMIN(2 + offset, 2*DRED_NUM_REDUNDANCY_FRAMES); + dred_ec_decode(dred, payload, payload_len, min_feature_frames, dred_frame_offset); + if (!defer_processing) + opus_dred_process(dred_dec, dred, dred); + if (dred_end) *dred_end = IMAX(0, -dred->dred_offset*sampling_rate/400); + return IMAX(0, dred->nb_latents*sampling_rate/25 - dred->dred_offset* sampling_rate/400); + } + if (dred_end) *dred_end = 0; + return 0; +#else + (void)dred_dec; + (void)dred; + (void)data; + (void)len; + (void)max_dred_samples; + (void)sampling_rate; + (void)defer_processing; + (void)dred_end; + return OPUS_UNIMPLEMENTED; +#endif +} + +int opus_dred_process(OpusDREDDecoder *dred_dec, const OpusDRED *src, OpusDRED *dst) +{ +#ifdef ENABLE_DRED + if (dred_dec == NULL || src == NULL || dst == NULL || (src->process_stage != 1 && src->process_stage != 2)) + return OPUS_BAD_ARG; + VALIDATE_DRED_DECODER(dred_dec); + if (!dred_dec->loaded) return OPUS_UNIMPLEMENTED; + if (src != dst) + OPUS_COPY(dst, src, 1); + if (dst->process_stage == 2) + return OPUS_OK; + DRED_rdovae_decode_all(&dred_dec->model, dst->fec_features, dst->state, dst->latents, dst->nb_latents, dred_dec->arch); + dst->process_stage = 2; + return OPUS_OK; +#else + (void)dred_dec; + (void)src; + (void)dst; + return OPUS_UNIMPLEMENTED; +#endif +} + +int opus_decoder_dred_decode(OpusDecoder *st, const OpusDRED *dred, opus_int32 dred_offset, opus_int16 *pcm, opus_int32 frame_size) +{ +#ifdef ENABLE_DRED + VARDECL(float, out); + int ret, i; + ALLOC_STACK; + + if(frame_size<=0) + { + RESTORE_STACK; + return OPUS_BAD_ARG; + } + + celt_assert(st->channels == 1 || st->channels == 2); + ALLOC(out, frame_size*st->channels, float); + + ret = opus_decode_native(st, NULL, 0, out, frame_size, 0, 0, NULL, 1, dred, dred_offset); + if (ret > 0) + { + for (i=0;ichannels;i++) + pcm[i] = FLOAT2INT16(out[i]); + } + RESTORE_STACK; + return ret; +#else + (void)st; + (void)dred; + (void)dred_offset; + (void)pcm; + (void)frame_size; + return OPUS_UNIMPLEMENTED; +#endif +} + +int opus_decoder_dred_decode_float(OpusDecoder *st, const OpusDRED *dred, opus_int32 dred_offset, float *pcm, opus_int32 frame_size) +{ +#ifdef ENABLE_DRED + if(frame_size<=0) + return OPUS_BAD_ARG; + return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL, 0, dred, dred_offset); +#else + (void)st; + (void)dred; + (void)dred_offset; + (void)pcm; + (void)frame_size; + return OPUS_UNIMPLEMENTED; +#endif +} diff --git a/src/libopus/src/opus_defines.h b/src/libopus/src/opus_defines.h new file mode 100644 index 00000000..dcc24434 --- /dev/null +++ b/src/libopus/src/opus_defines.h @@ -0,0 +1 @@ +#include "../include/opus_defines.h" diff --git a/src/libopus/src/opus_multistream.h b/src/libopus/src/opus_multistream.h new file mode 100644 index 00000000..89f62298 --- /dev/null +++ b/src/libopus/src/opus_multistream.h @@ -0,0 +1 @@ +#include "../include/opus_multistream.h" diff --git a/src/libopus/opus_private.h b/src/libopus/src/opus_private.h similarity index 84% rename from src/libopus/opus_private.h rename to src/libopus/src/opus_private.h index 8e48d42f..364c21ce 100644 --- a/src/libopus/opus_private.h +++ b/src/libopus/src/opus_private.h @@ -29,9 +29,9 @@ #ifndef OPUS_PRIVATE_H #define OPUS_PRIVATE_H -#include "celt/arch.h" +#include "arch.h" #include "opus.h" -#include "celt/celt.h" +#include "celt.h" #include /* va_list */ #include /* offsetof */ @@ -42,8 +42,17 @@ struct OpusRepacketizer { const unsigned char *frames[48]; opus_int16 len[48]; int framesize; + const unsigned char *paddings[48]; + opus_int32 padding_len[48]; }; +typedef struct { + int id; + int frame; + const unsigned char *data; + opus_int32 len; +} opus_extension_data; + typedef struct ChannelLayout { int nb_channels; int nb_streams; @@ -148,7 +157,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_ int opus_decode_native(OpusDecoder *st, const unsigned char *data, opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec, int self_delimited, - opus_int32 *packet_offset, int soft_clip); + opus_int32 *packet_offset, int soft_clip, const OpusDRED *dred, opus_int32 dred_offset); /* Make sure everything is properly aligned. */ static OPUS_INLINE int align(int i) @@ -162,13 +171,18 @@ static OPUS_INLINE int align(int i) return ((i + alignment - 1) / alignment) * alignment; } +/* More than that is ridiculous for now (3 * max frames per packet)*/ +opus_int32 skip_extension(const unsigned char **data, opus_int32 len, opus_int32 *header_size); + int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, int self_delimited, unsigned char *out_toc, const unsigned char *frames[48], opus_int16 size[48], - int *payload_offset, opus_int32 *packet_offset); + int *payload_offset, opus_int32 *packet_offset, + const unsigned char **padding, opus_int32 *padding_len); opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end, - unsigned char *data, opus_int32 maxlen, int self_delimited, int pad); + unsigned char *data, opus_int32 maxlen, int self_delimited, int pad, + const opus_extension_data *extensions, int nb_extensions); int pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len); @@ -198,4 +212,12 @@ int opus_multistream_decode_native( void *user_data ); +opus_int32 opus_packet_extensions_parse(const unsigned char *data, opus_int32 len, opus_extension_data *extensions, opus_int32 *nb_extensions); + +opus_int32 opus_packet_extensions_generate(unsigned char *data, opus_int32 len, const opus_extension_data *extensions, int nb_extensions, int pad); + +opus_int32 opus_packet_extensions_count(const unsigned char *data, opus_int32 len); + +opus_int32 opus_packet_pad_impl(unsigned char *data, opus_int32 len, opus_int32 new_len, int pad, const opus_extension_data *extensions, int nb_extensions); + #endif /* OPUS_PRIVATE_H */ diff --git a/src/libopus/src/opus_projection.h b/src/libopus/src/opus_projection.h new file mode 100644 index 00000000..72f59cc1 --- /dev/null +++ b/src/libopus/src/opus_projection.h @@ -0,0 +1 @@ +#include "../include/opus_projection.h" diff --git a/src/libopus/src/opus_types.h b/src/libopus/src/opus_types.h new file mode 100644 index 00000000..a7958a5d --- /dev/null +++ b/src/libopus/src/opus_types.h @@ -0,0 +1 @@ +#include "../include/opus_types.h" diff --git a/src/libopus/src/os_support.h b/src/libopus/src/os_support.h new file mode 100644 index 00000000..dc47379f --- /dev/null +++ b/src/libopus/src/os_support.h @@ -0,0 +1 @@ +#include "../celt/os_support.h" diff --git a/src/libopus/src/stack_alloc.h b/src/libopus/src/stack_alloc.h new file mode 100644 index 00000000..416720bf --- /dev/null +++ b/src/libopus/src/stack_alloc.h @@ -0,0 +1 @@ +#include "../celt/stack_alloc.h" diff --git a/src/libopus/src/structs.h b/src/libopus/src/structs.h new file mode 100644 index 00000000..336e73b0 --- /dev/null +++ b/src/libopus/src/structs.h @@ -0,0 +1 @@ +#include "../silk/structs.h" diff --git a/src/libopus/tansig_table.h b/src/libopus/tansig_table.h deleted file mode 100644 index c76f844a..00000000 --- a/src/libopus/tansig_table.h +++ /dev/null @@ -1,45 +0,0 @@ -/* This file is auto-generated by gen_tables */ - -static const float tansig_table[201] = { -0.000000f, 0.039979f, 0.079830f, 0.119427f, 0.158649f, -0.197375f, 0.235496f, 0.272905f, 0.309507f, 0.345214f, -0.379949f, 0.413644f, 0.446244f, 0.477700f, 0.507977f, -0.537050f, 0.564900f, 0.591519f, 0.616909f, 0.641077f, -0.664037f, 0.685809f, 0.706419f, 0.725897f, 0.744277f, -0.761594f, 0.777888f, 0.793199f, 0.807569f, 0.821040f, -0.833655f, 0.845456f, 0.856485f, 0.866784f, 0.876393f, -0.885352f, 0.893698f, 0.901468f, 0.908698f, 0.915420f, -0.921669f, 0.927473f, 0.932862f, 0.937863f, 0.942503f, -0.946806f, 0.950795f, 0.954492f, 0.957917f, 0.961090f, -0.964028f, 0.966747f, 0.969265f, 0.971594f, 0.973749f, -0.975743f, 0.977587f, 0.979293f, 0.980869f, 0.982327f, -0.983675f, 0.984921f, 0.986072f, 0.987136f, 0.988119f, -0.989027f, 0.989867f, 0.990642f, 0.991359f, 0.992020f, -0.992631f, 0.993196f, 0.993718f, 0.994199f, 0.994644f, -0.995055f, 0.995434f, 0.995784f, 0.996108f, 0.996407f, -0.996682f, 0.996937f, 0.997172f, 0.997389f, 0.997590f, -0.997775f, 0.997946f, 0.998104f, 0.998249f, 0.998384f, -0.998508f, 0.998623f, 0.998728f, 0.998826f, 0.998916f, -0.999000f, 0.999076f, 0.999147f, 0.999213f, 0.999273f, -0.999329f, 0.999381f, 0.999428f, 0.999472f, 0.999513f, -0.999550f, 0.999585f, 0.999617f, 0.999646f, 0.999673f, -0.999699f, 0.999722f, 0.999743f, 0.999763f, 0.999781f, -0.999798f, 0.999813f, 0.999828f, 0.999841f, 0.999853f, -0.999865f, 0.999875f, 0.999885f, 0.999893f, 0.999902f, -0.999909f, 0.999916f, 0.999923f, 0.999929f, 0.999934f, -0.999939f, 0.999944f, 0.999948f, 0.999952f, 0.999956f, -0.999959f, 0.999962f, 0.999965f, 0.999968f, 0.999970f, -0.999973f, 0.999975f, 0.999977f, 0.999978f, 0.999980f, -0.999982f, 0.999983f, 0.999984f, 0.999986f, 0.999987f, -0.999988f, 0.999989f, 0.999990f, 0.999990f, 0.999991f, -0.999992f, 0.999992f, 0.999993f, 0.999994f, 0.999994f, -0.999994f, 0.999995f, 0.999995f, 0.999996f, 0.999996f, -0.999996f, 0.999997f, 0.999997f, 0.999997f, 0.999997f, -0.999997f, 0.999998f, 0.999998f, 0.999998f, 0.999998f, -0.999998f, 0.999998f, 0.999999f, 0.999999f, 0.999999f, -0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, -0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, -1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, -1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, -1.000000f, -}; diff --git a/src/libtinysoundfont/README.ESP8266 b/src/libtinysoundfont/README.ESP8266 index e88104df..1009f36f 100644 --- a/src/libtinysoundfont/README.ESP8266 +++ b/src/libtinysoundfont/README.ESP8266 @@ -28,7 +28,7 @@ Even with the caching, it was found that SPIFFS, while having great functionality, was horrbly slow. So I wrote a new "faster" ROM filesystem called, surprisingly, FastROMFilesystem. https://github.com/earlephilhower/ESP8266FastROMFS -If you are getting choppy playback, try this new filesytem or using a SD +If you are getting choppy playback, try this new filesystem or using a SD card (not tested by myself, but it'd be hard top be slower than SPIFFS). Simply going from SPIFFS to FastROMFilesystem took my testing of FURELISE.MID and 1MGM.SF2 from 0.5x realtime to 2.5x (i.e. from unusable diff --git a/src/libtinysoundfont/tsf.h b/src/libtinysoundfont/tsf.h index e1a43221..41865ed9 100644 --- a/src/libtinysoundfont/tsf.h +++ b/src/libtinysoundfont/tsf.h @@ -1,47 +1,59 @@ -/* TinySoundFont - v0.8 - SoundFont2 synthesizer - https://github.com/schellingb/TinySoundFont +/* TinySoundFont - v0.8 - SoundFont2 synthesizer - https://github.com/schellingb/TinySoundFont no warranty implied; use at your own risk - Do this: + Do this: #define TSF_IMPLEMENTATION - before you include this file in *one* C or C++ file to create the implementation. - // i.e. it should look like this: - #include ... - #include ... - #define TSF_IMPLEMENTATION - #include "tsf.h" - - [OPTIONAL] #define TSF_NO_STDIO to remove stdio dependency - [OPTIONAL] #define TSF_MALLOC, TSF_REALLOC, and TSF_FREE to avoid stdlib.h - [OPTIONAL] #define TSF_MEMCPY, TSF_MEMSET to avoid string.h - [OPTIONAL] #define TSF_POW, TSF_POWF, TSF_EXPF, TSF_LOG, TSF_TAN, TSF_LOG10, TSF_SQRT to avoid math.h - - NOT YET IMPLEMENTED + before you include this file in *one* C or C++ file to create the implementation. + // i.e. it should look like this: + #include ... + #include ... + #define TSF_IMPLEMENTATION + #include "tsf.h" + + [OPTIONAL] #define TSF_NO_STDIO to remove stdio dependency + [OPTIONAL] #define TSF_MALLOC, TSF_REALLOC, and TSF_FREE to avoid stdlib.h + [OPTIONAL] #define TSF_MEMCPY, TSF_MEMSET to avoid string.h + [OPTIONAL] #define TSF_POW, TSF_POWF, TSF_EXPF, TSF_LOG, TSF_TAN, TSF_LOG10, TSF_SQRT to avoid math.h + + NOT YET IMPLEMENTED - Support for ChorusEffectsSend and ReverbEffectsSend generators - Better low-pass filter without lowering performance too much - Support for modulators - LICENSE (MIT) + LICENSE (MIT) - Copyright (C) 2017, 2018 Bernhard Schelling - Based on SFZero, Copyright (C) 2012 Steve Folta (https://github.com/stevefolta/SFZero) + Copyright (C) 2017, 2018 Bernhard Schelling + Based on SFZero, Copyright (C) 2012 Steve Folta (https://github.com/stevefolta/SFZero) - 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: + 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 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. + 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. */ +// ESP32 as of 3.x has a compiler bug in this section, with the G++ generated assembly +// being illegal. There's nothing wrong with the code here, it just looks like an +// Xtensa backend issue. Until that's fixed, no MIDI for you! +///home/earle/Arduino/libraries/ESP8266Audio/src/libtinysoundfont/tsf.h: In function 'void tsf_channel_midi_control(tsf*, int, int, int)': +// /home/earle/Arduino/libraries/ESP8266Audio/src/libtinysoundfont/tsf.h:2101:1: error: insn does not satisfy its constraints: +// 2101 | } +// | ^ + +#if defined(ESP32) && (__GNUC__ >= 8) && (__XTENSA__) +// Not defined, can't build +#else + #ifndef TSF_INCLUDE_TSF_INL #define TSF_INCLUDE_TSF_INL @@ -74,28 +86,27 @@ TSFDEF tsf* tsf_load_filename(const char* filename); TSFDEF tsf* tsf_load_memory(const void* buffer, int size); // Stream structure for the generic loading -struct tsf_stream -{ - // Custom data given to the functions as the first parameter - void* data; +struct tsf_stream { + // Custom data given to the functions as the first parameter + void* data; + + // Function pointer will be called to read 'size' bytes into ptr (returns number of read bytes) + int (*read)(void* data, void* ptr, unsigned int size); - // Function pointer will be called to read 'size' bytes into ptr (returns number of read bytes) - int (*read)(void* data, void* ptr, unsigned int size); + // Function pointer will be called to skip ahead over 'count' bytes + int (*tell)(void* data); - // Function pointer will be called to skip ahead over 'count' bytes - int (*tell)(void* data); + // Function pointer will be called to skip ahead over 'count' bytes (returns 1 on success, 0 on error) + int (*skip)(void* data, unsigned int count); - // Function pointer will be called to skip ahead over 'count' bytes (returns 1 on success, 0 on error) - int (*skip)(void* data, unsigned int count); + // Function pointer will be called to seek to absolute position + int (*seek)(void* data, unsigned int pos); - // Function pointer will be called to seek to absolute position - int (*seek)(void* data, unsigned int pos); + // Function pointer will be called to skip ahead over 'count' bytes + int (*close)(void* data); - // Function pointer will be called to skip ahead over 'count' bytes - int (*close)(void* data); - - // Function pointer will be called to skip ahead over 'count' bytes - int (*size)(void* data); + // Function pointer will be called to skip ahead over 'count' bytes + int (*size)(void* data); }; // Generic SoundFont loading method using the stream structure above @@ -104,7 +115,7 @@ TSFDEF tsf* tsf_load(struct tsf_stream* stream); // Free the memory related to this tsf instance TSFDEF void tsf_close(tsf* f); -// Stop all playing notes immediatly and reset all channel parameters +// Stop all playing notes immediately and reset all channel parameters TSFDEF void tsf_reset(tsf* f); // Returns the preset index from a bank and preset number, or -1 if it does not exist in the loaded SoundFont @@ -120,14 +131,13 @@ TSFDEF const char* tsf_get_presetname(const tsf* f, int preset_index); TSFDEF const char* tsf_bank_get_presetname(const tsf* f, int bank, int preset_number); // Supported output modes by the render methods -enum TSFOutputMode -{ - // Two channels with single left/right samples one after another - TSF_STEREO_INTERLEAVED, - // Two channels with all samples for the left channel first then right - TSF_STEREO_UNWEAVED, - // A single channel (stereo instruments are mixed into center) - TSF_MONO +enum TSFOutputMode { + // Two channels with single left/right samples one after another + TSF_STEREO_INTERLEAVED, + // Two channels with all samples for the left channel first then right + TSF_STEREO_UNWEAVED, + // A single channel (stereo instruments are mixed into center) + TSF_MONO }; // Thread safety: @@ -201,7 +211,7 @@ TSFDEF void tsf_channel_set_tuning(tsf* f, int channel, float tuning); TSFDEF void tsf_channel_note_on(tsf* f, int channel, int key, float vel); TSFDEF void tsf_channel_note_off(tsf* f, int channel, int key); TSFDEF void tsf_channel_note_off_all(tsf* f, int channel); //end with sustain and release -TSFDEF void tsf_channel_sounds_off_all(tsf* f, int channel); //end immediatly +TSFDEF void tsf_channel_sounds_off_all(tsf* f, int channel); //end immediately // Apply a MIDI control change to the channel (not all controllers are supported!) TSFDEF void tsf_channel_midi_control(tsf* f, int channel, int controller, int control_value); @@ -293,250 +303,344 @@ typedef char tsf_char20[20]; #define TSF_BUFFS 16 #define TSF_BUFFSIZE 512 -struct tsf -{ - struct tsf_preset* presets; - struct tsf_voice* voices; +struct tsf { + struct tsf_preset* presets; + struct tsf_voice* voices; - unsigned int fontSamplesOffset; - unsigned int fontSampleCount; - struct tsf_channels* channels; - float* outputSamples; + unsigned int fontSamplesOffset; + unsigned int fontSampleCount; + struct tsf_channels* channels; + float* outputSamples; - int presetNum; - int voiceNum; - int outputSampleSize; - unsigned int voicePlayIndex; + int presetNum; + int voiceNum; + int outputSampleSize; + unsigned int voicePlayIndex; - enum TSFOutputMode outputmode; - float outSampleRate; - float globalGainDB; + enum TSFOutputMode outputmode; + float outSampleRate; + float globalGainDB; - struct tsf_hydra *hydra; + struct tsf_hydra *hydra; - // Cached sample read - short *buffer[TSF_BUFFS]; - int offset[TSF_BUFFS]; - int timestamp[TSF_BUFFS]; - int epoch; + // Cached sample read + short *buffer[TSF_BUFFS]; + int offset[TSF_BUFFS]; + int timestamp[TSF_BUFFS]; + int epoch; }; struct tsf_stream_cached_data { - int buffs; - int buffsize; - struct tsf_stream *stream; - unsigned int size, pos; - unsigned char **buffer; - unsigned int *offset; - unsigned int *timestamp; - unsigned int epoch; - unsigned int hit; - unsigned int miss; + int buffs; + int buffsize; + struct tsf_stream *stream; + unsigned int size, pos; + unsigned char **buffer; + unsigned int *offset; + unsigned int *timestamp; + unsigned int epoch; + unsigned int hit; + unsigned int miss; }; -static int tsf_stream_cached_read(void* v, void* ptr, unsigned int size) -{ - struct tsf_stream_cached_data *d = (struct tsf_stream_cached_data*)v; - unsigned char *p = (unsigned char *)ptr; - - while (size) { - if (d->pos >= d->size) return 0; // EOF - for (int i=0; i < d->buffs; i++) { - if ((d->offset[i] <= d->pos) && ((d->offset[i] + d->buffsize) > d->pos) ) { - d->timestamp[i] = d->epoch++; - // Handle case of epoch rollover by just setting low, random epochs - if (d->epoch==0) { - for (int i=0; ibuffs; i++) d->timestamp[i] = d->epoch++; - } - unsigned int startOffset = d->pos - d->offset[i]; - unsigned int len = d->buffsize - (d->pos % d->buffsize); - if (len > size) len = size; - TSF_MEMCPY(p, &d->buffer[i][startOffset], len); - size -= len; - d->pos += len; - p += len; - d->hit++; - if (size == 0) return 1; - i = -1; // Restart the for() at block 0 after postincrement - } - } - - int repl = 0; - for (int i=1; i < d->buffs; i++) { - if (d->timestamp[i] < d->timestamp[repl]) repl = i; - } - int readOff = d->pos - (d->pos % d->buffsize); - d->stream->seek(d->stream->data, readOff); - d->stream->read(d->stream->data, d->buffer[repl], d->buffsize); - d->timestamp[repl] = d->epoch++; - d->offset[repl] = readOff; - d->miss++; - d->hit--; // Avoid counting this as a hit on next loop that returns data - // Don't actually do anything yet, we'll retry the search on next loop where it will notice new data - } - return 1; -} - -static int tsf_stream_cached_tell(void* v) -{ - struct tsf_stream_cached_data *d = (struct tsf_stream_cached_data*)v; - return d->pos; -} - -static int tsf_stream_cached_size(void* v) -{ - struct tsf_stream_cached_data *d = (struct tsf_stream_cached_data*)v; - return d->size; -} - -static int tsf_stream_cached_skip(void* v, unsigned int count) -{ - struct tsf_stream_cached_data *d = (struct tsf_stream_cached_data*)v; - if ((d->pos + count) < d->size) { - d->pos += count; - return 1; - } - return 0; -} - -static int tsf_stream_cached_seek(void* v, unsigned int pos) -{ - struct tsf_stream_cached_data *d = (struct tsf_stream_cached_data*)v; - if (pos < d->size) { - d->pos = pos; - return 1; - } - return 0; -} - -static int tsf_stream_cached_close(void* v) -{ - struct tsf_stream_cached_data *d = (struct tsf_stream_cached_data*)v; - free(d->timestamp); - free(d->offset); - for (int i = d->buffs - 1; i >=0; i--) free(d->buffer[i]); - free(d->buffer); - int ret = d->stream->close(d->stream->data); - free(d); - return ret; -} - -/* Wraps an existing stream with a caching layer. First create the stream you need, then - call this to create a new stream. Use this new stream only, and when done close() will - close both this stream as well as the wrapped one. */ -TSFDEF struct tsf_stream *tsf_stream_wrap_cached(struct tsf_stream *stream, int buffs, int buffsize, struct tsf_stream *dest) -{ - struct tsf_stream_cached_data *s = (struct tsf_stream_cached_data*)TSF_MALLOC(sizeof(*s)); - s->buffs = buffs; - s->buffsize = buffsize; - s->stream = stream; - s->size = stream->size(stream->data); - s->pos = stream->tell(stream->data); - s->buffer = (unsigned char **)TSF_MALLOC(sizeof(*s->buffer) * buffs); - s->offset = (unsigned int *)TSF_MALLOC(sizeof(s->offset) * buffs); - s->timestamp = (unsigned int *)TSF_MALLOC(sizeof(s->timestamp) * buffs); - s->epoch = 0; - s->hit = 0; - s->miss = 0; - for (int i=0; ibuffer[i] = (unsigned char *)TSF_MALLOC(buffsize); - s->offset[i] = 0xfffffff; - s->timestamp[i] = 0; - } - dest->data = (void*)s; - dest->read = &tsf_stream_cached_read; - dest->tell = &tsf_stream_cached_tell; - dest->skip = &tsf_stream_cached_skip; - dest->seek = &tsf_stream_cached_seek; - dest->size = &tsf_stream_cached_size; - dest->close = &tsf_stream_cached_close; - return dest; +static int tsf_stream_cached_read(void* v, void* ptr, unsigned int size) { + struct tsf_stream_cached_data *d = (struct tsf_stream_cached_data*)v; + unsigned char *p = (unsigned char *)ptr; + + while (size) { + if (d->pos >= d->size) { + return 0; // EOF + } + for (int i = 0; i < d->buffs; i++) { + if ((d->offset[i] <= d->pos) && ((d->offset[i] + d->buffsize) > d->pos)) { + d->timestamp[i] = d->epoch++; + // Handle case of epoch rollover by just setting low, random epochs + if (d->epoch == 0) { + for (int i = 0; i < d->buffs; i++) { + d->timestamp[i] = d->epoch++; + } + } + unsigned int startOffset = d->pos - d->offset[i]; + unsigned int len = d->buffsize - (d->pos % d->buffsize); + if (len > size) { + len = size; + } + TSF_MEMCPY(p, &d->buffer[i][startOffset], len); + size -= len; + d->pos += len; + p += len; + d->hit++; + if (size == 0) { + return 1; + } + i = -1; // Restart the for() at block 0 after postincrement + } + } + + int repl = 0; + for (int i = 1; i < d->buffs; i++) { + if (d->timestamp[i] < d->timestamp[repl]) { + repl = i; + } + } + int readOff = d->pos - (d->pos % d->buffsize); + d->stream->seek(d->stream->data, readOff); + d->stream->read(d->stream->data, d->buffer[repl], d->buffsize); + d->timestamp[repl] = d->epoch++; + d->offset[repl] = readOff; + d->miss++; + d->hit--; // Avoid counting this as a hit on next loop that returns data + // Don't actually do anything yet, we'll retry the search on next loop where it will notice new data + } + return 1; +} + +static int tsf_stream_cached_tell(void* v) { + struct tsf_stream_cached_data *d = (struct tsf_stream_cached_data*)v; + return d->pos; +} + +static int tsf_stream_cached_size(void* v) { + struct tsf_stream_cached_data *d = (struct tsf_stream_cached_data*)v; + return d->size; +} + +static int tsf_stream_cached_skip(void* v, unsigned int count) { + struct tsf_stream_cached_data *d = (struct tsf_stream_cached_data*)v; + if ((d->pos + count) < d->size) { + d->pos += count; + return 1; + } + return 0; +} + +static int tsf_stream_cached_seek(void* v, unsigned int pos) { + struct tsf_stream_cached_data *d = (struct tsf_stream_cached_data*)v; + if (pos < d->size) { + d->pos = pos; + return 1; + } + return 0; +} + +static int tsf_stream_cached_close(void* v) { + struct tsf_stream_cached_data *d = (struct tsf_stream_cached_data*)v; + free(d->timestamp); + free(d->offset); + for (int i = d->buffs - 1; i >= 0; i--) { + free(d->buffer[i]); + } + free(d->buffer); + int ret = d->stream->close(d->stream->data); + free(d); + return ret; +} + +/* Wraps an existing stream with a caching layer. First create the stream you need, then + call this to create a new stream. Use this new stream only, and when done close() will + close both this stream as well as the wrapped one. */ +TSFDEF struct tsf_stream *tsf_stream_wrap_cached(struct tsf_stream *stream, int buffs, int buffsize, struct tsf_stream *dest) { + struct tsf_stream_cached_data *s = (struct tsf_stream_cached_data*)TSF_MALLOC(sizeof(*s)); + s->buffs = buffs; + s->buffsize = buffsize; + s->stream = stream; + s->size = stream->size(stream->data); + s->pos = stream->tell(stream->data); + s->buffer = (unsigned char **)TSF_MALLOC(sizeof(*s->buffer) * buffs); + s->offset = (unsigned int *)TSF_MALLOC(sizeof(s->offset) * buffs); + s->timestamp = (unsigned int *)TSF_MALLOC(sizeof(s->timestamp) * buffs); + s->epoch = 0; + s->hit = 0; + s->miss = 0; + for (int i = 0; i < buffs; i++) { + s->buffer[i] = (unsigned char *)TSF_MALLOC(buffsize); + s->offset[i] = 0xfffffff; + s->timestamp[i] = 0; + } + dest->data = (void*)s; + dest->read = &tsf_stream_cached_read; + dest->tell = &tsf_stream_cached_tell; + dest->skip = &tsf_stream_cached_skip; + dest->seek = &tsf_stream_cached_seek; + dest->size = &tsf_stream_cached_size; + dest->close = &tsf_stream_cached_close; + return dest; } #ifndef TSF_NO_STDIO -static int tsf_stream_stdio_read(FILE* f, void* ptr, unsigned int size) { return (int)fread(ptr, 1, size, f); } -static int tsf_stream_stdio_tell(FILE* f) { return ftell(f); } -static int tsf_stream_stdio_size(FILE* f) { int p = ftell(f); fseek(f, 0, SEEK_END); int e = ftell(f); fseek(f, p, SEEK_SET); return e; } -static int tsf_stream_stdio_skip(FILE* f, unsigned int count) { return !fseek(f, count, SEEK_CUR); } -static int tsf_stream_stdio_seek(FILE* f, unsigned int count) { return !fseek(f, count, SEEK_SET); } -static int tsf_stream_stdio_close(FILE* f) { return !fclose(f); } -TSFDEF tsf* tsf_load_filename(const char* filename) -{ - tsf* res; - struct tsf_stream stream = { TSF_NULL, (int(*)(void*,void*,unsigned int))&tsf_stream_stdio_read, (int(*)(void*))&tsf_stream_stdio_tell, (int(*)(void*,unsigned int))&tsf_stream_stdio_skip, (int(*)(void*,unsigned int))&tsf_stream_stdio_seek, (int(*)(void*))&tsf_stream_stdio_close, (int(*)(void*))&tsf_stream_stdio_size }; - #if __STDC_WANT_SECURE_LIB__ - FILE* f = TSF_NULL; fopen_s(&f, filename, "rb"); - #else - FILE* f = fopen(filename, "rb"); - #endif - if (!f) - { - //if (e) *e = TSF_FILENOTFOUND; - return TSF_NULL; - } - stream.data = f; - res = tsf_load(&stream); - //fclose(f); - return res; +static int tsf_stream_stdio_read(FILE* f, void* ptr, unsigned int size) { + return (int)fread(ptr, 1, size, f); +} +static int tsf_stream_stdio_tell(FILE* f) { + return ftell(f); +} +static int tsf_stream_stdio_size(FILE* f) { + int p = ftell(f); + fseek(f, 0, SEEK_END); + int e = ftell(f); + fseek(f, p, SEEK_SET); + return e; +} +static int tsf_stream_stdio_skip(FILE* f, unsigned int count) { + return !fseek(f, count, SEEK_CUR); +} +static int tsf_stream_stdio_seek(FILE* f, unsigned int count) { + return !fseek(f, count, SEEK_SET); +} +static int tsf_stream_stdio_close(FILE* f) { + return !fclose(f); +} +TSFDEF tsf* tsf_load_filename(const char* filename) { + tsf* res; + struct tsf_stream stream = { TSF_NULL, (int(*)(void*, void*, unsigned int))&tsf_stream_stdio_read, (int(*)(void*))&tsf_stream_stdio_tell, (int(*)(void*, unsigned int))&tsf_stream_stdio_skip, (int(*)(void*, unsigned int))&tsf_stream_stdio_seek, (int(*)(void*))&tsf_stream_stdio_close, (int(*)(void*))&tsf_stream_stdio_size }; +#if __STDC_WANT_SECURE_LIB__ + FILE* f = TSF_NULL; fopen_s(&f, filename, "rb"); +#else + FILE* f = fopen(filename, "rb"); +#endif + if (!f) { + //if (e) *e = TSF_FILENOTFOUND; + return TSF_NULL; + } + stream.data = f; + res = tsf_load(&stream); + //fclose(f); + return res; } #endif -struct tsf_stream_memory { const char* buffer; unsigned int total, pos; }; -static int tsf_stream_memory_read(struct tsf_stream_memory* m, void* ptr, unsigned int size) { if (size > m->total - m->pos) size = m->total - m->pos; TSF_MEMCPY(ptr, m->buffer+m->pos, size); m->pos += size; return size; } -static int tsf_stream_memory_tell(struct tsf_stream_memory* m) { return m->pos; } -static int tsf_stream_memory_size(struct tsf_stream_memory* m) { return m->total; } -static int tsf_stream_memory_skip(struct tsf_stream_memory* m, unsigned int count) { if (m->pos + count > m->total) return 0; m->pos += count; return 1; } -static int tsf_stream_memory_seek(struct tsf_stream_memory* m, unsigned int pos) { if (pos > m->total) return 0; else m->pos = pos; return 1; } -static int tsf_stream_memory_close(struct tsf_stream_memory* m) { (void)m; return 1; } -TSFDEF tsf* tsf_load_memory(const void* buffer, int size) -{ - struct tsf_stream stream = { TSF_NULL, (int(*)(void*,void*,unsigned int))&tsf_stream_memory_read, (int(*)(void*))&tsf_stream_memory_tell, (int(*)(void*,unsigned int))&tsf_stream_memory_skip, (int(*)(void*,unsigned int))&tsf_stream_memory_seek, (int(*)(void*))&tsf_stream_memory_close, (int(*)(void*))&tsf_stream_memory_size }; - struct tsf_stream_memory f = { 0, 0, 0 }; - f.buffer = (const char*)buffer; - f.total = size; - stream.data = &f; - return tsf_load(&stream); +struct tsf_stream_memory { + const char* buffer; + unsigned int total, pos; +}; +static int tsf_stream_memory_read(struct tsf_stream_memory* m, void* ptr, unsigned int size) { + if (size > m->total - m->pos) { + size = m->total - m->pos; + } TSF_MEMCPY(ptr, m->buffer + m->pos, size); + m->pos += size; + return size; +} +static int tsf_stream_memory_tell(struct tsf_stream_memory* m) { + return m->pos; +} +static int tsf_stream_memory_size(struct tsf_stream_memory* m) { + return m->total; +} +static int tsf_stream_memory_skip(struct tsf_stream_memory* m, unsigned int count) { + if (m->pos + count > m->total) { + count = m->total - m->pos; + } m->pos += count; + return 1; +} +static int tsf_stream_memory_seek(struct tsf_stream_memory* m, unsigned int pos) { + if (pos > m->total) { + return 0; + } else { + m->pos = pos; + } return 1; +} +static int tsf_stream_memory_close(struct tsf_stream_memory* m) { + TSF_FREE(m); + return 1; +} +TSFDEF tsf* tsf_load_memory(const void* buffer, int size) { + struct tsf_stream stream = { TSF_NULL, (int(*)(void*, void*, unsigned int))&tsf_stream_memory_read, (int(*)(void*))&tsf_stream_memory_tell, (int(*)(void*, unsigned int))&tsf_stream_memory_skip, (int(*)(void*, unsigned int))&tsf_stream_memory_seek, (int(*)(void*))&tsf_stream_memory_close, (int(*)(void*))&tsf_stream_memory_size }; + struct tsf_stream_memory* f = (struct tsf_stream_memory*)TSF_MALLOC(sizeof(struct tsf_stream_memory)); + f->pos = 0; + f->buffer = (const char*)buffer; + f->total = size; + stream.data = f; + return tsf_load(&stream); } enum { TSF_LOOPMODE_NONE, TSF_LOOPMODE_CONTINUOUS, TSF_LOOPMODE_SUSTAIN }; enum { TSF_SEGMENT_NONE, TSF_SEGMENT_DELAY, TSF_SEGMENT_ATTACK, TSF_SEGMENT_HOLD, TSF_SEGMENT_DECAY, TSF_SEGMENT_SUSTAIN, TSF_SEGMENT_RELEASE, TSF_SEGMENT_DONE }; -struct tsf_hydra -{ - struct tsf_stream *stream; - int phdrOffset, pbagOffset, pmodOffset, pgenOffset, instOffset, ibagOffset, imodOffset, igenOffset, shdrOffset; - int phdrNum, pbagNum, pmodNum, pgenNum, instNum, ibagNum, imodNum, igenNum, shdrNum; +struct tsf_hydra { + struct tsf_stream *stream; + int phdrOffset, pbagOffset, pmodOffset, pgenOffset, instOffset, ibagOffset, imodOffset, igenOffset, shdrOffset; + int phdrNum, pbagNum, pmodNum, pgenNum, instNum, ibagNum, imodNum, igenNum, shdrNum; }; -union tsf_hydra_genamount { struct { tsf_u8 lo, hi; } range; tsf_s16 shortAmount; tsf_u16 wordAmount; }; -struct tsf_hydra_phdr { tsf_char20 presetName; tsf_u16 preset, bank, presetBagNdx; tsf_u32 library, genre, morphology; }; -struct tsf_hydra_pbag { tsf_u16 genNdx, modNdx; }; -struct tsf_hydra_pmod { tsf_u16 modSrcOper, modDestOper; tsf_s16 modAmount; tsf_u16 modAmtSrcOper, modTransOper; }; -struct tsf_hydra_pgen { tsf_u16 genOper; union tsf_hydra_genamount genAmount; }; -struct tsf_hydra_inst { tsf_char20 instName; tsf_u16 instBagNdx; }; -struct tsf_hydra_ibag { tsf_u16 instGenNdx, instModNdx; }; -struct tsf_hydra_imod { tsf_u16 modSrcOper, modDestOper; tsf_s16 modAmount; tsf_u16 modAmtSrcOper, modTransOper; }; -struct tsf_hydra_igen { tsf_u16 genOper; union tsf_hydra_genamount genAmount; }; -struct tsf_hydra_shdr { tsf_char20 sampleName; tsf_u32 start, end, startLoop, endLoop, sampleRate; tsf_u8 originalPitch; tsf_s8 pitchCorrection; tsf_u16 sampleLink, sampleType; }; +union tsf_hydra_genamount { + struct { + tsf_u8 lo, hi; + } range; + tsf_s16 shortAmount; + tsf_u16 wordAmount; +}; +struct tsf_hydra_phdr { + tsf_char20 presetName; + tsf_u16 preset, bank, presetBagNdx; + tsf_u32 library, genre, morphology; +}; +struct tsf_hydra_pbag { + tsf_u16 genNdx, modNdx; +}; +struct tsf_hydra_pmod { + tsf_u16 modSrcOper, modDestOper; + tsf_s16 modAmount; + tsf_u16 modAmtSrcOper, modTransOper; +}; +struct tsf_hydra_pgen { + tsf_u16 genOper; + union tsf_hydra_genamount genAmount; +}; +struct tsf_hydra_inst { + tsf_char20 instName; + tsf_u16 instBagNdx; +}; +struct tsf_hydra_ibag { + tsf_u16 instGenNdx, instModNdx; +}; +struct tsf_hydra_imod { + tsf_u16 modSrcOper, modDestOper; + tsf_s16 modAmount; + tsf_u16 modAmtSrcOper, modTransOper; +}; +struct tsf_hydra_igen { + tsf_u16 genOper; + union tsf_hydra_genamount genAmount; +}; +struct tsf_hydra_shdr { + tsf_char20 sampleName; + tsf_u32 start, end, startLoop, endLoop, sampleRate; + tsf_u8 originalPitch; + tsf_s8 pitchCorrection; + tsf_u16 sampleLink, sampleType; +}; #define TSFR(FIELD) stream->read(stream->data, &i->FIELD, sizeof(i->FIELD)); -static void tsf_hydra_read_phdr(struct tsf_hydra_phdr* i, struct tsf_stream* stream) { TSFR(presetName) TSFR(preset) TSFR(bank) TSFR(presetBagNdx) TSFR(library) TSFR(genre) TSFR(morphology) } -static void tsf_hydra_read_pbag(struct tsf_hydra_pbag* i, struct tsf_stream* stream) { TSFR(genNdx) TSFR(modNdx) } +static void tsf_hydra_read_phdr(struct tsf_hydra_phdr* i, struct tsf_stream* stream) { + TSFR(presetName) TSFR(preset) TSFR(bank) TSFR(presetBagNdx) TSFR(library) TSFR(genre) TSFR(morphology) +} +static void tsf_hydra_read_pbag(struct tsf_hydra_pbag* i, struct tsf_stream* stream) { + TSFR(genNdx) TSFR(modNdx) +} //static void tsf_hydra_read_pmod(struct tsf_hydra_pmod* i, struct tsf_stream* stream) { TSFR(modSrcOper) TSFR(modDestOper) TSFR(modAmount) TSFR(modAmtSrcOper) TSFR(modTransOper) } -static void tsf_hydra_read_pgen(struct tsf_hydra_pgen* i, struct tsf_stream* stream) { TSFR(genOper) TSFR(genAmount) } -static void tsf_hydra_read_inst(struct tsf_hydra_inst* i, struct tsf_stream* stream) { TSFR(instName) TSFR(instBagNdx) } -static void tsf_hydra_read_ibag(struct tsf_hydra_ibag* i, struct tsf_stream* stream) { TSFR(instGenNdx) TSFR(instModNdx) } +static void tsf_hydra_read_pgen(struct tsf_hydra_pgen* i, struct tsf_stream* stream) { + TSFR(genOper) TSFR(genAmount) +} +static void tsf_hydra_read_inst(struct tsf_hydra_inst* i, struct tsf_stream* stream) { + TSFR(instName) TSFR(instBagNdx) +} +static void tsf_hydra_read_ibag(struct tsf_hydra_ibag* i, struct tsf_stream* stream) { + TSFR(instGenNdx) TSFR(instModNdx) +} //static void tsf_hydra_read_imod(struct tsf_hydra_imod* i, struct tsf_stream* stream) { TSFR(modSrcOper) TSFR(modDestOper) TSFR(modAmount) TSFR(modAmtSrcOper) TSFR(modTransOper) } -static void tsf_hydra_read_igen(struct tsf_hydra_igen* i, struct tsf_stream* stream) { TSFR(genOper) TSFR(genAmount) } -static void tsf_hydra_read_shdr(struct tsf_hydra_shdr* i, struct tsf_stream* stream) { TSFR(sampleName) TSFR(start) TSFR(end) TSFR(startLoop) TSFR(endLoop) TSFR(sampleRate) TSFR(originalPitch) TSFR(pitchCorrection) TSFR(sampleLink) TSFR(sampleType) } +static void tsf_hydra_read_igen(struct tsf_hydra_igen* i, struct tsf_stream* stream) { + TSFR(genOper) TSFR(genAmount) +} +static void tsf_hydra_read_shdr(struct tsf_hydra_shdr* i, struct tsf_stream* stream) { + TSFR(sampleName) TSFR(start) TSFR(end) TSFR(startLoop) TSFR(endLoop) TSFR(sampleRate) TSFR(originalPitch) TSFR(pitchCorrection) TSFR(sampleLink) TSFR(sampleType) +} #undef TSFR -enum -{ - phdrSizeInFile = 38, pbagSizeInFile = 4, pmodSizeInFile = 10, - pgenSizeInFile = 4, instSizeInFile = 22, ibagSizeInFile = 4, - imodSizeInFile = 10, igenSizeInFile = 4, shdrSizeInFile = 46 +enum { + phdrSizeInFile = 38, pbagSizeInFile = 4, pmodSizeInFile = 10, + pgenSizeInFile = 4, instSizeInFile = 22, ibagSizeInFile = 4, + imodSizeInFile = 10, igenSizeInFile = 4, shdrSizeInFile = 46 }; #define TGET(TYPE) \ @@ -566,1576 +670,1817 @@ typedef int32_t fixed8p24; -struct tsf_riffchunk { tsf_fourcc id; tsf_u32 size; }; -struct tsf_envelope { float delay, attack, hold, decay, sustain, release, keynumToHold, keynumToDecay; }; -struct tsf_voice_envelope { float level, slope; int samplesUntilNextSegment; short segment, midiVelocity; struct tsf_envelope parameters; TSF_BOOL segmentIsExponential, isAmpEnv; }; -struct tsf_voice_lowpass { double QInv, a0, a1, b1, b2, z1, z2; TSF_BOOL active; }; -struct tsf_voice_lfo { int samplesUntil; float level, delta; }; - -struct tsf_region -{ - int loop_mode; - unsigned int sample_rate; - unsigned char lokey, hikey, lovel, hivel; - unsigned int group, offset, end, loop_start, loop_end; - int transpose, tune, pitch_keycenter, pitch_keytrack; - float attenuation, pan; - struct tsf_envelope ampenv, modenv; - int initialFilterQ, initialFilterFc; - int modEnvToPitch, modEnvToFilterFc, modLfoToFilterFc, modLfoToVolume; - float delayModLFO; - int freqModLFO, modLfoToPitch; - float delayVibLFO; - int freqVibLFO, vibLfoToPitch; +struct tsf_riffchunk { + tsf_fourcc id; + tsf_u32 size; +}; +struct tsf_envelope { + float delay, attack, hold, decay, sustain, release, keynumToHold, keynumToDecay; +}; +struct tsf_voice_envelope { + float level, slope; + int samplesUntilNextSegment; + short segment, midiVelocity; + struct tsf_envelope parameters; + TSF_BOOL segmentIsExponential, isAmpEnv; +}; +struct tsf_voice_lowpass { + double QInv, a0, a1, b1, b2, z1, z2; + TSF_BOOL active; +}; +struct tsf_voice_lfo { + int samplesUntil; + float level, delta; }; -struct tsf_preset -{ - tsf_char20 presetName; - tsf_u16 preset, bank; - struct tsf_region* regions; - int regionNum; +struct tsf_region { + int loop_mode; + unsigned int sample_rate; + unsigned char lokey, hikey, lovel, hivel; + unsigned int group, offset, end, loop_start, loop_end; + int transpose, tune, pitch_keycenter, pitch_keytrack; + float attenuation, pan; + struct tsf_envelope ampenv, modenv; + int initialFilterQ, initialFilterFc; + int modEnvToPitch, modEnvToFilterFc, modLfoToFilterFc, modLfoToVolume; + float delayModLFO; + int freqModLFO, modLfoToPitch; + float delayVibLFO; + int freqVibLFO, vibLfoToPitch; }; -struct tsf_voice -{ - int playingPreset, playingKey, playingChannel; - struct tsf_region* region; - double pitchInputTimecents, pitchOutputFactor; - double sourceSamplePosition; - fixed32p32 sourceSamplePositionF32P32; - float noteGainDB, panFactorLeft, panFactorRight; - unsigned int playIndex, loopStart, loopEnd; - struct tsf_voice_envelope ampenv, modenv; - struct tsf_voice_lowpass lowpass; - struct tsf_voice_lfo modlfo, viblfo; +struct tsf_preset { + tsf_char20 presetName; + tsf_u16 preset, bank; + struct tsf_region* regions; + int regionNum; }; -struct tsf_channel -{ - unsigned short presetIndex, bank, pitchWheel, midiPan, midiVolume, midiExpression, midiRPN, midiData; - float panOffset, gainDB, pitchRange, tuning; +struct tsf_voice { + int playingPreset, playingKey, playingChannel; + struct tsf_region* region; + double pitchRatio; + double sourceSamplePosition; + fixed32p32 sourceSamplePositionF32P32, loopStartF32P32, loopEndF32P32, loopSizeF32P32, pitchRatioF32P32; + float noteGain, panFactorLeft, panFactorRight; + int playIndex, loopStart, loopEnd; + struct tsf_voice_envelope ampenv, modenv; + struct tsf_voice_lowpass lowpass; + struct tsf_voice_lfo modlfo, viblfo; }; -struct tsf_channels -{ - void (*setupVoice)(tsf* f, struct tsf_voice* voice); - struct tsf_channel* channels; - int channelNum, activeChannel; +struct tsf_channel { + unsigned short presetIndex, bank, pitchWheel, midiPan, midiVolume, midiExpression, midiRPN, midiData; + float panOffset, gainDB, pitchRange, tuning; }; -static double tsf_timecents2Secsd(double timecents) { return TSF_POW(2.0, timecents / 1200.0); } -static float tsf_timecents2Secsf(float timecents) { return TSF_POWF(2.0f, timecents / 1200.0f); } -static float tsf_cents2Hertz(float cents) { return 8.176f * TSF_POWF(2.0f, cents / 1200.0f); } -static float tsf_decibelsToGain(float db) { return (db > -100.f ? TSF_POWF(10.0f, db * 0.05f) : 0); } -static float tsf_gainToDecibels(float gain) { return (gain <= .00001f ? -100.f : (float)(20.0 * TSF_LOG10(gain))); } - -static TSF_BOOL tsf_riffchunk_read(struct tsf_riffchunk* parent, struct tsf_riffchunk* chunk, struct tsf_stream* stream) -{ - TSF_BOOL IsRiff, IsList; - if (parent && sizeof(tsf_fourcc) + sizeof(tsf_u32) > parent->size) return TSF_FALSE; - if (!stream->read(stream->data, &chunk->id, sizeof(tsf_fourcc)) || *chunk->id <= ' ' || *chunk->id >= 'z') return TSF_FALSE; - if (!stream->read(stream->data, &chunk->size, sizeof(tsf_u32))) return TSF_FALSE; - if (parent && sizeof(tsf_fourcc) + sizeof(tsf_u32) + chunk->size > parent->size) return TSF_FALSE; - if (parent) parent->size -= sizeof(tsf_fourcc) + sizeof(tsf_u32) + chunk->size; - IsRiff = TSF_FourCCEquals(chunk->id, "RIFF"), IsList = TSF_FourCCEquals(chunk->id, "LIST"); - if (IsRiff && parent) return TSF_FALSE; //not allowed - if (!IsRiff && !IsList) return TSF_TRUE; //custom type without sub type - if (!stream->read(stream->data, &chunk->id, sizeof(tsf_fourcc)) || *chunk->id <= ' ' || *chunk->id >= 'z') return TSF_FALSE; - chunk->size -= sizeof(tsf_fourcc); - return TSF_TRUE; -} - -static void tsf_region_clear(struct tsf_region* i, TSF_BOOL for_relative) -{ - TSF_MEMSET(i, 0, sizeof(struct tsf_region)); - i->hikey = i->hivel = 127; - i->pitch_keycenter = 60; // C4 - if (for_relative) return; - - i->pitch_keytrack = 100; - - i->pitch_keycenter = -1; - - // SF2 defaults in timecents. - i->ampenv.delay = i->ampenv.attack = i->ampenv.hold = i->ampenv.decay = i->ampenv.release = -12000.0f; - i->modenv.delay = i->modenv.attack = i->modenv.hold = i->modenv.decay = i->modenv.release = -12000.0f; - - i->initialFilterFc = 13500; - - i->delayModLFO = -12000.0f; - i->delayVibLFO = -12000.0f; -} - -static void tsf_region_operator(struct tsf_region* region, tsf_u16 genOper, union tsf_hydra_genamount* amount, struct tsf_region* merge_region) -{ - enum - { - _GEN_TYPE_MASK = 0x0F, - GEN_FLOAT = 0x01, - GEN_INT = 0x02, - GEN_UINT_ADD = 0x03, - GEN_UINT_ADD15 = 0x04, - GEN_KEYRANGE = 0x05, - GEN_VELRANGE = 0x06, - GEN_LOOPMODE = 0x07, - GEN_GROUP = 0x08, - GEN_KEYCENTER = 0x09, - - _GEN_LIMIT_MASK = 0xF0, - GEN_INT_LIMIT12K = 0x10, //min -12000, max 12000 - GEN_INT_LIMITFC = 0x20, //min 1500, max 13500 - GEN_INT_LIMITQ = 0x30, //min 0, max 960 - GEN_INT_LIMIT960 = 0x40, //min -960, max 960 - GEN_INT_LIMIT16K4500 = 0x50, //min -16000, max 4500 - GEN_FLOAT_LIMIT12K5K = 0x60, //min -12000, max 5000 - GEN_FLOAT_LIMIT12K8K = 0x70, //min -12000, max 8000 - GEN_FLOAT_LIMIT1200 = 0x80, //min -1200, max 1200 - GEN_FLOAT_LIMITPAN = 0x90, //* .001f, min -.5f, max .5f, - GEN_FLOAT_LIMITATTN = 0xA0, //* .1f, min 0, max 144.0 - GEN_FLOAT_MAX1000 = 0xB0, //min 0, max 1000 - GEN_FLOAT_MAX1440 = 0xC0, //min 0, max 1440 - - _GEN_MAX = 59, - }; - #define _TSFREGIONOFFSET(TYPE, FIELD) (unsigned char)(((TYPE*)&((struct tsf_region*)0)->FIELD) - (TYPE*)0) - #define _TSFREGIONENVOFFSET(TYPE, ENV, FIELD) (unsigned char)(((TYPE*)&((&(((struct tsf_region*)0)->ENV))->FIELD)) - (TYPE*)0) - static const struct { unsigned char mode, offset; } genMetas[_GEN_MAX] = - { - { GEN_UINT_ADD , _TSFREGIONOFFSET(unsigned int, offset ) }, // 0 StartAddrsOffset - { GEN_UINT_ADD , _TSFREGIONOFFSET(unsigned int, end ) }, // 1 EndAddrsOffset - { GEN_UINT_ADD , _TSFREGIONOFFSET(unsigned int, loop_start ) }, // 2 StartloopAddrsOffset - { GEN_UINT_ADD , _TSFREGIONOFFSET(unsigned int, loop_end ) }, // 3 EndloopAddrsOffset - { GEN_UINT_ADD15 , _TSFREGIONOFFSET(unsigned int, offset ) }, // 4 StartAddrsCoarseOffset - { GEN_INT | GEN_INT_LIMIT12K , _TSFREGIONOFFSET( int, modLfoToPitch ) }, // 5 ModLfoToPitch - { GEN_INT | GEN_INT_LIMIT12K , _TSFREGIONOFFSET( int, vibLfoToPitch ) }, // 6 VibLfoToPitch - { GEN_INT | GEN_INT_LIMIT12K , _TSFREGIONOFFSET( int, modEnvToPitch ) }, // 7 ModEnvToPitch - { GEN_INT | GEN_INT_LIMITFC , _TSFREGIONOFFSET( int, initialFilterFc ) }, // 8 InitialFilterFc - { GEN_INT | GEN_INT_LIMITQ , _TSFREGIONOFFSET( int, initialFilterQ ) }, // 9 InitialFilterQ - { GEN_INT | GEN_INT_LIMIT12K , _TSFREGIONOFFSET( int, modLfoToFilterFc ) }, //10 ModLfoToFilterFc - { GEN_INT | GEN_INT_LIMIT12K , _TSFREGIONOFFSET( int, modEnvToFilterFc ) }, //11 ModEnvToFilterFc - { GEN_UINT_ADD15 , _TSFREGIONOFFSET(unsigned int, end ) }, //12 EndAddrsCoarseOffset - { GEN_INT | GEN_INT_LIMIT960 , _TSFREGIONOFFSET( int, modLfoToVolume ) }, //13 ModLfoToVolume - { 0 , (0 ) }, // Unused - { 0 , (0 ) }, //15 ChorusEffectsSend (unsupported) - { 0 , (0 ) }, //16 ReverbEffectsSend (unsupported) - { GEN_FLOAT | GEN_FLOAT_LIMITPAN , _TSFREGIONOFFSET( float, pan ) }, //17 Pan - { 0 , (0 ) }, // Unused - { 0 , (0 ) }, // Unused - { 0 , (0 ) }, // Unused - { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONOFFSET( float, delayModLFO ) }, //21 DelayModLFO - { GEN_INT | GEN_INT_LIMIT16K4500 , _TSFREGIONOFFSET( int, freqModLFO ) }, //22 FreqModLFO - { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONOFFSET( float, delayVibLFO ) }, //23 DelayVibLFO - { GEN_INT | GEN_INT_LIMIT16K4500 , _TSFREGIONOFFSET( int, freqVibLFO ) }, //24 FreqVibLFO - { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONENVOFFSET( float, modenv, delay ) }, //25 DelayModEnv - { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET( float, modenv, attack ) }, //26 AttackModEnv - { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONENVOFFSET( float, modenv, hold ) }, //27 HoldModEnv - { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET( float, modenv, decay ) }, //28 DecayModEnv - { GEN_FLOAT | GEN_FLOAT_MAX1000 , _TSFREGIONENVOFFSET( float, modenv, sustain ) }, //29 SustainModEnv - { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET( float, modenv, release ) }, //30 ReleaseModEnv - { GEN_FLOAT | GEN_FLOAT_LIMIT1200 , _TSFREGIONENVOFFSET( float, modenv, keynumToHold ) }, //31 KeynumToModEnvHold - { GEN_FLOAT | GEN_FLOAT_LIMIT1200 , _TSFREGIONENVOFFSET( float, modenv, keynumToDecay) }, //32 KeynumToModEnvDecay - { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONENVOFFSET( float, ampenv, delay ) }, //33 DelayVolEnv - { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET( float, ampenv, attack ) }, //34 AttackVolEnv - { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K , _TSFREGIONENVOFFSET( float, ampenv, hold ) }, //35 HoldVolEnv - { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET( float, ampenv, decay ) }, //36 DecayVolEnv - { GEN_FLOAT | GEN_FLOAT_MAX1440 , _TSFREGIONENVOFFSET( float, ampenv, sustain ) }, //37 SustainVolEnv - { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K , _TSFREGIONENVOFFSET( float, ampenv, release ) }, //38 ReleaseVolEnv - { GEN_FLOAT | GEN_FLOAT_LIMIT1200 , _TSFREGIONENVOFFSET( float, ampenv, keynumToHold ) }, //39 KeynumToVolEnvHold - { GEN_FLOAT | GEN_FLOAT_LIMIT1200 , _TSFREGIONENVOFFSET( float, ampenv, keynumToDecay) }, //40 KeynumToVolEnvDecay - { 0 , (0 ) }, // Instrument (special) - { 0 , (0 ) }, // Reserved - { GEN_KEYRANGE , (0 ) }, //43 KeyRange - { GEN_VELRANGE , (0 ) }, //44 VelRange - { GEN_UINT_ADD15 , _TSFREGIONOFFSET(unsigned int, loop_start ) }, //45 StartloopAddrsCoarseOffset - { 0 , (0 ) }, //46 Keynum (special) - { 0 , (0 ) }, //47 Velocity (special) - { GEN_FLOAT | GEN_FLOAT_LIMITATTN , _TSFREGIONOFFSET( float, attenuation ) }, //48 InitialAttenuation - { 0 , (0 ) }, // Reserved - { GEN_UINT_ADD15 , _TSFREGIONOFFSET(unsigned int, loop_end ) }, //50 EndloopAddrsCoarseOffset - { GEN_INT , _TSFREGIONOFFSET( int, transpose ) }, //51 CoarseTune - { GEN_INT , _TSFREGIONOFFSET( int, tune ) }, //52 FineTune - { 0 , (0 ) }, // SampleID (special) - { GEN_LOOPMODE , _TSFREGIONOFFSET( int, loop_mode ) }, //54 SampleModes - { 0 , (0 ) }, // Reserved - { GEN_INT , _TSFREGIONOFFSET( int, pitch_keytrack ) }, //56 ScaleTuning - { GEN_GROUP , _TSFREGIONOFFSET(unsigned int, group ) }, //57 ExclusiveClass - { GEN_KEYCENTER , _TSFREGIONOFFSET( int, pitch_keycenter ) }, //58 OverridingRootKey - }; - #undef _TSFREGIONOFFSET - #undef _TSFREGIONENVOFFSET - if (amount) - { - int offset; - if (genOper >= _GEN_MAX) return; - offset = genMetas[genOper].offset; - switch (genMetas[genOper].mode & _GEN_TYPE_MASK) - { - case GEN_FLOAT: (( float*)region)[offset] = amount->shortAmount; return; - case GEN_INT: (( int*)region)[offset] = amount->shortAmount; return; - case GEN_UINT_ADD: ((unsigned int*)region)[offset] += amount->shortAmount; return; - case GEN_UINT_ADD15: ((unsigned int*)region)[offset] += amount->shortAmount<<15; return; - case GEN_KEYRANGE: region->lokey = amount->range.lo; region->hikey = amount->range.hi; return; - case GEN_VELRANGE: region->lovel = amount->range.lo; region->hivel = amount->range.hi; return; - case GEN_LOOPMODE: region->loop_mode = ((amount->wordAmount&3) == 3 ? TSF_LOOPMODE_SUSTAIN : ((amount->wordAmount&3) == 1 ? TSF_LOOPMODE_CONTINUOUS : TSF_LOOPMODE_NONE)); return; - case GEN_GROUP: region->group = amount->wordAmount; return; - case GEN_KEYCENTER: region->pitch_keycenter = amount->shortAmount; return; - } - } - else //merge regions and clamp values - { - for (genOper = 0; genOper != _GEN_MAX; genOper++) - { - int offset = genMetas[genOper].offset; - switch (genMetas[genOper].mode & _GEN_TYPE_MASK) - { - case GEN_FLOAT: - { - float *val = &((float*)region)[offset], vfactor, vmin, vmax; - *val += ((float*)merge_region)[offset]; - switch (genMetas[genOper].mode & _GEN_LIMIT_MASK) - { - case GEN_FLOAT_LIMIT12K5K: vfactor = 1.0f; vmin = -12000.0f; vmax = 5000.0f; break; - case GEN_FLOAT_LIMIT12K8K: vfactor = 1.0f; vmin = -12000.0f; vmax = 8000.0f; break; - case GEN_FLOAT_LIMIT1200: vfactor = 1.0f; vmin = -1200.0f; vmax = 1200.0f; break; - case GEN_FLOAT_LIMITPAN: vfactor = 0.001f; vmin = -0.5f; vmax = 0.5f; break; - case GEN_FLOAT_LIMITATTN: vfactor = 0.1f; vmin = 0.0f; vmax = 144.0f; break; - case GEN_FLOAT_MAX1000: vfactor = 1.0f; vmin = 0.0f; vmax = 1000.0f; break; - case GEN_FLOAT_MAX1440: vfactor = 1.0f; vmin = 0.0f; vmax = 1440.0f; break; - default: continue; - } - *val *= vfactor; - if (*val < vmin) *val = vmin; - else if (*val > vmax) *val = vmax; - continue; - } - case GEN_INT: - { - int *val = &((int*)region)[offset], vmin, vmax; - *val += ((int*)merge_region)[offset]; - switch (genMetas[genOper].mode & _GEN_LIMIT_MASK) - { - case GEN_INT_LIMIT12K: vmin = -12000; vmax = 12000; break; - case GEN_INT_LIMITFC: vmin = 1500; vmax = 13500; break; - case GEN_INT_LIMITQ: vmin = 0; vmax = 960; break; - case GEN_INT_LIMIT960: vmin = -960; vmax = 960; break; - case GEN_INT_LIMIT16K4500: vmin = -16000; vmax = 4500; break; - default: continue; - } - if (*val < vmin) *val = vmin; - else if (*val > vmax) *val = vmax; - continue; - } - case GEN_UINT_ADD: - { - ((unsigned int*)region)[offset] += ((unsigned int*)merge_region)[offset]; - continue; - } - } - } - } -} - -static void tsf_region_envtosecs(struct tsf_envelope* p, TSF_BOOL sustainIsGain) -{ - // EG times need to be converted from timecents to seconds. - // Pin very short EG segments. Timecents don't get to zero, and our EG is - // happier with zero values. - p->delay = (p->delay < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->delay)); - p->attack = (p->attack < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->attack)); - p->release = (p->release < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->release)); - - // If we have dynamic hold or decay times depending on key number we need - // to keep the values in timecents so we can calculate it during startNote - if (!p->keynumToHold) p->hold = (p->hold < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->hold)); - if (!p->keynumToDecay) p->decay = (p->decay < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->decay)); - - if (p->sustain < 0.0f) p->sustain = 0.0f; - else if (sustainIsGain) p->sustain = tsf_decibelsToGain(-p->sustain / 10.0f); - else p->sustain = 1.0f - (p->sustain / 1000.0f); -} - -static void tsf_load_preset(const tsf* res, struct tsf_hydra *hydra, int presetToLoad) -{ - enum { GenInstrument = 41, GenKeyRange = 43, GenVelRange = 44, GenSampleID = 53 }; - // Read each preset. - struct tsf_hydra_phdr phdr; - int phdrIdx, phdrMaxIdx; - for (phdrIdx = presetToLoad, get_phdr(hydra, phdrIdx, &phdr), phdrMaxIdx = presetToLoad + 1 /*hydra->phdrNum - 1*/; phdrIdx != phdrMaxIdx; phdrIdx++, get_phdr(hydra, phdrIdx, &phdr)) - { - int sortedIndex = 0, region_index = 0; - struct tsf_hydra_phdr otherPhdr; - int otherPhdrIdx; - struct tsf_preset* preset; - struct tsf_region globalRegion; - for (otherPhdrIdx = 0, get_phdr(hydra, otherPhdrIdx, &otherPhdr); otherPhdrIdx != phdrMaxIdx; otherPhdrIdx++, get_phdr(hydra, otherPhdrIdx, &otherPhdr)) - { - if (otherPhdrIdx == phdrIdx || otherPhdr.bank > phdr.bank) continue; - else if (otherPhdr.bank < phdr.bank) sortedIndex++; - else if (otherPhdr.preset > phdr.preset) continue; - else if (otherPhdr.preset < phdr.preset) sortedIndex++; - else if (otherPhdrIdx < phdrIdx) sortedIndex++; - } - - preset = &res->presets[sortedIndex]; - TSF_MEMCPY(preset->presetName, phdr.presetName, sizeof(preset->presetName)); - preset->presetName[sizeof(preset->presetName)-1] = '\0'; //should be zero terminated in source file but make sure - preset->bank = phdr.bank; - preset->preset = phdr.preset; - preset->regionNum = 0; - - struct tsf_hydra_phdr phdrNext; - get_phdr(hydra, phdrIdx + 1, &phdrNext); - - //count regions covered by this preset - struct tsf_hydra_pbag pbag; - int pbagIdx, pbagEndIdx; - for (pbagIdx = phdr.presetBagNdx, get_pbag(hydra, pbagIdx, &pbag), pbagEndIdx = phdrNext.presetBagNdx; pbagIdx != pbagEndIdx; pbagIdx++, get_pbag(hydra, pbagIdx, &pbag)) - { - struct tsf_hydra_pbag pbagNext; - unsigned char plokey = 0, phikey = 127, plovel = 0, phivel = 127; - get_pbag(hydra, pbagIdx + 1, &pbagNext); - struct tsf_hydra_pgen pgen; - int pgenIdx, pgenEndIdx; - for (pgenIdx = pbag.genNdx, get_pgen(hydra, pgenIdx, &pgen), pgenEndIdx = pbagNext.genNdx; pgenIdx != pgenEndIdx; pgenIdx++, get_pgen(hydra, pgenIdx, &pgen)) - { - if (pgen.genOper == GenKeyRange) { plokey = pgen.genAmount.range.lo; phikey = pgen.genAmount.range.hi; continue; } - if (pgen.genOper == GenVelRange) { plovel = pgen.genAmount.range.lo; phivel = pgen.genAmount.range.hi; continue; } - if (pgen.genOper != GenInstrument) continue; - if (pgen.genAmount.wordAmount >= hydra->instNum) continue; - struct tsf_hydra_inst inst, instNext; - get_inst(hydra, pgen.genAmount.wordAmount, &inst); - get_inst(hydra, pgen.genAmount.wordAmount+1, &instNext); - struct tsf_hydra_ibag ibag; - int ibagIdx, ibagEndIdx; - for (ibagIdx = inst.instBagNdx, get_ibag(hydra, ibagIdx, &ibag), ibagEndIdx = instNext.instBagNdx; ibagIdx != ibagEndIdx; ibagIdx++, get_ibag(hydra, ibagIdx, &ibag) ) - { - struct tsf_hydra_ibag ibagNext; - get_ibag(hydra, ibagIdx + 1, &ibagNext); - struct tsf_hydra_igen igen; - int igenIdx, igenEndIdx; - unsigned char ilokey = 0, ihikey = 127, ilovel = 0, ihivel = 127; - for (igenIdx = ibag.instGenNdx, get_igen(hydra, igenIdx, &igen), igenEndIdx = ibagNext.instGenNdx; igenIdx != igenEndIdx; igenIdx++, get_igen(hydra, igenIdx, &igen)) - { - if (igen.genOper == GenKeyRange) { ilokey = igen.genAmount.range.lo; ihikey = igen.genAmount.range.hi; continue; } - if (igen.genOper == GenVelRange) { ilovel = igen.genAmount.range.lo; ihivel = igen.genAmount.range.hi; continue; } - if (igen.genOper == GenSampleID && ihikey >= plokey && ilokey <= phikey && ihivel >= plovel && ilovel <= phivel) preset->regionNum++; - } - } - } - } - - preset->regions = (struct tsf_region*)TSF_MALLOC(preset->regionNum * sizeof(struct tsf_region)); - tsf_region_clear(&globalRegion, TSF_TRUE); - - // Zones. - for (pbagIdx = phdr.presetBagNdx, get_pbag(hydra, pbagIdx, &pbag), pbagEndIdx = phdrNext.presetBagNdx; pbagIdx != pbagEndIdx; pbagIdx++, get_pbag(hydra, pbagIdx, &pbag)) - { - struct tsf_region presetRegion = globalRegion; - int hadGenInstrument = 0; - struct tsf_hydra_pbag pbagNext; - get_pbag(hydra, pbagIdx + 1, &pbagNext); - struct tsf_hydra_pgen pgen; - int pgenIdx, pgenEndIdx; - - // Generators. - for (pgenIdx = pbag.genNdx, get_pgen(hydra, pgenIdx, &pgen), pgenEndIdx = pbagNext.genNdx; pgenIdx != pgenEndIdx; pgenIdx++, get_pgen(hydra, pgenIdx, &pgen)) - { - // Instrument. - if (pgen.genOper == GenInstrument) - { - struct tsf_region instRegion; - tsf_u16 whichInst = pgen.genAmount.wordAmount; - if (whichInst >= hydra->instNum) continue; - - tsf_region_clear(&instRegion, TSF_FALSE); - struct tsf_hydra_inst inst, instNext; - get_inst(hydra, whichInst, &inst); - get_inst(hydra, whichInst + 1, &instNext); - struct tsf_hydra_ibag ibag; - int ibagIdx, ibagEndIdx; - for (ibagIdx = inst.instBagNdx, get_ibag(hydra, ibagIdx, &ibag), ibagEndIdx = instNext.instBagNdx; ibagIdx != ibagEndIdx; ibagIdx++, get_ibag(hydra, ibagIdx, &ibag)) - { - // Generators. - struct tsf_region zoneRegion = instRegion; - int hadSampleID = 0; - struct tsf_hydra_ibag ibagNext; - get_ibag(hydra, ibagIdx + 1, &ibagNext); - struct tsf_hydra_igen igen; - int igenIdx, igenEndIdx; - for (igenIdx = ibag.instGenNdx, get_igen(hydra, igenIdx, &igen), igenEndIdx = ibagNext.instGenNdx; igenIdx != igenEndIdx; igenIdx++, get_igen(hydra, igenIdx, &igen)) - { - if (igen.genOper == GenSampleID) - { - struct tsf_hydra_shdr shdr; - get_shdr(hydra, igen.genAmount.wordAmount, &shdr); - - //preset region key and vel ranges are a filter for the zone regions - if (zoneRegion.hikey < presetRegion.lokey || zoneRegion.lokey > presetRegion.hikey) continue; - if (zoneRegion.hivel < presetRegion.lovel || zoneRegion.lovel > presetRegion.hivel) continue; - if (presetRegion.lokey > zoneRegion.lokey) zoneRegion.lokey = presetRegion.lokey; - if (presetRegion.hikey < zoneRegion.hikey) zoneRegion.hikey = presetRegion.hikey; - if (presetRegion.lovel > zoneRegion.lovel) zoneRegion.lovel = presetRegion.lovel; - if (presetRegion.hivel < zoneRegion.hivel) zoneRegion.hivel = presetRegion.hivel; - - //sum regions - tsf_region_operator(&zoneRegion, 0, TSF_NULL, &presetRegion); - - // EG times need to be converted from timecents to seconds. - tsf_region_envtosecs(&zoneRegion.ampenv, TSF_TRUE); - tsf_region_envtosecs(&zoneRegion.modenv, TSF_FALSE); - - // LFO times need to be converted from timecents to seconds. - zoneRegion.delayModLFO = (zoneRegion.delayModLFO < -11950.0f ? 0.0f : tsf_timecents2Secsf(zoneRegion.delayModLFO)); - zoneRegion.delayVibLFO = (zoneRegion.delayVibLFO < -11950.0f ? 0.0f : tsf_timecents2Secsf(zoneRegion.delayVibLFO)); - - // Fixup sample positions - - get_shdr(hydra, igen.genAmount.wordAmount, &shdr); - zoneRegion.offset += shdr.start; - zoneRegion.end += shdr.end; - zoneRegion.loop_start += shdr.startLoop; - zoneRegion.loop_end += shdr.endLoop; - if (shdr.endLoop > 0) zoneRegion.loop_end -= 1; - if (zoneRegion.pitch_keycenter == -1) zoneRegion.pitch_keycenter = shdr.originalPitch; - zoneRegion.tune += shdr.pitchCorrection; - zoneRegion.sample_rate = shdr.sampleRate; - if (zoneRegion.end && zoneRegion.end < res->fontSampleCount) zoneRegion.end++; - else zoneRegion.end = res->fontSampleCount; - - preset->regions[region_index] = zoneRegion; - region_index++; - hadSampleID = 1; - } - else tsf_region_operator(&zoneRegion, igen.genOper, &igen.genAmount, TSF_NULL); - } - - // Handle instrument's global zone. - if (ibagIdx == inst.instBagNdx && !hadSampleID) - instRegion = zoneRegion; - - // Modulators (TODO) - //if (ibag->instModNdx < ibag[1].instModNdx) addUnsupportedOpcode("any modulator"); - } - hadGenInstrument = 1; - } - else tsf_region_operator(&presetRegion, pgen.genOper, &pgen.genAmount, TSF_NULL); - } - - // Modulators (TODO) - //if (pbag->modNdx < pbag[1].modNdx) addUnsupportedOpcode("any modulator"); - - // Handle preset's global zone. - if (pbagIdx == phdr.presetBagNdx && !hadGenInstrument) - globalRegion = presetRegion; - } - } -} - -static void tsf_load_samples(int *fontSamplesOffset, unsigned int* fontSampleCount, struct tsf_riffchunk *chunkSmpl, struct tsf_stream* stream) -{ - // Read sample data into float format buffer. - unsigned int samplesLeft; - samplesLeft = *fontSampleCount = chunkSmpl->size / sizeof(short); - *fontSamplesOffset = stream->tell(stream->data); - stream->skip(stream->data, samplesLeft * sizeof(short)); -} - -static void tsf_voice_envelope_nextsegment(struct tsf_voice_envelope* e, short active_segment, float outSampleRate) -{ - switch (active_segment) - { - case TSF_SEGMENT_NONE: - e->samplesUntilNextSegment = (int)(e->parameters.delay * outSampleRate); - if (e->samplesUntilNextSegment > 0) - { - e->segment = TSF_SEGMENT_DELAY; - e->segmentIsExponential = TSF_FALSE; - e->level = 0.0; - e->slope = 0.0; - return; - } - /* fall through */ - case TSF_SEGMENT_DELAY: - e->samplesUntilNextSegment = (int)(e->parameters.attack * outSampleRate); - if (e->samplesUntilNextSegment > 0) - { - if (!e->isAmpEnv) - { - //mod env attack duration scales with velocity (velocity of 1 is full duration, max velocity is 0.125 times duration) - e->samplesUntilNextSegment = (int)(e->parameters.attack * ((145 - e->midiVelocity) / 144.0f) * outSampleRate); - } - e->segment = TSF_SEGMENT_ATTACK; - e->segmentIsExponential = TSF_FALSE; - e->level = 0.0f; - e->slope = 1.0f / e->samplesUntilNextSegment; - return; - } - /* fall through */ - case TSF_SEGMENT_ATTACK: - e->samplesUntilNextSegment = (int)(e->parameters.hold * outSampleRate); - if (e->samplesUntilNextSegment > 0) - { - e->segment = TSF_SEGMENT_HOLD; - e->segmentIsExponential = TSF_FALSE; - e->level = 1.0f; - e->slope = 0.0f; - return; - } - /* fall through */ - case TSF_SEGMENT_HOLD: - e->samplesUntilNextSegment = (int)(e->parameters.decay * outSampleRate); - if (e->samplesUntilNextSegment > 0) - { - e->segment = TSF_SEGMENT_DECAY; - e->level = 1.0f; - if (e->isAmpEnv) - { - // I don't truly understand this; just following what LinuxSampler does. - float mysterySlope = -9.226f / e->samplesUntilNextSegment; - e->slope = TSF_EXPF(mysterySlope); - e->segmentIsExponential = TSF_TRUE; - if (e->parameters.sustain > 0.0f) - { - // Again, this is following LinuxSampler's example, which is similar to - // SF2-style decay, where "decay" specifies the time it would take to - // get to zero, not to the sustain level. The SFZ spec is not that - // specific about what "decay" means, so perhaps it's really supposed - // to specify the time to reach the sustain level. - e->samplesUntilNextSegment = (int)(TSF_LOG(e->parameters.sustain) / mysterySlope); - } - } - else - { - e->slope = -1.0f / e->samplesUntilNextSegment; - e->samplesUntilNextSegment = (int)(e->parameters.decay * (1.0f - e->parameters.sustain) * outSampleRate); - e->segmentIsExponential = TSF_FALSE; - } - return; - } - /* fall through */ - case TSF_SEGMENT_DECAY: - e->segment = TSF_SEGMENT_SUSTAIN; - e->level = e->parameters.sustain; - e->slope = 0.0f; - e->samplesUntilNextSegment = 0x7FFFFFFF; - e->segmentIsExponential = TSF_FALSE; - return; - case TSF_SEGMENT_SUSTAIN: - e->segment = TSF_SEGMENT_RELEASE; - e->samplesUntilNextSegment = (int)((e->parameters.release <= 0 ? TSF_FASTRELEASETIME : e->parameters.release) * outSampleRate); - if (e->isAmpEnv) - { - // I don't truly understand this; just following what LinuxSampler does. - float mysterySlope = -9.226f / e->samplesUntilNextSegment; - e->slope = TSF_EXPF(mysterySlope); - e->segmentIsExponential = TSF_TRUE; - } - else - { - e->slope = -e->level / e->samplesUntilNextSegment; - e->segmentIsExponential = TSF_FALSE; - } - return; - case TSF_SEGMENT_RELEASE: - default: - e->segment = TSF_SEGMENT_DONE; - e->segmentIsExponential = TSF_FALSE; - e->level = e->slope = 0.0f; - e->samplesUntilNextSegment = 0x7FFFFFF; - } -} - -static void tsf_voice_envelope_setup(struct tsf_voice_envelope* e, struct tsf_envelope* new_parameters, int midiNoteNumber, short midiVelocity, TSF_BOOL isAmpEnv, float outSampleRate) -{ - e->parameters = *new_parameters; - if (e->parameters.keynumToHold) - { - e->parameters.hold += e->parameters.keynumToHold * (60.0f - midiNoteNumber); - e->parameters.hold = (e->parameters.hold < -10000.0f ? 0.0f : tsf_timecents2Secsf(e->parameters.hold)); - } - if (e->parameters.keynumToDecay) - { - e->parameters.decay += e->parameters.keynumToDecay * (60.0f - midiNoteNumber); - e->parameters.decay = (e->parameters.decay < -10000.0f ? 0.0f : tsf_timecents2Secsf(e->parameters.decay)); - } - e->midiVelocity = midiVelocity; - e->isAmpEnv = isAmpEnv; - tsf_voice_envelope_nextsegment(e, TSF_SEGMENT_NONE, outSampleRate); -} - -static void tsf_voice_envelope_process(struct tsf_voice_envelope* e, int numSamples, float outSampleRate) -{ - if (e->slope) - { - if (e->segmentIsExponential) e->level *= TSF_POWF(e->slope, (float)numSamples); - else e->level += (e->slope * numSamples); - } - if ((e->samplesUntilNextSegment -= numSamples) <= 0) - tsf_voice_envelope_nextsegment(e, e->segment, outSampleRate); -} - -static void tsf_voice_lowpass_setup(struct tsf_voice_lowpass* e, float Fc) -{ - // Lowpass filter from http://www.earlevel.com/main/2012/11/26/biquad-c-source-code/ - double K = TSF_TAN(TSF_PI * Fc), KK = K * K; - double norm = 1 / (1 + K * e->QInv + KK); - e->a0 = KK * norm; - e->a1 = 2 * e->a0; - e->b1 = 2 * (KK - 1) * norm; - e->b2 = (1 - K * e->QInv + KK) * norm; -} - -static float tsf_voice_lowpass_process(struct tsf_voice_lowpass* e, double In) -{ - double Out = In * e->a0 + e->z1; e->z1 = In * e->a1 + e->z2 - e->b1 * Out; e->z2 = In * e->a0 - e->b2 * Out; return (float)Out; -} - -static void tsf_voice_lfo_setup(struct tsf_voice_lfo* e, float delay, int freqCents, float outSampleRate) -{ - e->samplesUntil = (int)(delay * outSampleRate); - e->delta = (4.0f * tsf_cents2Hertz((float)freqCents) / outSampleRate); - e->level = 0; -} - -static void tsf_voice_lfo_process(struct tsf_voice_lfo* e, int blockSamples) -{ - if (e->samplesUntil > blockSamples) { e->samplesUntil -= blockSamples; return; } - e->level += e->delta * blockSamples; - if (e->level > 1.0f) { e->delta = -e->delta; e->level = 2.0f - e->level; } - else if (e->level < -1.0f) { e->delta = -e->delta; e->level = -2.0f - e->level; } -} - -static void tsf_voice_kill(struct tsf_voice* v) -{ - v->playingPreset = -1; -} - -static void tsf_voice_end(struct tsf_voice* v, float outSampleRate) -{ - tsf_voice_envelope_nextsegment(&v->ampenv, TSF_SEGMENT_SUSTAIN, outSampleRate); - tsf_voice_envelope_nextsegment(&v->modenv, TSF_SEGMENT_SUSTAIN, outSampleRate); - if (v->region->loop_mode == TSF_LOOPMODE_SUSTAIN) - { - // Continue playing, but stop looping. - v->loopEnd = v->loopStart; - } -} - -static void tsf_voice_endquick(struct tsf_voice* v, float outSampleRate) -{ - v->ampenv.parameters.release = 0.0f; tsf_voice_envelope_nextsegment(&v->ampenv, TSF_SEGMENT_SUSTAIN, outSampleRate); - v->modenv.parameters.release = 0.0f; tsf_voice_envelope_nextsegment(&v->modenv, TSF_SEGMENT_SUSTAIN, outSampleRate); -} - -static void tsf_voice_calcpitchratio(struct tsf_voice* v, float pitchShift, float outSampleRate) -{ - double note = v->playingKey + v->region->transpose + v->region->tune / 100.0; - double adjustedPitch = v->region->pitch_keycenter + (note - v->region->pitch_keycenter) * (v->region->pitch_keytrack / 100.0); - if (pitchShift) adjustedPitch += pitchShift; - v->pitchInputTimecents = adjustedPitch * 100.0; - v->pitchOutputFactor = v->region->sample_rate / (tsf_timecents2Secsd(v->region->pitch_keycenter * 100.0) * outSampleRate); -} - -short tsf_read_short_cached(tsf *f, int pos) -{ - static int hits = 0; - static int misses = 0; -// static int call =0; -// call++; -// if ((call % 88000) ==0) printf("Hit: %d, Miss: %d, Ratio: %f\n", hits, misses, (double)hits/(double)(misses+hits)); - - for (int i=0; ioffset[i] <= pos) && ((f->offset[i] + TSF_BUFFSIZE) > pos) ) { - f->timestamp[i] = f->epoch++; - if (f->epoch==0) { - for (int i=0; itimestamp[i] = f->epoch++; - } - hits++; - return f->buffer[i][pos - f->offset[i]]; - } - } - int repl = 0; - for (int i=1; itimestamp[i] < f->timestamp[repl]) repl = i; - } - int readOff = pos - (pos % TSF_BUFFSIZE); -// for (int i=0; ibuffer[repl][i] = i; } - f->hydra->stream->seek(f->hydra->stream->data, readOff * sizeof(short)); - f->hydra->stream->read(f->hydra->stream->data, f->buffer[repl], TSF_BUFFSIZE * sizeof(short)); -//static uint32_t *bp = NULL; if (!bp) bp = (uint32_t*)malloc(512); -//printf("off=%08x, buff=%p, len=%08x\n", readOff * sizeof(short), bp, TSF_BUFFSIZE); spi_flash_read(0x0000, bp, 512/4-4) ; - f->timestamp[repl] = f->epoch++; - f->offset[repl] = readOff; - misses++; -// fprintf(stderr, "buffer[%d][%d-%d = %d]\n", repl, pos, readOff, pos - readOff); - return f->buffer[repl][pos - readOff]; -} - -static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, int numSamples) -{ - struct tsf_region* region = v->region; - float* outL = outputBuffer; - float* outR = (f->outputmode == TSF_STEREO_UNWEAVED ? outL + numSamples : TSF_NULL); - - // Cache some values, to give them at least some chance of ending up in registers. - TSF_BOOL updateModEnv = (region->modEnvToPitch || region->modEnvToFilterFc); - TSF_BOOL updateModLFO = (v->modlfo.delta && (region->modLfoToPitch || region->modLfoToFilterFc || region->modLfoToVolume)); - TSF_BOOL updateVibLFO = (v->viblfo.delta && (region->vibLfoToPitch)); - TSF_BOOL isLooping = (v->loopStart < v->loopEnd); - unsigned int tmpLoopStart = v->loopStart, tmpLoopEnd = v->loopEnd; - double tmpSampleEndDbl = (double)region->end, tmpLoopEndDbl = (double)tmpLoopEnd + 1.0; - double tmpSourceSamplePosition = v->sourceSamplePosition; - struct tsf_voice_lowpass tmpLowpass = v->lowpass; - - TSF_BOOL dynamicLowpass = (region->modLfoToFilterFc || region->modEnvToFilterFc); - float tmpSampleRate = f->outSampleRate, tmpInitialFilterFc, tmpModLfoToFilterFc, tmpModEnvToFilterFc; - - TSF_BOOL dynamicPitchRatio = (region->modLfoToPitch || region->modEnvToPitch || region->vibLfoToPitch); - double pitchRatio; - float tmpModLfoToPitch, tmpVibLfoToPitch, tmpModEnvToPitch; - - TSF_BOOL dynamicGain = (region->modLfoToVolume != 0); - float noteGain = 0, tmpModLfoToVolume; - - if (dynamicLowpass) tmpInitialFilterFc = (float)region->initialFilterFc, tmpModLfoToFilterFc = (float)region->modLfoToFilterFc, tmpModEnvToFilterFc = (float)region->modEnvToFilterFc; - else tmpInitialFilterFc = 0, tmpModLfoToFilterFc = 0, tmpModEnvToFilterFc = 0; - - if (dynamicPitchRatio) pitchRatio = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch; - else pitchRatio = tsf_timecents2Secsd(v->pitchInputTimecents) * v->pitchOutputFactor, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0; - - if (dynamicGain) tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f; - else noteGain = tsf_decibelsToGain(v->noteGainDB), tmpModLfoToVolume = 0; - - while (numSamples) - { - float gainMono, gainLeft, gainRight; - int blockSamples = (numSamples > TSF_RENDER_EFFECTSAMPLEBLOCK ? TSF_RENDER_EFFECTSAMPLEBLOCK : numSamples); - numSamples -= blockSamples; - - if (dynamicLowpass) - { - float fres = tmpInitialFilterFc + v->modlfo.level * tmpModLfoToFilterFc + v->modenv.level * tmpModEnvToFilterFc; - float lowpassFc = (fres <= 13500 ? tsf_cents2Hertz(fres) / tmpSampleRate : 1.0f); - tmpLowpass.active = (lowpassFc < 0.499f); - if (tmpLowpass.active) tsf_voice_lowpass_setup(&tmpLowpass, lowpassFc); - } - - if (dynamicPitchRatio) - pitchRatio = tsf_timecents2Secsd(v->pitchInputTimecents + (v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch)) * v->pitchOutputFactor; - - if (dynamicGain) - noteGain = tsf_decibelsToGain(v->noteGainDB + (v->modlfo.level * tmpModLfoToVolume)); - - gainMono = noteGain * v->ampenv.level; - - // Update EG. - tsf_voice_envelope_process(&v->ampenv, blockSamples, tmpSampleRate); - if (updateModEnv) tsf_voice_envelope_process(&v->modenv, blockSamples, tmpSampleRate); - - // Update LFOs. - if (updateModLFO) tsf_voice_lfo_process(&v->modlfo, blockSamples); - if (updateVibLFO) tsf_voice_lfo_process(&v->viblfo, blockSamples); - - switch (f->outputmode) - { - case TSF_STEREO_INTERLEAVED: - gainLeft = gainMono * v->panFactorLeft, gainRight = gainMono * v->panFactorRight; - while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl) - { - unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1); - float inputPos, inputNextPos; - inputPos = (float)(tsf_read_short_cached(f, pos) / 32767.0); - inputNextPos = (float)(tsf_read_short_cached(f, nextPos) / 32767.0); - // Simple linear interpolation. - float alpha = (float)(tmpSourceSamplePosition - pos), val = (inputPos * (1.0f - alpha) + inputNextPos * alpha); - - // Low-pass filter. - if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val); - - *outL++ += val * gainLeft; - *outL++ += val * gainRight; - - // Next sample. - tmpSourceSamplePosition += pitchRatio; - if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0); - } - break; - - case TSF_STEREO_UNWEAVED: - gainLeft = gainMono * v->panFactorLeft, gainRight = gainMono * v->panFactorRight; - while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl) - { - unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1); - float inputPos, inputNextPos; - inputPos = (float)(tsf_read_short_cached(f, pos) / 32767.0); - inputNextPos = (float)(tsf_read_short_cached(f, nextPos) / 32767.0); - - // Simple linear interpolation. - float alpha = (float)(tmpSourceSamplePosition - pos), val = (inputPos * (1.0f - alpha) + inputNextPos * alpha); - - // Low-pass filter. - if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val); - - *outL++ += val * gainLeft; - *outR++ += val * gainRight; - - // Next sample. - tmpSourceSamplePosition += pitchRatio; - if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0); - } - break; - - case TSF_MONO: - while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl) - { - unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1); - float inputPos, inputNextPos; - inputPos = (float)(tsf_read_short_cached(f, pos) / 32767.0); - inputNextPos = (float)(tsf_read_short_cached(f, nextPos) / 32767.0); - - // Simple linear interpolation. - float alpha = (float)(tmpSourceSamplePosition - pos), val = (inputPos * (1.0f - alpha) + inputNextPos * alpha); - - // Low-pass filter. - if (tmpLowpass.active) val = tsf_voice_lowpass_process(&tmpLowpass, val); - - *outL++ += val * gainMono; - - // Next sample. - tmpSourceSamplePosition += pitchRatio; - if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0); - } - break; - } - - if (tmpSourceSamplePosition >= tmpSampleEndDbl || v->ampenv.segment == TSF_SEGMENT_DONE) - { - tsf_voice_kill(v); - return; - } - } - - v->sourceSamplePosition = tmpSourceSamplePosition; - if (tmpLowpass.active || dynamicLowpass) v->lowpass = tmpLowpass; +struct tsf_channels { + void (*setupVoice)(tsf* f, struct tsf_voice* voice); + struct tsf_channel* channels; + int channelNum, activeChannel; +}; + +// Math properties of tsf_timecents2Secs* (tc2s): +// # tc2s(a + b) = tc2s(a) * tc2s(b) +// # tc2s(a - b) = tc2s(a) / tc2s(b) +// # 1 / tc2s(a) = tc2s(-a) +// # The same applies to tsf_cents2Hertz and tsf_decibelsToGain +// Path properties of tsf_decibelsToGain (db2g) and tsf_gainToDecibels (g2db) +// # db2g(g2db(a)) = a +// # g2db(db2g(a)) = a +static double tsf_timecents2Secsd(double timecents) { + return TSF_POW(2.0, timecents / 1200.0); +} +static float tsf_timecents2Secsf(float timecents) { + return TSF_POWF(2.0f, timecents / 1200.0f); +} +static float tsf_cents2Hertz(float cents) { + return 8.176f * TSF_POWF(2.0f, cents / 1200.0f); +} +static float tsf_decibelsToGain(float db) { + return (db > -100.f ? TSF_POWF(10.0f, db * 0.05f) : 0); +} +static float tsf_gainToDecibels(float gain) { + return (gain <= .00001f ? -100.f : (float)(20.0 * TSF_LOG10(gain))); +} + +static TSF_BOOL tsf_riffchunk_read(struct tsf_riffchunk* parent, struct tsf_riffchunk* chunk, struct tsf_stream* stream) { + TSF_BOOL IsRiff, IsList; + if (parent && sizeof(tsf_fourcc) + sizeof(tsf_u32) > parent->size) { + return TSF_FALSE; + } + if (!stream->read(stream->data, &chunk->id, sizeof(tsf_fourcc)) || *chunk->id <= ' ' || *chunk->id >= 'z') { + return TSF_FALSE; + } + if (!stream->read(stream->data, &chunk->size, sizeof(tsf_u32))) { + return TSF_FALSE; + } + if (parent && sizeof(tsf_fourcc) + sizeof(tsf_u32) + chunk->size > parent->size) { + return TSF_FALSE; + } + if (parent) { + parent->size -= sizeof(tsf_fourcc) + sizeof(tsf_u32) + chunk->size; + } + IsRiff = TSF_FourCCEquals(chunk->id, "RIFF"), IsList = TSF_FourCCEquals(chunk->id, "LIST"); + if (IsRiff && parent) { + return TSF_FALSE; //not allowed + } + if (!IsRiff && !IsList) { + return TSF_TRUE; //custom type without sub type + } + if (!stream->read(stream->data, &chunk->id, sizeof(tsf_fourcc)) || *chunk->id <= ' ' || *chunk->id >= 'z') { + return TSF_FALSE; + } + chunk->size -= sizeof(tsf_fourcc); + return TSF_TRUE; +} + +static void tsf_region_clear(struct tsf_region* i, TSF_BOOL for_relative) { + TSF_MEMSET(i, 0, sizeof(struct tsf_region)); + i->hikey = i->hivel = 127; + i->pitch_keycenter = 60; // C4 + if (for_relative) { + return; + } + + i->pitch_keytrack = 100; + + i->pitch_keycenter = -1; + + // SF2 defaults in timecents. + i->ampenv.delay = i->ampenv.attack = i->ampenv.hold = i->ampenv.decay = i->ampenv.release = -12000.0f; + i->modenv.delay = i->modenv.attack = i->modenv.hold = i->modenv.decay = i->modenv.release = -12000.0f; + + i->initialFilterFc = 13500; + + i->delayModLFO = -12000.0f; + i->delayVibLFO = -12000.0f; +} + +static void tsf_region_operator(struct tsf_region* region, tsf_u16 genOper, union tsf_hydra_genamount* amount, struct tsf_region* merge_region) { + enum { + _GEN_TYPE_MASK = 0x0F, + GEN_FLOAT = 0x01, + GEN_INT = 0x02, + GEN_UINT_ADD = 0x03, + GEN_UINT_ADD15 = 0x04, + GEN_KEYRANGE = 0x05, + GEN_VELRANGE = 0x06, + GEN_LOOPMODE = 0x07, + GEN_GROUP = 0x08, + GEN_KEYCENTER = 0x09, + + _GEN_LIMIT_MASK = 0xF0, + GEN_INT_LIMIT12K = 0x10, //min -12000, max 12000 + GEN_INT_LIMITFC = 0x20, //min 1500, max 13500 + GEN_INT_LIMITQ = 0x30, //min 0, max 960 + GEN_INT_LIMIT960 = 0x40, //min -960, max 960 + GEN_INT_LIMIT16K4500 = 0x50, //min -16000, max 4500 + GEN_FLOAT_LIMIT12K5K = 0x60, //min -12000, max 5000 + GEN_FLOAT_LIMIT12K8K = 0x70, //min -12000, max 8000 + GEN_FLOAT_LIMIT1200 = 0x80, //min -1200, max 1200 + GEN_FLOAT_LIMITPAN = 0x90, //* .001f, min -.5f, max .5f, + GEN_FLOAT_LIMITATTN = 0xA0, //* .1f, min 0, max 144.0 + GEN_FLOAT_MAX1000 = 0xB0, //min 0, max 1000 + GEN_FLOAT_MAX1440 = 0xC0, //min 0, max 1440 + + _GEN_MAX = 59, + }; +#define _TSFREGIONOFFSET(TYPE, FIELD) (unsigned char)(((TYPE*)&((struct tsf_region*)0)->FIELD) - (TYPE*)0) +#define _TSFREGIONENVOFFSET(TYPE, ENV, FIELD) (unsigned char)(((TYPE*)&((&(((struct tsf_region*)0)->ENV))->FIELD)) - (TYPE*)0) + static const struct { + unsigned char mode, offset; + } genMetas[_GEN_MAX] = { + { GEN_UINT_ADD, _TSFREGIONOFFSET(unsigned int, offset) }, // 0 StartAddrsOffset + { GEN_UINT_ADD, _TSFREGIONOFFSET(unsigned int, end) }, // 1 EndAddrsOffset + { GEN_UINT_ADD, _TSFREGIONOFFSET(unsigned int, loop_start) }, // 2 StartloopAddrsOffset + { GEN_UINT_ADD, _TSFREGIONOFFSET(unsigned int, loop_end) }, // 3 EndloopAddrsOffset + { GEN_UINT_ADD15, _TSFREGIONOFFSET(unsigned int, offset) }, // 4 StartAddrsCoarseOffset + { GEN_INT | GEN_INT_LIMIT12K, _TSFREGIONOFFSET(int, modLfoToPitch) }, // 5 ModLfoToPitch + { GEN_INT | GEN_INT_LIMIT12K, _TSFREGIONOFFSET(int, vibLfoToPitch) }, // 6 VibLfoToPitch + { GEN_INT | GEN_INT_LIMIT12K, _TSFREGIONOFFSET(int, modEnvToPitch) }, // 7 ModEnvToPitch + { GEN_INT | GEN_INT_LIMITFC, _TSFREGIONOFFSET(int, initialFilterFc) }, // 8 InitialFilterFc + { GEN_INT | GEN_INT_LIMITQ, _TSFREGIONOFFSET(int, initialFilterQ) }, // 9 InitialFilterQ + { GEN_INT | GEN_INT_LIMIT12K, _TSFREGIONOFFSET(int, modLfoToFilterFc) }, //10 ModLfoToFilterFc + { GEN_INT | GEN_INT_LIMIT12K, _TSFREGIONOFFSET(int, modEnvToFilterFc) }, //11 ModEnvToFilterFc + { GEN_UINT_ADD15, _TSFREGIONOFFSET(unsigned int, end) }, //12 EndAddrsCoarseOffset + { GEN_INT | GEN_INT_LIMIT960, _TSFREGIONOFFSET(int, modLfoToVolume) }, //13 ModLfoToVolume + { 0, (0) }, // Unused + { 0, (0) }, //15 ChorusEffectsSend (unsupported) + { 0, (0) }, //16 ReverbEffectsSend (unsupported) + { GEN_FLOAT | GEN_FLOAT_LIMITPAN, _TSFREGIONOFFSET(float, pan) }, //17 Pan + { 0, (0) }, // Unused + { 0, (0) }, // Unused + { 0, (0) }, // Unused + { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K, _TSFREGIONOFFSET(float, delayModLFO) }, //21 DelayModLFO + { GEN_INT | GEN_INT_LIMIT16K4500, _TSFREGIONOFFSET(int, freqModLFO) }, //22 FreqModLFO + { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K, _TSFREGIONOFFSET(float, delayVibLFO) }, //23 DelayVibLFO + { GEN_INT | GEN_INT_LIMIT16K4500, _TSFREGIONOFFSET(int, freqVibLFO) }, //24 FreqVibLFO + { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K, _TSFREGIONENVOFFSET(float, modenv, delay) }, //25 DelayModEnv + { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K, _TSFREGIONENVOFFSET(float, modenv, attack) }, //26 AttackModEnv + { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K, _TSFREGIONENVOFFSET(float, modenv, hold) }, //27 HoldModEnv + { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K, _TSFREGIONENVOFFSET(float, modenv, decay) }, //28 DecayModEnv + { GEN_FLOAT | GEN_FLOAT_MAX1000, _TSFREGIONENVOFFSET(float, modenv, sustain) }, //29 SustainModEnv + { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K, _TSFREGIONENVOFFSET(float, modenv, release) }, //30 ReleaseModEnv + { GEN_FLOAT | GEN_FLOAT_LIMIT1200, _TSFREGIONENVOFFSET(float, modenv, keynumToHold) }, //31 KeynumToModEnvHold + { GEN_FLOAT | GEN_FLOAT_LIMIT1200, _TSFREGIONENVOFFSET(float, modenv, keynumToDecay) }, //32 KeynumToModEnvDecay + { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K, _TSFREGIONENVOFFSET(float, ampenv, delay) }, //33 DelayVolEnv + { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K, _TSFREGIONENVOFFSET(float, ampenv, attack) }, //34 AttackVolEnv + { GEN_FLOAT | GEN_FLOAT_LIMIT12K5K, _TSFREGIONENVOFFSET(float, ampenv, hold) }, //35 HoldVolEnv + { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K, _TSFREGIONENVOFFSET(float, ampenv, decay) }, //36 DecayVolEnv + { GEN_FLOAT | GEN_FLOAT_MAX1440, _TSFREGIONENVOFFSET(float, ampenv, sustain) }, //37 SustainVolEnv + { GEN_FLOAT | GEN_FLOAT_LIMIT12K8K, _TSFREGIONENVOFFSET(float, ampenv, release) }, //38 ReleaseVolEnv + { GEN_FLOAT | GEN_FLOAT_LIMIT1200, _TSFREGIONENVOFFSET(float, ampenv, keynumToHold) }, //39 KeynumToVolEnvHold + { GEN_FLOAT | GEN_FLOAT_LIMIT1200, _TSFREGIONENVOFFSET(float, ampenv, keynumToDecay) }, //40 KeynumToVolEnvDecay + { 0, (0) }, // Instrument (special) + { 0, (0) }, // Reserved + { GEN_KEYRANGE, (0) }, //43 KeyRange + { GEN_VELRANGE, (0) }, //44 VelRange + { GEN_UINT_ADD15, _TSFREGIONOFFSET(unsigned int, loop_start) }, //45 StartloopAddrsCoarseOffset + { 0, (0) }, //46 Keynum (special) + { 0, (0) }, //47 Velocity (special) + { GEN_FLOAT | GEN_FLOAT_LIMITATTN, _TSFREGIONOFFSET(float, attenuation) }, //48 InitialAttenuation + { 0, (0) }, // Reserved + { GEN_UINT_ADD15, _TSFREGIONOFFSET(unsigned int, loop_end) }, //50 EndloopAddrsCoarseOffset + { GEN_INT, _TSFREGIONOFFSET(int, transpose) }, //51 CoarseTune + { GEN_INT, _TSFREGIONOFFSET(int, tune) }, //52 FineTune + { 0, (0) }, // SampleID (special) + { GEN_LOOPMODE, _TSFREGIONOFFSET(int, loop_mode) }, //54 SampleModes + { 0, (0) }, // Reserved + { GEN_INT, _TSFREGIONOFFSET(int, pitch_keytrack) }, //56 ScaleTuning + { GEN_GROUP, _TSFREGIONOFFSET(unsigned int, group) }, //57 ExclusiveClass + { GEN_KEYCENTER, _TSFREGIONOFFSET(int, pitch_keycenter) }, //58 OverridingRootKey + }; +#undef _TSFREGIONOFFSET +#undef _TSFREGIONENVOFFSET + if (amount) { + int offset; + if (genOper >= _GEN_MAX) { + return; + } + offset = genMetas[genOper].offset; + switch (genMetas[genOper].mode & _GEN_TYPE_MASK) { + case GEN_FLOAT: ((float*)region)[offset] = amount->shortAmount; return; + case GEN_INT: ((int*)region)[offset] = amount->shortAmount; return; + case GEN_UINT_ADD: ((unsigned int*)region)[offset] += amount->shortAmount; return; + case GEN_UINT_ADD15: ((unsigned int*)region)[offset] += amount->shortAmount << 15; return; + case GEN_KEYRANGE: region->lokey = amount->range.lo; region->hikey = amount->range.hi; return; + case GEN_VELRANGE: region->lovel = amount->range.lo; region->hivel = amount->range.hi; return; + case GEN_LOOPMODE: region->loop_mode = ((amount->wordAmount & 3) == 3 ? TSF_LOOPMODE_SUSTAIN : ((amount->wordAmount & 3) == 1 ? TSF_LOOPMODE_CONTINUOUS : TSF_LOOPMODE_NONE)); return; + case GEN_GROUP: region->group = amount->wordAmount; return; + case GEN_KEYCENTER: region->pitch_keycenter = amount->shortAmount; return; + } + } else { //merge regions and clamp values + for (genOper = 0; genOper != _GEN_MAX; genOper++) { + int offset = genMetas[genOper].offset; + switch (genMetas[genOper].mode & _GEN_TYPE_MASK) { + case GEN_FLOAT: { + float *val = &((float*)region)[offset], vfactor, vmin, vmax; + *val += ((float*)merge_region)[offset]; + switch (genMetas[genOper].mode & _GEN_LIMIT_MASK) { + case GEN_FLOAT_LIMIT12K5K: vfactor = 1.0f; vmin = -12000.0f; vmax = 5000.0f; break; + case GEN_FLOAT_LIMIT12K8K: vfactor = 1.0f; vmin = -12000.0f; vmax = 8000.0f; break; + case GEN_FLOAT_LIMIT1200: vfactor = 1.0f; vmin = -1200.0f; vmax = 1200.0f; break; + case GEN_FLOAT_LIMITPAN: vfactor = 0.001f; vmin = -0.5f; vmax = 0.5f; break; + case GEN_FLOAT_LIMITATTN: vfactor = 0.1f; vmin = 0.0f; vmax = 144.0f; break; + case GEN_FLOAT_MAX1000: vfactor = 1.0f; vmin = 0.0f; vmax = 1000.0f; break; + case GEN_FLOAT_MAX1440: vfactor = 1.0f; vmin = 0.0f; vmax = 1440.0f; break; + default: continue; + } + *val *= vfactor; + if (*val < vmin) { + *val = vmin; + } else if (*val > vmax) { + *val = vmax; + } + continue; + } + case GEN_INT: { + int *val = &((int*)region)[offset], vmin, vmax; + *val += ((int*)merge_region)[offset]; + switch (genMetas[genOper].mode & _GEN_LIMIT_MASK) { + case GEN_INT_LIMIT12K: vmin = -12000; vmax = 12000; break; + case GEN_INT_LIMITFC: vmin = 1500; vmax = 13500; break; + case GEN_INT_LIMITQ: vmin = 0; vmax = 960; break; + case GEN_INT_LIMIT960: vmin = -960; vmax = 960; break; + case GEN_INT_LIMIT16K4500: vmin = -16000; vmax = 4500; break; + default: continue; + } + if (*val < vmin) { + *val = vmin; + } else if (*val > vmax) { + *val = vmax; + } + continue; + } + case GEN_UINT_ADD: { + ((unsigned int*)region)[offset] += ((unsigned int*)merge_region)[offset]; + continue; + } + } + } + } +} + +static void tsf_region_envtosecs(struct tsf_envelope* p, TSF_BOOL sustainIsGain) { + // EG times need to be converted from timecents to seconds. + // Pin very short EG segments. Timecents don't get to zero, and our EG is + // happier with zero values. + p->delay = (p->delay < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->delay)); + p->attack = (p->attack < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->attack)); + p->release = (p->release < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->release)); + + // If we have dynamic hold or decay times depending on key number we need + // to keep the values in timecents so we can calculate it during startNote + if (!p->keynumToHold) { + p->hold = (p->hold < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->hold)); + } + if (!p->keynumToDecay) { + p->decay = (p->decay < -11950.0f ? 0.0f : tsf_timecents2Secsf(p->decay)); + } + + if (p->sustain < 0.0f) { + p->sustain = 0.0f; + } else if (sustainIsGain) { + p->sustain = tsf_decibelsToGain(-p->sustain / 10.0f); + } else { + p->sustain = 1.0f - (p->sustain / 1000.0f); + } +} + +static void tsf_load_preset(const tsf* res, struct tsf_hydra *hydra, int presetToLoad) { + enum { GenInstrument = 41, GenKeyRange = 43, GenVelRange = 44, GenSampleID = 53 }; + // Read each preset. + struct tsf_hydra_phdr phdr; + int phdrIdx, phdrMaxIdx; + for (phdrIdx = presetToLoad, get_phdr(hydra, phdrIdx, &phdr), phdrMaxIdx = presetToLoad + 1 /*hydra->phdrNum - 1*/; phdrIdx != phdrMaxIdx; phdrIdx++, get_phdr(hydra, phdrIdx, &phdr)) { + int sortedIndex = 0, region_index = 0; + struct tsf_hydra_phdr otherPhdr; + int otherPhdrIdx; + struct tsf_preset* preset; + struct tsf_region globalRegion; + for (otherPhdrIdx = 0, get_phdr(hydra, otherPhdrIdx, &otherPhdr); otherPhdrIdx != phdrMaxIdx; otherPhdrIdx++, get_phdr(hydra, otherPhdrIdx, &otherPhdr)) { + if (otherPhdrIdx == phdrIdx || otherPhdr.bank > phdr.bank) { + continue; + } else if (otherPhdr.bank < phdr.bank) { + sortedIndex++; + } else if (otherPhdr.preset > phdr.preset) { + continue; + } else if (otherPhdr.preset < phdr.preset) { + sortedIndex++; + } else if (otherPhdrIdx < phdrIdx) { + sortedIndex++; + } + } + + preset = &res->presets[sortedIndex]; + TSF_MEMCPY(preset->presetName, phdr.presetName, sizeof(preset->presetName)); + preset->presetName[sizeof(preset->presetName) - 1] = '\0'; //should be zero terminated in source file but make sure + preset->bank = phdr.bank; + preset->preset = phdr.preset; + preset->regionNum = 0; + + struct tsf_hydra_phdr phdrNext; + get_phdr(hydra, phdrIdx + 1, &phdrNext); + + //count regions covered by this preset + struct tsf_hydra_pbag pbag; + int pbagIdx, pbagEndIdx; + for (pbagIdx = phdr.presetBagNdx, get_pbag(hydra, pbagIdx, &pbag), pbagEndIdx = phdrNext.presetBagNdx; pbagIdx != pbagEndIdx; pbagIdx++, get_pbag(hydra, pbagIdx, &pbag)) { + struct tsf_hydra_pbag pbagNext; + unsigned char plokey = 0, phikey = 127, plovel = 0, phivel = 127; + get_pbag(hydra, pbagIdx + 1, &pbagNext); + struct tsf_hydra_pgen pgen; + int pgenIdx, pgenEndIdx; + for (pgenIdx = pbag.genNdx, get_pgen(hydra, pgenIdx, &pgen), pgenEndIdx = pbagNext.genNdx; pgenIdx != pgenEndIdx; pgenIdx++, get_pgen(hydra, pgenIdx, &pgen)) { + if (pgen.genOper == GenKeyRange) { + plokey = pgen.genAmount.range.lo; + phikey = pgen.genAmount.range.hi; + continue; + } + if (pgen.genOper == GenVelRange) { + plovel = pgen.genAmount.range.lo; + phivel = pgen.genAmount.range.hi; + continue; + } + if (pgen.genOper != GenInstrument) { + continue; + } + if (pgen.genAmount.wordAmount >= hydra->instNum) { + continue; + } + struct tsf_hydra_inst inst, instNext; + get_inst(hydra, pgen.genAmount.wordAmount, &inst); + get_inst(hydra, pgen.genAmount.wordAmount + 1, &instNext); + struct tsf_hydra_ibag ibag; + int ibagIdx, ibagEndIdx; + for (ibagIdx = inst.instBagNdx, get_ibag(hydra, ibagIdx, &ibag), ibagEndIdx = instNext.instBagNdx; ibagIdx != ibagEndIdx; ibagIdx++, get_ibag(hydra, ibagIdx, &ibag)) { + struct tsf_hydra_ibag ibagNext; + get_ibag(hydra, ibagIdx + 1, &ibagNext); + struct tsf_hydra_igen igen; + int igenIdx, igenEndIdx; + unsigned char ilokey = 0, ihikey = 127, ilovel = 0, ihivel = 127; + for (igenIdx = ibag.instGenNdx, get_igen(hydra, igenIdx, &igen), igenEndIdx = ibagNext.instGenNdx; igenIdx != igenEndIdx; igenIdx++, get_igen(hydra, igenIdx, &igen)) { + if (igen.genOper == GenKeyRange) { + ilokey = igen.genAmount.range.lo; + ihikey = igen.genAmount.range.hi; + continue; + } + if (igen.genOper == GenVelRange) { + ilovel = igen.genAmount.range.lo; + ihivel = igen.genAmount.range.hi; + continue; + } + if (igen.genOper == GenSampleID && ihikey >= plokey && ilokey <= phikey && ihivel >= plovel && ilovel <= phivel) { + preset->regionNum++; + } + } + } + } + } + + preset->regions = (struct tsf_region*)TSF_MALLOC(preset->regionNum * sizeof(struct tsf_region)); + tsf_region_clear(&globalRegion, TSF_TRUE); + + // Zones. + for (pbagIdx = phdr.presetBagNdx, get_pbag(hydra, pbagIdx, &pbag), pbagEndIdx = phdrNext.presetBagNdx; pbagIdx != pbagEndIdx; pbagIdx++, get_pbag(hydra, pbagIdx, &pbag)) { + struct tsf_region presetRegion = globalRegion; + int hadGenInstrument = 0; + struct tsf_hydra_pbag pbagNext; + get_pbag(hydra, pbagIdx + 1, &pbagNext); + struct tsf_hydra_pgen pgen; + int pgenIdx, pgenEndIdx; + + // Generators. + for (pgenIdx = pbag.genNdx, get_pgen(hydra, pgenIdx, &pgen), pgenEndIdx = pbagNext.genNdx; pgenIdx != pgenEndIdx; pgenIdx++, get_pgen(hydra, pgenIdx, &pgen)) { + // Instrument. + if (pgen.genOper == GenInstrument) { + struct tsf_region instRegion; + tsf_u16 whichInst = pgen.genAmount.wordAmount; + if (whichInst >= hydra->instNum) { + continue; + } + + tsf_region_clear(&instRegion, TSF_FALSE); + struct tsf_hydra_inst inst, instNext; + get_inst(hydra, whichInst, &inst); + get_inst(hydra, whichInst + 1, &instNext); + struct tsf_hydra_ibag ibag; + int ibagIdx, ibagEndIdx; + for (ibagIdx = inst.instBagNdx, get_ibag(hydra, ibagIdx, &ibag), ibagEndIdx = instNext.instBagNdx; ibagIdx != ibagEndIdx; ibagIdx++, get_ibag(hydra, ibagIdx, &ibag)) { + // Generators. + struct tsf_region zoneRegion = instRegion; + int hadSampleID = 0; + struct tsf_hydra_ibag ibagNext; + get_ibag(hydra, ibagIdx + 1, &ibagNext); + struct tsf_hydra_igen igen; + int igenIdx, igenEndIdx; + for (igenIdx = ibag.instGenNdx, get_igen(hydra, igenIdx, &igen), igenEndIdx = ibagNext.instGenNdx; igenIdx != igenEndIdx; igenIdx++, get_igen(hydra, igenIdx, &igen)) { + if (igen.genOper == GenSampleID) { + struct tsf_hydra_shdr shdr; + get_shdr(hydra, igen.genAmount.wordAmount, &shdr); + + //preset region key and vel ranges are a filter for the zone regions + if (zoneRegion.hikey < presetRegion.lokey || zoneRegion.lokey > presetRegion.hikey) { + continue; + } + if (zoneRegion.hivel < presetRegion.lovel || zoneRegion.lovel > presetRegion.hivel) { + continue; + } + if (presetRegion.lokey > zoneRegion.lokey) { + zoneRegion.lokey = presetRegion.lokey; + } + if (presetRegion.hikey < zoneRegion.hikey) { + zoneRegion.hikey = presetRegion.hikey; + } + if (presetRegion.lovel > zoneRegion.lovel) { + zoneRegion.lovel = presetRegion.lovel; + } + if (presetRegion.hivel < zoneRegion.hivel) { + zoneRegion.hivel = presetRegion.hivel; + } + + //sum regions + tsf_region_operator(&zoneRegion, 0, TSF_NULL, &presetRegion); + + // EG times need to be converted from timecents to seconds. + tsf_region_envtosecs(&zoneRegion.ampenv, TSF_TRUE); + tsf_region_envtosecs(&zoneRegion.modenv, TSF_FALSE); + + // LFO times need to be converted from timecents to seconds. + zoneRegion.delayModLFO = (zoneRegion.delayModLFO < -11950.0f ? 0.0f : tsf_timecents2Secsf(zoneRegion.delayModLFO)); + zoneRegion.delayVibLFO = (zoneRegion.delayVibLFO < -11950.0f ? 0.0f : tsf_timecents2Secsf(zoneRegion.delayVibLFO)); + + // Fixup sample positions + + get_shdr(hydra, igen.genAmount.wordAmount, &shdr); + zoneRegion.offset += shdr.start; + zoneRegion.end += shdr.end; + zoneRegion.loop_start += shdr.startLoop; + zoneRegion.loop_end += shdr.endLoop; + if (shdr.endLoop > 0) { + zoneRegion.loop_end -= 1; + } + if (zoneRegion.pitch_keycenter == -1) { + zoneRegion.pitch_keycenter = shdr.originalPitch; + } + zoneRegion.tune += shdr.pitchCorrection; + zoneRegion.sample_rate = shdr.sampleRate; + if (zoneRegion.end && zoneRegion.end < res->fontSampleCount) { + zoneRegion.end++; + } else { + zoneRegion.end = res->fontSampleCount; + } + + preset->regions[region_index] = zoneRegion; + region_index++; + hadSampleID = 1; + } else { + tsf_region_operator(&zoneRegion, igen.genOper, &igen.genAmount, TSF_NULL); + } + } + + // Handle instrument's global zone. + if (ibagIdx == inst.instBagNdx && !hadSampleID) { + instRegion = zoneRegion; + } + + // Modulators (TODO) + //if (ibag->instModNdx < ibag[1].instModNdx) addUnsupportedOpcode("any modulator"); + } + hadGenInstrument = 1; + } else { + tsf_region_operator(&presetRegion, pgen.genOper, &pgen.genAmount, TSF_NULL); + } + } + + // Modulators (TODO) + //if (pbag->modNdx < pbag[1].modNdx) addUnsupportedOpcode("any modulator"); + + // Handle preset's global zone. + if (pbagIdx == phdr.presetBagNdx && !hadGenInstrument) { + globalRegion = presetRegion; + } + } + } +} + +static void tsf_load_samples(int *fontSamplesOffset, unsigned int* fontSampleCount, struct tsf_riffchunk *chunkSmpl, struct tsf_stream* stream) { + // Read sample data into float format buffer. + unsigned int samplesLeft; + samplesLeft = *fontSampleCount = chunkSmpl->size / sizeof(short); + *fontSamplesOffset = stream->tell(stream->data); + stream->skip(stream->data, samplesLeft * sizeof(short)); +} + +static void tsf_voice_envelope_nextsegment(struct tsf_voice_envelope* e, short active_segment, float outSampleRate) { + switch (active_segment) { + case TSF_SEGMENT_NONE: + e->samplesUntilNextSegment = (int)(e->parameters.delay * outSampleRate); + if (e->samplesUntilNextSegment > 0) { + e->segment = TSF_SEGMENT_DELAY; + e->segmentIsExponential = TSF_FALSE; + e->level = 0.0; + e->slope = 0.0; + return; + } + /* fall through */ + case TSF_SEGMENT_DELAY: + e->samplesUntilNextSegment = (int)(e->parameters.attack * outSampleRate); + if (e->samplesUntilNextSegment > 0) { + if (!e->isAmpEnv) { + //mod env attack duration scales with velocity (velocity of 1 is full duration, max velocity is 0.125 times duration) + e->samplesUntilNextSegment = (int)(e->parameters.attack * ((145 - e->midiVelocity) / 144.0f) * outSampleRate); + } + e->segment = TSF_SEGMENT_ATTACK; + e->segmentIsExponential = TSF_FALSE; + e->level = 0.0f; + e->slope = 1.0f / e->samplesUntilNextSegment; + return; + } + /* fall through */ + case TSF_SEGMENT_ATTACK: + e->samplesUntilNextSegment = (int)(e->parameters.hold * outSampleRate); + if (e->samplesUntilNextSegment > 0) { + e->segment = TSF_SEGMENT_HOLD; + e->segmentIsExponential = TSF_FALSE; + e->level = 1.0f; + e->slope = 0.0f; + return; + } + /* fall through */ + case TSF_SEGMENT_HOLD: + e->samplesUntilNextSegment = (int)(e->parameters.decay * outSampleRate); + if (e->samplesUntilNextSegment > 0) { + e->segment = TSF_SEGMENT_DECAY; + e->level = 1.0f; + if (e->isAmpEnv) { + // I don't truly understand this; just following what LinuxSampler does. + float mysterySlope = -9.226f / e->samplesUntilNextSegment; + e->slope = TSF_EXPF(mysterySlope); + e->segmentIsExponential = TSF_TRUE; + if (e->parameters.sustain > 0.0f) { + // Again, this is following LinuxSampler's example, which is similar to + // SF2-style decay, where "decay" specifies the time it would take to + // get to zero, not to the sustain level. The SFZ spec is not that + // specific about what "decay" means, so perhaps it's really supposed + // to specify the time to reach the sustain level. + e->samplesUntilNextSegment = (int)(TSF_LOG(e->parameters.sustain) / mysterySlope); + } + } else { + e->slope = -1.0f / e->samplesUntilNextSegment; + e->samplesUntilNextSegment = (int)(e->parameters.decay * (1.0f - e->parameters.sustain) * outSampleRate); + e->segmentIsExponential = TSF_FALSE; + } + return; + } + /* fall through */ + case TSF_SEGMENT_DECAY: + e->segment = TSF_SEGMENT_SUSTAIN; + e->level = e->parameters.sustain; + e->slope = 0.0f; + e->samplesUntilNextSegment = 0x7FFFFFFF; + e->segmentIsExponential = TSF_FALSE; + return; + case TSF_SEGMENT_SUSTAIN: + e->segment = TSF_SEGMENT_RELEASE; + e->samplesUntilNextSegment = (int)((e->parameters.release <= 0 ? TSF_FASTRELEASETIME : e->parameters.release) * outSampleRate); + if (e->isAmpEnv) { + // I don't truly understand this; just following what LinuxSampler does. + float mysterySlope = -9.226f / e->samplesUntilNextSegment; + e->slope = TSF_EXPF(mysterySlope); + e->segmentIsExponential = TSF_TRUE; + } else { + e->slope = -e->level / e->samplesUntilNextSegment; + e->segmentIsExponential = TSF_FALSE; + } + return; + case TSF_SEGMENT_RELEASE: + default: + e->segment = TSF_SEGMENT_DONE; + e->segmentIsExponential = TSF_FALSE; + e->level = e->slope = 0.0f; + e->samplesUntilNextSegment = 0x7FFFFFF; + } +} + +static void tsf_voice_envelope_setup(struct tsf_voice_envelope* e, struct tsf_envelope* new_parameters, int midiNoteNumber, short midiVelocity, TSF_BOOL isAmpEnv, float outSampleRate) { + e->parameters = *new_parameters; + if (e->parameters.keynumToHold) { + e->parameters.hold += e->parameters.keynumToHold * (60.0f - midiNoteNumber); + e->parameters.hold = (e->parameters.hold < -10000.0f ? 0.0f : tsf_timecents2Secsf(e->parameters.hold)); + } + if (e->parameters.keynumToDecay) { + e->parameters.decay += e->parameters.keynumToDecay * (60.0f - midiNoteNumber); + e->parameters.decay = (e->parameters.decay < -10000.0f ? 0.0f : tsf_timecents2Secsf(e->parameters.decay)); + } + e->midiVelocity = midiVelocity; + e->isAmpEnv = isAmpEnv; + tsf_voice_envelope_nextsegment(e, TSF_SEGMENT_NONE, outSampleRate); +} + +static void tsf_voice_envelope_process(struct tsf_voice_envelope* e, int numSamples, float outSampleRate) { + if (e->slope) { + if (e->segmentIsExponential) { + e->level *= TSF_POWF(e->slope, (float)numSamples); + } else { + e->level += (e->slope * numSamples); + } + } + if ((e->samplesUntilNextSegment -= numSamples) <= 0) { + tsf_voice_envelope_nextsegment(e, e->segment, outSampleRate); + } +} + +static void tsf_voice_lowpass_setup(struct tsf_voice_lowpass* e, float Fc) { + // Lowpass filter from http://www.earlevel.com/main/2012/11/26/biquad-c-source-code/ + double K = TSF_TAN(TSF_PI * Fc), KK = K * K; + double norm = 1 / (1 + K * e->QInv + KK); + e->a0 = KK * norm; + e->a1 = 2 * e->a0; + e->b1 = 2 * (KK - 1) * norm; + e->b2 = (1 - K * e->QInv + KK) * norm; +} + +static float tsf_voice_lowpass_process(struct tsf_voice_lowpass* e, double In) { + double Out = In * e->a0 + e->z1; e->z1 = In * e->a1 + e->z2 - e->b1 * Out; e->z2 = In * e->a0 - e->b2 * Out; return (float)Out; +} + +static void tsf_voice_lfo_setup(struct tsf_voice_lfo* e, float delay, int freqCents, float outSampleRate) { + e->samplesUntil = (int)(delay * outSampleRate); + e->delta = (4.0f * tsf_cents2Hertz((float)freqCents) / outSampleRate); + e->level = 0; +} + +static void tsf_voice_lfo_process(struct tsf_voice_lfo* e, int blockSamples) { + if (e->samplesUntil > blockSamples) { + e->samplesUntil -= blockSamples; + return; + } + e->level += e->delta * blockSamples; + if (e->level > 1.0f) { + e->delta = -e->delta; + e->level = 2.0f - e->level; + } else if (e->level < -1.0f) { + e->delta = -e->delta; + e->level = -2.0f - e->level; + } +} + +static void tsf_voice_kill(struct tsf_voice* v) { + v->playingPreset = -1; +} + +static void tsf_voice_end(struct tsf_voice* v, float outSampleRate) { + tsf_voice_envelope_nextsegment(&v->ampenv, TSF_SEGMENT_SUSTAIN, outSampleRate); + tsf_voice_envelope_nextsegment(&v->modenv, TSF_SEGMENT_SUSTAIN, outSampleRate); + if (v->region->loop_mode == TSF_LOOPMODE_SUSTAIN) { + // Continue playing, but stop looping. + v->loopEnd = v->loopStart; + v->loopSizeF32P32 = 0; + } +} + +static void tsf_voice_endquick(struct tsf_voice* v, float outSampleRate) { + v->ampenv.parameters.release = 0.0f; tsf_voice_envelope_nextsegment(&v->ampenv, TSF_SEGMENT_SUSTAIN, outSampleRate); + v->modenv.parameters.release = 0.0f; tsf_voice_envelope_nextsegment(&v->modenv, TSF_SEGMENT_SUSTAIN, outSampleRate); +} + +static void tsf_voice_calcpitchratio(struct tsf_voice* v, float pitchShift, float outSampleRate) { + double note = v->playingKey + v->region->transpose + v->region->tune / 100.0; + double adjustedPitch = (note - v->region->pitch_keycenter) * v->region->pitch_keytrack; + if (pitchShift) { + adjustedPitch += adjustedPitch * 100.0f; + } + v->pitchRatio = v->region->sample_rate * tsf_timecents2Secsd(adjustedPitch) / outSampleRate; +} + +short tsf_read_short_cached(tsf *f, int pos) { + static int hits = 0; + static int misses = 0; + // static int call =0; + // call++; + // if ((call % 88000) ==0) printf("Hit: %d, Miss: %d, Ratio: %f\n", hits, misses, (double)hits/(double)(misses+hits)); + + for (int i = 0; i < TSF_BUFFS; i++) { + if ((f->offset[i] <= pos) && ((f->offset[i] + TSF_BUFFSIZE) > pos)) { + f->timestamp[i] = f->epoch++; + if (f->epoch == 0) { + for (int i = 0; i < TSF_BUFFS; i++) { + f->timestamp[i] = f->epoch++; + } + } + hits++; + return f->buffer[i][pos - f->offset[i]]; + } + } + int repl = 0; + for (int i = 1; i < TSF_BUFFS; i++) { + if (f->timestamp[i] < f->timestamp[repl]) { + repl = i; + } + } + int readOff = pos - (pos % TSF_BUFFSIZE); + // for (int i=0; ibuffer[repl][i] = i; } + f->hydra->stream->seek(f->hydra->stream->data, readOff * sizeof(short)); + f->hydra->stream->read(f->hydra->stream->data, f->buffer[repl], TSF_BUFFSIZE * sizeof(short)); + //static uint32_t *bp = NULL; if (!bp) bp = (uint32_t*)malloc(512); + //printf("off=%08x, buff=%p, len=%08x\n", readOff * sizeof(short), bp, TSF_BUFFSIZE); spi_flash_read(0x0000, bp, 512/4-4) ; + f->timestamp[repl] = f->epoch++; + f->offset[repl] = readOff; + misses++; + // fprintf(stderr, "buffer[%d][%d-%d = %d]\n", repl, pos, readOff, pos - readOff); + return f->buffer[repl][pos - readOff]; +} + +static void tsf_voice_render(tsf* f, struct tsf_voice* v, float* outputBuffer, int numSamples) { + struct tsf_region* region = v->region; + float* outL = outputBuffer; + float* outR = (f->outputmode == TSF_STEREO_UNWEAVED ? outL + numSamples : TSF_NULL); + + // Cache some values, to give them at least some chance of ending up in registers. + TSF_BOOL updateModEnv = (region->modEnvToPitch || region->modEnvToFilterFc); + TSF_BOOL updateModLFO = (v->modlfo.delta && (region->modLfoToPitch || region->modLfoToFilterFc || region->modLfoToVolume)); + TSF_BOOL updateVibLFO = (v->viblfo.delta && (region->vibLfoToPitch)); + TSF_BOOL isLooping = (v->loopStart < v->loopEnd); + unsigned int tmpLoopStart = v->loopStart, tmpLoopEnd = v->loopEnd; + double tmpSampleEndDbl = (double)region->end, tmpLoopEndDbl = (double)tmpLoopEnd + 1.0; + double tmpSourceSamplePosition = v->sourceSamplePosition; + struct tsf_voice_lowpass tmpLowpass = v->lowpass; + + TSF_BOOL dynamicLowpass = (region->modLfoToFilterFc || region->modEnvToFilterFc); + float tmpSampleRate = f->outSampleRate, tmpInitialFilterFc, tmpModLfoToFilterFc, tmpModEnvToFilterFc; + + TSF_BOOL dynamicPitchRatio = (region->modLfoToPitch || region->modEnvToPitch || region->vibLfoToPitch); + double pitchRatio; + float tmpModLfoToPitch, tmpVibLfoToPitch, tmpModEnvToPitch; + + TSF_BOOL dynamicGain = (region->modLfoToVolume != 0); + float noteGain = 0, tmpModLfoToVolume; + + if (dynamicLowpass) { + tmpInitialFilterFc = (float)region->initialFilterFc, tmpModLfoToFilterFc = (float)region->modLfoToFilterFc, tmpModEnvToFilterFc = (float)region->modEnvToFilterFc; + } else { + tmpInitialFilterFc = 0, tmpModLfoToFilterFc = 0, tmpModEnvToFilterFc = 0; + } + + if (dynamicPitchRatio) { + pitchRatio = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch; + } else { + pitchRatio = v->pitchRatio, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0; + } + + if (dynamicGain) { + tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f; + } else { + noteGain = v->noteGain, tmpModLfoToVolume = 0; + } + + while (numSamples) { + float gainMono, gainLeft, gainRight; + int blockSamples = (numSamples > TSF_RENDER_EFFECTSAMPLEBLOCK ? TSF_RENDER_EFFECTSAMPLEBLOCK : numSamples); + numSamples -= blockSamples; + + if (dynamicLowpass) { + float fres = tmpInitialFilterFc + v->modlfo.level * tmpModLfoToFilterFc + v->modenv.level * tmpModEnvToFilterFc; + float lowpassFc = (fres <= 13500 ? tsf_cents2Hertz(fres) / tmpSampleRate : 1.0f); + tmpLowpass.active = (lowpassFc < 0.499f); + if (tmpLowpass.active) { + tsf_voice_lowpass_setup(&tmpLowpass, lowpassFc); + } + } + + if (dynamicPitchRatio) { + pitchRatio = v->pitchRatio * tsf_timecents2Secsd(v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch); + } + + if (dynamicGain) { + noteGain = v->noteGain * tsf_decibelsToGain(v->modlfo.level * tmpModLfoToVolume); + } + + gainMono = noteGain * v->ampenv.level; + + // Update EG. + tsf_voice_envelope_process(&v->ampenv, blockSamples, tmpSampleRate); + if (updateModEnv) { + tsf_voice_envelope_process(&v->modenv, blockSamples, tmpSampleRate); + } + + // Update LFOs. + if (updateModLFO) { + tsf_voice_lfo_process(&v->modlfo, blockSamples); + } + if (updateVibLFO) { + tsf_voice_lfo_process(&v->viblfo, blockSamples); + } + + switch (f->outputmode) { + case TSF_STEREO_INTERLEAVED: + gainLeft = gainMono * v->panFactorLeft, gainRight = gainMono * v->panFactorRight; + while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl) { + unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1); + float inputPos, inputNextPos; + inputPos = (float)(tsf_read_short_cached(f, pos) / 32767.0); + inputNextPos = (float)(tsf_read_short_cached(f, nextPos) / 32767.0); + // Simple linear interpolation. + float alpha = (float)(tmpSourceSamplePosition - pos), val = (inputPos * (1.0f - alpha) + inputNextPos * alpha); + + // Low-pass filter. + if (tmpLowpass.active) { + val = tsf_voice_lowpass_process(&tmpLowpass, val); + } + + *outL++ += val * gainLeft; + *outL++ += val * gainRight; + + // Next sample. + tmpSourceSamplePosition += pitchRatio; + if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) { + tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0); + } + } + break; + + case TSF_STEREO_UNWEAVED: + gainLeft = gainMono * v->panFactorLeft, gainRight = gainMono * v->panFactorRight; + while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl) { + unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1); + float inputPos, inputNextPos; + inputPos = (float)(tsf_read_short_cached(f, pos) / 32767.0); + inputNextPos = (float)(tsf_read_short_cached(f, nextPos) / 32767.0); + + // Simple linear interpolation. + float alpha = (float)(tmpSourceSamplePosition - pos), val = (inputPos * (1.0f - alpha) + inputNextPos * alpha); + + // Low-pass filter. + if (tmpLowpass.active) { + val = tsf_voice_lowpass_process(&tmpLowpass, val); + } + + *outL++ += val * gainLeft; + *outR++ += val * gainRight; + + // Next sample. + tmpSourceSamplePosition += pitchRatio; + if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) { + tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0); + } + } + break; + + case TSF_MONO: + while (blockSamples-- && tmpSourceSamplePosition < tmpSampleEndDbl) { + unsigned int pos = (unsigned int)tmpSourceSamplePosition, nextPos = (pos >= tmpLoopEnd && isLooping ? tmpLoopStart : pos + 1); + float inputPos, inputNextPos; + inputPos = (float)(tsf_read_short_cached(f, pos) / 32767.0); + inputNextPos = (float)(tsf_read_short_cached(f, nextPos) / 32767.0); + + // Simple linear interpolation. + float alpha = (float)(tmpSourceSamplePosition - pos), val = (inputPos * (1.0f - alpha) + inputNextPos * alpha); + + // Low-pass filter. + if (tmpLowpass.active) { + val = tsf_voice_lowpass_process(&tmpLowpass, val); + } + + *outL++ += val * gainMono; + + // Next sample. + tmpSourceSamplePosition += pitchRatio; + if (tmpSourceSamplePosition >= tmpLoopEndDbl && isLooping) { + tmpSourceSamplePosition -= (tmpLoopEnd - tmpLoopStart + 1.0); + } + } + break; + } + + if (tmpSourceSamplePosition >= tmpSampleEndDbl || v->ampenv.segment == TSF_SEGMENT_DONE) { + tsf_voice_kill(v); + return; + } + } + + v->sourceSamplePosition = tmpSourceSamplePosition; + if (tmpLowpass.active || dynamicLowpass) { + v->lowpass = tmpLowpass; + } } //void DumpF32P32(char *name, long long x) { // printf("%s = %08x.%08x\n", name, (int32_t)((x>>32)&0xffffffff), (int32_t)(x&0xffffffff)); //} -static void tsf_voice_render_fast(tsf* f, struct tsf_voice* v, short* outputBuffer, int numSamples) -{ - struct tsf_region* region = v->region; - short* outL = outputBuffer; - short* outR = (f->outputmode == TSF_STEREO_UNWEAVED ? outL + numSamples : TSF_NULL); - - // Cache some values, to give them at least some chance of ending up in registers. - TSF_BOOL updateModEnv = (region->modEnvToPitch || region->modEnvToFilterFc); - TSF_BOOL updateModLFO = (v->modlfo.delta && (region->modLfoToPitch || region->modLfoToFilterFc || region->modLfoToVolume)); - TSF_BOOL updateVibLFO = (v->viblfo.delta && (region->vibLfoToPitch)); - TSF_BOOL isLooping = (v->loopStart < v->loopEnd); - unsigned int tmpLoopStart = v->loopStart, tmpLoopEnd = v->loopEnd; - //double tmpSampleEndDbl = (double)v->sampleEnd, tmpLoopEndDbl = (double)tmpLoopEnd + 1.0; - //double tmpSourceSamplePosition = v->sourceSamplePosition; - fixed32p32 tmpSampleEndF32P32 = ((fixed32p32)(region->end)) << 32; - fixed32p32 tmpLoopEndF32P32 = ((fixed32p32)(tmpLoopEnd + 1)) << 32; - fixed32p32 tmpSourceSamplePositionF32P32 = v->sourceSamplePositionF32P32; - struct tsf_voice_lowpass tmpLowpass = v->lowpass; - - TSF_BOOL dynamicLowpass = (region->modLfoToFilterFc || region->modEnvToFilterFc); - float tmpSampleRate = f->outSampleRate, tmpInitialFilterFc, tmpModLfoToFilterFc, tmpModEnvToFilterFc; - - TSF_BOOL dynamicPitchRatio = (region->modLfoToPitch || region->modEnvToPitch || region->vibLfoToPitch); - //double pitchRatio; - fixed32p32 pitchRatioF32P32; - float tmpModLfoToPitch, tmpVibLfoToPitch, tmpModEnvToPitch; - - TSF_BOOL dynamicGain = (region->modLfoToVolume != 0); - float noteGain, tmpModLfoToVolume; - - if (dynamicLowpass) tmpInitialFilterFc = (float)region->initialFilterFc, tmpModLfoToFilterFc = (float)region->modLfoToFilterFc, tmpModEnvToFilterFc = (float)region->modEnvToFilterFc; - else tmpInitialFilterFc = 0, tmpModLfoToFilterFc = 0, tmpModEnvToFilterFc = 0; - - if (dynamicPitchRatio) pitchRatioF32P32 = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch; - else { - double pr = tsf_timecents2Secsd(v->pitchInputTimecents) * v->pitchOutputFactor; - fixed32p32 adj = 1LL<<32; - pr *= adj; - pitchRatioF32P32 = (int64_t)pr, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0; - } - - if (dynamicGain) noteGain = 0, tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f; - else noteGain = tsf_decibelsToGain(v->noteGainDB), tmpModLfoToVolume = 0; - - while (numSamples) - { - float gainMono; - int blockSamples = (numSamples > TSF_RENDER_EFFECTSAMPLEBLOCK ? TSF_RENDER_EFFECTSAMPLEBLOCK : numSamples); - numSamples -= blockSamples; - - if (dynamicLowpass) - { - float fres = tmpInitialFilterFc + v->modlfo.level * tmpModLfoToFilterFc + v->modenv.level * tmpModEnvToFilterFc; - tmpLowpass.active = (fres <= 13500.0f); - if (tmpLowpass.active) tsf_voice_lowpass_setup(&tmpLowpass, tsf_cents2Hertz(fres) / tmpSampleRate); - } +static void tsf_voice_render_fast(tsf* f, struct tsf_voice* v, short* outputBuffer, int numSamples) { + struct tsf_region* region = v->region; + short* outL = outputBuffer; + short* outR = (f->outputmode == TSF_STEREO_UNWEAVED ? outL + numSamples : TSF_NULL); + + // Cache some values, to give them at least some chance of ending up in registers. + TSF_BOOL updateModEnv = (region->modEnvToPitch || region->modEnvToFilterFc); + TSF_BOOL updateModLFO = (v->modlfo.delta && (region->modLfoToPitch || region->modLfoToFilterFc || region->modLfoToVolume)); + TSF_BOOL updateVibLFO = (v->viblfo.delta && (region->vibLfoToPitch)); + TSF_BOOL isLooping = (v->loopSizeF32P32 > 0); + fixed32p32 tmpSampleEndF32P32 = (fixed32p32)(region->end) << 32; + fixed32p32 tmpSourceSamplePositionF32P32 = v->sourceSamplePositionF32P32; + + TSF_BOOL dynamicPitchRatio = (region->modLfoToPitch || region->modEnvToPitch || region->vibLfoToPitch); + fixed32p32 pitchRatioF32P32, tmpPitchRatioF32P32; + float tmpModLfoToPitch, tmpVibLfoToPitch, tmpModEnvToPitch; + + TSF_BOOL dynamicGain = (region->modLfoToVolume != 0); + float noteGain, tmpNoteGain, tmpModLfoToVolume; if (dynamicPitchRatio) { - pitchRatioF32P32 = tsf_timecents2Secsd(v->pitchInputTimecents + (v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch)) * v->pitchOutputFactor * (1LL<<32); - } - - if (dynamicGain) - noteGain = tsf_decibelsToGain(v->noteGainDB + (v->modlfo.level * tmpModLfoToVolume)); - - gainMono = noteGain * v->ampenv.level; - short gainMonoFP = gainMono * 32767; - - // Update EG. - tsf_voice_envelope_process(&v->ampenv, blockSamples, f->outSampleRate); - if (updateModEnv) tsf_voice_envelope_process(&v->modenv, blockSamples, f->outSampleRate); - - // Update LFOs. - if (updateModLFO) tsf_voice_lfo_process(&v->modlfo, blockSamples); - if (updateVibLFO) tsf_voice_lfo_process(&v->viblfo, blockSamples); - - while (blockSamples-- && tmpSourceSamplePositionF32P32 < tmpSampleEndF32P32) - { - unsigned int pos = (unsigned int)(tmpSourceSamplePositionF32P32>>32); - if (pos == 0xffffffff) pos = 0; - short val = tsf_read_short_cached(f, pos); - int32_t val32 = (int)val * (int)gainMonoFP; - - *outL++ += val32>>16; - if (f->outputmode != TSF_MONO) *outR++ += val32>>16; - - // Next sample. - tmpSourceSamplePositionF32P32 += pitchRatioF32P32; - if (tmpSourceSamplePositionF32P32 >= tmpLoopEndF32P32 && isLooping) - tmpSourceSamplePositionF32P32 -= (tmpLoopEndF32P32 - tmpLoopStart + (1LL<<32)); - } - - if (tmpSourceSamplePositionF32P32 >= tmpSampleEndF32P32 || v->ampenv.segment == TSF_SEGMENT_DONE) - { - tsf_voice_kill(v); - return; - } - } - - v->sourceSamplePositionF32P32 = tmpSourceSamplePositionF32P32; - if (tmpLowpass.active || dynamicLowpass) v->lowpass = tmpLowpass; -} - - - - -TSFDEF tsf* tsf_load(struct tsf_stream* stream) -{ - tsf* res = TSF_NULL; - struct tsf_riffchunk chunkHead; - struct tsf_riffchunk chunkList; - struct tsf_hydra hydra; - int fontSamplesOffset = 0; - unsigned int fontSampleCount = 0; - - if (!tsf_riffchunk_read(TSF_NULL, &chunkHead, stream) || !TSF_FourCCEquals(chunkHead.id, "sfbk")) - { - //if (e) *e = TSF_INVALID_NOSF2HEADER; - return res; - } - - // Read hydra and locate sample data. - TSF_MEMSET(&hydra, 0, sizeof(hydra)); - hydra.stream = stream; - while (tsf_riffchunk_read(&chunkHead, &chunkList, stream)) - { - struct tsf_riffchunk chunk; - if (TSF_FourCCEquals(chunkList.id, "pdta")) - { - while (tsf_riffchunk_read(&chunkList, &chunk, stream)) - { - #define GetChunkOffset(chunkName) (TSF_FourCCEquals(chunk.id, #chunkName) && !(chunk.size % chunkName##SizeInFile)) \ + tmpPitchRatioF32P32 = v->pitchRatioF32P32, pitchRatioF32P32 = 0, tmpModLfoToPitch = (float)region->modLfoToPitch, tmpVibLfoToPitch = (float)region->vibLfoToPitch, tmpModEnvToPitch = (float)region->modEnvToPitch; + } else { + pitchRatioF32P32 = v->pitchRatioF32P32, tmpModLfoToPitch = 0, tmpVibLfoToPitch = 0, tmpModEnvToPitch = 0; + } + + if (dynamicGain) { + noteGain = 0, tmpNoteGain = v->noteGain, tmpModLfoToVolume = (float)region->modLfoToVolume * 0.1f; + } else { + noteGain = v->noteGain, tmpModLfoToVolume = 0; + } + + while (numSamples) { + float gainMono; + int blockSamples = (numSamples > TSF_RENDER_EFFECTSAMPLEBLOCK ? TSF_RENDER_EFFECTSAMPLEBLOCK : numSamples); + numSamples -= blockSamples; + + if (dynamicPitchRatio) { + if (v->modlfo.level || v->viblfo.level || v->modenv.level) { + pitchRatioF32P32 = tmpPitchRatioF32P32 * tsf_timecents2Secsd(v->modlfo.level * tmpModLfoToPitch + v->viblfo.level * tmpVibLfoToPitch + v->modenv.level * tmpModEnvToPitch); + } else { + pitchRatioF32P32 = tmpPitchRatioF32P32; // If all levels are 0, just bypass conversion function + } + } + + if (dynamicGain) { + if (v->modlfo.level) { + noteGain = tmpNoteGain * tsf_decibelsToGain(v->modlfo.level * tmpModLfoToVolume); + } else { + noteGain = tmpNoteGain; // If level is 0, just bypass conversion function + } + } + + gainMono = noteGain * v->ampenv.level; + short gainMonoFP = gainMono * 32767; + + // Update EG. + tsf_voice_envelope_process(&v->ampenv, blockSamples, f->outSampleRate); + if (updateModEnv) { + tsf_voice_envelope_process(&v->modenv, blockSamples, f->outSampleRate); + } + + // Update LFOs. + if (updateModLFO) { + tsf_voice_lfo_process(&v->modlfo, blockSamples); + } + if (updateVibLFO) { + tsf_voice_lfo_process(&v->viblfo, blockSamples); + } + + while (blockSamples--) { + unsigned int pos = (unsigned int)(tmpSourceSamplePositionF32P32 >> 32); + if (pos == 0xffffffff) { + pos = 0; + } + short val = tsf_read_short_cached(f, pos); + int32_t val32 = (int)val * (int)gainMonoFP; + + *outL++ += val32 >> 16; + if (f->outputmode != TSF_MONO) { + *outR++ += val32 >> 16; + } + + // Next sample. + tmpSourceSamplePositionF32P32 += pitchRatioF32P32; + + if (tmpSourceSamplePositionF32P32 >= v->loopEndF32P32) { + if (isLooping) { + tmpSourceSamplePositionF32P32 -= v->loopSizeF32P32; + } else if (tmpSourceSamplePositionF32P32 >= tmpSampleEndF32P32) { + break; + } + } + } + + if (tmpSourceSamplePositionF32P32 >= tmpSampleEndF32P32 || v->ampenv.segment == TSF_SEGMENT_DONE) { + tsf_voice_kill(v); + return; + } + } + + v->sourceSamplePositionF32P32 = tmpSourceSamplePositionF32P32; +} + + + + +TSFDEF tsf* tsf_load(struct tsf_stream* stream) { + tsf* res = TSF_NULL; + struct tsf_riffchunk chunkHead; + struct tsf_riffchunk chunkList; + struct tsf_hydra hydra; + int fontSamplesOffset = 0; + unsigned int fontSampleCount = 0; + + if (!tsf_riffchunk_read(TSF_NULL, &chunkHead, stream) || !TSF_FourCCEquals(chunkHead.id, "sfbk")) { + //if (e) *e = TSF_INVALID_NOSF2HEADER; + return res; + } + + // Read hydra and locate sample data. + TSF_MEMSET(&hydra, 0, sizeof(hydra)); + hydra.stream = stream; + while (tsf_riffchunk_read(&chunkHead, &chunkList, stream)) { + struct tsf_riffchunk chunk; + if (TSF_FourCCEquals(chunkList.id, "pdta")) { + while (tsf_riffchunk_read(&chunkList, &chunk, stream)) { +#define GetChunkOffset(chunkName) (TSF_FourCCEquals(chunk.id, #chunkName) && !(chunk.size % chunkName##SizeInFile)) \ { \ int num = chunk.size / chunkName##SizeInFile; \ hydra.chunkName##Num = num; \ hydra.chunkName##Offset = stream->tell(stream->data); \ stream->skip(stream->data, num * chunkName##SizeInFile); \ } - if GetChunkOffset(phdr) - else if GetChunkOffset(pbag) - else if GetChunkOffset(pmod) - else if GetChunkOffset(pgen) - else if GetChunkOffset(inst) - else if GetChunkOffset(ibag) - else if GetChunkOffset(imod) - else if GetChunkOffset(igen) - else if GetChunkOffset(shdr) - else stream->skip(stream->data, chunk.size); - #undef HandleChunk - } - } - else if (TSF_FourCCEquals(chunkList.id, "sdta")) - { - while (tsf_riffchunk_read(&chunkList, &chunk, stream)) - { - if (TSF_FourCCEquals(chunk.id, "smpl")) - { - tsf_load_samples(&fontSamplesOffset, &fontSampleCount, &chunk, stream); - } - else stream->skip(stream->data, chunk.size); - } - } - else stream->skip(stream->data, chunkList.size); - } - if (!hydra.phdrNum || !hydra.pbagNum || !hydra.pmodNum || !hydra.pgenNum || !hydra.instNum || !hydra.ibagNum || !hydra.imodNum || !hydra.igenNum || !hydra.shdrNum) - { - //if (e) *e = TSF_INVALID_INCOMPLETE; - } - else if (fontSamplesOffset == 0) - { - //if (e) *e = TSF_INVALID_NOSAMPLEDATA; - } - else - { - res = (tsf*)TSF_MALLOC(sizeof(tsf)); - TSF_MEMSET(res, 0, sizeof(tsf)); - res->presetNum = hydra.phdrNum - 1; - res->presets = (struct tsf_preset*)TSF_MALLOC(res->presetNum * sizeof(struct tsf_preset)); - TSF_MEMSET(res->presets, 0, res->presetNum * sizeof(struct tsf_preset)); - res->fontSamplesOffset = fontSamplesOffset; - res->fontSampleCount = fontSampleCount; - res->outSampleRate = 44100.0f; - res->hydra = (struct tsf_hydra*)TSF_MALLOC(sizeof(struct tsf_hydra)); - TSF_MEMCPY(res->hydra, &hydra, sizeof(*res->hydra)); - res->hydra->stream = (struct tsf_stream*)TSF_MALLOC(sizeof(struct tsf_stream)); - TSF_MEMCPY(res->hydra->stream, stream, sizeof(*res->hydra->stream)); - - // Cached sample - for (int i=0; ibuffer[i] = (short*)TSF_MALLOC(TSF_BUFFSIZE * sizeof(short)); - res->offset[i] = 0xfffffff; - res->timestamp[i] = -1; - } - res->epoch = 0; - } - return res; -} - -TSFDEF void tsf_close(tsf* f) -{ - struct tsf_preset *preset, *presetEnd; - if (!f) return; - for (preset = f->presets, presetEnd = preset + f->presetNum; preset != presetEnd; preset++) - TSF_FREE(preset->regions); - TSF_FREE(f->presets); - TSF_FREE(f->voices); - if (f->channels) { TSF_FREE(f->channels->channels); TSF_FREE(f->channels); } - TSF_FREE(f->outputSamples); - f->hydra->stream->close(f->hydra->stream->data); - TSF_FREE(f->hydra->stream); - TSF_FREE(f->hydra); - for (int i=0; ibuffer[i]); - TSF_FREE(f); -} - -TSFDEF void tsf_reset(tsf* f) -{ - struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; - for (; v != vEnd; v++) - if (v->playingPreset != -1 && (v->ampenv.segment < TSF_SEGMENT_RELEASE || v->ampenv.parameters.release)) - tsf_voice_endquick(v, f->outSampleRate); - if (f->channels) { TSF_FREE(f->channels->channels); TSF_FREE(f->channels); f->channels = TSF_NULL; } -} - -TSFDEF int tsf_get_presetindex(const tsf* f, int bank, int preset_number) -{ - const struct tsf_preset *presets; - int i, iMax; - for (presets = f->presets, i = 0, iMax = f->presetNum; i < iMax; i++) - if (presets[i].preset == preset_number && presets[i].bank == bank) - return i; - return -1; -} - -TSFDEF int tsf_get_presetcount(const tsf* f) -{ - return f->presetNum; -} - -TSFDEF const char* tsf_get_presetname(const tsf* f, int preset) -{ - if (f->presets[preset].regions == NULL && preset >= 0 && preset < f->presetNum) tsf_load_preset(f, f->hydra, preset); - return (preset < 0 || preset >= f->presetNum ? TSF_NULL : f->presets[preset].presetName); -} - -TSFDEF const char* tsf_bank_get_presetname(const tsf* f, int bank, int preset_number) -{ - return tsf_get_presetname(f, tsf_get_presetindex(f, bank, preset_number)); -} - -TSFDEF void tsf_set_output(tsf* f, enum TSFOutputMode outputmode, int samplerate, float global_gain_db) -{ - f->outputmode = outputmode; - f->outSampleRate = (float)(samplerate >= 1 ? samplerate : 44100.0f); - f->globalGainDB = global_gain_db; -} - -TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel) -{ - short midiVelocity = (short)(vel * 127); - int voicePlayIndex; - struct tsf_region *region, *regionEnd; - - if (preset_index < 0 || preset_index >= f->presetNum) return; - if (vel <= 0.0f) { tsf_note_off(f, preset_index, key); return; } - if (f->presets[preset_index].regions == NULL) tsf_load_preset(f, f->hydra, preset_index); - - // Play all matching regions. - voicePlayIndex = f->voicePlayIndex++; - for (region = f->presets[preset_index].regions, regionEnd = region + f->presets[preset_index].regionNum; region != regionEnd; region++) - { - struct tsf_voice *voice, *v, *vEnd; TSF_BOOL doLoop; float lowpassFilterQDB, lowpassFc; - if (key < region->lokey || key > region->hikey || midiVelocity < region->lovel || midiVelocity > region->hivel) continue; - - voice = TSF_NULL, v = f->voices, vEnd = v + f->voiceNum; - if (region->group) - { - for (; v != vEnd; v++) - if (v->playingPreset == preset_index && v->region->group == region->group) tsf_voice_endquick(v, f->outSampleRate); - else if (v->playingPreset == -1 && !voice) voice = v; - } - else for (; v != vEnd; v++) if (v->playingPreset == -1) { voice = v; break; } - - if (!voice) - { - f->voiceNum += 4; - struct tsf_voice *saveVoice = f->voices; - f->voices = (struct tsf_voice*)TSF_REALLOC(f->voices, f->voiceNum * sizeof(struct tsf_voice)); - if (!f->voices) { - f->voices = saveVoice; - printf("OOM, no room for new voice. Ignoring note_on\n"); - return; - } - voice = &f->voices[f->voiceNum - 4]; - voice[1].playingPreset = voice[2].playingPreset = voice[3].playingPreset = -1; - } - - voice->region = region; - voice->playingPreset = preset_index; - voice->playingKey = key; - voice->playIndex = voicePlayIndex; - voice->noteGainDB = f->globalGainDB - region->attenuation - tsf_gainToDecibels(1.0f / vel); - - if (f->channels) - { - f->channels->setupVoice(f, voice); - } - else - { - tsf_voice_calcpitchratio(voice, 0, f->outSampleRate); - // The SFZ spec is silent about the pan curve, but a 3dB pan law seems common. This sqrt() curve matches what Dimension LE does; Alchemy Free seems closer to sin(adjustedPan * pi/2). - voice->panFactorLeft = TSF_SQRTF(0.5f - region->pan); - voice->panFactorRight = TSF_SQRTF(0.5f + region->pan); - } - - // Offset/end. - voice->sourceSamplePosition = region->offset; - voice->sourceSamplePositionF32P32 = ((int64_t)region->offset)<< 32; - - // Loop. - doLoop = (region->loop_mode != TSF_LOOPMODE_NONE && region->loop_start < region->loop_end); - voice->loopStart = (doLoop ? region->loop_start : 0); - voice->loopEnd = (doLoop ? region->loop_end : 0); - - // Setup envelopes. - tsf_voice_envelope_setup(&voice->ampenv, ®ion->ampenv, key, midiVelocity, TSF_TRUE, f->outSampleRate); - tsf_voice_envelope_setup(&voice->modenv, ®ion->modenv, key, midiVelocity, TSF_FALSE, f->outSampleRate); - - // Setup lowpass filter. - lowpassFc = (region->initialFilterFc <= 13500 ? tsf_cents2Hertz((float)region->initialFilterFc) / f->outSampleRate : 1.0f); - lowpassFilterQDB = region->initialFilterQ / 10.0f; - voice->lowpass.QInv = 1.0 / TSF_POW(10.0, (lowpassFilterQDB / 20.0)); - voice->lowpass.z1 = voice->lowpass.z2 = 0; - voice->lowpass.active = (lowpassFc < 0.499f); - if (voice->lowpass.active) tsf_voice_lowpass_setup(&voice->lowpass, lowpassFc); - - // Setup LFO filters. - tsf_voice_lfo_setup(&voice->modlfo, region->delayModLFO, region->freqModLFO, f->outSampleRate); - tsf_voice_lfo_setup(&voice->viblfo, region->delayVibLFO, region->freqVibLFO, f->outSampleRate); - } -} - -TSFDEF int tsf_bank_note_on(tsf* f, int bank, int preset_number, int key, float vel) -{ - int preset_index = tsf_get_presetindex(f, bank, preset_number); - if (preset_index == -1) return 0; - tsf_note_on(f, preset_index, key, vel); - return 1; -} - -TSFDEF void tsf_note_off(tsf* f, int preset_index, int key) -{ - struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum, *vMatchFirst = TSF_NULL, *vMatchLast = TSF_NULL; - for (; v != vEnd; v++) - { - //Find the first and last entry in the voices list with matching preset, key and look up the smallest play index - if (v->playingPreset != preset_index || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_RELEASE) continue; - else if (!vMatchFirst || v->playIndex < vMatchFirst->playIndex) vMatchFirst = vMatchLast = v; - else if (v->playIndex == vMatchFirst->playIndex) vMatchLast = v; - } - if (!vMatchFirst) return; - for (v = vMatchFirst; v <= vMatchLast; v++) - { - //Stop all voices with matching preset, key and the smallest play index which was enumerated above - if (v != vMatchFirst && v != vMatchLast && - (v->playIndex != vMatchFirst->playIndex || v->playingPreset != preset_index || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_RELEASE)) continue; - tsf_voice_end(v, f->outSampleRate); - } -} - -TSFDEF int tsf_bank_note_off(tsf* f, int bank, int preset_number, int key) -{ - int preset_index = tsf_get_presetindex(f, bank, preset_number); - if (preset_index == -1) return 0; - tsf_note_off(f, preset_index, key); - return 1; -} - -TSFDEF void tsf_note_off_all(tsf* f) -{ - struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; - for (; v != vEnd; v++) if (v->playingPreset != -1 && v->ampenv.segment < TSF_SEGMENT_RELEASE) - tsf_voice_end(v, f->outSampleRate); -} - -TSFDEF int tsf_active_voice_count(tsf* f) -{ - int count = 0; - struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; - for (; v != vEnd; v++) if (v->playingPreset != -1) count++; - return count; -} - -TSFDEF void tsf_render_short(tsf* f, short* buffer, int samples, int flag_mixing) -{ - float *floatSamples; - int channelSamples = (f->outputmode == TSF_MONO ? 1 : 2) * samples, floatBufferSize = channelSamples * sizeof(float); - short* bufferEnd = buffer + channelSamples; - if (floatBufferSize > f->outputSampleSize) - { - TSF_FREE(f->outputSamples); - f->outputSamples = (float*)TSF_MALLOC(floatBufferSize); - f->outputSampleSize = floatBufferSize; - } - - tsf_render_float(f, f->outputSamples, samples, TSF_FALSE); - - floatSamples = f->outputSamples; - if (flag_mixing) - while (buffer != bufferEnd) - { - float v = *floatSamples++; - int vi = *buffer + (v < -1.00004566f ? (int)-32768 : (v > 1.00001514f ? (int)32767 : (int)(v * 32767.5f))); - *buffer++ = (vi < -32768 ? (short)-32768 : (vi > 32767 ? (short)32767 : (short)vi)); - } - else - while (buffer != bufferEnd) - { - float v = *floatSamples++; - *buffer++ = (v < -1.00004566f ? (short)-32768 : (v > 1.00001514f ? (short)32767 : (short)(v * 32767.5f))); - } -} - -TSFDEF void tsf_render_float(tsf* f, float* buffer, int samples, int flag_mixing) -{ - struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; - if (!flag_mixing) TSF_MEMSET(buffer, 0, (f->outputmode == TSF_MONO ? 1 : 2) * sizeof(float) * samples); - for (; v != vEnd; v++) - if (v->playingPreset != -1) - tsf_voice_render(f, v, buffer, samples); -} - -TSFDEF void tsf_render_short_fast(tsf* f, short* buffer, int samples, int flag_mixing) -{ - struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; - if (!flag_mixing) TSF_MEMSET(buffer, 0, (f->outputmode == TSF_MONO ? 1 : 2) * sizeof(short) * samples); - for (; v != vEnd; v++) { - if (v->playingPreset != -1) - tsf_voice_render_fast(f, v, buffer, samples); - yield(); - } -} - - -static void tsf_channel_setup_voice(tsf* f, struct tsf_voice* v) -{ - struct tsf_channel* c = &f->channels->channels[f->channels->activeChannel]; - float newpan = v->region->pan + c->panOffset; - v->playingChannel = f->channels->activeChannel; - v->noteGainDB += c->gainDB; - tsf_voice_calcpitchratio(v, (c->pitchWheel == 8192 ? c->tuning : ((c->pitchWheel / 16383.0f * c->pitchRange * 2.0f) - c->pitchRange + c->tuning)), f->outSampleRate); - if (newpan <= -0.5f) { v->panFactorLeft = 1.0f; v->panFactorRight = 0.0f; } - else if (newpan >= 0.5f) { v->panFactorLeft = 0.0f; v->panFactorRight = 1.0f; } - else { v->panFactorLeft = TSF_SQRTF(0.5f - newpan); v->panFactorRight = TSF_SQRTF(0.5f + newpan); } -} - -static struct tsf_channel* tsf_channel_init(tsf* f, int channel) -{ - int i; - if (f->channels && channel < f->channels->channelNum) return &f->channels->channels[channel]; - if (!f->channels) - { - f->channels = (struct tsf_channels*)TSF_MALLOC(sizeof(struct tsf_channels)); - f->channels->setupVoice = &tsf_channel_setup_voice; - f->channels->channels = NULL; - f->channels->channelNum = 0; - f->channels->activeChannel = 0; - } - i = f->channels->channelNum; - f->channels->channelNum = channel + 1; - f->channels->channels = (struct tsf_channel*)TSF_REALLOC(f->channels->channels, f->channels->channelNum * sizeof(struct tsf_channel)); - for (; i <= channel; i++) - { - struct tsf_channel* c = &f->channels->channels[i]; - c->presetIndex = c->bank = 0; - c->pitchWheel = c->midiPan = 8192; - c->midiVolume = c->midiExpression = 16383; - c->midiRPN = 0xFFFF; - c->midiData = 0; - c->panOffset = 0.0f; - c->gainDB = 0.0f; - c->pitchRange = 2.0f; - c->tuning = 0.0f; - } - return &f->channels->channels[channel]; -} - -static void tsf_channel_applypitch(tsf* f, int channel, struct tsf_channel* c) -{ - struct tsf_voice *v, *vEnd; - float pitchShift = (c->pitchWheel == 8192 ? c->tuning : ((c->pitchWheel / 16383.0f * c->pitchRange * 2.0f) - c->pitchRange + c->tuning)); - for (v = f->voices, vEnd = v + f->voiceNum; v != vEnd; v++) - if (v->playingChannel == channel && v->playingPreset != -1) - tsf_voice_calcpitchratio(v, pitchShift, f->outSampleRate); -} - -TSFDEF void tsf_channel_set_presetindex(tsf* f, int channel, int preset_index) -{ - tsf_channel_init(f, channel)->presetIndex = (unsigned short)preset_index; -} - -TSFDEF int tsf_channel_set_presetnumber(tsf* f, int channel, int preset_number, int flag_mididrums) -{ - struct tsf_channel *c = tsf_channel_init(f, channel); - int preset_index; - if (flag_mididrums) - { - preset_index = tsf_get_presetindex(f, 128 | (c->bank & 0x7FFF), preset_number); - if (preset_index == -1) preset_index = tsf_get_presetindex(f, 128, preset_number); - if (preset_index == -1) preset_index = tsf_get_presetindex(f, 128, 0); - if (preset_index == -1) preset_index = tsf_get_presetindex(f, (c->bank & 0x7FFF), preset_number); - } - else preset_index = tsf_get_presetindex(f, (c->bank & 0x7FFF), preset_number); - if (preset_index == -1) preset_index = tsf_get_presetindex(f, 0, preset_number); - if (preset_index != -1) - { - c->presetIndex = (unsigned short)preset_index; - return 1; - } - return 0; -} - -TSFDEF void tsf_channel_set_bank(tsf* f, int channel, int bank) -{ - tsf_channel_init(f, channel)->bank = (unsigned short)bank; -} - -TSFDEF int tsf_channel_set_bank_preset(tsf* f, int channel, int bank, int preset_number) -{ - struct tsf_channel *c = tsf_channel_init(f, channel); - int preset_index = tsf_get_presetindex(f, bank, preset_number); - if (preset_index == -1) return 0; - c->presetIndex = (unsigned short)preset_index; - c->bank = (unsigned short)bank; - return 1; -} - -TSFDEF void tsf_channel_set_pan(tsf* f, int channel, float pan) -{ - struct tsf_voice *v, *vEnd; - for (v = f->voices, vEnd = v + f->voiceNum; v != vEnd; v++) - if (v->playingChannel == channel && v->playingPreset != -1) - { - float newpan = v->region->pan + pan - 0.5f; - if (newpan <= -0.5f) { v->panFactorLeft = 1.0f; v->panFactorRight = 0.0f; } - else if (newpan >= 0.5f) { v->panFactorLeft = 0.0f; v->panFactorRight = 1.0f; } - else { v->panFactorLeft = TSF_SQRTF(0.5f - newpan); v->panFactorRight = TSF_SQRTF(0.5f + newpan); } - } - tsf_channel_init(f, channel)->panOffset = pan - 0.5f; -} - -TSFDEF void tsf_channel_set_volume(tsf* f, int channel, float volume) -{ - struct tsf_channel *c = tsf_channel_init(f, channel); - float gainDB = tsf_gainToDecibels(volume), gainDBChange = gainDB - c->gainDB; - struct tsf_voice *v, *vEnd; - if (gainDBChange == 0) return; - for (v = f->voices, vEnd = v + f->voiceNum; v != vEnd; v++) - if (v->playingChannel == channel && v->playingPreset != -1) - v->noteGainDB += gainDBChange; - c->gainDB = gainDB; -} - -TSFDEF void tsf_channel_set_pitchwheel(tsf* f, int channel, int pitch_wheel) -{ - struct tsf_channel *c = tsf_channel_init(f, channel); - if (c->pitchWheel == pitch_wheel) return; - c->pitchWheel = (unsigned short)pitch_wheel; - tsf_channel_applypitch(f, channel, c); -} - -TSFDEF void tsf_channel_set_pitchrange(tsf* f, int channel, float pitch_range) -{ - struct tsf_channel *c = tsf_channel_init(f, channel); - if (c->pitchRange == pitch_range) return; - c->pitchRange = pitch_range; - if (c->pitchWheel != 8192) tsf_channel_applypitch(f, channel, c); -} - -TSFDEF void tsf_channel_set_tuning(tsf* f, int channel, float tuning) -{ - struct tsf_channel *c = tsf_channel_init(f, channel); - if (c->tuning == tuning) return; - c->tuning = tuning; - tsf_channel_applypitch(f, channel, c); -} - -TSFDEF void tsf_channel_note_on(tsf* f, int channel, int key, float vel) -{ - if (!f->channels || channel >= f->channels->channelNum) return; - f->channels->activeChannel = channel; - tsf_note_on(f, f->channels->channels[channel].presetIndex, key, vel); -} - -TSFDEF void tsf_channel_note_off(tsf* f, int channel, int key) -{ - struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum, *vMatchFirst = TSF_NULL, *vMatchLast = TSF_NULL; - for (; v != vEnd; v++) - { - //Find the first and last entry in the voices list with matching channel, key and look up the smallest play index - if (v->playingPreset == -1 || v->playingChannel != channel || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_RELEASE) continue; - else if (!vMatchFirst || v->playIndex < vMatchFirst->playIndex) vMatchFirst = vMatchLast = v; - else if (v->playIndex == vMatchFirst->playIndex) vMatchLast = v; - } - if (!vMatchFirst) return; - for (v = vMatchFirst; v <= vMatchLast; v++) - { - //Stop all voices with matching channel, key and the smallest play index which was enumerated above - if (v != vMatchFirst && v != vMatchLast && - (v->playIndex != vMatchFirst->playIndex || v->playingPreset == -1 || v->playingChannel != channel || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_RELEASE)) continue; - tsf_voice_end(v, f->outSampleRate); - } -} - -TSFDEF void tsf_channel_note_off_all(tsf* f, int channel) -{ - struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; - for (; v != vEnd; v++) - if (v->playingPreset != -1 && v->playingChannel == channel && v->ampenv.segment < TSF_SEGMENT_RELEASE) - tsf_voice_end(v, f->outSampleRate); -} - -TSFDEF void tsf_channel_sounds_off_all(tsf* f, int channel) -{ - struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; - for (; v != vEnd; v++) - if (v->playingPreset != -1 && v->playingChannel == channel && (v->ampenv.segment < TSF_SEGMENT_RELEASE || v->ampenv.parameters.release)) - tsf_voice_endquick(v, f->outSampleRate); -} - -TSFDEF void tsf_channel_midi_control(tsf* f, int channel, int controller, int control_value) -{ - struct tsf_channel* c = tsf_channel_init(f, channel); - switch (controller) - { - case 7 /*VOLUME_MSB*/ : c->midiVolume = (unsigned short)((c->midiVolume & 0x7F ) | (control_value << 7)); goto TCMC_SET_VOLUME; - case 39 /*VOLUME_LSB*/ : c->midiVolume = (unsigned short)((c->midiVolume & 0x3F80) | control_value); goto TCMC_SET_VOLUME; - case 11 /*EXPRESSION_MSB*/ : c->midiExpression = (unsigned short)((c->midiExpression & 0x7F ) | (control_value << 7)); goto TCMC_SET_VOLUME; - case 43 /*EXPRESSION_LSB*/ : c->midiExpression = (unsigned short)((c->midiExpression & 0x3F80) | control_value); goto TCMC_SET_VOLUME; - case 10 /*PAN_MSB*/ : c->midiPan = (unsigned short)((c->midiPan & 0x7F ) | (control_value << 7)); goto TCMC_SET_PAN; - case 42 /*PAN_LSB*/ : c->midiPan = (unsigned short)((c->midiPan & 0x3F80) | control_value); goto TCMC_SET_PAN; - case 6 /*DATA_ENTRY_MSB*/ : c->midiData = (unsigned short)((c->midiData & 0x7F) | (control_value << 7)); goto TCMC_SET_DATA; - case 38 /*DATA_ENTRY_LSB*/ : c->midiData = (unsigned short)((c->midiData & 0x3F80) | control_value); goto TCMC_SET_DATA; - case 0 /*BANK_SELECT_MSB*/ : c->bank = (unsigned short)(0x8000 | control_value); return; //bank select MSB alone acts like LSB - case 32 /*BANK_SELECT_LSB*/ : c->bank = (unsigned short)((c->bank & 0x8000 ? ((c->bank & 0x7F) << 7) : 0) | control_value); return; - case 101 /*RPN_MSB*/ : c->midiRPN = (unsigned short)(((c->midiRPN == 0xFFFF ? 0 : c->midiRPN) & 0x7F ) | (control_value << 7)); return; - case 100 /*RPN_LSB*/ : c->midiRPN = (unsigned short)(((c->midiRPN == 0xFFFF ? 0 : c->midiRPN) & 0x3F80) | control_value); return; - case 98 /*NRPN_LSB*/ : c->midiRPN = 0xFFFF; return; - case 99 /*NRPN_MSB*/ : c->midiRPN = 0xFFFF; return; - case 120 /*ALL_SOUND_OFF*/ : tsf_channel_sounds_off_all(f, channel); return; - case 123 /*ALL_NOTES_OFF*/ : tsf_channel_note_off_all(f, channel); return; - case 121 /*ALL_CTRL_OFF*/ : - c->midiVolume = c->midiExpression = 16383; - c->midiPan = 8192; - c->bank = 0; - tsf_channel_set_volume(f, channel, 1.0f); - tsf_channel_set_pan(f, channel, 0.5f); - tsf_channel_set_pitchrange(f, channel, 2.0f); - return; - } - return; + if GetChunkOffset(phdr) + else if GetChunkOffset(pbag) + else if GetChunkOffset(pmod) + else if GetChunkOffset(pgen) + else if GetChunkOffset(inst) + else if GetChunkOffset(ibag) + else if GetChunkOffset(imod) + else if GetChunkOffset(igen) + else if GetChunkOffset(shdr) + else { + stream->skip(stream->data, chunk.size); + } +#undef HandleChunk + } + } else if (TSF_FourCCEquals(chunkList.id, "sdta")) { + while (tsf_riffchunk_read(&chunkList, &chunk, stream)) { + if (TSF_FourCCEquals(chunk.id, "smpl")) { + tsf_load_samples(&fontSamplesOffset, &fontSampleCount, &chunk, stream); + } else { + stream->skip(stream->data, chunk.size); + } + } + } else { + stream->skip(stream->data, chunkList.size); + } + } + if (!hydra.phdrNum || !hydra.pbagNum || !hydra.pmodNum || !hydra.pgenNum || !hydra.instNum || !hydra.ibagNum || !hydra.imodNum || !hydra.igenNum || !hydra.shdrNum) { + //if (e) *e = TSF_INVALID_INCOMPLETE; + } else if (fontSamplesOffset == 0) { + //if (e) *e = TSF_INVALID_NOSAMPLEDATA; + } else { + res = (tsf*)TSF_MALLOC(sizeof(tsf)); + TSF_MEMSET(res, 0, sizeof(tsf)); + res->presetNum = hydra.phdrNum - 1; + res->presets = (struct tsf_preset*)TSF_MALLOC(res->presetNum * sizeof(struct tsf_preset)); + TSF_MEMSET(res->presets, 0, res->presetNum * sizeof(struct tsf_preset)); + res->fontSamplesOffset = fontSamplesOffset; + res->fontSampleCount = fontSampleCount; + res->outSampleRate = 44100.0f; + res->hydra = (struct tsf_hydra*)TSF_MALLOC(sizeof(struct tsf_hydra)); + TSF_MEMCPY(res->hydra, &hydra, sizeof(*res->hydra)); + res->hydra->stream = (struct tsf_stream*)TSF_MALLOC(sizeof(struct tsf_stream)); + TSF_MEMCPY(res->hydra->stream, stream, sizeof(*res->hydra->stream)); + + // Cached sample + for (int i = 0; i < TSF_BUFFS; i++) { + res->buffer[i] = (short*)TSF_MALLOC(TSF_BUFFSIZE * sizeof(short)); + res->offset[i] = 0xfffffff; + res->timestamp[i] = -1; + } + res->epoch = 0; + } + return res; +} + +TSFDEF void tsf_close(tsf* f) { + struct tsf_preset *preset, *presetEnd; + if (!f) { + return; + } + for (preset = f->presets, presetEnd = preset + f->presetNum; preset != presetEnd; preset++) { + TSF_FREE(preset->regions); + } + TSF_FREE(f->presets); + TSF_FREE(f->voices); + if (f->channels) { + TSF_FREE(f->channels->channels); + TSF_FREE(f->channels); + } + TSF_FREE(f->outputSamples); + f->hydra->stream->close(f->hydra->stream->data); + TSF_FREE(f->hydra->stream); + TSF_FREE(f->hydra); + for (int i = 0; i < TSF_BUFFS; i++) { + TSF_FREE(f->buffer[i]); + } + TSF_FREE(f); +} + +TSFDEF void tsf_reset(tsf* f) { + struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; + for (; v != vEnd; v++) + if (v->playingPreset != -1 && (v->ampenv.segment < TSF_SEGMENT_RELEASE || v->ampenv.parameters.release)) { + tsf_voice_endquick(v, f->outSampleRate); + } + if (f->channels) { + TSF_FREE(f->channels->channels); + TSF_FREE(f->channels); + f->channels = TSF_NULL; + } +} + +TSFDEF int tsf_get_presetindex(const tsf* f, int bank, int preset_number) { + const struct tsf_preset *presets; + int i, iMax; + for (presets = f->presets, i = 0, iMax = f->presetNum; i < iMax; i++) + if (presets[i].preset == preset_number && presets[i].bank == bank) { + return i; + } + return -1; +} + +TSFDEF int tsf_get_presetcount(const tsf* f) { + return f->presetNum; +} + +TSFDEF const char* tsf_get_presetname(const tsf* f, int preset) { + if (preset >= 0 && preset < f->presetNum && f->presets[preset].regions == NULL) { + tsf_load_preset(f, f->hydra, preset); + } + return (preset < 0 || preset >= f->presetNum ? TSF_NULL : f->presets[preset].presetName); +} + +TSFDEF const char* tsf_bank_get_presetname(const tsf* f, int bank, int preset_number) { + return tsf_get_presetname(f, tsf_get_presetindex(f, bank, preset_number)); +} + +TSFDEF void tsf_set_output(tsf* f, enum TSFOutputMode outputmode, int samplerate, float global_gain_db) { + f->outputmode = outputmode; + f->outSampleRate = (float)(samplerate >= 1 ? samplerate : 44100.0f); + f->globalGainDB = global_gain_db; +} + +TSFDEF void tsf_note_on(tsf* f, int preset_index, int key, float vel) { + short midiVelocity = (short)(vel * 127); + int voicePlayIndex; + struct tsf_region *region, *regionEnd; + + if (preset_index < 0 || preset_index >= f->presetNum) { + return; + } + if (vel <= 0.0f) { + tsf_note_off(f, preset_index, key); + return; + } + if (f->presets[preset_index].regions == NULL) { + tsf_load_preset(f, f->hydra, preset_index); + } + + // Play all matching regions. + voicePlayIndex = f->voicePlayIndex++; + for (region = f->presets[preset_index].regions, regionEnd = region + f->presets[preset_index].regionNum; region != regionEnd; region++) { + struct tsf_voice *voice, *v, *vEnd; TSF_BOOL doLoop; float lowpassFilterQDB, lowpassFc; + if (key < region->lokey || key > region->hikey || midiVelocity < region->lovel || midiVelocity > region->hivel) { + continue; + } + + voice = TSF_NULL, v = f->voices, vEnd = v + f->voiceNum; + if (region->group) { + for (; v != vEnd; v++) + if (v->playingPreset == preset_index && v->region->group == region->group) { + tsf_voice_endquick(v, f->outSampleRate); + } else if (v->playingPreset == -1 && !voice) { + voice = v; + } + } else for (; v != vEnd; v++) if (v->playingPreset == -1) { + voice = v; + break; + } + + if (!voice) { + f->voiceNum += 4; + struct tsf_voice *saveVoice = f->voices; + f->voices = (struct tsf_voice*)TSF_REALLOC(f->voices, f->voiceNum * sizeof(struct tsf_voice)); + if (!f->voices) { + f->voices = saveVoice; + printf("OOM, no room for new voice. Ignoring note_on\n"); + return; + } + voice = &f->voices[f->voiceNum - 4]; + voice[1].playingPreset = voice[2].playingPreset = voice[3].playingPreset = -1; + voice[1].playIndex = voice[2].playIndex = voice[3].playIndex = -1; + } + + voice->region = region; + voice->playingPreset = preset_index; + voice->playingKey = key; + voice->playIndex = voicePlayIndex; + voice->noteGain = vel * tsf_decibelsToGain(f->globalGainDB - region->attenuation); + + if (f->channels) { + f->channels->setupVoice(f, voice); + } else { + tsf_voice_calcpitchratio(voice, 0, f->outSampleRate); + // The SFZ spec is silent about the pan curve, but a 3dB pan law seems common. This sqrt() curve matches what Dimension LE does; Alchemy Free seems closer to sin(adjustedPan * pi/2). + voice->panFactorLeft = TSF_SQRTF(0.5f - region->pan); + voice->panFactorRight = TSF_SQRTF(0.5f + region->pan); + } + + // Offset/end. + voice->sourceSamplePosition = region->offset; + + // Loop. + doLoop = (region->loop_mode != TSF_LOOPMODE_NONE && region->loop_start < region->loop_end); + voice->loopStart = (doLoop ? region->loop_start : 0); + voice->loopEnd = (doLoop ? region->loop_end : 0); + + // Setup envelopes. + tsf_voice_envelope_setup(&voice->ampenv, ®ion->ampenv, key, midiVelocity, TSF_TRUE, f->outSampleRate); + tsf_voice_envelope_setup(&voice->modenv, ®ion->modenv, key, midiVelocity, TSF_FALSE, f->outSampleRate); + + // Setup lowpass filter. + lowpassFc = (region->initialFilterFc <= 13500 ? tsf_cents2Hertz((float)region->initialFilterFc) / f->outSampleRate : 1.0f); + lowpassFilterQDB = region->initialFilterQ / 10.0f; + voice->lowpass.QInv = 1.0 / TSF_POW(10.0, (lowpassFilterQDB / 20.0)); + voice->lowpass.z1 = voice->lowpass.z2 = 0; + voice->lowpass.active = (lowpassFc < 0.499f); + if (voice->lowpass.active) { + tsf_voice_lowpass_setup(&voice->lowpass, lowpassFc); + } + + // Setup LFO filters. + tsf_voice_lfo_setup(&voice->modlfo, region->delayModLFO, region->freqModLFO, f->outSampleRate); + tsf_voice_lfo_setup(&voice->viblfo, region->delayVibLFO, region->freqVibLFO, f->outSampleRate); + } +} + +/** + Returns the generated playing index that can be used to identify all voices related to this note. +*/ +TSFDEF int tsf_note_on_fast(tsf* f, int preset_index, int key, float vel) { + if (preset_index < 0 || preset_index >= f->presetNum) { + return -1; + } + if (!vel) { + tsf_note_off(f, preset_index, key); + return -1; + } + if (f->presets[preset_index].regions == NULL) { + tsf_load_preset(f, f->hydra, preset_index); + } + + short midiVelocity = (short)(vel * 127); + struct tsf_region *region, *regionEnd; + + // Play all matching regions. + int voicePlayIndex = f->voicePlayIndex++; + for (region = f->presets[preset_index].regions, regionEnd = region + f->presets[preset_index].regionNum; region != regionEnd; region++) { + if (key < region->lokey || key > region->hikey || midiVelocity < region->lovel || midiVelocity > region->hivel) { + continue; + } + + struct tsf_voice *voice, *v, *vEnd; TSF_BOOL doLoop; + voice = TSF_NULL, v = f->voices, vEnd = v + f->voiceNum; + if (region->group) { + for (; v != vEnd; v++) + if (v->playingPreset == preset_index && v->region->group == region->group) { + tsf_voice_endquick(v, f->outSampleRate); + } else if (v->playingPreset == -1 && !voice) { + voice = v; + } + } else for (; v != vEnd; v++) if (v->playingPreset == -1) { + voice = v; + break; + } + + if (!voice) { + f->voiceNum += 4; + struct tsf_voice *saveVoice = f->voices; + f->voices = (struct tsf_voice*)TSF_REALLOC(f->voices, f->voiceNum * sizeof(struct tsf_voice)); + if (!f->voices) { + f->voices = saveVoice; + printf("OOM, no room for new voice. Ignoring note_on\n"); + return -1; + } + voice = &f->voices[f->voiceNum - 4]; + voice[1].playingPreset = voice[2].playingPreset = voice[3].playingPreset = -1; + voice[1].playIndex = voice[2].playIndex = voice[3].playIndex = -1; + } + + voice->region = region; + voice->playingPreset = preset_index; + voice->playingKey = key; + voice->playIndex = voicePlayIndex; + voice->noteGain = vel * tsf_decibelsToGain(f->globalGainDB - region->attenuation); + + if (f->channels) { + f->channels->setupVoice(f, voice); + } else { + tsf_voice_calcpitchratio(voice, 0, f->outSampleRate); + voice->pitchRatioF32P32 = voice->pitchRatio * (1LL << 32); + } + + // Offset/end. + voice->sourceSamplePositionF32P32 = ((int64_t)region->offset) << 32; + + // Loop. + doLoop = (region->loop_mode != TSF_LOOPMODE_NONE && region->loop_start < region->loop_end); + voice->loopStartF32P32 = doLoop ? ((int64_t)region->loop_start + 1) << 32 : 0; + voice->loopEndF32P32 = doLoop ? ((int64_t)region->loop_end + 1) << 32 : 0; + voice->loopSizeF32P32 = doLoop ? voice->loopEndF32P32 - voice->loopStartF32P32 + (1LL << 32) : 0; + + // Setup envelopes. + tsf_voice_envelope_setup(&voice->ampenv, ®ion->ampenv, key, midiVelocity, TSF_TRUE, f->outSampleRate); + tsf_voice_envelope_setup(&voice->modenv, ®ion->modenv, key, midiVelocity, TSF_FALSE, f->outSampleRate); + + // Setup LFO filters. + tsf_voice_lfo_setup(&voice->modlfo, region->delayModLFO, region->freqModLFO, f->outSampleRate); + tsf_voice_lfo_setup(&voice->viblfo, region->delayVibLFO, region->freqVibLFO, f->outSampleRate); + } + + return voicePlayIndex; +} + +TSFDEF int tsf_bank_note_on(tsf* f, int bank, int preset_number, int key, float vel) { + int preset_index = tsf_get_presetindex(f, bank, preset_number); + if (preset_index == -1) { + return 0; + } + tsf_note_on(f, preset_index, key, vel); + return 1; +} + +TSFDEF void tsf_note_off(tsf* f, int preset_index, int key) { + struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum, *vMatchFirst = TSF_NULL, *vMatchLast = TSF_NULL; + for (; v != vEnd; v++) { + //Find the first and last entry in the voices list with matching preset, key and look up the smallest play index + if (v->playingPreset != preset_index || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_RELEASE) { + continue; + } else if (!vMatchFirst || v->playIndex < vMatchFirst->playIndex) { + vMatchFirst = vMatchLast = v; + } else if (v->playIndex == vMatchFirst->playIndex) { + vMatchLast = v; + } + } + if (!vMatchFirst) { + return; + } + for (v = vMatchFirst; v <= vMatchLast; v++) { + //Stop all voices with matching preset, key and the smallest play index which was enumerated above + if (v != vMatchFirst && v != vMatchLast && + (v->playIndex != vMatchFirst->playIndex || v->playingPreset != preset_index || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_RELEASE)) { + continue; + } + tsf_voice_end(v, f->outSampleRate); + } +} + +/** + Stops all voices with the given playing index. If no key provided or if -1, fallbacks to tsf_note_off +*/ +TSFDEF void tsf_note_off_fast(tsf* f, int preset_index, int key, int playIndex = -1) { + if (playIndex < 0) { + tsf_note_off(f, preset_index, key); + } else + for (struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; v != vEnd; v++) + if (v->playIndex == playIndex && v->playingPreset == preset_index && v->playingKey == key && v->ampenv.segment < TSF_SEGMENT_RELEASE) { + tsf_voice_end(v, f->outSampleRate); + } +} + +TSFDEF int tsf_bank_note_off(tsf* f, int bank, int preset_number, int key) { + int preset_index = tsf_get_presetindex(f, bank, preset_number); + if (preset_index == -1) { + return 0; + } + tsf_note_off(f, preset_index, key); + return 1; +} + +TSFDEF void tsf_note_off_all(tsf* f) { + struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; + for (; v != vEnd; v++) if (v->playingPreset != -1 && v->ampenv.segment < TSF_SEGMENT_RELEASE) { + tsf_voice_end(v, f->outSampleRate); + } +} + +TSFDEF int tsf_active_voice_count(tsf* f) { + int count = 0; + struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; + for (; v != vEnd; v++) if (v->playingPreset != -1) { + count++; + } + return count; +} + +TSFDEF void tsf_render_short(tsf* f, short* buffer, int samples, int flag_mixing) { + float *floatSamples; + int channelSamples = (f->outputmode == TSF_MONO ? 1 : 2) * samples, floatBufferSize = channelSamples * sizeof(float); + short* bufferEnd = buffer + channelSamples; + if (floatBufferSize > f->outputSampleSize) { + TSF_FREE(f->outputSamples); + f->outputSamples = (float*)TSF_MALLOC(floatBufferSize); + f->outputSampleSize = floatBufferSize; + } + + tsf_render_float(f, f->outputSamples, samples, TSF_FALSE); + + floatSamples = f->outputSamples; + if (flag_mixing) + while (buffer != bufferEnd) { + float v = *floatSamples++; + int vi = *buffer + (v < -1.00004566f ? (int) -32768 : (v > 1.00001514f ? (int)32767 : (int)(v * 32767.5f))); + *buffer++ = (vi < -32768 ? (short) -32768 : (vi > 32767 ? (short)32767 : (short)vi)); + } else + while (buffer != bufferEnd) { + float v = *floatSamples++; + *buffer++ = (v < -1.00004566f ? (short) -32768 : (v > 1.00001514f ? (short)32767 : (short)(v * 32767.5f))); + } +} + +TSFDEF void tsf_render_float(tsf* f, float* buffer, int samples, int flag_mixing) { + struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; + if (!flag_mixing) { + TSF_MEMSET(buffer, 0, (f->outputmode == TSF_MONO ? 1 : 2) * sizeof(float) * samples); + } + for (; v != vEnd; v++) + if (v->playingPreset != -1) { + tsf_voice_render(f, v, buffer, samples); + } +} + +TSFDEF void tsf_render_short_fast(tsf* f, short* buffer, int samples, int flag_mixing) { + struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; + if (!flag_mixing) { + TSF_MEMSET(buffer, 0, (f->outputmode == TSF_MONO ? 1 : 2) * sizeof(short) * samples); + } + for (; v != vEnd; v++) { + if (v->playingPreset != -1) { + tsf_voice_render_fast(f, v, buffer, samples); + } + yield(); + } +} + + +static void tsf_channel_setup_voice(tsf* f, struct tsf_voice* v) { + struct tsf_channel* c = &f->channels->channels[f->channels->activeChannel]; + float newpan = v->region->pan + c->panOffset; + v->playingChannel = f->channels->activeChannel; + v->noteGain *= tsf_decibelsToGain(c->gainDB); + tsf_voice_calcpitchratio(v, (c->pitchWheel == 8192 ? c->tuning : ((c->pitchWheel / 16383.0f * c->pitchRange * 2.0f) - c->pitchRange + c->tuning)), f->outSampleRate); + if (newpan <= -0.5f) { + v->panFactorLeft = 1.0f; + v->panFactorRight = 0.0f; + } else if (newpan >= 0.5f) { + v->panFactorLeft = 0.0f; + v->panFactorRight = 1.0f; + } else { + v->panFactorLeft = TSF_SQRTF(0.5f - newpan); + v->panFactorRight = TSF_SQRTF(0.5f + newpan); + } +} + +static struct tsf_channel* tsf_channel_init(tsf* f, int channel) { + int i; + if (f->channels && channel < f->channels->channelNum) { + return &f->channels->channels[channel]; + } + if (!f->channels) { + f->channels = (struct tsf_channels*)TSF_MALLOC(sizeof(struct tsf_channels)); + f->channels->setupVoice = &tsf_channel_setup_voice; + f->channels->channels = NULL; + f->channels->channelNum = 0; + f->channels->activeChannel = 0; + } + i = f->channels->channelNum; + f->channels->channelNum = channel + 1; + f->channels->channels = (struct tsf_channel*)TSF_REALLOC(f->channels->channels, f->channels->channelNum * sizeof(struct tsf_channel)); + for (; i <= channel; i++) { + struct tsf_channel* c = &f->channels->channels[i]; + c->presetIndex = c->bank = 0; + c->pitchWheel = c->midiPan = 8192; + c->midiVolume = c->midiExpression = 16383; + c->midiRPN = 0xFFFF; + c->midiData = 0; + c->panOffset = 0.0f; + c->gainDB = 0.0f; + c->pitchRange = 2.0f; + c->tuning = 0.0f; + } + return &f->channels->channels[channel]; +} + +static void tsf_channel_applypitch(tsf* f, int channel, struct tsf_channel* c) { + struct tsf_voice *v, *vEnd; + float pitchShift = (c->pitchWheel == 8192 ? c->tuning : ((c->pitchWheel / 16383.0f * c->pitchRange * 2.0f) - c->pitchRange + c->tuning)); + for (v = f->voices, vEnd = v + f->voiceNum; v != vEnd; v++) + if (v->playingChannel == channel && v->playingPreset != -1) { + tsf_voice_calcpitchratio(v, pitchShift, f->outSampleRate); + } +} + +TSFDEF void tsf_channel_set_presetindex(tsf* f, int channel, int preset_index) { + tsf_channel_init(f, channel)->presetIndex = (unsigned short)preset_index; +} + +TSFDEF int tsf_channel_set_presetnumber(tsf* f, int channel, int preset_number, int flag_mididrums) { + struct tsf_channel *c = tsf_channel_init(f, channel); + int preset_index; + if (flag_mididrums) { + preset_index = tsf_get_presetindex(f, 128 | (c->bank & 0x7FFF), preset_number); + if (preset_index == -1) { + preset_index = tsf_get_presetindex(f, 128, preset_number); + } + if (preset_index == -1) { + preset_index = tsf_get_presetindex(f, 128, 0); + } + if (preset_index == -1) { + preset_index = tsf_get_presetindex(f, (c->bank & 0x7FFF), preset_number); + } + } else { + preset_index = tsf_get_presetindex(f, (c->bank & 0x7FFF), preset_number); + } + if (preset_index == -1) { + preset_index = tsf_get_presetindex(f, 0, preset_number); + } + if (preset_index != -1) { + c->presetIndex = (unsigned short)preset_index; + return 1; + } + return 0; +} + +TSFDEF void tsf_channel_set_bank(tsf* f, int channel, int bank) { + tsf_channel_init(f, channel)->bank = (unsigned short)bank; +} + +TSFDEF int tsf_channel_set_bank_preset(tsf* f, int channel, int bank, int preset_number) { + struct tsf_channel *c = tsf_channel_init(f, channel); + int preset_index = tsf_get_presetindex(f, bank, preset_number); + if (preset_index == -1) { + return 0; + } + c->presetIndex = (unsigned short)preset_index; + c->bank = (unsigned short)bank; + return 1; +} + +TSFDEF void tsf_channel_set_pan(tsf* f, int channel, float pan) { + struct tsf_voice *v, *vEnd; + for (v = f->voices, vEnd = v + f->voiceNum; v != vEnd; v++) + if (v->playingChannel == channel && v->playingPreset != -1) { + float newpan = v->region->pan + pan - 0.5f; + if (newpan <= -0.5f) { + v->panFactorLeft = 1.0f; + v->panFactorRight = 0.0f; + } else if (newpan >= 0.5f) { + v->panFactorLeft = 0.0f; + v->panFactorRight = 1.0f; + } else { + v->panFactorLeft = TSF_SQRTF(0.5f - newpan); + v->panFactorRight = TSF_SQRTF(0.5f + newpan); + } + } + tsf_channel_init(f, channel)->panOffset = pan - 0.5f; +} + +TSFDEF void tsf_channel_set_volume(tsf* f, int channel, float volume) { + struct tsf_channel *c = tsf_channel_init(f, channel); + float gainDB = tsf_gainToDecibels(volume), gainDBChange = gainDB - c->gainDB; + struct tsf_voice *v, *vEnd; + if (gainDBChange == 0) { + return; + } + for (v = f->voices, vEnd = v + f->voiceNum; v != vEnd; v++) + if (v->playingChannel == channel && v->playingPreset != -1) { + v->noteGain *= tsf_decibelsToGain(gainDBChange); + } + c->gainDB = gainDB; +} + +TSFDEF void tsf_channel_set_pitchwheel(tsf* f, int channel, int pitch_wheel) { + struct tsf_channel *c = tsf_channel_init(f, channel); + if (c->pitchWheel == pitch_wheel) { + return; + } + c->pitchWheel = (unsigned short)pitch_wheel; + tsf_channel_applypitch(f, channel, c); +} + +TSFDEF void tsf_channel_set_pitchrange(tsf* f, int channel, float pitch_range) { + struct tsf_channel *c = tsf_channel_init(f, channel); + if (c->pitchRange == pitch_range) { + return; + } + c->pitchRange = pitch_range; + if (c->pitchWheel != 8192) { + tsf_channel_applypitch(f, channel, c); + } +} + +TSFDEF void tsf_channel_set_tuning(tsf* f, int channel, float tuning) { + struct tsf_channel *c = tsf_channel_init(f, channel); + if (c->tuning == tuning) { + return; + } + c->tuning = tuning; + tsf_channel_applypitch(f, channel, c); +} + +TSFDEF void tsf_channel_note_on(tsf* f, int channel, int key, float vel) { + if (!f->channels || channel >= f->channels->channelNum) { + return; + } + f->channels->activeChannel = channel; + tsf_note_on(f, f->channels->channels[channel].presetIndex, key, vel); +} + +TSFDEF void tsf_channel_note_off(tsf* f, int channel, int key) { + struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum, *vMatchFirst = TSF_NULL, *vMatchLast = TSF_NULL; + for (; v != vEnd; v++) { + //Find the first and last entry in the voices list with matching channel, key and look up the smallest play index + if (v->playingPreset == -1 || v->playingChannel != channel || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_RELEASE) { + continue; + } else if (!vMatchFirst || v->playIndex < vMatchFirst->playIndex) { + vMatchFirst = vMatchLast = v; + } else if (v->playIndex == vMatchFirst->playIndex) { + vMatchLast = v; + } + } + if (!vMatchFirst) { + return; + } + for (v = vMatchFirst; v <= vMatchLast; v++) { + //Stop all voices with matching channel, key and the smallest play index which was enumerated above + if (v != vMatchFirst && v != vMatchLast && + (v->playIndex != vMatchFirst->playIndex || v->playingPreset == -1 || v->playingChannel != channel || v->playingKey != key || v->ampenv.segment >= TSF_SEGMENT_RELEASE)) { + continue; + } + tsf_voice_end(v, f->outSampleRate); + } +} + +TSFDEF void tsf_channel_note_off_all(tsf* f, int channel) { + struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; + for (; v != vEnd; v++) + if (v->playingPreset != -1 && v->playingChannel == channel && v->ampenv.segment < TSF_SEGMENT_RELEASE) { + tsf_voice_end(v, f->outSampleRate); + } +} + +TSFDEF void tsf_channel_sounds_off_all(tsf* f, int channel) { + struct tsf_voice *v = f->voices, *vEnd = v + f->voiceNum; + for (; v != vEnd; v++) + if (v->playingPreset != -1 && v->playingChannel == channel && (v->ampenv.segment < TSF_SEGMENT_RELEASE || v->ampenv.parameters.release)) { + tsf_voice_endquick(v, f->outSampleRate); + } +} + +TSFDEF void tsf_channel_midi_control(tsf* f, int channel, int controller, int control_value) { + struct tsf_channel* c = tsf_channel_init(f, channel); + switch (controller) { + case 7 /*VOLUME_MSB*/ : c->midiVolume = (unsigned short)((c->midiVolume & 0x7F) | (control_value << 7)); goto TCMC_SET_VOLUME; + case 39 /*VOLUME_LSB*/ : c->midiVolume = (unsigned short)((c->midiVolume & 0x3F80) | control_value); goto TCMC_SET_VOLUME; + case 11 /*EXPRESSION_MSB*/ : c->midiExpression = (unsigned short)((c->midiExpression & 0x7F) | (control_value << 7)); goto TCMC_SET_VOLUME; + case 43 /*EXPRESSION_LSB*/ : c->midiExpression = (unsigned short)((c->midiExpression & 0x3F80) | control_value); goto TCMC_SET_VOLUME; + case 10 /*PAN_MSB*/ : c->midiPan = (unsigned short)((c->midiPan & 0x7F) | (control_value << 7)); goto TCMC_SET_PAN; + case 42 /*PAN_LSB*/ : c->midiPan = (unsigned short)((c->midiPan & 0x3F80) | control_value); goto TCMC_SET_PAN; + case 6 /*DATA_ENTRY_MSB*/ : c->midiData = (unsigned short)((c->midiData & 0x7F) | (control_value << 7)); goto TCMC_SET_DATA; + case 38 /*DATA_ENTRY_LSB*/ : c->midiData = (unsigned short)((c->midiData & 0x3F80) | control_value); goto TCMC_SET_DATA; + case 0 /*BANK_SELECT_MSB*/ : c->bank = (unsigned short)(0x8000 | control_value); return; //bank select MSB alone acts like LSB + case 32 /*BANK_SELECT_LSB*/ : c->bank = (unsigned short)((c->bank & 0x8000 ? ((c->bank & 0x7F) << 7) : 0) | control_value); return; + case 101 /*RPN_MSB*/ : c->midiRPN = (unsigned short)(((c->midiRPN == 0xFFFF ? 0 : c->midiRPN) & 0x7F) | (control_value << 7)); return; + case 100 /*RPN_LSB*/ : c->midiRPN = (unsigned short)(((c->midiRPN == 0xFFFF ? 0 : c->midiRPN) & 0x3F80) | control_value); return; + case 98 /*NRPN_LSB*/ : c->midiRPN = 0xFFFF; return; + case 99 /*NRPN_MSB*/ : c->midiRPN = 0xFFFF; return; + case 120 /*ALL_SOUND_OFF*/ : tsf_channel_sounds_off_all(f, channel); return; + case 123 /*ALL_NOTES_OFF*/ : tsf_channel_note_off_all(f, channel); return; + case 121 /*ALL_CTRL_OFF*/ : + c->midiVolume = c->midiExpression = 16383; + c->midiPan = 8192; + c->bank = 0; + tsf_channel_set_volume(f, channel, 1.0f); + tsf_channel_set_pan(f, channel, 0.5f); + tsf_channel_set_pitchrange(f, channel, 2.0f); + return; + } + return; TCMC_SET_VOLUME: - //Raising to the power of 3 seems to result in a decent sounding volume curve for MIDI - tsf_channel_set_volume(f, channel, TSF_POWF((c->midiVolume / 16383.0f) * (c->midiExpression / 16383.0f), 3.0f)); - return; + //Raising to the power of 3 seems to result in a decent sounding volume curve for MIDI + tsf_channel_set_volume(f, channel, TSF_POWF((c->midiVolume / 16383.0f) * (c->midiExpression / 16383.0f), 3.0f)); + return; TCMC_SET_PAN: - tsf_channel_set_pan(f, channel, c->midiPan / 16383.0f); - return; + tsf_channel_set_pan(f, channel, c->midiPan / 16383.0f); + return; TCMC_SET_DATA: - if (c->midiRPN == 0) tsf_channel_set_pitchrange(f, channel, (c->midiData >> 7) + 0.01f * (c->midiData & 0x7F)); - else if (c->midiRPN == 1) tsf_channel_set_tuning(f, channel, (int)c->tuning + ((float)c->midiData - 8192.0f) / 8192.0f); //fine tune - else if (c->midiRPN == 2 && controller == 6) tsf_channel_set_tuning(f, channel, ((float)control_value - 64.0f) + (c->tuning - (int)c->tuning)); //coarse tune - return; + if (c->midiRPN == 0) { + tsf_channel_set_pitchrange(f, channel, (c->midiData >> 7) + 0.01f * (c->midiData & 0x7F)); + } else if (c->midiRPN == 1) { + tsf_channel_set_tuning(f, channel, (int)c->tuning + ((float)c->midiData - 8192.0f) / 8192.0f); //fine tune + } else if (c->midiRPN == 2 && controller == 6) { + tsf_channel_set_tuning(f, channel, ((float)control_value - 64.0f) + (c->tuning - (int)c->tuning)); //coarse tune + } + return; } -TSFDEF int tsf_channel_get_preset_index(tsf* f, int channel) -{ - return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].presetIndex : 0); +TSFDEF int tsf_channel_get_preset_index(tsf* f, int channel) { + return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].presetIndex : 0); } -TSFDEF int tsf_channel_get_preset_bank(tsf* f, int channel) -{ - return (f->channels && channel < f->channels->channelNum ? (f->channels->channels[channel].bank & 0x7FFF) : 0); +TSFDEF int tsf_channel_get_preset_bank(tsf* f, int channel) { + return (f->channels && channel < f->channels->channelNum ? (f->channels->channels[channel].bank & 0x7FFF) : 0); } -TSFDEF int tsf_channel_get_preset_number(tsf* f, int channel) -{ - return (f->channels && channel < f->channels->channelNum ? f->presets[f->channels->channels[channel].presetIndex].preset : 0); +TSFDEF int tsf_channel_get_preset_number(tsf* f, int channel) { + return (f->channels && channel < f->channels->channelNum ? f->presets[f->channels->channels[channel].presetIndex].preset : 0); } -TSFDEF float tsf_channel_get_pan(tsf* f, int channel) -{ - return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].panOffset - 0.5f : 0.5f); +TSFDEF float tsf_channel_get_pan(tsf* f, int channel) { + return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].panOffset - 0.5f : 0.5f); } -TSFDEF float tsf_channel_get_volume(tsf* f, int channel) -{ - return (f->channels && channel < f->channels->channelNum ? tsf_decibelsToGain(f->channels->channels[channel].gainDB) : 1.0f); +TSFDEF float tsf_channel_get_volume(tsf* f, int channel) { + return (f->channels && channel < f->channels->channelNum ? tsf_decibelsToGain(f->channels->channels[channel].gainDB) : 1.0f); } -TSFDEF int tsf_channel_get_pitchwheel(tsf* f, int channel) -{ - return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].pitchWheel : 8192); +TSFDEF int tsf_channel_get_pitchwheel(tsf* f, int channel) { + return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].pitchWheel : 8192); } -TSFDEF float tsf_channel_get_pitchrange(tsf* f, int channel) -{ - return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].pitchRange : 2.0f); +TSFDEF float tsf_channel_get_pitchrange(tsf* f, int channel) { + return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].pitchRange : 2.0f); } -TSFDEF float tsf_channel_get_tuning(tsf* f, int channel) -{ - return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].tuning : 0.0f); +TSFDEF float tsf_channel_get_tuning(tsf* f, int channel) { + return (f->channels && channel < f->channels->channelNum ? f->channels->channels[channel].tuning : 0.0f); } #ifdef __cplusplus @@ -2143,3 +2488,5 @@ TSFDEF float tsf_channel_get_tuning(tsf* f, int channel) #endif #endif //TSF_IMPLEMENTATION + +#endif // ! ESP32 diff --git a/src/opusfile/AUTHORS b/src/opusfile/AUTHORS deleted file mode 100644 index d0ac09d6..00000000 --- a/src/opusfile/AUTHORS +++ /dev/null @@ -1,5 +0,0 @@ -Timothy B. Terriberry -Ralph Giles -Christopher "Monty" Montgomery (original libvorbisfile) -Gregory Maxwell (noise shaping dithering) -nu774 (original winsock support) diff --git a/src/opusfile/COPYING b/src/opusfile/COPYING deleted file mode 100644 index 7b53d665..00000000 --- a/src/opusfile/COPYING +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 1994-2013 Xiph.Org Foundation and contributors - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -- Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -- Neither the name of the Xiph.Org Foundation nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/opusfile/README.esp8266.md b/src/opusfile/README.esp8266.md deleted file mode 100644 index 267aa28a..00000000 --- a/src/opusfile/README.esp8266.md +++ /dev/null @@ -1,3 +0,0 @@ -This is opusfile from Xiph, modified to build under Arduino by and adjusted to work with AudioFileSources, - -Original license/etc. unchanged. diff --git a/src/opusfile/README.md b/src/opusfile/README.md deleted file mode 100644 index 609cc6b9..00000000 --- a/src/opusfile/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# Opusfile - -[![GitLab Pipeline Status](https://gitlab.xiph.org/xiph/opusfile/badges/master/pipeline.svg)](https://gitlab.xiph.org/xiph/opusfile/commits/master) -[![Travis Build Status](https://travis-ci.org/xiph/opusfile.svg?branch=master)](https://travis-ci.org/xiph/opusfile) -[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/xiph/opusfile?branch=master&svg=true)](https://ci.appveyor.com/project/rillian/opusfile) - -The opusfile and opusurl libraries provide a high-level API for -decoding and seeking within .opus files on disk or over http(s). - -opusfile depends on libopus and libogg. -opusurl depends on opusfile and openssl. - -The library is functional, but there are likely issues -we didn't find in our own testing. Please give feedback -in #opus on irc.freenode.net or at opus@xiph.org. - -Programming documentation is available in tree and online at -https://opus-codec.org/docs/ diff --git a/src/opusfile/config.h b/src/opusfile/config.h deleted file mode 100644 index 47d57494..00000000 --- a/src/opusfile/config.h +++ /dev/null @@ -1,128 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H 0 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 0 - -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -#define LT_OBJDIR ".libs/" - -/* Disable floating-point API */ -#define OP_DISABLE_FLOAT_API 1 - -/* Enable assertions in code */ -/* #undef OP_ENABLE_ASSERTIONS */ - -/* Enable HTTP support */ -/* #undef OP_ENABLE_HTTP */ - -/* Enable fixed-point calculation */ -#define OP_FIXED_POINT 1 - -/* Enable use of clock_gettime function */ -/* #undef OP_HAVE_CLOCK_GETTIME */ - -/* Enable use of lrintf function */ -/* #undef OP_HAVE_LRINTF */ - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "opus@xiph.org" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "opusfile" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "opusfile 0.12" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "opusfile" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "0.12" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define this if the compiler supports __attribute__(( - ifelse([visibility("default")], , [visibility_default], - [visibility("default")]) )) */ -#define SUPPORT_ATTRIBUTE_VISIBILITY_DEFAULT 1 - -/* Define this if the compiler supports the -fvisibility flag */ -#define SUPPORT_FLAG_VISIBILITY 1 - -/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# define _ALL_SOURCE 1 -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif -/* Enable threading extensions on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# define _POSIX_PTHREAD_SEMANTICS 1 -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# define _TANDEM_SOURCE 1 -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# define __EXTENSIONS__ 1 -#endif - - -/* Enable large inode numbers on Mac OS X 10.5. */ -#ifndef _DARWIN_USE_64_BIT_INODE -# define _DARWIN_USE_64_BIT_INODE 1 -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -/* #undef _FILE_OFFSET_BITS */ - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define to 1 if on MINIX. */ -/* #undef _MINIX */ - -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define to 1 if you need to in order for `stat' and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* We need at least WindowsXP for getaddrinfo/freeaddrinfo */ -/* #undef _WIN32_WINNT */ diff --git a/src/opusfile/info.c b/src/opusfile/info.c deleted file mode 100644 index 106e6047..00000000 --- a/src/opusfile/info.c +++ /dev/null @@ -1,775 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE libopusfile SOURCE CODE IS (C) COPYRIGHT 2012-2020 * - * by the Xiph.Org Foundation and contributors https://xiph.org/ * - * * - ********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "config.h" -//#endif - -#include "internal.h" -#include -#include - -static unsigned op_parse_uint16le(const unsigned char *_data){ - return _data[0]|_data[1]<<8; -} - -static int op_parse_int16le(const unsigned char *_data){ - int ret; - ret=_data[0]|_data[1]<<8; - return (ret^0x8000)-0x8000; -} - -static opus_uint32 op_parse_uint32le(const unsigned char *_data){ - return _data[0]|(opus_uint32)_data[1]<<8| - (opus_uint32)_data[2]<<16|(opus_uint32)_data[3]<<24; -} - -static opus_uint32 op_parse_uint32be(const unsigned char *_data){ - return _data[3]|(opus_uint32)_data[2]<<8| - (opus_uint32)_data[1]<<16|(opus_uint32)_data[0]<<24; -} - -int opus_head_parse(OpusHead *_head,const unsigned char *_data,size_t _len){ - OpusHead head; - if(_len<8)return OP_ENOTFORMAT; - if(memcmp(_data,"OpusHead",8)!=0)return OP_ENOTFORMAT; - if(_len<9)return OP_EBADHEADER; - head.version=_data[8]; - if(head.version>15)return OP_EVERSION; - if(_len<19)return OP_EBADHEADER; - head.channel_count=_data[9]; - head.pre_skip=op_parse_uint16le(_data+10); - head.input_sample_rate=op_parse_uint32le(_data+12); - head.output_gain=op_parse_int16le(_data+16); - head.mapping_family=_data[18]; - if(head.mapping_family==0){ - if(head.channel_count<1||head.channel_count>2)return OP_EBADHEADER; - if(head.version<=1&&_len>19)return OP_EBADHEADER; - head.stream_count=1; - head.coupled_count=head.channel_count-1; - if(_head!=NULL){ - _head->mapping[0]=0; - _head->mapping[1]=1; - } - } - else if(head.mapping_family==1){ - size_t size; - int ci; - if(head.channel_count<1||head.channel_count>8)return OP_EBADHEADER; - size=21+head.channel_count; - if(_lensize)return OP_EBADHEADER; - head.stream_count=_data[19]; - if(head.stream_count<1)return OP_EBADHEADER; - head.coupled_count=_data[20]; - if(head.coupled_count>head.stream_count)return OP_EBADHEADER; - for(ci=0;ci=head.stream_count+head.coupled_count - &&_data[21+ci]!=255){ - return OP_EBADHEADER; - } - } - if(_head!=NULL)memcpy(_head->mapping,_data+21,head.channel_count); - } - /*General purpose players should not attempt to play back content with - channel mapping family 255.*/ - else if(head.mapping_family==255)return OP_EIMPL; - /*No other channel mapping families are currently defined.*/ - else return OP_EBADHEADER; - if(_head!=NULL)memcpy(_head,&head,head.mapping-(unsigned char *)&head); - return 0; -} - -void opus_tags_init(OpusTags *_tags){ - memset(_tags,0,sizeof(*_tags)); -} - -void opus_tags_clear(OpusTags *_tags){ - int ncomments; - int ci; - ncomments=_tags->comments; - if(_tags->user_comments!=NULL)ncomments++; - else{ - OP_ASSERT(ncomments==0); - } - for(ci=ncomments;ci-->0;)_ogg_free(_tags->user_comments[ci]); - _ogg_free(_tags->user_comments); - _ogg_free(_tags->comment_lengths); - _ogg_free(_tags->vendor); -} - -/*Ensure there's room for up to _ncomments comments.*/ -static int op_tags_ensure_capacity(OpusTags *_tags,size_t _ncomments){ - char **user_comments; - int *comment_lengths; - int cur_ncomments; - size_t size; - if(OP_UNLIKELY(_ncomments>=(size_t)INT_MAX))return OP_EFAULT; - size=sizeof(*_tags->comment_lengths)*(_ncomments+1); - if(size/sizeof(*_tags->comment_lengths)!=_ncomments+1)return OP_EFAULT; - cur_ncomments=_tags->comments; - /*We only support growing. - Trimming requires cleaning up the allocated strings in the old space, and - is best handled separately if it's ever needed.*/ - OP_ASSERT(_ncomments>=(size_t)cur_ncomments); - comment_lengths=(int *)_ogg_realloc(_tags->comment_lengths,size); - if(OP_UNLIKELY(comment_lengths==NULL))return OP_EFAULT; - if(_tags->comment_lengths==NULL){ - OP_ASSERT(cur_ncomments==0); - comment_lengths[cur_ncomments]=0; - } - comment_lengths[_ncomments]=comment_lengths[cur_ncomments]; - _tags->comment_lengths=comment_lengths; - size=sizeof(*_tags->user_comments)*(_ncomments+1); - if(size/sizeof(*_tags->user_comments)!=_ncomments+1)return OP_EFAULT; - user_comments=(char **)_ogg_realloc(_tags->user_comments,size); - if(OP_UNLIKELY(user_comments==NULL))return OP_EFAULT; - if(_tags->user_comments==NULL){ - OP_ASSERT(cur_ncomments==0); - user_comments[cur_ncomments]=NULL; - } - user_comments[_ncomments]=user_comments[cur_ncomments]; - _tags->user_comments=user_comments; - return 0; -} - -/*Duplicate a (possibly non-NUL terminated) string with a known length.*/ -static char *op_strdup_with_len(const char *_s,size_t _len){ - size_t size; - char *ret; - size=sizeof(*ret)*(_len+1); - if(OP_UNLIKELY(size<_len))return NULL; - ret=(char *)_ogg_malloc(size); - if(OP_LIKELY(ret!=NULL)){ - ret=(char *)memcpy(ret,_s,sizeof(*ret)*_len); - ret[_len]='\0'; - } - return ret; -} - -/*The actual implementation of opus_tags_parse(). - Unlike the public API, this function requires _tags to already be - initialized, modifies its contents before success is guaranteed, and assumes - the caller will clear it on error.*/ -static int opus_tags_parse_impl(OpusTags *_tags, - const unsigned char *_data,size_t _len){ - opus_uint32 count; - size_t len; - int ncomments; - int ci; - len=_len; - if(len<8)return OP_ENOTFORMAT; - if(memcmp(_data,"OpusTags",8)!=0)return OP_ENOTFORMAT; - if(len<16)return OP_EBADHEADER; - _data+=8; - len-=8; - count=op_parse_uint32le(_data); - _data+=4; - len-=4; - if(count>len)return OP_EBADHEADER; - if(_tags!=NULL){ - _tags->vendor=op_strdup_with_len((char *)_data,count); - if(_tags->vendor==NULL)return OP_EFAULT; - } - _data+=count; - len-=count; - if(len<4)return OP_EBADHEADER; - count=op_parse_uint32le(_data); - _data+=4; - len-=4; - /*Check to make sure there's minimally sufficient data left in the packet.*/ - if(count>len>>2)return OP_EBADHEADER; - /*Check for overflow (the API limits this to an int).*/ - if(count>(opus_uint32)INT_MAX-1)return OP_EFAULT; - if(_tags!=NULL){ - int ret; - ret=op_tags_ensure_capacity(_tags,count); - if(ret<0)return ret; - } - ncomments=(int)count; - for(ci=0;cilen>>2)return OP_EBADHEADER; - count=op_parse_uint32le(_data); - _data+=4; - len-=4; - if(count>len)return OP_EBADHEADER; - /*Check for overflow (the API limits this to an int).*/ - if(count>(opus_uint32)INT_MAX)return OP_EFAULT; - if(_tags!=NULL){ - _tags->user_comments[ci]=op_strdup_with_len((char *)_data,count); - if(_tags->user_comments[ci]==NULL)return OP_EFAULT; - _tags->comment_lengths[ci]=(int)count; - _tags->comments=ci+1; - /*Needed by opus_tags_clear() if we fail before parsing the (optional) - binary metadata.*/ - _tags->user_comments[ci+1]=NULL; - } - _data+=count; - len-=count; - } - if(len>0&&(_data[0]&1)){ - if(len>(opus_uint32)INT_MAX)return OP_EFAULT; - if(_tags!=NULL){ - _tags->user_comments[ncomments]=(char *)_ogg_malloc(len); - if(OP_UNLIKELY(_tags->user_comments[ncomments]==NULL))return OP_EFAULT; - memcpy(_tags->user_comments[ncomments],_data,len); - _tags->comment_lengths[ncomments]=(int)len; - } - } - return 0; -} - -int opus_tags_parse(OpusTags *_tags,const unsigned char *_data,size_t _len){ - if(_tags!=NULL){ - OpusTags tags; - int ret; - opus_tags_init(&tags); - ret=opus_tags_parse_impl(&tags,_data,_len); - if(ret<0)opus_tags_clear(&tags); - else *_tags=*&tags; - return ret; - } - else return opus_tags_parse_impl(NULL,_data,_len); -} - -/*The actual implementation of opus_tags_copy(). - Unlike the public API, this function requires _dst to already be - initialized, modifies its contents before success is guaranteed, and assumes - the caller will clear it on error.*/ -static int opus_tags_copy_impl(OpusTags *_dst,const OpusTags *_src){ - char *vendor; - int ncomments; - int ret; - int ci; - vendor=_src->vendor; - _dst->vendor=op_strdup_with_len(vendor,strlen(vendor)); - if(OP_UNLIKELY(_dst->vendor==NULL))return OP_EFAULT; - ncomments=_src->comments; - ret=op_tags_ensure_capacity(_dst,ncomments); - if(OP_UNLIKELY(ret<0))return ret; - for(ci=0;cicomment_lengths[ci]; - OP_ASSERT(len>=0); - _dst->user_comments[ci]=op_strdup_with_len(_src->user_comments[ci],len); - if(OP_UNLIKELY(_dst->user_comments[ci]==NULL))return OP_EFAULT; - _dst->comment_lengths[ci]=len; - _dst->comments=ci+1; - } - if(_src->comment_lengths!=NULL){ - int len; - len=_src->comment_lengths[ncomments]; - if(len>0){ - _dst->user_comments[ncomments]=(char *)_ogg_malloc(len); - if(OP_UNLIKELY(_dst->user_comments[ncomments]==NULL))return OP_EFAULT; - memcpy(_dst->user_comments[ncomments],_src->user_comments[ncomments],len); - _dst->comment_lengths[ncomments]=len; - } - } - return 0; -} - -int opus_tags_copy(OpusTags *_dst,const OpusTags *_src){ - OpusTags dst; - int ret; - opus_tags_init(&dst); - ret=opus_tags_copy_impl(&dst,_src); - if(OP_UNLIKELY(ret<0))opus_tags_clear(&dst); - else *_dst=*&dst; - return ret; -} - -int opus_tags_add(OpusTags *_tags,const char *_tag,const char *_value){ - char *comment; - size_t tag_len; - size_t value_len; - int ncomments; - int ret; - ncomments=_tags->comments; - ret=op_tags_ensure_capacity(_tags,ncomments+1); - if(OP_UNLIKELY(ret<0))return ret; - tag_len=strlen(_tag); - value_len=strlen(_value); - /*+2 for '=' and '\0'.*/ - if(tag_len+value_len(size_t)INT_MAX-2)return OP_EFAULT; - comment=(char *)_ogg_malloc(sizeof(*comment)*(tag_len+value_len+2)); - if(OP_UNLIKELY(comment==NULL))return OP_EFAULT; - memcpy(comment,_tag,sizeof(*comment)*tag_len); - comment[tag_len]='='; - memcpy(comment+tag_len+1,_value,sizeof(*comment)*(value_len+1)); - _tags->user_comments[ncomments]=comment; - _tags->comment_lengths[ncomments]=(int)(tag_len+value_len+1); - _tags->comments=ncomments+1; - return 0; -} - -int opus_tags_add_comment(OpusTags *_tags,const char *_comment){ - char *comment; - int comment_len; - int ncomments; - int ret; - ncomments=_tags->comments; - ret=op_tags_ensure_capacity(_tags,ncomments+1); - if(OP_UNLIKELY(ret<0))return ret; - comment_len=(int)strlen(_comment); - comment=op_strdup_with_len(_comment,comment_len); - if(OP_UNLIKELY(comment==NULL))return OP_EFAULT; - _tags->user_comments[ncomments]=comment; - _tags->comment_lengths[ncomments]=comment_len; - _tags->comments=ncomments+1; - return 0; -} - -int opus_tags_set_binary_suffix(OpusTags *_tags, - const unsigned char *_data,int _len){ - unsigned char *binary_suffix_data; - int ncomments; - int ret; - if(_len<0||_len>0&&(_data==NULL||!(_data[0]&1)))return OP_EINVAL; - ncomments=_tags->comments; - ret=op_tags_ensure_capacity(_tags,ncomments); - if(OP_UNLIKELY(ret<0))return ret; - binary_suffix_data= - (unsigned char *)_ogg_realloc(_tags->user_comments[ncomments],_len); - if(OP_UNLIKELY(binary_suffix_data==NULL))return OP_EFAULT; - memcpy(binary_suffix_data,_data,_len); - _tags->user_comments[ncomments]=(char *)binary_suffix_data; - _tags->comment_lengths[ncomments]=_len; - return 0; -} - -int opus_tagcompare(const char *_tag_name,const char *_comment){ - size_t tag_len; - tag_len=strlen(_tag_name); - if(OP_UNLIKELY(tag_len>(size_t)INT_MAX))return -1; - return opus_tagncompare(_tag_name,(int)tag_len,_comment); -} - -int opus_tagncompare(const char *_tag_name,int _tag_len,const char *_comment){ - int ret; - OP_ASSERT(_tag_len>=0); - ret=op_strncasecmp(_tag_name,_comment,_tag_len); - return ret?ret:'='-_comment[_tag_len]; -} - -const char *opus_tags_query(const OpusTags *_tags,const char *_tag,int _count){ - char **user_comments; - size_t tag_len; - int found; - int ncomments; - int ci; - tag_len=strlen(_tag); - if(OP_UNLIKELY(tag_len>(size_t)INT_MAX))return NULL; - ncomments=_tags->comments; - user_comments=_tags->user_comments; - found=0; - for(ci=0;ci(size_t)INT_MAX))return 0; - ncomments=_tags->comments; - user_comments=_tags->user_comments; - found=0; - for(ci=0;cicomments; - len=_tags->comment_lengths==NULL?0:_tags->comment_lengths[ncomments]; - *_len=len; - OP_ASSERT(len==0||_tags->user_comments!=NULL); - return len>0?(const unsigned char *)_tags->user_comments[ncomments]:NULL; -} - -static int opus_tags_get_gain(const OpusTags *_tags,int *_gain_q8, - const char *_tag_name,size_t _tag_len){ - char **comments; - int ncomments; - int ci; - comments=_tags->user_comments; - ncomments=_tags->comments; - /*Look for the first valid tag with the name _tag_name and use that.*/ - for(ci=0;ci='0'&&*p<='9'){ - gain_q8=10*gain_q8+*p-'0'; - if(gain_q8>32767-negative)break; - p++; - } - /*This didn't look like a signed 16-bit decimal integer. - Not a valid gain tag.*/ - if(*p!='\0')continue; - *_gain_q8=(int)(gain_q8+negative^negative); - return 0; - } - } - return OP_FALSE; -} - -int opus_tags_get_album_gain(const OpusTags *_tags,int *_gain_q8){ - return opus_tags_get_gain(_tags,_gain_q8,"R128_ALBUM_GAIN",15); -} - -int opus_tags_get_track_gain(const OpusTags *_tags,int *_gain_q8){ - return opus_tags_get_gain(_tags,_gain_q8,"R128_TRACK_GAIN",15); -} - -static int op_is_jpeg(const unsigned char *_buf,size_t _buf_sz){ - return _buf_sz>=3&&memcmp(_buf,"\xFF\xD8\xFF",3)==0; -} - -/*Tries to extract the width, height, bits per pixel, and palette size of a - JPEG. - On failure, simply leaves its outputs unmodified.*/ -static void op_extract_jpeg_params(const unsigned char *_buf,size_t _buf_sz, - opus_uint32 *_width,opus_uint32 *_height, - opus_uint32 *_depth,opus_uint32 *_colors,int *_has_palette){ - if(op_is_jpeg(_buf,_buf_sz)){ - size_t offs; - offs=2; - for(;;){ - size_t segment_len; - int marker; - while(offs<_buf_sz&&_buf[offs]!=0xFF)offs++; - while(offs<_buf_sz&&_buf[offs]==0xFF)offs++; - marker=_buf[offs]; - offs++; - /*If we hit EOI* (end of image), or another SOI* (start of image), - or SOS (start of scan), then stop now.*/ - if(offs>=_buf_sz||(marker>=0xD8&&marker<=0xDA))break; - /*RST* (restart markers): skip (no segment length).*/ - else if(marker>=0xD0&&marker<=0xD7)continue; - /*Read the length of the marker segment.*/ - if(_buf_sz-offs<2)break; - segment_len=_buf[offs]<<8|_buf[offs+1]; - if(segment_len<2||_buf_sz-offs0xC0&&marker<0xD0&&(marker&3)!=0)){ - /*Found a SOFn (start of frame) marker segment:*/ - if(segment_len>=8){ - *_height=_buf[offs+3]<<8|_buf[offs+4]; - *_width=_buf[offs+5]<<8|_buf[offs+6]; - *_depth=_buf[offs+2]*_buf[offs+7]; - *_colors=0; - *_has_palette=0; - } - break; - } - /*Other markers: skip the whole marker segment.*/ - offs+=segment_len; - } - } -} - -static int op_is_png(const unsigned char *_buf,size_t _buf_sz){ - return _buf_sz>=8&&memcmp(_buf,"\x89PNG\x0D\x0A\x1A\x0A",8)==0; -} - -/*Tries to extract the width, height, bits per pixel, and palette size of a - PNG. - On failure, simply leaves its outputs unmodified.*/ -static void op_extract_png_params(const unsigned char *_buf,size_t _buf_sz, - opus_uint32 *_width,opus_uint32 *_height, - opus_uint32 *_depth,opus_uint32 *_colors,int *_has_palette){ - if(op_is_png(_buf,_buf_sz)){ - size_t offs; - offs=8; - while(_buf_sz-offs>=12){ - ogg_uint32_t chunk_len; - chunk_len=op_parse_uint32be(_buf+offs); - if(chunk_len>_buf_sz-(offs+12))break; - else if(chunk_len==13&&memcmp(_buf+offs+4,"IHDR",4)==0){ - int color_type; - *_width=op_parse_uint32be(_buf+offs+8); - *_height=op_parse_uint32be(_buf+offs+12); - color_type=_buf[offs+17]; - if(color_type==3){ - *_depth=24; - *_has_palette=1; - } - else{ - int sample_depth; - sample_depth=_buf[offs+16]; - if(color_type==0)*_depth=sample_depth; - else if(color_type==2)*_depth=sample_depth*3; - else if(color_type==4)*_depth=sample_depth*2; - else if(color_type==6)*_depth=sample_depth*4; - *_colors=0; - *_has_palette=0; - break; - } - } - else if(*_has_palette>0&&memcmp(_buf+offs+4,"PLTE",4)==0){ - *_colors=chunk_len/3; - break; - } - offs+=12+chunk_len; - } - } -} - -static int op_is_gif(const unsigned char *_buf,size_t _buf_sz){ - return _buf_sz>=6&&(memcmp(_buf,"GIF87a",6)==0||memcmp(_buf,"GIF89a",6)==0); -} - -/*Tries to extract the width, height, bits per pixel, and palette size of a - GIF. - On failure, simply leaves its outputs unmodified.*/ -static void op_extract_gif_params(const unsigned char *_buf,size_t _buf_sz, - opus_uint32 *_width,opus_uint32 *_height, - opus_uint32 *_depth,opus_uint32 *_colors,int *_has_palette){ - if(op_is_gif(_buf,_buf_sz)&&_buf_sz>=14){ - *_width=_buf[6]|_buf[7]<<8; - *_height=_buf[8]|_buf[9]<<8; - /*libFLAC hard-codes the depth to 24.*/ - *_depth=24; - *_colors=1<<((_buf[10]&7)+1); - *_has_palette=1; - } -} - -/*The actual implementation of opus_picture_tag_parse(). - Unlike the public API, this function requires _pic to already be - initialized, modifies its contents before success is guaranteed, and assumes - the caller will clear it on error.*/ -static int opus_picture_tag_parse_impl(OpusPictureTag *_pic,const char *_tag, - unsigned char *_buf,size_t _buf_sz,size_t _base64_sz){ - opus_int32 picture_type; - opus_uint32 mime_type_length; - char *mime_type; - opus_uint32 description_length; - char *description; - opus_uint32 width; - opus_uint32 height; - opus_uint32 depth; - opus_uint32 colors; - opus_uint32 data_length; - opus_uint32 file_width; - opus_uint32 file_height; - opus_uint32 file_depth; - opus_uint32 file_colors; - int format; - int has_palette; - int colors_set; - size_t i; - /*Decode the BASE64 data.*/ - OP_ASSERT(_base64_sz>=11); - for(i=0;i<_base64_sz;i++){ - opus_uint32 value; - int j; - value=0; - for(j=0;j<4;j++){ - unsigned c; - unsigned d; - c=(unsigned char)_tag[4*i+j]; - if(c=='+')d=62; - else if(c=='/')d=63; - else if(c>='0'&&c<='9')d=52+c-'0'; - else if(c>='a'&&c<='z')d=26+c-'a'; - else if(c>='A'&&c<='Z')d=c-'A'; - else if(c=='='&&3*i+j>_buf_sz)d=0; - else return OP_ENOTFORMAT; - value=value<<6|d; - } - _buf[3*i]=(unsigned char)(value>>16); - if(3*i+1<_buf_sz){ - _buf[3*i+1]=(unsigned char)(value>>8); - if(3*i+2<_buf_sz)_buf[3*i+2]=(unsigned char)value; - } - } - i=0; - picture_type=op_parse_uint32be(_buf+i); - i+=4; - /*Extract the MIME type.*/ - mime_type_length=op_parse_uint32be(_buf+i); - i+=4; - if(mime_type_length>_buf_sz-32)return OP_ENOTFORMAT; - mime_type=(char *)_ogg_malloc(sizeof(*_pic->mime_type)*(mime_type_length+1)); - if(mime_type==NULL)return OP_EFAULT; - memcpy(mime_type,_buf+i,sizeof(*mime_type)*mime_type_length); - mime_type[mime_type_length]='\0'; - _pic->mime_type=mime_type; - i+=mime_type_length; - /*Extract the description string.*/ - description_length=op_parse_uint32be(_buf+i); - i+=4; - if(description_length>_buf_sz-mime_type_length-32)return OP_ENOTFORMAT; - description= - (char *)_ogg_malloc(sizeof(*_pic->mime_type)*(description_length+1)); - if(description==NULL)return OP_EFAULT; - memcpy(description,_buf+i,sizeof(*description)*description_length); - description[description_length]='\0'; - _pic->description=description; - i+=description_length; - /*Extract the remaining fields.*/ - width=op_parse_uint32be(_buf+i); - i+=4; - height=op_parse_uint32be(_buf+i); - i+=4; - depth=op_parse_uint32be(_buf+i); - i+=4; - colors=op_parse_uint32be(_buf+i); - i+=4; - /*If one of these is set, they all must be, but colors==0 is a valid value.*/ - colors_set=width!=0||height!=0||depth!=0||colors!=0; - if((width==0||height==0||depth==0)&&colors_set)return OP_ENOTFORMAT; - data_length=op_parse_uint32be(_buf+i); - i+=4; - if(data_length>_buf_sz-i)return OP_ENOTFORMAT; - /*Trim extraneous data so we don't copy it below.*/ - _buf_sz=i+data_length; - /*Attempt to determine the image format.*/ - format=OP_PIC_FORMAT_UNKNOWN; - if(mime_type_length==3&&strcmp(mime_type,"-->")==0){ - format=OP_PIC_FORMAT_URL; - /*Picture type 1 must be a 32x32 PNG.*/ - if(picture_type==1&&(width!=0||height!=0)&&(width!=32||height!=32)){ - return OP_ENOTFORMAT; - } - /*Append a terminating NUL for the convenience of our callers.*/ - _buf[_buf_sz++]='\0'; - } - else{ - if(mime_type_length==10 - &&op_strncasecmp(mime_type,"image/jpeg",mime_type_length)==0){ - if(op_is_jpeg(_buf+i,data_length))format=OP_PIC_FORMAT_JPEG; - } - else if(mime_type_length==9 - &&op_strncasecmp(mime_type,"image/png",mime_type_length)==0){ - if(op_is_png(_buf+i,data_length))format=OP_PIC_FORMAT_PNG; - } - else if(mime_type_length==9 - &&op_strncasecmp(mime_type,"image/gif",mime_type_length)==0){ - if(op_is_gif(_buf+i,data_length))format=OP_PIC_FORMAT_GIF; - } - else if(mime_type_length==0||(mime_type_length==6 - &&op_strncasecmp(mime_type,"image/",mime_type_length)==0)){ - if(op_is_jpeg(_buf+i,data_length))format=OP_PIC_FORMAT_JPEG; - else if(op_is_png(_buf+i,data_length))format=OP_PIC_FORMAT_PNG; - else if(op_is_gif(_buf+i,data_length))format=OP_PIC_FORMAT_GIF; - } - file_width=file_height=file_depth=file_colors=0; - has_palette=-1; - switch(format){ - case OP_PIC_FORMAT_JPEG:{ - op_extract_jpeg_params(_buf+i,data_length, - &file_width,&file_height,&file_depth,&file_colors,&has_palette); - }break; - case OP_PIC_FORMAT_PNG:{ - op_extract_png_params(_buf+i,data_length, - &file_width,&file_height,&file_depth,&file_colors,&has_palette); - }break; - case OP_PIC_FORMAT_GIF:{ - op_extract_gif_params(_buf+i,data_length, - &file_width,&file_height,&file_depth,&file_colors,&has_palette); - }break; - } - if(has_palette>=0){ - /*If we successfully extracted these parameters from the image, override - any declared values.*/ - width=file_width; - height=file_height; - depth=file_depth; - colors=file_colors; - } - /*Picture type 1 must be a 32x32 PNG.*/ - if(picture_type==1&&(format!=OP_PIC_FORMAT_PNG||width!=32||height!=32)){ - return OP_ENOTFORMAT; - } - } - /*Adjust _buf_sz instead of using data_length to capture the terminating NUL - for URLs.*/ - _buf_sz-=i; - memmove(_buf,_buf+i,sizeof(*_buf)*_buf_sz); - _buf=(unsigned char *)_ogg_realloc(_buf,_buf_sz); - if(_buf_sz>0&&_buf==NULL)return OP_EFAULT; - _pic->type=picture_type; - _pic->width=width; - _pic->height=height; - _pic->depth=depth; - _pic->colors=colors; - _pic->data_length=data_length; - _pic->data=_buf; - _pic->format=format; - return 0; -} - -int opus_picture_tag_parse(OpusPictureTag *_pic,const char *_tag){ - OpusPictureTag pic; - unsigned char *buf; - size_t base64_sz; - size_t buf_sz; - size_t tag_length; - int ret; - if(opus_tagncompare("METADATA_BLOCK_PICTURE",22,_tag)==0)_tag+=23; - /*Figure out how much BASE64-encoded data we have.*/ - tag_length=strlen(_tag); - if(tag_length&3)return OP_ENOTFORMAT; - base64_sz=tag_length>>2; - buf_sz=3*base64_sz; - if(buf_sz<32)return OP_ENOTFORMAT; - if(_tag[tag_length-1]=='=')buf_sz--; - if(_tag[tag_length-2]=='=')buf_sz--; - if(buf_sz<32)return OP_ENOTFORMAT; - /*Allocate an extra byte to allow appending a terminating NUL to URL data.*/ - buf=(unsigned char *)_ogg_malloc(sizeof(*buf)*(buf_sz+1)); - if(buf==NULL)return OP_EFAULT; - opus_picture_tag_init(&pic); - ret=opus_picture_tag_parse_impl(&pic,_tag,buf,buf_sz,base64_sz); - if(ret<0){ - opus_picture_tag_clear(&pic); - _ogg_free(buf); - } - else *_pic=*&pic; - return ret; -} - -void opus_picture_tag_init(OpusPictureTag *_pic){ - memset(_pic,0,sizeof(*_pic)); -} - -void opus_picture_tag_clear(OpusPictureTag *_pic){ - _ogg_free(_pic->description); - _ogg_free(_pic->mime_type); - _ogg_free(_pic->data); -} diff --git a/src/opusfile/internal.c b/src/opusfile/internal.c deleted file mode 100644 index 8df4f158..00000000 --- a/src/opusfile/internal.c +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE libopusfile SOURCE CODE IS (C) COPYRIGHT 2012-2020 * - * by the Xiph.Org Foundation and contributors https://xiph.org/ * - * * - ********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "config.h" -//#endif - -#include "internal.h" - -#if defined(OP_ENABLE_ASSERTIONS) -void op_fatal_impl(const char *_str,const char *_file,int _line){ - fprintf(stderr,"Fatal (internal) error in %s, line %i: %s\n", - _file,_line,_str); - abort(); -} -#endif - -/*A version of strncasecmp() that is guaranteed to only ignore the case of - ASCII characters.*/ -int op_strncasecmp(const char *_a,const char *_b,int _n){ - int i; - for(i=0;i<_n;i++){ - int a; - int b; - int d; - a=_a[i]; - b=_b[i]; - if(a>='a'&&a<='z')a-='a'-'A'; - if(b>='a'&&b<='z')b-='a'-'A'; - d=a-b; - if(d)return d; - } - return 0; -} diff --git a/src/opusfile/internal.h b/src/opusfile/internal.h deleted file mode 100644 index 1c47eecb..00000000 --- a/src/opusfile/internal.h +++ /dev/null @@ -1,259 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE libopusfile SOURCE CODE IS (C) COPYRIGHT 2012-2020 * - * by the Xiph.Org Foundation and contributors https://xiph.org/ * - * * - ********************************************************************/ -#if !defined(_opusfile_internal_h) -# define _opusfile_internal_h (1) - -# if !defined(_REENTRANT) -# define _REENTRANT -# endif -# if !defined(_GNU_SOURCE) -# define _GNU_SOURCE -# endif -# if !defined(_LARGEFILE_SOURCE) -# define _LARGEFILE_SOURCE -# endif -# if !defined(_LARGEFILE64_SOURCE) -# define _LARGEFILE64_SOURCE -# endif -# if !defined(_FILE_OFFSET_BITS) -# define _FILE_OFFSET_BITS 64 -# endif - -# include -# include "opusfile.h" - -typedef struct OggOpusLink OggOpusLink; - -# if defined(OP_FIXED_POINT) - -typedef opus_int16 op_sample; - -# else - -typedef float op_sample; - -/*We're using this define to test for libopus 1.1 or later until libopus - provides a better mechanism.*/ -# if defined(OPUS_GET_EXPERT_FRAME_DURATION_REQUEST) -/*Enable soft clipping prevention in 16-bit decodes.*/ -# define OP_SOFT_CLIP (1) -# endif - -# endif - -# if OP_GNUC_PREREQ(4,2) -/*Disable excessive warnings about the order of operations.*/ -# pragma GCC diagnostic ignored "-Wparentheses" -# elif defined(_MSC_VER) -/*Disable excessive warnings about the order of operations.*/ -# pragma warning(disable:4554) -/*Disable warnings about "deprecated" POSIX functions.*/ -# pragma warning(disable:4996) -# endif - -# if OP_GNUC_PREREQ(3,0) -/*Another alternative is - (__builtin_constant_p(_x)?!!(_x):__builtin_expect(!!(_x),1)) - but that evaluates _x multiple times, which may be bad.*/ -# define OP_LIKELY(_x) (__builtin_expect(!!(_x),1)) -# define OP_UNLIKELY(_x) (__builtin_expect(!!(_x),0)) -# else -# define OP_LIKELY(_x) (!!(_x)) -# define OP_UNLIKELY(_x) (!!(_x)) -# endif - -# if defined(OP_ENABLE_ASSERTIONS) -# if OP_GNUC_PREREQ(2,5)||__SUNPRO_C>=0x590 -__attribute__((noreturn)) -# endif -void op_fatal_impl(const char *_str,const char *_file,int _line); - -# define OP_FATAL(_str) (op_fatal_impl(_str,__FILE__,__LINE__)) - -# define OP_ASSERT(_cond) \ - do{ \ - if(OP_UNLIKELY(!(_cond)))OP_FATAL("assertion failed: " #_cond); \ - } \ - while(0) -# define OP_ALWAYS_TRUE(_cond) OP_ASSERT(_cond) - -# else -# define OP_FATAL(_str) abort() -# define OP_ASSERT(_cond) -# define OP_ALWAYS_TRUE(_cond) ((void)(_cond)) -# endif - -# define OP_INT64_MAX (2*(((ogg_int64_t)1<<62)-1)|1) -# define OP_INT64_MIN (-OP_INT64_MAX-1) -# define OP_INT32_MAX (2*(((ogg_int32_t)1<<30)-1)|1) -# define OP_INT32_MIN (-OP_INT32_MAX-1) - -# define OP_MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) -# define OP_MAX(_a,_b) ((_a)>(_b)?(_a):(_b)) -# define OP_CLAMP(_lo,_x,_hi) (OP_MAX(_lo,OP_MIN(_x,_hi))) - -/*Advance a file offset by the given amount, clamping against OP_INT64_MAX. - This is used to advance a known offset by things like OP_CHUNK_SIZE or - OP_PAGE_SIZE_MAX, while making sure to avoid signed overflow. - It assumes that both _offset and _amount are non-negative.*/ -#define OP_ADV_OFFSET(_offset,_amount) \ - (OP_MIN(_offset,OP_INT64_MAX-(_amount))+(_amount)) - -/*The maximum channel count for any mapping we'll actually decode.*/ -# define OP_NCHANNELS_MAX (2) - -/*Initial state.*/ -# define OP_NOTOPEN (0) -/*We've found the first Opus stream in the first link.*/ -# define OP_PARTOPEN (1) -# define OP_OPENED (2) -/*We've found the first Opus stream in the current link.*/ -# define OP_STREAMSET (3) -/*We've initialized the decoder for the chosen Opus stream in the current - link.*/ -# define OP_INITSET (4) - -/*Information cached for a single link in a chained Ogg Opus file. - We choose the first Opus stream encountered in each link to play back (and - require at least one).*/ -struct OggOpusLink{ - /*The byte offset of the first header page in this link.*/ - opus_int64 offset; - /*The byte offset of the first data page from the chosen Opus stream in this - link (after the headers).*/ - opus_int64 data_offset; - /*The byte offset of the last page from the chosen Opus stream in this link. - This is used when seeking to ensure we find a page before the last one, so - that end-trimming calculations work properly. - This is only valid for seekable sources.*/ - opus_int64 end_offset; - /*The total duration of all prior links. - This is always zero for non-seekable sources.*/ - ogg_int64_t pcm_file_offset; - /*The granule position of the last sample. - This is only valid for seekable sources.*/ - ogg_int64_t pcm_end; - /*The granule position before the first sample.*/ - ogg_int64_t pcm_start; - /*The serial number.*/ - ogg_uint32_t serialno; - /*The contents of the info header.*/ - OpusHead head; - /*The contents of the comment header.*/ - OpusTags tags; -}; - -struct OggOpusFile{ - /*The callbacks used to access the stream.*/ - OpusFileCallbacks callbacks; - /*A FILE *, memory buffer, etc.*/ - void *stream; - /*Whether or not we can seek with this stream.*/ - int seekable; - /*The number of links in this chained Ogg Opus file.*/ - int nlinks; - /*The cached information from each link in a chained Ogg Opus file. - If stream isn't seekable (e.g., it's a pipe), only the current link - appears.*/ - OggOpusLink *links; - /*The number of serial numbers from a single link.*/ - int nserialnos; - /*The capacity of the list of serial numbers from a single link.*/ - int cserialnos; - /*Storage for the list of serial numbers from a single link. - This is a scratch buffer used when scanning the BOS pages at the start of - each link.*/ - ogg_uint32_t *serialnos; - /*This is the current offset of the data processed by the ogg_sync_state. - After a seek, this should be set to the target offset so that we can track - the byte offsets of subsequent pages. - After a call to op_get_next_page(), this will point to the first byte after - that page.*/ - opus_int64 offset; - /*The total size of this stream, or -1 if it's unseekable.*/ - opus_int64 end; - /*Used to locate pages in the stream.*/ - ogg_sync_state oy; - /*One of OP_NOTOPEN, OP_PARTOPEN, OP_OPENED, OP_STREAMSET, OP_INITSET.*/ - int ready_state; - /*The current link being played back.*/ - int cur_link; - /*The number of decoded samples to discard from the start of decoding.*/ - opus_int32 cur_discard_count; - /*The granule position of the previous packet (current packet start time).*/ - ogg_int64_t prev_packet_gp; - /*The stream offset of the most recent page with completed packets, or -1. - This is only needed to recover continued packet data in the seeking logic, - when we use the current position as one of our bounds, only to later - discover it was the correct starting point.*/ - opus_int64 prev_page_offset; - /*The number of bytes read since the last bitrate query, including framing.*/ - opus_int64 bytes_tracked; - /*The number of samples decoded since the last bitrate query.*/ - ogg_int64_t samples_tracked; - /*Takes physical pages and welds them into a logical stream of packets.*/ - ogg_stream_state os; - /*Re-timestamped packets from a single page. - Buffering these relies on the undocumented libogg behavior that ogg_packet - pointers remain valid until the next page is submitted to the - ogg_stream_state they came from.*/ - ogg_packet op[255]; - /*The index of the next packet to return.*/ - int op_pos; - /*The total number of packets available.*/ - int op_count; - /*Central working state for the packet-to-PCM decoder.*/ - OpusMSDecoder *od; - /*The application-provided packet decode callback.*/ - op_decode_cb_func decode_cb; - /*The application-provided packet decode callback context.*/ - void *decode_cb_ctx; - /*The stream count used to initialize the decoder.*/ - int od_stream_count; - /*The coupled stream count used to initialize the decoder.*/ - int od_coupled_count; - /*The channel count used to initialize the decoder.*/ - int od_channel_count; - /*The channel mapping used to initialize the decoder.*/ - unsigned char od_mapping[OP_NCHANNELS_MAX]; - /*The buffered data for one decoded packet.*/ - op_sample *od_buffer; - /*The current position in the decoded buffer.*/ - int od_buffer_pos; - /*The number of valid samples in the decoded buffer.*/ - int od_buffer_size; - /*The type of gain offset to apply. - One of OP_HEADER_GAIN, OP_ALBUM_GAIN, OP_TRACK_GAIN, or OP_ABSOLUTE_GAIN.*/ - int gain_type; - /*The offset to apply to the gain.*/ - opus_int32 gain_offset_q8; - /*Internal state for soft clipping and dithering float->short output.*/ -#if !defined(OP_FIXED_POINT) -# if defined(OP_SOFT_CLIP) - float clip_state[OP_NCHANNELS_MAX]; -# endif - float dither_a[OP_NCHANNELS_MAX*4]; - float dither_b[OP_NCHANNELS_MAX*4]; - opus_uint32 dither_seed; - int dither_mute; - int dither_disabled; - /*The number of channels represented by the internal state. - This gets set to 0 whenever anything that would prevent state propagation - occurs (switching between the float/short APIs, or between the - stereo/multistream APIs).*/ - int state_channel_count; -#endif -}; - -int op_strncasecmp(const char *_a,const char *_b,int _n); - -#endif diff --git a/src/opusfile/opusfile.c b/src/opusfile/opusfile.c deleted file mode 100644 index bfd3c9e5..00000000 --- a/src/opusfile/opusfile.c +++ /dev/null @@ -1,3346 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE libopusfile SOURCE CODE IS (C) COPYRIGHT 1994-2020 * - * by the Xiph.Org Foundation and contributors https://xiph.org/ * - * * - ******************************************************************** - - function: stdio-based convenience library for opening/seeking/decoding - last mod: $Id: vorbisfile.c 17573 2010-10-27 14:53:59Z xiphmont $ - - ********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "config.h" -//#endif - -#include "internal.h" -#include -#include -#include -#include -#include -#include - -#include "opusfile.h" - -/*This implementation is largely based off of libvorbisfile. - All of the Ogg bits work roughly the same, though I have made some - "improvements" that have not been folded back there, yet.*/ - -/*A 'chained bitstream' is an Ogg Opus bitstream that contains more than one - logical bitstream arranged end to end (the only form of Ogg multiplexing - supported by this library. - Grouping (parallel multiplexing) is not supported, except to the extent that - if there are multiple logical Ogg streams in a single link of the chain, we - will ignore all but the first Opus stream we find.*/ - -/*An Ogg Opus file can be played beginning to end (streamed) without worrying - ahead of time about chaining (see opusdec from the opus-tools package). - If we have the whole file, however, and want random access - (seeking/scrubbing) or desire to know the total length/time of a file, we - need to account for the possibility of chaining.*/ - -/*We can handle things a number of ways. - We can determine the entire bitstream structure right off the bat, or find - pieces on demand. - This library determines and caches structure for the entire bitstream, but - builds a virtual decoder on the fly when moving between links in the chain.*/ - -/*There are also different ways to implement seeking. - Enough information exists in an Ogg bitstream to seek to sample-granularity - positions in the output. - Or, one can seek by picking some portion of the stream roughly in the desired - area if we only want coarse navigation through the stream. - We implement and expose both strategies.*/ - -/*The maximum number of bytes in a page (including the page headers).*/ -#define OP_PAGE_SIZE_MAX (65307) -/*The default amount to seek backwards per step when trying to find the - previous page. - This must be at least as large as the maximum size of a page.*/ -#define OP_CHUNK_SIZE (65536) -/*The maximum amount to seek backwards per step when trying to find the - previous page.*/ -#define OP_CHUNK_SIZE_MAX (1024*(opus_int32)1024) -/*A smaller read size is needed for low-rate streaming.*/ -#define OP_READ_SIZE (2048) - -int op_test(OpusHead *_head, - const unsigned char *_initial_data,size_t _initial_bytes){ - ogg_sync_state oy; - char *data; - int err; - /*The first page of a normal Opus file will be at most 57 bytes (27 Ogg - page header bytes + 1 lacing value + 21 Opus header bytes + 8 channel - mapping bytes). - It will be at least 47 bytes (27 Ogg page header bytes + 1 lacing value + - 19 Opus header bytes using channel mapping family 0). - If we don't have at least that much data, give up now.*/ - if(_initial_bytes<47)return OP_FALSE; - /*Only proceed if we start with the magic OggS string. - This is to prevent us spending a lot of time allocating memory and looking - for Ogg pages in non-Ogg files.*/ - if(memcmp(_initial_data,"OggS",4)!=0)return OP_ENOTFORMAT; - if(OP_UNLIKELY(_initial_bytes>(size_t)LONG_MAX))return OP_EFAULT; - ogg_sync_init(&oy); - data=ogg_sync_buffer(&oy,(long)_initial_bytes); - if(data!=NULL){ - ogg_stream_state os; - ogg_page og; - int ret; - memcpy(data,_initial_data,_initial_bytes); - ogg_sync_wrote(&oy,(long)_initial_bytes); - ogg_stream_init(&os,-1); - err=OP_FALSE; - do{ - ogg_packet op; - ret=ogg_sync_pageout(&oy,&og); - /*Ignore holes.*/ - if(ret<0)continue; - /*Stop if we run out of data.*/ - if(!ret)break; - ogg_stream_reset_serialno(&os,ogg_page_serialno(&og)); - ogg_stream_pagein(&os,&og); - /*Only process the first packet on this page (if it's a BOS packet, - it's required to be the only one).*/ - if(ogg_stream_packetout(&os,&op)==1){ - if(op.b_o_s){ - ret=opus_head_parse(_head,op.packet,op.bytes); - /*If this didn't look like Opus, keep going.*/ - if(ret==OP_ENOTFORMAT)continue; - /*Otherwise we're done, one way or another.*/ - err=ret; - } - /*We finished parsing the headers. - There is no Opus to be found.*/ - else err=OP_ENOTFORMAT; - } - } - while(err==OP_FALSE); - ogg_stream_clear(&os); - } - else err=OP_EFAULT; - ogg_sync_clear(&oy); - return err; -} - -/*Many, many internal helpers. - The intention is not to be confusing. - Rampant duplication and monolithic function implementation (though we do have - some large, omnibus functions still) would be harder to understand anyway. - The high level functions are last. - Begin grokking near the end of the file if you prefer to read things - top-down.*/ - -/*The read/seek functions track absolute position within the stream.*/ - -/*Read a little more data from the file/pipe into the ogg_sync framer. - _nbytes: The maximum number of bytes to read. - Return: A positive number of bytes read on success, 0 on end-of-file, or a - negative value on failure.*/ -static int op_get_data(OggOpusFile *_of,int _nbytes){ - unsigned char *buffer; - int nbytes; - OP_ASSERT(_nbytes>0); - buffer=(unsigned char *)ogg_sync_buffer(&_of->oy,_nbytes); - nbytes=(int)(*_of->callbacks.read)(_of->stream,buffer,_nbytes); - OP_ASSERT(nbytes<=_nbytes); - if(OP_LIKELY(nbytes>0))ogg_sync_wrote(&_of->oy,nbytes); - return nbytes; -} - -/*Save a tiny smidge of verbosity to make the code more readable.*/ -static int op_seek_helper(OggOpusFile *_of,opus_int64 _offset){ - if(_offset==_of->offset)return 0; - if(_of->callbacks.seek==NULL - ||(*_of->callbacks.seek)(_of->stream,_offset,SEEK_SET)){ - return OP_EREAD; - } - _of->offset=_offset; - ogg_sync_reset(&_of->oy); - return 0; -} - -/*Get the current position indicator of the underlying stream. - This should be the same as the value reported by tell().*/ -static opus_int64 op_position(const OggOpusFile *_of){ - /*The current position indicator is _not_ simply offset. - We may also have unprocessed, buffered data in the sync state.*/ - return _of->offset+_of->oy.fill-_of->oy.returned; -} - -/*From the head of the stream, get the next page. - _boundary specifies if the function is allowed to fetch more data from the - stream (and how much) or only use internally buffered data. - _boundary: -1: Unbounded search. - 0: Read no additional data. - Use only cached data. - n: Search for the start of a new page up to file position n. - Return: n>=0: Found a page at absolute offset n. - OP_FALSE: Hit the _boundary limit. - OP_EREAD: An underlying read operation failed. - OP_BADLINK: We hit end-of-file before reaching _boundary.*/ -static opus_int64 op_get_next_page(OggOpusFile *_of,ogg_page *_og, - opus_int64 _boundary){ - while(_boundary<=0||_of->offset<_boundary){ - int more; - more=ogg_sync_pageseek(&_of->oy,_og); - /*Skipped (-more) bytes.*/ - if(OP_UNLIKELY(more<0))_of->offset-=more; - else if(more==0){ - int read_nbytes; - int ret; - /*Send more paramedics.*/ - if(!_boundary)return OP_FALSE; - if(_boundary<0)read_nbytes=OP_READ_SIZE; - else{ - opus_int64 position; - position=op_position(_of); - if(position>=_boundary)return OP_FALSE; - read_nbytes=(int)OP_MIN(_boundary-position,OP_READ_SIZE); - } - ret=op_get_data(_of,read_nbytes); - if(OP_UNLIKELY(ret<0))return OP_EREAD; - if(OP_UNLIKELY(ret==0)){ - /*Only fail cleanly on EOF if we didn't have a known boundary. - Otherwise, we should have been able to reach that boundary, and this - is a fatal error.*/ - return OP_UNLIKELY(_boundary<0)?OP_FALSE:OP_EBADLINK; - } - } - else{ - /*Got a page. - Return the page start offset and advance the internal offset past the - page end.*/ - opus_int64 page_offset; - page_offset=_of->offset; - _of->offset+=more; - OP_ASSERT(page_offset>=0); - return page_offset; - } - } - return OP_FALSE; -} - -static int op_add_serialno(const ogg_page *_og, - ogg_uint32_t **_serialnos,int *_nserialnos,int *_cserialnos){ - ogg_uint32_t *serialnos; - int nserialnos; - int cserialnos; - ogg_uint32_t s; - s=ogg_page_serialno(_og); - serialnos=*_serialnos; - nserialnos=*_nserialnos; - cserialnos=*_cserialnos; - if(OP_UNLIKELY(nserialnos>=cserialnos)){ - if(OP_UNLIKELY(cserialnos>INT_MAX/(int)sizeof(*serialnos)-1>>1)){ - return OP_EFAULT; - } - cserialnos=2*cserialnos+1; - OP_ASSERT(nserialnos=OP_PAGE_SIZE_MAX); - begin=OP_MAX(begin-chunk_size,0); - ret=op_seek_helper(_of,begin); - if(OP_UNLIKELY(ret<0))return ret; - search_start=begin; - while(_of->offsetsearch_start=search_start; - _sr->offset=_offset=llret; - _sr->serialno=serialno; - OP_ASSERT(_of->offset-_offset>=0); - OP_ASSERT(_of->offset-_offset<=OP_PAGE_SIZE_MAX); - _sr->size=(opus_int32)(_of->offset-_offset); - _sr->gp=ogg_page_granulepos(&og); - /*If this page is from the stream we're looking for, remember it.*/ - if(serialno==_serialno){ - preferred_found=1; - *&preferred_sr=*_sr; - } - if(!op_lookup_serialno(serialno,_serialnos,_nserialnos)){ - /*We fell off the end of the link, which means we seeked back too far - and shouldn't have been looking in that link to begin with. - If we found the preferred serial number, forget that we saw it.*/ - preferred_found=0; - } - search_start=llret+1; - } - /*We started from the beginning of the stream and found nothing. - This should be impossible unless the contents of the stream changed out - from under us after we read from it.*/ - if(OP_UNLIKELY(!begin)&&OP_UNLIKELY(_offset<0))return OP_EBADLINK; - /*Bump up the chunk size. - This is mildly helpful when seeks are very expensive (http).*/ - chunk_size=OP_MIN(2*chunk_size,OP_CHUNK_SIZE_MAX); - /*Avoid quadratic complexity if we hit an invalid patch of the file.*/ - end=OP_MIN(begin+OP_PAGE_SIZE_MAX-1,original_end); - } - while(_offset<0); - if(preferred_found)*_sr=*&preferred_sr; - return 0; -} - -/*Find the last page beginning before _offset with the given serial number and - a valid granule position. - Unlike the above search, this continues until it finds such a page, but does - not stray outside the current link. - We could implement it (inefficiently) by calling op_get_prev_page_serial() - repeatedly until it returned a page that had both our preferred serial - number and a valid granule position, but doing it with a separate function - allows us to avoid repeatedly re-scanning valid pages from other streams as - we seek-back-and-read-forward. - [out] _gp: Returns the granule position of the page that was found on - success. - _offset: The _offset before which to find a page. - Any page returned will consist of data entirely before _offset. - _serialno: The target serial number. - _serialnos: The list of serial numbers in the link that contains the - preferred serial number. - _nserialnos: The number of serial numbers in the current link. - Return: The offset of the page on success, or a negative value on failure. - OP_EREAD: Failed to read more data (error or EOF). - OP_EBADLINK: We couldn't find a page even after seeking back past the - beginning of the link.*/ -static opus_int64 op_get_last_page(OggOpusFile *_of,ogg_int64_t *_gp, - opus_int64 _offset,ogg_uint32_t _serialno, - const ogg_uint32_t *_serialnos,int _nserialnos){ - ogg_page og; - ogg_int64_t gp; - opus_int64 begin; - opus_int64 end; - opus_int64 original_end; - opus_int32 chunk_size; - /*The target serial number must belong to the current link.*/ - OP_ASSERT(op_lookup_serialno(_serialno,_serialnos,_nserialnos)); - original_end=end=begin=_offset; - _offset=-1; - /*We shouldn't have to initialize gp, but gcc is too dumb to figure out that - ret>=0 implies we entered the if(page_gp!=-1) block at least once.*/ - gp=-1; - chunk_size=OP_CHUNK_SIZE; - do{ - int left_link; - int ret; - OP_ASSERT(chunk_size>=OP_PAGE_SIZE_MAX); - begin=OP_MAX(begin-chunk_size,0); - ret=op_seek_helper(_of,begin); - if(OP_UNLIKELY(ret<0))return ret; - left_link=0; - while(_of->offsetready_stateos,ogg_page_serialno(_og)); - ogg_stream_pagein(&_of->os,_og); - if(OP_LIKELY(ogg_stream_packetout(&_of->os,&op)>0)){ - ret=opus_head_parse(_head,op.packet,op.bytes); - /*Found a valid Opus header. - Continue setup.*/ - if(OP_LIKELY(ret>=0))_of->ready_state=OP_STREAMSET; - /*If it's just a stream type we don't recognize, ignore it. - Everything else is fatal.*/ - else if(ret!=OP_ENOTFORMAT)return ret; - } - /*TODO: Should a BOS page with no packets be an error?*/ - } - /*Get the next page. - No need to clamp the boundary offset against _of->end, as all errors - become OP_ENOTFORMAT or OP_EBADHEADER.*/ - if(OP_UNLIKELY(op_get_next_page(_of,_og, - OP_ADV_OFFSET(_of->offset,OP_CHUNK_SIZE))<0)){ - return _of->ready_stateready_state!=OP_STREAMSET))return OP_ENOTFORMAT; - /*If the first non-header page belonged to our Opus stream, submit it.*/ - if(_of->os.serialno==ogg_page_serialno(_og))ogg_stream_pagein(&_of->os,_og); - /*Loop getting packets.*/ - for(;;){ - switch(ogg_stream_packetout(&_of->os,&op)){ - case 0:{ - /*Loop getting pages.*/ - for(;;){ - /*No need to clamp the boundary offset against _of->end, as all - errors become OP_EBADHEADER.*/ - if(OP_UNLIKELY(op_get_next_page(_of,_og, - OP_ADV_OFFSET(_of->offset,OP_CHUNK_SIZE))<0)){ - return OP_EBADHEADER; - } - /*If this page belongs to the correct stream, go parse it.*/ - if(_of->os.serialno==ogg_page_serialno(_og)){ - ogg_stream_pagein(&_of->os,_og); - break; - } - /*If the link ends before we see the Opus comment header, abort.*/ - if(OP_UNLIKELY(ogg_page_bos(_og)))return OP_EBADHEADER; - /*Otherwise, keep looking.*/ - } - }break; - /*We shouldn't get a hole in the headers!*/ - case -1:return OP_EBADHEADER; - default:{ - /*Got a packet. - It should be the comment header.*/ - ret=opus_tags_parse(_tags,op.packet,op.bytes); - if(OP_UNLIKELY(ret<0))return ret; - /*Make sure the page terminated at the end of the comment header. - If there is another packet on the page, or part of a packet, then - reject the stream. - Otherwise seekable sources won't be able to seek back to the start - properly.*/ - ret=ogg_stream_packetout(&_of->os,&op); - if(OP_UNLIKELY(ret!=0) - ||OP_UNLIKELY(_og->header[_og->header_len-1]==255)){ - /*If we fail, the caller assumes our tags are uninitialized.*/ - opus_tags_clear(_tags); - return OP_EBADHEADER; - } - return 0; - } - } - } -} - -static int op_fetch_headers(OggOpusFile *_of,OpusHead *_head, - OpusTags *_tags,ogg_uint32_t **_serialnos,int *_nserialnos, - int *_cserialnos,ogg_page *_og){ - ogg_page og; - int ret; - if(!_og){ - /*No need to clamp the boundary offset against _of->end, as all errors - become OP_ENOTFORMAT.*/ - if(OP_UNLIKELY(op_get_next_page(_of,&og, - OP_ADV_OFFSET(_of->offset,OP_CHUNK_SIZE))<0)){ - return OP_ENOTFORMAT; - } - _og=&og; - } - _of->ready_state=OP_OPENED; - ret=op_fetch_headers_impl(_of,_head,_tags,_serialnos,_nserialnos, - _cserialnos,_og); - /*Revert back from OP_STREAMSET to OP_OPENED on failure, to prevent - double-free of the tags in an unseekable stream.*/ - if(OP_UNLIKELY(ret<0))_of->ready_state=OP_OPENED; - return ret; -} - -/*Granule position manipulation routines. - A granule position is defined to be an unsigned 64-bit integer, with the - special value -1 in two's complement indicating an unset or invalid granule - position. - We are not guaranteed to have an unsigned 64-bit type, so we construct the - following routines that - a) Properly order negative numbers as larger than positive numbers, and - b) Check for underflow or overflow past the special -1 value. - This lets us operate on the full, valid range of granule positions in a - consistent and safe manner. - This full range is organized into distinct regions: - [ -1 (invalid) ][ 0 ... OP_INT64_MAX ][ OP_INT64_MIN ... -2 ][-1 (invalid) ] - - No one should actually use granule positions so large that they're negative, - even if they are technically valid, as very little software handles them - correctly (including most of Xiph.Org's). - This library also refuses to support durations so large they won't fit in a - signed 64-bit integer (to avoid exposing this mess to the application, and - to simplify a good deal of internal arithmetic), so the only way to use them - successfully is if pcm_start is very large. - This means there isn't anything you can do with negative granule positions - that you couldn't have done with purely non-negative ones. - The main purpose of these routines is to allow us to think very explicitly - about the possible failure cases of all granule position manipulations.*/ - -/*Safely adds a small signed integer to a valid (not -1) granule position. - The result can use the full 64-bit range of values (both positive and - negative), but will fail on overflow (wrapping past -1; wrapping past - OP_INT64_MAX is explicitly okay). - [out] _dst_gp: The resulting granule position. - Only modified on success. - _src_gp: The granule position to add to. - This must not be -1. - _delta: The amount to add. - This is allowed to be up to 32 bits to support the maximum - duration of a single Ogg page (255 packets * 120 ms per - packet == 1,468,800 samples at 48 kHz). - Return: 0 on success, or OP_EINVAL if the result would wrap around past -1.*/ -static int op_granpos_add(ogg_int64_t *_dst_gp,ogg_int64_t _src_gp, - opus_int32 _delta){ - /*The code below handles this case correctly, but there's no reason we - should ever be called with these values, so make sure we aren't.*/ - OP_ASSERT(_src_gp!=-1); - if(_delta>0){ - /*Adding this amount to the granule position would overflow its 64-bit - range.*/ - if(OP_UNLIKELY(_src_gp<0)&&OP_UNLIKELY(_src_gp>=-1-_delta))return OP_EINVAL; - if(OP_UNLIKELY(_src_gp>OP_INT64_MAX-_delta)){ - /*Adding this amount to the granule position would overflow the positive - half of its 64-bit range. - Since signed overflow is undefined in C, do it in a way the compiler - isn't allowed to screw up.*/ - _delta-=(opus_int32)(OP_INT64_MAX-_src_gp)+1; - _src_gp=OP_INT64_MIN; - } - } - else if(_delta<0){ - /*Subtracting this amount from the granule position would underflow its - 64-bit range.*/ - if(_src_gp>=0&&OP_UNLIKELY(_src_gp<-_delta))return OP_EINVAL; - if(OP_UNLIKELY(_src_gp da < 0.*/ - da=(OP_INT64_MIN-_gp_a)-1; - /*_gp_b >= 0 => db >= 0.*/ - db=OP_INT64_MAX-_gp_b; - /*Step 2: Check for overflow.*/ - if(OP_UNLIKELY(OP_INT64_MAX+da= 0 => da <= 0*/ - da=_gp_a+OP_INT64_MIN; - /*_gp_b < 0 => db <= 0*/ - db=OP_INT64_MIN-_gp_b; - /*Step 2: Check for overflow.*/ - if(OP_UNLIKELY(da=0)return 1; - /*Else fall through.*/ - } - else if(OP_UNLIKELY(_gp_b<0))return -1; - /*No wrapping case.*/ - return (_gp_a>_gp_b)-(_gp_b>_gp_a); -} - -/*Returns the duration of the packet (in samples at 48 kHz), or a negative - value on error.*/ -static int op_get_packet_duration(const unsigned char *_data,int _len){ - int nframes; - int frame_size; - int nsamples; - nframes=opus_packet_get_nb_frames(_data,_len); - if(OP_UNLIKELY(nframes<0))return OP_EBADPACKET; - frame_size=opus_packet_get_samples_per_frame(_data,48000); - nsamples=nframes*frame_size; - if(OP_UNLIKELY(nsamples>120*48))return OP_EBADPACKET; - return nsamples; -} - -/*This function more properly belongs in info.c, but we define it here to allow - the static granule position manipulation functions to remain static.*/ -ogg_int64_t opus_granule_sample(const OpusHead *_head,ogg_int64_t _gp){ - opus_int32 pre_skip; - pre_skip=_head->pre_skip; - if(_gp!=-1&&op_granpos_add(&_gp,_gp,-pre_skip))_gp=-1; - return _gp; -} - -/*Grab all the packets currently in the stream state, and compute their - durations. - _of->op_count is set to the number of packets collected. - [out] _durations: Returns the durations of the individual packets. - Return: The total duration of all packets, or OP_HOLE if there was a hole.*/ -static opus_int32 op_collect_audio_packets(OggOpusFile *_of, - int _durations[255]){ - opus_int32 total_duration; - int op_count; - /*Count the durations of all packets in the page.*/ - op_count=0; - total_duration=0; - for(;;){ - int ret; - /*This takes advantage of undocumented libogg behavior that returned - ogg_packet buffers are valid at least until the next page is - submitted. - Relying on this is not too terrible, as _none_ of the Ogg memory - ownership/lifetime rules are well-documented. - But I can read its code and know this will work.*/ - ret=ogg_stream_packetout(&_of->os,_of->op+op_count); - if(!ret)break; - if(OP_UNLIKELY(ret<0)){ - /*We shouldn't get holes in the middle of pages.*/ - OP_ASSERT(op_count==0); - /*Set the return value and break out of the loop. - We want to make sure op_count gets set to 0, because we've ingested a - page, so any previously loaded packets are now invalid.*/ - total_duration=OP_HOLE; - break; - } - /*Unless libogg is broken, we can't get more than 255 packets from a - single page.*/ - OP_ASSERT(op_count<255); - _durations[op_count]=op_get_packet_duration(_of->op[op_count].packet, - _of->op[op_count].bytes); - if(OP_LIKELY(_durations[op_count]>0)){ - /*With at most 255 packets on a page, this can't overflow.*/ - total_duration+=_durations[op_count++]; - } - /*Ignore packets with an invalid TOC sequence.*/ - else if(op_count>0){ - /*But save the granule position, if there was one.*/ - _of->op[op_count-1].granulepos=_of->op[op_count].granulepos; - } - } - _of->op_pos=0; - _of->op_count=op_count; - return total_duration; -} - -/*Starting from current cursor position, get the initial PCM offset of the next - page. - This also validates the granule position on the first page with a completed - audio data packet, as required by the spec. - If this link is completely empty (no pages with completed packets), then this - function sets pcm_start=pcm_end=0 and returns the BOS page of the next link - (if any). - In the seekable case, we initialize pcm_end=-1 before calling this function, - so that later we can detect that the link was empty before calling - op_find_final_pcm_offset(). - [inout] _link: The link for which to find pcm_start. - [out] _og: Returns the BOS page of the next link if this link was empty. - In the unseekable case, we can then feed this to - op_fetch_headers() to start the next link. - The caller may pass NULL (e.g., for seekable streams), in - which case this page will be discarded. - Return: 0 on success, 1 if there is a buffered BOS page available, or a - negative value on unrecoverable error.*/ -static int op_find_initial_pcm_offset(OggOpusFile *_of, - OggOpusLink *_link,ogg_page *_og){ - ogg_page og; - opus_int64 page_offset; - ogg_int64_t pcm_start; - ogg_int64_t prev_packet_gp; - ogg_int64_t cur_page_gp; - ogg_uint32_t serialno; - opus_int32 total_duration; - int durations[255]; - int cur_page_eos; - int op_count; - int pi; - if(_og==NULL)_og=&og; - serialno=_of->os.serialno; - op_count=0; - /*We shouldn't have to initialize total_duration, but gcc is too dumb to - figure out that op_count>0 implies we've been through the whole loop at - least once.*/ - total_duration=0; - do{ - page_offset=op_get_next_page(_of,_og,_of->end); - /*We should get a page unless the file is truncated or mangled. - Otherwise there are no audio data packets in the whole logical stream.*/ - if(OP_UNLIKELY(page_offset<0)){ - /*Fail if there was a read error.*/ - if(page_offsethead.pre_skip>0)return OP_EBADTIMESTAMP; - _link->pcm_file_offset=0; - /*Set pcm_end and end_offset so we can skip the call to - op_find_final_pcm_offset().*/ - _link->pcm_start=_link->pcm_end=0; - _link->end_offset=_link->data_offset; - return 0; - } - /*Similarly, if we hit the next link in the chain, we've gone too far.*/ - if(OP_UNLIKELY(ogg_page_bos(_og))){ - if(_link->head.pre_skip>0)return OP_EBADTIMESTAMP; - /*Set pcm_end and end_offset so we can skip the call to - op_find_final_pcm_offset().*/ - _link->pcm_file_offset=0; - _link->pcm_start=_link->pcm_end=0; - _link->end_offset=_link->data_offset; - /*Tell the caller we've got a buffered page for them.*/ - return 1; - } - /*Ignore pages from other streams (not strictly necessary, because of the - checks in ogg_stream_pagein(), but saves some work).*/ - if(serialno!=(ogg_uint32_t)ogg_page_serialno(_og))continue; - ogg_stream_pagein(&_of->os,_og); - /*Bitrate tracking: add the header's bytes here. - The body bytes are counted when we consume the packets.*/ - _of->bytes_tracked+=_og->header_len; - /*Count the durations of all packets in the page.*/ - do total_duration=op_collect_audio_packets(_of,durations); - /*Ignore holes.*/ - while(OP_UNLIKELY(total_duration<0)); - op_count=_of->op_count; - } - while(op_count<=0); - /*We found the first page with a completed audio data packet: actually look - at the granule position. - RFC 3533 says, "A special value of -1 (in two's complement) indicates that - no packets finish on this page," which does not say that a granule - position that is NOT -1 indicates that some packets DO finish on that page - (even though this was the intention, libogg itself violated this intention - for years before we fixed it). - The Ogg Opus specification only imposes its start-time requirements - on the granule position of the first page with completed packets, - so we ignore any set granule positions until then.*/ - cur_page_gp=_of->op[op_count-1].granulepos; - /*But getting a packet without a valid granule position on the page is not - okay.*/ - if(cur_page_gp==-1)return OP_EBADTIMESTAMP; - cur_page_eos=_of->op[op_count-1].e_o_s; - if(OP_LIKELY(!cur_page_eos)){ - /*The EOS flag wasn't set. - Work backwards from the provided granule position to get the starting PCM - offset.*/ - if(OP_UNLIKELY(op_granpos_add(&pcm_start,cur_page_gp,-total_duration)<0)){ - /*The starting granule position MUST not be smaller than the amount of - audio on the first page with completed packets.*/ - return OP_EBADTIMESTAMP; - } - } - else{ - /*The first page with completed packets was also the last.*/ - if(OP_LIKELY(op_granpos_add(&pcm_start,cur_page_gp,-total_duration)<0)){ - /*If there's less audio on the page than indicated by the granule - position, then we're doing end-trimming, and the starting PCM offset - is zero by spec mandate.*/ - pcm_start=0; - /*However, the end-trimming MUST not ask us to trim more samples than - exist after applying the pre-skip.*/ - if(OP_UNLIKELY(op_granpos_cmp(cur_page_gp,_link->head.pre_skip)<0)){ - return OP_EBADTIMESTAMP; - } - } - } - /*Timestamp the individual packets.*/ - prev_packet_gp=pcm_start; - for(pi=0;pi0){ - /*If we trimmed the entire packet, stop (the spec says encoders - shouldn't do this, but we support it anyway).*/ - if(OP_UNLIKELY(diff>durations[pi]))break; - _of->op[pi].granulepos=prev_packet_gp=cur_page_gp; - /*Move the EOS flag to this packet, if necessary, so we'll trim the - samples.*/ - _of->op[pi].e_o_s=1; - continue; - } - } - /*Update the granule position as normal.*/ - OP_ALWAYS_TRUE(!op_granpos_add(&_of->op[pi].granulepos, - prev_packet_gp,durations[pi])); - prev_packet_gp=_of->op[pi].granulepos; - } - /*Update the packet count after end-trimming.*/ - _of->op_count=pi; - _of->cur_discard_count=_link->head.pre_skip; - _link->pcm_file_offset=0; - _of->prev_packet_gp=_link->pcm_start=pcm_start; - _of->prev_page_offset=page_offset; - return 0; -} - -/*Starting from current cursor position, get the final PCM offset of the - previous page. - This also validates the duration of the link, which, while not strictly - required by the spec, we need to ensure duration calculations don't - overflow. - This is only done for seekable sources. - We must validate that op_find_initial_pcm_offset() succeeded for this link - before calling this function, otherwise it will scan the entire stream - backwards until it reaches the start, and then fail.*/ -static int op_find_final_pcm_offset(OggOpusFile *_of, - const ogg_uint32_t *_serialnos,int _nserialnos,OggOpusLink *_link, - opus_int64 _offset,ogg_uint32_t _end_serialno,ogg_int64_t _end_gp, - ogg_int64_t *_total_duration){ - ogg_int64_t total_duration; - ogg_int64_t duration; - ogg_uint32_t cur_serialno; - /*For the time being, fetch end PCM offset the simple way.*/ - cur_serialno=_link->serialno; - if(_end_serialno!=cur_serialno||_end_gp==-1){ - _offset=op_get_last_page(_of,&_end_gp,_offset, - cur_serialno,_serialnos,_nserialnos); - if(OP_UNLIKELY(_offset<0))return (int)_offset; - } - /*At worst we should have found the first page with completed packets.*/ - if(OP_UNLIKELY(_offset<_link->data_offset))return OP_EBADLINK; - /*This implementation requires that the difference between the first and last - granule positions in each link be representable in a signed, 64-bit - number, and that each link also have at least as many samples as the - pre-skip requires.*/ - if(OP_UNLIKELY(op_granpos_diff(&duration,_end_gp,_link->pcm_start)<0) - ||OP_UNLIKELY(duration<_link->head.pre_skip)){ - return OP_EBADTIMESTAMP; - } - /*We also require that the total duration be representable in a signed, - 64-bit number.*/ - duration-=_link->head.pre_skip; - total_duration=*_total_duration; - if(OP_UNLIKELY(OP_INT64_MAX-durationpcm_end=_end_gp; - _link->end_offset=_offset; - return 0; -} - -/*Rescale the number _x from the range [0,_from] to [0,_to]. - _from and _to must be positive.*/ -static opus_int64 op_rescale64(opus_int64 _x,opus_int64 _from,opus_int64 _to){ - opus_int64 frac; - opus_int64 ret; - int i; - if(_x>=_from)return _to; - if(_x<=0)return 0; - frac=0; - for(i=0;i<63;i++){ - frac<<=1; - OP_ASSERT(_x<=_from); - if(_x>=_from>>1){ - _x-=_from-_x; - frac|=1; - } - else _x<<=1; - } - ret=0; - for(i=0;i<63;i++){ - if(frac&1)ret=(ret&_to&1)+(ret>>1)+(_to>>1); - else ret>>=1; - frac>>=1; - } - return ret; -} - -/*The minimum granule position spacing allowed for making predictions. - This corresponds to about 1 second of audio at 48 kHz for both Opus and - Vorbis, or one keyframe interval in Theora with the default keyframe spacing - of 256.*/ -#define OP_GP_SPACING_MIN (48000) - -/*Try to estimate the location of the next link using the current seek - records, assuming the initial granule position of any streams we've found is - 0.*/ -static opus_int64 op_predict_link_start(const OpusSeekRecord *_sr,int _nsr, - opus_int64 _searched,opus_int64 _end_searched,opus_int32 _bias){ - opus_int64 bisect; - int sri; - int srj; - /*Require that we be at least OP_CHUNK_SIZE from the end. - We don't require that we be at least OP_CHUNK_SIZE from the beginning, - because if we are we'll just scan forward without seeking.*/ - _end_searched-=OP_CHUNK_SIZE; - if(_searched>=_end_searched)return -1; - bisect=_end_searched; - for(sri=0;sri<_nsr;sri++){ - ogg_int64_t gp1; - ogg_int64_t gp2_min; - ogg_uint32_t serialno1; - opus_int64 offset1; - /*If the granule position is negative, either it's invalid or we'd cause - overflow.*/ - gp1=_sr[sri].gp; - if(gp1<0)continue; - /*We require some minimum distance between granule positions to make an - estimate. - We don't actually know what granule position scheme is being used, - because we have no idea what kind of stream these came from. - Therefore we require a minimum spacing between them, with the - expectation that while bitrates and granule position increments might - vary locally in quite complex ways, they are globally smooth.*/ - if(OP_UNLIKELY(op_granpos_add(&gp2_min,gp1,OP_GP_SPACING_MIN)<0)){ - /*No granule position would satisfy us.*/ - continue; - } - offset1=_sr[sri].offset; - serialno1=_sr[sri].serialno; - for(srj=sri;srj-->0;){ - ogg_int64_t gp2; - opus_int64 offset2; - opus_int64 num; - ogg_int64_t den; - ogg_int64_t ipart; - gp2=_sr[srj].gp; - if(gp20); - if(ipart>0&&(offset2-_searched)/ipart=_end_searched?-1:bisect; -} - -/*Finds each bitstream link, one at a time, using a bisection search. - This has to begin by knowing the offset of the first link's initial page.*/ -static int op_bisect_forward_serialno(OggOpusFile *_of, - opus_int64 _searched,OpusSeekRecord *_sr,int _csr, - ogg_uint32_t **_serialnos,int *_nserialnos,int *_cserialnos){ - ogg_page og; - OggOpusLink *links; - int nlinks; - int clinks; - ogg_uint32_t *serialnos; - int nserialnos; - ogg_int64_t total_duration; - int nsr; - int ret; - links=_of->links; - nlinks=clinks=_of->nlinks; - total_duration=0; - /*We start with one seek record, for the last page in the file. - We build up a list of records for places we seek to during link - enumeration. - This list is kept sorted in reverse order. - We only care about seek locations that were _not_ in the current link, - therefore we can add them one at a time to the end of the list as we - improve the lower bound on the location where the next link starts.*/ - nsr=1; - for(;;){ - opus_int64 end_searched; - opus_int64 bisect; - opus_int64 next; - opus_int64 last; - ogg_int64_t end_offset; - ogg_int64_t end_gp; - int sri; - serialnos=*_serialnos; - nserialnos=*_nserialnos; - if(OP_UNLIKELY(nlinks>=clinks)){ - if(OP_UNLIKELY(clinks>INT_MAX-1>>1))return OP_EFAULT; - clinks=2*clinks+1; - OP_ASSERT(nlinkslinks=links; - } - /*Invariants: - We have the headers and serial numbers for the link beginning at 'begin'. - We have the offset and granule position of the last page in the file - (potentially not a page we care about).*/ - /*Scan the seek records we already have to save us some bisection.*/ - for(sri=0;sri1){ - opus_int64 last_offset; - opus_int64 avg_link_size; - opus_int64 upper_limit; - last_offset=links[nlinks-1].offset; - avg_link_size=last_offset/(nlinks-1); - upper_limit=end_searched-OP_CHUNK_SIZE-avg_link_size; - if(OP_LIKELY(last_offset>_searched-avg_link_size) - &&OP_LIKELY(last_offset>1); - /*If we're within OP_CHUNK_SIZE of the start, scan forward.*/ - if(bisect-_searchedoffset-last>=0); - OP_ASSERT(_of->offset-last<=OP_PAGE_SIZE_MAX); - _sr[nsr].size=(opus_int32)(_of->offset-last); - _sr[nsr].serialno=serialno; - _sr[nsr].gp=gp; - nsr++; - } - } - else{ - _searched=_of->offset; - next_bias=OP_CHUNK_SIZE; - if(serialno==links[nlinks-1].serialno){ - /*This page was from the stream we want, remember it. - If it's the last such page in the link, we won't have to go back - looking for it later.*/ - end_gp=gp; - end_offset=last; - } - } - } - bisect=op_predict_link_start(_sr,nsr,_searched,end_searched,next_bias); - } - /*Bisection point found. - Get the final granule position of the previous link, assuming - op_find_initial_pcm_offset() didn't already determine the link was - empty.*/ - if(OP_LIKELY(links[nlinks-1].pcm_end==-1)){ - if(end_gp==-1){ - /*If we don't know where the end page is, we'll have to seek back and - look for it, starting from the end of the link.*/ - end_offset=next; - /*Also forget the last page we read. - It won't be available after the seek.*/ - last=-1; - } - ret=op_find_final_pcm_offset(_of,serialnos,nserialnos, - links+nlinks-1,end_offset,links[nlinks-1].serialno,end_gp, - &total_duration); - if(OP_UNLIKELY(ret<0))return ret; - } - if(last!=next){ - /*The last page we read was not the first page the next link. - Move the cursor position to the offset of that first page. - This only performs an actual seek if the first page of the next link - does not start at the end of the last page from the current Opus - stream with a valid granule position.*/ - ret=op_seek_helper(_of,next); - if(OP_UNLIKELY(ret<0))return ret; - } - ret=op_fetch_headers(_of,&links[nlinks].head,&links[nlinks].tags, - _serialnos,_nserialnos,_cserialnos,last!=next?NULL:&og); - if(OP_UNLIKELY(ret<0))return ret; - links[nlinks].offset=next; - links[nlinks].data_offset=_of->offset; - links[nlinks].serialno=_of->os.serialno; - links[nlinks].pcm_end=-1; - /*This might consume a page from the next link, however the next bisection - always starts with a seek.*/ - ret=op_find_initial_pcm_offset(_of,links+nlinks,NULL); - if(OP_UNLIKELY(ret<0))return ret; - links[nlinks].pcm_file_offset=total_duration; - _searched=_of->offset; - /*Mark the current link count so it can be cleaned up on error.*/ - _of->nlinks=++nlinks; - } - /*Last page is in the starting serialno list, so we've reached the last link. - Now find the last granule position for it (if we didn't the first time we - looked at the end of the stream, and if op_find_initial_pcm_offset() - didn't already determine the link was empty).*/ - if(OP_LIKELY(links[nlinks-1].pcm_end==-1)){ - ret=op_find_final_pcm_offset(_of,serialnos,nserialnos, - links+nlinks-1,_sr[0].offset,_sr[0].serialno,_sr[0].gp,&total_duration); - if(OP_UNLIKELY(ret<0))return ret; - } - /*Trim back the links array if necessary.*/ - links=(OggOpusLink *)_ogg_realloc(links,sizeof(*links)*nlinks); - if(OP_LIKELY(links!=NULL))_of->links=links; - /*We also don't need these anymore.*/ - _ogg_free(*_serialnos); - *_serialnos=NULL; - *_cserialnos=*_nserialnos=0; - return 0; -} - -static void op_update_gain(OggOpusFile *_of){ - OpusHead *head; - opus_int32 gain_q8; - int li; - /*If decode isn't ready, then we'll apply the gain when we initialize the - decoder.*/ - if(_of->ready_stategain_offset_q8; - li=_of->seekable?_of->cur_link:0; - head=&_of->links[li].head; - /*We don't have to worry about overflow here because the header gain and - track gain must lie in the range [-32768,32767], and the user-supplied - offset has been pre-clamped to [-98302,98303].*/ - switch(_of->gain_type){ - case OP_ALBUM_GAIN:{ - int album_gain_q8; - album_gain_q8=0; - opus_tags_get_album_gain(&_of->links[li].tags,&album_gain_q8); - gain_q8+=album_gain_q8; - gain_q8+=head->output_gain; - }break; - case OP_TRACK_GAIN:{ - int track_gain_q8; - track_gain_q8=0; - opus_tags_get_track_gain(&_of->links[li].tags,&track_gain_q8); - gain_q8+=track_gain_q8; - gain_q8+=head->output_gain; - }break; - case OP_HEADER_GAIN:gain_q8+=head->output_gain;break; - case OP_ABSOLUTE_GAIN:break; - default:OP_ASSERT(0); - } - gain_q8=OP_CLAMP(-32768,gain_q8,32767); - OP_ASSERT(_of->od!=NULL); -#if defined(OPUS_SET_GAIN) - opus_multistream_decoder_ctl(_of->od,OPUS_SET_GAIN(gain_q8)); -#else -/*A fallback that works with both float and fixed-point is a bunch of work, - so just force people to use a sufficiently new version. - This is deployed well enough at this point that this shouldn't be a burden.*/ -# error "libopus 1.0.1 or later required" -#endif -} - -static int op_make_decode_ready(OggOpusFile *_of){ - const OpusHead *head; - int li; - int stream_count; - int coupled_count; - int channel_count; - if(_of->ready_state>OP_STREAMSET)return 0; - if(OP_UNLIKELY(_of->ready_stateseekable?_of->cur_link:0; - head=&_of->links[li].head; - stream_count=head->stream_count; - coupled_count=head->coupled_count; - channel_count=head->channel_count; - /*Check to see if the current decoder is compatible with the current link.*/ - if(_of->od!=NULL&&_of->od_stream_count==stream_count - &&_of->od_coupled_count==coupled_count&&_of->od_channel_count==channel_count - &&memcmp(_of->od_mapping,head->mapping, - sizeof(*head->mapping)*channel_count)==0){ - opus_multistream_decoder_ctl(_of->od,OPUS_RESET_STATE); - } - else{ - int err; - opus_multistream_decoder_destroy(_of->od); - _of->od=opus_multistream_decoder_create(48000,channel_count, - stream_count,coupled_count,head->mapping,&err); - if(_of->od==NULL)return OP_EFAULT; - _of->od_stream_count=stream_count; - _of->od_coupled_count=coupled_count; - _of->od_channel_count=channel_count; - memcpy(_of->od_mapping,head->mapping,sizeof(*head->mapping)*channel_count); - } - _of->ready_state=OP_INITSET; - _of->bytes_tracked=0; - _of->samples_tracked=0; -#if !defined(OP_FIXED_POINT) - _of->state_channel_count=0; - /*Use the serial number for the PRNG seed to get repeatable output for - straight play-throughs.*/ - _of->dither_seed=_of->links[li].serialno; -#endif - op_update_gain(_of); - return 0; -} - -static int op_open_seekable2_impl(OggOpusFile *_of){ - /*64 seek records should be enough for anybody. - Actually, with a bisection search in a 63-bit range down to OP_CHUNK_SIZE - granularity, much more than enough.*/ - OpusSeekRecord sr[64]; - opus_int64 data_offset; - int ret; - /*We can seek, so set out learning all about this file.*/ - (*_of->callbacks.seek)(_of->stream,0,SEEK_END); - _of->offset=_of->end=(*_of->callbacks.tell)(_of->stream); - if(OP_UNLIKELY(_of->end<0))return OP_EREAD; - data_offset=_of->links[0].data_offset; - if(OP_UNLIKELY(_of->endend, - _of->links[0].serialno,_of->serialnos,_of->nserialnos); - if(OP_UNLIKELY(ret<0))return ret; - /*If there's any trailing junk, forget about it.*/ - _of->end=sr[0].offset+sr[0].size; - if(OP_UNLIKELY(_of->endserialnos,&_of->nserialnos,&_of->cserialnos); -} - -static int op_open_seekable2(OggOpusFile *_of){ - ogg_sync_state oy_start; - ogg_stream_state os_start; - ogg_packet *op_start; - opus_int64 prev_page_offset; - opus_int64 start_offset; - int start_op_count; - int ret; - /*We're partially open and have a first link header state in storage in _of. - Save off that stream state so we can come back to it. - It would be simpler to just dump all this state and seek back to - links[0].data_offset when we're done. - But we do the extra work to allow us to seek back to _exactly_ the same - stream position we're at now. - This allows, e.g., the HTTP backend to continue reading from the original - connection (if it's still available), instead of opening a new one. - This means we can open and start playing a normal Opus file with a single - link and reasonable packet sizes using only two HTTP requests.*/ - start_op_count=_of->op_count; - /*This is a bit too large to put on the stack unconditionally.*/ - op_start=(ogg_packet *)_ogg_malloc(sizeof(*op_start)*start_op_count); - if(op_start==NULL)return OP_EFAULT; - *&oy_start=_of->oy; - *&os_start=_of->os; - prev_page_offset=_of->prev_page_offset; - start_offset=_of->offset; - memcpy(op_start,_of->op,sizeof(*op_start)*start_op_count); - OP_ASSERT((*_of->callbacks.tell)(_of->stream)==op_position(_of)); - ogg_sync_init(&_of->oy); - ogg_stream_init(&_of->os,-1); - ret=op_open_seekable2_impl(_of); - /*Restore the old stream state.*/ - ogg_stream_clear(&_of->os); - ogg_sync_clear(&_of->oy); - *&_of->oy=*&oy_start; - *&_of->os=*&os_start; - _of->offset=start_offset; - _of->op_count=start_op_count; - memcpy(_of->op,op_start,sizeof(*_of->op)*start_op_count); - _ogg_free(op_start); - _of->prev_packet_gp=_of->links[0].pcm_start; - _of->prev_page_offset=prev_page_offset; - _of->cur_discard_count=_of->links[0].head.pre_skip; - if(OP_UNLIKELY(ret<0))return ret; - /*And restore the position indicator.*/ - ret=(*_of->callbacks.seek)(_of->stream,op_position(_of),SEEK_SET); - return OP_UNLIKELY(ret<0)?OP_EREAD:0; -} - -/*Clear out the current logical bitstream decoder.*/ -static void op_decode_clear(OggOpusFile *_of){ - /*We don't actually free the decoder. - We might be able to re-use it for the next link.*/ - _of->op_count=0; - _of->od_buffer_size=0; - _of->prev_packet_gp=-1; - _of->prev_page_offset=-1; - if(!_of->seekable){ - OP_ASSERT(_of->ready_state>=OP_INITSET); - opus_tags_clear(&_of->links[0].tags); - } - _of->ready_state=OP_OPENED; -} - -static void op_clear(OggOpusFile *_of){ - OggOpusLink *links; - _ogg_free(_of->od_buffer); - if(_of->od!=NULL)opus_multistream_decoder_destroy(_of->od); - links=_of->links; - if(!_of->seekable){ - if(_of->ready_state>OP_OPENED||_of->ready_state==OP_PARTOPEN){ - opus_tags_clear(&links[0].tags); - } - } - else if(OP_LIKELY(links!=NULL)){ - int nlinks; - int link; - nlinks=_of->nlinks; - for(link=0;linkserialnos); - ogg_stream_clear(&_of->os); - ogg_sync_clear(&_of->oy); - if(_of->callbacks.close!=NULL)(*_of->callbacks.close)(_of->stream); -} - -static int op_open1(OggOpusFile *_of, - void *_stream,const OpusFileCallbacks *_cb, - const unsigned char *_initial_data,size_t _initial_bytes){ - ogg_page og; - ogg_page *pog; - int seekable; - int ret; - memset(_of,0,sizeof(*_of)); - if(OP_UNLIKELY(_initial_bytes>(size_t)LONG_MAX))return OP_EFAULT; - _of->end=-1; - _of->stream=_stream; - *&_of->callbacks=*_cb; - /*At a minimum, we need to be able to read data.*/ - if(OP_UNLIKELY(_of->callbacks.read==NULL))return OP_EREAD; - /*Initialize the framing state.*/ - ogg_sync_init(&_of->oy); - /*Perhaps some data was previously read into a buffer for testing against - other stream types. - Allow initialization from this previously read data (especially as we may - be reading from a non-seekable stream). - This requires copying it into a buffer allocated by ogg_sync_buffer() and - doesn't support seeking, so this is not a good mechanism to use for - decoding entire files from RAM.*/ - if(_initial_bytes>0){ - char *buffer; - buffer=ogg_sync_buffer(&_of->oy,(long)_initial_bytes); - memcpy(buffer,_initial_data,_initial_bytes*sizeof(*buffer)); - ogg_sync_wrote(&_of->oy,(long)_initial_bytes); - } - /*Can we seek? - Stevens suggests the seek test is portable. - It's actually not for files on win32, but we address that by fixing it in - our callback implementation (see stream.c).*/ - seekable=_cb->seek!=NULL&&(*_cb->seek)(_stream,0,SEEK_CUR)!=-1; - /*If seek is implemented, tell must also be implemented.*/ - if(seekable){ - opus_int64 pos; - if(OP_UNLIKELY(_of->callbacks.tell==NULL))return OP_EINVAL; - pos=(*_of->callbacks.tell)(_of->stream); - /*If the current position is not equal to the initial bytes consumed, - absolute seeking will not work.*/ - if(OP_UNLIKELY(pos!=(opus_int64)_initial_bytes))return OP_EINVAL; - } - _of->seekable=seekable; - /*Don't seek yet. - Set up a 'single' (current) logical bitstream entry for partial open.*/ - _of->links=(OggOpusLink *)_ogg_malloc(sizeof(*_of->links)); - /*The serialno gets filled in later by op_fetch_headers().*/ - ogg_stream_init(&_of->os,-1); - pog=NULL; - for(;;){ - /*Fetch all BOS pages, store the Opus header and all seen serial numbers, - and load subsequent Opus setup headers.*/ - ret=op_fetch_headers(_of,&_of->links[0].head,&_of->links[0].tags, - &_of->serialnos,&_of->nserialnos,&_of->cserialnos,pog); - if(OP_UNLIKELY(ret<0))break; - _of->nlinks=1; - _of->links[0].offset=0; - _of->links[0].data_offset=_of->offset; - _of->links[0].pcm_end=-1; - _of->links[0].serialno=_of->os.serialno; - /*Fetch the initial PCM offset.*/ - ret=op_find_initial_pcm_offset(_of,_of->links,&og); - if(seekable||OP_LIKELY(ret<=0))break; - /*This link was empty, but we already have the BOS page for the next one in - og. - We can't seek, so start processing the next link right now.*/ - opus_tags_clear(&_of->links[0].tags); - _of->nlinks=0; - if(!seekable)_of->cur_link++; - pog=&og; - } - if(OP_LIKELY(ret>=0))_of->ready_state=OP_PARTOPEN; - return ret; -} - -static int op_open2(OggOpusFile *_of){ - int ret; - OP_ASSERT(_of->ready_state==OP_PARTOPEN); - if(_of->seekable){ - _of->ready_state=OP_OPENED; - ret=op_open_seekable2(_of); - } - else ret=0; - if(OP_LIKELY(ret>=0)){ - /*We have buffered packets from op_find_initial_pcm_offset(). - Move to OP_INITSET so we can use them.*/ - _of->ready_state=OP_STREAMSET; - ret=op_make_decode_ready(_of); - if(OP_LIKELY(ret>=0))return 0; - } - /*Don't auto-close the stream on failure.*/ - _of->callbacks.close=NULL; - op_clear(_of); - return ret; -} - -OggOpusFile *op_test_callbacks(void *_stream,const OpusFileCallbacks *_cb, - const unsigned char *_initial_data,size_t _initial_bytes,int *_error){ - OggOpusFile *of; - int ret; - of=(OggOpusFile *)_ogg_malloc(sizeof(*of)); - ret=OP_EFAULT; - if(OP_LIKELY(of!=NULL)){ - ret=op_open1(of,_stream,_cb,_initial_data,_initial_bytes); - if(OP_LIKELY(ret>=0)){ - if(_error!=NULL)*_error=0; - return of; - } - /*Don't auto-close the stream on failure.*/ - of->callbacks.close=NULL; - op_clear(of); - _ogg_free(of); - } - if(_error!=NULL)*_error=ret; - return NULL; -} - -OggOpusFile *op_open_callbacks(void *_stream,const OpusFileCallbacks *_cb, - const unsigned char *_initial_data,size_t _initial_bytes,int *_error){ - OggOpusFile *of; - of=op_test_callbacks(_stream,_cb,_initial_data,_initial_bytes,_error); - if(OP_LIKELY(of!=NULL)){ - int ret; - ret=op_open2(of); - if(OP_LIKELY(ret>=0))return of; - if(_error!=NULL)*_error=ret; - _ogg_free(of); - } - return NULL; -} - -/*Convenience routine to clean up from failure for the open functions that - create their own streams.*/ -static OggOpusFile *op_open_close_on_failure(void *_stream, - const OpusFileCallbacks *_cb,int *_error){ - OggOpusFile *of; - if(OP_UNLIKELY(_stream==NULL)){ - if(_error!=NULL)*_error=OP_EFAULT; - return NULL; - } - of=op_open_callbacks(_stream,_cb,NULL,0,_error); - if(OP_UNLIKELY(of==NULL))(*_cb->close)(_stream); - return of; -} - -OggOpusFile *op_open_file(const char *_path,int *_error){ - OpusFileCallbacks cb; - return op_open_close_on_failure(op_fopen(&cb,_path,"rb"),&cb,_error); -} - -OggOpusFile *op_open_memory(const unsigned char *_data,size_t _size, - int *_error){ - OpusFileCallbacks cb; - return op_open_close_on_failure(op_mem_stream_create(&cb,_data,_size),&cb, - _error); -} - -/*Convenience routine to clean up from failure for the open functions that - create their own streams.*/ -static OggOpusFile *op_test_close_on_failure(void *_stream, - const OpusFileCallbacks *_cb,int *_error){ - OggOpusFile *of; - if(OP_UNLIKELY(_stream==NULL)){ - if(_error!=NULL)*_error=OP_EFAULT; - return NULL; - } - of=op_test_callbacks(_stream,_cb,NULL,0,_error); - if(OP_UNLIKELY(of==NULL))(*_cb->close)(_stream); - return of; -} - -OggOpusFile *op_test_file(const char *_path,int *_error){ - OpusFileCallbacks cb; - return op_test_close_on_failure(op_fopen(&cb,_path,"rb"),&cb,_error); -} - -OggOpusFile *op_test_memory(const unsigned char *_data,size_t _size, - int *_error){ - OpusFileCallbacks cb; - return op_test_close_on_failure(op_mem_stream_create(&cb,_data,_size),&cb, - _error); -} - -int op_test_open(OggOpusFile *_of){ - int ret; - if(OP_UNLIKELY(_of->ready_state!=OP_PARTOPEN))return OP_EINVAL; - ret=op_open2(_of); - /*op_open2() will clear this structure on failure. - Reset its contents to prevent double-frees in op_free().*/ - if(OP_UNLIKELY(ret<0))memset(_of,0,sizeof(*_of)); - return ret; -} - -void op_free(OggOpusFile *_of){ - if(OP_LIKELY(_of!=NULL)){ - op_clear(_of); - _ogg_free(_of); - } -} - -int op_seekable(const OggOpusFile *_of){ - return _of->seekable; -} - -int op_link_count(const OggOpusFile *_of){ - return _of->nlinks; -} - -opus_uint32 op_serialno(const OggOpusFile *_of,int _li){ - if(OP_UNLIKELY(_li>=_of->nlinks))_li=_of->nlinks-1; - if(!_of->seekable)_li=0; - return _of->links[_li<0?_of->cur_link:_li].serialno; -} - -int op_channel_count(const OggOpusFile *_of,int _li){ - return op_head(_of,_li)->channel_count; -} - -opus_int64 op_raw_total(const OggOpusFile *_of,int _li){ - if(OP_UNLIKELY(_of->ready_stateseekable) - ||OP_UNLIKELY(_li>=_of->nlinks)){ - return OP_EINVAL; - } - if(_li<0)return _of->end; - return (_li+1>=_of->nlinks?_of->end:_of->links[_li+1].offset) - -(_li>0?_of->links[_li].offset:0); -} - -ogg_int64_t op_pcm_total(const OggOpusFile *_of,int _li){ - OggOpusLink *links; - ogg_int64_t pcm_total; - ogg_int64_t diff; - int nlinks; - nlinks=_of->nlinks; - if(OP_UNLIKELY(_of->ready_stateseekable) - ||OP_UNLIKELY(_li>=nlinks)){ - return OP_EINVAL; - } - links=_of->links; - /*We verify that the granule position differences are larger than the - pre-skip and that the total duration does not overflow during link - enumeration, so we don't have to check here.*/ - pcm_total=0; - if(_li<0){ - pcm_total=links[nlinks-1].pcm_file_offset; - _li=nlinks-1; - } - OP_ALWAYS_TRUE(!op_granpos_diff(&diff, - links[_li].pcm_end,links[_li].pcm_start)); - return pcm_total+diff-links[_li].head.pre_skip; -} - -const OpusHead *op_head(const OggOpusFile *_of,int _li){ - if(OP_UNLIKELY(_li>=_of->nlinks))_li=_of->nlinks-1; - if(!_of->seekable)_li=0; - return &_of->links[_li<0?_of->cur_link:_li].head; -} - -const OpusTags *op_tags(const OggOpusFile *_of,int _li){ - if(OP_UNLIKELY(_li>=_of->nlinks))_li=_of->nlinks-1; - if(!_of->seekable){ - if(_of->ready_stateready_state!=OP_PARTOPEN){ - return NULL; - } - _li=0; - } - else if(_li<0)_li=_of->ready_state>=OP_STREAMSET?_of->cur_link:0; - return &_of->links[_li].tags; -} - -int op_current_link(const OggOpusFile *_of){ - if(OP_UNLIKELY(_of->ready_statecur_link; -} - -/*Compute an average bitrate given a byte and sample count. - Return: The bitrate in bits per second.*/ -static opus_int32 op_calc_bitrate(opus_int64 _bytes,ogg_int64_t _samples){ - if(OP_UNLIKELY(_samples<=0))return OP_INT32_MAX; - /*These rates are absurd, but let's handle them anyway.*/ - if(OP_UNLIKELY(_bytes>(OP_INT64_MAX-(_samples>>1))/(48000*8))){ - ogg_int64_t den; - if(OP_UNLIKELY(_bytes/(OP_INT32_MAX/(48000*8))>=_samples)){ - return OP_INT32_MAX; - } - den=_samples/(48000*8); - return (opus_int32)((_bytes+(den>>1))/den); - } - /*This can't actually overflow in normal operation: even with a pre-skip of - 545 2.5 ms frames with 8 streams running at 1282*8+1 bytes per packet - (1275 byte frames + Opus framing overhead + Ogg lacing values), that all - produce a single sample of decoded output, we still don't top 45 Mbps. - The only way to get bitrates larger than that is with excessive Opus - padding, more encoded streams than output channels, or lots and lots of - Ogg pages with no packets on them.*/ - return (opus_int32)OP_MIN((_bytes*48000*8+(_samples>>1))/_samples, - OP_INT32_MAX); -} - -opus_int32 op_bitrate(const OggOpusFile *_of,int _li){ - if(OP_UNLIKELY(_of->ready_stateseekable) - ||OP_UNLIKELY(_li>=_of->nlinks)){ - return OP_EINVAL; - } - return op_calc_bitrate(op_raw_total(_of,_li),op_pcm_total(_of,_li)); -} - -opus_int32 op_bitrate_instant(OggOpusFile *_of){ - ogg_int64_t samples_tracked; - opus_int32 ret; - if(OP_UNLIKELY(_of->ready_statesamples_tracked; - if(OP_UNLIKELY(samples_tracked==0))return OP_FALSE; - ret=op_calc_bitrate(_of->bytes_tracked,samples_tracked); - _of->bytes_tracked=0; - _of->samples_tracked=0; - return ret; -} - -/*Given a serialno, find a link with a corresponding Opus stream, if it exists. - Return: The index of the link to which the page belongs, or a negative number - if it was not a desired Opus bitstream section.*/ -static int op_get_link_from_serialno(const OggOpusFile *_of,int _cur_link, - opus_int64 _page_offset,ogg_uint32_t _serialno){ - const OggOpusLink *links; - int nlinks; - int li_lo; - int li_hi; - OP_ASSERT(_of->seekable); - links=_of->links; - nlinks=_of->nlinks; - li_lo=0; - /*Start off by guessing we're just a multiplexed page in the current link.*/ - li_hi=_cur_link+1=links[_cur_link].offset)li_lo=_cur_link; - else li_hi=_cur_link; - _cur_link=li_lo+(li_hi-li_lo>>1); - } - while(li_hi-li_lo>1); - /*We've identified the link that should contain this page. - Make sure it's a page we care about.*/ - if(links[_cur_link].serialno!=_serialno)return OP_FALSE; - return _cur_link; -} - -/*Fetch and process a page. - This handles the case where we're at a bitstream boundary and dumps the - decoding machine. - If the decoding machine is unloaded, it loads it. - It also keeps prev_packet_gp up to date (seek and read both use this). - Return: <0) Error, OP_HOLE (lost packet), or OP_EOF. - 0) Got at least one audio data packet.*/ -static int op_fetch_and_process_page(OggOpusFile *_of, - ogg_page *_og,opus_int64 _page_offset,int _spanp,int _ignore_holes){ - OggOpusLink *links; - ogg_uint32_t cur_serialno; - int seekable; - int cur_link; - int ret; - /*We shouldn't get here if we have unprocessed packets.*/ - OP_ASSERT(_of->ready_stateop_pos>=_of->op_count); - seekable=_of->seekable; - links=_of->links; - cur_link=seekable?_of->cur_link:0; - cur_serialno=links[cur_link].serialno; - /*Handle one page.*/ - for(;;){ - ogg_page og; - OP_ASSERT(_of->ready_state>=OP_OPENED); - /*If we were given a page to use, use it.*/ - if(_og!=NULL){ - *&og=*_og; - _og=NULL; - } - /*Keep reading until we get a page with the correct serialno.*/ - else _page_offset=op_get_next_page(_of,&og,_of->end); - /*EOF: Leave uninitialized.*/ - if(_page_offset<0)return _page_offsetready_state>=OP_STREAMSET) - &&cur_serialno!=(ogg_uint32_t)ogg_page_serialno(&og)){ - /*Two possibilities: - 1) Another stream is multiplexed into this logical section, or*/ - if(OP_LIKELY(!ogg_page_bos(&og)))continue; - /* 2) Our decoding just traversed a bitstream boundary.*/ - if(!_spanp)return OP_EOF; - if(OP_LIKELY(_of->ready_state>=OP_INITSET))op_decode_clear(_of); - } - /*Bitrate tracking: add the header's bytes here. - The body bytes are counted when we consume the packets.*/ - else _of->bytes_tracked+=og.header_len; - /*Do we need to load a new machine before submitting the page? - This is different in the seekable and non-seekable cases. - In the seekable case, we already have all the header information loaded - and cached. - We just initialize the machine with it and continue on our merry way. - In the non-seekable (streaming) case, we'll only be at a boundary if we - just left the previous logical bitstream, and we're now nominally at the - header of the next bitstream.*/ - if(OP_UNLIKELY(_of->ready_state=0&&cur_link<_of->nlinks); - if(links[cur_link].serialno!=serialno){ - /*It wasn't a page from the current link. - Is it from the next one?*/ - if(OP_LIKELY(cur_link+1<_of->nlinks&&links[cur_link+1].serialno== - serialno)){ - cur_link++; - } - else{ - int new_link; - new_link= - op_get_link_from_serialno(_of,cur_link,_page_offset,serialno); - /*Not a desired Opus bitstream section. - Keep trying.*/ - if(new_link<0)continue; - cur_link=new_link; - } - } - cur_serialno=serialno; - _of->cur_link=cur_link; - ogg_stream_reset_serialno(&_of->os,serialno); - _of->ready_state=OP_STREAMSET; - /*If we're at the start of this link, initialize the granule position - and pre-skip tracking.*/ - if(_page_offset<=links[cur_link].data_offset){ - _of->prev_packet_gp=links[cur_link].pcm_start; - _of->prev_page_offset=-1; - _of->cur_discard_count=links[cur_link].head.pre_skip; - /*Ignore a hole at the start of a new link (this is common for - streams joined in the middle) or after seeking.*/ - _ignore_holes=1; - } - } - else{ - do{ - /*We're streaming. - Fetch the two header packets, build the info struct.*/ - ret=op_fetch_headers(_of,&links[0].head,&links[0].tags, - NULL,NULL,NULL,&og); - if(OP_UNLIKELY(ret<0))return ret; - /*op_find_initial_pcm_offset() will suppress any initial hole for us, - so no need to set _ignore_holes.*/ - ret=op_find_initial_pcm_offset(_of,links,&og); - if(OP_UNLIKELY(ret<0))return ret; - _of->links[0].serialno=cur_serialno=_of->os.serialno; - _of->cur_link++; - } - /*If the link was empty, keep going, because we already have the - BOS page of the next one in og.*/ - while(OP_UNLIKELY(ret>0)); - /*If we didn't get any packets out of op_find_initial_pcm_offset(), - keep going (this is possible if end-trimming trimmed them all).*/ - if(_of->op_count<=0)continue; - /*Otherwise, we're done. - TODO: This resets bytes_tracked, which misses the header bytes - already processed by op_find_initial_pcm_offset().*/ - ret=op_make_decode_ready(_of); - if(OP_UNLIKELY(ret<0))return ret; - return 0; - } - } - /*The buffered page is the data we want, and we're ready for it. - Add it to the stream state.*/ - if(OP_UNLIKELY(_of->ready_state==OP_STREAMSET)){ - ret=op_make_decode_ready(_of); - if(OP_UNLIKELY(ret<0))return ret; - } - /*Extract all the packets from the current page.*/ - ogg_stream_pagein(&_of->os,&og); - if(OP_LIKELY(_of->ready_state>=OP_INITSET)){ - opus_int32 total_duration; - int durations[255]; - int op_count; - int report_hole; - report_hole=0; - total_duration=op_collect_audio_packets(_of,durations); - if(OP_UNLIKELY(total_duration<0)){ - /*libogg reported a hole (a gap in the page sequence numbers). - Drain the packets from the page anyway. - If we don't, they'll still be there when we fetch the next page. - Then, when we go to pull out packets, we might get more than 255, - which would overrun our packet buffer. - We repeat this call until we get any actual packets, since we might - have buffered multiple out-of-sequence pages with no packets on - them.*/ - do total_duration=op_collect_audio_packets(_of,durations); - while(total_duration<0); - if(!_ignore_holes){ - /*Report the hole to the caller after we finish timestamping the - packets.*/ - report_hole=1; - /*We had lost or damaged pages, so reset our granule position - tracking. - This makes holes behave the same as a small raw seek. - If the next page is the EOS page, we'll discard it (because we - can't perform end trimming properly), and we'll always discard at - least 80 ms of audio (to allow decoder state to re-converge). - We could try to fill in the gap with PLC by looking at timestamps - in the non-EOS case, but that's complicated and error prone and we - can't rely on the timestamps being valid.*/ - _of->prev_packet_gp=-1; - } - } - op_count=_of->op_count; - /*If we found at least one audio data packet, compute per-packet granule - positions for them.*/ - if(op_count>0){ - ogg_int64_t diff; - ogg_int64_t prev_packet_gp; - ogg_int64_t cur_packet_gp; - ogg_int64_t cur_page_gp; - int cur_page_eos; - int pi; - cur_page_gp=_of->op[op_count-1].granulepos; - cur_page_eos=_of->op[op_count-1].e_o_s; - prev_packet_gp=_of->prev_packet_gp; - if(OP_UNLIKELY(prev_packet_gp==-1)){ - opus_int32 cur_discard_count; - /*This is the first call after a raw seek. - Try to reconstruct prev_packet_gp from scratch.*/ - OP_ASSERT(seekable); - if(OP_UNLIKELY(cur_page_eos)){ - /*If the first page we hit after our seek was the EOS page, and - we didn't start from data_offset or before, we don't have - enough information to do end-trimming. - Proceed to the next link, rather than risk playing back some - samples that shouldn't have been played.*/ - _of->op_count=0; - if(report_hole)return OP_HOLE; - continue; - } - /*By default discard 80 ms of data after a seek, unless we seek - into the pre-skip region.*/ - cur_discard_count=80*48; - cur_page_gp=_of->op[op_count-1].granulepos; - /*Try to initialize prev_packet_gp. - If the current page had packets but didn't have a granule - position, or the granule position it had was too small (both - illegal), just use the starting granule position for the link.*/ - prev_packet_gp=links[cur_link].pcm_start; - if(OP_LIKELY(cur_page_gp!=-1)){ - op_granpos_add(&prev_packet_gp,cur_page_gp,-total_duration); - } - if(OP_LIKELY(!op_granpos_diff(&diff, - prev_packet_gp,links[cur_link].pcm_start))){ - opus_int32 pre_skip; - /*If we start at the beginning of the pre-skip region, or we're - at least 80 ms from the end of the pre-skip region, we discard - to the end of the pre-skip region. - Otherwise, we still use the 80 ms default, which will discard - past the end of the pre-skip region.*/ - pre_skip=links[cur_link].head.pre_skip; - if(diff>=0&&diff<=OP_MAX(0,pre_skip-80*48)){ - cur_discard_count=pre_skip-(int)diff; - } - } - _of->cur_discard_count=cur_discard_count; - } - if(OP_UNLIKELY(cur_page_gp==-1)){ - /*This page had completed packets but didn't have a valid granule - position. - This is illegal, but we'll try to handle it by continuing to count - forwards from the previous page.*/ - if(op_granpos_add(&cur_page_gp,prev_packet_gp,total_duration)<0){ - /*The timestamp for this page overflowed.*/ - cur_page_gp=links[cur_link].pcm_end; - } - } - /*If we hit the last page, handle end-trimming.*/ - if(OP_UNLIKELY(cur_page_eos) - &&OP_LIKELY(!op_granpos_diff(&diff,cur_page_gp,prev_packet_gp)) - &&OP_LIKELY(diff0){ - /*If we trimmed the entire packet, stop (the spec says encoders - shouldn't do this, but we support it anyway).*/ - if(OP_UNLIKELY(diff>durations[pi]))break; - cur_packet_gp=cur_page_gp; - /*Move the EOS flag to this packet, if necessary, so we'll trim - the samples during decode.*/ - _of->op[pi].e_o_s=1; - } - else{ - /*Update the granule position as normal.*/ - OP_ALWAYS_TRUE(!op_granpos_add(&cur_packet_gp, - cur_packet_gp,durations[pi])); - } - _of->op[pi].granulepos=cur_packet_gp; - OP_ALWAYS_TRUE(!op_granpos_diff(&diff,cur_page_gp,cur_packet_gp)); - } - } - else{ - /*Propagate timestamps to earlier packets. - op_granpos_add(&prev_packet_gp,prev_packet_gp,total_duration) - should succeed and give prev_packet_gp==cur_page_gp. - But we don't bother to check that, as there isn't much we can do - if it's not true, and it actually will not be true on the first - page after a seek, if there was a continued packet. - The only thing we guarantee is that the start and end granule - positions of the packets are valid, and that they are monotonic - within a page. - They might be completely out of range for this link (we'll check - that elsewhere), or non-monotonic between pages.*/ - if(OP_UNLIKELY(op_granpos_add(&prev_packet_gp, - cur_page_gp,-total_duration)<0)){ - /*The starting timestamp for the first packet on this page - underflowed. - This is illegal, but we ignore it.*/ - prev_packet_gp=0; - } - for(pi=0;pi=0); - OP_ALWAYS_TRUE(!op_granpos_add(&cur_packet_gp, - cur_packet_gp,durations[pi])); - _of->op[pi].granulepos=cur_packet_gp; - } - OP_ASSERT(total_duration==0); - } - _of->prev_packet_gp=prev_packet_gp; - _of->prev_page_offset=_page_offset; - _of->op_count=op_count=pi; - } - if(report_hole)return OP_HOLE; - /*If end-trimming didn't trim all the packets, we're done.*/ - if(op_count>0)return 0; - } - } -} - -int op_raw_seek(OggOpusFile *_of,opus_int64 _pos){ - int ret; - if(OP_UNLIKELY(_of->ready_stateseekable))return OP_ENOSEEK; - if(OP_UNLIKELY(_pos<0)||OP_UNLIKELY(_pos>_of->end))return OP_EINVAL; - /*Clear out any buffered, decoded data.*/ - op_decode_clear(_of); - _of->bytes_tracked=0; - _of->samples_tracked=0; - ret=op_seek_helper(_of,_pos); - if(OP_UNLIKELY(ret<0))return OP_EREAD; - ret=op_fetch_and_process_page(_of,NULL,-1,1,1); - /*If we hit EOF, op_fetch_and_process_page() leaves us uninitialized. - Instead, jump to the end.*/ - if(ret==OP_EOF){ - int cur_link; - op_decode_clear(_of); - cur_link=_of->nlinks-1; - _of->cur_link=cur_link; - _of->prev_packet_gp=_of->links[cur_link].pcm_end; - _of->cur_discard_count=0; - ret=0; - } - return ret; -} - -/*Convert a PCM offset relative to the start of the whole stream to a granule - position in an individual link.*/ -static ogg_int64_t op_get_granulepos(const OggOpusFile *_of, - ogg_int64_t _pcm_offset,int *_li){ - const OggOpusLink *links; - ogg_int64_t duration; - ogg_int64_t pcm_start; - opus_int32 pre_skip; - int nlinks; - int li_lo; - int li_hi; - OP_ASSERT(_pcm_offset>=0); - nlinks=_of->nlinks; - links=_of->links; - li_lo=0; - li_hi=nlinks; - do{ - int li; - li=li_lo+(li_hi-li_lo>>1); - if(links[li].pcm_file_offset<=_pcm_offset)li_lo=li; - else li_hi=li; - } - while(li_hi-li_lo>1); - _pcm_offset-=links[li_lo].pcm_file_offset; - pcm_start=links[li_lo].pcm_start; - pre_skip=links[li_lo].head.pre_skip; - OP_ALWAYS_TRUE(!op_granpos_diff(&duration,links[li_lo].pcm_end,pcm_start)); - duration-=pre_skip; - if(_pcm_offset>=duration)return -1; - _pcm_offset+=pre_skip; - if(OP_UNLIKELY(pcm_start>OP_INT64_MAX-_pcm_offset)){ - /*Adding this amount to the granule position would overflow the positive - half of its 64-bit range. - Since signed overflow is undefined in C, do it in a way the compiler - isn't allowed to screw up.*/ - _pcm_offset-=OP_INT64_MAX-pcm_start+1; - pcm_start=OP_INT64_MIN; - } - pcm_start+=_pcm_offset; - *_li=li_lo; - return pcm_start; -} - -/*A small helper to determine if an Ogg page contains data that continues onto - a subsequent page.*/ -static int op_page_continues(const ogg_page *_og){ - int nlacing; - OP_ASSERT(_og->header_len>=27); - nlacing=_og->header[26]; - OP_ASSERT(_og->header_len>=27+nlacing); - /*This also correctly handles the (unlikely) case of nlacing==0, because - 0!=255.*/ - return _og->header[27+nlacing-1]==255; -} - -/*A small helper to buffer the continued packet data from a page.*/ -static void op_buffer_continued_data(OggOpusFile *_of,ogg_page *_og){ - ogg_packet op; - ogg_stream_pagein(&_of->os,_og); - /*Drain any packets that did end on this page (and ignore holes). - We only care about the continued packet data.*/ - while(ogg_stream_packetout(&_of->os,&op)); -} - -/*This controls how close the target has to be to use the current stream - position to subdivide the initial range. - Two minutes seems to be a good default.*/ -#define OP_CUR_TIME_THRESH (120*48*(opus_int32)1000) - -/*Note: The OP_SMALL_FOOTPRINT #define doesn't (currently) save much code size, - but it's meant to serve as documentation for portions of the seeking - algorithm that are purely optional, to aid others learning from/porting this - code to other contexts.*/ -/*#define OP_SMALL_FOOTPRINT (1)*/ - -/*Search within link _li for the page with the highest granule position - preceding (or equal to) _target_gp. - There is a danger here: missing pages or incorrect frame number information - in the bitstream could make our task impossible. - Account for that (and report it as an error condition).*/ -static int op_pcm_seek_page(OggOpusFile *_of, - ogg_int64_t _target_gp,int _li){ - const OggOpusLink *link; - ogg_page og; - ogg_int64_t pcm_pre_skip; - ogg_int64_t pcm_start; - ogg_int64_t pcm_end; - ogg_int64_t best_gp; - ogg_int64_t diff; - ogg_uint32_t serialno; - opus_int32 pre_skip; - opus_int64 begin; - opus_int64 end; - opus_int64 boundary; - opus_int64 best; - opus_int64 best_start; - opus_int64 page_offset; - opus_int64 d0; - opus_int64 d1; - opus_int64 d2; - int force_bisect; - int buffering; - int ret; - _of->bytes_tracked=0; - _of->samples_tracked=0; - link=_of->links+_li; - best_gp=pcm_start=link->pcm_start; - pcm_end=link->pcm_end; - serialno=link->serialno; - best=best_start=begin=link->data_offset; - page_offset=-1; - buffering=0; - /*We discard the first 80 ms of data after a seek, so seek back that much - farther. - If we can't, simply seek to the beginning of the link.*/ - if(OP_UNLIKELY(op_granpos_add(&_target_gp,_target_gp,-80*48)<0) - ||OP_UNLIKELY(op_granpos_cmp(_target_gp,pcm_start)<0)){ - _target_gp=pcm_start; - } - /*Special case seeking to the start of the link.*/ - pre_skip=link->head.pre_skip; - OP_ALWAYS_TRUE(!op_granpos_add(&pcm_pre_skip,pcm_start,pre_skip)); - if(op_granpos_cmp(_target_gp,pcm_pre_skip)<0)end=boundary=begin; - else{ - end=boundary=link->end_offset; -#if !defined(OP_SMALL_FOOTPRINT) - /*If we were decoding from this link, we can narrow the range a bit.*/ - if(_li==_of->cur_link&&_of->ready_state>=OP_INITSET){ - opus_int64 offset; - int op_count; - op_count=_of->op_count; - /*The only way the offset can be invalid _and_ we can fail the granule - position checks below is if someone changed the contents of the last - page since we read it. - We'd be within our rights to just return OP_EBADLINK in that case, but - we'll simply ignore the current position instead.*/ - offset=_of->offset; - if(op_count>0&&OP_LIKELY(offset<=end)){ - ogg_int64_t gp; - /*Make sure the timestamp is valid. - The granule position might be -1 if we collected the packets from a - page without a granule position after reporting a hole.*/ - gp=_of->op[op_count-1].granulepos; - if(OP_LIKELY(gp!=-1)&&OP_LIKELY(op_granpos_cmp(pcm_start,gp)<0) - &&OP_LIKELY(op_granpos_cmp(pcm_end,gp)>0)){ - OP_ALWAYS_TRUE(!op_granpos_diff(&diff,gp,_target_gp)); - /*We only actually use the current time if either - a) We can cut off at least half the range, or - b) We're seeking sufficiently close to the current position that - it's likely to be informative. - Otherwise it appears using the whole link range to estimate the - first seek location gives better results, on average.*/ - if(diff<0){ - OP_ASSERT(offset>=begin); - if(offset-begin>=end-begin>>1||diff>-OP_CUR_TIME_THRESH){ - best=begin=offset; - best_gp=pcm_start=gp; - /*If we have buffered data from a continued packet, remember the - offset of the previous page's start, so that if we do wind up - having to seek back here later, we can prime the stream with - the continued packet data. - With no continued packet, we remember the end of the page.*/ - best_start=_of->os.body_returned<_of->os.body_fill? - _of->prev_page_offset:best; - /*If there's completed packets and data in the stream state, - prev_page_offset should always be set.*/ - OP_ASSERT(best_start>=0); - /*Buffer any continued packet data starting from here.*/ - buffering=1; - } - } - else{ - ogg_int64_t prev_page_gp; - /*We might get lucky and already have the packet with the target - buffered. - Worth checking. - For very small files (with all of the data in a single page, - generally 1 second or less), we can loop them continuously - without seeking at all.*/ - OP_ALWAYS_TRUE(!op_granpos_add(&prev_page_gp,_of->op[0].granulepos, - -op_get_packet_duration(_of->op[0].packet,_of->op[0].bytes))); - if(op_granpos_cmp(prev_page_gp,_target_gp)<=0){ - /*Don't call op_decode_clear(), because it will dump our - packets.*/ - _of->op_pos=0; - _of->od_buffer_size=0; - _of->prev_packet_gp=prev_page_gp; - /*_of->prev_page_offset already points to the right place.*/ - _of->ready_state=OP_STREAMSET; - return op_make_decode_ready(_of); - } - /*No such luck. - Check if we can cut off at least half the range, though.*/ - if(offset-begin<=end-begin>>1||diffos,serialno); - _of->cur_link=_li; - _of->ready_state=OP_STREAMSET; - /*Initialize the interval size history.*/ - d2=d1=d0=end-begin; - force_bisect=0; - while(begin>1; - d1=d2>>1; - d2=end-begin>>1; - if(force_bisect)bisect=begin+(end-begin>>1); - else{ - ogg_int64_t diff2; - OP_ALWAYS_TRUE(!op_granpos_diff(&diff,_target_gp,pcm_start)); - OP_ALWAYS_TRUE(!op_granpos_diff(&diff2,pcm_end,pcm_start)); - /*Take a (pretty decent) guess.*/ - bisect=begin+op_rescale64(diff,diff2,end-begin)-OP_CHUNK_SIZE; - } - if(bisect-OP_CHUNK_SIZEoffset){ - /*Discard any buffered continued packet data.*/ - if(buffering)ogg_stream_reset(&_of->os); - buffering=0; - page_offset=-1; - ret=op_seek_helper(_of,bisect); - if(OP_UNLIKELY(ret<0))return ret; - } - chunk_size=OP_CHUNK_SIZE; - next_boundary=boundary; - /*Now scan forward and figure out where we landed. - In the ideal case, we will see a page with a granule position at or - before our target, followed by a page with a granule position after our - target (or the end of the search interval). - Then we can just drop out and will have all of the data we need with no - additional seeking. - If we landed too far before, or after, we'll break out and do another - bisection.*/ - while(beginos); - buffering=0; - bisect=OP_MAX(bisect-chunk_size,begin); - ret=op_seek_helper(_of,bisect); - if(OP_UNLIKELY(ret<0))return ret; - /*Bump up the chunk size.*/ - chunk_size=OP_MIN(2*chunk_size,OP_CHUNK_SIZE_MAX); - /*If we did find a page from another stream or without a timestamp, - don't read past it.*/ - boundary=next_boundary; - } - } - else{ - ogg_int64_t gp; - int has_packets; - /*Save the offset of the first page we found after the seek, regardless - of the stream it came from or whether or not it has a timestamp.*/ - next_boundary=OP_MIN(page_offset,next_boundary); - if(serialno!=(ogg_uint32_t)ogg_page_serialno(&og))continue; - has_packets=ogg_page_packets(&og)>0; - /*Force the gp to -1 (as it should be per spec) if no packets end on - this page. - Otherwise we might get confused when we try to pull out a packet - with that timestamp and can't find it.*/ - gp=has_packets?ogg_page_granulepos(&og):-1; - if(gp==-1){ - if(buffering){ - if(OP_LIKELY(!has_packets))ogg_stream_pagein(&_of->os,&og); - else{ - /*If packets did end on this page, but we still didn't have a - valid granule position (in violation of the spec!), stop - buffering continued packet data. - Otherwise we might continue past the packet we actually - wanted.*/ - ogg_stream_reset(&_of->os); - buffering=0; - } - } - continue; - } - if(op_granpos_cmp(gp,_target_gp)<0){ - /*We found a page that ends before our target. - Advance to the raw offset of the next page.*/ - begin=_of->offset; - if(OP_UNLIKELY(op_granpos_cmp(pcm_start,gp)>0) - ||OP_UNLIKELY(op_granpos_cmp(pcm_end,gp)<0)){ - /*Don't let pcm_start get out of range! - That could happen with an invalid timestamp.*/ - break; - } - /*Save the byte offset of the end of the page with this granule - position.*/ - best=best_start=begin; - /*Buffer any data from a continued packet, if necessary. - This avoids the need to seek back here if the next timestamp we - encounter while scanning forward lies after our target.*/ - if(buffering)ogg_stream_reset(&_of->os); - if(op_page_continues(&og)){ - op_buffer_continued_data(_of,&og); - /*If we have a continued packet, remember the offset of this - page's start, so that if we do wind up having to seek back here - later, we can prime the stream with the continued packet data. - With no continued packet, we remember the end of the page.*/ - best_start=page_offset; - } - /*Then force buffering on, so that if a packet starts (but does not - end) on the next page, we still avoid the extra seek back.*/ - buffering=1; - best_gp=pcm_start=gp; - OP_ALWAYS_TRUE(!op_granpos_diff(&diff,_target_gp,pcm_start)); - /*If we're more than a second away from our target, break out and - do another bisection.*/ - if(diff>48000)break; - /*Otherwise, keep scanning forward (do NOT use begin+1).*/ - bisect=begin; - } - else{ - /*We found a page that ends after our target.*/ - /*If we scanned the whole interval before we found it, we're done.*/ - if(bisect<=begin+1)end=begin; - else{ - end=bisect; - /*In later iterations, don't read past the first page we found.*/ - boundary=next_boundary; - /*If we're not making much progress shrinking the interval size, - start forcing straight bisection to limit the worst case.*/ - force_bisect=end-begin>d0*2; - /*Don't let pcm_end get out of range! - That could happen with an invalid timestamp.*/ - if(OP_LIKELY(op_granpos_cmp(pcm_end,gp)>0) - &&OP_LIKELY(op_granpos_cmp(pcm_start,gp)<=0)){ - pcm_end=gp; - } - break; - } - } - } - } - } - /*Found our page.*/ - OP_ASSERT(op_granpos_cmp(best_gp,pcm_start)>=0); - /*Seek, if necessary. - If we were buffering data from a continued packet, we should be able to - continue to scan forward to get the rest of the data (even if - page_offset==-1). - Otherwise, we need to seek back to best_start.*/ - if(!buffering){ - if(best_start!=page_offset){ - page_offset=-1; - ret=op_seek_helper(_of,best_start); - if(OP_UNLIKELY(ret<0))return ret; - } - if(best_startend_offset); - if(OP_UNLIKELY(page_offsetprev_packet_gp=best_gp; - _of->prev_page_offset=best_start; - ret=op_fetch_and_process_page(_of,page_offset<0?NULL:&og,page_offset,0,1); - if(OP_UNLIKELY(ret<0))return OP_EBADLINK; - /*Verify result.*/ - if(OP_UNLIKELY(op_granpos_cmp(_of->prev_packet_gp,_target_gp)>0)){ - return OP_EBADLINK; - } - /*Our caller will set cur_discard_count to handle pre-roll.*/ - return 0; -} - -int op_pcm_seek(OggOpusFile *_of,ogg_int64_t _pcm_offset){ - const OggOpusLink *link; - ogg_int64_t pcm_start; - ogg_int64_t target_gp; - ogg_int64_t prev_packet_gp; - ogg_int64_t skip; - ogg_int64_t diff; - int op_count; - int op_pos; - int ret; - int li; - if(OP_UNLIKELY(_of->ready_stateseekable))return OP_ENOSEEK; - if(OP_UNLIKELY(_pcm_offset<0))return OP_EINVAL; - target_gp=op_get_granulepos(_of,_pcm_offset,&li); - if(OP_UNLIKELY(target_gp==-1))return OP_EINVAL; - link=_of->links+li; - pcm_start=link->pcm_start; - OP_ALWAYS_TRUE(!op_granpos_diff(&_pcm_offset,target_gp,pcm_start)); -#if !defined(OP_SMALL_FOOTPRINT) - /*For small (90 ms or less) forward seeks within the same link, just decode - forward. - This also optimizes the case of seeking to the current position.*/ - if(li==_of->cur_link&&_of->ready_state>=OP_INITSET){ - ogg_int64_t gp; - gp=_of->prev_packet_gp; - if(OP_LIKELY(gp!=-1)){ - ogg_int64_t discard_count; - int nbuffered; - nbuffered=OP_MAX(_of->od_buffer_size-_of->od_buffer_pos,0); - OP_ALWAYS_TRUE(!op_granpos_add(&gp,gp,-nbuffered)); - /*We do _not_ add cur_discard_count to gp. - Otherwise the total amount to discard could grow without bound, and it - would be better just to do a full seek.*/ - if(OP_LIKELY(!op_granpos_diff(&discard_count,target_gp,gp))){ - /*We use a threshold of 90 ms instead of 80, since 80 ms is the - _minimum_ we would have discarded after a full seek. - Assuming 20 ms frames (the default), we'd discard 90 ms on average.*/ - if(discard_count>=0&&OP_UNLIKELY(discard_count<90*48)){ - _of->cur_discard_count=(opus_int32)discard_count; - return 0; - } - } - } - } -#endif - ret=op_pcm_seek_page(_of,target_gp,li); - if(OP_UNLIKELY(ret<0))return ret; - /*Now skip samples until we actually get to our target.*/ - /*Figure out where we should skip to.*/ - if(_pcm_offset<=link->head.pre_skip)skip=0; - else skip=OP_MAX(_pcm_offset-80*48,0); - OP_ASSERT(_pcm_offset-skip>=0); - OP_ASSERT(_pcm_offset-skipop_count; - prev_packet_gp=_of->prev_packet_gp; - for(op_pos=_of->op_pos;op_posop[op_pos].granulepos; - if(OP_LIKELY(!op_granpos_diff(&diff,cur_packet_gp,pcm_start)) - &&diff>skip){ - break; - } - prev_packet_gp=cur_packet_gp; - } - _of->prev_packet_gp=prev_packet_gp; - _of->op_pos=op_pos; - if(op_posskip - ||_pcm_offset-diff>=OP_INT32_MAX){ - return OP_EBADLINK; - } - /*TODO: If there are further holes/illegal timestamps, we still won't decode - to the correct sample. - However, at least op_pcm_tell() will report the correct value immediately - after returning.*/ - _of->cur_discard_count=(opus_int32)(_pcm_offset-diff); - return 0; -} - -opus_int64 op_raw_tell(const OggOpusFile *_of){ - if(OP_UNLIKELY(_of->ready_stateoffset; -} - -/*Convert a granule position from a given link to a PCM offset relative to the - start of the whole stream. - For unseekable sources, this gets reset to 0 at the beginning of each link.*/ -static ogg_int64_t op_get_pcm_offset(const OggOpusFile *_of, - ogg_int64_t _gp,int _li){ - const OggOpusLink *links; - ogg_int64_t pcm_offset; - links=_of->links; - OP_ASSERT(_li>=0&&_li<_of->nlinks); - pcm_offset=links[_li].pcm_file_offset; - if(_of->seekable&&OP_UNLIKELY(op_granpos_cmp(_gp,links[_li].pcm_end)>0)){ - _gp=links[_li].pcm_end; - } - if(OP_LIKELY(op_granpos_cmp(_gp,links[_li].pcm_start)>0)){ - ogg_int64_t delta; - if(OP_UNLIKELY(op_granpos_diff(&delta,_gp,links[_li].pcm_start)<0)){ - /*This means an unseekable stream claimed to have a page from more than - 2 billion days after we joined.*/ - OP_ASSERT(!_of->seekable); - return OP_INT64_MAX; - } - if(deltaready_stateprev_packet_gp; - if(gp==-1)return 0; - nbuffered=OP_MAX(_of->od_buffer_size-_of->od_buffer_pos,0); - OP_ALWAYS_TRUE(!op_granpos_add(&gp,gp,-nbuffered)); - li=_of->seekable?_of->cur_link:0; - if(op_granpos_add(&gp,gp,_of->cur_discard_count)<0){ - gp=_of->links[li].pcm_end; - } - return op_get_pcm_offset(_of,gp,li); -} - -void op_set_decode_callback(OggOpusFile *_of, - op_decode_cb_func _decode_cb,void *_ctx){ - _of->decode_cb=_decode_cb; - _of->decode_cb_ctx=_ctx; -} - -int op_set_gain_offset(OggOpusFile *_of, - int _gain_type,opus_int32 _gain_offset_q8){ - if(_gain_type!=OP_HEADER_GAIN&&_gain_type!=OP_ALBUM_GAIN - &&_gain_type!=OP_TRACK_GAIN&&_gain_type!=OP_ABSOLUTE_GAIN){ - return OP_EINVAL; - } - _of->gain_type=_gain_type; - /*The sum of header gain and track gain lies in the range [-65536,65534]. - These bounds allow the offset to set the final value to anywhere in the - range [-32768,32767], which is what we'll clamp it to before applying.*/ - _of->gain_offset_q8=OP_CLAMP(-98302,_gain_offset_q8,98303); - op_update_gain(_of); - return 0; -} - -void op_set_dither_enabled(OggOpusFile *_of,int _enabled){ -#if !defined(OP_FIXED_POINT) - _of->dither_disabled=!_enabled; - if(!_enabled)_of->dither_mute=65; -#else - (void) _of; - (void) _enabled; -#endif -} - -/*Allocate the decoder scratch buffer. - This is done lazily, since if the user provides large enough buffers, we'll - never need it.*/ -static int op_init_buffer(OggOpusFile *_of){ - int nchannels_max; - if(_of->seekable){ - const OggOpusLink *links; - int nlinks; - int li; - links=_of->links; - nlinks=_of->nlinks; - nchannels_max=1; - for(li=0;liod_buffer=(op_sample *)_ogg_malloc( - sizeof(*_of->od_buffer)*nchannels_max*120*48); - if(_of->od_buffer==NULL)return OP_EFAULT; - return 0; -} - -/*Decode a single packet into the target buffer.*/ -static int op_decode(OggOpusFile *_of,op_sample *_pcm, - const ogg_packet *_op,int _nsamples,int _nchannels){ - int ret; - /*First we try using the application-provided decode callback.*/ - if(_of->decode_cb!=NULL){ -#if defined(OP_FIXED_POINT) - ret=(*_of->decode_cb)(_of->decode_cb_ctx,_of->od,_pcm,_op, - _nsamples,_nchannels,OP_DEC_FORMAT_SHORT,_of->cur_link); -#else - ret=(*_of->decode_cb)(_of->decode_cb_ctx,_of->od,_pcm,_op, - _nsamples,_nchannels,OP_DEC_FORMAT_FLOAT,_of->cur_link); -#endif - } - else ret=OP_DEC_USE_DEFAULT; - /*If the application didn't want to handle decoding, do it ourselves.*/ - if(ret==OP_DEC_USE_DEFAULT){ -#if defined(OP_FIXED_POINT) - ret=opus_multistream_decode(_of->od, - _op->packet,_op->bytes,_pcm,_nsamples,0); -#else - ret=opus_multistream_decode_float(_of->od, - _op->packet,_op->bytes,_pcm,_nsamples,0); -#endif - OP_ASSERT(ret<0||ret==_nsamples); - } - /*If the application returned a positive value other than 0 or - OP_DEC_USE_DEFAULT, fail.*/ - else if(OP_UNLIKELY(ret>0))return OP_EBADPACKET; - if(OP_UNLIKELY(ret<0))return OP_EBADPACKET; - return ret; -} - -/*Read more samples from the stream, using the same API as op_read() or - op_read_float().*/ -static int op_read_native(OggOpusFile *_of, - op_sample *_pcm,int _buf_size,int *_li){ - if(OP_UNLIKELY(_of->ready_stateready_state>=OP_INITSET)){ - int nchannels; - int od_buffer_pos; - int nsamples; - int op_pos; - nchannels=_of->links[_of->seekable?_of->cur_link:0].head.channel_count; - od_buffer_pos=_of->od_buffer_pos; - nsamples=_of->od_buffer_size-od_buffer_pos; - /*If we have buffered samples, return them.*/ - if(nsamples>0){ - if(nsamples*nchannels>_buf_size)nsamples=_buf_size/nchannels; - OP_ASSERT(_pcm!=NULL||nsamples<=0); - /*Check nsamples again so we don't pass NULL to memcpy() if _buf_size - is zero. - That would technically be undefined behavior, even if the number of - bytes to copy were zero.*/ - if(nsamples>0){ - memcpy(_pcm,_of->od_buffer+nchannels*od_buffer_pos, - sizeof(*_pcm)*nchannels*nsamples); - od_buffer_pos+=nsamples; - _of->od_buffer_pos=od_buffer_pos; - } - if(_li!=NULL)*_li=_of->cur_link; - return nsamples; - } - /*If we have buffered packets, decode one.*/ - op_pos=_of->op_pos; - if(OP_LIKELY(op_pos<_of->op_count)){ - const ogg_packet *pop; - ogg_int64_t diff; - opus_int32 cur_discard_count; - int duration; - int trimmed_duration; - pop=_of->op+op_pos++; - _of->op_pos=op_pos; - cur_discard_count=_of->cur_discard_count; - duration=op_get_packet_duration(pop->packet,pop->bytes); - /*We don't buffer packets with an invalid TOC sequence.*/ - OP_ASSERT(duration>0); - trimmed_duration=duration; - /*Perform end-trimming.*/ - if(OP_UNLIKELY(pop->e_o_s)){ - if(OP_UNLIKELY(op_granpos_cmp(pop->granulepos, - _of->prev_packet_gp)<=0)){ - trimmed_duration=0; - } - else if(OP_LIKELY(!op_granpos_diff(&diff, - pop->granulepos,_of->prev_packet_gp))){ - trimmed_duration=(int)OP_MIN(diff,trimmed_duration); - } - } - _of->prev_packet_gp=pop->granulepos; - if(OP_UNLIKELY(duration*nchannels>_buf_size)){ - op_sample *buf; - /*If the user's buffer is too small, decode into a scratch buffer.*/ - buf=_of->od_buffer; - if(OP_UNLIKELY(buf==NULL)){ - ret=op_init_buffer(_of); - if(OP_UNLIKELY(ret<0))return ret; - buf=_of->od_buffer; - } - ret=op_decode(_of,buf,pop,duration,nchannels); - if(OP_UNLIKELY(ret<0))return ret; - /*Perform pre-skip/pre-roll.*/ - od_buffer_pos=(int)OP_MIN(trimmed_duration,cur_discard_count); - cur_discard_count-=od_buffer_pos; - _of->cur_discard_count=cur_discard_count; - _of->od_buffer_pos=od_buffer_pos; - _of->od_buffer_size=trimmed_duration; - /*Update bitrate tracking based on the actual samples we used from - what was decoded.*/ - _of->bytes_tracked+=pop->bytes; - _of->samples_tracked+=trimmed_duration-od_buffer_pos; - } - else{ - OP_ASSERT(_pcm!=NULL); - /*Otherwise decode directly into the user's buffer.*/ - ret=op_decode(_of,_pcm,pop,duration,nchannels); - if(OP_UNLIKELY(ret<0))return ret; - if(OP_LIKELY(trimmed_duration>0)){ - /*Perform pre-skip/pre-roll.*/ - od_buffer_pos=(int)OP_MIN(trimmed_duration,cur_discard_count); - cur_discard_count-=od_buffer_pos; - _of->cur_discard_count=cur_discard_count; - trimmed_duration-=od_buffer_pos; - if(OP_LIKELY(trimmed_duration>0) - &&OP_UNLIKELY(od_buffer_pos>0)){ - memmove(_pcm,_pcm+od_buffer_pos*nchannels, - sizeof(*_pcm)*trimmed_duration*nchannels); - } - /*Update bitrate tracking based on the actual samples we used from - what was decoded.*/ - _of->bytes_tracked+=pop->bytes; - _of->samples_tracked+=trimmed_duration; - if(OP_LIKELY(trimmed_duration>0)){ - if(_li!=NULL)*_li=_of->cur_link; - return trimmed_duration; - } - } - } - /*Don't grab another page yet. - This one might have more packets, or might have buffered data now.*/ - continue; - } - } - /*Suck in another page.*/ - ret=op_fetch_and_process_page(_of,NULL,-1,1,0); - if(OP_UNLIKELY(ret==OP_EOF)){ - if(_li!=NULL)*_li=_of->cur_link; - return 0; - } - if(OP_UNLIKELY(ret<0))return ret; - } -} - -/*A generic filter to apply to the decoded audio data. - _src is non-const because we will destructively modify the contents of the - source buffer that we consume in some cases.*/ -typedef int (*op_read_filter_func)(OggOpusFile *_of,void *_dst,int _dst_sz, - op_sample *_src,int _nsamples,int _nchannels); - -/*Decode some samples and then apply a custom filter to them. - This is used to convert to different output formats.*/ -static int op_filter_read_native(OggOpusFile *_of,void *_dst,int _dst_sz, - op_read_filter_func _filter,int *_li){ - int ret; - /*Ensure we have some decoded samples in our buffer.*/ - ret=op_read_native(_of,NULL,0,_li); - /*Now apply the filter to them.*/ - if(OP_LIKELY(ret>=0)&&OP_LIKELY(_of->ready_state>=OP_INITSET)){ - int od_buffer_pos; - od_buffer_pos=_of->od_buffer_pos; - ret=_of->od_buffer_size-od_buffer_pos; - if(OP_LIKELY(ret>0)){ - int nchannels; - nchannels=_of->links[_of->seekable?_of->cur_link:0].head.channel_count; - ret=(*_filter)(_of,_dst,_dst_sz, - _of->od_buffer+nchannels*od_buffer_pos,ret,nchannels); - OP_ASSERT(ret>=0); - OP_ASSERT(ret<=_of->od_buffer_size-od_buffer_pos); - od_buffer_pos+=ret; - _of->od_buffer_pos=od_buffer_pos; - } - } - return ret; -} - -#if !defined(OP_FIXED_POINT)||!defined(OP_DISABLE_FLOAT_API) - -/*Matrices for downmixing from the supported channel counts to stereo. - The matrices with 5 or more channels are normalized to a total volume of 2.0, - since most mixes sound too quiet if normalized to 1.0 (as there is generally - little volume in the side/rear channels).*/ -static const float OP_STEREO_DOWNMIX[OP_NCHANNELS_MAX-2][OP_NCHANNELS_MAX][2]={ - /*3.0*/ - { - {0.5858F,0.0F},{0.4142F,0.4142F},{0.0F,0.5858F} - }, - /*quadrophonic*/ - { - {0.4226F,0.0F},{0.0F,0.4226F},{0.366F,0.2114F},{0.2114F,0.336F} - }, - /*5.0*/ - { - {0.651F,0.0F},{0.46F,0.46F},{0.0F,0.651F},{0.5636F,0.3254F}, - {0.3254F,0.5636F} - }, - /*5.1*/ - { - {0.529F,0.0F},{0.3741F,0.3741F},{0.0F,0.529F},{0.4582F,0.2645F}, - {0.2645F,0.4582F},{0.3741F,0.3741F} - }, - /*6.1*/ - { - {0.4553F,0.0F},{0.322F,0.322F},{0.0F,0.4553F},{0.3943F,0.2277F}, - {0.2277F,0.3943F},{0.2788F,0.2788F},{0.322F,0.322F} - }, - /*7.1*/ - { - {0.3886F,0.0F},{0.2748F,0.2748F},{0.0F,0.3886F},{0.3366F,0.1943F}, - {0.1943F,0.3366F},{0.3366F,0.1943F},{0.1943F,0.3366F},{0.2748F,0.2748F} - } -}; - -#endif - -#if defined(OP_FIXED_POINT) -#if 0 -/*Matrices for downmixing from the supported channel counts to stereo. - The matrices with 5 or more channels are normalized to a total volume of 2.0, - since most mixes sound too quiet if normalized to 1.0 (as there is generally - little volume in the side/rear channels). - Hence we keep the coefficients in Q14, so the downmix values won't overflow a - 32-bit number.*/ -static const opus_int16 OP_STEREO_DOWNMIX_Q14 - [OP_NCHANNELS_MAX-2][OP_NCHANNELS_MAX][2]={ - /*3.0*/ - { - {9598,0},{6786,6786},{0,9598} - }, - /*quadrophonic*/ - { - {6924,0},{0,6924},{5996,3464},{3464,5996} - }, - /*5.0*/ - { - {10666,0},{7537,7537},{0,10666},{9234,5331},{5331,9234} - }, - /*5.1*/ - { - {8668,0},{6129,6129},{0,8668},{7507,4335},{4335,7507},{6129,6129} - }, - /*6.1*/ - { - {7459,0},{5275,5275},{0,7459},{6460,3731},{3731,6460},{4568,4568}, - {5275,5275} - }, - /*7.1*/ - { - {6368,0},{4502,4502},{0,6368},{5515,3183},{3183,5515},{5515,3183}, - {3183,5515},{4502,4502} - } -}; -#endif -int op_read(OggOpusFile *_of,opus_int16 *_pcm,int _buf_size,int *_li){ - return op_read_native(_of,_pcm,_buf_size,_li); -} - -static int op_stereo_filter(OggOpusFile *_of,void *_dst,int _dst_sz, - op_sample *_src,int _nsamples,int _nchannels){ - (void)_of; - _nsamples=OP_MIN(_nsamples,_dst_sz>>1); - if(_nchannels==2)memcpy(_dst,_src,_nsamples*2*sizeof(*_src)); - else{ - opus_int16 *dst; - int i; - dst=(opus_int16 *)_dst; - if(_nchannels==1){ - for(i=0;i<_nsamples;i++)dst[2*i+0]=dst[2*i+1]=_src[i]; - } - else{ -#if 0 - for(i=0;i<_nsamples;i++){ - opus_int32 l; - opus_int32 r; - int ci; - l=r=0; - for(ci=0;ci<_nchannels;ci++){ - opus_int32 s; - s=_src[_nchannels*i+ci]; - l+=OP_STEREO_DOWNMIX_Q14[_nchannels-3][ci][0]*s; - r+=OP_STEREO_DOWNMIX_Q14[_nchannels-3][ci][1]*s; - } - /*TODO: For 5 or more channels, we should do soft clipping here.*/ - dst[2*i+0]=(opus_int16)OP_CLAMP(-32768,l+8192>>14,32767); - dst[2*i+1]=(opus_int16)OP_CLAMP(-32768,r+8192>>14,32767); - } -#endif - // noop, removed for RAM savings - } - } - return _nsamples; -} - -int op_read_stereo(OggOpusFile *_of,opus_int16 *_pcm,int _buf_size){ - return op_filter_read_native(_of,_pcm,_buf_size,op_stereo_filter,NULL); -} - -# if !defined(OP_DISABLE_FLOAT_API) - -static int op_short2float_filter(OggOpusFile *_of,void *_dst,int _dst_sz, - op_sample *_src,int _nsamples,int _nchannels){ - float *dst; - int i; - (void)_of; - dst=(float *)_dst; - if(OP_UNLIKELY(_nsamples*_nchannels>_dst_sz))_nsamples=_dst_sz/_nchannels; - _dst_sz=_nsamples*_nchannels; - for(i=0;i<_dst_sz;i++)dst[i]=(1.0F/32768)*_src[i]; - return _nsamples; -} - -int op_read_float(OggOpusFile *_of,float *_pcm,int _buf_size,int *_li){ - return op_filter_read_native(_of,_pcm,_buf_size,op_short2float_filter,_li); -} - -static int op_short2float_stereo_filter(OggOpusFile *_of, - void *_dst,int _dst_sz,op_sample *_src,int _nsamples,int _nchannels){ - float *dst; - int i; - dst=(float *)_dst; - _nsamples=OP_MIN(_nsamples,_dst_sz>>1); - if(_nchannels==1){ - _nsamples=op_short2float_filter(_of,dst,_nsamples,_src,_nsamples,1); - for(i=_nsamples;i-->0;)dst[2*i+0]=dst[2*i+1]=dst[i]; - } - else if(_nchannels<5){ - /*For 3 or 4 channels, we can downmix in fixed point without risk of - clipping.*/ - if(_nchannels>2){ - _nsamples=op_stereo_filter(_of,_src,_nsamples*2, - _src,_nsamples,_nchannels); - } - return op_short2float_filter(_of,dst,_dst_sz,_src,_nsamples,2); - } - else{ - /*For 5 or more channels, we convert to floats and then downmix (so that we - don't risk clipping).*/ - for(i=0;i<_nsamples;i++){ - float l; - float r; - int ci; - l=r=0; - for(ci=0;ci<_nchannels;ci++){ - float s; - s=(1.0F/32768)*_src[_nchannels*i+ci]; - l+=OP_STEREO_DOWNMIX[_nchannels-3][ci][0]*s; - r+=OP_STEREO_DOWNMIX[_nchannels-3][ci][1]*s; - } - dst[2*i+0]=l; - dst[2*i+1]=r; - } - } - return _nsamples; -} - -int op_read_float_stereo(OggOpusFile *_of,float *_pcm,int _buf_size){ - return op_filter_read_native(_of,_pcm,_buf_size, - op_short2float_stereo_filter,NULL); -} - -# endif - -#else - -# if defined(OP_HAVE_LRINTF) -# include -# define op_float2int(_x) (lrintf(_x)) -# else -# define op_float2int(_x) ((int)((_x)+((_x)<0?-0.5F:0.5F))) -# endif - -/*The dithering code here is adapted from opusdec, part of opus-tools. - It was originally written by Greg Maxwell.*/ - -static opus_uint32 op_rand(opus_uint32 _seed){ - return _seed*96314165+907633515&0xFFFFFFFFU; -} - -/*This implements 16-bit quantization with full triangular dither and IIR noise - shaping. - The noise shaping filters were designed by Sebastian Gesemann, and are based - on the LAME ATH curves with flattening to limit their peak gain to 20 dB. - Everyone else's noise shaping filters are mildly crazy. - The 48 kHz version of this filter is just a warped version of the 44.1 kHz - filter and probably could be improved by shifting the HF shelf up in - frequency a little bit, since 48 kHz has a bit more room and being more - conservative against bat-ears is probably more important than more noise - suppression. - This process can increase the peak level of the signal (in theory by the peak - error of 1.5 +20 dB, though that is unobservably rare). - To avoid clipping, the signal is attenuated by a couple thousandths of a dB. - Initially, the approach taken here was to only attenuate by the 99.9th - percentile, making clipping rare but not impossible (like SoX), but the - limited gain of the filter means that the worst case was only two - thousandths of a dB more, so this just uses the worst case. - The attenuation is probably also helpful to prevent clipping in the DAC - reconstruction filters or downstream resampling, in any case.*/ - -# define OP_GAIN (32753.0F) - -# define OP_PRNG_GAIN (1.0F/(float)0xFFFFFFFF) - -/*48 kHz noise shaping filter, sd=2.34.*/ - -static const float OP_FCOEF_B[4]={ - 2.2374F,-0.7339F,-0.1251F,-0.6033F -}; - -static const float OP_FCOEF_A[4]={ - 0.9030F,0.0116F,-0.5853F,-0.2571F -}; - -static int op_float2short_filter(OggOpusFile *_of,void *_dst,int _dst_sz, - float *_src,int _nsamples,int _nchannels){ - opus_int16 *dst; - int ci; - int i; - dst=(opus_int16 *)_dst; - if(OP_UNLIKELY(_nsamples*_nchannels>_dst_sz))_nsamples=_dst_sz/_nchannels; -# if defined(OP_SOFT_CLIP) - if(_of->state_channel_count!=_nchannels){ - for(ci=0;ci<_nchannels;ci++)_of->clip_state[ci]=0; - } - opus_pcm_soft_clip(_src,_nsamples,_nchannels,_of->clip_state); -# endif - if(_of->dither_disabled){ - for(i=0;i<_nchannels*_nsamples;i++){ - dst[i]=op_float2int(OP_CLAMP(-32768,32768.0F*_src[i],32767)); - } - } - else{ - opus_uint32 seed; - int mute; - seed=_of->dither_seed; - mute=_of->dither_mute; - if(_of->state_channel_count!=_nchannels)mute=65; - /*In order to avoid replacing digital silence with quiet dither noise, we - mute if the output has been silent for a while.*/ - if(mute>64)memset(_of->dither_a,0,sizeof(*_of->dither_a)*4*_nchannels); - for(i=0;i<_nsamples;i++){ - int silent; - silent=1; - for(ci=0;ci<_nchannels;ci++){ - float r; - float s; - float err; - int si; - int j; - s=_src[_nchannels*i+ci]; - silent&=s==0; - s*=OP_GAIN; - err=0; - for(j=0;j<4;j++){ - err+=OP_FCOEF_B[j]*_of->dither_b[ci*4+j] - -OP_FCOEF_A[j]*_of->dither_a[ci*4+j]; - } - for(j=3;j-->0;)_of->dither_a[ci*4+j+1]=_of->dither_a[ci*4+j]; - for(j=3;j-->0;)_of->dither_b[ci*4+j+1]=_of->dither_b[ci*4+j]; - _of->dither_a[ci*4]=err; - s-=err; - if(mute>16)r=0; - else{ - seed=op_rand(seed); - r=seed*OP_PRNG_GAIN; - seed=op_rand(seed); - r-=seed*OP_PRNG_GAIN; - } - /*Clamp in float out of paranoia that the input will be > 96 dBFS and - wrap if the integer is clamped.*/ - si=op_float2int(OP_CLAMP(-32768,s+r,32767)); - dst[_nchannels*i+ci]=(opus_int16)si; - /*Including clipping in the noise shaping is generally disastrous: the - futile effort to restore the clipped energy results in more clipping. - However, small amounts---at the level which could normally be created - by dither and rounding---are harmless and can even reduce clipping - somewhat due to the clipping sometimes reducing the dither + rounding - error.*/ - _of->dither_b[ci*4]=mute>16?0:OP_CLAMP(-1.5F,si-s,1.5F); - } - mute++; - if(!silent)mute=0; - } - _of->dither_mute=OP_MIN(mute,65); - _of->dither_seed=seed; - } - _of->state_channel_count=_nchannels; - return _nsamples; -} - -int op_read(OggOpusFile *_of,opus_int16 *_pcm,int _buf_size,int *_li){ - return op_filter_read_native(_of,_pcm,_buf_size,op_float2short_filter,_li); -} - -int op_read_float(OggOpusFile *_of,float *_pcm,int _buf_size,int *_li){ - _of->state_channel_count=0; - return op_read_native(_of,_pcm,_buf_size,_li); -} - -static int op_stereo_filter(OggOpusFile *_of,void *_dst,int _dst_sz, - op_sample *_src,int _nsamples,int _nchannels){ - (void)_of; - _nsamples=OP_MIN(_nsamples,_dst_sz>>1); - if(_nchannels==2)memcpy(_dst,_src,_nsamples*2*sizeof(*_src)); - else{ - float *dst; - int i; - dst=(float *)_dst; - if(_nchannels==1){ - for(i=0;i<_nsamples;i++)dst[2*i+0]=dst[2*i+1]=_src[i]; - } - else{ - for(i=0;i<_nsamples;i++){ - float l; - float r; - int ci; - l=r=0; - for(ci=0;ci<_nchannels;ci++){ - l+=OP_STEREO_DOWNMIX[_nchannels-3][ci][0]*_src[_nchannels*i+ci]; - r+=OP_STEREO_DOWNMIX[_nchannels-3][ci][1]*_src[_nchannels*i+ci]; - } - dst[2*i+0]=l; - dst[2*i+1]=r; - } - } - } - return _nsamples; -} - -static int op_float2short_stereo_filter(OggOpusFile *_of, - void *_dst,int _dst_sz,op_sample *_src,int _nsamples,int _nchannels){ - opus_int16 *dst; - dst=(opus_int16 *)_dst; - if(_nchannels==1){ - int i; - _nsamples=op_float2short_filter(_of,dst,_dst_sz>>1,_src,_nsamples,1); - for(i=_nsamples;i-->0;)dst[2*i+0]=dst[2*i+1]=dst[i]; - } - else{ - if(_nchannels>2){ - _nsamples=OP_MIN(_nsamples,_dst_sz>>1); - _nsamples=op_stereo_filter(_of,_src,_nsamples*2, - _src,_nsamples,_nchannels); - } - _nsamples=op_float2short_filter(_of,dst,_dst_sz,_src,_nsamples,2); - } - return _nsamples; -} - -int op_read_stereo(OggOpusFile *_of,opus_int16 *_pcm,int _buf_size){ - return op_filter_read_native(_of,_pcm,_buf_size, - op_float2short_stereo_filter,NULL); -} - -int op_read_float_stereo(OggOpusFile *_of,float *_pcm,int _buf_size){ - _of->state_channel_count=0; - return op_filter_read_native(_of,_pcm,_buf_size,op_stereo_filter,NULL); -} - -#endif diff --git a/src/opusfile/opusfile.h b/src/opusfile/opusfile.h deleted file mode 100644 index 7a645724..00000000 --- a/src/opusfile/opusfile.h +++ /dev/null @@ -1,2164 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE libopusfile SOURCE CODE IS (C) COPYRIGHT 1994-2012 * - * by the Xiph.Org Foundation and contributors https://xiph.org/ * - * * - ******************************************************************** - - function: stdio-based convenience library for opening/seeking/decoding - last mod: $Id: vorbisfile.h 17182 2010-04-29 03:48:32Z xiphmont $ - - ********************************************************************/ -#if !defined(_opusfile_h) -# define _opusfile_h (1) - -/**\mainpage - \section Introduction - - This is the documentation for the libopusfile C API. - - The libopusfile package provides a convenient high-level API for - decoding and basic manipulation of all Ogg Opus audio streams. - libopusfile is implemented as a layer on top of Xiph.Org's - reference - libogg - and - libopus - libraries. - - libopusfile provides several sets of built-in routines for - file/stream access, and may also use custom stream I/O routines provided by - the embedded environment. - There are built-in I/O routines provided for ANSI-compliant - stdio (FILE *), memory buffers, and URLs - (including URLs, plus optionally and URLs). - - \section Organization - - The main API is divided into several sections: - - \ref stream_open_close - - \ref stream_info - - \ref stream_decoding - - \ref stream_seeking - - Several additional sections are not tied to the main API. - - \ref stream_callbacks - - \ref header_info - - \ref error_codes - - \section Overview - - The libopusfile API always decodes files to 48 kHz. - The original sample rate is not preserved by the lossy compression, though - it is stored in the header to allow you to resample to it after decoding - (the libopusfile API does not currently provide a resampler, - but the - the - Speex resampler is a good choice if you need one). - In general, if you are playing back the audio, you should leave it at - 48 kHz, provided your audio hardware supports it. - When decoding to a file, it may be worth resampling back to the original - sample rate, so as not to surprise users who might not expect the sample - rate to change after encoding to Opus and decoding. - - Opus files can contain anywhere from 1 to 255 channels of audio. - The channel mappings for up to 8 channels are the same as the - Vorbis - mappings. - A special stereo API can convert everything to 2 channels, making it simple - to support multichannel files in an application which only has stereo - output. - Although the libopusfile ABI provides support for the theoretical - maximum number of channels, the current implementation does not support - files with more than 8 channels, as they do not have well-defined channel - mappings. - - Like all Ogg files, Opus files may be "chained". - That is, multiple Opus files may be combined into a single, longer file just - by concatenating the original files. - This is commonly done in internet radio streaming, as it allows the title - and artist to be updated each time the song changes, since each link in the - chain includes its own set of metadata. - - libopusfile fully supports chained files. - It will decode the first Opus stream found in each link of a chained file - (ignoring any other streams that might be concurrently multiplexed with it, - such as a video stream). - - The channel count can also change between links. - If your application is not prepared to deal with this, it can use the stereo - API to ensure the audio from all links will always get decoded into a - common format. - Since libopusfile always decodes to 48 kHz, you do not have to - worry about the sample rate changing between links (as was possible with - Vorbis). - This makes application support for chained files with libopusfile - very easy.*/ - -# if defined(__cplusplus) -extern "C" { -# endif - -# include -# include -# include "../libogg/ogg/ogg.h" -# include "../libopus/opus_multistream.h" - -/**@cond PRIVATE*/ - -/*Enable special features for gcc and gcc-compatible compilers.*/ -# if !defined(OP_GNUC_PREREQ) -# if defined(__GNUC__)&&defined(__GNUC_MINOR__) -# define OP_GNUC_PREREQ(_maj,_min) \ - ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) -# else -# define OP_GNUC_PREREQ(_maj,_min) 0 -# endif -# endif - -# if OP_GNUC_PREREQ(4,0) -# pragma GCC visibility push(default) -# endif - -typedef struct OpusHead OpusHead; -typedef struct OpusTags OpusTags; -typedef struct OpusPictureTag OpusPictureTag; -typedef struct OpusServerInfo OpusServerInfo; -typedef struct OpusFileCallbacks OpusFileCallbacks; -typedef struct OggOpusFile OggOpusFile; - -/*Warning attributes for libopusfile functions.*/ -# if OP_GNUC_PREREQ(3,4) -# define OP_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) -# else -# define OP_WARN_UNUSED_RESULT -# endif -# if OP_GNUC_PREREQ(3,4) -# define OP_ARG_NONNULL(_x) __attribute__((__nonnull__(_x))) -# else -# define OP_ARG_NONNULL(_x) -# endif - -/**@endcond*/ - -/**\defgroup error_codes Error Codes*/ -/*@{*/ -/**\name List of possible error codes - Many of the functions in this library return a negative error code when a - function fails. - This list provides a brief explanation of the common errors. - See each individual function for more details on what a specific error code - means in that context.*/ -/*@{*/ - -/**A request did not succeed.*/ -#define OP_FALSE (-1) -/*Currently not used externally.*/ -#define OP_EOF (-2) -/**There was a hole in the page sequence numbers (e.g., a page was corrupt or - missing).*/ -#define OP_HOLE (-3) -/**An underlying read, seek, or tell operation failed when it should have - succeeded.*/ -#define OP_EREAD (-128) -/**A NULL pointer was passed where one was unexpected, or an - internal memory allocation failed, or an internal library error was - encountered.*/ -#define OP_EFAULT (-129) -/**The stream used a feature that is not implemented, such as an unsupported - channel family.*/ -#define OP_EIMPL (-130) -/**One or more parameters to a function were invalid.*/ -#define OP_EINVAL (-131) -/**A purported Ogg Opus stream did not begin with an Ogg page, a purported - header packet did not start with one of the required strings, "OpusHead" or - "OpusTags", or a link in a chained file was encountered that did not - contain any logical Opus streams.*/ -#define OP_ENOTFORMAT (-132) -/**A required header packet was not properly formatted, contained illegal - values, or was missing altogether.*/ -#define OP_EBADHEADER (-133) -/**The ID header contained an unrecognized version number.*/ -#define OP_EVERSION (-134) -/*Currently not used at all.*/ -#define OP_ENOTAUDIO (-135) -/**An audio packet failed to decode properly. - This is usually caused by a multistream Ogg packet where the durations of - the individual Opus packets contained in it are not all the same.*/ -#define OP_EBADPACKET (-136) -/**We failed to find data we had seen before, or the bitstream structure was - sufficiently malformed that seeking to the target destination was - impossible.*/ -#define OP_EBADLINK (-137) -/**An operation that requires seeking was requested on an unseekable stream.*/ -#define OP_ENOSEEK (-138) -/**The first or last granule position of a link failed basic validity checks.*/ -#define OP_EBADTIMESTAMP (-139) - -/*@}*/ -/*@}*/ - -/**\defgroup header_info Header Information*/ -/*@{*/ - -/**The maximum number of channels in an Ogg Opus stream.*/ -#define OPUS_CHANNEL_COUNT_MAX (255) - -/**Ogg Opus bitstream information. - This contains the basic playback parameters for a stream, and corresponds to - the initial ID header packet of an Ogg Opus stream.*/ -struct OpusHead{ - /**The Ogg Opus format version, in the range 0...255. - The top 4 bits represent a "major" version, and the bottom four bits - represent backwards-compatible "minor" revisions. - The current specification describes version 1. - This library will recognize versions up through 15 as backwards compatible - with the current specification. - An earlier draft of the specification described a version 0, but the only - difference between version 1 and version 0 is that version 0 did - not specify the semantics for handling the version field.*/ - int version; - /**The number of channels, in the range 1...255.*/ - int channel_count; - /**The number of samples that should be discarded from the beginning of the - stream.*/ - unsigned pre_skip; - /**The sampling rate of the original input. - All Opus audio is coded at 48 kHz, and should also be decoded at 48 kHz - for playback (unless the target hardware does not support this sampling - rate). - However, this field may be used to resample the audio back to the original - sampling rate, for example, when saving the output to a file.*/ - opus_uint32 input_sample_rate; - /**The gain to apply to the decoded output, in dB, as a Q8 value in the range - -32768...32767. - The libopusfile API will automatically apply this gain to the - decoded output before returning it, scaling it by - pow(10,output_gain/(20.0*256)). - You can adjust this behavior with op_set_gain_offset().*/ - int output_gain; - /**The channel mapping family, in the range 0...255. - Channel mapping family 0 covers mono or stereo in a single stream. - Channel mapping family 1 covers 1 to 8 channels in one or more streams, - using the Vorbis speaker assignments. - Channel mapping family 255 covers 1 to 255 channels in one or more - streams, but without any defined speaker assignment.*/ - int mapping_family; - /**The number of Opus streams in each Ogg packet, in the range 1...255.*/ - int stream_count; - /**The number of coupled Opus streams in each Ogg packet, in the range - 0...127. - This must satisfy 0 <= coupled_count <= stream_count and - coupled_count + stream_count <= 255. - The coupled streams appear first, before all uncoupled streams, in an Ogg - Opus packet.*/ - int coupled_count; - /**The mapping from coded stream channels to output channels. - Let index=mapping[k] be the value for channel k. - If index<2*coupled_count, then it refers to the left channel - from stream (index/2) if even, and the right channel from - stream (index/2) if odd. - Otherwise, it refers to the output of the uncoupled stream - (index-coupled_count).*/ - unsigned char mapping[OPUS_CHANNEL_COUNT_MAX]; -}; - -/**The metadata from an Ogg Opus stream. - - This structure holds the in-stream metadata corresponding to the 'comment' - header packet of an Ogg Opus stream. - The comment header is meant to be used much like someone jotting a quick - note on the label of a CD. - It should be a short, to the point text note that can be more than a couple - words, but not more than a short paragraph. - - The metadata is stored as a series of (tag, value) pairs, in length-encoded - string vectors, using the same format as Vorbis (without the final "framing - bit"), Theora, and Speex, except for the packet header. - The first occurrence of the '=' character delimits the tag and value. - A particular tag may occur more than once, and order is significant. - The character set encoding for the strings is always UTF-8, but the tag - names are limited to ASCII, and treated as case-insensitive. - See the Vorbis - comment header specification for details. - - In filling in this structure, libopusfile will null-terminate the - #user_comments strings for safety. - However, the bitstream format itself treats them as 8-bit clean vectors, - possibly containing NUL characters, so the #comment_lengths array should be - treated as their authoritative length. - - This structure is binary and source-compatible with a - vorbis_comment, and pointers to it may be freely cast to - vorbis_comment pointers, and vice versa. - It is provided as a separate type to avoid introducing a compile-time - dependency on the libvorbis headers.*/ -struct OpusTags{ - /**The array of comment string vectors.*/ - char **user_comments; - /**An array of the corresponding length of each vector, in bytes.*/ - int *comment_lengths; - /**The total number of comment streams.*/ - int comments; - /**The null-terminated vendor string. - This identifies the software used to encode the stream.*/ - char *vendor; -}; - -/**\name Picture tag image formats*/ -/*@{*/ - -/**The MIME type was not recognized, or the image data did not match the - declared MIME type.*/ -#define OP_PIC_FORMAT_UNKNOWN (-1) -/**The MIME type indicates the image data is really a URL.*/ -#define OP_PIC_FORMAT_URL (0) -/**The image is a JPEG.*/ -#define OP_PIC_FORMAT_JPEG (1) -/**The image is a PNG.*/ -#define OP_PIC_FORMAT_PNG (2) -/**The image is a GIF.*/ -#define OP_PIC_FORMAT_GIF (3) - -/*@}*/ - -/**The contents of a METADATA_BLOCK_PICTURE tag.*/ -struct OpusPictureTag{ - /**The picture type according to the ID3v2 APIC frame: -
    -
  1. Other
  2. -
  3. 32x32 pixels 'file icon' (PNG only)
  4. -
  5. Other file icon
  6. -
  7. Cover (front)
  8. -
  9. Cover (back)
  10. -
  11. Leaflet page
  12. -
  13. Media (e.g. label side of CD)
  14. -
  15. Lead artist/lead performer/soloist
  16. -
  17. Artist/performer
  18. -
  19. Conductor
  20. -
  21. Band/Orchestra
  22. -
  23. Composer
  24. -
  25. Lyricist/text writer
  26. -
  27. Recording Location
  28. -
  29. During recording
  30. -
  31. During performance
  32. -
  33. Movie/video screen capture
  34. -
  35. A bright colored fish
  36. -
  37. Illustration
  38. -
  39. Band/artist logotype
  40. -
  41. Publisher/Studio logotype
  42. -
- Others are reserved and should not be used. - There may only be one each of picture type 1 and 2 in a file.*/ - opus_int32 type; - /**The MIME type of the picture, in printable ASCII characters 0x20-0x7E. - The MIME type may also be "-->" to signify that the data part - is a URL pointing to the picture instead of the picture data itself. - In this case, a terminating NUL is appended to the URL string in #data, - but #data_length is set to the length of the string excluding that - terminating NUL.*/ - char *mime_type; - /**The description of the picture, in UTF-8.*/ - char *description; - /**The width of the picture in pixels.*/ - opus_uint32 width; - /**The height of the picture in pixels.*/ - opus_uint32 height; - /**The color depth of the picture in bits-per-pixel (not - bits-per-channel).*/ - opus_uint32 depth; - /**For indexed-color pictures (e.g., GIF), the number of colors used, or 0 - for non-indexed pictures.*/ - opus_uint32 colors; - /**The length of the picture data in bytes.*/ - opus_uint32 data_length; - /**The binary picture data.*/ - unsigned char *data; - /**The format of the picture data, if known. - One of -
    -
  • #OP_PIC_FORMAT_UNKNOWN,
  • -
  • #OP_PIC_FORMAT_URL,
  • -
  • #OP_PIC_FORMAT_JPEG,
  • -
  • #OP_PIC_FORMAT_PNG, or
  • -
  • #OP_PIC_FORMAT_GIF.
  • -
*/ - int format; -}; - -/**\name Functions for manipulating header data - - These functions manipulate the #OpusHead and #OpusTags structures, - which describe the audio parameters and tag-value metadata, respectively. - These can be used to query the headers returned by libopusfile, or - to parse Opus headers from sources other than an Ogg Opus stream, provided - they use the same format.*/ -/*@{*/ - -/**Parses the contents of the ID header packet of an Ogg Opus stream. - \param[out] _head Returns the contents of the parsed packet. - The contents of this structure are untouched on error. - This may be NULL to merely test the header - for validity. - \param[in] _data The contents of the ID header packet. - \param _len The number of bytes of data in the ID header packet. - \return 0 on success or a negative value on error. - \retval #OP_ENOTFORMAT If the data does not start with the "OpusHead" - string. - \retval #OP_EVERSION If the version field signaled a version this library - does not know how to parse. - \retval #OP_EIMPL If the channel mapping family was 255, which general - purpose players should not attempt to play. - \retval #OP_EBADHEADER If the contents of the packet otherwise violate the - Ogg Opus specification: -
    -
  • Insufficient data,
  • -
  • Too much data for the known minor versions,
  • -
  • An unrecognized channel mapping family,
  • -
  • Zero channels or too many channels,
  • -
  • Zero coded streams,
  • -
  • Too many coupled streams, or
  • -
  • An invalid channel mapping index.
  • -
*/ -OP_WARN_UNUSED_RESULT int opus_head_parse(OpusHead *_head, - const unsigned char *_data,size_t _len) OP_ARG_NONNULL(2); - -/**Converts a granule position to a sample offset for a given Ogg Opus stream. - The sample offset is simply _gp-_head->pre_skip. - Granule position values smaller than OpusHead#pre_skip correspond to audio - that should never be played, and thus have no associated sample offset. - This function returns -1 for such values. - This function also correctly handles extremely large granule positions, - which may have wrapped around to a negative number when stored in a signed - ogg_int64_t value. - \param _head The #OpusHead information from the ID header of the stream. - \param _gp The granule position to convert. - \return The sample offset associated with the given granule position - (counting at a 48 kHz sampling rate), or the special value -1 on - error (i.e., the granule position was smaller than the pre-skip - amount).*/ -ogg_int64_t opus_granule_sample(const OpusHead *_head,ogg_int64_t _gp) - OP_ARG_NONNULL(1); - -/**Parses the contents of the 'comment' header packet of an Ogg Opus stream. - \param[out] _tags An uninitialized #OpusTags structure. - This returns the contents of the parsed packet. - The contents of this structure are untouched on error. - This may be NULL to merely test the header - for validity. - \param[in] _data The contents of the 'comment' header packet. - \param _len The number of bytes of data in the 'info' header packet. - \retval 0 Success. - \retval #OP_ENOTFORMAT If the data does not start with the "OpusTags" - string. - \retval #OP_EBADHEADER If the contents of the packet otherwise violate the - Ogg Opus specification. - \retval #OP_EFAULT If there wasn't enough memory to store the tags.*/ -OP_WARN_UNUSED_RESULT int opus_tags_parse(OpusTags *_tags, - const unsigned char *_data,size_t _len) OP_ARG_NONNULL(2); - -/**Performs a deep copy of an #OpusTags structure. - \param _dst The #OpusTags structure to copy into. - If this function fails, the contents of this structure remain - untouched. - \param _src The #OpusTags structure to copy from. - \retval 0 Success. - \retval #OP_EFAULT If there wasn't enough memory to copy the tags.*/ -int opus_tags_copy(OpusTags *_dst,const OpusTags *_src) OP_ARG_NONNULL(1); - -/**Initializes an #OpusTags structure. - This should be called on a freshly allocated #OpusTags structure before - attempting to use it. - \param _tags The #OpusTags structure to initialize.*/ -void opus_tags_init(OpusTags *_tags) OP_ARG_NONNULL(1); - -/**Add a (tag, value) pair to an initialized #OpusTags structure. - \note Neither opus_tags_add() nor opus_tags_add_comment() support values - containing embedded NULs, although the bitstream format does support them. - To add such tags, you will need to manipulate the #OpusTags structure - directly. - \param _tags The #OpusTags structure to add the (tag, value) pair to. - \param _tag A NUL-terminated, case-insensitive, ASCII string containing - the tag to add (without an '=' character). - \param _value A NUL-terminated UTF-8 containing the corresponding value. - \return 0 on success, or a negative value on failure. - \retval #OP_EFAULT An internal memory allocation failed.*/ -int opus_tags_add(OpusTags *_tags,const char *_tag,const char *_value) - OP_ARG_NONNULL(1) OP_ARG_NONNULL(2) OP_ARG_NONNULL(3); - -/**Add a comment to an initialized #OpusTags structure. - \note Neither opus_tags_add_comment() nor opus_tags_add() support comments - containing embedded NULs, although the bitstream format does support them. - To add such tags, you will need to manipulate the #OpusTags structure - directly. - \param _tags The #OpusTags structure to add the comment to. - \param _comment A NUL-terminated UTF-8 string containing the comment in - "TAG=value" form. - \return 0 on success, or a negative value on failure. - \retval #OP_EFAULT An internal memory allocation failed.*/ -int opus_tags_add_comment(OpusTags *_tags,const char *_comment) - OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); - -/**Replace the binary suffix data at the end of the packet (if any). - \param _tags An initialized #OpusTags structure. - \param _data A buffer of binary data to append after the encoded user - comments. - The least significant bit of the first byte of this data must - be set (to ensure the data is preserved by other editors). - \param _len The number of bytes of binary data to append. - This may be zero to remove any existing binary suffix data. - \return 0 on success, or a negative value on error. - \retval #OP_EINVAL \a _len was negative, or \a _len was positive but - \a _data was NULL or the least significant - bit of the first byte was not set. - \retval #OP_EFAULT An internal memory allocation failed.*/ -int opus_tags_set_binary_suffix(OpusTags *_tags, - const unsigned char *_data,int _len) OP_ARG_NONNULL(1); - -/**Look up a comment value by its tag. - \param _tags An initialized #OpusTags structure. - \param _tag The tag to look up. - \param _count The instance of the tag. - The same tag can appear multiple times, each with a distinct - value, so an index is required to retrieve them all. - The order in which these values appear is significant and - should be preserved. - Use opus_tags_query_count() to get the legal range for the - \a _count parameter. - \return A pointer to the queried tag's value. - This points directly to data in the #OpusTags structure. - It should not be modified or freed by the application, and - modifications to the structure may invalidate the pointer. - \retval NULL If no matching tag is found.*/ -const char *opus_tags_query(const OpusTags *_tags,const char *_tag,int _count) - OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); - -/**Look up the number of instances of a tag. - Call this first when querying for a specific tag and then iterate over the - number of instances with separate calls to opus_tags_query() to retrieve - all the values for that tag in order. - \param _tags An initialized #OpusTags structure. - \param _tag The tag to look up. - \return The number of instances of this particular tag.*/ -int opus_tags_query_count(const OpusTags *_tags,const char *_tag) - OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); - -/**Retrieve the binary suffix data at the end of the packet (if any). - \param _tags An initialized #OpusTags structure. - \param[out] _len Returns the number of bytes of binary suffix data returned. - \return A pointer to the binary suffix data, or NULL if none - was present.*/ -const unsigned char *opus_tags_get_binary_suffix(const OpusTags *_tags, - int *_len) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); - -/**Get the album gain from an R128_ALBUM_GAIN tag, if one was specified. - This searches for the first R128_ALBUM_GAIN tag with a valid signed, - 16-bit decimal integer value and returns the value. - This routine is exposed merely for convenience for applications which wish - to do something special with the album gain (i.e., display it). - If you simply wish to apply the album gain instead of the header gain, you - can use op_set_gain_offset() with an #OP_ALBUM_GAIN type and no offset. - \param _tags An initialized #OpusTags structure. - \param[out] _gain_q8 The album gain, in 1/256ths of a dB. - This will lie in the range [-32768,32767], and should - be applied in addition to the header gain. - On error, no value is returned, and the previous - contents remain unchanged. - \return 0 on success, or a negative value on error. - \retval #OP_FALSE There was no album gain available in the given tags.*/ -int opus_tags_get_album_gain(const OpusTags *_tags,int *_gain_q8) - OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); - -/**Get the track gain from an R128_TRACK_GAIN tag, if one was specified. - This searches for the first R128_TRACK_GAIN tag with a valid signed, - 16-bit decimal integer value and returns the value. - This routine is exposed merely for convenience for applications which wish - to do something special with the track gain (i.e., display it). - If you simply wish to apply the track gain instead of the header gain, you - can use op_set_gain_offset() with an #OP_TRACK_GAIN type and no offset. - \param _tags An initialized #OpusTags structure. - \param[out] _gain_q8 The track gain, in 1/256ths of a dB. - This will lie in the range [-32768,32767], and should - be applied in addition to the header gain. - On error, no value is returned, and the previous - contents remain unchanged. - \return 0 on success, or a negative value on error. - \retval #OP_FALSE There was no track gain available in the given tags.*/ -int opus_tags_get_track_gain(const OpusTags *_tags,int *_gain_q8) - OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); - -/**Clears the #OpusTags structure. - This should be called on an #OpusTags structure after it is no longer - needed. - It will free all memory used by the structure members. - \param _tags The #OpusTags structure to clear.*/ -void opus_tags_clear(OpusTags *_tags) OP_ARG_NONNULL(1); - -/**Check if \a _comment is an instance of a \a _tag_name tag. - \see opus_tagncompare - \param _tag_name A NUL-terminated, case-insensitive, ASCII string containing - the name of the tag to check for (without the terminating - '=' character). - \param _comment The comment string to check. - \return An integer less than, equal to, or greater than zero if \a _comment - is found respectively, to be less than, to match, or be greater - than a "tag=value" string whose tag matches \a _tag_name.*/ -int opus_tagcompare(const char *_tag_name,const char *_comment); - -/**Check if \a _comment is an instance of a \a _tag_name tag. - This version is slightly more efficient than opus_tagcompare() if the length - of the tag name is already known (e.g., because it is a constant). - \see opus_tagcompare - \param _tag_name A case-insensitive ASCII string containing the name of the - tag to check for (without the terminating '=' character). - \param _tag_len The number of characters in the tag name. - This must be non-negative. - \param _comment The comment string to check. - \return An integer less than, equal to, or greater than zero if \a _comment - is found respectively, to be less than, to match, or be greater - than a "tag=value" string whose tag matches the first \a _tag_len - characters of \a _tag_name.*/ -int opus_tagncompare(const char *_tag_name,int _tag_len,const char *_comment); - -/**Parse a single METADATA_BLOCK_PICTURE tag. - This decodes the BASE64-encoded content of the tag and returns a structure - with the MIME type, description, image parameters (if known), and the - compressed image data. - If the MIME type indicates the presence of an image format we recognize - (JPEG, PNG, or GIF) and the actual image data contains the magic signature - associated with that format, then the OpusPictureTag::format field will be - set to the corresponding format. - This is provided as a convenience to avoid requiring applications to parse - the MIME type and/or do their own format detection for the commonly used - formats. - In this case, we also attempt to extract the image parameters directly from - the image data (overriding any that were present in the tag, which the - specification says applications are not meant to rely on). - The application must still provide its own support for actually decoding the - image data and, if applicable, retrieving that data from URLs. - \param[out] _pic Returns the parsed picture data. - No sanitation is done on the type, MIME type, or - description fields, so these might return invalid values. - The contents of this structure are left unmodified on - failure. - \param _tag The METADATA_BLOCK_PICTURE tag contents. - The leading "METADATA_BLOCK_PICTURE=" portion is optional, - to allow the function to be used on either directly on the - values in OpusTags::user_comments or on the return value - of opus_tags_query(). - \return 0 on success or a negative value on error. - \retval #OP_ENOTFORMAT The METADATA_BLOCK_PICTURE contents were not valid. - \retval #OP_EFAULT There was not enough memory to store the picture tag - contents.*/ -OP_WARN_UNUSED_RESULT int opus_picture_tag_parse(OpusPictureTag *_pic, - const char *_tag) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); - -/**Initializes an #OpusPictureTag structure. - This should be called on a freshly allocated #OpusPictureTag structure - before attempting to use it. - \param _pic The #OpusPictureTag structure to initialize.*/ -void opus_picture_tag_init(OpusPictureTag *_pic) OP_ARG_NONNULL(1); - -/**Clears the #OpusPictureTag structure. - This should be called on an #OpusPictureTag structure after it is no longer - needed. - It will free all memory used by the structure members. - \param _pic The #OpusPictureTag structure to clear.*/ -void opus_picture_tag_clear(OpusPictureTag *_pic) OP_ARG_NONNULL(1); - -/*@}*/ - -/*@}*/ - -/**\defgroup url_options URL Reading Options*/ -/*@{*/ -/**\name URL reading options - Options for op_url_stream_create() and associated functions. - These allow you to provide proxy configuration parameters, skip SSL - certificate checks, etc. - Options are processed in order, and if the same option is passed multiple - times, only the value specified by the last occurrence has an effect - (unless otherwise specified). - They may be expanded in the future.*/ -/*@{*/ - -/**@cond PRIVATE*/ - -/*These are the raw numbers used to define the request codes. - They should not be used directly.*/ -#define OP_SSL_SKIP_CERTIFICATE_CHECK_REQUEST (6464) -#define OP_HTTP_PROXY_HOST_REQUEST (6528) -#define OP_HTTP_PROXY_PORT_REQUEST (6592) -#define OP_HTTP_PROXY_USER_REQUEST (6656) -#define OP_HTTP_PROXY_PASS_REQUEST (6720) -#define OP_GET_SERVER_INFO_REQUEST (6784) - -#define OP_URL_OPT(_request) ((char *)(_request)) - -/*These macros trigger compilation errors or warnings if the wrong types are - provided to one of the URL options.*/ -#define OP_CHECK_INT(_x) ((void)((_x)==(opus_int32)0),(opus_int32)(_x)) -#define OP_CHECK_CONST_CHAR_PTR(_x) ((_x)+((_x)-(const char *)(_x))) -#define OP_CHECK_SERVER_INFO_PTR(_x) ((_x)+((_x)-(OpusServerInfo *)(_x))) - -/**@endcond*/ - -/**HTTP/Shoutcast/Icecast server information associated with a URL.*/ -struct OpusServerInfo{ - /**The name of the server (icy-name/ice-name). - This is NULL if there was no icy-name or - ice-name header.*/ - char *name; - /**A short description of the server (icy-description/ice-description). - This is NULL if there was no icy-description or - ice-description header.*/ - char *description; - /**The genre the server falls under (icy-genre/ice-genre). - This is NULL if there was no icy-genre or - ice-genre header.*/ - char *genre; - /**The homepage for the server (icy-url/ice-url). - This is NULL if there was no icy-url or - ice-url header.*/ - char *url; - /**The software used by the origin server (Server). - This is NULL if there was no Server header.*/ - char *server; - /**The media type of the entity sent to the recepient (Content-Type). - This is NULL if there was no Content-Type - header.*/ - char *content_type; - /**The nominal stream bitrate in kbps (icy-br/ice-bitrate). - This is -1 if there was no icy-br or - ice-bitrate header.*/ - opus_int32 bitrate_kbps; - /**Flag indicating whether the server is public (1) or not - (0) (icy-pub/ice-public). - This is -1 if there was no icy-pub or - ice-public header.*/ - int is_public; - /**Flag indicating whether the server is using HTTPS instead of HTTP. - This is 0 unless HTTPS is being used. - This may not match the protocol used in the original URL if there were - redirections.*/ - int is_ssl; -}; - -/**Initializes an #OpusServerInfo structure. - All fields are set as if the corresponding header was not available. - \param _info The #OpusServerInfo structure to initialize. - \note If you use this function, you must link against libopusurl.*/ -void opus_server_info_init(OpusServerInfo *_info) OP_ARG_NONNULL(1); - -/**Clears the #OpusServerInfo structure. - This should be called on an #OpusServerInfo structure after it is no longer - needed. - It will free all memory used by the structure members. - \param _info The #OpusServerInfo structure to clear. - \note If you use this function, you must link against libopusurl.*/ -void opus_server_info_clear(OpusServerInfo *_info) OP_ARG_NONNULL(1); - -/**Skip the certificate check when connecting via TLS/SSL (https). - \param _b opus_int32: Whether or not to skip the certificate - check. - The check will be skipped if \a _b is non-zero, and will not be - skipped if \a _b is zero. - \hideinitializer*/ -#define OP_SSL_SKIP_CERTIFICATE_CHECK(_b) \ - OP_URL_OPT(OP_SSL_SKIP_CERTIFICATE_CHECK_REQUEST),OP_CHECK_INT(_b) - -/**Proxy connections through the given host. - If no port is specified via #OP_HTTP_PROXY_PORT, the port number defaults - to 8080 (http-alt). - All proxy parameters are ignored for non-http and non-https URLs. - \param _host const char *: The proxy server hostname. - This may be NULL to disable the use of a proxy - server. - \hideinitializer*/ -#define OP_HTTP_PROXY_HOST(_host) \ - OP_URL_OPT(OP_HTTP_PROXY_HOST_REQUEST),OP_CHECK_CONST_CHAR_PTR(_host) - -/**Use the given port when proxying connections. - This option only has an effect if #OP_HTTP_PROXY_HOST is specified with a - non-NULL \a _host. - If this option is not provided, the proxy port number defaults to 8080 - (http-alt). - All proxy parameters are ignored for non-http and non-https URLs. - \param _port opus_int32: The proxy server port. - This must be in the range 0...65535 (inclusive), or the - URL function this is passed to will fail. - \hideinitializer*/ -#define OP_HTTP_PROXY_PORT(_port) \ - OP_URL_OPT(OP_HTTP_PROXY_PORT_REQUEST),OP_CHECK_INT(_port) - -/**Use the given user name for authentication when proxying connections. - All proxy parameters are ignored for non-http and non-https URLs. - \param _user const char *: The proxy server user name. - This may be NULL to disable proxy - authentication. - A non-NULL value only has an effect - if #OP_HTTP_PROXY_HOST and #OP_HTTP_PROXY_PASS - are also specified with non-NULL - arguments. - \hideinitializer*/ -#define OP_HTTP_PROXY_USER(_user) \ - OP_URL_OPT(OP_HTTP_PROXY_USER_REQUEST),OP_CHECK_CONST_CHAR_PTR(_user) - -/**Use the given password for authentication when proxying connections. - All proxy parameters are ignored for non-http and non-https URLs. - \param _pass const char *: The proxy server password. - This may be NULL to disable proxy - authentication. - A non-NULL value only has an effect - if #OP_HTTP_PROXY_HOST and #OP_HTTP_PROXY_USER - are also specified with non-NULL - arguments. - \hideinitializer*/ -#define OP_HTTP_PROXY_PASS(_pass) \ - OP_URL_OPT(OP_HTTP_PROXY_PASS_REQUEST),OP_CHECK_CONST_CHAR_PTR(_pass) - -/**Parse information about the streaming server (if any) and return it. - Very little validation is done. - In particular, OpusServerInfo::url may not be a valid URL, - OpusServerInfo::bitrate_kbps may not really be in kbps, and - OpusServerInfo::content_type may not be a valid MIME type. - The character set of the string fields is not specified anywhere, and should - not be assumed to be valid UTF-8. - \param _info OpusServerInfo *: Returns information about the server. - If there is any error opening the stream, the - contents of this structure remain - unmodified. - On success, fills in the structure with the - server information that was available, if - any. - After a successful return, the contents of - this structure should be freed by calling - opus_server_info_clear(). - \hideinitializer*/ -#define OP_GET_SERVER_INFO(_info) \ - OP_URL_OPT(OP_GET_SERVER_INFO_REQUEST),OP_CHECK_SERVER_INFO_PTR(_info) - -/*@}*/ -/*@}*/ - -/**\defgroup stream_callbacks Abstract Stream Reading Interface*/ -/*@{*/ -/**\name Functions for reading from streams - These functions define the interface used to read from and seek in a stream - of data. - A stream does not need to implement seeking, but the decoder will not be - able to seek if it does not do so. - These functions also include some convenience routines for working with - standard FILE pointers, complete streams stored in a single - block of memory, or URLs.*/ -/*@{*/ - -/**Reads up to \a _nbytes bytes of data from \a _stream. - \param _stream The stream to read from. - \param[out] _ptr The buffer to store the data in. - \param _nbytes The maximum number of bytes to read. - This function may return fewer, though it will not - return zero unless it reaches end-of-file. - \return The number of bytes successfully read, or a negative value on - error.*/ -typedef int (*op_read_func)(void *_stream,unsigned char *_ptr,int _nbytes); - -/**Sets the position indicator for \a _stream. - The new position, measured in bytes, is obtained by adding \a _offset - bytes to the position specified by \a _whence. - If \a _whence is set to SEEK_SET, SEEK_CUR, or - SEEK_END, the offset is relative to the start of the stream, - the current position indicator, or end-of-file, respectively. - \retval 0 Success. - \retval -1 Seeking is not supported or an error occurred. - errno need not be set.*/ -typedef int (*op_seek_func)(void *_stream,opus_int64 _offset,int _whence); - -/**Obtains the current value of the position indicator for \a _stream. - \return The current position indicator.*/ -typedef opus_int64 (*op_tell_func)(void *_stream); - -/**Closes the underlying stream. - \retval 0 Success. - \retval EOF An error occurred. - errno need not be set.*/ -typedef int (*op_close_func)(void *_stream); - -/**The callbacks used to access non-FILE stream resources. - The function prototypes are basically the same as for the stdio functions - fread(), fseek(), ftell(), and - fclose(). - The differences are that the FILE * arguments have been - replaced with a void *, which is to be used as a pointer to - whatever internal data these functions might need, that #seek and #tell - take and return 64-bit offsets, and that #seek must return -1 if - the stream is unseekable.*/ -struct OpusFileCallbacks{ - /**Used to read data from the stream. - This must not be NULL.*/ - op_read_func read; - /**Used to seek in the stream. - This may be NULL if seeking is not implemented.*/ - op_seek_func seek; - /**Used to return the current read position in the stream. - This may be NULL if seeking is not implemented.*/ - op_tell_func tell; - /**Used to close the stream when the decoder is freed. - This may be NULL to leave the stream open.*/ - op_close_func close; -}; - -/**Opens a stream with fopen() and fills in a set of callbacks - that can be used to access it. - This is useful to avoid writing your own portable 64-bit seeking wrappers, - and also avoids cross-module linking issues on Windows, where a - FILE * must be accessed by routines defined in the same module - that opened it. - \param[out] _cb The callbacks to use for this file. - If there is an error opening the file, nothing will be - filled in here. - \param _path The path to the file to open. - On Windows, this string must be UTF-8 (to allow access to - files whose names cannot be represented in the current - MBCS code page). - All other systems use the native character encoding. - \param _mode The mode to open the file in. - \return A stream handle to use with the callbacks, or NULL on - error.*/ -OP_WARN_UNUSED_RESULT void *op_fopen(OpusFileCallbacks *_cb, - const char *_path,const char *_mode) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2) - OP_ARG_NONNULL(3); - -/**Opens a stream with fdopen() and fills in a set of callbacks - that can be used to access it. - This is useful to avoid writing your own portable 64-bit seeking wrappers, - and also avoids cross-module linking issues on Windows, where a - FILE * must be accessed by routines defined in the same module - that opened it. - \param[out] _cb The callbacks to use for this file. - If there is an error opening the file, nothing will be - filled in here. - \param _fd The file descriptor to open. - \param _mode The mode to open the file in. - \return A stream handle to use with the callbacks, or NULL on - error.*/ -OP_WARN_UNUSED_RESULT void *op_fdopen(OpusFileCallbacks *_cb, - int _fd,const char *_mode) OP_ARG_NONNULL(1) OP_ARG_NONNULL(3); - -/**Opens a stream with freopen() and fills in a set of callbacks - that can be used to access it. - This is useful to avoid writing your own portable 64-bit seeking wrappers, - and also avoids cross-module linking issues on Windows, where a - FILE * must be accessed by routines defined in the same module - that opened it. - \param[out] _cb The callbacks to use for this file. - If there is an error opening the file, nothing will be - filled in here. - \param _path The path to the file to open. - On Windows, this string must be UTF-8 (to allow access - to files whose names cannot be represented in the - current MBCS code page). - All other systems use the native character encoding. - \param _mode The mode to open the file in. - \param _stream A stream previously returned by op_fopen(), op_fdopen(), - or op_freopen(). - \return A stream handle to use with the callbacks, or NULL on - error.*/ -OP_WARN_UNUSED_RESULT void *op_freopen(OpusFileCallbacks *_cb, - const char *_path,const char *_mode,void *_stream) OP_ARG_NONNULL(1) - OP_ARG_NONNULL(2) OP_ARG_NONNULL(3) OP_ARG_NONNULL(4); - -/**Creates a stream that reads from the given block of memory. - This block of memory must contain the complete stream to decode. - This is useful for caching small streams (e.g., sound effects) in RAM. - \param[out] _cb The callbacks to use for this stream. - If there is an error creating the stream, nothing will be - filled in here. - \param _data The block of memory to read from. - \param _size The size of the block of memory. - \return A stream handle to use with the callbacks, or NULL on - error.*/ -OP_WARN_UNUSED_RESULT void *op_mem_stream_create(OpusFileCallbacks *_cb, - const unsigned char *_data,size_t _size) OP_ARG_NONNULL(1); - -/**Creates a stream that reads from the given URL. - This function behaves identically to op_url_stream_create(), except that it - takes a va_list instead of a variable number of arguments. - It does not call the va_end macro, and because it invokes the - va_arg macro, the value of \a _ap is undefined after the call. - \note If you use this function, you must link against libopusurl. - \param[out] _cb The callbacks to use for this stream. - If there is an error creating the stream, nothing will - be filled in here. - \param _url The URL to read from. - Currently only the , , and - schemes are supported. - Both and may be disabled at compile - time, in which case opening such URLs will always fail. - Currently this only supports URIs. - IRIs should be converted to UTF-8 and URL-escaped, with - internationalized domain names encoded in punycode, - before passing them to this function. - \param[in,out] _ap A list of the \ref url_options "optional flags" to use. - This is a variable-length list of options terminated - with NULL. - \return A stream handle to use with the callbacks, or NULL on - error.*/ -OP_WARN_UNUSED_RESULT void *op_url_stream_vcreate(OpusFileCallbacks *_cb, - const char *_url,va_list _ap) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); - -/**Creates a stream that reads from the given URL. - \note If you use this function, you must link against libopusurl. - \param[out] _cb The callbacks to use for this stream. - If there is an error creating the stream, nothing will be - filled in here. - \param _url The URL to read from. - Currently only the , , and schemes - are supported. - Both and may be disabled at compile time, - in which case opening such URLs will always fail. - Currently this only supports URIs. - IRIs should be converted to UTF-8 and URL-escaped, with - internationalized domain names encoded in punycode, before - passing them to this function. - \param ... The \ref url_options "optional flags" to use. - This is a variable-length list of options terminated with - NULL. - \return A stream handle to use with the callbacks, or NULL on - error.*/ -OP_WARN_UNUSED_RESULT void *op_url_stream_create(OpusFileCallbacks *_cb, - const char *_url,...) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); - -/*@}*/ -/*@}*/ - -/**\defgroup stream_open_close Opening and Closing*/ -/*@{*/ -/**\name Functions for opening and closing streams - - These functions allow you to test a stream to see if it is Opus, open it, - and close it. - Several flavors are provided for each of the built-in stream types, plus a - more general version which takes a set of application-provided callbacks.*/ -/*@{*/ - -/**Test to see if this is an Opus stream. - For good results, you will need at least 57 bytes (for a pure Opus-only - stream). - Something like 512 bytes will give more reliable results for multiplexed - streams. - This function is meant to be a quick-rejection filter. - Its purpose is not to guarantee that a stream is a valid Opus stream, but to - ensure that it looks enough like Opus that it isn't going to be recognized - as some other format (except possibly an Opus stream that is also - multiplexed with other codecs, such as video). - \param[out] _head The parsed ID header contents. - You may pass NULL if you do not need - this information. - If the function fails, the contents of this structure - remain untouched. - \param _initial_data An initial buffer of data from the start of the - stream. - \param _initial_bytes The number of bytes in \a _initial_data. - \return 0 if the data appears to be Opus, or a negative value on error. - \retval #OP_FALSE There was not enough data to tell if this was an Opus - stream or not. - \retval #OP_EFAULT An internal memory allocation failed. - \retval #OP_EIMPL The stream used a feature that is not implemented, - such as an unsupported channel family. - \retval #OP_ENOTFORMAT If the data did not contain a recognizable ID - header for an Opus stream. - \retval #OP_EVERSION If the version field signaled a version this library - does not know how to parse. - \retval #OP_EBADHEADER The ID header was not properly formatted or contained - illegal values.*/ -int op_test(OpusHead *_head, - const unsigned char *_initial_data,size_t _initial_bytes); - -/**Open a stream from the given file path. - \param _path The path to the file to open. - \param[out] _error Returns 0 on success, or a failure code on error. - You may pass in NULL if you don't want the - failure code. - The failure code will be #OP_EFAULT if the file could not - be opened, or one of the other failure codes from - op_open_callbacks() otherwise. - \return A freshly opened \c OggOpusFile, or NULL on error.*/ -OP_WARN_UNUSED_RESULT OggOpusFile *op_open_file(const char *_path,int *_error) - OP_ARG_NONNULL(1); - -/**Open a stream from a memory buffer. - \param _data The memory buffer to open. - \param _size The number of bytes in the buffer. - \param[out] _error Returns 0 on success, or a failure code on error. - You may pass in NULL if you don't want the - failure code. - See op_open_callbacks() for a full list of failure codes. - \return A freshly opened \c OggOpusFile, or NULL on error.*/ -OP_WARN_UNUSED_RESULT OggOpusFile *op_open_memory(const unsigned char *_data, - size_t _size,int *_error); - -/**Open a stream from a URL. - This function behaves identically to op_open_url(), except that it - takes a va_list instead of a variable number of arguments. - It does not call the va_end macro, and because it invokes the - va_arg macro, the value of \a _ap is undefined after the call. - \note If you use this function, you must link against libopusurl. - \param _url The URL to open. - Currently only the , , and - schemes are supported. - Both and may be disabled at compile - time, in which case opening such URLs will always - fail. - Currently this only supports URIs. - IRIs should be converted to UTF-8 and URL-escaped, - with internationalized domain names encoded in - punycode, before passing them to this function. - \param[out] _error Returns 0 on success, or a failure code on error. - You may pass in NULL if you don't want - the failure code. - See op_open_callbacks() for a full list of failure - codes. - \param[in,out] _ap A list of the \ref url_options "optional flags" to - use. - This is a variable-length list of options terminated - with NULL. - \return A freshly opened \c OggOpusFile, or NULL on error.*/ -OP_WARN_UNUSED_RESULT OggOpusFile *op_vopen_url(const char *_url, - int *_error,va_list _ap) OP_ARG_NONNULL(1); - -/**Open a stream from a URL. - \note If you use this function, you must link against libopusurl. - \param _url The URL to open. - Currently only the , , and schemes - are supported. - Both and may be disabled at compile - time, in which case opening such URLs will always fail. - Currently this only supports URIs. - IRIs should be converted to UTF-8 and URL-escaped, with - internationalized domain names encoded in punycode, - before passing them to this function. - \param[out] _error Returns 0 on success, or a failure code on error. - You may pass in NULL if you don't want the - failure code. - See op_open_callbacks() for a full list of failure codes. - \param ... The \ref url_options "optional flags" to use. - This is a variable-length list of options terminated with - NULL. - \return A freshly opened \c OggOpusFile, or NULL on error.*/ -OP_WARN_UNUSED_RESULT OggOpusFile *op_open_url(const char *_url, - int *_error,...) OP_ARG_NONNULL(1); - -/**Open a stream using the given set of callbacks to access it. - \param _stream The stream to read from (e.g., a FILE *). - This value will be passed verbatim as the first - argument to all of the callbacks. - \param _cb The callbacks with which to access the stream. - read() must - be implemented. - seek() and - tell() may - be NULL, or may always return -1 to - indicate a stream is unseekable, but if - seek() is - implemented and succeeds on a particular stream, then - tell() must - also. - close() may - be NULL, but if it is not, it will be - called when the \c OggOpusFile is destroyed by - op_free(). - It will not be called if op_open_callbacks() fails - with an error. - \param _initial_data An initial buffer of data from the start of the - stream. - Applications can read some number of bytes from the - start of the stream to help identify this as an Opus - stream, and then provide them here to allow the - stream to be opened, even if it is unseekable. - \param _initial_bytes The number of bytes in \a _initial_data. - If the stream is seekable, its current position (as - reported by - tell() - at the start of this function) must be equal to - \a _initial_bytes. - Otherwise, seeking to absolute positions will - generate inconsistent results. - \param[out] _error Returns 0 on success, or a failure code on error. - You may pass in NULL if you don't want - the failure code. - The failure code will be one of -
-
#OP_EREAD
-
An underlying read, seek, or tell operation - failed when it should have succeeded, or we failed - to find data in the stream we had seen before.
-
#OP_EFAULT
-
There was a memory allocation failure, or an - internal library error.
-
#OP_EIMPL
-
The stream used a feature that is not - implemented, such as an unsupported channel - family.
-
#OP_EINVAL
-
seek() - was implemented and succeeded on this source, but - tell() - did not, or the starting position indicator was - not equal to \a _initial_bytes.
-
#OP_ENOTFORMAT
-
The stream contained a link that did not have - any logical Opus streams in it.
-
#OP_EBADHEADER
-
A required header packet was not properly - formatted, contained illegal values, or was missing - altogether.
-
#OP_EVERSION
-
An ID header contained an unrecognized version - number.
-
#OP_EBADLINK
-
We failed to find data we had seen before after - seeking.
-
#OP_EBADTIMESTAMP
-
The first or last timestamp in a link failed - basic validity checks.
-
- \return A freshly opened \c OggOpusFile, or NULL on error. - libopusfile does not take ownership of the stream - if the call fails. - The calling application is responsible for closing the stream if - this call returns an error.*/ -OP_WARN_UNUSED_RESULT OggOpusFile *op_open_callbacks(void *_stream, - const OpusFileCallbacks *_cb,const unsigned char *_initial_data, - size_t _initial_bytes,int *_error) OP_ARG_NONNULL(2); - -/**Partially open a stream from the given file path. - \see op_test_callbacks - \param _path The path to the file to open. - \param[out] _error Returns 0 on success, or a failure code on error. - You may pass in NULL if you don't want the - failure code. - The failure code will be #OP_EFAULT if the file could not - be opened, or one of the other failure codes from - op_open_callbacks() otherwise. - \return A partially opened \c OggOpusFile, or NULL on error.*/ -OP_WARN_UNUSED_RESULT OggOpusFile *op_test_file(const char *_path,int *_error) - OP_ARG_NONNULL(1); - -/**Partially open a stream from a memory buffer. - \see op_test_callbacks - \param _data The memory buffer to open. - \param _size The number of bytes in the buffer. - \param[out] _error Returns 0 on success, or a failure code on error. - You may pass in NULL if you don't want the - failure code. - See op_open_callbacks() for a full list of failure codes. - \return A partially opened \c OggOpusFile, or NULL on error.*/ -OP_WARN_UNUSED_RESULT OggOpusFile *op_test_memory(const unsigned char *_data, - size_t _size,int *_error); - -/**Partially open a stream from a URL. - This function behaves identically to op_test_url(), except that it - takes a va_list instead of a variable number of arguments. - It does not call the va_end macro, and because it invokes the - va_arg macro, the value of \a _ap is undefined after the call. - \note If you use this function, you must link against libopusurl. - \see op_test_url - \see op_test_callbacks - \param _url The URL to open. - Currently only the , , and - schemes are supported. - Both and may be disabled at compile - time, in which case opening such URLs will always - fail. - Currently this only supports URIs. - IRIs should be converted to UTF-8 and URL-escaped, - with internationalized domain names encoded in - punycode, before passing them to this function. - \param[out] _error Returns 0 on success, or a failure code on error. - You may pass in NULL if you don't want - the failure code. - See op_open_callbacks() for a full list of failure - codes. - \param[in,out] _ap A list of the \ref url_options "optional flags" to - use. - This is a variable-length list of options terminated - with NULL. - \return A partially opened \c OggOpusFile, or NULL on error.*/ -OP_WARN_UNUSED_RESULT OggOpusFile *op_vtest_url(const char *_url, - int *_error,va_list _ap) OP_ARG_NONNULL(1); - -/**Partially open a stream from a URL. - \note If you use this function, you must link against libopusurl. - \see op_test_callbacks - \param _url The URL to open. - Currently only the , , and - schemes are supported. - Both and may be disabled at compile - time, in which case opening such URLs will always fail. - Currently this only supports URIs. - IRIs should be converted to UTF-8 and URL-escaped, with - internationalized domain names encoded in punycode, - before passing them to this function. - \param[out] _error Returns 0 on success, or a failure code on error. - You may pass in NULL if you don't want the - failure code. - See op_open_callbacks() for a full list of failure - codes. - \param ... The \ref url_options "optional flags" to use. - This is a variable-length list of options terminated - with NULL. - \return A partially opened \c OggOpusFile, or NULL on error.*/ -OP_WARN_UNUSED_RESULT OggOpusFile *op_test_url(const char *_url, - int *_error,...) OP_ARG_NONNULL(1); - -/**Partially open a stream using the given set of callbacks to access it. - This tests for Opusness and loads the headers for the first link. - It does not seek (although it tests for seekability). - You can query a partially open stream for the few pieces of basic - information returned by op_serialno(), op_channel_count(), op_head(), and - op_tags() (but only for the first link). - You may also determine if it is seekable via a call to op_seekable(). - You cannot read audio from the stream, seek, get the size or duration, - get information from links other than the first one, or even get the total - number of links until you finish opening the stream with op_test_open(). - If you do not need to do any of these things, you can dispose of it with - op_free() instead. - - This function is provided mostly to simplify porting existing code that used - libvorbisfile. - For new code, you are likely better off using op_test() instead, which - is less resource-intensive, requires less data to succeed, and imposes a - hard limit on the amount of data it examines (important for unseekable - streams, where all such data must be buffered until you are sure of the - stream type). - \param _stream The stream to read from (e.g., a FILE *). - This value will be passed verbatim as the first - argument to all of the callbacks. - \param _cb The callbacks with which to access the stream. - read() must - be implemented. - seek() and - tell() may - be NULL, or may always return -1 to - indicate a stream is unseekable, but if - seek() is - implemented and succeeds on a particular stream, then - tell() must - also. - close() may - be NULL, but if it is not, it will be - called when the \c OggOpusFile is destroyed by - op_free(). - It will not be called if op_open_callbacks() fails - with an error. - \param _initial_data An initial buffer of data from the start of the - stream. - Applications can read some number of bytes from the - start of the stream to help identify this as an Opus - stream, and then provide them here to allow the - stream to be tested more thoroughly, even if it is - unseekable. - \param _initial_bytes The number of bytes in \a _initial_data. - If the stream is seekable, its current position (as - reported by - tell() - at the start of this function) must be equal to - \a _initial_bytes. - Otherwise, seeking to absolute positions will - generate inconsistent results. - \param[out] _error Returns 0 on success, or a failure code on error. - You may pass in NULL if you don't want - the failure code. - See op_open_callbacks() for a full list of failure - codes. - \return A partially opened \c OggOpusFile, or NULL on error. - libopusfile does not take ownership of the stream - if the call fails. - The calling application is responsible for closing the stream if - this call returns an error.*/ -OP_WARN_UNUSED_RESULT OggOpusFile *op_test_callbacks(void *_stream, - const OpusFileCallbacks *_cb,const unsigned char *_initial_data, - size_t _initial_bytes,int *_error) OP_ARG_NONNULL(2); - -/**Finish opening a stream partially opened with op_test_callbacks() or one of - the associated convenience functions. - If this function fails, you are still responsible for freeing the - \c OggOpusFile with op_free(). - \param _of The \c OggOpusFile to finish opening. - \return 0 on success, or a negative value on error. - \retval #OP_EREAD An underlying read, seek, or tell operation failed - when it should have succeeded. - \retval #OP_EFAULT There was a memory allocation failure, or an - internal library error. - \retval #OP_EIMPL The stream used a feature that is not implemented, - such as an unsupported channel family. - \retval #OP_EINVAL The stream was not partially opened with - op_test_callbacks() or one of the associated - convenience functions. - \retval #OP_ENOTFORMAT The stream contained a link that did not have any - logical Opus streams in it. - \retval #OP_EBADHEADER A required header packet was not properly - formatted, contained illegal values, or was - missing altogether. - \retval #OP_EVERSION An ID header contained an unrecognized version - number. - \retval #OP_EBADLINK We failed to find data we had seen before after - seeking. - \retval #OP_EBADTIMESTAMP The first or last timestamp in a link failed basic - validity checks.*/ -int op_test_open(OggOpusFile *_of) OP_ARG_NONNULL(1); - -/**Release all memory used by an \c OggOpusFile. - \param _of The \c OggOpusFile to free.*/ -void op_free(OggOpusFile *_of); - -/*@}*/ -/*@}*/ - -/**\defgroup stream_info Stream Information*/ -/*@{*/ -/**\name Functions for obtaining information about streams - - These functions allow you to get basic information about a stream, including - seekability, the number of links (for chained streams), plus the size, - duration, bitrate, header parameters, and meta information for each link - (or, where available, the stream as a whole). - Some of these (size, duration) are only available for seekable streams. - You can also query the current stream position, link, and playback time, - and instantaneous bitrate during playback. - - Some of these functions may be used successfully on the partially open - streams returned by op_test_callbacks() or one of the associated - convenience functions. - Their documention will indicate so explicitly.*/ -/*@{*/ - -/**Returns whether or not the stream being read is seekable. - This is true if -
    -
  1. The seek() and - tell() callbacks are both - non-NULL,
  2. -
  3. The seek() callback was - successfully executed at least once, and
  4. -
  5. The tell() callback was - successfully able to report the position indicator afterwards.
  6. -
- This function may be called on partially-opened streams. - \param _of The \c OggOpusFile whose seekable status is to be returned. - \return A non-zero value if seekable, and 0 if unseekable.*/ -int op_seekable(const OggOpusFile *_of) OP_ARG_NONNULL(1); - -/**Returns the number of links in this chained stream. - This function may be called on partially-opened streams, but it will always - return 1. - The actual number of links is not known until the stream is fully opened. - \param _of The \c OggOpusFile from which to retrieve the link count. - \return For fully-open seekable streams, this returns the total number of - links in the whole stream, which will be at least 1. - For partially-open or unseekable streams, this always returns 1.*/ -int op_link_count(const OggOpusFile *_of) OP_ARG_NONNULL(1); - -/**Get the serial number of the given link in a (possibly-chained) Ogg Opus - stream. - This function may be called on partially-opened streams, but it will always - return the serial number of the Opus stream in the first link. - \param _of The \c OggOpusFile from which to retrieve the serial number. - \param _li The index of the link whose serial number should be retrieved. - Use a negative number to get the serial number of the current - link. - \return The serial number of the given link. - If \a _li is greater than the total number of links, this returns - the serial number of the last link. - If the stream is not seekable, this always returns the serial number - of the current link.*/ -opus_uint32 op_serialno(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); - -/**Get the channel count of the given link in a (possibly-chained) Ogg Opus - stream. - This is equivalent to op_head(_of,_li)->channel_count, but - is provided for convenience. - This function may be called on partially-opened streams, but it will always - return the channel count of the Opus stream in the first link. - \param _of The \c OggOpusFile from which to retrieve the channel count. - \param _li The index of the link whose channel count should be retrieved. - Use a negative number to get the channel count of the current - link. - \return The channel count of the given link. - If \a _li is greater than the total number of links, this returns - the channel count of the last link. - If the stream is not seekable, this always returns the channel count - of the current link.*/ -int op_channel_count(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); - -/**Get the total (compressed) size of the stream, or of an individual link in - a (possibly-chained) Ogg Opus stream, including all headers and Ogg muxing - overhead. - \warning If the Opus stream (or link) is concurrently multiplexed with other - logical streams (e.g., video), this returns the size of the entire stream - (or link), not just the number of bytes in the first logical Opus stream. - Returning the latter would require scanning the entire file. - \param _of The \c OggOpusFile from which to retrieve the compressed size. - \param _li The index of the link whose compressed size should be computed. - Use a negative number to get the compressed size of the entire - stream. - \return The compressed size of the entire stream if \a _li is negative, the - compressed size of link \a _li if it is non-negative, or a negative - value on error. - The compressed size of the entire stream may be smaller than that - of the underlying stream if trailing garbage was detected in the - file. - \retval #OP_EINVAL The stream is not seekable (so we can't know the length), - \a _li wasn't less than the total number of links in - the stream, or the stream was only partially open.*/ -opus_int64 op_raw_total(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); - -/**Get the total PCM length (number of samples at 48 kHz) of the stream, or of - an individual link in a (possibly-chained) Ogg Opus stream. - Users looking for op_time_total() should use op_pcm_total() - instead. - Because timestamps in Opus are fixed at 48 kHz, there is no need for a - separate function to convert this to seconds (and leaving it out avoids - introducing floating point to the API, for those that wish to avoid it). - \param _of The \c OggOpusFile from which to retrieve the PCM offset. - \param _li The index of the link whose PCM length should be computed. - Use a negative number to get the PCM length of the entire stream. - \return The PCM length of the entire stream if \a _li is negative, the PCM - length of link \a _li if it is non-negative, or a negative value on - error. - \retval #OP_EINVAL The stream is not seekable (so we can't know the length), - \a _li wasn't less than the total number of links in - the stream, or the stream was only partially open.*/ -ogg_int64_t op_pcm_total(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); - -/**Get the ID header information for the given link in a (possibly chained) Ogg - Opus stream. - This function may be called on partially-opened streams, but it will always - return the ID header information of the Opus stream in the first link. - \param _of The \c OggOpusFile from which to retrieve the ID header - information. - \param _li The index of the link whose ID header information should be - retrieved. - Use a negative number to get the ID header information of the - current link. - For an unseekable stream, \a _li is ignored, and the ID header - information for the current link is always returned, if - available. - \return The contents of the ID header for the given link.*/ -const OpusHead *op_head(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); - -/**Get the comment header information for the given link in a (possibly - chained) Ogg Opus stream. - This function may be called on partially-opened streams, but it will always - return the tags from the Opus stream in the first link. - \param _of The \c OggOpusFile from which to retrieve the comment header - information. - \param _li The index of the link whose comment header information should be - retrieved. - Use a negative number to get the comment header information of - the current link. - For an unseekable stream, \a _li is ignored, and the comment - header information for the current link is always returned, if - available. - \return The contents of the comment header for the given link, or - NULL if this is an unseekable stream that encountered - an invalid link.*/ -const OpusTags *op_tags(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); - -/**Retrieve the index of the current link. - This is the link that produced the data most recently read by - op_read_float() or its associated functions, or, after a seek, the link - that the seek target landed in. - Reading more data may advance the link index (even on the first read after a - seek). - \param _of The \c OggOpusFile from which to retrieve the current link index. - \return The index of the current link on success, or a negative value on - failure. - For seekable streams, this is a number between 0 (inclusive) and the - value returned by op_link_count() (exclusive). - For unseekable streams, this value starts at 0 and increments by one - each time a new link is encountered (even though op_link_count() - always returns 1). - \retval #OP_EINVAL The stream was only partially open.*/ -int op_current_link(const OggOpusFile *_of) OP_ARG_NONNULL(1); - -/**Computes the bitrate of the stream, or of an individual link in a - (possibly-chained) Ogg Opus stream. - The stream must be seekable to compute the bitrate. - For unseekable streams, use op_bitrate_instant() to get periodic estimates. - \warning If the Opus stream (or link) is concurrently multiplexed with other - logical streams (e.g., video), this uses the size of the entire stream (or - link) to compute the bitrate, not just the number of bytes in the first - logical Opus stream. - Returning the latter requires scanning the entire file, but this may be done - by decoding the whole file and calling op_bitrate_instant() once at the - end. - Install a trivial decoding callback with op_set_decode_callback() if you - wish to skip actual decoding during this process. - \param _of The \c OggOpusFile from which to retrieve the bitrate. - \param _li The index of the link whose bitrate should be computed. - Use a negative number to get the bitrate of the whole stream. - \return The bitrate on success, or a negative value on error. - \retval #OP_EINVAL The stream was only partially open, the stream was not - seekable, or \a _li was larger than the number of - links.*/ -opus_int32 op_bitrate(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); - -/**Compute the instantaneous bitrate, measured as the ratio of bits to playable - samples decoded since a) the last call to op_bitrate_instant(), b) the last - seek, or c) the start of playback, whichever was most recent. - This will spike somewhat after a seek or at the start/end of a chain - boundary, as pre-skip, pre-roll, and end-trimming causes samples to be - decoded but not played. - \param _of The \c OggOpusFile from which to retrieve the bitrate. - \return The bitrate, in bits per second, or a negative value on error. - \retval #OP_FALSE No data has been decoded since any of the events - described above. - \retval #OP_EINVAL The stream was only partially open.*/ -opus_int32 op_bitrate_instant(OggOpusFile *_of) OP_ARG_NONNULL(1); - -/**Obtain the current value of the position indicator for \a _of. - \param _of The \c OggOpusFile from which to retrieve the position indicator. - \return The byte position that is currently being read from. - \retval #OP_EINVAL The stream was only partially open.*/ -opus_int64 op_raw_tell(const OggOpusFile *_of) OP_ARG_NONNULL(1); - -/**Obtain the PCM offset of the next sample to be read. - If the stream is not properly timestamped, this might not increment by the - proper amount between reads, or even return monotonically increasing - values. - \param _of The \c OggOpusFile from which to retrieve the PCM offset. - \return The PCM offset of the next sample to be read. - \retval #OP_EINVAL The stream was only partially open.*/ -ogg_int64_t op_pcm_tell(const OggOpusFile *_of) OP_ARG_NONNULL(1); - -/*@}*/ -/*@}*/ - -/**\defgroup stream_seeking Seeking*/ -/*@{*/ -/**\name Functions for seeking in Opus streams - - These functions let you seek in Opus streams, if the underlying stream - support it. - Seeking is implemented for all built-in stream I/O routines, though some - individual streams may not be seekable (pipes, live HTTP streams, or HTTP - streams from a server that does not support Range requests). - - op_raw_seek() is the fastest: it is guaranteed to perform at most one - physical seek, but, since the target is a byte position, makes no guarantee - how close to a given time it will come. - op_pcm_seek() provides sample-accurate seeking. - The number of physical seeks it requires is still quite small (often 1 or - 2, even in highly variable bitrate streams). - - Seeking in Opus requires decoding some pre-roll amount before playback to - allow the internal state to converge (as if recovering from packet loss). - This is handled internally by libopusfile, but means there is - little extra overhead for decoding up to the exact position requested - (since it must decode some amount of audio anyway). - It also means that decoding after seeking may not return exactly the same - values as would be obtained by decoding the stream straight through. - However, such differences are expected to be smaller than the loss - introduced by Opus's lossy compression.*/ -/*@{*/ - -/**Seek to a byte offset relative to the compressed data. - This also scans packets to update the PCM cursor. - It will cross a logical bitstream boundary, but only if it can't get any - packets out of the tail of the link to which it seeks. - \param _of The \c OggOpusFile in which to seek. - \param _byte_offset The byte position to seek to. - This must be between 0 and #op_raw_total(\a _of,\c -1) - (inclusive). - \return 0 on success, or a negative error code on failure. - \retval #OP_EREAD The underlying seek operation failed. - \retval #OP_EINVAL The stream was only partially open, or the target was - outside the valid range for the stream. - \retval #OP_ENOSEEK This stream is not seekable. - \retval #OP_EBADLINK Failed to initialize a decoder for a stream for an - unknown reason.*/ -int op_raw_seek(OggOpusFile *_of,opus_int64 _byte_offset) OP_ARG_NONNULL(1); - -/**Seek to the specified PCM offset, such that decoding will begin at exactly - the requested position. - \param _of The \c OggOpusFile in which to seek. - \param _pcm_offset The PCM offset to seek to. - This is in samples at 48 kHz relative to the start of the - stream. - \return 0 on success, or a negative value on error. - \retval #OP_EREAD An underlying read or seek operation failed. - \retval #OP_EINVAL The stream was only partially open, or the target was - outside the valid range for the stream. - \retval #OP_ENOSEEK This stream is not seekable. - \retval #OP_EBADLINK We failed to find data we had seen before, or the - bitstream structure was sufficiently malformed that - seeking to the target destination was impossible.*/ -int op_pcm_seek(OggOpusFile *_of,ogg_int64_t _pcm_offset) OP_ARG_NONNULL(1); - -/*@}*/ -/*@}*/ - -/**\defgroup stream_decoding Decoding*/ -/*@{*/ -/**\name Functions for decoding audio data - - These functions retrieve actual decoded audio data from the stream. - The general functions, op_read() and op_read_float() return 16-bit or - floating-point output, both using native endian ordering. - The number of channels returned can change from link to link in a chained - stream. - There are special functions, op_read_stereo() and op_read_float_stereo(), - which always output two channels, to simplify applications which do not - wish to handle multichannel audio. - These downmix multichannel files to two channels, so they can always return - samples in the same format for every link in a chained file. - - If the rest of your audio processing chain can handle floating point, the - floating-point routines should be preferred, as they prevent clipping and - other issues which might be avoided entirely if, e.g., you scale down the - volume at some other stage. - However, if you intend to consume 16-bit samples directly, the conversion in - libopusfile provides noise-shaping dithering and, if compiled - against libopus 1.1 or later, soft-clipping prevention. - - libopusfile can also be configured at compile time to use the - fixed-point libopus API. - If so, libopusfile's floating-point API may also be disabled. - In that configuration, nothing in libopusfile will use any - floating-point operations, to simplify support on devices without an - adequate FPU. - - \warning HTTPS streams may be be vulnerable to truncation attacks if you do - not check the error return code from op_read_float() or its associated - functions. - If the remote peer does not close the connection gracefully (with a TLS - "close notify" message), these functions will return #OP_EREAD instead of 0 - when they reach the end of the file. - If you are reading from an URL (particularly if seeking is not - supported), you should make sure to check for this error and warn the user - appropriately.*/ -/*@{*/ - -/**Indicates that the decoding callback should produce signed 16-bit - native-endian output samples.*/ -#define OP_DEC_FORMAT_SHORT (7008) -/**Indicates that the decoding callback should produce 32-bit native-endian - float samples.*/ -#define OP_DEC_FORMAT_FLOAT (7040) - -/**Indicates that the decoding callback did not decode anything, and that - libopusfile should decode normally instead.*/ -#define OP_DEC_USE_DEFAULT (6720) - -/**Called to decode an Opus packet. - This should invoke the functional equivalent of opus_multistream_decode() or - opus_multistream_decode_float(), except that it returns 0 on success - instead of the number of decoded samples (which is known a priori). - \param _ctx The application-provided callback context. - \param _decoder The decoder to use to decode the packet. - \param[out] _pcm The buffer to decode into. - This will always have enough room for \a _nchannels of - \a _nsamples samples, which should be placed into this - buffer interleaved. - \param _op The packet to decode. - This will always have its granule position set to a valid - value. - \param _nsamples The number of samples expected from the packet. - \param _nchannels The number of channels expected from the packet. - \param _format The desired sample output format. - This is either #OP_DEC_FORMAT_SHORT or - #OP_DEC_FORMAT_FLOAT. - \param _li The index of the link from which this packet was decoded. - \return A non-negative value on success, or a negative value on error. - Any error codes should be the same as those returned by - opus_multistream_decode() or opus_multistream_decode_float(). - Success codes are as follows: - \retval 0 Decoding was successful. - The application has filled the buffer with - exactly \a _nsamples*\a - _nchannels samples in the requested - format. - \retval #OP_DEC_USE_DEFAULT No decoding was done. - libopusfile should do the decoding - by itself instead.*/ -typedef int (*op_decode_cb_func)(void *_ctx,OpusMSDecoder *_decoder,void *_pcm, - const ogg_packet *_op,int _nsamples,int _nchannels,int _format,int _li); - -/**Sets the packet decode callback function. - If set, this is called once for each packet that needs to be decoded. - This can be used by advanced applications to do additional processing on the - compressed or uncompressed data. - For example, an application might save the final entropy coder state for - debugging and testing purposes, or it might apply additional filters - before the downmixing, dithering, or soft-clipping performed by - libopusfile, so long as these filters do not introduce any - latency. - - A call to this function is no guarantee that the audio will eventually be - delivered to the application. - libopusfile may discard some or all of the decoded audio data - (i.e., at the beginning or end of a link, or after a seek), however the - callback is still required to provide all of it. - \param _of The \c OggOpusFile on which to set the decode callback. - \param _decode_cb The callback function to call. - This may be NULL to disable calling the - callback. - \param _ctx The application-provided context pointer to pass to the - callback on each call.*/ -void op_set_decode_callback(OggOpusFile *_of, - op_decode_cb_func _decode_cb,void *_ctx) OP_ARG_NONNULL(1); - -/**Gain offset type that indicates that the provided offset is relative to the - header gain. - This is the default.*/ -#define OP_HEADER_GAIN (0) - -/**Gain offset type that indicates that the provided offset is relative to the - R128_ALBUM_GAIN value (if any), in addition to the header gain.*/ -#define OP_ALBUM_GAIN (3007) - -/**Gain offset type that indicates that the provided offset is relative to the - R128_TRACK_GAIN value (if any), in addition to the header gain.*/ -#define OP_TRACK_GAIN (3008) - -/**Gain offset type that indicates that the provided offset should be used as - the gain directly, without applying any the header or track gains.*/ -#define OP_ABSOLUTE_GAIN (3009) - -/**Sets the gain to be used for decoded output. - By default, the gain in the header is applied with no additional offset. - The total gain (including header gain and/or track gain, if applicable, and - this offset), will be clamped to [-32768,32767]/256 dB. - This is more than enough to saturate or underflow 16-bit PCM. - \note The new gain will not be applied to any already buffered, decoded - output. - This means you cannot change it sample-by-sample, as at best it will be - updated packet-by-packet. - It is meant for setting a target volume level, rather than applying smooth - fades, etc. - \param _of The \c OggOpusFile on which to set the gain offset. - \param _gain_type One of #OP_HEADER_GAIN, #OP_ALBUM_GAIN, - #OP_TRACK_GAIN, or #OP_ABSOLUTE_GAIN. - \param _gain_offset_q8 The gain offset to apply, in 1/256ths of a dB. - \return 0 on success or a negative value on error. - \retval #OP_EINVAL The \a _gain_type was unrecognized.*/ -int op_set_gain_offset(OggOpusFile *_of, - int _gain_type,opus_int32 _gain_offset_q8) OP_ARG_NONNULL(1); - -/**Sets whether or not dithering is enabled for 16-bit decoding. - By default, when libopusfile is compiled to use floating-point - internally, calling op_read() or op_read_stereo() will first decode to - float, and then convert to fixed-point using noise-shaping dithering. - This flag can be used to disable that dithering. - When the application uses op_read_float() or op_read_float_stereo(), or when - the library has been compiled to decode directly to fixed point, this flag - has no effect. - \param _of The \c OggOpusFile on which to enable or disable dithering. - \param _enabled A non-zero value to enable dithering, or 0 to disable it.*/ -void op_set_dither_enabled(OggOpusFile *_of,int _enabled) OP_ARG_NONNULL(1); - -/**Reads more samples from the stream. - \note Although \a _buf_size must indicate the total number of values that - can be stored in \a _pcm, the return value is the number of samples - per channel. - This is done because -
    -
  1. The channel count cannot be known a priori (reading more samples might - advance us into the next link, with a different channel count), so - \a _buf_size cannot also be in units of samples per channel,
  2. -
  3. Returning the samples per channel matches the libopus API - as closely as we're able,
  4. -
  5. Returning the total number of values instead of samples per channel - would mean the caller would need a division to compute the samples per - channel, and might worry about the possibility of getting back samples - for some channels and not others, and
  6. -
  7. This approach is relatively fool-proof: if an application passes too - small a value to \a _buf_size, they will simply get fewer samples back, - and if they assume the return value is the total number of values, then - they will simply read too few (rather than reading too many and going - off the end of the buffer).
  8. -
- \param _of The \c OggOpusFile from which to read. - \param[out] _pcm A buffer in which to store the output PCM samples, as - signed native-endian 16-bit values at 48 kHz - with a nominal range of [-32768,32767). - Multiple channels are interleaved using the - Vorbis - channel ordering. - This must have room for at least \a _buf_size values. - \param _buf_size The number of values that can be stored in \a _pcm. - It is recommended that this be large enough for at - least 120 ms of data at 48 kHz per channel (5760 - values per channel). - Smaller buffers will simply return less data, possibly - consuming more memory to buffer the data internally. - libopusfile may return less data than - requested. - If so, there is no guarantee that the remaining data - in \a _pcm will be unmodified. - \param[out] _li The index of the link this data was decoded from. - You may pass NULL if you do not need this - information. - If this function fails (returning a negative value), - this parameter is left unset. - \return The number of samples read per channel on success, or a negative - value on failure. - The channel count can be retrieved on success by calling - op_head(_of,*_li). - The number of samples returned may be 0 if the buffer was too small - to store even a single sample for all channels, or if end-of-file - was reached. - The list of possible failure codes follows. - Most of them can only be returned by unseekable, chained streams - that encounter a new link. - \retval #OP_HOLE There was a hole in the data, and some samples - may have been skipped. - Call this function again to continue decoding - past the hole. - \retval #OP_EREAD An underlying read operation failed. - This may signal a truncation attack from an - source. - \retval #OP_EFAULT An internal memory allocation failed. - \retval #OP_EIMPL An unseekable stream encountered a new link that - used a feature that is not implemented, such as - an unsupported channel family. - \retval #OP_EINVAL The stream was only partially open. - \retval #OP_ENOTFORMAT An unseekable stream encountered a new link that - did not have any logical Opus streams in it. - \retval #OP_EBADHEADER An unseekable stream encountered a new link with a - required header packet that was not properly - formatted, contained illegal values, or was - missing altogether. - \retval #OP_EVERSION An unseekable stream encountered a new link with - an ID header that contained an unrecognized - version number. - \retval #OP_EBADPACKET Failed to properly decode the next packet. - \retval #OP_EBADLINK We failed to find data we had seen before. - \retval #OP_EBADTIMESTAMP An unseekable stream encountered a new link with - a starting timestamp that failed basic validity - checks.*/ -OP_WARN_UNUSED_RESULT int op_read(OggOpusFile *_of, - opus_int16 *_pcm,int _buf_size,int *_li) OP_ARG_NONNULL(1); - -/**Reads more samples from the stream. - \note Although \a _buf_size must indicate the total number of values that - can be stored in \a _pcm, the return value is the number of samples - per channel. -
    -
  1. The channel count cannot be known a priori (reading more samples might - advance us into the next link, with a different channel count), so - \a _buf_size cannot also be in units of samples per channel,
  2. -
  3. Returning the samples per channel matches the libopus API - as closely as we're able,
  4. -
  5. Returning the total number of values instead of samples per channel - would mean the caller would need a division to compute the samples per - channel, and might worry about the possibility of getting back samples - for some channels and not others, and
  6. -
  7. This approach is relatively fool-proof: if an application passes too - small a value to \a _buf_size, they will simply get fewer samples back, - and if they assume the return value is the total number of values, then - they will simply read too few (rather than reading too many and going - off the end of the buffer).
  8. -
- \param _of The \c OggOpusFile from which to read. - \param[out] _pcm A buffer in which to store the output PCM samples as - signed floats at 48 kHz with a nominal range of - [-1.0,1.0]. - Multiple channels are interleaved using the - Vorbis - channel ordering. - This must have room for at least \a _buf_size floats. - \param _buf_size The number of floats that can be stored in \a _pcm. - It is recommended that this be large enough for at - least 120 ms of data at 48 kHz per channel (5760 - samples per channel). - Smaller buffers will simply return less data, possibly - consuming more memory to buffer the data internally. - If less than \a _buf_size values are returned, - libopusfile makes no guarantee that the - remaining data in \a _pcm will be unmodified. - \param[out] _li The index of the link this data was decoded from. - You may pass NULL if you do not need this - information. - If this function fails (returning a negative value), - this parameter is left unset. - \return The number of samples read per channel on success, or a negative - value on failure. - The channel count can be retrieved on success by calling - op_head(_of,*_li). - The number of samples returned may be 0 if the buffer was too small - to store even a single sample for all channels, or if end-of-file - was reached. - The list of possible failure codes follows. - Most of them can only be returned by unseekable, chained streams - that encounter a new link. - \retval #OP_HOLE There was a hole in the data, and some samples - may have been skipped. - Call this function again to continue decoding - past the hole. - \retval #OP_EREAD An underlying read operation failed. - This may signal a truncation attack from an - source. - \retval #OP_EFAULT An internal memory allocation failed. - \retval #OP_EIMPL An unseekable stream encountered a new link that - used a feature that is not implemented, such as - an unsupported channel family. - \retval #OP_EINVAL The stream was only partially open. - \retval #OP_ENOTFORMAT An unseekable stream encountered a new link that - did not have any logical Opus streams in it. - \retval #OP_EBADHEADER An unseekable stream encountered a new link with a - required header packet that was not properly - formatted, contained illegal values, or was - missing altogether. - \retval #OP_EVERSION An unseekable stream encountered a new link with - an ID header that contained an unrecognized - version number. - \retval #OP_EBADPACKET Failed to properly decode the next packet. - \retval #OP_EBADLINK We failed to find data we had seen before. - \retval #OP_EBADTIMESTAMP An unseekable stream encountered a new link with - a starting timestamp that failed basic validity - checks.*/ -OP_WARN_UNUSED_RESULT int op_read_float(OggOpusFile *_of, - float *_pcm,int _buf_size,int *_li) OP_ARG_NONNULL(1); - -/**Reads more samples from the stream and downmixes to stereo, if necessary. - This function is intended for simple players that want a uniform output - format, even if the channel count changes between links in a chained - stream. - \note \a _buf_size indicates the total number of values that can be stored - in \a _pcm, while the return value is the number of samples per - channel, even though the channel count is known, for consistency with - op_read(). - \param _of The \c OggOpusFile from which to read. - \param[out] _pcm A buffer in which to store the output PCM samples, as - signed native-endian 16-bit values at 48 kHz - with a nominal range of [-32768,32767). - The left and right channels are interleaved in the - buffer. - This must have room for at least \a _buf_size values. - \param _buf_size The number of values that can be stored in \a _pcm. - It is recommended that this be large enough for at - least 120 ms of data at 48 kHz per channel (11520 - values total). - Smaller buffers will simply return less data, possibly - consuming more memory to buffer the data internally. - If less than \a _buf_size values are returned, - libopusfile makes no guarantee that the - remaining data in \a _pcm will be unmodified. - \return The number of samples read per channel on success, or a negative - value on failure. - The number of samples returned may be 0 if the buffer was too small - to store even a single sample for both channels, or if end-of-file - was reached. - The list of possible failure codes follows. - Most of them can only be returned by unseekable, chained streams - that encounter a new link. - \retval #OP_HOLE There was a hole in the data, and some samples - may have been skipped. - Call this function again to continue decoding - past the hole. - \retval #OP_EREAD An underlying read operation failed. - This may signal a truncation attack from an - source. - \retval #OP_EFAULT An internal memory allocation failed. - \retval #OP_EIMPL An unseekable stream encountered a new link that - used a feature that is not implemented, such as - an unsupported channel family. - \retval #OP_EINVAL The stream was only partially open. - \retval #OP_ENOTFORMAT An unseekable stream encountered a new link that - did not have any logical Opus streams in it. - \retval #OP_EBADHEADER An unseekable stream encountered a new link with a - required header packet that was not properly - formatted, contained illegal values, or was - missing altogether. - \retval #OP_EVERSION An unseekable stream encountered a new link with - an ID header that contained an unrecognized - version number. - \retval #OP_EBADPACKET Failed to properly decode the next packet. - \retval #OP_EBADLINK We failed to find data we had seen before. - \retval #OP_EBADTIMESTAMP An unseekable stream encountered a new link with - a starting timestamp that failed basic validity - checks.*/ -OP_WARN_UNUSED_RESULT int op_read_stereo(OggOpusFile *_of, - opus_int16 *_pcm,int _buf_size) OP_ARG_NONNULL(1); - -/**Reads more samples from the stream and downmixes to stereo, if necessary. - This function is intended for simple players that want a uniform output - format, even if the channel count changes between links in a chained - stream. - \note \a _buf_size indicates the total number of values that can be stored - in \a _pcm, while the return value is the number of samples per - channel, even though the channel count is known, for consistency with - op_read_float(). - \param _of The \c OggOpusFile from which to read. - \param[out] _pcm A buffer in which to store the output PCM samples, as - signed floats at 48 kHz with a nominal range of - [-1.0,1.0]. - The left and right channels are interleaved in the - buffer. - This must have room for at least \a _buf_size values. - \param _buf_size The number of values that can be stored in \a _pcm. - It is recommended that this be large enough for at - least 120 ms of data at 48 kHz per channel (11520 - values total). - Smaller buffers will simply return less data, possibly - consuming more memory to buffer the data internally. - If less than \a _buf_size values are returned, - libopusfile makes no guarantee that the - remaining data in \a _pcm will be unmodified. - \return The number of samples read per channel on success, or a negative - value on failure. - The number of samples returned may be 0 if the buffer was too small - to store even a single sample for both channels, or if end-of-file - was reached. - The list of possible failure codes follows. - Most of them can only be returned by unseekable, chained streams - that encounter a new link. - \retval #OP_HOLE There was a hole in the data, and some samples - may have been skipped. - Call this function again to continue decoding - past the hole. - \retval #OP_EREAD An underlying read operation failed. - This may signal a truncation attack from an - source. - \retval #OP_EFAULT An internal memory allocation failed. - \retval #OP_EIMPL An unseekable stream encountered a new link that - used a feature that is not implemented, such as - an unsupported channel family. - \retval #OP_EINVAL The stream was only partially open. - \retval #OP_ENOTFORMAT An unseekable stream encountered a new link that - that did not have any logical Opus streams in it. - \retval #OP_EBADHEADER An unseekable stream encountered a new link with a - required header packet that was not properly - formatted, contained illegal values, or was - missing altogether. - \retval #OP_EVERSION An unseekable stream encountered a new link with - an ID header that contained an unrecognized - version number. - \retval #OP_EBADPACKET Failed to properly decode the next packet. - \retval #OP_EBADLINK We failed to find data we had seen before. - \retval #OP_EBADTIMESTAMP An unseekable stream encountered a new link with - a starting timestamp that failed basic validity - checks.*/ -OP_WARN_UNUSED_RESULT int op_read_float_stereo(OggOpusFile *_of, - float *_pcm,int _buf_size) OP_ARG_NONNULL(1); - -/*@}*/ -/*@}*/ - -# if OP_GNUC_PREREQ(4,0) -# pragma GCC visibility pop -# endif - -# if defined(__cplusplus) -} -# endif - -#endif diff --git a/src/opusfile/opusfile.pc b/src/opusfile/opusfile.pc deleted file mode 100644 index 398f8c44..00000000 --- a/src/opusfile/opusfile.pc +++ /dev/null @@ -1,15 +0,0 @@ -# opusfile installed pkg-config file - -prefix=/usr/local -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -includedir=${prefix}/include - -Name: opusfile -Description: High-level Opus decoding library -Version: 0.12 -Requires.private: ogg >= 1.3 opus >= 1.0.1 -Conflicts: -Libs: -L${libdir} -lopusfile -Libs.private: -Cflags: -I${includedir}/opus diff --git a/src/opusfile/stream.c b/src/opusfile/stream.c deleted file mode 100644 index 9421d8fa..00000000 --- a/src/opusfile/stream.c +++ /dev/null @@ -1,415 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE libopusfile SOURCE CODE IS (C) COPYRIGHT 1994-2018 * - * by the Xiph.Org Foundation and contributors https://xiph.org/ * - * * - ******************************************************************** - - function: stdio-based convenience library for opening/seeking/decoding - last mod: $Id: vorbisfile.c 17573 2010-10-27 14:53:59Z xiphmont $ - - ********************************************************************/ -//#ifdef HAVE_CONFIG_H -#include "config.h" -//#endif - -#include "internal.h" -#include -#include -#include -#include -#include -#if defined(_WIN32) -# include -#endif - -typedef struct OpusMemStream OpusMemStream; - -#define OP_MEM_SIZE_MAX (~(size_t)0>>1) -#define OP_MEM_DIFF_MAX ((ptrdiff_t)OP_MEM_SIZE_MAX) - -/*The context information needed to read from a block of memory as if it were a - file.*/ -struct OpusMemStream{ - /*The block of memory to read from.*/ - const unsigned char *data; - /*The total size of the block. - This must be at most OP_MEM_SIZE_MAX to prevent signed overflow while - seeking.*/ - ptrdiff_t size; - /*The current file position. - This is allowed to be set arbitrarily greater than size (i.e., past the end - of the block, though we will not read data past the end of the block), but - is not allowed to be negative (i.e., before the beginning of the block).*/ - ptrdiff_t pos; -}; - -static int op_fread(void *_stream,unsigned char *_ptr,int _buf_size){ - FILE *stream; - size_t ret; - /*Check for empty read.*/ - if(_buf_size<=0)return 0; - stream=(FILE *)_stream; - ret=fread(_ptr,1,_buf_size,stream); - OP_ASSERT(ret<=(size_t)_buf_size); - /*If ret==0 and !feof(stream), there was a read error.*/ - return ret>0||feof(stream)?(int)ret:OP_EREAD; -} - -static int op_fseek(void *_stream,opus_int64 _offset,int _whence){ -#if defined(_WIN32) - /*_fseeki64() is not exposed until MSVCRT80. - This is the default starting with MSVC 2005 (_MSC_VER>=1400), but we want - to allow linking against older MSVCRT versions for compatibility back to - XP without installing extra runtime libraries. - i686-pc-mingw32 does not have fseeko() and requires - __MSVCRT_VERSION__>=0x800 for _fseeki64(), which screws up linking with - other libraries (that don't use MSVCRT80 from MSVC 2005 by default). - i686-w64-mingw32 does have fseeko() and respects _FILE_OFFSET_BITS, but I - don't know how to detect that at compile time. - We could just use fseeko64() (which is available in both), but it's - implemented using fgetpos()/fsetpos() just like this code, except without - the overflow checking, so we prefer our version.*/ - opus_int64 pos; - /*We don't use fpos_t directly because it might be a struct if __STDC__ is - non-zero or _INTEGRAL_MAX_BITS < 64. - I'm not certain when the latter is true, but someone could in theory set - the former. - Either way, it should be binary compatible with a normal 64-bit int (this - assumption is not portable, but I believe it is true for MSVCRT).*/ - OP_ASSERT(sizeof(pos)==sizeof(fpos_t)); - /*Translate the seek to an absolute one.*/ - if(_whence==SEEK_CUR){ - int ret; - ret=fgetpos((FILE *)_stream,(fpos_t *)&pos); - if(ret)return ret; - } - else if(_whence==SEEK_END)pos=_filelengthi64(_fileno((FILE *)_stream)); - else if(_whence==SEEK_SET)pos=0; - else return -1; - /*Check for errors or overflow.*/ - if(pos<0||_offset<-pos||_offset>OP_INT64_MAX-pos)return -1; - pos+=_offset; - return fsetpos((FILE *)_stream,(fpos_t *)&pos); -#else - /*This function actually conforms to the SUSv2 and POSIX.1-2001, so we prefer - it except on Windows.*/ - return fseeko((FILE *)_stream,(off_t)_offset,_whence); -#endif -} - -static opus_int64 op_ftell(void *_stream){ -#if defined(_WIN32) - /*_ftelli64() is not exposed until MSVCRT80, and ftello()/ftello64() have - the same problems as fseeko()/fseeko64() in MingW. - See above for a more detailed explanation.*/ - opus_int64 pos; - OP_ASSERT(sizeof(pos)==sizeof(fpos_t)); - return fgetpos((FILE *)_stream,(fpos_t *)&pos)?-1:pos; -#else - /*This function actually conforms to the SUSv2 and POSIX.1-2001, so we prefer - it except on Windows.*/ - return ftello((FILE *)_stream); -#endif -} - -static const OpusFileCallbacks OP_FILE_CALLBACKS={ - op_fread, - op_fseek, - op_ftell, - (op_close_func)fclose -}; - -#if defined(_WIN32) -# include -# include - -/*Windows doesn't accept UTF-8 by default, and we don't have a wchar_t API, - so if we just pass the path to fopen(), then there'd be no way for a user - of our API to open a Unicode filename. - Instead, we translate from UTF-8 to UTF-16 and use Windows' wchar_t API. - This makes this API more consistent with platforms where the character set - used by fopen is the same as used on disk, which is generally UTF-8, and - with our metadata API, which always uses UTF-8.*/ -static wchar_t *op_utf8_to_utf16(const char *_src){ - wchar_t *dst; - size_t len; - len=strlen(_src); - /*Worst-case output is 1 wide character per 1 input character.*/ - dst=(wchar_t *)_ogg_malloc(sizeof(*dst)*(len+1)); - if(dst!=NULL){ - size_t si; - size_t di; - for(di=si=0;si=0x80U){ - /*This is a 2-byte sequence that is not overlong.*/ - dst[di++]=w; - si++; - continue; - } - } - else{ - int c2; - /*This is safe, because c1 was not 0 and _src is NUL-terminated.*/ - c2=(unsigned char)_src[si+2]; - if((c2&0xC0)==0x80){ - /*Found at least two continuation bytes.*/ - if((c0&0xF0)==0xE0){ - wchar_t w; - /*Start byte says this is a 3-byte sequence.*/ - w=(c0&0xF)<<12|(c1&0x3F)<<6|c2&0x3F; - if(w>=0x800U&&(w<0xD800||w>=0xE000)&&w<0xFFFE){ - /*This is a 3-byte sequence that is not overlong, not a - UTF-16 surrogate pair value, and not a 'not a character' - value.*/ - dst[di++]=w; - si+=2; - continue; - } - } - else{ - int c3; - /*This is safe, because c2 was not 0 and _src is - NUL-terminated.*/ - c3=(unsigned char)_src[si+3]; - if((c3&0xC0)==0x80){ - /*Found at least three continuation bytes.*/ - if((c0&0xF8)==0xF0){ - opus_uint32 w; - /*Start byte says this is a 4-byte sequence.*/ - w=(c0&7)<<18|(c1&0x3F)<<12|(c2&0x3F)<<6&(c3&0x3F); - if(w>=0x10000U&&w<0x110000U){ - /*This is a 4-byte sequence that is not overlong and not - greater than the largest valid Unicode code point. - Convert it to a surrogate pair.*/ - w-=0x10000; - dst[di++]=(wchar_t)(0xD800+(w>>10)); - dst[di++]=(wchar_t)(0xDC00+(w&0x3FF)); - si+=3; - continue; - } - } - } - } - } - } - } - } - /*If we got here, we encountered an illegal UTF-8 sequence.*/ - _ogg_free(dst); - return NULL; - } - OP_ASSERT(di<=len); - dst[di]='\0'; - } - return dst; -} - -/*fsetpos() internally dispatches to the win32 API call SetFilePointer(). - According to SetFilePointer()'s documentation [0], the behavior is - undefined if you do not call it on "a file stored on a seeking device". - However, none of the MSVCRT seeking functions verify what kind of file is - being used before calling it (which I believe is a bug, since they are - supposed to fail and return an error, but it is a bug that has been there - for multiple decades now). - In practice, SetFilePointer() appears to succeed for things like stdin, - even when you are not just piping in a regular file, which prevents the use - of this API to determine whether it is possible to seek in a file at all. - Therefore, we take the approach recommended by the SetFilePointer() - documentation and confirm the type of file using GetFileType() first. - We do this once, when the file is opened, and return the corresponding - callback in order to avoid an extra win32 API call on every seek in the - common case. - Hopefully the return value of GetFileType() cannot actually change for the - lifetime of a file handle. - [0] https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-setfilepointer -*/ -static int op_fseek_fail(void *_stream,opus_int64 _offset,int _whence){ - (void)_stream; - (void)_offset; - (void)_whence; - return -1; -} - -static const OpusFileCallbacks OP_UNSEEKABLE_FILE_CALLBACKS={ - op_fread, - op_fseek_fail, - op_ftell, - (op_close_func)fclose -}; - -# define WIN32_LEAN_AND_MEAN -# define WIN32_EXTRA_LEAN -# include - -static const OpusFileCallbacks *op_get_file_callbacks(FILE *_fp){ - intptr_t h_file; - h_file=_get_osfhandle(_fileno(_fp)); - if(h_file!=-1 - &&(GetFileType((HANDLE)h_file)&~FILE_TYPE_REMOTE)==FILE_TYPE_DISK){ - return &OP_FILE_CALLBACKS; - } - return &OP_UNSEEKABLE_FILE_CALLBACKS; -} -#else -static const OpusFileCallbacks *op_get_file_callbacks(FILE *_fp){ - (void)_fp; - return &OP_FILE_CALLBACKS; -} -#endif - -void *op_fopen(OpusFileCallbacks *_cb,const char *_path,const char *_mode){ - FILE *fp; -#if !defined(_WIN32) - fp=fopen(_path,_mode); -#else - fp=NULL; - { - wchar_t *wpath; - wchar_t *wmode; - wpath=op_utf8_to_utf16(_path); - wmode=op_utf8_to_utf16(_mode); - if(wmode==NULL)errno=EINVAL; - else if(wpath==NULL)errno=ENOENT; - else fp=_wfopen(wpath,wmode); - _ogg_free(wmode); - _ogg_free(wpath); - } -#endif - if(fp!=NULL)*_cb=*op_get_file_callbacks(fp); - return fp; -} - -void *op_fdopen(OpusFileCallbacks *_cb,int _fd,const char *_mode){ - FILE *fp; - fp=fdopen(_fd,_mode); - if(fp!=NULL)*_cb=*op_get_file_callbacks(fp); - return fp; -} - -void *op_freopen(OpusFileCallbacks *_cb,const char *_path,const char *_mode, - void *_stream){ - FILE *fp; -#if !defined(_WIN32) - fp=freopen(_path,_mode,(FILE *)_stream); -#else - fp=NULL; - { - wchar_t *wpath; - wchar_t *wmode; - wpath=op_utf8_to_utf16(_path); - wmode=op_utf8_to_utf16(_mode); - if(wmode==NULL)errno=EINVAL; - else if(wpath==NULL)errno=ENOENT; - else fp=_wfreopen(wpath,wmode,(FILE *)_stream); - _ogg_free(wmode); - _ogg_free(wpath); - } -#endif - if(fp!=NULL)*_cb=*op_get_file_callbacks(fp); - return fp; -} - -static int op_mem_read(void *_stream,unsigned char *_ptr,int _buf_size){ - OpusMemStream *stream; - ptrdiff_t size; - ptrdiff_t pos; - stream=(OpusMemStream *)_stream; - /*Check for empty read.*/ - if(_buf_size<=0)return 0; - size=stream->size; - pos=stream->pos; - /*Check for EOF.*/ - if(pos>=size)return 0; - /*Check for a short read.*/ - _buf_size=(int)OP_MIN(size-pos,_buf_size); - memcpy(_ptr,stream->data+pos,_buf_size); - pos+=_buf_size; - stream->pos=pos; - return _buf_size; -} - -static int op_mem_seek(void *_stream,opus_int64 _offset,int _whence){ - OpusMemStream *stream; - ptrdiff_t pos; - stream=(OpusMemStream *)_stream; - pos=stream->pos; - OP_ASSERT(pos>=0); - switch(_whence){ - case SEEK_SET:{ - /*Check for overflow:*/ - if(_offset<0||_offset>OP_MEM_DIFF_MAX)return -1; - pos=(ptrdiff_t)_offset; - }break; - case SEEK_CUR:{ - /*Check for overflow:*/ - if(_offset<-pos||_offset>OP_MEM_DIFF_MAX-pos)return -1; - pos=(ptrdiff_t)(pos+_offset); - }break; - case SEEK_END:{ - ptrdiff_t size; - size=stream->size; - OP_ASSERT(size>=0); - /*Check for overflow:*/ - if(_offset<-size||_offset>OP_MEM_DIFF_MAX-size)return -1; - pos=(ptrdiff_t)(size+_offset); - }break; - default:return -1; - } - stream->pos=pos; - return 0; -} - -static opus_int64 op_mem_tell(void *_stream){ - OpusMemStream *stream; - stream=(OpusMemStream *)_stream; - return (ogg_int64_t)stream->pos; -} - -static int op_mem_close(void *_stream){ - _ogg_free(_stream); - return 0; -} - -static const OpusFileCallbacks OP_MEM_CALLBACKS={ - op_mem_read, - op_mem_seek, - op_mem_tell, - op_mem_close -}; - -void *op_mem_stream_create(OpusFileCallbacks *_cb, - const unsigned char *_data,size_t _size){ - OpusMemStream *stream; - if(_size>OP_MEM_SIZE_MAX)return NULL; - stream=(OpusMemStream *)_ogg_malloc(sizeof(*stream)); - if(stream!=NULL){ - *_cb=*&OP_MEM_CALLBACKS; - stream->data=_data; - stream->size=_size; - stream->pos=0; - } - return stream; -} diff --git a/src/spiram-fast.h b/src/spiram-fast.h index ce568873..721d958b 100644 --- a/src/spiram-fast.h +++ b/src/spiram-fast.h @@ -1,23 +1,23 @@ /* - spiram-fast - Fast, hardcoded interface for SPI-based RAMs, allowing DIO + spiram-fast - Fast, hardcoded interface for SPI-based RAMs, allowing DIO mode to be used and speeding up individual SPI operations significantly. - Copyright (c) 2020 Earle F. Philhower, III All rights reserved. + Copyright (c) 2020 Earle F. Philhower, III All rights reserved. - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -30,216 +30,217 @@ #ifndef ESP32 class ESP8266SPIRAM { - private: - typedef struct { - volatile uint32_t spi_cmd; // The SPI can change this behind our backs, so volatile! - uint32_t spi_addr; - uint32_t spi_ctrl; - uint32_t spi_ctrl1; // undocumented? Not shown in the reg map - uint32_t spi_rd_status; - uint32_t spi_ctrl2; - uint32_t spi_clock; - uint32_t spi_user; - uint32_t spi_user1; - uint32_t spi_user2; - uint32_t spi_wr_status; - uint32_t spi_pin; - uint32_t spi_slave; - uint32_t spi_slave1; - uint32_t spi_slave2; - uint32_t spi_slave3; - uint32_t spi_w[16]; // NOTE: You need a memory barrier before reading these after a read xaction - uint32_t spi_ext3; - } spi_regs; - spi_regs *spi1 = (spi_regs*)&SPI1CMD; - - // The standard HSPI bus pins are used - static constexpr uint8_t cs = 15; - static constexpr uint8_t miso = 12; - static constexpr uint8_t mosi = 13; - static constexpr uint8_t sck = 14; - - uint32_t spi_clkval; - uint32_t csPin; - bool swCS; - - typedef enum { sio = 0, dio = 1 } iotype; - static constexpr iotype hspi_mode = sio; - - static constexpr int read_delay = (hspi_mode == dio) ? 4-1 : 0; - - void spi_init() - { - pinMode(sck, SPECIAL); - pinMode(miso, SPECIAL); - pinMode(mosi, SPECIAL); - pinMode(csPin, swCS ? OUTPUT : SPECIAL ); - spi1->spi_cmd = 0; - GPMUX &= ~(1 << 9); - spi1->spi_clock = spi_clkval; - spi1->spi_ctrl = 0 ; // MSB first + plain SPI mode - spi1->spi_ctrl1 = 0; // undocumented, clear for safety? - spi1->spi_ctrl2 = 0; // No add'l delays on signals - spi1->spi_user2 = 0; // No insn or insn_bits to set +private: + typedef struct { + volatile uint32_t spi_cmd; // The SPI can change this behind our backs, so volatile! + uint32_t spi_addr; + uint32_t spi_ctrl; + uint32_t spi_ctrl1; // undocumented? Not shown in the reg map + uint32_t spi_rd_status; + uint32_t spi_ctrl2; + uint32_t spi_clock; + uint32_t spi_user; + uint32_t spi_user1; + uint32_t spi_user2; + uint32_t spi_wr_status; + uint32_t spi_pin; + uint32_t spi_slave; + uint32_t spi_slave1; + uint32_t spi_slave2; + uint32_t spi_slave3; + uint32_t spi_w[16]; // NOTE: You need a memory barrier before reading these after a read xaction + uint32_t spi_ext3; + } spi_regs; + spi_regs *spi1 = (spi_regs*)&SPI1CMD; + + // The standard HSPI bus pins are used + static constexpr uint8_t cs = 15; + static constexpr uint8_t miso = 12; + static constexpr uint8_t mosi = 13; + static constexpr uint8_t sck = 14; + + uint32_t spi_clkval; + uint32_t csPin; + bool swCS; + + typedef enum { sio = 0, dio = 1 } iotype; + static constexpr iotype hspi_mode = sio; + + static constexpr int read_delay = (hspi_mode == dio) ? 4 - 1 : 0; + + void spi_init() { + pinMode(sck, SPECIAL); + pinMode(miso, SPECIAL); + pinMode(mosi, SPECIAL); + pinMode(csPin, swCS ? OUTPUT : SPECIAL); + spi1->spi_cmd = 0; + GPMUX &= ~(1 << 9); + spi1->spi_clock = spi_clkval; + spi1->spi_ctrl = 0 ; // MSB first + plain SPI mode + spi1->spi_ctrl1 = 0; // undocumented, clear for safety? + spi1->spi_ctrl2 = 0; // No add'l delays on signals + spi1->spi_user2 = 0; // No insn or insn_bits to set + } + + // The SPI hardware cannot make the "command" portion dual or quad, only the addr and data + // So using the command portion of the cycle will not work. Concatenate the address + // and command into a single 32-bit chunk "address" which will be sent across both bits. + void spi_writetransaction(int addr, int addr_bits, int dummy_bits, int data_bits, iotype dual) { + // Ensure no writes are still ongoing + while (spi1->spi_cmd & SPIBUSY) { + delay(0); } - // The SPI hardware cannot make the "command" portion dual or quad, only the addr and data - // So using the command portion of the cycle will not work. Concatenate the address - // and command into a single 32-bit chunk "address" which will be sent across both bits. - void spi_writetransaction(int addr, int addr_bits, int dummy_bits, int data_bits, iotype dual) - { - // Ensure no writes are still ongoing - while (spi1->spi_cmd & SPIBUSY) { delay(0); } - - spi1->spi_addr = addr; - spi1->spi_user = (addr_bits? SPIUADDR : 0) | (dummy_bits ? SPIUDUMMY : 0) | (data_bits ? SPIUMOSI : 0) | (dual ? SPIUFWDIO : 0); - spi1->spi_user1 = (addr_bits << 26) | (data_bits << 17) | dummy_bits; - // No need to set spi_user2, insn field never used - __asm ( "" ::: "memory" ); - if (swCS) { - pinMode(csPin, OUTPUT); - digitalWrite(csPin, LOW); - spi1->spi_cmd = SPIBUSY; - while (spi1->spi_cmd & SPIBUSY) { delay(0); } - digitalWrite(csPin, HIGH); - } else { - spi1->spi_cmd = SPIBUSY; - // The write may continue on in the background + spi1->spi_addr = addr; + spi1->spi_user = (addr_bits ? SPIUADDR : 0) | (dummy_bits ? SPIUDUMMY : 0) | (data_bits ? SPIUMOSI : 0) | (dual ? SPIUFWDIO : 0); + spi1->spi_user1 = (addr_bits << 26) | (data_bits << 17) | dummy_bits; + // No need to set spi_user2, insn field never used + __asm("" ::: "memory"); + if (swCS) { + pinMode(csPin, OUTPUT); + digitalWrite(csPin, LOW); + spi1->spi_cmd = SPIBUSY; + while (spi1->spi_cmd & SPIBUSY) { + delay(0); } + digitalWrite(csPin, HIGH); + } else { + spi1->spi_cmd = SPIBUSY; + // The write may continue on in the background } + } - uint32_t spi_readtransaction(int addr, int addr_bits, int dummy_bits, int data_bits, iotype dual) - { - // Ensure no writes are still ongoing - while (spi1->spi_cmd & SPIBUSY) { delay(0); } - - spi1->spi_addr = addr; - spi1->spi_user = (addr_bits? SPIUADDR : 0) | (dummy_bits ? SPIUDUMMY : 0) | SPIUMISO | (dual ? SPIUFWDIO : 0); - spi1->spi_user1 = (addr_bits << 26) | (data_bits << 8) | dummy_bits; - // No need to set spi_user2, insn field never used - __asm ( "" ::: "memory" ); - if (swCS) { - pinMode(csPin, OUTPUT); - digitalWrite(csPin, LOW); - } - spi1->spi_cmd = SPIBUSY; - while (spi1->spi_cmd & SPIBUSY) { delay(0); } - __asm ( "" ::: "memory" ); - if (swCS) { - digitalWrite(csPin, HIGH); - } - return spi1->spi_w[0]; + uint32_t spi_readtransaction(int addr, int addr_bits, int dummy_bits, int data_bits, iotype dual) { + // Ensure no writes are still ongoing + while (spi1->spi_cmd & SPIBUSY) { + delay(0); } - public: - ESP8266SPIRAM() - { - /* noop */ + spi1->spi_addr = addr; + spi1->spi_user = (addr_bits ? SPIUADDR : 0) | (dummy_bits ? SPIUDUMMY : 0) | SPIUMISO | (dual ? SPIUFWDIO : 0); + spi1->spi_user1 = (addr_bits << 26) | (data_bits << 8) | dummy_bits; + // No need to set spi_user2, insn field never used + __asm("" ::: "memory"); + if (swCS) { + pinMode(csPin, OUTPUT); + digitalWrite(csPin, LOW); } - ~ESP8266SPIRAM() - { - end(); + spi1->spi_cmd = SPIBUSY; + while (spi1->spi_cmd & SPIBUSY) { + delay(0); } - void readBytes(uint32_t addr, void *destV, int count) - { - uint8_t *dest = (uint8_t*)destV; - while (count > 0) { - int toRead = std::min(count, 64); - spi_readtransaction((0x03 << 24) | addr, 32-1, read_delay, toRead * 8 - 1, hspi_mode); - __asm ( "" ::: "memory" ); - uint32_t work[16]; // FIFO image in RAM that we can byte address - int toCopy = (toRead + 3) / 4; // make sure all 32b values updated - for (auto i = 0; i < toCopy; i++) { - work[i] = spi1->spi_w[i]; - } - memcpy(dest, work, toRead); - count -= toRead; - dest += toRead; - addr += toRead; - } + __asm("" ::: "memory"); + if (swCS) { + digitalWrite(csPin, HIGH); } - - void writeBytes(uint32_t addr, const void *srcV, int count) - { - const uint8_t *src = (const uint8_t *)srcV; - while (count > 0) { - uint32_t work[16]; // FIFO image in RAM that we can byte address - int toWrite = std::min(count, 64); - memcpy((void *)work, src, toWrite); - int toCopy = (toWrite + 3) / 4; // make sure all 32b values updated - - // Ensure the last SPI is done so we don't overwrite unsent data - while (spi1->spi_cmd & SPIBUSY) { delay(0); } - for (auto i = 0; i < toCopy; i++) { - spi1->spi_w[i] = work[i]; - } - spi_writetransaction((0x02 << 24) | addr, 32 - 1, 0, toWrite * 8 - 1, hspi_mode); - count -= toWrite; - src += toWrite; - addr += toWrite; + return spi1->spi_w[0]; + } + +public: + ESP8266SPIRAM() { + /* noop */ + } + ~ESP8266SPIRAM() { + end(); + } + void readBytes(uint32_t addr, void *destV, int count) { + uint8_t *dest = (uint8_t*)destV; + while (count > 0) { + int toRead = std::min(count, 64); + spi_readtransaction((0x03 << 24) | addr, 32 - 1, read_delay, toRead * 8 - 1, hspi_mode); + __asm("" ::: "memory"); + uint32_t work[16]; // FIFO image in RAM that we can byte address + int toCopy = (toRead + 3) / 4; // make sure all 32b values updated + for (auto i = 0; i < toCopy; i++) { + work[i] = spi1->spi_w[i]; } + memcpy(dest, work, toRead); + count -= toRead; + dest += toRead; + addr += toRead; } - - void begin(int freqMHz, int cs_pin) - { - if (freqMHz >= 40) { - spi_clkval = 0x00001001; - } else if (freqMHz >= 30) { - spi_clkval = 0x00002001; - } else if (freqMHz >= 20) { - spi_clkval = 0x00041001; - } else if (freqMHz >= 10) { - spi_clkval = 0x000c1001; - } else if (freqMHz >= 5) { - spi_clkval = 0x001c1001; - } else { - spi_clkval = 0x009c1001; + } + + void writeBytes(uint32_t addr, const void *srcV, int count) { + const uint8_t *src = (const uint8_t *)srcV; + while (count > 0) { + uint32_t work[16]; // FIFO image in RAM that we can byte address + int toWrite = std::min(count, 64); + memcpy((void *)work, src, toWrite); + int toCopy = (toWrite + 3) / 4; // make sure all 32b values updated + + // Ensure the last SPI is done so we don't overwrite unsent data + while (spi1->spi_cmd & SPIBUSY) { + delay(0); } - csPin = cs_pin; - swCS = csPin != cs; - - // Manually reset chip from DIO to SIO mode (HW SPI has issues with <8 bits/clocks total output) - digitalWrite(csPin, HIGH); - digitalWrite(mosi, HIGH); - digitalWrite(miso, HIGH); + for (auto i = 0; i < toCopy; i++) { + spi1->spi_w[i] = work[i]; + } + spi_writetransaction((0x02 << 24) | addr, 32 - 1, 0, toWrite * 8 - 1, hspi_mode); + count -= toWrite; + src += toWrite; + addr += toWrite; + } + } + + void begin(int freqMHz, int cs_pin) { + if (freqMHz >= 40) { + spi_clkval = 0x00001001; + } else if (freqMHz >= 30) { + spi_clkval = 0x00002001; + } else if (freqMHz >= 20) { + spi_clkval = 0x00041001; + } else if (freqMHz >= 10) { + spi_clkval = 0x000c1001; + } else if (freqMHz >= 5) { + spi_clkval = 0x001c1001; + } else { + spi_clkval = 0x009c1001; + } + csPin = cs_pin; + swCS = csPin != cs; + + // Manually reset chip from DIO to SIO mode (HW SPI has issues with <8 bits/clocks total output) + digitalWrite(csPin, HIGH); + digitalWrite(mosi, HIGH); + digitalWrite(miso, HIGH); + digitalWrite(sck, LOW); + pinMode(csPin, OUTPUT); + pinMode(miso, OUTPUT); + pinMode(mosi, OUTPUT); + pinMode(sck, OUTPUT); + digitalWrite(csPin, HIGH); + delay(100); + digitalWrite(csPin, LOW); + delay(1); + for (int i = 0; i < 4; i++) { + digitalWrite(sck, HIGH); + delay(1); digitalWrite(sck, LOW); - pinMode(csPin, OUTPUT); - pinMode(miso, OUTPUT); - pinMode(mosi, OUTPUT); - pinMode(sck, OUTPUT); - digitalWrite(csPin, HIGH); - delay(100); - digitalWrite(csPin, LOW); delay(1); - for (int i = 0; i < 4; i++) { - digitalWrite(sck, HIGH); - delay(1); - digitalWrite(sck, LOW); - delay(1); - } - digitalWrite(csPin, HIGH); + } + digitalWrite(csPin, HIGH); - // Set up the SPI regs - spi_init(); + // Set up the SPI regs + spi_init(); - // Enable streaming read/write mode - spi1->spi_w[0] = 0x40; - spi_writetransaction(0x01<<24, 8-1, 0, 8-1, sio); + // Enable streaming read/write mode + spi1->spi_w[0] = 0x40; + spi_writetransaction(0x01 << 24, 8 - 1, 0, 8 - 1, sio); - if (hspi_mode == dio) { - // Ramp up to DIO mode - spi_writetransaction(0x3b<<24, 8-1, 0, 0, sio); - spi1->spi_ctrl |= SPICDIO | SPICFASTRD; - } + if (hspi_mode == dio) { + // Ramp up to DIO mode + spi_writetransaction(0x3b << 24, 8 - 1, 0, 0, sio); + spi1->spi_ctrl |= SPICDIO | SPICFASTRD; } + } - void end() - { - pinMode(csPin, INPUT); - pinMode(miso, INPUT); - pinMode(mosi, INPUT); - pinMode(sck, INPUT); - } + void end() { + pinMode(csPin, INPUT); + pinMode(miso, INPUT); + pinMode(mosi, INPUT); + pinMode(sck, INPUT); + } }; @@ -248,120 +249,114 @@ class ESP8266SPIRAM { #include class ESP8266SPIRAM { - private: - uint8_t csPin; - uint32_t freq; - - // The standard HSPI bus pins are used - static constexpr uint8_t miso = 12; - static constexpr uint8_t mosi = 13; - static constexpr uint8_t sck = 14; - - public: - ESP8266SPIRAM() - { - /* noop */ - } - ~ESP8266SPIRAM() - { - end(); - } - void readBytes(uint32_t addr, void *destV, int count) - { - uint8_t *dest = (uint8_t *)destV; - SPI.beginTransaction(SPISettings(freq, MSBFIRST, SPI_MODE0)); - pinMode(csPin, OUTPUT); - digitalWrite(csPin, LOW); - uint32_t cmd = (0x03 << 24) | (addr & ((1<<24)-1)); - SPI.transfer((uint8_t)(cmd >> 24)); - SPI.transfer((uint8_t)(cmd >> 16)); - SPI.transfer((uint8_t)(cmd >> 8)); - SPI.transfer((uint8_t)(cmd >> 0)); - while (count--) { - *(dest++) = SPI.transfer((uint8_t)0); - } - pinMode(csPin, OUTPUT); - digitalWrite(csPin, HIGH); - SPI.endTransaction(); +private: + uint8_t csPin; + uint32_t freq; + + // The standard HSPI bus pins are used + static constexpr uint8_t miso = 12; + static constexpr uint8_t mosi = 13; + static constexpr uint8_t sck = 14; + +public: + ESP8266SPIRAM() { + /* noop */ + } + ~ESP8266SPIRAM() { + end(); + } + void readBytes(uint32_t addr, void *destV, int count) { + uint8_t *dest = (uint8_t *)destV; + SPI.beginTransaction(SPISettings(freq, MSBFIRST, SPI_MODE0)); + pinMode(csPin, OUTPUT); + digitalWrite(csPin, LOW); + uint32_t cmd = (0x03 << 24) | (addr & ((1 << 24) - 1)); + SPI.transfer((uint8_t)(cmd >> 24)); + SPI.transfer((uint8_t)(cmd >> 16)); + SPI.transfer((uint8_t)(cmd >> 8)); + SPI.transfer((uint8_t)(cmd >> 0)); + while (count--) { + *(dest++) = SPI.transfer((uint8_t)0); } - - void writeBytes(uint32_t addr, const void *srcV, int count) - { - const uint8_t *src = (const uint8_t *)srcV; - SPI.beginTransaction(SPISettings(freq, MSBFIRST, SPI_MODE0)); - pinMode(csPin, OUTPUT); - digitalWrite(csPin, LOW); - uint32_t cmd = (0x02 << 24) | (addr & ((1<<24)-1)); - SPI.transfer((uint8_t)(cmd >> 24)); - SPI.transfer((uint8_t)(cmd >> 16)); - SPI.transfer((uint8_t)(cmd >> 8)); - SPI.transfer((uint8_t)(cmd >> 0)); - while (count--) { - SPI.transfer((uint8_t)*(src++)); - } - pinMode(csPin, OUTPUT); - digitalWrite(csPin, HIGH); - SPI.endTransaction(); + pinMode(csPin, OUTPUT); + digitalWrite(csPin, HIGH); + SPI.endTransaction(); + } + + void writeBytes(uint32_t addr, const void *srcV, int count) { + const uint8_t *src = (const uint8_t *)srcV; + SPI.beginTransaction(SPISettings(freq, MSBFIRST, SPI_MODE0)); + pinMode(csPin, OUTPUT); + digitalWrite(csPin, LOW); + uint32_t cmd = (0x02 << 24) | (addr & ((1 << 24) - 1)); + SPI.transfer((uint8_t)(cmd >> 24)); + SPI.transfer((uint8_t)(cmd >> 16)); + SPI.transfer((uint8_t)(cmd >> 8)); + SPI.transfer((uint8_t)(cmd >> 0)); + while (count--) { + SPI.transfer((uint8_t) * (src++)); } - - void begin(int freqMHz, int cs_pin) - { - csPin = cs_pin; - freq = freqMHz * 1000000; - - SPI.begin(); - - // Manually reset chip from DIO to SIO mode (HW SPI has issues with <8 bits/clocks total output) - digitalWrite(csPin, HIGH); - digitalWrite(mosi, HIGH); - digitalWrite(miso, HIGH); + pinMode(csPin, OUTPUT); + digitalWrite(csPin, HIGH); + SPI.endTransaction(); + } + + void begin(int freqMHz, int cs_pin) { + csPin = cs_pin; + freq = freqMHz * 1000000; + + SPI.begin(); + + // Manually reset chip from DIO to SIO mode (HW SPI has issues with <8 bits/clocks total output) + digitalWrite(csPin, HIGH); + digitalWrite(mosi, HIGH); + digitalWrite(miso, HIGH); + digitalWrite(sck, LOW); + pinMode(csPin, OUTPUT); + pinMode(miso, OUTPUT); + pinMode(mosi, OUTPUT); + pinMode(sck, OUTPUT); + digitalWrite(csPin, HIGH); + delay(100); + digitalWrite(csPin, LOW); + delay(1); + for (int i = 0; i < 4; i++) { + digitalWrite(sck, HIGH); + delay(1); digitalWrite(sck, LOW); - pinMode(csPin, OUTPUT); - pinMode(miso, OUTPUT); - pinMode(mosi, OUTPUT); - pinMode(sck, OUTPUT); - digitalWrite(csPin, HIGH); - delay(100); - digitalWrite(csPin, LOW); delay(1); - for (int i = 0; i < 4; i++) { - digitalWrite(sck, HIGH); - delay(1); - digitalWrite(sck, LOW); - delay(1); - } - digitalWrite(csPin, HIGH); - - pinMode(sck, SPECIAL); - pinMode(miso, SPECIAL); - pinMode(mosi, SPECIAL); - pinMode(csPin, OUTPUT); - - // Enable streaming read/write mode - SPI.beginTransaction(SPISettings(freq, MSBFIRST, SPI_MODE0)); - pinMode(csPin, OUTPUT); - digitalWrite(csPin, LOW); - SPI.transfer((uint8_t) 0x01); - SPI.transfer((uint8_t) 0x40); - pinMode(csPin, OUTPUT); - digitalWrite(csPin, HIGH); - SPI.endTransaction(); - pinMode(csPin, OUTPUT); - digitalWrite(csPin, HIGH); - } - - void end() - { - pinMode(csPin, INPUT); - pinMode(miso, INPUT); - pinMode(mosi, INPUT); - pinMode(sck, INPUT); - SPI.end(); } + digitalWrite(csPin, HIGH); + + pinMode(sck, OUTPUT); + pinMode(miso, INPUT); + pinMode(mosi, OUTPUT); + pinMode(csPin, OUTPUT); + + // Enable streaming read/write mode + SPI.beginTransaction(SPISettings(freq, MSBFIRST, SPI_MODE0)); + pinMode(csPin, OUTPUT); + digitalWrite(csPin, LOW); + SPI.transfer((uint8_t) 0x01); + SPI.transfer((uint8_t) 0x40); + pinMode(csPin, OUTPUT); + digitalWrite(csPin, HIGH); + SPI.endTransaction(); + pinMode(csPin, OUTPUT); + digitalWrite(csPin, HIGH); + } + + void end() { + pinMode(csPin, INPUT); + pinMode(miso, INPUT); + pinMode(mosi, INPUT); + pinMode(sck, INPUT); + SPI.end(); + } }; #endif // ESP32 -#endif \ No newline at end of file +#endif diff --git a/tests/astyle_core.conf b/tests/astyle_core.conf new file mode 100644 index 00000000..720ee1b7 --- /dev/null +++ b/tests/astyle_core.conf @@ -0,0 +1,32 @@ +# Code formatting rules for Arduino examples, taken from: +# +# https://github.com/arduino/Arduino/blob/master/build/shared/examples_formatter.conf +# + +mode=c +lineend=linux +style=java + +# 4 spaces indentation +indent=spaces=4 + +# also indent macros +#indent-preprocessor + +# indent classes, switches (and cases), comments starting at column 1 +indent-col1-comments + +# put a space around operators +pad-oper + +# put a space after if/for/while +pad-header + +# if you like one-liners, keep them +keep-one-line-statements + +attach-closing-while +unpad-paren +pad-oper +remove-comment-prefix +add-braces diff --git a/tests/astyle_examples.conf b/tests/astyle_examples.conf new file mode 100644 index 00000000..f3b77f2c --- /dev/null +++ b/tests/astyle_examples.conf @@ -0,0 +1,44 @@ +# Code formatting rules for Arduino examples, taken from: +# +# https://github.com/arduino/Arduino/blob/master/build/shared/examples_formatter.conf +# + +mode=c +lineend=linux + +# 2 spaces indentation +indent=spaces=2 + +# also indent macros +#indent-preprocessor + +# indent classes, switches (and cases), comments starting at column 1 +indent-classes +indent-switches +indent-cases +indent-col1-comments + +# put a space around operators +pad-oper + +# put a space after if/for/while +pad-header + +# if you like one-liners, keep them +keep-one-line-statements +add-braces + +style=java +attach-namespaces +attach-classes +attach-inlines +attach-extern-c +indent-modifiers +indent-namespaces +indent-labels +#indent-preproc-block +#indent-preproc-define +#indent-preproc-cond +unpad-paren +add-braces +remove-comment-prefix \ No newline at end of file diff --git a/tests/build-ci.sh b/tests/build-ci.sh new file mode 100755 index 00000000..9479dce8 --- /dev/null +++ b/tests/build-ci.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +set -e +set -o pipefail + +outdir=$1; shift +offset=$1; shift +fqbn=$1; shift +werror=$1; shift + +mkdir $outdir +rm -f *.elf + +# Get initial list and shift off to the starting point +sketches=$(find ~/Arduino/libraries/ESP8266Audio/examples -name "*.ino" | sort | tr '\n' ' ' | cut -f$offset -d " ") + +# Iterate over sketches +while [ $(echo $sketches | wc -w) -gt 0 ]; do + sketch=$(echo $sketches | cut -f1 -d " ") + echo "::group::Compiling $(basename $sketch) for $fqbn into $outdir" + if [ 0"$werror" -gt 0 ]; then + ./arduino-cli compile -b "$fqbn" -v --warnings all \ + --build-property "compiler.c.extra_flags=-Wall -Wextra -Werror -Wno-ignored-qualifiers" \ + --build-property "compiler.cpp.extra_flags=-Wall -Wextra -Werror -Wno-ignored-qualifiers -Wno-overloaded-virtual" \ + --build-path "$outdir" "$sketch" || exit 255 + else + ./arduino-cli compile -b "$fqbn" -v --warnings all --build-path "$outdir" "$sketch" || exit 255 + fi + mv -f "$outdir"/*.elf . + echo "::endgroup::" + # Shift out 5 + if [ $(echo $sketches | wc -w) -gt 5 ]; then + sketches=$(echo $sketches | cut -f6- -d " ") + else + sketches="" + fi +done + +echo "::group::Final Sizes" +size ./*.elf +echo "::endgroup::" diff --git a/tests/common.sh b/tests/common.sh index cabad512..518d7db8 100755 --- a/tests/common.sh +++ b/tests/common.sh @@ -2,98 +2,17 @@ set -ex -function print_size_info() -{ - elf_file=$1 - - if [ -z "$elf_file" ]; then - printf "sketch data rodata bss text irom0.text dram flash\n" - return 0 - fi - - elf_name=$(basename $elf_file) - sketch_name="${elf_name%.*}" - # echo $sketch_name - declare -A segments - while read -a tokens; do - seg=${tokens[0]} - seg=${seg//./} - size=${tokens[1]} - addr=${tokens[2]} - if [ "$addr" -eq "$addr" -a "$addr" -ne "0" ] 2>/dev/null; then - segments[$seg]=$size - fi - - - done < <(xtensa-lx106-elf-size --format=sysv $elf_file) - - total_ram=$((${segments[data]} + ${segments[rodata]} + ${segments[bss]})) - total_flash=$((${segments[data]} + ${segments[rodata]} + ${segments[text]} + ${segments[irom0text]})) - - printf "%-28s %-8d %-8d %-8d %-8d %-8d %-8d %-8d\n" $sketch_name ${segments[data]} ${segments[rodata]} ${segments[bss]} ${segments[text]} ${segments[irom0text]} $total_ram $total_flash - return 0 -} - -function build_sketches() -{ - set +e - local arduino=$1 - local srcpath=$2 - local build_arg=$3 - local build_dir=build.tmp - local build_mod=$BUILD_MOD - local build_rem=$BUILD_REM - mkdir -p $build_dir - local build_cmd="python3 $arduino/$BUILD_PY -p $PWD/$build_dir $build_arg " - local sketches=$(find $srcpath -name *.ino) - print_size_info >size.log - export ARDUINO_IDE_PATH=$arduino - for sketch in $sketches; do - testcnt=$(( ($testcnt + 1) % $build_mod )) - if [ $testcnt -ne $build_rem ]; then - continue # Not ours to do - fi - rm -rf $build_dir/* - local sketchdir=$(dirname $sketch) - local sketchdirname=$(basename $sketchdir) - local sketchname=$(basename $sketch) - if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then - echo "Skipping $sketch, beacause it is not the main sketch file"; - continue - fi; - if [[ -f "$sketchdir/.test.skip" ]]; then - echo -e "\n ------------ Skipping $sketch ------------ \n"; - continue - fi - echo -e "\n ------------ Building $sketch ------------ \n"; - # $arduino --verify $sketch; - echo "$build_cmd $sketch" - time ($build_cmd $sketch >build.log) - local result=$? - if [ $result -ne 0 ]; then - echo "Build failed ($1)" - echo "Build log:" - cat build.log - set -e - return $result - fi - rm build.log - #print_size_info $build_dir/*.elf >>size.log - done - set -e -} - function install_libraries() { mkdir -p $HOME/Arduino/libraries - cp -a $TRAVIS_BUILD_DIR $HOME/Arduino/libraries/ESP8266Audio + cp -a $GITHUB_WORKSPACE $HOME/Arduino/libraries/ESP8266Audio git clone https://github.com/earlephilhower/ESP8266SAM $HOME/Arduino/libraries/ESP8266SAM } function install_ide() { local ide_path=$1 - wget -q -O arduino.tar.xz https://www.arduino.cc/download.php?f=/arduino-nightly-linux64.tar.xz + wget -q -O arduino.tar.xz https://downloads.arduino.cc/arduino-nightly-linux64.tar.xz tar xf arduino.tar.xz mv arduino-nightly $ide_path export PATH="$ide_path:$PATH" @@ -111,84 +30,128 @@ function install_esp8266() # Set custom warnings for all builds (i.e. could add -Wextra at some point) echo "compiler.c.extra_flags=-Wall -Wextra -Werror $debug_flags" > ../platform.local.txt echo "compiler.cpp.extra_flags=-Wall -Wextra -Werror $debug_flags" >> ../platform.local.txt + echo "mkbuildoptglobals.extra_flags=--ci --cache_core" >> ../platform.local.txt echo -e "\n----platform.local.txt----" cat ../platform.local.txt git submodule init git submodule update - python3 get.py + python3 get.py -q export PATH="$ide_path/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin:$PATH" popd - + cd esp8266 } -function install_esp32() +function install_rp2040() { local ide_path=$1 - sudo pip install pyserial + mkdir -p $ide_path/hardware cd $ide_path/hardware - mkdir espressif - cd espressif - git clone https://github.com/espressif/arduino-esp32.git esp32 - pushd esp32 + mkdir pico + cd pico + git clone https://github.com/earlephilhower/arduino-pico rp2040 + pushd rp2040/tools # Set custom warnings for all builds (i.e. could add -Wextra at some point) - echo "compiler.c.extra_flags=-Wall -Wextra -Werror $debug_flags" > platform.local.txt - echo "compiler.cpp.extra_flags=-Wall -Wextra -Werror $debug_flags" >> platform.local.txt + echo "compiler.c.extra_flags=-Wall -Wextra -Werror $debug_flags" > ../platform.local.txt + echo "compiler.cpp.extra_flags=-Wall -Wextra -Werror $debug_flags" >> ../platform.local.txt echo -e "\n----platform.local.txt----" - cat platform.local.txt - git submodule init - git submodule update - cd tools - python3 get.py - export PATH="$ide_path/hardware/espressif/esp32/tools/xtensa-esp32-elf/bin/:$PATH" + cat ../platform.local.txt + git submodule update --init + cd ../pico-sdk + git submodule update --init + cd ../tools + python3 get.py -q + export PATH="$ide_path/hardware/pico/rp2040/system/arm-none-eabi/bin:$PATH" popd + cd rp2040 +} +function install_esp32() +{ + local ide_path=$1 + pip install pyserial + pip3 install pyserial + mkdir -p ~/bin + pushd ~/bin + wget -q https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Linux_64bit.tar.gz + tar xvf arduino-cli_latest_Linux_64bit.tar.gz + export PATH=$PATH:$PWD + popd + arduino-cli core install --additional-urls https://espressif.github.io/arduino-esp32/package_esp32_index.json esp32:esp32 } function install_arduino() { # Install Arduino IDE and required libraries - echo -e "travis_fold:start:sketch_test_env_prepare" - cd $TRAVIS_BUILD_DIR - install_ide $HOME/arduino_ide $TRAVIS_BUILD_DIR + cd "$GITHUB_WORKSPACE" + install_ide "$HOME/arduino_ide" "$GITHUB_WORKSPACE" which arduino - cd $TRAVIS_BUILD_DIR + cd "$GITHUB_WORKSPACE" install_libraries - echo -e "travis_fold:end:sketch_test_env_prepare" } -function build_sketches_with_arduino() +function skip_esp32() { - # Compile sketches - echo -e "travis_fold:start:sketch_test" - build_sketches $HOME/arduino_ide $HOME/Arduino/libraries "-l $HOME/Arduino/libraries" - echo -e "travis_fold:end:sketch_test" - # Generate size report - echo -e "travis_fold:start:size_report" - cat size.log - echo -e "travis_fold:end:size_report" + local ino=$1 + local skiplist="" + # Add items to the following list with "\n" netween them to skip running. No spaces, tabs, etc. allowed + read -d '' skiplist << EOL || true +/MixerSample/ +EOL + echo $ino | grep -q -F "$skiplist" + echo $(( 1 - $? )) } -set -e +# ESP8266 CI infra +function skip_sketch() +{ + local sketch=$1 + local sketchname=$2 + local sketchdir=$3 + local sketchdirname=$4 + + if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then + echo "Skipping $sketch (not the main sketch file)" + fi + if skip_ino "$sketch" || [[ -f "$sketchdir/.test.skip" ]]; then + echo "Skipping $sketch" + fi +} if [ "$BUILD_MOD" == "" ]; then export BUILD_MOD=1 export BUILD_REM=0 fi +export cache_dir=$(mktemp -d) if [ "$BUILD_TYPE" = "build" ]; then - export BUILD_PY="hardware/esp8266com/esp8266/tools/build.py -b generic -s 4M1M -v -k " install_arduino install_esp8266 "$HOME/arduino_ide" - build_sketches_with_arduino + source "$HOME/arduino_ide/hardware/esp8266com/esp8266/tests/common.sh" + export ESP8266_ARDUINO_SKETCHES=$(find $HOME/Arduino/libraries/ESP8266Audio -name *.ino | sort) + # ESP8266 scripts now expect tools in wrong spot. Use simple and dumb fix + mkdir -p "$HOME/work/ESP8266Audio/ESP8266Audio" + ln -s "$HOME/arduino_ide/hardware/esp8266com/esp8266/tools" "$HOME/work/ESP8266Audio/ESP8266Audio/tools" + mkdir -p /home/runner/work/ESP8266Audio/ESP8266Audio/tools/xtensa-lx106-elf/bin/ + ln -s $HOME/arduino_ide/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-size /home/runner/work/ESP8266Audio/ESP8266Audio/tools/xtensa-lx106-elf/bin/. + build_sketches "$TRAVIS_BUILD_DIR" "$HOME/arduino_ide" "$HOME/arduino_ide/hardware" "$HOME/Arduino/libraries" "$BUILD_MOD" "$BUILD_REM" "lm2f" elif [ "$BUILD_TYPE" = "build_esp32" ]; then install_arduino install_esp32 "$HOME/arduino_ide" - export ide_path=$HOME/arduino_ide - export FQBN="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app" - export GITHUB_WORKSPACE="$TRAVIS_BUILD_DIR" - export GITHUB_REPOSITORY="$TRAVIS_REPO_SLUG" - source $ide_path/hardware/espressif/esp32/.github/scripts/install-arduino-ide.sh - source $ide_path/hardware/espressif/esp32/.github/scripts/install-arduino-core-esp32.sh - build_sketches "$FQBN" "$HOME/Arduino/libraries" "$BUILD_REM" "$BUILD_MOD" + export testcnt=0 + for i in $(find ~/Arduino/libraries/ESP8266Audio -name "*.ino"); do + testcnt=$(( ($testcnt + 1) % $BUILD_MOD )) + if [ $testcnt -ne $BUILD_REM ]; then + continue # Not ours to do + fi + if [[ $(skip_esp32 $i) = 1 ]]; then + echo -e "\n ------------ Skipping $i ------------ \n"; + continue + fi + arduino-cli compile --fqbn esp32:esp32:esp32 --warnings all $i + done +elif [ "$BUILD_TYPE" = "build_rp2040" ]; then + install_arduino + install_rp2040 "$HOME/arduino_ide" + source "$HOME/arduino_ide/hardware/pico/rp2040/tests/common.sh" + build_sketches "$HOME/arduino_ide" "$TRAVIS_BUILD_DIR" "-l $HOME/Arduino/libraries" "$BUILD_MOD" "$BUILD_REM" fi - diff --git a/tests/host/Makefile b/tests/host/Makefile index 9a219465..c25430cc 100644 --- a/tests/host/Makefile +++ b/tests/host/Makefile @@ -20,65 +20,23 @@ libhelix_aac=../../src/libhelix-aac/decelmnt.c ../../src/libhelix-aac/dct4.c ../ ../../src/libhelix-aac/trigtabs.c ../../src/libhelix-aac/fft.c ../../src/libhelix-aac/pns.c ../../src/libhelix-aac/sbrfreq.c \ ../../src/libhelix-aac/sbrside.c ../../src/libhelix-aac/sbrhfadj.c ../../src/libhelix-aac/buffers.c ../../src/libhelix-aac/bitstream.c \ ../../src/libhelix-aac/noiseless.c ../../src/libhelix-aac/imdct.c ../../src/libhelix-aac/aacdec.c ../../src/libhelix-aac/sbrhfgen.c \ -../../src/libhelix-aac/sbrqmf.c ../../src/libhelix-aac/huffman.c ../../src/libhelix-aac/sbr.c ../../src/libhelix-aac/sbrimdct.c +../../src/libhelix-aac/sbrqmf.c ../../src/libhelix-aac/huffmanaac.c ../../src/libhelix-aac/sbr.c ../../src/libhelix-aac/sbrimdct.c libflac=../../src/libflac/md5.c ../../src/libflac/window.c ../../src/libflac/memory.c ../../src/libflac/cpu.c ../../src/libflac/fixed.c \ ../../src/libflac/format.c ../../src/libflac/lpc.c ../../src/libflac/crc.c ../../src/libflac/bitreader.c ../../src/libflac/bitmath.c \ ../../src/libflac/stream_decoder.c ../../src/libflac/float.c -libogg=../../src/libogg/framing.c ../../src/libogg/bitwise.c - -libopus=../../src/libopus/opus_decoder.c ../../src/libopus/opus_projection_decoder.c ../../src/libopus/opus.c ../../src/libopus/opus_multistream.c \ -../../src/libopus/opus_multistream_encoder.c ../../src/libopus/repacketizer.c ../../src/libopus/opus_multistream_decoder.c \ -../../src/libopus/mapping_matrix.c ../../src/libopus/opus_projection_encoder.c ../../src/libopus/silk/NLSF_VQ_weights_laroia.c \ -../../src/libopus/silk/decode_core.c ../../src/libopus/silk/resampler_down2_3.c ../../src/libopus/silk/resampler_private_down_FIR.c \ -../../src/libopus/silk/tables_other.c ../../src/libopus/silk/resampler_private_up2_HQ.c ../../src/libopus/silk/init_encoder.c \ -../../src/libopus/silk/tables_NLSF_CB_WB.c ../../src/libopus/silk/control_codec.c ../../src/libopus/silk/decode_frame.c \ -../../src/libopus/silk/table_LSF_cos.c ../../src/libopus/silk/resampler_private_AR2.c ../../src/libopus/silk/NLSF_del_dec_quant.c \ -../../src/libopus/silk/VQ_WMat_EC.c ../../src/libopus/silk/encode_indices.c ../../src/libopus/silk/sort.c ../../src/libopus/silk/NSQ.c \ -../../src/libopus/silk/NLSF_unpack.c ../../src/libopus/silk/bwexpander_32.c ../../src/libopus/silk/tables_NLSF_CB_NB_MB.c \ -../../src/libopus/silk/ana_filt_bank_1.c ../../src/libopus/silk/resampler_down2.c ../../src/libopus/silk/stereo_encode_pred.c \ -../../src/libopus/silk/bwexpander.c ../../src/libopus/silk/PLC.c ../../src/libopus/silk/pitch_est_tables.c ../../src/libopus/silk/NLSF2A.c \ -../../src/libopus/silk/stereo_quant_pred.c ../../src/libopus/silk/debug.c ../../src/libopus/silk/LPC_analysis_filter.c \ -../../src/libopus/silk/control_audio_bandwidth.c ../../src/libopus/silk/decode_indices.c ../../src/libopus/silk/sigm_Q15.c \ -../../src/libopus/silk/resampler_private_IIR_FIR.c ../../src/libopus/silk/log2lin.c ../../src/libopus/silk/A2NLSF.c \ -../../src/libopus/silk/quant_LTP_gains.c ../../src/libopus/silk/NLSF_stabilize.c ../../src/libopus/silk/fixed/find_pred_coefs_FIX.c \ -../../src/libopus/silk/fixed/autocorr_FIX.c ../../src/libopus/silk/fixed/burg_modified_FIX.c ../../src/libopus/silk/fixed/vector_ops_FIX.c \ -../../src/libopus/silk/fixed/find_LTP_FIX.c ../../src/libopus/silk/fixed/find_pitch_lags_FIX.c ../../src/libopus/silk/fixed/schur64_FIX.c \ -../../src/libopus/silk/fixed/noise_shape_analysis_FIX.c ../../src/libopus/silk/fixed/find_LPC_FIX.c \ -../../src/libopus/silk/fixed/residual_energy16_FIX.c ../../src/libopus/silk/fixed/apply_sine_window_FIX.c \ -../../src/libopus/silk/fixed/regularize_correlations_FIX.c ../../src/libopus/silk/fixed/k2a_Q16_FIX.c \ -../../src/libopus/silk/fixed/encode_frame_FIX.c ../../src/libopus/silk/fixed/k2a_FIX.c ../../src/libopus/silk/fixed/pitch_analysis_core_FIX.c \ -../../src/libopus/silk/fixed/process_gains_FIX.c ../../src/libopus/silk/fixed/LTP_scale_ctrl_FIX.c \ -../../src/libopus/silk/fixed/warped_autocorrelation_FIX.c ../../src/libopus/silk/fixed/schur_FIX.c \ -../../src/libopus/silk/fixed/LTP_analysis_filter_FIX.c ../../src/libopus/silk/fixed/corrMatrix_FIX.c \ -../../src/libopus/silk/fixed/residual_energy_FIX.c ../../src/libopus/silk/LPC_fit.c ../../src/libopus/silk/tables_gain.c \ -../../src/libopus/silk/decode_parameters.c ../../src/libopus/silk/tables_pitch_lag.c ../../src/libopus/silk/stereo_MS_to_LR.c \ -../../src/libopus/silk/dec_API.c ../../src/libopus/silk/code_signs.c ../../src/libopus/silk/shell_coder.c \ -../../src/libopus/silk/stereo_find_predictor.c ../../src/libopus/silk/init_decoder.c ../../src/libopus/silk/decode_pulses.c \ -../../src/libopus/silk/gain_quant.c ../../src/libopus/silk/check_control_input.c ../../src/libopus/silk/tables_LTP.c \ -../../src/libopus/silk/resampler_rom.c ../../src/libopus/silk/NSQ_del_dec.c ../../src/libopus/silk/decode_pitch.c ../../src/libopus/silk/VAD.c \ -../../src/libopus/silk/NLSF_decode.c ../../src/libopus/silk/sum_sqr_shift.c ../../src/libopus/silk/stereo_LR_to_MS.c \ -../../src/libopus/silk/encode_pulses.c ../../src/libopus/silk/control_SNR.c ../../src/libopus/silk/tables_pulses_per_block.c \ -../../src/libopus/silk/LP_variable_cutoff.c ../../src/libopus/silk/enc_API.c ../../src/libopus/silk/interpolate.c \ -../../src/libopus/silk/LPC_inv_pred_gain.c ../../src/libopus/silk/NLSF_VQ.c ../../src/libopus/silk/lin2log.c \ -../../src/libopus/silk/resampler.c ../../src/libopus/silk/NLSF_encode.c ../../src/libopus/silk/CNG.c ../../src/libopus/silk/stereo_decode_pred.c \ -../../src/libopus/silk/process_NLSFs.c ../../src/libopus/silk/HP_variable_cutoff.c ../../src/libopus/silk/biquad_alt.c \ -../../src/libopus/silk/inner_prod_aligned.c ../../src/libopus/silk/decoder_set_fs.c ../../src/libopus/celt/celt.c \ -../../src/libopus/celt/mdct.c ../../src/libopus/celt/cwrs.c ../../src/libopus/celt/rate.c ../../src/libopus/celt/vq.c \ -../../src/libopus/celt/quant_bands.c ../../src/libopus/celt/celt_decoder.c ../../src/libopus/celt/celt_lpc.c \ -../../src/libopus/celt/celt_encoder.c ../../src/libopus/celt/entenc.c ../../src/libopus/celt/bands.c ../../src/libopus/celt/kiss_fft.c \ -../../src/libopus/celt/pitch.c ../../src/libopus/celt/entdec.c ../../src/libopus/celt/laplace.c ../../src/libopus/celt/entcode.c \ -../../src/libopus/celt/modes.c ../../src/libopus/celt/mathops.c ../../src/libopus/opus_encoder.c - -opusfile=../../src/opusfile/opusfile.c ../../src/opusfile/stream.c ../../src/opusfile/internal.c ../../src/opusfile/info.c - -CCOPTS=-g -Wunused-parameter -Wall -m32 -include Arduino.h -CPPOPTS=-g -Wunused-parameter -Wall -std=c++11 -m32 -include Arduino.h +libflac=../../src/libflac/md5.c ../../src/libflac/window.c ../../src/libflac/memory.c ../../src/libflac/cpu.c \ +../../src/libflac/fixed.c ../../src/libflac/format.c ../../src/libflac/lpc.c ../../src/libflac/crc.c \ +../../src/libflac/bitreader.c ../../src/libflac/bitmath.c ../../src/libflac/stream_decoder.c ../../src/libflac/float.c + + +CCOPTS=-g -Wunused-parameter -Wall -m32 -include Arduino.h -Wstack-usage=300 +CPPOPTS=-g -Wunused-parameter -Wall -std=c++11 -m32 -Wstack-usage=300 -include Arduino.h .phony: all -all: mp3 aac wav midi opus +all: mp3 aac wav midi opus flac mod mp3: FORCE rm -f *.o @@ -94,6 +52,19 @@ aac: FORCE rm -f *.o echo valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all ./aac +flac: FORCE + rm -f *.o + gcc $(CCOPTS) -DUSE_DEFAULT_STDLIB -c $(libflac) -I ../../src/ -I ../../src/libflac -I. + g++ $(CPPOPTS) -o flac flac.cpp Serial.cpp *.o ../../src/AudioFileSourceSTDIO.cpp ../../src/AudioOutputSTDIO.cpp ../../src/AudioFileSourceID3.cpp ../../src/AudioGeneratorFLAC.cpp ../../src/AudioLogger.cpp -I ../../src/ -I. + rm -f *.o + echo valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all ./flac + +mod: FORCE + rm -f *.o + g++ $(CPPOPTS) -o mod mod.cpp Serial.cpp ../../src/AudioFileSourcePROGMEM.cpp ../../src/AudioOutputSTDIO.cpp ../../src/AudioGeneratorMOD.cpp ../../src/AudioLogger.cpp -I ../../src/ -I. + rm -f *.o + echo valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all ./mod + wav: FORCE rm -f *.o g++ $(CPPOPTS) -o wav wav.cpp Serial.cpp ../../src/AudioFileSourceSTDIO.cpp ../../src/AudioOutputSTDIO.cpp ../../src/AudioGeneratorWAV.cpp ../../src/AudioLogger.cpp -I ../../src/ -I. @@ -108,14 +79,12 @@ midi: FORCE opus: FORCE rm -f *.o - gcc $(CCOPTS) -DUSE_DEFAULT_STDLIB -c $(libogg) -I ../../src/ -I. - gcc $(CCOPTS) -DUSE_DEFAULT_STDLIB -c $(libopus) -I ../../src/ -I. - gcc $(CCOPTS) -DUSE_DEFAULT_STDLIB -c $(opusfile) -I ../../src/ -I. + find ../../src/libopus -name *.c -exec gcc $(CCOPTS) -DUSE_DEFAULT_STDLIB -c \{\} -I ../../src/ -I. \; g++ $(CPPOPTS) -o opus opus.cpp Serial.cpp *.o ../../src/AudioFileSourceSTDIO.cpp ../../src/AudioOutputSTDIO.cpp ../../src/AudioGeneratorOpus.cpp ../../src/AudioLogger.cpp -I ../../src/ -I. rm -f *.o echo valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all ./opus clean: - rm -f mp3 aac wav midi opus *.o + rm -f mp3 aac wav midi opus flac mod *.o FORCE: diff --git a/tests/host/flac.cpp b/tests/host/flac.cpp new file mode 100644 index 00000000..2d7110da --- /dev/null +++ b/tests/host/flac.cpp @@ -0,0 +1,24 @@ +#include +#include "AudioFileSourceSTDIO.h" +#include "AudioOutputSTDIO.h" +#include "AudioGeneratorFLAC.h" + +#define AAC "gs-16b-2c-44100hz.flac" + +int main(int argc, char **argv) +{ + (void) argc; + (void) argv; + AudioFileSourceSTDIO *in = new AudioFileSourceSTDIO(AAC); + AudioOutputSTDIO *out = new AudioOutputSTDIO(); + out->SetFilename("out.flac.wav"); + AudioGeneratorFLAC *flac = new AudioGeneratorFLAC(); + + flac->begin(in, out); + while (flac->loop()) { /*noop*/ } + flac->stop(); + + delete flac; + delete out; + delete in; +} diff --git a/tests/host/gs-16b-2c-44100hz.flac b/tests/host/gs-16b-2c-44100hz.flac new file mode 100644 index 00000000..17713214 Binary files /dev/null and b/tests/host/gs-16b-2c-44100hz.flac differ diff --git a/tests/host/mod.cpp b/tests/host/mod.cpp new file mode 100644 index 00000000..18da2ce3 --- /dev/null +++ b/tests/host/mod.cpp @@ -0,0 +1,26 @@ +#include +#include "AudioFileSourcePROGMEM.h" +#include "AudioOutputSTDIO.h" +#include "AudioGeneratorMOD.h" + +#include "../../examples/PlayMODFromPROGMEMToDAC/enigma.h" + +int main(int argc, char **argv) +{ + (void) argc; + (void) argv; + + AudioFileSourcePROGMEM *file = new AudioFileSourcePROGMEM(enigma_mod, sizeof(enigma_mod)); + AudioOutputSTDIO *out = new AudioOutputSTDIO(); + out->SetFilename("mod.wav"); + AudioGeneratorMOD *mod = new AudioGeneratorMOD(); + + mod->begin(file, out); + // The MOD plays forever, so only run for ~30 seconds worth + for (int i=0; i<10000; i++) mod->loop(); + mod->stop(); + + delete out; + delete mod; + delete file; +} diff --git a/tests/host/opus.cpp b/tests/host/opus.cpp index 45e8d712..861e833d 100644 --- a/tests/host/opus.cpp +++ b/tests/host/opus.cpp @@ -3,7 +3,7 @@ #include "AudioOutputSTDIO.h" #include "AudioGeneratorOpus.h" -#define OPUS "../../examples/PlayOpusFromSPIFFS/data/gs-16b-2c-44100hz.opus" +#define OPUS "../../examples/PlayOpusFromLittleFS/data/gs-16b-2c-44100hz.opus" int main(int argc, char **argv) { diff --git a/tests/restyle.sh b/tests/restyle.sh new file mode 100755 index 00000000..6c331b40 --- /dev/null +++ b/tests/restyle.sh @@ -0,0 +1,4 @@ +#!/bin/bash +find ./src -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" \) -a \! -path '*api*' -a \! -path '*libespeak-ng*' -a \! -path '*libopus*' -exec astyle --suffix=none --options=./tests/astyle_core.conf \{\} \; +find ./examples -type f -name "*.ino" -exec astyle --suffix=none --options=./tests/astyle_examples.conf \{\} \; + diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 00000000..b02acdc0 --- /dev/null +++ b/tools/README.md @@ -0,0 +1,16 @@ +Publishing New Releases +======================= + +First, update the version number throughout the repo and push the change: + + ./tools/makever.py --version X.Y.Z + git commit -a -m "Update version" + git push + +Then tag it + + git tag X.Y.Z + git push origin X.Y.Z + +Then on the GH web interface it will generate a draft release from that tag +that can be released if proper through the GUI. diff --git a/tools/makever.py b/tools/makever.py new file mode 100755 index 00000000..7ae3f47e --- /dev/null +++ b/tools/makever.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +import sys +import struct +import subprocess +import re +import os +import os.path +import argparse +import time +import shutil +import json + +def main(): + parser = argparse.ArgumentParser(description='Version updater') + parser.add_argument('-v', '--version', action='store', required=True, help='Version in X.Y.Z form') + args = parser.parse_args() + + major, minor, sub = args.version.split(".") + # Silly way to check for integer x.y.z + major = int(major) + minor = int(minor) + sub = int(sub) + + # library.properties + with open("library.properties", "r") as fin: + with open("library.properties.new", "w") as fout: + for l in fin: + if l.startswith("version="): + l = "version=" + str(args.version) + "\n" + fout.write(l); + shutil.move("library.properties.new", "library.properties") + + # package.json + with open("library.json", "r") as fin: + library = json.load(fin); + library["version"] = str(args.version); + with open("library.json.new", "w") as fout: + json.dump(library, fout, indent = 4); + shutil.move("library.json.new", "library.json") + +main()